diff options
Diffstat (limited to 'frontends/riscos')
228 files changed, 63025 insertions, 0 deletions
diff --git a/frontends/riscos/401login.c b/frontends/riscos/401login.c new file mode 100644 index 000000000..e95a74809 --- /dev/null +++ b/frontends/riscos/401login.c @@ -0,0 +1,236 @@ +/* + * Copyright 2003 John M Bell <jmb202@ecs.soton.ac.uk> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "utils/config.h" + +#include <assert.h> +#include <stdbool.h> +#include <string.h> +#include <oslib/wimp.h> + +#include "utils/log.h" +#include "utils/messages.h" +#include "content/content.h" +#include "content/hlcache.h" +#include "content/urldb.h" +#include "desktop/browser.h" + +#include "riscos/gui.h" +#include "riscos/dialog.h" +#include "riscos/wimp_event.h" + +#define ICON_401LOGIN_LOGIN 0 +#define ICON_401LOGIN_CANCEL 1 +#define ICON_401LOGIN_HOST 2 +#define ICON_401LOGIN_REALM 3 +#define ICON_401LOGIN_USERNAME 4 +#define ICON_401LOGIN_PASSWORD 5 + +static void ro_gui_401login_close(wimp_w w); +static bool ro_gui_401login_apply(wimp_w w); +static void ro_gui_401login_open(nsurl *url, lwc_string *host, + const char *realm, + nserror (*cb)(bool proceed, void *pw), void *cbpw); + +static wimp_window *dialog_401_template; + +struct session_401 { + lwc_string *host; /**< Host for user display */ + char *realm; /**< Authentication realm */ + char uname[256]; /**< Buffer for username */ + nsurl *url; /**< URL being fetched */ + char pwd[256]; /**< Buffer for password */ + nserror (*cb)(bool proceed, void *pw); /**< Continuation callback */ + void *cbpw; /**< Continuation callback data */ +}; + + +/** + * Load the 401 login window template. + */ + +void ro_gui_401login_init(void) +{ + dialog_401_template = ro_gui_dialog_load_template("login"); +} + + +/** + * Open the login dialog + */ +void gui_401login_open(nsurl *url, const char *realm, + nserror (*cb)(bool proceed, void *pw), void *cbpw) +{ + lwc_string *host = nsurl_get_component(url, NSURL_HOST); + assert(host != NULL); + + ro_gui_401login_open(url, host, realm, cb, cbpw); + + lwc_string_unref(host); +} + + +/** + * Open a 401 login window. + */ + +void ro_gui_401login_open(nsurl *url, lwc_string *host, const char *realm, + nserror (*cb)(bool proceed, void *pw), void *cbpw) +{ + struct session_401 *session; + wimp_w w; + const char *auth; + + session = calloc(1, sizeof(struct session_401)); + if (!session) { + ro_warn_user("NoMemory", 0); + return; + } + + session->url = nsurl_ref(url); + if (realm == NULL) + realm = "Secure Area"; + auth = urldb_get_auth_details(session->url, realm); + if (auth == NULL) { + session->uname[0] = '\0'; + session->pwd[0] = '\0'; + } else { + const char *pwd; + size_t pwd_len; + + pwd = strchr(auth, ':'); + assert(pwd && pwd < auth + sizeof(session->uname)); + memcpy(session->uname, auth, pwd - auth); + session->uname[pwd - auth] = '\0'; + ++pwd; + pwd_len = strlen(pwd); + assert(pwd_len < sizeof(session->pwd)); + memcpy(session->pwd, pwd, pwd_len); + session->pwd[pwd_len] = '\0'; + } + session->host = lwc_string_ref(host); + session->realm = strdup(realm); + session->cb = cb; + session->cbpw = cbpw; + + if (!session->realm) { + nsurl_unref(session->url); + lwc_string_unref(session->host); + free(session); + ro_warn_user("NoMemory", 0); + return; + } + + /* fill in download window icons */ + dialog_401_template->icons[ICON_401LOGIN_HOST].data. + indirected_text.text = + (char *)lwc_string_data(session->host); + dialog_401_template->icons[ICON_401LOGIN_HOST].data. + indirected_text.size = + lwc_string_length(session->host) + 1; + dialog_401_template->icons[ICON_401LOGIN_REALM].data. + indirected_text.text = session->realm; + dialog_401_template->icons[ICON_401LOGIN_REALM].data. + indirected_text.size = strlen(session->realm) + 1; + dialog_401_template->icons[ICON_401LOGIN_USERNAME].data. + indirected_text.text = session->uname; + dialog_401_template->icons[ICON_401LOGIN_USERNAME].data. + indirected_text.size = sizeof(session->uname); + dialog_401_template->icons[ICON_401LOGIN_PASSWORD].data. + indirected_text.text = session->pwd; + dialog_401_template->icons[ICON_401LOGIN_PASSWORD].data. + indirected_text.size = sizeof(session->pwd); + + /* create and open the window */ + w = wimp_create_window(dialog_401_template); + + ro_gui_wimp_event_register_text_field(w, ICON_401LOGIN_USERNAME); + ro_gui_wimp_event_register_text_field(w, ICON_401LOGIN_PASSWORD); + ro_gui_wimp_event_register_cancel(w, ICON_401LOGIN_CANCEL); + ro_gui_wimp_event_register_ok(w, ICON_401LOGIN_LOGIN, + ro_gui_401login_apply); + ro_gui_wimp_event_register_close_window(w, ro_gui_401login_close); + ro_gui_wimp_event_set_user_data(w, session); + + ro_gui_dialog_open_persistent(NULL, w, false); +} + +/** + * Handle closing of login dialog + */ +void ro_gui_401login_close(wimp_w w) +{ + os_error *error; + struct session_401 *session; + + session = (struct session_401 *)ro_gui_wimp_event_get_user_data(w); + + assert(session); + + /* If ok didn't happen, send failure response */ + if (session->cb != NULL) + session->cb(false, session->cbpw); + + nsurl_unref(session->url); + lwc_string_unref(session->host); + free(session->realm); + free(session); + + error = xwimp_delete_window(w); + if (error) { + LOG("xwimp_delete_window: 0x%x:%s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + ro_gui_wimp_event_finalise(w); +} + + +/* Login Clicked -> create a new fetch request, specifying uname & pwd + * CURLOPT_USERPWD takes a string "username:password" + */ +bool ro_gui_401login_apply(wimp_w w) +{ + struct session_401 *session; + char *auth; + + session = (struct session_401 *)ro_gui_wimp_event_get_user_data(w); + + assert(session); + + auth = malloc(strlen(session->uname) + strlen(session->pwd) + 2); + if (!auth) { + LOG("calloc failed"); + ro_warn_user("NoMemory", 0); + return false; + } + + sprintf(auth, "%s:%s", session->uname, session->pwd); + + urldb_set_auth_details(session->url, session->realm, auth); + + free(auth); + + session->cb(true, session->cbpw); + + /* Flag that we sent response by invalidating callback details */ + session->cb = NULL; + session->cbpw = NULL; + + return true; +} + diff --git a/frontends/riscos/Makefile b/frontends/riscos/Makefile new file mode 100644 index 000000000..6ed076800 --- /dev/null +++ b/frontends/riscos/Makefile @@ -0,0 +1,153 @@ +# +# Makefile for NetSurf RISC OS target +# +# This file is part of NetSurf + +# ---------------------------------------------------------------------------- +# RISC OS target setup +# ---------------------------------------------------------------------------- + +$(eval $(call pkg_config_find_and_add,libcares,Cares)) + +$(eval $(call feature_enabled,DRAW,-DWITH_DRAW,,Drawfile rendering)) +$(eval $(call feature_enabled,SPRITE,-DWITH_SPRITE,,Sprite rendering)) +$(eval $(call feature_enabled,ARTWORKS,-DWITH_ARTWORKS,,ArtWorks rendering)) +$(eval $(call feature_enabled,DRAW_EXPORT,-DWITH_DRAW_EXPORT,-lpencil,Drawfile export)) + + +TPD_RISCOS = $(foreach TPL,$(notdir $(TPL_RISCOS)), \ + !NetSurf/Resources/$(TPL)/Templates$(TPLEXT)) + +RESOURCES = $(TPD_RISCOS) + +CFLAGS += -Driscos -std=c99 -D_BSD_SOURCE -D_POSIX_C_SOURCE \ + -mpoke-function-name -fno-strict-aliasing + +CFLAGS += -I$(GCCSDK_INSTALL_ENV)/include +ifeq ($(HOST),riscos) + CFLAGS += -I<OSLib$$Dir> -mthrowback +endif +ASFLAGS += -xassembler-with-cpp -I. -I$(GCCSDK_INSTALL_ENV)/include +LDFLAGS += -L$(GCCSDK_INSTALL_ENV)/lib -lrufl +ifeq ($(HOST),riscos) + LDFLAGS += -LOSLib: -lOSLib32 +else + LDFLAGS += -lOSLib32 + ifeq ($(SUBTARGET),-elf) + # Go for static builds & AIF binary at the moment: + CFLAGS += -static + LDFLAGS += -static + EXEEXT := ,ff8 + endif +endif + +# ---------------------------------------------------------------------------- +# Source file setup +# ---------------------------------------------------------------------------- + +# S_RISCOS are sources purely for the RISC OS build +S_FRONTEND := 401login.c assert.c bitmap.c buffer.c cookies.c configure.c \ + dialog.c download.c filetype.c font.c \ + global_history.c gui.c help.c history.c hotlist.c iconbar.c \ + image.c menus.c message.c mouse.c palettes.c plotters.c \ + print.c query.c save.c save_draw.c save_pdf.c schedule.c \ + search.c searchweb.c sslcert.c textarea.c \ + textselection.c theme.c theme_install.c toolbar.c \ + treeview.c ucstables.c uri.c url_complete.c url_protocol.c \ + url_suggest.c wimp.c wimp_event.c window.c \ + $(addprefix content-handlers/,artworks.c awrender.s draw.c \ + sprite.c) \ + $(addprefix gui/,button_bar.c progress_bar.c status_bar.c \ + throbber.c url_bar.c) \ + $(addprefix configure/,con_cache.c con_connect.c con_content.c \ + con_fonts.c con_home.c con_image.c con_inter.c con_language.c \ + con_secure.c con_theme.c) + +# This is the final source build list +# Note this is deliberately *not* expanded here as common and image +# are not yet available +SOURCES = $(S_COMMON) $(S_IMAGE) $(S_BROWSER) $(S_FRONTEND) + +EXETARGET := !NetSurf/!RunImage$(EXEEXT) + +# The filter and target for split messages +MESSAGES_FILTER=ro + +!NetSurf/!Run$(RUNEXT): $(FRONTEND_SOURCE_DIR)/scripts/Run $(EXETARGET) + $(VQ)echo " MAKERUN: $@" + $(Q)$(MAKERUN) $(EXETARGET) $< $@ + +!NetSurf/!Help$(RUNEXT): $(FRONTEND_SOURCE_DIR)/scripts/Help + $(VQ)echo " CP: $@" + $(Q)cp $< $@ + +$(DEPROOT)/squeeze.d: $(EXETARGET) + $(VQ)echo " SQUEEZE: $<" + $(Q)$(SQUEEZE) -f -v $(EXETARGET) + $(Q)$(TOUCH) $@ + +POSTEXES += !NetSurf/!Run$(RUNEXT) !NetSurf/!Help$(RUNEXT) $(DEPROOT)/squeeze.d + + +clean-run: + $(VQ)echo " CLEAN: !NetSurf/!Run$(RUNEXT)" + $(Q) $(RM) !NetSurf/!Run$(RUNEXT) + +clean-help: + $(VQ)echo " CLEAN: !NetSurf/!Help$(RUNEXT)" + $(Q) $(RM) !NetSurf/!Help$(RUNEXT) + +CLEANS += clean-run clean-help + +# ---------------------------------------------------------------------------- +# Template targets +# ---------------------------------------------------------------------------- + +# Template objects +TPL_RISCOS := de en fr nl # TODO: It'd be nice to auto-detect these +TPL_RISCOS := $(addprefix $(FRONTEND_SOURCE_DIR)/templates/,$(TPL_RISCOS)) + +# Template target creation macro +define compile_template +!NetSurf/Resources/$(1)/Templates$$(TPLEXT): $(2) + $$(VQ)echo "TEMPLATE: $(2)" + $$(Q)mkdir -p !NetSurf/Resources/$(1) + $$(Q)$$(CC) -x c -E -P $$(CFLAGS) $(2) | $$(CCRES) - $$@ + +CLEAN_TEMPLATES += !NetSurf/Resources/$(1)/Templates$$(TPLEXT) + +endef + +$(eval $(foreach TPL,$(TPL_RISCOS), \ + $(call compile_template,$(notdir $(TPL)),$(TPL)))) + +clean-templates: + $(VQ)echo " CLEAN: $(CLEAN_TEMPLATES)" + $(Q)$(RM) $(CLEAN_TEMPLATES) +CLEANS += clean-templates + + +# ---------------------------------------------------------------------------- +# Install target +# ---------------------------------------------------------------------------- + +install-riscos: + +# ---------------------------------------------------------------------------- +# Package target +# ---------------------------------------------------------------------------- + +package-riscos: netsurf.zip + +netsurf.zip: $(EXETARGET) + $(eval $@_TMPDIR := $(shell mktemp -d)) + $(Q) $(RM) $@ + $(Q) rsync --archive --verbose $(CURDIR)/!NetSurf $($@_TMPDIR) + $(Q) $(CURDIR)/utils/git-date.sh $(FRONTEND_SOURCE_DIR)/distribution + $(Q) rsync --archive --verbose $(FRONTEND_SOURCE_DIR)/distribution/!Boot $($@_TMPDIR) + $(Q) rsync --archive --verbose $(FRONTEND_SOURCE_DIR)/distribution/!System $($@_TMPDIR) + $(Q) rsync --archive --verbose $(FRONTEND_SOURCE_DIR)/distribution/3rdParty $($@_TMPDIR) + $(Q) cp $(FRONTEND_SOURCE_DIR)/distribution/ReadMe $($@_TMPDIR) + $(Q) cp $(FRONTEND_SOURCE_DIR)/distribution/LeesMij $($@_TMPDIR) + $(Q) cd $($@_TMPDIR) && /opt/netsurf/arm-unknown-riscos/env/bin/zip -9vr\, $(CURDIR)/$@ * + $(Q) $(RM) -rf $($@_TMPDIR) diff --git a/frontends/riscos/Makefile.defaults b/frontends/riscos/Makefile.defaults new file mode 100644 index 000000000..aed361631 --- /dev/null +++ b/frontends/riscos/Makefile.defaults @@ -0,0 +1,37 @@ +# ---------------------------------------------------------------------------- +# RISC OS-specific options +# ---------------------------------------------------------------------------- + +# Enable NetSurf's use of libsvgtiny for displaying SVGs +# Valid options: YES, NO +NETSURF_USE_NSSVG := YES + +# Enable NetSurf's support for displaying RISC OS Draw files +# Valid options: YES, NO +NETSURF_USE_DRAW := YES + +# Enable NetSurf's support for displaying RISC OS Sprites +# Valid options: YES, NO +NETSURF_USE_SPRITE := YES + +# Enable NetSurf's use of librosprite for displaying RISC OS Sprites +# Valid options: YES, NO, AUTO +NETSURF_USE_ROSPRITE := NO + +# Enable NetSurf's use of AWRender for displaying ArtWorks files +# Valid options: YES, NO +NETSURF_USE_ARTWORKS := YES + +# Enable NetSurf's support for the Acorn plugin protocol +# Valid options: YES, NO +NETSURF_USE_PLUGINS := NO + +# Enable NetSurf's use of pencil for Drawfile export +# Valid options: YES, NO +NETSURF_USE_DRAW_EXPORT := YES + +# Enable building the source object cache filesystem based backing store. +NETSURF_FS_BACKING_STORE := YES + +# Optimisation levels +CFLAGS += -O2 diff --git a/frontends/riscos/assert.c b/frontends/riscos/assert.c new file mode 100644 index 000000000..50b8f5d54 --- /dev/null +++ b/frontends/riscos/assert.c @@ -0,0 +1,44 @@ +/* + * Copyright 2005 James Bursa <bursa@users.sourceforge.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Assert reporting (RISC OS implementation). + */ + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include "oslib/wimp.h" + + +/** + * Report an assert() failure and exit. + */ + +void __assert2(const char *expr, const char *function, const char *file, + int line) +{ + fprintf(stderr, "\n\"%s\", line %d: %s%sAssertion failed: %s\n", + file, line, + function ? function : "", + function ? ": " : "", + expr); + fflush(stderr); + + abort(); +} diff --git a/frontends/riscos/bitmap.c b/frontends/riscos/bitmap.c new file mode 100644 index 000000000..cc4be590c --- /dev/null +++ b/frontends/riscos/bitmap.c @@ -0,0 +1,876 @@ +/* + * Copyright 2004 James Bursa <bursa@users.sourceforge.net> + * Copyright 2005 Richard Wilson <info@tinct.net> + * Copyright 2008 Adrian Lees <adrianl@users.sourceforge.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * \file + * RISC OS implementation of bitmap operations. + * + * This implements the interface given by image/bitmap.h using RISC OS + * sprites. + */ + +#include <assert.h> +#include <stdbool.h> +#include <string.h> +#include <swis.h> +#include <rufl.h> +#include <unixlib/local.h> +#include <oslib/colourtrans.h> +#include <oslib/osfile.h> +#include <oslib/osfind.h> +#include <oslib/osgbpb.h> +#include <oslib/osspriteop.h> +#include <oslib/wimp.h> + +#include "utils/nsoption.h" +#include "utils/filename.h" +#include "utils/log.h" +#include "utils/messages.h" +#include "desktop/plotters.h" +#include "content/content.h" +#include "image/bitmap.h" + +#include "riscos/gui.h" +#include "riscos/image.h" +#include "riscos/palettes.h" +#include "riscos/content-handlers/sprite.h" +#include "riscos/tinct.h" +#include "riscos/bitmap.h" + +/** Colour in the overlay sprite that allows the bitmap to show through */ +#define OVERLAY_INDEX 0xfe + +/** Size of buffer used when constructing mask data to be saved */ +#define SAVE_CHUNK_SIZE 4096 + +/** + * Whether we can use 32bpp sprites + */ +static int thumbnail_32bpp_available = -1; + +/** + * Sprite output context saving + */ +struct thumbnail_save_area { + osspriteop_save_area *save_area; + int context1; + int context2; + int context3; +}; + +/** + * Initialise a bitmaps sprite area. + * + * \param bitmap the bitmap to initialise + * \return true if bitmap initialised else false. + */ + +static bool bitmap_initialise(struct bitmap *bitmap) +{ + unsigned int area_size; + osspriteop_area *sprite_area; + osspriteop_header *sprite; + + assert(!bitmap->sprite_area); + + area_size = 16 + 44 + bitmap->width * bitmap->height * 4; + if (bitmap->state & BITMAP_CLEAR_MEMORY) + bitmap->sprite_area = calloc(1, area_size); + else + bitmap->sprite_area = malloc(area_size); + + if (!bitmap->sprite_area) + return false; + + /* area control block */ + sprite_area = bitmap->sprite_area; + sprite_area->size = area_size; + sprite_area->sprite_count = 1; + sprite_area->first = 16; + sprite_area->used = area_size; + + /* sprite control block */ + sprite = (osspriteop_header *) (sprite_area + 1); + sprite->size = area_size - 16; + memset(sprite->name, 0x00, 12); + strncpy(sprite->name, "bitmap", 12); + sprite->width = bitmap->width - 1; + sprite->height = bitmap->height - 1; + sprite->left_bit = 0; + sprite->right_bit = 31; + sprite->image = sprite->mask = 44; + sprite->mode = tinct_SPRITE_MODE; + + return true; +} + + +/* exported interface documented in riscos/bitmap.h */ +void *riscos_bitmap_create(int width, int height, unsigned int state) +{ + struct bitmap *bitmap; + + if (width == 0 || height == 0) + return NULL; + + bitmap = calloc(1, sizeof(struct bitmap)); + if (!bitmap) + return NULL; + bitmap->width = width; + bitmap->height = height; + bitmap->state = state; + + return bitmap; +} + + +/* exported interface documented in riscos/bitmap.h */ +unsigned char *riscos_bitmap_get_buffer(void *vbitmap) +{ + struct bitmap *bitmap = (struct bitmap *) vbitmap; + assert(bitmap); + + /* dynamically create the buffer */ + if (bitmap->sprite_area == NULL) { + if (!bitmap_initialise(bitmap)) + return NULL; + } + + /* image data area should exist */ + if (bitmap->sprite_area) + return ((unsigned char *) (bitmap->sprite_area)) + 16 + 44; + + return NULL; +} + + +/** + * Sets whether a bitmap should be plotted opaque + * + * \param vbitmap a bitmap, as returned by bitmap_create() + * \param opaque whether the bitmap should be plotted opaque + */ +static void bitmap_set_opaque(void *vbitmap, bool opaque) +{ + struct bitmap *bitmap = (struct bitmap *) vbitmap; + assert(bitmap); + + if (opaque) + bitmap->state |= BITMAP_OPAQUE; + else + bitmap->state &= ~BITMAP_OPAQUE; +} + + +/** + * Find the width of a pixel row in bytes. + * + * \param vbitmap A bitmap, as returned by riscos_bitmap_create() + * \return width of a pixel row in the bitmap + */ +static size_t bitmap_get_rowstride(void *vbitmap) +{ + struct bitmap *bitmap = (struct bitmap *) vbitmap; + return bitmap->width * 4; +} + + +/** + * Tests whether a bitmap has an opaque alpha channel + * + * \param vbitmap a bitmap, as returned by bitmap_create() + * \return whether the bitmap is opaque + */ +static bool bitmap_test_opaque(void *vbitmap) +{ + struct bitmap *bitmap = (struct bitmap *) vbitmap; + unsigned char *sprite; + unsigned int width, height, size; + osspriteop_header *sprite_header; + unsigned *p, *ep; + + assert(bitmap); + + sprite = riscos_bitmap_get_buffer(bitmap); + if (!sprite) + return false; + + width = bitmap_get_rowstride(bitmap); + + sprite_header = (osspriteop_header *) (bitmap->sprite_area + 1); + + height = (sprite_header->height + 1); + + size = width * height; + + p = (void *) sprite; + + ep = (void *) (sprite + (size & ~31)); + while (p < ep) { + /* \todo prefetch(p, 128)? */ + if (((p[0] & p[1] & p[2] & p[3] & p[4] & p[5] & p[6] & p[7]) + & 0xff000000U) != 0xff000000U) + return false; + p += 8; + } + + ep = (void *) (sprite + size); + while (p < ep) { + if ((*p & 0xff000000U) != 0xff000000U) return false; + p++; + } + + return true; +} + + +/* exported interface documented in riscos/bitmap.h */ +bool riscos_bitmap_get_opaque(void *vbitmap) +{ + struct bitmap *bitmap = (struct bitmap *) vbitmap; + assert(bitmap); + return (bitmap->state & BITMAP_OPAQUE); +} + + +/* exported interface documented in riscos/bitmap.h */ +void riscos_bitmap_destroy(void *vbitmap) +{ + struct bitmap *bitmap = (struct bitmap *) vbitmap; + + assert(bitmap); + + /* destroy bitmap */ + if (bitmap->sprite_area) { + free(bitmap->sprite_area); + } + + free(bitmap); +} + + +/* exported interface documented in riscos/bitmap.h */ +bool riscos_bitmap_save(void *vbitmap, const char *path, unsigned flags) +{ + struct bitmap *bitmap = (struct bitmap *) vbitmap; + os_error *error; + + if (bitmap == NULL) { + ro_warn_user("SaveError", messages_get("SprIsNull")); + return false; + } + + if (!bitmap->sprite_area) { + riscos_bitmap_get_buffer(bitmap); + } + if (!bitmap->sprite_area) + return false; + + if (riscos_bitmap_get_opaque(bitmap)) { + error = xosspriteop_save_sprite_file(osspriteop_USER_AREA, + (bitmap->sprite_area), path); + if (error) { + LOG("xosspriteop_save_sprite_file: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("SaveError", error->errmess); + return false; + } + return true; + } else { + /* to make the saved sprite useful we must convert from 'Tinct' + * format to either a bi-level mask or a Select-style full + * alpha channel */ + osspriteop_area *area = bitmap->sprite_area; + osspriteop_header *hdr = (void *) ((char *) area + area->first); + unsigned width = hdr->width + 1, height = hdr->height + 1; + unsigned image_size = height * width * 4; + unsigned char *chunk_buf; + unsigned *p, *elp, *eip; + unsigned mask_size; + size_t chunk_pix; + struct { + osspriteop_area area; + osspriteop_header hdr; + } file_hdr; + os_fw fw; + + /* we only support 32bpp sprites */ + if ((((unsigned)hdr->mode >> 27)&15) != 6) { + assert(!"Unsupported sprite format in bitmap_save"); + return false; + } + + chunk_buf = malloc(SAVE_CHUNK_SIZE); + if (!chunk_buf) { + ro_warn_user("NoMemory", NULL); + return false; + } + + file_hdr.area = *area; + file_hdr.hdr = *hdr; + + if (flags & BITMAP_SAVE_FULL_ALPHA) { + mask_size = ((width + 3) & ~3) * height; + chunk_pix = SAVE_CHUNK_SIZE; + file_hdr.hdr.mode = (os_mode)((unsigned)file_hdr.hdr.mode + | (1U<<31)); + } else { + mask_size = (((width + 31) & ~31)/8) * height; + chunk_pix = SAVE_CHUNK_SIZE<<3; + file_hdr.hdr.mode = (os_mode)((unsigned)file_hdr.hdr.mode + & ~(1U<<31)); + } + + file_hdr.area.sprite_count = 1; + file_hdr.area.first = sizeof(file_hdr.area); + file_hdr.area.used = sizeof(file_hdr) + image_size + mask_size; + + file_hdr.hdr.image = sizeof(file_hdr.hdr); + file_hdr.hdr.mask = file_hdr.hdr.image + image_size; + file_hdr.hdr.size = file_hdr.hdr.mask + mask_size; + + error = xosfind_openoutw(0, path, NULL, &fw); + if (error) { + LOG("xosfind_openoutw: 0x%x: %s", error->errnum, error->errmess); + free(chunk_buf); + ro_warn_user("SaveError", error->errmess); + return false; + } + + p = (void *) ((char *) hdr + hdr->image); + + /* write out the area header, sprite header and image data */ + error = xosgbpb_writew(fw, (byte*)&file_hdr + 4, + sizeof(file_hdr)-4, NULL); + if (!error) + error = xosgbpb_writew(fw, (byte*)p, image_size, NULL); + if (error) { + LOG("xosgbpb_writew: 0x%x: %s", error->errnum, error->errmess); + free(chunk_buf); + xosfind_closew(fw); + ro_warn_user("SaveError", error->errmess); + return false; + } + + /* then write out the mask data in chunks */ + eip = p + (width * height); /* end of image */ + elp = p + width; /* end of line */ + + while (p < eip) { + unsigned char *dp = chunk_buf; + unsigned *ep = p + chunk_pix; + if (ep > elp) ep = elp; + + if (flags & BITMAP_SAVE_FULL_ALPHA) { + while (p < ep) { + *dp++ = ((unsigned char*)p)[3]; + p++; + } + } + else { + unsigned char mb = 0; + int msh = 0; + while (p < ep) { + if (((unsigned char*)p)[3]) mb |= (1 << msh); + if (++msh >= 8) { + *dp++ = mb; + msh = 0; + mb = 0; + } + p++; + } + if (msh > 0) *dp++ = mb; + } + + if (p >= elp) { /* end of line yet? */ + /* align to word boundary */ + while ((int)dp & 3) *dp++ = 0; + /* advance end of line pointer */ + elp += width; + } + error = xosgbpb_writew(fw, (byte*)chunk_buf, dp-chunk_buf, NULL); + if (error) { + LOG("xosgbpb_writew: 0x%x: %s", error->errnum, error->errmess); + free(chunk_buf); + xosfind_closew(fw); + ro_warn_user("SaveError", error->errmess); + return false; + } + } + + error = xosfind_closew(fw); + if (error) { + LOG("xosfind_closew: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("SaveError", error->errmess); + } + + error = xosfile_set_type(path, osfile_TYPE_SPRITE); + if (error) { + LOG("xosfile_set_type: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("SaveError", error->errmess); + } + + free(chunk_buf); + return true; + } +} + + +/** + * The bitmap image has changed, so flush any persistent cache. + * + * \param vbitmap a bitmap, as returned by bitmap_create() + */ +static void bitmap_modified(void *vbitmap) +{ + struct bitmap *bitmap = (struct bitmap *) vbitmap; + bitmap->state |= BITMAP_MODIFIED; +} + + +/** + * Get the width of a bitmap. + * + * \param vbitmap A bitmap, as returned by bitmap_create() + * \return The bitmaps width in pixels. + */ +static int bitmap_get_width(void *vbitmap) +{ + struct bitmap *bitmap = (struct bitmap *) vbitmap; + return bitmap->width; +} + + +/** + * Get the height of a bitmap. + * + * \param vbitmap A bitmap, as returned by bitmap_create() + * \return The bitmaps height in pixels. + */ +static int bitmap_get_height(void *vbitmap) +{ + struct bitmap *bitmap = (struct bitmap *) vbitmap; + return bitmap->height; +} + + +/** + * Find the bytes per pixel of a bitmap + * + * \param vbitmap a bitmap, as returned by bitmap_create() + * \return bytes per pixel + */ +static size_t bitmap_get_bpp(void *vbitmap) +{ + struct bitmap *bitmap = (struct bitmap *)vbitmap; + assert(bitmap); + return 4; +} + + +/* exported interface documented in riscos/bitmap.h */ +void riscos_bitmap_overlay_sprite(struct bitmap *bitmap, + const osspriteop_header *s) +{ + const os_colour *palette; + const byte *sp, *mp; + bool masked = false; + bool alpha = false; + os_error *error; + int dp_offset; + int sp_offset; + unsigned *dp; + int x, y; + int w, h; + + assert(sprite_bpp(s) == 8); + + if ((unsigned)s->mode & 0x80000000U) + alpha = true; + + error = xosspriteop_read_sprite_info(osspriteop_PTR, + (osspriteop_area *)0x100, + (osspriteop_id)s, + &w, &h, NULL, NULL); + if (error) { + LOG("xosspriteop_read_sprite_info: 0x%x:%s", error->errnum, error->errmess); + return; + } + sp_offset = ((s->width + 1) * 4) - w; + + if (w > bitmap->width) + w = bitmap->width; + if (h > bitmap->height) + h = bitmap->height; + + dp_offset = bitmap_get_rowstride(bitmap) / 4; + + dp = (void*)riscos_bitmap_get_buffer(bitmap); + if (!dp) + return; + sp = (byte*)s + s->image; + mp = (byte*)s + s->mask; + + sp += s->left_bit / 8; + mp += s->left_bit / 8; + + if (s->image > (int)sizeof(*s)) + palette = (os_colour*)(s + 1); + else + palette = default_palette8; + + if (s->mask != s->image) { + masked = true; + bitmap_set_opaque(bitmap, false); + } + + /* (partially-)transparent pixels in the overlayed sprite retain + * their transparency in the output bitmap; opaque sprite pixels + * are also propagated to the bitmap, except those which are the + * OVERLAY_INDEX colour which allow the original bitmap contents to + * show through */ + for (y = 0; y < h; y++) { + unsigned *sdp = dp; + for(x = 0; x < w; x++) { + os_colour d = ((unsigned)palette[(*sp) << 1]) >> 8; + if (*sp++ == OVERLAY_INDEX) + d = *dp; + if (masked) { + if (alpha) + d |= ((*mp << 24) ^ 0xff000000U); + else if (*mp) + d |= 0xff000000U; + } + *dp++ = d; + mp++; + } + dp = sdp + dp_offset; + sp += sp_offset; + mp += sp_offset; + } +} + + +/** + * Creates an 8bpp canvas. + * + * \param bitmap the bitmap to clone the size of + * \return a sprite area containing an 8bpp sprite + */ +static osspriteop_area *thumbnail_create_8bpp(struct bitmap *bitmap) +{ + unsigned image_size = ((bitmap->width + 3) & ~3) * bitmap->height; + bool opaque = riscos_bitmap_get_opaque(bitmap); + osspriteop_header *sprite_header = NULL; + osspriteop_area *sprite_area = NULL; + unsigned area_size; + + /* clone the sprite */ + area_size = sizeof(osspriteop_area) + + sizeof(osspriteop_header) + + image_size + + 2048; + + if (!opaque) area_size += image_size; + + sprite_area = (osspriteop_area *)malloc(area_size); + if (!sprite_area) { + LOG("no memory for malloc()"); + return NULL; + } + sprite_area->size = area_size; + sprite_area->sprite_count = 1; + sprite_area->first = 16; + sprite_area->used = area_size; + sprite_header = (osspriteop_header *)(sprite_area + 1); + sprite_header->size = area_size - sizeof(osspriteop_area); + memset(sprite_header->name, 0x00, 12); + strcpy(sprite_header->name, "bitmap"); + sprite_header->left_bit = 0; + sprite_header->height = bitmap->height - 1; + sprite_header->mode = os_MODE8BPP90X90; + sprite_header->right_bit = ((bitmap->width << 3) - 1) & 31; + sprite_header->width = ((bitmap->width + 3) >> 2) - 1; + sprite_header->image = sizeof(osspriteop_header) + 2048; + sprite_header->mask = sizeof(osspriteop_header) + 2048; + if (!opaque) sprite_header->mask += image_size; + + /* create the palette. we don't read the necessary size like + * we really should as we know it's going to have 256 entries + * of 8 bytes = 2048. */ + xcolourtrans_read_palette((osspriteop_area *)os_MODE8BPP90X90, + (osspriteop_id)0, + (os_palette *)(sprite_header + 1), 2048, + (colourtrans_palette_flags)(1 << 1), 0); + return sprite_area; +} + + +/** + * Switches output to the specified sprite and returns the previous context. + */ +static struct thumbnail_save_area* +thumbnail_switch_output(osspriteop_area *sprite_area, + osspriteop_header *sprite_header) +{ + struct thumbnail_save_area *save_area; + int size; + + /* create a save area */ + save_area = calloc(sizeof(struct thumbnail_save_area), 1); + if (save_area == NULL) return NULL; + + /* allocate OS_SpriteOp save area */ + if (xosspriteop_read_save_area_size(osspriteop_PTR, sprite_area, + (osspriteop_id)sprite_header, &size)) { + free(save_area); + return NULL; + } + + /* create the save area */ + save_area->save_area = malloc((unsigned)size); + if (save_area->save_area == NULL) { + free(save_area); + return NULL; + } + save_area->save_area->a[0] = 0; + + /* switch output to sprite */ + if (xosspriteop_switch_output_to_sprite(osspriteop_PTR, sprite_area, + (osspriteop_id)sprite_header, save_area->save_area, + 0, &save_area->context1, &save_area->context2, + &save_area->context3)) { + free(save_area->save_area); + free(save_area); + return NULL; + } + return save_area; +} + + +/** + * Restores output to the specified context, and destroys it. + */ +static void thumbnail_restore_output(struct thumbnail_save_area *save_area) +{ + /* we don't care if we err, as there's nothing we can do about it */ + xosspriteop_switch_output_to_sprite(osspriteop_PTR, + (osspriteop_area *)save_area->context1, + (osspriteop_id)save_area->context2, + (osspriteop_save_area *)save_area->context3, + 0, 0, 0, 0); + free(save_area->save_area); + free(save_area); +} + + +/** + * Convert a bitmap to 8bpp. + * + * \param bitmap the bitmap to convert + * \return a sprite area containing an 8bpp sprite + */ +osspriteop_area *riscos_bitmap_convert_8bpp(struct bitmap *bitmap) +{ + struct thumbnail_save_area *save_area; + osspriteop_area *sprite_area = NULL; + osspriteop_header *sprite_header = NULL; + + sprite_area = thumbnail_create_8bpp(bitmap); + if (!sprite_area) + return NULL; + sprite_header = (osspriteop_header *)(sprite_area + 1); + + + /* switch output and redraw */ + save_area = thumbnail_switch_output(sprite_area, sprite_header); + if (save_area == NULL) { + if (thumbnail_32bpp_available != 1) + free(sprite_area); + return false; + } + _swix(Tinct_Plot, _IN(2) | _IN(3) | _IN(4) | _IN(7), + (osspriteop_header *)(bitmap->sprite_area + 1), + 0, 0, + tinct_ERROR_DIFFUSE); + thumbnail_restore_output(save_area); + + if (sprite_header->image != sprite_header->mask) { + /* build the sprite mask from the alpha channel */ + void *buf = riscos_bitmap_get_buffer(bitmap); + unsigned *dp = (unsigned *) buf; + if (!dp) + return sprite_area; + int w = bitmap_get_width(bitmap); + int h = bitmap_get_height(bitmap); + int dp_offset = bitmap_get_rowstride(bitmap) / 4 - w; + int mp_offset = ((sprite_header->width + 1) * 4) - w; + byte *mp = (byte*)sprite_header + sprite_header->mask; + bool alpha = ((unsigned)sprite_header->mode & 0x80000000U) != 0; + + while (h-- > 0) { + int x = 0; + for(x = 0; x < w; x++) { + unsigned d = *dp++; + if (alpha) + *mp++ = (d >> 24) ^ 0xff; + else + *mp++ = (d < 0xff000000U) ? 0 : 0xff; + } + dp += dp_offset; + mp += mp_offset; + } + } + + return sprite_area; +} + + + + +/** + * Check to see whether 32bpp sprites are available. + * + * Rather than using Wimp_ReadSysInfo we test if 32bpp sprites are available + * in case the user has a 3rd party patch to enable them. + */ +static void thumbnail_test(void) +{ + unsigned int area_size; + osspriteop_area *sprite_area; + + /* try to create a 1x1 32bpp sprite */ + area_size = sizeof(osspriteop_area) + + sizeof(osspriteop_header) + sizeof(int); + if ((sprite_area = (osspriteop_area *)malloc(area_size)) == NULL) { + LOG("Insufficient memory to perform sprite test."); + return; + } + sprite_area->size = area_size + 1; + sprite_area->sprite_count = 0; + sprite_area->first = 16; + sprite_area->used = 16; + if (xosspriteop_create_sprite(osspriteop_NAME, sprite_area, + "test", false, 1, 1, (os_mode)tinct_SPRITE_MODE)) + thumbnail_32bpp_available = 0; + else + thumbnail_32bpp_available = 1; + free(sprite_area); +} + + +/* exported interface documented in riscos/bitmap.h */ +nserror riscos_bitmap_render(struct bitmap *bitmap, + struct hlcache_handle *content) +{ + struct thumbnail_save_area *save_area; + osspriteop_area *sprite_area = NULL; + osspriteop_header *sprite_header = NULL; + struct redraw_context ctx = { + .interactive = false, + .background_images = true, + .plot = &ro_plotters + }; + + assert(content); + assert(bitmap); + + LOG("content %p in bitmap %p", content, bitmap); + + /* check if we have access to 32bpp sprites natively */ + if (thumbnail_32bpp_available == -1) { + thumbnail_test(); + } + + /* if we don't support 32bpp sprites then we redirect to an 8bpp + * image and then convert back. + */ + if (thumbnail_32bpp_available != 1) { + sprite_area = thumbnail_create_8bpp(bitmap); + if (!sprite_area) + return false; + sprite_header = (osspriteop_header *)(sprite_area + 1); + } else { + const uint8_t *pixbufp = riscos_bitmap_get_buffer(bitmap); + if (!pixbufp || !bitmap->sprite_area) + return false; + sprite_area = bitmap->sprite_area; + sprite_header = (osspriteop_header *)(sprite_area + 1); + } + + /* set up the plotters */ + ro_plot_origin_x = 0; + ro_plot_origin_y = bitmap->height * 2; + + /* switch output and redraw */ + save_area = thumbnail_switch_output(sprite_area, sprite_header); + if (!save_area) { + if (thumbnail_32bpp_available != 1) + free(sprite_area); + return false; + } + rufl_invalidate_cache(); + colourtrans_set_gcol(os_COLOUR_WHITE, colourtrans_SET_BG_GCOL, + os_ACTION_OVERWRITE, 0); + + /* render the content */ + content_scaled_redraw(content, bitmap->width, bitmap->height, &ctx); + + thumbnail_restore_output(save_area); + rufl_invalidate_cache(); + + /* if we changed to 8bpp then go back to 32bpp */ + if (thumbnail_32bpp_available != 1) { + const uint8_t *pixbufp = riscos_bitmap_get_buffer(bitmap); + _kernel_oserror *error; + + if (!pixbufp || !bitmap->sprite_area) { + free(sprite_area); + return false; + } + error = _swix(Tinct_ConvertSprite, _INR(2,3), + sprite_header, + (osspriteop_header *)(bitmap->sprite_area + 1)); + free(sprite_area); + if (error) + return false; + } + + bitmap_modified(bitmap); + + return NSERROR_OK; +} + +static struct gui_bitmap_table bitmap_table = { + .create = riscos_bitmap_create, + .destroy = riscos_bitmap_destroy, + .set_opaque = bitmap_set_opaque, + .get_opaque = riscos_bitmap_get_opaque, + .test_opaque = bitmap_test_opaque, + .get_buffer = riscos_bitmap_get_buffer, + .get_rowstride = bitmap_get_rowstride, + .get_width = bitmap_get_width, + .get_height = bitmap_get_height, + .get_bpp = bitmap_get_bpp, + .save = riscos_bitmap_save, + .modified = bitmap_modified, + .render = riscos_bitmap_render, +}; + +struct gui_bitmap_table *riscos_bitmap_table = &bitmap_table; diff --git a/frontends/riscos/bitmap.h b/frontends/riscos/bitmap.h new file mode 100644 index 000000000..3aca30de6 --- /dev/null +++ b/frontends/riscos/bitmap.h @@ -0,0 +1,116 @@ +/* + * Copyright 2004 James Bursa <bursa@users.sourceforge.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _NETSURF_RISCOS_BITMAP_H_ +#define _NETSURF_RISCOS_BITMAP_H_ + +struct osspriteop_area; +struct osspriteop_header; +struct hlcache_handle; +struct bitmap; + +/** bitmap operations table */ +struct gui_bitmap_table *riscos_bitmap_table; + +/** save with full alpha channel (if not opaque) */ +#define BITMAP_SAVE_FULL_ALPHA (1 << 0) + +/** + * RISC OS wimp toolkit bitmap. + */ +struct bitmap { + int width; /**< width of bitmap */ + int height; /**< height of bitmap */ + + unsigned int state; /**< The bitmap attributes (opaque/dirty etc.) */ + + struct osspriteop_area *sprite_area; /**< Uncompressed data, or NULL */ +}; + +/** + * Convert bitmap to 8bpp sprite. + * + * \param bitmap the bitmap to convert. + * \return The converted sprite. + */ +struct osspriteop_area *riscos_bitmap_convert_8bpp(struct bitmap *bitmap); + +/** + * Render content into bitmap. + * + * \param bitmap the bitmap to draw to + * \param content content structure to render + * \return true on success and bitmap updated else false + */ +nserror riscos_bitmap_render(struct bitmap *bitmap, struct hlcache_handle *content); + +/** + * Overlay a sprite onto the given bitmap + * + * \param bitmap bitmap object + * \param s 8bpp sprite to be overlayed onto bitmap + */ +void riscos_bitmap_overlay_sprite(struct bitmap *bitmap, const struct osspriteop_header *s); + +/** + * Create a bitmap. + * + * \param width width of image in pixels + * \param height width of image in pixels + * \param state the state to create the bitmap in. + * \return an opaque struct bitmap, or NULL on memory exhaustion + */ +void *riscos_bitmap_create(int width, int height, unsigned int state); + +/** + * Free a bitmap. + * + * \param vbitmap a bitmap, as returned by bitmap_create() + */ +void riscos_bitmap_destroy(void *vbitmap); + +/** + * Return a pointer to the pixel data in a bitmap. + * + * The pixel data is packed as BITMAP_FORMAT, possibly with padding at + * the end of rows. The width of a row in bytes is given by + * riscos_bitmap_get_rowstride(). + * + * \param vbitmap A bitmap as returned by riscos_bitmap_create() + * \return pointer to the pixel buffer + */ +unsigned char *riscos_bitmap_get_buffer(void *vbitmap); + +/** + * Gets whether a bitmap should be plotted opaque + * + * \param vbitmap A bitmap, as returned by riscos_bitmap_create() + */ +bool riscos_bitmap_get_opaque(void *vbitmap); + +/** + * Save a bitmap in the platform's native format. + * + * \param vbitmap a bitmap, as returned by bitmap_create() + * \param path pathname for file + * \param flags modify the behaviour of the save + * \return true on success, false on error and error reported + */ +bool riscos_bitmap_save(void *vbitmap, const char *path, unsigned flags); + +#endif diff --git a/frontends/riscos/buffer.c b/frontends/riscos/buffer.c new file mode 100644 index 000000000..7176c1c1c --- /dev/null +++ b/frontends/riscos/buffer.c @@ -0,0 +1,396 @@ +/* + * Copyright 2004, 2005 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> +#include <swis.h> +#include <oslib/colourtrans.h> +#include <oslib/os.h> +#include <oslib/osspriteop.h> +#include <oslib/wimp.h> +#include <oslib/wimpreadsysinfo.h> + +#include "utils/nsoption.h" +#include "utils/log.h" + +#include "riscos/buffer.h" +#include "riscos/gui.h" +#include "riscos/tinct.h" +#include "riscos/wimp.h" +#include "riscos/wimputils.h" + +#define BUFFER_EXCLUSIVE_USER_REDRAW "Only support pure user redraw (faster)" +//#define BUFFER_EMULATE_32BPP "Redirect to a 32bpp sprite and plot with Tinct" + +/** Absent from OSLib +*/ +#ifndef osspriteop_TYPEEXPANSION +#define osspriteop_TYPEEXPANSION ((osspriteop_mode_word) 0xFu) +#endif +#ifndef osspriteop_TYPE16BPP4K +#define osspriteop_TYPE16BPP4K ((osspriteop_mode_word) 0x10u) +#endif + +static void ro_gui_buffer_free(void); + + +/** The buffer characteristics +*/ +static osspriteop_area *buffer = NULL; +static char buffer_name[12] = "scr_buffer"; + +/** The current clip area +*/ +static os_box clipping; + +/** The current save area +*/ +static osspriteop_save_area *save_area; +static int context0; +static int context1; +static int context2; +static int context3; + +/** The current sprite mode +*/ +static os_mode mode; + + +/** + * Opens a buffer for writing to. + * + * The ro_plot_origin_ variables are updated to reflect the new screen origin, + * so the variables should be set before calling this function, and not + * changed until after ro_gui_buffer_close() has been called. + * + * \param redraw the current WIMP redraw area to buffer + */ +void ro_gui_buffer_open(wimp_draw *redraw) +{ + int size; + int total_size; + os_coord sprite_size; + int bpp, word_width; + bool palette; + os_error *error; + int palette_size = 0; +#ifdef BUFFER_EXCLUSIVE_USER_REDRAW + osspriteop_header *header; +#endif + + /* Close any open buffer + */ + if (buffer) + ro_gui_buffer_close(); + + /* Store our clipping region + */ + clipping = redraw->clip; + + /* Stop bad rectangles + */ + if ((clipping.x1 < clipping.x0) || + (clipping.y1 < clipping.y0)) { + LOG("Invalid clipping rectangle (%i, %i) to (%i,%i)", clipping.x0, clipping.y0, clipping.x1, clipping.y1); + return; + } + + /* Work out how much buffer we need + */ + sprite_size.x = clipping.x1 - clipping.x0 + 1; + sprite_size.y = clipping.y1 - clipping.y0 + 1; + ro_convert_os_units_to_pixels(&sprite_size, (os_mode)-1); + if (sprite_size.y == 1) /* work around SpriteExtend bug */ + sprite_size.y = 2; + +#ifdef BUFFER_EMULATE_32BPP + bpp = 5; + palette = false; +#else + /* Get the screen depth as we can't use palettes for >8bpp + */ + xos_read_mode_variable((os_mode)-1, os_MODEVAR_LOG2_BPP, &bpp, 0); + palette = (bpp < 4); +#endif + + /* Get our required buffer size + */ + word_width = ((sprite_size.x << bpp) + 31) >> 5; + if (palette) + palette_size = ((1 << (1 << bpp)) << 3); + total_size = sizeof(osspriteop_area) + sizeof(osspriteop_header) + + (word_width * sprite_size.y * 4) + palette_size; + buffer = (osspriteop_area *)malloc(total_size); + if (!buffer) { + LOG("Failed to allocate memory"); + ro_gui_buffer_free(); + return; + } + buffer->size = total_size; + buffer->first = 16; + +#ifdef BUFFER_EMULATE_32BPP + mode = tinct_SPRITE_MODE; +#else + if ((error = xwimpreadsysinfo_wimp_mode(&mode)) != NULL) { + LOG("Error reading mode '%s'", error->errmess); + ro_gui_buffer_free(); + return; + } + + /* if we're not in a numbered screen mode then we need + to build a suitable sprite mode word */ + if (mode >= (os_mode)0x100) { + static const ns_os_vdu_var_list vars = { + os_MODEVAR_LOG2_BPP, + { + os_MODEVAR_MODE_FLAGS, + os_MODEVAR_NCOLOUR, + os_MODEVAR_XEIG_FACTOR, + os_MODEVAR_YEIG_FACTOR, + os_VDUVAR_END_LIST + } + }; + struct { + int log2bpp; + int flags; + int ncolour; + int xeig, yeig; + } vals; + int type; + + error = xos_read_vdu_variables(PTR_OS_VDU_VAR_LIST(&vars), (int *)&vals); + if (error) { + LOG("Error reading mode properties '%s'", error->errmess); + ro_gui_buffer_free(); + return; + } + + switch (vals.ncolour) { + case 1: + case 3: + case 15: + case 63: + case 255: + /* Paletted modes are pixel packing order agnostic */ + type = 1 + vals.log2bpp; + mode = (os_mode)((type << osspriteop_TYPE_SHIFT) | + osspriteop_NEW_STYLE | + ((180 >> vals.yeig) << osspriteop_YRES_SHIFT) | + ((180 >> vals.xeig) << osspriteop_XRES_SHIFT)); + break; + case 4095: + /* 16bpp 4k colours */ + type = osspriteop_TYPE16BPP4K; + mode = (os_mode)((osspriteop_TYPEEXPANSION << osspriteop_TYPE_SHIFT) | + osspriteop_NEW_STYLE | + (vals.yeig << 6) | + (vals.xeig << 4) | + (type << 20) | + (vals.flags & 0xFF00)); + break; + case 65535: + switch ((vals.flags & 0x3000) >> os_MODE_FLAG_DATA_FORMAT_SHIFT) { + case os_MODE_FLAG_DATA_FORMAT_RGB: + if (vals.flags & 0xC000) { + /* Non VIDC packing order */ + if (vals.flags & os_MODE_FLAG_FULL_PALETTE) + type = osspriteop_TYPE16BPP64K; + else + type = osspriteop_TYPE16BPP; + mode = (os_mode)((osspriteop_TYPEEXPANSION << osspriteop_TYPE_SHIFT) | + osspriteop_NEW_STYLE | + (vals.yeig << 6) | + (vals.xeig << 4) | + (type << 20) | + (vals.flags & 0xFF00)); + } else { + /* VIDC packing order */ + if (vals.flags & os_MODE_FLAG_FULL_PALETTE) + type = osspriteop_TYPE16BPP64K; + else + type = osspriteop_TYPE16BPP; + mode = (os_mode)((type << osspriteop_TYPE_SHIFT) | + osspriteop_NEW_STYLE | + ((180 >> vals.yeig) << osspriteop_YRES_SHIFT) | + ((180 >> vals.xeig) << osspriteop_XRES_SHIFT)); + } + break; + default: + LOG("Unhandled 16bpp format from flags %d", vals.flags); + ro_gui_buffer_free(); + return; + } + break; + case -1: + /* 16M colours */ + switch ((vals.flags & 0x3000) >> os_MODE_FLAG_DATA_FORMAT_SHIFT) { + case os_MODE_FLAG_DATA_FORMAT_RGB: + if (vals.flags & 0xC000) { + /* Non VIDC packing order */ + type = osspriteop_TYPE32BPP; + mode = (os_mode)((osspriteop_TYPEEXPANSION << osspriteop_TYPE_SHIFT) | + osspriteop_NEW_STYLE | + (vals.yeig << 6) | + (vals.xeig << 4) | + (type << 20) | + (vals.flags & 0xFF00)); + } else { + /* VIDC packing order */ + type = osspriteop_TYPE32BPP; + mode = (os_mode)((type << osspriteop_TYPE_SHIFT) | + osspriteop_NEW_STYLE | + ((180 >> vals.yeig) << osspriteop_YRES_SHIFT) | + ((180 >> vals.xeig) << osspriteop_XRES_SHIFT)); + } + break; + default: + LOG("Unhandled 32bpp data format from flags %d", vals.flags); + ro_gui_buffer_free(); + return; + } + break; + default: + LOG("Unhandled NCOLOUR value %d", vals.ncolour); + ro_gui_buffer_free(); + return; + } + } +#endif + +#ifdef BUFFER_EXCLUSIVE_USER_REDRAW + /* Create the sprite manually so we don't waste time clearing the + background. + */ + buffer->sprite_count = 1; + buffer->used = total_size; + header = (osspriteop_header *)(buffer + 1); + header->size = total_size - sizeof(osspriteop_area); + memcpy(header->name, buffer_name, 12); + header->width = word_width - 1; + header->height = sprite_size.y - 1; + header->left_bit = 0; + header->right_bit = ((sprite_size.x << bpp) - 1) & 31; + header->image = sizeof(osspriteop_header) + palette_size; + header->mask = header->image; + header->mode = mode; + if (palette) + xcolourtrans_read_palette((osspriteop_area *)mode, + (osspriteop_id)os_CURRENT_MODE, + (os_palette *)(header + 1), palette_size, + (colourtrans_palette_flags) + colourtrans_FLASHING_PALETTE, 0); +#else + /* Read the current contents of the screen + */ + buffer->sprite_count = 0; + buffer->used = 16; + if ((error = xosspriteop_get_sprite_user_coords(osspriteop_NAME, + buffer, buffer_name, palette, + clipping.x0, clipping.y0, + clipping.x1, clipping.y1)) != NULL) { + LOG("Grab error '%s'", error->errmess); + ro_gui_buffer_free(); + return; + } +#endif + /* Allocate OS_SpriteOp save area + */ + if ((error = xosspriteop_read_save_area_size(osspriteop_PTR, + buffer, (osspriteop_id)(buffer + 1), &size)) != NULL) { + LOG("Save area error '%s'", error->errmess); + ro_gui_buffer_free(); + return; + } + if ((save_area = malloc((size_t)size)) == NULL) { + ro_gui_buffer_free(); + return; + } + save_area->a[0] = 0; + + /* Switch output to sprite + */ + if ((error = xosspriteop_switch_output_to_sprite(osspriteop_PTR, + buffer, (osspriteop_id)(buffer + 1), save_area, + &context0, &context1, &context2, &context3)) != NULL) { + LOG("Switching error '%s'", error->errmess); + free(save_area); + ro_gui_buffer_free(); + return; + } + + /* Emulate an origin as the FontManager doesn't respect it in + most cases. + */ + ro_plot_origin_x -= clipping.x0; + ro_plot_origin_y -= clipping.y0; + + /* Update the ECF origin + */ + if ((error = xos_set_ecf_origin(-ro_plot_origin_x, + -ro_plot_origin_y)) != NULL) { + LOG("Invalid ECF origin: '%s'", error->errmess); + } +} + + +/** + * Closes any open buffer and flushes the contents to screen + */ +void ro_gui_buffer_close(void) +{ + /* Check we have an open buffer + */ + if (!buffer) + return; + + /* Remove any previous redirection + */ + ro_plot_origin_x += clipping.x0; + ro_plot_origin_y += clipping.y0; + xosspriteop_unswitch_output(context0, context1, context2, context3); + free(save_area); + + /* Plot the contents to screen + */ + if (mode == tinct_SPRITE_MODE) + _swix(Tinct_Plot, _IN(2) | _IN(3) | _IN(4) | _IN(7), + (char *)(buffer + 1), + clipping.x0, clipping.y0, + nsoption_int(plot_fg_quality)); + else + xosspriteop_put_sprite_user_coords(osspriteop_PTR, + buffer, (osspriteop_id)(buffer + 1), + clipping.x0, clipping.y0, (os_action)0); + ro_gui_buffer_free(); + + /* Update the ECF origin + */ + os_set_ecf_origin(0, 0); +} + + +/** + * Releases any buffer memory depending on cache constraints. + */ +static void ro_gui_buffer_free(void) +{ + free(buffer); + buffer = NULL; +} diff --git a/frontends/riscos/buffer.h b/frontends/riscos/buffer.h new file mode 100644 index 000000000..a683c324c --- /dev/null +++ b/frontends/riscos/buffer.h @@ -0,0 +1,31 @@ +/* + * Copyright 2004 Richard Wilson <not_ginger_matt@users.sourceforge.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Screen buffering (interface). + */ + +#ifndef _NETSURF_RISCOS_BUFFER_H_ +#define _NETSURF_RISCOS_BUFFER_H_ + +#include "oslib/wimp.h" + +void ro_gui_buffer_open(wimp_draw *redraw); +void ro_gui_buffer_close(void); + +#endif diff --git a/frontends/riscos/configure.c b/frontends/riscos/configure.c new file mode 100644 index 000000000..9d28616ec --- /dev/null +++ b/frontends/riscos/configure.c @@ -0,0 +1,410 @@ +/* + * Copyright 2005 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * \file + * RISC OS option setting (implementation). + */ + +#include <assert.h> +#include <stdbool.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <oslib/os.h> +#include <oslib/osbyte.h> +#include <oslib/territory.h> +#include <oslib/wimp.h> + +#include "utils/log.h" +#include "utils/messages.h" + +#include "riscos/gui.h" +#include "riscos/dialog.h" +#include "riscos/configure.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" +#include "riscos/configure/configure.h" + +#define CONFIGURE_ICON_PADDING_H 32 +#define CONFIGURE_ICON_PADDING_V 32 +#define CONFIGURE_DEFAULT_ICON_WIDTH (68 + CONFIGURE_ICON_PADDING_H) +#define CONFIGURE_DEFAULT_ICON_HEIGHT (128 + CONFIGURE_ICON_PADDING_V) + +struct configure_tool { + const char *name; +#define CONFIGURE_TOOL_TRANSLATED_SIZE 64 + char translated[CONFIGURE_TOOL_TRANSLATED_SIZE]; + char *validation; + bool (*initialise)(wimp_w w); + void (*finalise)(wimp_w w); + wimp_w w; + wimp_i i; + bool open; + struct configure_tool *next; +}; + +static wimp_w configure_window; +static int configure_current_encoding; +static int configure_icons = 0; +static struct configure_tool *configure_tools = NULL; +static int configure_icon_width = CONFIGURE_DEFAULT_ICON_WIDTH; +static int configure_icon_height = CONFIGURE_DEFAULT_ICON_HEIGHT; +static int configure_icons_per_line = 0; +static int configure_width; +static int configure_height; + +static bool ro_gui_configure_click(wimp_pointer *pointer); +static void ro_gui_configure_open_window(wimp_open *open); +static void ro_gui_configure_close(wimp_w w); +static bool ro_gui_configure_translate(void); +static void ro_gui_configure_register(const char *window, + bool (*initialise)(wimp_w w), void (*finalise)(wimp_w w)); + +void ro_gui_configure_initialise(void) +{ + /* create our window */ + configure_window = ro_gui_dialog_create("configure"); + ro_gui_wimp_event_register_open_window(configure_window, + ro_gui_configure_open_window); + ro_gui_wimp_event_register_mouse_click(configure_window, + ro_gui_configure_click); + ro_gui_wimp_event_set_help_prefix(configure_window, "HelpConfigure"); + + /* add in our option windows */ + ro_gui_configure_register("con_cache", + ro_gui_options_cache_initialise, + ro_gui_wimp_event_finalise); + ro_gui_configure_register("con_connect", + ro_gui_options_connection_initialise, + ro_gui_wimp_event_finalise); + ro_gui_configure_register("con_content", + ro_gui_options_content_initialise, + ro_gui_wimp_event_finalise); + ro_gui_configure_register("con_fonts", + ro_gui_options_fonts_initialise, + ro_gui_wimp_event_finalise); + ro_gui_configure_register("con_home", + ro_gui_options_home_initialise, + ro_gui_wimp_event_finalise); + ro_gui_configure_register("con_image", + ro_gui_options_image_initialise, + ro_gui_options_image_finalise); + ro_gui_configure_register("con_inter", + ro_gui_options_interface_initialise, + ro_gui_wimp_event_finalise); + ro_gui_configure_register("con_lang", + ro_gui_options_language_initialise, + ro_gui_wimp_event_finalise); + ro_gui_configure_register("con_theme", + ro_gui_options_theme_initialise, + ro_gui_options_theme_finalise); + ro_gui_configure_register("con_secure", + ro_gui_options_security_initialise, + ro_gui_wimp_event_finalise); + + /* translate the icons */ + if (!ro_gui_configure_translate()) + die("ro_gui_configure_translate failed"); +} + +void ro_gui_configure_show(void) +{ + int width, height; + + width = configure_icon_width << 2; + height = ((configure_icons + 3) >> 2) * configure_icon_height; + ro_gui_dialog_open_top(configure_window, NULL, width, height); +} + +bool ro_gui_configure_click(wimp_pointer *pointer) +{ + struct configure_tool *tool; + + if (pointer->buttons == wimp_CLICK_MENU) + return true; + + for (tool = configure_tools; tool; tool = tool->next) { + if (tool->i == pointer->i) { + if (!tool->open) { + tool->open = true; + if (!tool->initialise(tool->w)) + return false; + ro_gui_dialog_open_persistent( + configure_window, + tool->w, true); + ro_gui_wimp_event_register_close_window( + tool->w, + ro_gui_configure_close); + } else { + ro_gui_dialog_open_top(tool->w, NULL, 0, 0); + } + break; + } + } + return true; +} + +void ro_gui_configure_close(wimp_w w) +{ + struct configure_tool *tool; + + for (tool = configure_tools; tool; tool = tool->next) { + if (tool->w == w) { + tool->open = false; + if (tool->finalise) + tool->finalise(w); + break; + } + } +} + +void ro_gui_configure_open_window(wimp_open *open) +{ + os_error *error; + int screen_width, screen_height; + int height, width; + int icons_per_line, icon_lines; + int max_height; + os_box extent = { 0, 0, 0, 0 }; + struct configure_tool *tool; + + if (!ro_gui_configure_translate()) { + ro_warn_user("ro_gui_configure_translate failed", 0); + return; + } + + width = open->visible.x1 - open->visible.x0; + height = open->visible.y1 - open->visible.y0; + icons_per_line = width / configure_icon_width; + if (icons_per_line < 1) + icons_per_line = 1; + + /* move our icons */ + if (icons_per_line != configure_icons_per_line) { + int x, y, l; + configure_icons_per_line = icons_per_line; + x = CONFIGURE_ICON_PADDING_H / 2; + y = -configure_icon_height + (CONFIGURE_ICON_PADDING_V / 2); + l = 0; + for (tool = configure_tools; tool; tool = tool->next) { + error = xwimp_resize_icon(configure_window, + tool->i, + x, + y, + x + configure_icon_width - + CONFIGURE_ICON_PADDING_H, + y + configure_icon_height - + CONFIGURE_ICON_PADDING_V); + if (error) { + LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess); + } + x += configure_icon_width; + l++; + if (l >= icons_per_line) { + x = CONFIGURE_ICON_PADDING_H / 2; + l = 0; + y -= configure_icon_height; + } + } + error = xwimp_force_redraw(configure_window, + 0, -16384, 16384, 0); + if (error) { + LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + } + + /* restrict our height */ + icon_lines = (configure_icons + icons_per_line - 1) / + icons_per_line; + max_height = (icon_lines * configure_icon_height); + if (height > max_height) + open->visible.y0 = open->visible.y1 - max_height; + + /* set the extent */ + if ((configure_height != height) || (configure_width != width)) { + int max_icons_per_line; + ro_gui_screen_size(&screen_width, &screen_height); + max_icons_per_line = screen_width / configure_icon_width; + if (max_icons_per_line > configure_icons) + max_icons_per_line = configure_icons; + extent.x1 = configure_icon_width * max_icons_per_line; + extent.y0 = -max_height; + error = xwimp_set_extent(open->w, &extent); + if (error) { + LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + configure_height = height; + configure_width = width; + } + + /* open the window */ + error = xwimp_open_window(open); + if (error) { + LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } +} + +void ro_gui_configure_register(const char *window, + bool (*initialise)(wimp_w w), void (*finalise)(wimp_w w)) +{ + wimp_icon_create new_icon; + struct configure_tool *tool; + struct configure_tool *link; + os_error *error; + + /* create our tool */ + tool = calloc(sizeof(struct configure_tool), 1); + if (!tool) { + LOG("Insufficient memory for calloc()"); + die("Insufficient memory"); + return; /* For the benefit of scan-build */ + } + tool->name = window; + tool->translated[0] = '\0'; + tool->validation = malloc(strlen(window) + 2); + if (!tool->validation) { + LOG("Insufficient memory for malloc()"); + die("Insufficient memory"); + } + sprintf(tool->validation, "S%s", window); + tool->initialise = initialise; + tool->finalise = finalise; + tool->w = ro_gui_dialog_create(tool->name); + + /* create the icon */ + new_icon.w = configure_window; + new_icon.icon.extent.x0 = 0; + new_icon.icon.extent.x1 = configure_icon_width; + new_icon.icon.extent.y1 = 0; + new_icon.icon.extent.y0 = -configure_icon_height; + new_icon.icon.flags = wimp_ICON_TEXT | wimp_ICON_SPRITE | + wimp_ICON_INDIRECTED | wimp_ICON_HCENTRED | + (wimp_COLOUR_VERY_LIGHT_GREY << wimp_ICON_BG_COLOUR_SHIFT) | + (wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT) | + (wimp_BUTTON_CLICK << wimp_ICON_BUTTON_TYPE_SHIFT); + new_icon.icon.data.indirected_text_and_sprite.text = + tool->translated; + new_icon.icon.data.indirected_text_and_sprite.validation = + tool->validation; + new_icon.icon.data.indirected_text_and_sprite.size = + CONFIGURE_TOOL_TRANSLATED_SIZE; + error = xwimp_create_icon(&new_icon, &tool->i); + if (error) { + LOG("xwimp_create_icon: 0x%x: %s", error->errnum, error->errmess); + die(error->errmess); + } + + /* Set the icon's text in current local encoding */ + ro_gui_set_icon_string(configure_window, tool->i, + messages_get(tool->name), true); + + /* link into our list alphabetically */ + if ((!configure_tools) || + (strcmp(configure_tools->translated, + tool->translated) > 0)) { + tool->next = configure_tools; + configure_tools = tool; + } else { + for (link = configure_tools; link; link = link->next) { + if (link->next) { + if (strcmp(link->next->translated, + tool->translated) > 0) { + tool->next = link->next; + link->next = tool; + break; + } + } else { + link->next = tool; + break; + } + } + } + configure_icons++; +} + +/** + * Translate tool icons into the system local encoding. + * This will also recalculate the minimum required icon width. + * + * \return true on success, false on memory exhaustion + */ +bool ro_gui_configure_translate(void) +{ + int alphabet; + struct configure_tool *tool; + int icon_width; + os_error *error; + + /* read current alphabet */ + error = xosbyte1(osbyte_ALPHABET_NUMBER, 127, 0, + &alphabet); + if (error) { + LOG("failed reading alphabet: 0x%x: %s", error->errnum, error->errmess); + /* assume Latin1 */ + alphabet = territory_ALPHABET_LATIN1; + } + + if (alphabet == configure_current_encoding) + /* text is already in the correct encoding */ + return true; + + /* reset icon width */ + configure_icon_width = CONFIGURE_DEFAULT_ICON_WIDTH; + + for (tool = configure_tools; tool; tool = tool->next) { + /* re-translate the text */ + ro_gui_set_icon_string(configure_window, tool->i, + messages_get(tool->name), true); + + /* update the width */ + error = xwimptextop_string_width(tool->translated, + strlen(tool->translated), &icon_width); + if (error) { + LOG("xwimptextop_string_width: 0x%x: %s", error->errnum, error->errmess); + return false; + } + icon_width += CONFIGURE_ICON_PADDING_H; + if (icon_width > configure_icon_width) + configure_icon_width = icon_width; + + error = xwimp_resize_icon(configure_window, + tool->i, + 0, + -configure_icon_height, + configure_icon_width, + 0); + if (error) { + LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess); + } + } + + /* invalidate our global icons_per_line setting + * so the icons get reflowed */ + configure_icons_per_line = 0; + + /* finally, set the current encoding */ + configure_current_encoding = alphabet; + + return true; +} diff --git a/frontends/riscos/configure.h b/frontends/riscos/configure.h new file mode 100644 index 000000000..c190a6d0c --- /dev/null +++ b/frontends/riscos/configure.h @@ -0,0 +1,34 @@ +/* + * Copyright 2005 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * RISC OS option setting (interface). + */ + + +#ifndef _NETSURF_RISCOS_CONFIGURE_H_ +#define _NETSURF_RISCOS_CONFIGURE_H_ + +#include <stdbool.h> +#include "oslib/os.h" +#include "oslib/wimp.h" + +void ro_gui_configure_initialise(void); +void ro_gui_configure_show(void); + +#endif diff --git a/frontends/riscos/configure/con_cache.c b/frontends/riscos/configure/con_cache.c new file mode 100644 index 000000000..730d6f82f --- /dev/null +++ b/frontends/riscos/configure/con_cache.c @@ -0,0 +1,107 @@ +/* + * Copyright 2005 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdbool.h> +#include <oslib/hourglass.h> + +#include "utils/nsoption.h" +#include "utils/filename.h" +#include "utils/messages.h" + +#include "riscos/gui.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" +#include "riscos/configure.h" +#include "riscos/configure/configure.h" +#include "riscos/dialog.h" + + +#define CACHE_MEMORY_SIZE 3 +#define CACHE_MEMORY_DEC 4 +#define CACHE_MEMORY_INC 5 +#define CACHE_DISC_SIZE 10 +#define CACHE_DISC_DEC 11 +#define CACHE_DISC_INC 12 +#define CACHE_DISC_EXPIRE 15 +#define CACHE_DISC_EXPIRE_DEC 16 +#define CACHE_DISC_EXPIRE_INC 17 +#define CACHE_DEFAULT_BUTTON 19 +#define CACHE_CANCEL_BUTTON 20 +#define CACHE_OK_BUTTON 21 + +static bool ro_gui_options_cache_click(wimp_pointer *pointer); +static bool ro_gui_options_cache_ok(wimp_w w); + +bool ro_gui_options_cache_initialise(wimp_w w) +{ + /* set the current values */ + ro_gui_set_icon_decimal(w, CACHE_MEMORY_SIZE, + (nsoption_int(memory_cache_size) * 10) >> 20, 1); + ro_gui_set_icon_decimal(w, CACHE_DISC_SIZE, + (int) ((nsoption_uint(disc_cache_size)) >> 20), 0); + ro_gui_set_icon_decimal(w, CACHE_DISC_EXPIRE, + (nsoption_int(disc_cache_age)), 0); + + /* initialise all functions for a newly created window */ + ro_gui_wimp_event_register_numeric_field(w, CACHE_MEMORY_SIZE, + CACHE_MEMORY_INC, CACHE_MEMORY_DEC, 0, 640, 1, 1); + ro_gui_wimp_event_register_numeric_field(w, CACHE_DISC_SIZE, + CACHE_DISC_INC, CACHE_DISC_DEC, 0, 4095, 1, 0); + ro_gui_wimp_event_register_numeric_field(w, CACHE_DISC_EXPIRE, + CACHE_DISC_EXPIRE_INC, CACHE_DISC_EXPIRE_DEC, 1, 3650, + 1, 0); + ro_gui_wimp_event_register_mouse_click(w, ro_gui_options_cache_click); + ro_gui_wimp_event_register_cancel(w, CACHE_CANCEL_BUTTON); + ro_gui_wimp_event_register_ok(w, CACHE_OK_BUTTON, + ro_gui_options_cache_ok); + ro_gui_wimp_event_set_help_prefix(w, "HelpCacheConfig"); + ro_gui_wimp_event_memorise(w); + return true; + +} + +bool ro_gui_options_cache_click(wimp_pointer *pointer) +{ + switch (pointer->i) { + case CACHE_DEFAULT_BUTTON: + /* set the default values */ + ro_gui_set_icon_decimal(pointer->w, CACHE_MEMORY_SIZE, + 120, 1); + ro_gui_set_icon_decimal(pointer->w, CACHE_DISC_SIZE, + 1024, 0); + ro_gui_set_icon_decimal(pointer->w, CACHE_DISC_EXPIRE, + 28, 0); + return true; + } + return false; +} + +bool ro_gui_options_cache_ok(wimp_w w) +{ + nsoption_set_int(memory_cache_size, + (((ro_gui_get_icon_decimal(w, + CACHE_MEMORY_SIZE, 1) + 1) << 20) - 1) / 10); + nsoption_set_uint(disc_cache_size, + (uint) (ro_gui_get_icon_decimal(w, + CACHE_DISC_SIZE, 0) << 20)); + nsoption_set_int(disc_cache_age, + ro_gui_get_icon_decimal(w, CACHE_DISC_EXPIRE, 0)); + + ro_gui_save_options(); + return true; +} diff --git a/frontends/riscos/configure/con_connect.c b/frontends/riscos/configure/con_connect.c new file mode 100644 index 000000000..9515c5d6f --- /dev/null +++ b/frontends/riscos/configure/con_connect.c @@ -0,0 +1,220 @@ +/* + * Copyright 2006 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdbool.h> +#include "swis.h" +#include "oslib/osspriteop.h" +#include "oslib/wimp.h" + +#include "utils/nsoption.h" +#include "utils/log.h" + +#include "riscos/configure/configure.h" +#include "riscos/dialog.h" +#include "riscos/menus.h" +#include "riscos/tinct.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" + + +#define CONNECTION_PROXY_FIELD 3 +#define CONNECTION_PROXY_MENU 4 +#define CONNECTION_PROXY_HOST_LABEL 5 +#define CONNECTION_PROXY_HOST 6 +#define CONNECTION_PROXY_PORT_LABEL 7 +#define CONNECTION_PROXY_PORT 8 +#define CONNECTION_PROXY_USERNAME_LABEL 9 +#define CONNECTION_PROXY_USERNAME 10 +#define CONNECTION_PROXY_PASSWORD_LABEL 11 +#define CONNECTION_PROXY_PASSWORD 12 +#define CONNECTION_MAX_FETCH_FIELD 16 +#define CONNECTION_MAX_FETCH_DEC 17 +#define CONNECTION_MAX_FETCH_INC 18 +#define CONNECTION_HOST_FETCH_FIELD 20 +#define CONNECTION_HOST_FETCH_DEC 21 +#define CONNECTION_HOST_FETCH_INC 22 +#define CONNECTION_CACHE_FETCH_FIELD 24 +#define CONNECTION_CACHE_FETCH_DEC 25 +#define CONNECTION_CACHE_FETCH_INC 26 +#define CONNECTION_DEFAULT_BUTTON 27 +#define CONNECTION_CANCEL_BUTTON 28 +#define CONNECTION_OK_BUTTON 29 + +#define http_proxy_type (nsoption_bool(http_proxy) ? (nsoption_int(http_proxy_auth) + 1) : 0) + +static int ro_gui_options_connection_proxy_type(wimp_w w); +static void ro_gui_options_connection_default(wimp_pointer *pointer); +static bool ro_gui_options_connection_ok(wimp_w w); +static bool ro_gui_options_connection_update(wimp_w w, wimp_i i, wimp_menu *m, + wimp_selection *s, menu_action a); + +bool ro_gui_options_connection_initialise(wimp_w w) +{ + int proxy_type; + + /* set the current values */ + proxy_type = (nsoption_bool(http_proxy) ? (nsoption_int(http_proxy_auth) + 1) : 0); + ro_gui_set_icon_string(w, CONNECTION_PROXY_FIELD, + proxy_type_menu->entries[proxy_type]. + data.indirected_text.text, true); + ro_gui_set_icon_string(w, CONNECTION_PROXY_HOST, + nsoption_charp(http_proxy_host) ? + nsoption_charp(http_proxy_host) : "", true); + ro_gui_set_icon_integer(w, CONNECTION_PROXY_PORT, + nsoption_int(http_proxy_port)); + ro_gui_set_icon_string(w, CONNECTION_PROXY_USERNAME, + nsoption_charp(http_proxy_auth_user) ? + nsoption_charp(http_proxy_auth_user) : "", true); + ro_gui_set_icon_string(w, CONNECTION_PROXY_PASSWORD, + nsoption_charp(http_proxy_auth_pass) ? + nsoption_charp(http_proxy_auth_pass) : "", true); + ro_gui_set_icon_integer(w, CONNECTION_MAX_FETCH_FIELD, + nsoption_int(max_fetchers)); + ro_gui_set_icon_integer(w, CONNECTION_HOST_FETCH_FIELD, + nsoption_int(max_fetchers_per_host)); + ro_gui_set_icon_integer(w, CONNECTION_CACHE_FETCH_FIELD, + nsoption_int(max_cached_fetch_handles)); + ro_gui_options_connection_update(w, -1, NULL, NULL, NO_ACTION); + + /* register icons */ + ro_gui_wimp_event_register_menu_gright(w, CONNECTION_PROXY_FIELD, + CONNECTION_PROXY_MENU, proxy_type_menu); + ro_gui_wimp_event_register_text_field(w, CONNECTION_PROXY_HOST_LABEL); + ro_gui_wimp_event_register_text_field(w, CONNECTION_PROXY_HOST); + ro_gui_wimp_event_register_text_field(w, CONNECTION_PROXY_PORT_LABEL); + ro_gui_wimp_event_register_text_field(w, CONNECTION_PROXY_PORT); + ro_gui_wimp_event_register_text_field(w, CONNECTION_PROXY_USERNAME_LABEL); + ro_gui_wimp_event_register_text_field(w, CONNECTION_PROXY_USERNAME); + ro_gui_wimp_event_register_text_field(w, CONNECTION_PROXY_PASSWORD_LABEL); + ro_gui_wimp_event_register_text_field(w, CONNECTION_PROXY_PASSWORD); + ro_gui_wimp_event_register_numeric_field(w, CONNECTION_MAX_FETCH_FIELD, + CONNECTION_MAX_FETCH_INC, CONNECTION_MAX_FETCH_DEC, + 1, 99, 1, 0); + ro_gui_wimp_event_register_numeric_field(w, CONNECTION_HOST_FETCH_FIELD, + CONNECTION_HOST_FETCH_INC, CONNECTION_HOST_FETCH_DEC, + 1, 99, 1, 0); + ro_gui_wimp_event_register_numeric_field(w, CONNECTION_CACHE_FETCH_FIELD, + CONNECTION_CACHE_FETCH_INC, CONNECTION_CACHE_FETCH_DEC, + 1, 99, 1, 0); + ro_gui_wimp_event_register_menu_selection(w, + ro_gui_options_connection_update); + ro_gui_wimp_event_register_button(w, CONNECTION_DEFAULT_BUTTON, + ro_gui_options_connection_default); + ro_gui_wimp_event_register_cancel(w, CONNECTION_CANCEL_BUTTON); + ro_gui_wimp_event_register_ok(w, CONNECTION_OK_BUTTON, + ro_gui_options_connection_ok); + + ro_gui_wimp_event_set_help_prefix(w, "HelpConnectConfig"); + ro_gui_wimp_event_memorise(w); + return true; + +} + +bool ro_gui_options_connection_update(wimp_w w, wimp_i i, wimp_menu *m, + wimp_selection *s, menu_action a) +{ + int proxy_type; + bool host, user; + + /* update the shaded state */ + proxy_type = ro_gui_options_connection_proxy_type(w); + host = (proxy_type > 0); + user = (proxy_type > 1); + + ro_gui_set_icon_shaded_state(w, CONNECTION_PROXY_HOST_LABEL, !host); + ro_gui_set_icon_shaded_state(w, CONNECTION_PROXY_HOST, !host); + ro_gui_set_icon_shaded_state(w, CONNECTION_PROXY_PORT_LABEL, !host); + ro_gui_set_icon_shaded_state(w, CONNECTION_PROXY_PORT, !host); + ro_gui_set_icon_shaded_state(w, CONNECTION_PROXY_USERNAME_LABEL, !user); + ro_gui_set_icon_shaded_state(w, CONNECTION_PROXY_USERNAME, !user); + ro_gui_set_icon_shaded_state(w, CONNECTION_PROXY_PASSWORD_LABEL, !user); + ro_gui_set_icon_shaded_state(w, CONNECTION_PROXY_PASSWORD, !user); + + return true; +} + +int ro_gui_options_connection_proxy_type(wimp_w w) +{ + const char *text; + int i; + + text = ro_gui_get_icon_string(w, CONNECTION_PROXY_FIELD); + for (i = 0; (i < 4); i++) + if (!strcmp(text, proxy_type_menu->entries[i]. + data.indirected_text.text)) + return i; + assert(false); +} + +void ro_gui_options_connection_default(wimp_pointer *pointer) +{ + ro_gui_set_icon_string(pointer->w, CONNECTION_PROXY_FIELD, + proxy_type_menu->entries[0]. + data.indirected_text.text, true); + ro_gui_set_icon_string(pointer->w, CONNECTION_PROXY_HOST, "", true); + ro_gui_set_icon_integer(pointer->w, CONNECTION_PROXY_PORT, 8080); + ro_gui_set_icon_string(pointer->w, CONNECTION_PROXY_USERNAME, "", true); + ro_gui_set_icon_string(pointer->w, CONNECTION_PROXY_PASSWORD, "", true); + ro_gui_set_icon_integer(pointer->w, CONNECTION_MAX_FETCH_FIELD, 24); + ro_gui_set_icon_integer(pointer->w, CONNECTION_HOST_FETCH_FIELD, 5); + ro_gui_set_icon_integer(pointer->w, CONNECTION_CACHE_FETCH_FIELD, 6); + ro_gui_options_connection_update(pointer->w, -1, NULL, NULL, NO_ACTION); +} + +bool ro_gui_options_connection_ok(wimp_w w) +{ + int proxy_type; + + proxy_type = ro_gui_options_connection_proxy_type(w); + if (proxy_type == 0) { + nsoption_set_bool(http_proxy, false); + } else { + nsoption_set_bool(http_proxy, true); + nsoption_set_int(http_proxy_auth, proxy_type - 1); + } + + nsoption_set_charp(http_proxy_host, + strdup(ro_gui_get_icon_string(w, + CONNECTION_PROXY_HOST))); + + nsoption_set_int(http_proxy_port, + ro_gui_get_icon_decimal(w, CONNECTION_PROXY_PORT, 0)); + + nsoption_set_charp(http_proxy_auth_user, + strdup(ro_gui_get_icon_string(w, + CONNECTION_PROXY_USERNAME))); + + nsoption_set_charp(http_proxy_auth_pass, + strdup(ro_gui_get_icon_string(w, + CONNECTION_PROXY_PASSWORD))); + + nsoption_set_int(max_fetchers, + ro_gui_get_icon_decimal(w, + CONNECTION_MAX_FETCH_FIELD, 0)); + + nsoption_set_int(max_fetchers_per_host, + ro_gui_get_icon_decimal(w, + CONNECTION_HOST_FETCH_FIELD, 0)); + + nsoption_set_int(max_cached_fetch_handles, + ro_gui_get_icon_decimal(w, + CONNECTION_CACHE_FETCH_FIELD, 0)); + + ro_gui_save_options(); + return true; +} diff --git a/frontends/riscos/configure/con_content.c b/frontends/riscos/configure/con_content.c new file mode 100644 index 000000000..50bbd15ef --- /dev/null +++ b/frontends/riscos/configure/con_content.c @@ -0,0 +1,107 @@ +/* + * Copyright 2006 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdbool.h> + +#include "utils/nsoption.h" +#include "utils/messages.h" + +#include "riscos/gui.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" +#include "riscos/configure.h" +#include "riscos/configure/configure.h" +#include "riscos/dialog.h" + +#define CONTENT_BLOCK_ADVERTISEMENTS 2 +#define CONTENT_BLOCK_POPUPS 3 +#define CONTENT_NO_PLUGINS 4 +#define CONTENT_TARGET_BLANK 7 +#define CONTENT_DEFAULT_BUTTON 8 +#define CONTENT_CANCEL_BUTTON 9 +#define CONTENT_OK_BUTTON 10 +#define CONTENT_NO_JAVASCRIPT 11 + +static void ro_gui_options_content_default(wimp_pointer *pointer); +static bool ro_gui_options_content_ok(wimp_w w); + +bool ro_gui_options_content_initialise(wimp_w w) +{ + /* set the current values */ + ro_gui_set_icon_selected_state(w, CONTENT_BLOCK_ADVERTISEMENTS, + nsoption_bool(block_advertisements)); + ro_gui_set_icon_selected_state(w, CONTENT_BLOCK_POPUPS, + nsoption_bool(block_popups)); + ro_gui_set_icon_selected_state(w, CONTENT_NO_PLUGINS, + nsoption_bool(no_plugins)); + ro_gui_set_icon_selected_state(w, CONTENT_TARGET_BLANK, + nsoption_bool(target_blank)); + ro_gui_set_icon_selected_state(w, CONTENT_NO_JAVASCRIPT, + !nsoption_bool(enable_javascript)); + + /* initialise all functions for a newly created window */ + ro_gui_wimp_event_register_checkbox(w, CONTENT_BLOCK_ADVERTISEMENTS); + ro_gui_wimp_event_register_checkbox(w, CONTENT_BLOCK_POPUPS); + ro_gui_wimp_event_register_checkbox(w, CONTENT_NO_PLUGINS); + ro_gui_wimp_event_register_checkbox(w, CONTENT_TARGET_BLANK); + ro_gui_wimp_event_register_checkbox(w, CONTENT_NO_JAVASCRIPT); + ro_gui_wimp_event_register_button(w, CONTENT_DEFAULT_BUTTON, + ro_gui_options_content_default); + ro_gui_wimp_event_register_cancel(w, CONTENT_CANCEL_BUTTON); + ro_gui_wimp_event_register_ok(w, CONTENT_OK_BUTTON, + ro_gui_options_content_ok); + ro_gui_wimp_event_set_help_prefix(w, "HelpContentConfig"); + ro_gui_wimp_event_memorise(w); + return true; + +} + +void ro_gui_options_content_default(wimp_pointer *pointer) +{ + /* set the default values */ + ro_gui_set_icon_selected_state(pointer->w, CONTENT_BLOCK_ADVERTISEMENTS, + false); + ro_gui_set_icon_selected_state(pointer->w, CONTENT_BLOCK_POPUPS, + false); + ro_gui_set_icon_selected_state(pointer->w, CONTENT_NO_PLUGINS, + false); + ro_gui_set_icon_selected_state(pointer->w, CONTENT_TARGET_BLANK, + true); + ro_gui_set_icon_selected_state(pointer->w, CONTENT_NO_JAVASCRIPT, + false); +} + +bool ro_gui_options_content_ok(wimp_w w) +{ + nsoption_set_bool(block_advertisements, + ro_gui_get_icon_selected_state(w, CONTENT_BLOCK_ADVERTISEMENTS)); + + nsoption_set_bool(block_popups, + ro_gui_get_icon_selected_state(w, CONTENT_BLOCK_POPUPS)); + nsoption_set_bool(no_plugins, + ro_gui_get_icon_selected_state(w, CONTENT_NO_PLUGINS)); + + nsoption_set_bool(target_blank, + ro_gui_get_icon_selected_state(w, CONTENT_TARGET_BLANK)); + + nsoption_set_bool(enable_javascript, + !ro_gui_get_icon_selected_state(w, CONTENT_NO_JAVASCRIPT)); + + ro_gui_save_options(); + return true; +} diff --git a/frontends/riscos/configure/con_fonts.c b/frontends/riscos/configure/con_fonts.c new file mode 100644 index 000000000..280312843 --- /dev/null +++ b/frontends/riscos/configure/con_fonts.c @@ -0,0 +1,209 @@ +/* + * Copyright 2005 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdbool.h> +#include <stddef.h> + +#include "utils/nsoption.h" +#include "utils/messages.h" +#include "desktop/plot_style.h" + +#include "riscos/gui.h" +#include "riscos/font.h" +#include "riscos/menus.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" +#include "riscos/configure.h" +#include "riscos/configure/configure.h" +#include "riscos/dialog.h" + + +#define FONT_SANS_FIELD 3 +#define FONT_SANS_MENU 4 +#define FONT_SERIF_FIELD 6 +#define FONT_SERIF_MENU 7 +#define FONT_MONOSPACE_FIELD 9 +#define FONT_MONOSPACE_MENU 10 +#define FONT_CURSIVE_FIELD 12 +#define FONT_CURSIVE_MENU 13 +#define FONT_FANTASY_FIELD 15 +#define FONT_FANTASY_MENU 16 +#define FONT_DEFAULT_FIELD 18 +#define FONT_DEFAULT_MENU 19 +#define FONT_DEFAULT_SIZE 23 +#define FONT_DEFAULT_DEC 24 +#define FONT_DEFAULT_INC 25 +#define FONT_MINIMUM_SIZE 28 +#define FONT_MINIMUM_DEC 29 +#define FONT_MINIMUM_INC 30 +#define FONT_DEFAULT_BUTTON 32 +#define FONT_CANCEL_BUTTON 33 +#define FONT_OK_BUTTON 34 + +/* This menu only ever gets created once */ +/** \todo The memory claimed for this menu should + * probably be released at some point */ +static wimp_menu *default_menu; + +static const char *font_names[PLOT_FONT_FAMILY_COUNT] = { + "Sans-serif", + "Serif", + "Monospace", + "Cursive", + "Fantasy" +}; + +static void ro_gui_options_fonts_default(wimp_pointer *pointer); +static bool ro_gui_options_fonts_ok(wimp_w w); +static bool ro_gui_options_fonts_init_menu(void); + +bool ro_gui_options_fonts_initialise(wimp_w w) +{ + /* set the current values */ + ro_gui_set_icon_decimal(w, FONT_DEFAULT_SIZE, nsoption_int(font_size), 1); + ro_gui_set_icon_decimal(w, FONT_MINIMUM_SIZE, nsoption_int(font_min_size), 1); + ro_gui_set_icon_string(w, FONT_SANS_FIELD, nsoption_charp(font_sans), true); + ro_gui_set_icon_string(w, FONT_SERIF_FIELD, nsoption_charp(font_serif), true); + ro_gui_set_icon_string(w, FONT_MONOSPACE_FIELD, nsoption_charp(font_mono), true); + ro_gui_set_icon_string(w, FONT_CURSIVE_FIELD, nsoption_charp(font_cursive), true); + ro_gui_set_icon_string(w, FONT_FANTASY_FIELD, nsoption_charp(font_fantasy), true); + ro_gui_set_icon_string(w, FONT_DEFAULT_FIELD, + font_names[nsoption_int(font_default)], true); + + if (!ro_gui_options_fonts_init_menu()) + return false; + + /* initialise all functions for a newly created window */ + ro_gui_wimp_event_register_menu_gright(w, FONT_SANS_FIELD, + FONT_SANS_MENU, rufl_family_menu); + ro_gui_wimp_event_register_menu_gright(w, FONT_SERIF_FIELD, + FONT_SERIF_MENU, rufl_family_menu); + ro_gui_wimp_event_register_menu_gright(w, FONT_MONOSPACE_FIELD, + FONT_MONOSPACE_MENU, rufl_family_menu); + ro_gui_wimp_event_register_menu_gright(w, FONT_CURSIVE_FIELD, + FONT_CURSIVE_MENU, rufl_family_menu); + ro_gui_wimp_event_register_menu_gright(w, FONT_FANTASY_FIELD, + FONT_FANTASY_MENU, rufl_family_menu); + ro_gui_wimp_event_register_menu_gright(w, FONT_DEFAULT_FIELD, + FONT_DEFAULT_MENU, default_menu); + ro_gui_wimp_event_register_numeric_field(w, FONT_DEFAULT_SIZE, + FONT_DEFAULT_INC, FONT_DEFAULT_DEC, 50, 1000, 1, 1); + ro_gui_wimp_event_register_numeric_field(w, FONT_MINIMUM_SIZE, + FONT_MINIMUM_INC, FONT_MINIMUM_DEC, 10, 500, 1, 1); + ro_gui_wimp_event_register_button(w, FONT_DEFAULT_BUTTON, + ro_gui_options_fonts_default); + ro_gui_wimp_event_register_cancel(w, FONT_CANCEL_BUTTON); + ro_gui_wimp_event_register_ok(w, FONT_OK_BUTTON, + ro_gui_options_fonts_ok); + ro_gui_wimp_event_set_help_prefix(w, "HelpFontConfig"); + ro_gui_wimp_event_memorise(w); + return true; + +} + +void ro_gui_options_fonts_default(wimp_pointer *pointer) +{ + const char *fallback = nsfont_fallback_font(); + + /* set the default values */ + ro_gui_set_icon_decimal(pointer->w, FONT_DEFAULT_SIZE, 128, 1); + ro_gui_set_icon_decimal(pointer->w, FONT_MINIMUM_SIZE, 85, 1); + ro_gui_set_icon_string(pointer->w, FONT_SANS_FIELD, + nsfont_exists("Homerton") ? "Homerton" : fallback, true); + ro_gui_set_icon_string(pointer->w, FONT_SERIF_FIELD, + nsfont_exists("Trinity") ? "Trinity" : fallback, true); + ro_gui_set_icon_string(pointer->w, FONT_MONOSPACE_FIELD, + nsfont_exists("Corpus") ? "Corpus" : fallback, true); + ro_gui_set_icon_string(pointer->w, FONT_CURSIVE_FIELD, + nsfont_exists("Churchill") ? "Churchill" : fallback, true); + ro_gui_set_icon_string(pointer->w, FONT_FANTASY_FIELD, + nsfont_exists("Sassoon") ? "Sassoon" : fallback, true); + ro_gui_set_icon_string(pointer->w, FONT_DEFAULT_FIELD, + font_names[0], true); +} + +bool ro_gui_options_fonts_ok(wimp_w w) +{ + unsigned int i; + + nsoption_set_int(font_size, + ro_gui_get_icon_decimal(w, FONT_DEFAULT_SIZE, 1)); + + nsoption_set_int(font_min_size, + ro_gui_get_icon_decimal(w, FONT_MINIMUM_SIZE, 1)); + + if (nsoption_int(font_size) < nsoption_int(font_min_size)) { + nsoption_set_int(font_size, nsoption_int(font_min_size)); + ro_gui_set_icon_decimal(w, FONT_DEFAULT_SIZE, nsoption_int(font_size), 1); + +} + + nsoption_set_charp(font_sans, + strdup(ro_gui_get_icon_string(w, FONT_SANS_FIELD))); + + nsoption_set_charp(font_serif, + strdup(ro_gui_get_icon_string(w, FONT_SERIF_FIELD))); + + nsoption_set_charp(font_mono, + strdup(ro_gui_get_icon_string(w, FONT_MONOSPACE_FIELD))); + + nsoption_set_charp(font_cursive, + strdup(ro_gui_get_icon_string(w, FONT_CURSIVE_FIELD))); + + nsoption_set_charp(font_fantasy, + strdup(ro_gui_get_icon_string(w, FONT_FANTASY_FIELD))); + + for (i = 0; i != 5; i++) { + if (!strcmp(font_names[i], ro_gui_get_icon_string(w, + FONT_DEFAULT_FIELD))) + break; + } + if (i == 5) + /* this should never happen, but still */ + i = 0; + + nsoption_set_int(font_default, i); + + ro_gui_save_options(); + return true; +} + +bool ro_gui_options_fonts_init_menu(void) +{ + unsigned int i; + + if (default_menu) + /* Already exists */ + return true; + + default_menu = malloc(wimp_SIZEOF_MENU(5)); + if (!default_menu) { + ro_warn_user("NoMemory", 0); + return false; + } + default_menu->title_data.indirected_text.text = + (char *) messages_get("DefaultFonts"); + ro_gui_menu_init_structure(default_menu, 5); + for (i = 0; i < 5; i++) { + default_menu->entries[i].data.indirected_text.text = + (char *) font_names[i]; + default_menu->entries[i].data.indirected_text.size = + strlen(font_names[i]); + } + return true; +} diff --git a/frontends/riscos/configure/con_home.c b/frontends/riscos/configure/con_home.c new file mode 100644 index 000000000..ea8e243ed --- /dev/null +++ b/frontends/riscos/configure/con_home.c @@ -0,0 +1,118 @@ +/* + * Copyright 2005 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdbool.h> +#include <stdlib.h> + +#include "utils/messages.h" +#include "utils/nsoption.h" + +#include "riscos/gui.h" +#include "riscos/menus.h" +#include "riscos/url_suggest.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" +#include "riscos/configure.h" +#include "riscos/configure/configure.h" +#include "riscos/dialog.h" + +#define HOME_URL_FIELD 3 +#define HOME_URL_GRIGHT 4 +#define HOME_OPEN_STARTUP 5 +#define HOME_DEFAULT_BUTTON 6 +#define HOME_CANCEL_BUTTON 7 +#define HOME_OK_BUTTON 8 + +static void ro_gui_options_home_default(wimp_pointer *pointer); +static bool ro_gui_options_home_ok(wimp_w w); +static bool ro_gui_options_home_menu_prepare(wimp_w w, wimp_i i, + wimp_menu *menu, wimp_pointer *pointer); + +bool ro_gui_options_home_initialise(wimp_w w) +{ + /* set the current values */ + ro_gui_set_icon_string(w, HOME_URL_FIELD, + nsoption_charp(homepage_url) ? + nsoption_charp(homepage_url) : "", true); + + ro_gui_set_icon_selected_state(w, HOME_OPEN_STARTUP, + nsoption_bool(open_browser_at_startup)); + + ro_gui_set_icon_shaded_state(w, + HOME_URL_GRIGHT, !ro_gui_url_suggest_prepare_menu()); + + /* initialise all functions for a newly created window */ + ro_gui_wimp_event_register_menu_gright(w, HOME_URL_FIELD, + HOME_URL_GRIGHT, ro_gui_url_suggest_menu); + ro_gui_wimp_event_register_checkbox(w, HOME_OPEN_STARTUP); + ro_gui_wimp_event_register_button(w, HOME_DEFAULT_BUTTON, + ro_gui_options_home_default); + ro_gui_wimp_event_register_cancel(w, HOME_CANCEL_BUTTON); + ro_gui_wimp_event_register_ok(w, HOME_OK_BUTTON, + ro_gui_options_home_ok); + ro_gui_wimp_event_register_menu_prepare(w, + ro_gui_options_home_menu_prepare); + ro_gui_wimp_event_set_help_prefix(w, "HelpHomeConfig"); + ro_gui_wimp_event_memorise(w); + return true; + +} + +void ro_gui_options_home_default(wimp_pointer *pointer) +{ + /* set the default values */ + ro_gui_set_icon_string(pointer->w, HOME_URL_FIELD, "", true); + ro_gui_set_icon_selected_state(pointer->w, HOME_OPEN_STARTUP, false); +} + +bool ro_gui_options_home_ok(wimp_w w) +{ + nsoption_set_charp(homepage_url, + strdup(ro_gui_get_icon_string(w, HOME_URL_FIELD))); + + nsoption_set_bool(open_browser_at_startup, + ro_gui_get_icon_selected_state(w, HOME_OPEN_STARTUP)); + + ro_gui_save_options(); + return true; +} + + +/** + * Callback to prepare menus in the Configure Home dialog. At present, this + * only has to handle the URL Suggestion pop-up. + * + * \param w The window handle owning the menu. + * \param i The icon handle owning the menu. + * \param *menu The menu to be prepared. + * \param *pointer The associated mouse click event block, or NULL + * on an Adjust-click re-opening. + * \return true if the event was handled; false if not. + */ + +bool ro_gui_options_home_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_pointer *pointer) +{ + if (menu != ro_gui_url_suggest_menu || i != HOME_URL_GRIGHT) + return false; + + if (pointer != NULL) + ro_gui_url_suggest_prepare_menu(); + + return true; +} diff --git a/frontends/riscos/configure/con_image.c b/frontends/riscos/configure/con_image.c new file mode 100644 index 000000000..49dd4f76d --- /dev/null +++ b/frontends/riscos/configure/con_image.c @@ -0,0 +1,269 @@ +/* + * Copyright 2006 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdbool.h> +#include <swis.h> +#include <oslib/osspriteop.h> +#include <oslib/wimp.h> + +#include "utils/nsoption.h" +#include "utils/log.h" + +#include "riscos/gui.h" +#include "riscos/configure/configure.h" +#include "riscos/dialog.h" +#include "riscos/menus.h" +#include "riscos/tinct.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" + + +#define IMAGE_FOREGROUND_FIELD 3 +#define IMAGE_FOREGROUND_MENU 4 +#define IMAGE_BACKGROUND_FIELD 6 +#define IMAGE_BACKGROUND_MENU 7 +#define IMAGE_CURRENT_DISPLAY 8 +#define IMAGE_SPEED_TEXT 11 +#define IMAGE_SPEED_FIELD 12 +#define IMAGE_SPEED_DEC 13 +#define IMAGE_SPEED_INC 14 +#define IMAGE_SPEED_CS 15 +#define IMAGE_DISABLE_ANIMATION 16 +#define IMAGE_DEFAULT_BUTTON 17 +#define IMAGE_CANCEL_BUTTON 18 +#define IMAGE_OK_BUTTON 19 + +static bool ro_gui_options_image_click(wimp_pointer *pointer); +static bool ro_gui_options_image_ok(wimp_w w); +static void ro_gui_options_image_redraw(wimp_draw *redraw); +static bool ro_gui_options_image_update(wimp_w w, wimp_i i, wimp_menu *m, + wimp_selection *s, menu_action a); +static void ro_gui_options_image_read(wimp_w w, unsigned int *bg, + unsigned int *fg); +static void ro_gui_options_update_shading(wimp_w w); + +static osspriteop_area *example_images; +int example_users = 0; +unsigned int tinct_options[] = {tinct_USE_OS_SPRITE_OP, 0, tinct_DITHER, + tinct_ERROR_DIFFUSE}; + +bool ro_gui_options_image_initialise(wimp_w w) +{ + int i; + + /* load the sprite file */ + if (example_users == 0) { + char pathname[256]; + snprintf(pathname, 256, "%s.Resources.Image", NETSURF_DIR); + pathname[255] = '\0'; + example_images = ro_gui_load_sprite_file(pathname); + if (!example_images) + return false; + } + example_users++; + + /* set the current values */ + for (i = 0; (i < 4); i++) { + if ((unsigned int)nsoption_int(plot_fg_quality) == tinct_options[i]) + ro_gui_set_icon_string(w, IMAGE_FOREGROUND_FIELD, + image_quality_menu->entries[i]. + data.indirected_text.text, true); + if ((unsigned int)nsoption_int(plot_bg_quality) == tinct_options[i]) + ro_gui_set_icon_string(w, IMAGE_BACKGROUND_FIELD, + image_quality_menu->entries[i]. + data.indirected_text.text, true); + } + ro_gui_set_icon_decimal(w, IMAGE_SPEED_FIELD, + nsoption_int(minimum_gif_delay), 2); + ro_gui_set_icon_selected_state(w, IMAGE_DISABLE_ANIMATION, + !nsoption_bool(animate_images)); + ro_gui_options_update_shading(w); + + /* register icons */ + ro_gui_wimp_event_register_menu_gright(w, IMAGE_FOREGROUND_FIELD, + IMAGE_FOREGROUND_MENU, image_quality_menu); + ro_gui_wimp_event_register_menu_gright(w, IMAGE_BACKGROUND_FIELD, + IMAGE_BACKGROUND_MENU, image_quality_menu); + ro_gui_wimp_event_register_text_field(w, IMAGE_SPEED_TEXT); + ro_gui_wimp_event_register_numeric_field(w, IMAGE_SPEED_FIELD, + IMAGE_SPEED_INC, IMAGE_SPEED_DEC, 0, 6000, 10, 2); + ro_gui_wimp_event_register_checkbox(w, IMAGE_DISABLE_ANIMATION); + ro_gui_wimp_event_register_text_field(w, IMAGE_SPEED_CS); + ro_gui_wimp_event_register_redraw_window(w, + ro_gui_options_image_redraw); + ro_gui_wimp_event_register_mouse_click(w, + ro_gui_options_image_click); + ro_gui_wimp_event_register_menu_selection(w, + ro_gui_options_image_update); + ro_gui_wimp_event_register_cancel(w, IMAGE_CANCEL_BUTTON); + ro_gui_wimp_event_register_ok(w, IMAGE_OK_BUTTON, + ro_gui_options_image_ok); + ro_gui_wimp_event_set_help_prefix(w, "HelpImageConfig"); + ro_gui_wimp_event_memorise(w); + + return true; +} + +void ro_gui_options_image_finalise(wimp_w w) +{ + example_users--; + if (example_users == 0) { + free(example_images); + example_images = NULL; + } + ro_gui_wimp_event_finalise(w); +} + +bool ro_gui_options_image_update(wimp_w w, wimp_i i, wimp_menu *m, + wimp_selection *s, menu_action a) +{ + ro_gui_redraw_icon(w, IMAGE_CURRENT_DISPLAY); + + return true; +} + +void ro_gui_options_image_redraw(wimp_draw *redraw) +{ + osbool more; + os_error *error; + wimp_icon_state icon_state; + osspriteop_header *bg = NULL, *fg = NULL; + unsigned int bg_tinct = 0, fg_tinct = 0; + + /* get the icon location */ + icon_state.w = redraw->w; + icon_state.i = IMAGE_CURRENT_DISPLAY; + error = xwimp_get_icon_state(&icon_state); + if (error) { + LOG("xwimp_get_icon_state: 0x%x: %s", + error->errnum, error->errmess); + ro_warn_user("MenuError", error->errmess); + return; + } + + /* find the sprites */ + if (example_images) { + ro_gui_options_image_read(redraw->w, &bg_tinct, &fg_tinct); + fg_tinct |= 0xeeeeee00; + xosspriteop_select_sprite(osspriteop_USER_AREA, + example_images, (osspriteop_id)"img_bg", &bg); + xosspriteop_select_sprite(osspriteop_USER_AREA, + example_images, (osspriteop_id)"img_fg", &fg); + } + + /* perform the redraw */ + more = wimp_redraw_window(redraw); + while (more) { + int origin_x, origin_y; + origin_x = redraw->box.x0 - redraw->xscroll + + icon_state.icon.extent.x0 + 2; + origin_y = redraw->box.y1 - redraw->yscroll + + icon_state.icon.extent.y0 + 2; + if (bg) + _swix(Tinct_Plot, _INR(2,4) | _IN(7), + bg, origin_x, origin_y, bg_tinct); + if (fg) + _swix(Tinct_PlotAlpha, _INR(2,4) | _IN(7), + fg, origin_x, origin_y, fg_tinct); + more = wimp_get_rectangle(redraw); + } +} + +void ro_gui_options_image_read(wimp_w w, unsigned int *bg, unsigned int *fg) +{ + const char *text; + int i; + + text = ro_gui_get_icon_string(w, IMAGE_FOREGROUND_FIELD); + for (i = 0; i < 4; i++) + if (!strcmp(text, image_quality_menu->entries[i]. + data.indirected_text.text)) + *fg = tinct_options[i]; + + text = ro_gui_get_icon_string(w, IMAGE_BACKGROUND_FIELD); + for (i = 0; i < 4; i++) + if (!strcmp(text, image_quality_menu->entries[i]. + data.indirected_text.text)) + *bg = tinct_options[i]; +} + +bool ro_gui_options_image_click(wimp_pointer *pointer) +{ + unsigned int old_fg, old_bg, bg, fg; + + ro_gui_options_image_read(pointer->w, &old_bg, &old_fg); + switch (pointer->i) { + case IMAGE_DEFAULT_BUTTON: + ro_gui_set_icon_string(pointer->w, + IMAGE_FOREGROUND_FIELD, + image_quality_menu->entries[3]. + data.indirected_text.text, true); + ro_gui_set_icon_string(pointer->w, + IMAGE_BACKGROUND_FIELD, + image_quality_menu->entries[2]. + data.indirected_text.text, true); + ro_gui_set_icon_decimal(pointer->w, IMAGE_SPEED_FIELD, + 10, 2); + ro_gui_set_icon_selected_state(pointer->w, + IMAGE_DISABLE_ANIMATION, false); + case IMAGE_DISABLE_ANIMATION: + ro_gui_options_update_shading(pointer->w); + break; + case IMAGE_CANCEL_BUTTON: + ro_gui_wimp_event_restore(pointer->w); + break; + default: + return false; + } + + ro_gui_options_image_read(pointer->w, &bg, &fg); + if ((bg != old_bg) || (fg != old_fg)) + ro_gui_options_image_update(pointer->w, pointer->i, + NULL, NULL, NO_ACTION); + + return false; +} + +void ro_gui_options_update_shading(wimp_w w) +{ + bool shaded; + + shaded = ro_gui_get_icon_selected_state(w, IMAGE_DISABLE_ANIMATION); + ro_gui_set_icon_shaded_state(w, IMAGE_SPEED_TEXT, shaded); + ro_gui_set_icon_shaded_state(w, IMAGE_SPEED_FIELD, shaded); + ro_gui_set_icon_shaded_state(w, IMAGE_SPEED_DEC, shaded); + ro_gui_set_icon_shaded_state(w, IMAGE_SPEED_INC, shaded); + ro_gui_set_icon_shaded_state(w, IMAGE_SPEED_CS, shaded); +} + +bool ro_gui_options_image_ok(wimp_w w) +{ + ro_gui_options_image_read(w, + (unsigned int *)&nsoption_int(plot_bg_quality), + (unsigned int *)&nsoption_int(plot_fg_quality)); + + nsoption_set_int(minimum_gif_delay, + ro_gui_get_icon_decimal(w, IMAGE_SPEED_FIELD, 2)); + + nsoption_set_bool(animate_images, + !ro_gui_get_icon_selected_state(w, + IMAGE_DISABLE_ANIMATION)); + ro_gui_save_options(); + + return true; +} diff --git a/frontends/riscos/configure/con_inter.c b/frontends/riscos/configure/con_inter.c new file mode 100644 index 000000000..7ab912c54 --- /dev/null +++ b/frontends/riscos/configure/con_inter.c @@ -0,0 +1,145 @@ +/* + * Copyright 2006 Adrian Lees <adrianl@users.sourceforge.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdbool.h> + +#include "utils/nsoption.h" + +#include "riscos/gui.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" +#include "riscos/configure.h" +#include "riscos/configure/configure.h" +#include "riscos/dialog.h" + +#define INTERFACE_STRIP_EXTNS_OPTION 2 +#define INTERFACE_CONFIRM_OVWR_OPTION 3 +#define INTERFACE_URL_COMPLETE_OPTION 6 +#define INTERFACE_HISTORY_TOOLTIP_OPTION 7 +#define INTERFACE_THUMBNAIL_ICONISE_OPTION 10 +#define INTERFACE_DEFAULT_BUTTON 11 +#define INTERFACE_CANCEL_BUTTON 12 +#define INTERFACE_OK_BUTTON 13 +#define INTERFACE_USE_EXTERNAL_HOTLIST 16 +#define INTERFACE_EXTERNAL_HOTLIST_APP 18 + + +static bool ro_gui_options_interface_click(wimp_pointer *pointer); +static void ro_gui_options_interface_default(wimp_pointer *pointer); +static bool ro_gui_options_interface_ok(wimp_w w); + +bool ro_gui_options_interface_initialise(wimp_w w) +{ + /* set the current values */ + ro_gui_set_icon_selected_state(w, INTERFACE_STRIP_EXTNS_OPTION, + nsoption_bool(strip_extensions)); + ro_gui_set_icon_selected_state(w, INTERFACE_CONFIRM_OVWR_OPTION, + nsoption_bool(confirm_overwrite)); + ro_gui_set_icon_selected_state(w, INTERFACE_URL_COMPLETE_OPTION, + nsoption_bool(url_suggestion)); + ro_gui_set_icon_selected_state(w, INTERFACE_HISTORY_TOOLTIP_OPTION, + nsoption_bool(history_tooltip)); + ro_gui_set_icon_selected_state(w, INTERFACE_THUMBNAIL_ICONISE_OPTION, + nsoption_bool(thumbnail_iconise)); + ro_gui_set_icon_selected_state(w, INTERFACE_USE_EXTERNAL_HOTLIST, + nsoption_bool(external_hotlists)); + ro_gui_set_icon_string(w, INTERFACE_EXTERNAL_HOTLIST_APP, + (nsoption_charp(external_hotlist_app)) ? + nsoption_charp(external_hotlist_app) : "", false); + + ro_gui_set_icon_shaded_state(w, INTERFACE_EXTERNAL_HOTLIST_APP, + !nsoption_bool(external_hotlists)); + + /* initialise all functions for a newly created window */ + ro_gui_wimp_event_register_mouse_click(w, + ro_gui_options_interface_click); + ro_gui_wimp_event_register_button(w, INTERFACE_DEFAULT_BUTTON, + ro_gui_options_interface_default); + ro_gui_wimp_event_register_cancel(w, INTERFACE_CANCEL_BUTTON); + ro_gui_wimp_event_register_ok(w, INTERFACE_OK_BUTTON, + ro_gui_options_interface_ok); + ro_gui_wimp_event_set_help_prefix(w, "HelpInterfaceConfig"); + ro_gui_wimp_event_memorise(w); + return true; + +} + + +bool ro_gui_options_interface_click(wimp_pointer *pointer) +{ + bool shaded; + + switch (pointer->i) { + case INTERFACE_USE_EXTERNAL_HOTLIST: + shaded = !ro_gui_get_icon_selected_state(pointer->w, + INTERFACE_USE_EXTERNAL_HOTLIST); + ro_gui_set_icon_shaded_state(pointer->w, + INTERFACE_EXTERNAL_HOTLIST_APP, shaded); + return false; + break; + } + return false; +} + + + +void ro_gui_options_interface_default(wimp_pointer *pointer) +{ + ro_gui_set_icon_selected_state(pointer->w, + INTERFACE_STRIP_EXTNS_OPTION, true); + ro_gui_set_icon_selected_state(pointer->w, + INTERFACE_CONFIRM_OVWR_OPTION, true); + ro_gui_set_icon_selected_state(pointer->w, + INTERFACE_URL_COMPLETE_OPTION, true); + ro_gui_set_icon_selected_state(pointer->w, + INTERFACE_HISTORY_TOOLTIP_OPTION, true); + ro_gui_set_icon_selected_state(pointer->w, + INTERFACE_THUMBNAIL_ICONISE_OPTION, true); + ro_gui_set_icon_selected_state(pointer->w, + INTERFACE_USE_EXTERNAL_HOTLIST, false); + ro_gui_set_icon_string(pointer->w, INTERFACE_EXTERNAL_HOTLIST_APP, + "", false); +} + +bool ro_gui_options_interface_ok(wimp_w w) +{ + nsoption_set_bool(strip_extensions, + ro_gui_get_icon_selected_state(w, + INTERFACE_STRIP_EXTNS_OPTION)); + nsoption_set_bool(confirm_overwrite, + ro_gui_get_icon_selected_state(w, + INTERFACE_CONFIRM_OVWR_OPTION)); + nsoption_set_bool(url_suggestion, + ro_gui_get_icon_selected_state(w, + INTERFACE_URL_COMPLETE_OPTION)); + nsoption_set_bool(history_tooltip, + ro_gui_get_icon_selected_state(w, + INTERFACE_HISTORY_TOOLTIP_OPTION)); + nsoption_set_bool(thumbnail_iconise, + ro_gui_get_icon_selected_state(w, + INTERFACE_THUMBNAIL_ICONISE_OPTION)); + nsoption_set_bool(external_hotlists, + ro_gui_get_icon_selected_state(w, + INTERFACE_USE_EXTERNAL_HOTLIST)); + nsoption_set_charp(external_hotlist_app, + strdup(ro_gui_get_icon_string(w, + INTERFACE_EXTERNAL_HOTLIST_APP))); + + ro_gui_save_options(); + return true; +} diff --git a/frontends/riscos/configure/con_language.c b/frontends/riscos/configure/con_language.c new file mode 100644 index 000000000..2030c65c0 --- /dev/null +++ b/frontends/riscos/configure/con_language.c @@ -0,0 +1,139 @@ +/* + * Copyright 2004 John M Bell <jmb202@ecs.soton.ac.uk> + * Copyright 2006 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdbool.h> + +#include "utils/nsoption.h" +#include "utils/log.h" +#include "utils/messages.h" + +#include "riscos/gui.h" +#include "riscos/menus.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" +#include "riscos/configure.h" +#include "riscos/configure/configure.h" +#include "riscos/dialog.h" + + +#define LANGUAGE_INTERFACE_FIELD 3 +#define LANGUAGE_INTERFACE_GRIGHT 4 +#define LANGUAGE_WEB_PAGES_FIELD 6 +#define LANGUAGE_WEB_PAGES_GRIGHT 7 +#define LANGUAGE_DEFAULT_BUTTON 8 +#define LANGUAGE_CANCEL_BUTTON 9 +#define LANGUAGE_OK_BUTTON 10 + +static void ro_gui_options_language_default(wimp_pointer *pointer); +static bool ro_gui_options_language_ok(wimp_w w); +static const char *ro_gui_options_language_name(const char *code); + +bool ro_gui_options_language_initialise(wimp_w w) +{ + /* set the current values */ + ro_gui_set_icon_string(w, LANGUAGE_INTERFACE_FIELD, + ro_gui_options_language_name(nsoption_charp(language) ? + nsoption_charp(language) : "en"), true); + ro_gui_set_icon_string(w, LANGUAGE_WEB_PAGES_FIELD, + ro_gui_options_language_name(nsoption_charp(accept_language) ? + nsoption_charp(accept_language) : "en"), true); + + /* initialise all functions for a newly created window */ + ro_gui_wimp_event_register_menu_gright(w, LANGUAGE_INTERFACE_FIELD, + LANGUAGE_INTERFACE_GRIGHT, languages_menu); + ro_gui_wimp_event_register_menu_gright(w, LANGUAGE_WEB_PAGES_FIELD, + LANGUAGE_WEB_PAGES_GRIGHT, languages_menu); + ro_gui_wimp_event_register_button(w, LANGUAGE_DEFAULT_BUTTON, + ro_gui_options_language_default); + ro_gui_wimp_event_register_cancel(w, LANGUAGE_CANCEL_BUTTON); + ro_gui_wimp_event_register_ok(w, LANGUAGE_OK_BUTTON, + ro_gui_options_language_ok); + ro_gui_wimp_event_set_help_prefix(w, "HelpLanguageConfig"); + ro_gui_wimp_event_memorise(w); + return true; + +} + +void ro_gui_options_language_default(wimp_pointer *pointer) +{ + const char *code; + + code = ro_gui_default_language(); + ro_gui_set_icon_string(pointer->w, LANGUAGE_INTERFACE_FIELD, + ro_gui_options_language_name(code ? + code : "en"), true); + ro_gui_set_icon_string(pointer->w, LANGUAGE_WEB_PAGES_FIELD, + ro_gui_options_language_name(code ? + code : "en"), true); +} + +bool ro_gui_options_language_ok(wimp_w w) +{ + const char *code; + char *temp; + + code = ro_gui_menu_find_menu_entry_key(languages_menu, + ro_gui_get_icon_string(w, LANGUAGE_INTERFACE_FIELD)); + if (code) { + code += 5; /* skip 'lang_' */ + if ((!nsoption_charp(language)) || + (strcmp(nsoption_charp(language), code))) { + temp = strdup(code); + if (temp) { + nsoption_set_charp(language, temp); + } else { + LOG("No memory to duplicate language code"); + ro_warn_user("NoMemory", 0); + } + } + } + code = ro_gui_menu_find_menu_entry_key(languages_menu, + ro_gui_get_icon_string(w, LANGUAGE_WEB_PAGES_FIELD)); + if (code) { + code += 5; /* skip 'lang_' */ + if ((!nsoption_charp(accept_language)) || + (strcmp(nsoption_charp(accept_language), code))) { + temp = strdup(code); + if (temp) { + nsoption_set_charp(accept_language,temp); + } else { + LOG("No memory to duplicate language code"); + ro_warn_user("NoMemory", 0); + } + } + } + ro_gui_save_options(); + return true; +} + + +/** + * Convert a 2-letter ISO language code to the language name. + * + * \param code 2-letter ISO language code + * \return language name, or code if unknown + */ +const char *ro_gui_options_language_name(const char *code) +{ + char key[] = "lang_xx"; + key[5] = code[0]; + key[6] = code[1]; + + return messages_get(key); +} diff --git a/frontends/riscos/configure/con_secure.c b/frontends/riscos/configure/con_secure.c new file mode 100644 index 000000000..9c8a846c3 --- /dev/null +++ b/frontends/riscos/configure/con_secure.c @@ -0,0 +1,83 @@ +/* + * Copyright 2006 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdbool.h> + +#include "utils/nsoption.h" +#include "utils/messages.h" + +#include "riscos/gui.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" +#include "riscos/configure.h" +#include "riscos/configure/configure.h" +#include "riscos/dialog.h" + +#define SECURITY_REFERRER 2 +#define SECURITY_DURATION_FIELD 6 +#define SECURITY_DURATION_INC 7 +#define SECURITY_DURATION_DEC 8 +#define SECURITY_DEFAULT_BUTTON 10 +#define SECURITY_CANCEL_BUTTON 11 +#define SECURITY_OK_BUTTON 12 + +static void ro_gui_options_security_default(wimp_pointer *pointer); +static bool ro_gui_options_security_ok(wimp_w w); + +bool ro_gui_options_security_initialise(wimp_w w) +{ + /* set the current values */ + ro_gui_set_icon_selected_state(w, SECURITY_REFERRER, + nsoption_bool(send_referer)); + ro_gui_set_icon_integer(w, SECURITY_DURATION_FIELD, + nsoption_int(expire_url)); + + /* initialise all functions for a newly created window */ + ro_gui_wimp_event_register_checkbox(w, SECURITY_REFERRER); + ro_gui_wimp_event_register_numeric_field(w, SECURITY_DURATION_FIELD, + SECURITY_DURATION_DEC, SECURITY_DURATION_INC, + 0, 365, 1, 0); + ro_gui_wimp_event_register_button(w, SECURITY_DEFAULT_BUTTON, + ro_gui_options_security_default); + ro_gui_wimp_event_register_cancel(w, SECURITY_CANCEL_BUTTON); + ro_gui_wimp_event_register_ok(w, SECURITY_OK_BUTTON, + ro_gui_options_security_ok); + ro_gui_wimp_event_set_help_prefix(w, "HelpSecurityConfig"); + ro_gui_wimp_event_memorise(w); + return true; + +} + +void ro_gui_options_security_default(wimp_pointer *pointer) +{ + /* set the default values */ + ro_gui_set_icon_integer(pointer->w, SECURITY_DURATION_FIELD, 28); + ro_gui_set_icon_selected_state(pointer->w, SECURITY_REFERRER, true); +} + +bool ro_gui_options_security_ok(wimp_w w) +{ + nsoption_set_bool(send_referer, + ro_gui_get_icon_selected_state(w, SECURITY_REFERRER)); + + nsoption_set_int(expire_url, + ro_gui_get_icon_decimal(w,SECURITY_DURATION_FIELD, 0)); + + ro_gui_save_options(); + return true; +} diff --git a/frontends/riscos/configure/con_theme.c b/frontends/riscos/configure/con_theme.c new file mode 100644 index 000000000..fb0d3dfb0 --- /dev/null +++ b/frontends/riscos/configure/con_theme.c @@ -0,0 +1,420 @@ +/* + * Copyright 2006 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#include <oslib/osspriteop.h> +#include <oslib/wimp.h> +#include <oslib/wimpspriteop.h> + +#include "utils/config.h" +#include "utils/nsoption.h" +#include "utils/log.h" +#include "utils/messages.h" + +#include "riscos/gui.h" +#include "riscos/configure/configure.h" +#include "riscos/configure.h" +#include "riscos/dialog.h" +#include "riscos/menus.h" +#include "riscos/theme.h" +#include "riscos/toolbar.h" +#include "riscos/url_complete.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" +#include "riscos/wimputils.h" + + +#define THEME_PANE_AREA 0 +#define THEME_DEFAULT_BUTTON 2 +#define THEME_CANCEL_BUTTON 3 +#define THEME_OK_BUTTON 4 + +struct toolbar_display { + struct toolbar *toolbar; + struct theme_descriptor *descriptor; + int icon_number; + struct toolbar_display *next; +}; + +static wimp_window theme_pane_definition = { + {0, 0, 16, 16}, + 0, + 0, + wimp_TOP, + wimp_WINDOW_NEW_FORMAT | wimp_WINDOW_VSCROLL | wimp_WINDOW_AUTO_REDRAW, + wimp_COLOUR_BLACK, + wimp_COLOUR_LIGHT_GREY, + wimp_COLOUR_LIGHT_GREY, + wimp_COLOUR_VERY_LIGHT_GREY, + wimp_COLOUR_DARK_GREY, + wimp_COLOUR_MID_LIGHT_GREY, + wimp_COLOUR_CREAM, + 0, + {0, -16384, 16384, 0}, + wimp_ICON_TEXT | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED, + wimp_BUTTON_CLICK << wimp_ICON_BUTTON_TYPE_SHIFT, + wimpspriteop_AREA, + 1, + 1, + {""}, + 0, + {} +}; + + +static wimp_w theme_pane; +static struct theme_descriptor *theme_list = NULL; +static struct toolbar_display *toolbars = NULL; +static char theme_radio_validation[] = "Sradiooff,radioon"; +static char theme_null_validation[] = ""; +static char theme_line_validation[] = "R2"; + +static bool ro_gui_options_theme_ok(wimp_w w); +static bool ro_gui_options_theme_click(wimp_pointer *pointer); +static void ro_gui_options_theme_load(void); +static void ro_gui_options_theme_free(void); + +bool ro_gui_options_theme_initialise(wimp_w w) +{ + wimp_window_state state; + wimp_icon_state icon_state; + os_error *error; + struct theme_descriptor *theme_choice; + struct toolbar_display *toolbar; + + /* only allow one instance for now*/ + if (theme_pane) + return false; + error = xwimp_create_window(&theme_pane_definition, &theme_pane); + if (error) { + LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess); + return false; + } + state.w = w; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + return false; + } + icon_state.w = w; + icon_state.i = THEME_PANE_AREA; + error = xwimp_get_icon_state(&icon_state); + if (error) { + LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess); + return false; + } + state.w = theme_pane; + state.visible.x1 = state.visible.x0 + icon_state.icon.extent.x1 - 16 - + ro_get_vscroll_width(theme_pane); + state.visible.x0 += icon_state.icon.extent.x0 + 16; + state.visible.y0 = state.visible.y1 + icon_state.icon.extent.y0 + 16; + state.visible.y1 += icon_state.icon.extent.y1 - 28; + LOG("Y0 = %i, y1 = %i", icon_state.icon.extent.y0, icon_state.icon.extent.y1); + error = xwimp_open_window_nested(PTR_WIMP_OPEN(&state), w, + wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT + << wimp_CHILD_XORIGIN_SHIFT | + wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT + << wimp_CHILD_YORIGIN_SHIFT | + wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT + << wimp_CHILD_LS_EDGE_SHIFT | + wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT + << wimp_CHILD_BS_EDGE_SHIFT | + wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT + << wimp_CHILD_RS_EDGE_SHIFT | + wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT + << wimp_CHILD_TS_EDGE_SHIFT); + if (error) { + LOG("xwimp_open_window_nested: 0x%x: %s", error->errnum, error->errmess); + return false; + } + + /* load themes */ + ro_gui_options_theme_load(); + + /* set the current selection */ + theme_choice = ro_gui_theme_find(nsoption_charp(theme)); + if (!theme_choice) + theme_choice = ro_gui_theme_find("Aletheia"); + for (toolbar = toolbars; toolbar; toolbar = toolbar->next) + ro_gui_set_icon_selected_state(theme_pane, toolbar->icon_number, + (toolbar->descriptor == theme_choice)); + ro_gui_wimp_event_memorise(theme_pane); + ro_gui_wimp_event_set_help_prefix(theme_pane, "HelpThemePConfig"); + + ro_gui_wimp_event_register_mouse_click(w, ro_gui_options_theme_click); + ro_gui_wimp_event_register_cancel(w, THEME_CANCEL_BUTTON); + ro_gui_wimp_event_register_ok(w, THEME_OK_BUTTON, + ro_gui_options_theme_ok); + ro_gui_wimp_event_set_help_prefix(w, "HelpThemeConfig"); + ro_gui_wimp_event_memorise(w); + + return true; +} + +void ro_gui_options_theme_finalise(wimp_w w) +{ + ro_gui_options_theme_free(); + if (theme_pane) { + os_error *error; + ro_gui_wimp_event_finalise(theme_pane); + error = xwimp_delete_window(theme_pane); + if (error) { + LOG("xwimp_delete_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + theme_pane = 0; + } + ro_gui_wimp_event_finalise(w); +} + +bool ro_gui_options_theme_ok(wimp_w w) +{ + struct toolbar_display *toolbar; + struct theme_descriptor *theme_new = NULL; + + /* find the current selection */ + for (toolbar = toolbars; toolbar; toolbar = toolbar->next) { + if (ro_gui_get_icon_selected_state(theme_pane, toolbar->icon_number)) { + theme_new = toolbar->descriptor; + break; + } + } + + /* set the options */ + if (theme_new) { + nsoption_set_charp(theme, strdup(theme_new->leafname)); + ro_gui_theme_apply(theme_new); + } else { + nsoption_set_charp(theme, NULL); + } + ro_gui_save_options(); + + /* store the pane status */ + ro_gui_wimp_event_memorise(theme_pane); + return true; +} + +bool ro_gui_options_theme_click(wimp_pointer *pointer) +{ + struct theme_descriptor *theme_default; + struct toolbar_display *toolbar; + + switch (pointer->i) { + case THEME_DEFAULT_BUTTON: + theme_default = ro_gui_theme_find("Aletheia"); + for (toolbar = toolbars; toolbar; toolbar = toolbar->next) + ro_gui_set_icon_selected_state(theme_pane, + toolbar->icon_number, + (toolbar->descriptor == theme_default)); + break; + case THEME_CANCEL_BUTTON: + ro_gui_wimp_event_restore(theme_pane); + break; + case THEME_OK_BUTTON: + ro_gui_wimp_event_memorise(theme_pane); + break; + } + return false; +} + +void ro_gui_options_theme_load(void) +{ + os_error *error; + os_box extent = { 0, 0, 0, 0 }; + struct theme_descriptor *descriptor; + struct toolbar_display *link; + struct toolbar_display *toolbar_display; + struct toolbar *toolbar; + wimp_icon_create new_icon; + wimp_window_state state; + int parent_width, nested_y, min_extent, base_extent; + int *radio_icons, *radio_set; + int theme_count; + + /* delete our old list and get/open a new one */ + ro_gui_options_theme_free(); + theme_list = ro_gui_theme_get_available(); + ro_gui_theme_open(theme_list, true); + + /* create toolbars for each theme */ + theme_count = 0; + descriptor = theme_list; + while (descriptor != NULL) { + /* try to create a toolbar */ + toolbar = ro_toolbar_create(descriptor, NULL, + THEME_STYLE_BROWSER_TOOLBAR, + TOOLBAR_FLAGS_DISPLAY, NULL, NULL, NULL); + if (toolbar != NULL) { + ro_toolbar_add_buttons(toolbar, brower_toolbar_buttons, + nsoption_charp(toolbar_browser)); + ro_toolbar_add_url(toolbar); + ro_toolbar_add_throbber(toolbar); + ro_toolbar_rebuild(toolbar); + toolbar_display = calloc(sizeof(struct toolbar_display), 1); + if (!toolbar_display) { + LOG("No memory for calloc()"); + ro_warn_user("NoMemory", 0); + return; + } + toolbar_display->toolbar = toolbar; + toolbar_display->descriptor = descriptor; + if (!toolbars) { + toolbars = toolbar_display; + } else { + link = toolbars; + while (link->next) link = link->next; + link->next = toolbar_display; + } + theme_count++; + } + descriptor = descriptor->next; + } + + /* nest the toolbars */ + state.w = theme_pane; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + parent_width = state.visible.x1 - state.visible.x0; + min_extent = state.visible.y0 - state.visible.y1; + nested_y = 0; + base_extent = state.visible.y1 - state.yscroll; + extent.x1 = parent_width; + link = toolbars; + new_icon.w = theme_pane; + new_icon.icon.flags = wimp_ICON_TEXT | wimp_ICON_INDIRECTED | + wimp_ICON_VCENTRED | + (wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT) | + (wimp_COLOUR_VERY_LIGHT_GREY << wimp_ICON_BG_COLOUR_SHIFT); + while (link) { + /* update the toolbar */ + int item_height = 44 + 44 + 16; + if (link->next) item_height += 16; + ro_toolbar_process(link->toolbar, parent_width, false); + extent.y0 = nested_y - + ro_toolbar_height(link->toolbar) - + item_height; + if (link->next) extent.y0 -= 16; + if (extent.y0 > min_extent) extent.y0 = min_extent; + xwimp_set_extent(theme_pane, &extent); + + /* create the descriptor icons and separator line */ + new_icon.icon.extent.x0 = 8; + new_icon.icon.extent.x1 = parent_width - 8; + new_icon.icon.flags &= ~wimp_ICON_BORDER; + new_icon.icon.flags |= wimp_ICON_SPRITE; + new_icon.icon.extent.y1 = nested_y - + ro_toolbar_height(link->toolbar) - 8; + new_icon.icon.extent.y0 = nested_y - + ro_toolbar_height(link->toolbar) - 52; + new_icon.icon.data.indirected_text_and_sprite.text = + (char *)&link->descriptor->name; + new_icon.icon.data.indirected_text_and_sprite.size = + strlen(link->descriptor->name) + 1; + new_icon.icon.data.indirected_text_and_sprite.validation = + theme_radio_validation; + new_icon.icon.flags |= (wimp_BUTTON_RADIO << + wimp_ICON_BUTTON_TYPE_SHIFT); + xwimp_create_icon(&new_icon, &link->icon_number); + new_icon.icon.flags &= ~wimp_ICON_SPRITE; + new_icon.icon.extent.x0 = 52; + new_icon.icon.extent.y1 -= 44; + new_icon.icon.extent.y0 -= 44; + new_icon.icon.data.indirected_text.text = + (char *)&link->descriptor->author; + new_icon.icon.data.indirected_text.size = + strlen(link->descriptor->author) + 1; + new_icon.icon.data.indirected_text.validation = + theme_null_validation; + new_icon.icon.flags &= ~(wimp_BUTTON_RADIO << + wimp_ICON_BUTTON_TYPE_SHIFT); + xwimp_create_icon(&new_icon, 0); + if (link->next) { + new_icon.icon.flags |= wimp_ICON_BORDER; + new_icon.icon.extent.x0 = -8; + new_icon.icon.extent.x1 = parent_width + 8; + new_icon.icon.extent.y1 -= 52; + new_icon.icon.extent.y0 = new_icon.icon.extent.y1 - 8; + new_icon.icon.data.indirected_text.text = + theme_null_validation; + new_icon.icon.data.indirected_text.validation = + theme_line_validation; + new_icon.icon.data.indirected_text.size = 1; + xwimp_create_icon(&new_icon, 0); + } + + /* nest the toolbar window */ + state.w = ro_toolbar_get_window(link->toolbar); + state.yscroll = 0; + state.visible.y1 = nested_y + base_extent; + state.visible.y0 = state.visible.y1 - + ro_toolbar_height(link->toolbar) + 2; + xwimp_open_window_nested(PTR_WIMP_OPEN(&state), theme_pane, + wimp_CHILD_LINKS_PARENT_WORK_AREA + << wimp_CHILD_BS_EDGE_SHIFT | + wimp_CHILD_LINKS_PARENT_WORK_AREA + << wimp_CHILD_TS_EDGE_SHIFT); + + /* continue processing */ + nested_y -= ro_toolbar_height(link->toolbar) + + item_height; + link = link->next; + } + + /* set the icons as radios */ + radio_icons = (int *)calloc(theme_count + 1, sizeof(int)); + radio_set = radio_icons; + for (link = toolbars; link; link = link->next) + *radio_set++ = link->icon_number; + *radio_set = -1; + ro_gui_wimp_event_register_radio(theme_pane, radio_icons); + + /* update our display */ + xwimp_force_redraw(theme_pane, 0, -16384, 16384, 16384); +} + +void ro_gui_options_theme_free(void) +{ + struct toolbar_display *toolbar; + struct toolbar_display *next_toolbar; + + /* free all our toolbars */ + next_toolbar = toolbars; + while ((toolbar = next_toolbar) != NULL) { + next_toolbar = toolbar->next; + xwimp_delete_icon(theme_pane, toolbar->icon_number); + xwimp_delete_icon(theme_pane, toolbar->icon_number + 1); + if (next_toolbar) + xwimp_delete_icon(theme_pane, + toolbar->icon_number + 2); + ro_toolbar_destroy(toolbar->toolbar); + free(toolbar); + } + toolbars = NULL; + + /* close all our themes */ + if (theme_list) + ro_gui_theme_close(theme_list, true); + theme_list = NULL; +} diff --git a/frontends/riscos/configure/configure.h b/frontends/riscos/configure/configure.h new file mode 100644 index 000000000..e5cdb392e --- /dev/null +++ b/frontends/riscos/configure/configure.h @@ -0,0 +1,43 @@ +/* + * Copyright 2005 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Automated RISC OS WIMP event handling (interface). + */ + + +#ifndef _NETSURF_RISCOS_OPTIONS_CONFIGURE_H_ +#define _NETSURF_RISCOS_OPTIONS_CONFIGURE_H_ + +#include <stdbool.h> +#include "oslib/wimp.h" + +bool ro_gui_options_cache_initialise(wimp_w w); +bool ro_gui_options_connection_initialise(wimp_w w); +bool ro_gui_options_content_initialise(wimp_w w); +bool ro_gui_options_fonts_initialise(wimp_w w); +bool ro_gui_options_home_initialise(wimp_w w); +bool ro_gui_options_image_initialise(wimp_w w); +void ro_gui_options_image_finalise(wimp_w w); +bool ro_gui_options_interface_initialise(wimp_w w); +bool ro_gui_options_language_initialise(wimp_w w); +bool ro_gui_options_security_initialise(wimp_w w); +bool ro_gui_options_theme_initialise(wimp_w w); +void ro_gui_options_theme_finalise(wimp_w w); + +#endif diff --git a/frontends/riscos/content-handlers/artworks.c b/frontends/riscos/content-handlers/artworks.c new file mode 100644 index 000000000..b6f7a0d08 --- /dev/null +++ b/frontends/riscos/content-handlers/artworks.c @@ -0,0 +1,435 @@ +/* + * Copyright 2005 Adrian Lees <adrianl@users.sourceforge.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Content for image/x-artworks (RISC OS implementation). + * + * Uses the ArtworksRenderer module + */ + +#include "utils/config.h" +#ifdef WITH_ARTWORKS + +#include <assert.h> +#include <limits.h> +#include <stdlib.h> +#include "swis.h" +#include "oslib/os.h" +#include "oslib/wimp.h" + +#include "utils/config.h" +#include "utils/log.h" +#include "utils/messages.h" +#include "utils/utils.h" +#include "content/content_protected.h" +#include "desktop/plotters.h" + +#include "riscos/content-handlers/artworks.h" +#include "riscos/gui.h" +#include "riscos/wimputils.h" + +#define AWRender_FileInitAddress 0x46080 +#define AWRender_RenderAddress 0x46081 +#define AWRender_DocBounds 0x46082 +#define AWRender_SendDefs 0x46083 +#define AWRender_ClaimVectors 0x46084 +#define AWRender_ReleaseVectors 0x46085 +#define AWRender_FindFirstFont 0x46086 +#define AWRender_FindNextFont 0x46087 + + +#define INITIAL_BLOCK_SIZE 0x1000 + +typedef struct artworks_content { + struct content base; + + int x0, y0, x1, y1; + + void *render_routine; + void *render_workspace; + + /* dynamically-resizable block required by + ArtWorksRenderer rendering routine */ + + void *block; + size_t size; +} artworks_content; + +struct awinfo_block { + int ditherx; + int dithery; + int clip_x0; + int clip_y0; + int clip_x1; + int clip_y1; + int print_lowx; + int print_lowy; + int print_handle; + int print_x1; + int print_y1; + int bgcolour; +}; + + +/* Assembler routines for interfacing with the ArtworksRenderer module */ + +extern os_error *awrender_init(const char **doc, + unsigned long *doc_size, + void *routine, + void *workspace); + +extern os_error *awrender_render(const char *doc, + const struct awinfo_block *info, + const os_trfm *trans, + const int *vdu_vars, + void **rsz_block, + size_t *rsz_size, + int wysiwyg_setting, + int output_dest, + size_t doc_size, + void *routine, + void *workspace); + +static nserror artworks_create(const content_handler *handler, + lwc_string *imime_type, const struct http_parameter *params, + llcache_handle *llcache, const char *fallback_charset, + bool quirks, struct content **c); +static bool artworks_convert(struct content *c); +static void artworks_destroy(struct content *c); +static bool artworks_redraw(struct content *c, struct content_redraw_data *data, + const struct rect *clip, const struct redraw_context *ctx); +static nserror artworks_clone(const struct content *old, struct content **newc); +static content_type artworks_content_type(void); + +static const content_handler artworks_content_handler = { + .create = artworks_create, + .data_complete = artworks_convert, + .destroy = artworks_destroy, + .redraw = artworks_redraw, + .clone = artworks_clone, + .type = artworks_content_type, + .no_share = false, +}; + +static const char *artworks_types[] = { + "image/x-artworks" +}; + +CONTENT_FACTORY_REGISTER_TYPES(artworks, artworks_types, + artworks_content_handler) + +nserror artworks_create(const content_handler *handler, + lwc_string *imime_type, const struct http_parameter *params, + llcache_handle *llcache, const char *fallback_charset, + bool quirks, struct content **c) +{ + artworks_content *aw; + nserror error; + + aw = calloc(1, sizeof(artworks_content)); + if (aw == NULL) + return NSERROR_NOMEM; + + error = content__init(&aw->base, handler, imime_type, params, + llcache, fallback_charset, quirks); + if (error != NSERROR_OK) { + free(aw); + return error; + } + + *c = (struct content *) aw; + + return NSERROR_OK; +} + +/** + * Convert a CONTENT_ARTWORKS for display. + * + * No conversion is necessary. We merely read the ArtWorks + * bounding box bottom-left. + */ + +bool artworks_convert(struct content *c) +{ + artworks_content *aw = (artworks_content *) c; + union content_msg_data msg_data; + const char *source_data; + unsigned long source_size; + void *init_workspace; + void *init_routine; + os_error *error; + int used = -1; /* slightly better with older OSLib versions */ + char *title; + + /* check whether AWViewer has been seen and we can therefore + locate the ArtWorks rendering modules */ + xos_read_var_val_size("Alias$LoadArtWorksModules", 0, os_VARTYPE_STRING, + &used, NULL, NULL); + if (used >= 0) { + LOG("Alias$LoadArtWorksModules not defined"); + msg_data.error = messages_get("AWNotSeen"); + content_broadcast(c, CONTENT_MSG_ERROR, msg_data); + return false; + } + + /* load the modules, or do nothing if they're already loaded */ + error = xos_cli("LoadArtWorksModules"); + if (error) { + LOG("xos_cli: 0x%x: %s", error->errnum, error->errmess); + msg_data.error = error->errmess; + content_broadcast(c, CONTENT_MSG_ERROR, msg_data); + return false; + } + + /* lookup the addresses of the init and render routines */ + error = (os_error*)_swix(AWRender_FileInitAddress, _OUT(0) | _OUT(1), + &init_routine, &init_workspace); + if (error) { + LOG("AWRender_FileInitAddress: 0x%x: %s", error->errnum, error->errmess); + msg_data.error = error->errmess; + content_broadcast(c, CONTENT_MSG_ERROR, msg_data); + return false; + } + + error = (os_error*)_swix(AWRender_RenderAddress, _OUT(0) | _OUT(1), + &aw->render_routine, + &aw->render_workspace); + if (error) { + LOG("AWRender_RenderAddress: 0x%x: %s", error->errnum, error->errmess); + msg_data.error = error->errmess; + content_broadcast(c, CONTENT_MSG_ERROR, msg_data); + return false; + } + + source_data = content__get_source_data(c, &source_size); + + /* initialise (convert file to new format if required) */ + error = awrender_init(&source_data, &source_size, + init_routine, init_workspace); + if (error) { + LOG("awrender_init: 0x%x : %s", error->errnum, error->errmess); + msg_data.error = error->errmess; + content_broadcast(c, CONTENT_MSG_ERROR, msg_data); + return false; + } + + error = (os_error*)_swix(AWRender_DocBounds, + _IN(0) | _OUT(2) | _OUT(3) | _OUT(4) | _OUT(5), + source_data, + &aw->x0, + &aw->y0, + &aw->x1, + &aw->y1); + + if (error) { + LOG("AWRender_DocBounds: 0x%x: %s", error->errnum, error->errmess); + msg_data.error = error->errmess; + content_broadcast(c, CONTENT_MSG_ERROR, msg_data); + return false; + } + + LOG("bounding box: %d,%d,%d,%d", aw->x0, aw->y0, aw->x1, aw->y1); + + /* create the resizable workspace required by the + ArtWorksRenderer rendering routine */ + + aw->size = INITIAL_BLOCK_SIZE; + aw->block = malloc(INITIAL_BLOCK_SIZE); + if (!aw->block) { + LOG("failed to create block for ArtworksRenderer"); + msg_data.error = messages_get("NoMemory"); + content_broadcast(c, CONTENT_MSG_ERROR, msg_data); + return false; + } + + c->width = (aw->x1 - aw->x0) / 512; + c->height = (aw->y1 - aw->y0) / 512; + + title = messages_get_buff("ArtWorksTitle", + nsurl_access_leaf(llcache_handle_get_url(c->llcache)), + c->width, c->height); + if (title != NULL) { + content__set_title(c, title); + free(title); + } + content_set_ready(c); + content_set_done(c); + /* Done: update status bar */ + content_set_status(c, ""); + return true; +} + + +/** + * Destroy a CONTENT_ARTWORKS and free all resources it owns. + */ + +void artworks_destroy(struct content *c) +{ + artworks_content *aw = (artworks_content *) c; + + free(aw->block); +} + + +/** + * Redraw a CONTENT_ARTWORKS. + */ + +bool artworks_redraw(struct content *c, struct content_redraw_data *data, + const struct rect *clip, const struct redraw_context *ctx) +{ + static const ns_os_vdu_var_list vars = { + os_MODEVAR_XEIG_FACTOR, + { + os_MODEVAR_YEIG_FACTOR, + os_MODEVAR_LOG2_BPP, + os_VDUVAR_END_LIST + } + }; + artworks_content *aw = (artworks_content *) c; + struct awinfo_block info; + const char *source_data; + unsigned long source_size; + os_error *error; + os_trfm matrix; + int vals[24]; + + int clip_x0 = clip->x0; + int clip_y0 = clip->y0; + int clip_x1 = clip->x1; + int clip_y1 = clip->y1; + + if (ctx->plot->flush && !ctx->plot->flush()) + return false; + + /* pick up render addresses again in case they've changed + (eg. newer AWRender module loaded since we first loaded this file) */ + (void)_swix(AWRender_RenderAddress, _OUT(0) | _OUT(1), + &aw->render_routine, + &aw->render_workspace); + + /* Scaled image. Transform units (65536*OS units) */ + matrix.entries[0][0] = data->width * 65536 / c->width; + matrix.entries[0][1] = 0; + matrix.entries[1][0] = 0; + matrix.entries[1][1] = data->height * 65536 / c->height; + /* Draw units. (x,y) = bottom left */ + matrix.entries[2][0] = ro_plot_origin_x * 256 + data->x * 512 - + aw->x0 * data->width / c->width; + matrix.entries[2][1] = ro_plot_origin_y * 256 - + (data->y + data->height) * 512 - + aw->y0 * data->height / c->height; + + info.ditherx = ro_plot_origin_x; + info.dithery = ro_plot_origin_y; + + clip_x0 -= data->x; + clip_y0 -= data->y; + clip_x1 -= data->x; + clip_y1 -= data->y; + + if (data->scale == 1.0) { + info.clip_x0 = (clip_x0 * 512) + aw->x0 - 511; + info.clip_y0 = ((c->height - clip_y1) * 512) + aw->y0 - 511; + info.clip_x1 = (clip_x1 * 512) + aw->x0 + 511; + info.clip_y1 = ((c->height - clip_y0) * 512) + aw->y0 + 511; + } + else { + info.clip_x0 = (clip_x0 * 512 / data->scale) + aw->x0 - 511; + info.clip_y0 = ((c->height - (clip_y1 / data->scale)) * 512) + + aw->y0 - 511; + info.clip_x1 = (clip_x1 * 512 / data->scale) + aw->x0 + 511; + info.clip_y1 = ((c->height - (clip_y0 / data->scale)) * 512) + + aw->y0 + 511; + } + + info.print_lowx = 0; + info.print_lowy = 0; + info.print_handle = 0; + info.bgcolour = 0x20000000 | data->background_colour; + + error = xos_read_vdu_variables(PTR_OS_VDU_VAR_LIST(&vars), vals); + if (error) { + LOG("xos_read_vdu_variables: 0x%x: %s", error->errnum, error->errmess); + return false; + } + + error = xwimp_read_palette((os_palette*)&vals[3]); + if (error) { + LOG("xwimp_read_palette: 0x%x: %s", error->errnum, error->errmess); + return false; + } + + source_data = content__get_source_data(c, &source_size); + + error = awrender_render(source_data, + &info, + &matrix, + vals, + &aw->block, + &aw->size, + 110, /* fully anti-aliased */ + 0, + source_size, + aw->render_routine, + aw->render_workspace); + + if (error) { + LOG("awrender_render: 0x%x: %s", error->errnum, error->errmess); + return false; + } + + return true; +} + +nserror artworks_clone(const struct content *old, struct content **newc) +{ + artworks_content *aw; + nserror error; + + aw = calloc(1, sizeof(artworks_content)); + if (aw == NULL) + return NSERROR_NOMEM; + + error = content__clone(old, &aw->base); + if (error != NSERROR_OK) { + content_destroy(&aw->base); + return error; + } + + /* Simply re-run convert */ + if (old->status == CONTENT_STATUS_READY || + old->status == CONTENT_STATUS_DONE) { + if (artworks_convert(&aw->base) == false) { + content_destroy(&aw->base); + return NSERROR_CLONE_FAILED; + } + } + + *newc = (struct content *) aw; + + return NSERROR_OK; +} + +content_type artworks_content_type(void) +{ + return CONTENT_IMAGE; +} + +#endif diff --git a/frontends/riscos/content-handlers/artworks.h b/frontends/riscos/content-handlers/artworks.h new file mode 100644 index 000000000..67832cc54 --- /dev/null +++ b/frontends/riscos/content-handlers/artworks.h @@ -0,0 +1,42 @@ +/* + * Copyright 2005 Adrian Lees <adrianl@users.sourceforge.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Content for image/x-artworks (RISC OS interface). + */ + +#ifndef _NETSURF_RISCOS_ARTWORKS_H_ +#define _NETSURF_RISCOS_ARTWORKS_H_ + +#include "utils/config.h" +#include "utils/errors.h" + +#ifdef WITH_ARTWORKS + +nserror artworks_init(void); + +#else + +static inline nserror artworks_init(void) +{ + return NSERROR_OK; +} + +#endif + +#endif diff --git a/frontends/riscos/content-handlers/awrender.s b/frontends/riscos/content-handlers/awrender.s new file mode 100644 index 000000000..5bcafe520 --- /dev/null +++ b/frontends/riscos/content-handlers/awrender.s @@ -0,0 +1,390 @@ +#if defined(__aof__) + AREA |ARM$$code|,CODE,READONLY + + IMPORT messages_get + IMPORT realloc + IMPORT strcpy + IMPORT |__rt_stkovf_split_big| + + EXPORT awrender_init + EXPORT awrender_render + + +aw_rsz_block * 0 +aw_rsz_size * 4 +aw_fixed_block * 8 +aw_fixed_size * 12 +aw_sl * 16 +aw_fp * 20 +sizeof_aw * 24 + + +; os_error *awrender_init(byte **doc, size_t *doc_size, void *init_routine, void *init_workspace); + +awrender_init MOV ip,sp + STMFD sp!,{a1,a2,v1,v2,fp,ip,lr,pc} + SUB fp,ip,#4 + SUB ip,sp,#512 + CMP ip,sl + BLMI |__rt_stkovf_split_big| + + LDR v2,=aw_temp + LDR a1,[a1] + MOV v1,a3 + LDR a3,[a2] + MOV ip,a4 + STR a1,[v2,#aw_rsz_block] + STR a3,[v2,#aw_rsz_size] + MOV a2,#-1 + STR a2,[v2,#aw_fixed_block] + STR a3,[v2,#aw_fixed_size] + STR sl,[v2,#aw_sl] + STR fp,[v2,#aw_fp] + ADR a2,aw_callback + MOV lr,pc + MOV pc,v1 + MOVVC a1,#0 + + ;return updated block ptr & size to caller + + LDR a2,[fp,#-28] + LDR a3,[fp,#-24] + LDR ip,[v2,#aw_rsz_block] + LDR lr,[v2,#aw_rsz_size] + STR ip,[a2] + STR lr,[a3] + + LDMEA fp,{v1,v2,fp,sp,pc} + + +; os_error *awrender_render(const char *doc, +; const struct awinfo_block *info, +; const os_trfm *trans, +; const int *vdu_vars, +; char **rsz_block, +; size_t *rsz_size, +; int wysiwyg_setting, +; int output_dest, +; size_t doc_size, +; void *routine, +; void *workspace); + +awrender_render MOV ip,sp + STMFD sp!,{v1-v4,fp,ip,lr,pc} + SUB fp,ip,#4 + SUB ip,sp,#512 + CMP ip,sl + BLMI |__rt_stkovf_split_big| + + LDR R12,[fp,#20] + LDR R14,=aw_temp + LDR R5,[fp,#4] + LDR R6,[fp,#12] + LDR R4,[R5] ;resizable block + LDR R7,[fp,#16] + STR R4,[R14,#aw_rsz_block] + STR R0,[R14,#aw_fixed_block] ;document ptr + STR R12,[R14,#aw_fixed_size] ;document size + LDR R12,[fp,#8] + + STR R5,[sp,#-4]! ;ptr to receive block + STR R12,[sp,#-4]! ;ptr to receive size + + LDR R12,[R12] + ADR R5,aw_callback + STR R12,[R14,#aw_rsz_size] + + STR sl,[R14,#aw_sl] + STR fp,[R14,#aw_fp] + + LDR R12,[fp,#28] + MOV lr,pc + LDR pc,[fp,#24] + MOVVC a1,#0 + + ;return updated block ptr & size to caller + + LDR R7,=aw_temp + LDR R12,[sp],#4 + LDR R4,[sp],#4 + LDR R5,[R7,#aw_rsz_size] + LDR R6,[R7,#aw_rsz_block] + STR R5,[R12] + STR R6,[R4] + + LDMEA fp,{v1-v4,fp,sp,pc} + + +; Callback routine for block resizing +; (passed to AWRender init and render routines) +; +; entry R11 = reason code +; 0 = CallBackReason_Memory +; 3 = CallBackReason_Interface +; (0 => return capabilities) +; exit R0 => base of resizable block +; R1 = size of resizable block +; R2 => base of fixed block (or -1 if no fixed block) +; R3 = size of fixed block (or document in resizable block) +; VC if resize successful, VS and R0 => error otherwise + +aw_callback TEQ R11,#3 + TEQEQ R0,#0 + MOVEQ R0,#1<<10 ;background colour supplied + TEQ R11,#0 + LDREQ R11,=aw_temp + MOVNE PC,R14 + + CMP R0,#-1 ;read block size? + LDRNE R2,[R11,#aw_rsz_size] + MOVNE R1,R0 ;new block size + LDR R0,[R11,#aw_rsz_block] + BEQ aw_read + + ; Note: because ArtworksRenderer seems to call + ; this routine for every scanline rendered + ; we never call realloc unless we have to in + ; order to expand the block. Also it calls + ; us with a size request of 0 which we must + ; safely ignore otherwise rendering will stop. + + CMP R1,R2 + BLS aw_read + + STMFD R13!,{R1,R10-R12,R14} + LDR sl,[R11,#aw_sl] + LDR fp,[R11,#aw_fp] + BL realloc + LDMFD R13!,{R1,R10-R12,R14} + + CMP R0,#0 ;did it work? + BEQ aw_nomem + + STR R0,[R11] + STR R1,[R11,#aw_rsz_size] + +aw_read ; return details of fixed block + + LDR R2,[R11,#aw_fixed_block] + LDR R3,[R11,#aw_fixed_size] + SUBS R11,R11,R11 ;clear V + MOV PC,R14 + +aw_nomem STMFD R13!,{R10,R12,R14} + LDR sl,[R11,#aw_sl] + LDR fp,[R11,#aw_fp] + ADR R0,tok_nomem + BL messages_get + MOV a2,a1 + LDR a1,=errblk + 4 + BL strcpy + SUB R0,R0,#4 ;error number already 0 + MOV R11,#0 ;restore reason code + CMP PC,#1<<31 ;set V + LDMFD R13!,{R10,R12,PC} + +tok_nomem = "NoMemory",0 + ALIGN + + + AREA |ARM$$zidata|,DATA,NOINIT + +aw_temp % sizeof_aw +errblk % 256 + + END + +#elif defined(__ELF__) + + .text + +.set aw_rsz_block, 0 +.set aw_rsz_size, 4 +.set aw_fixed_block, 8 +.set aw_fixed_size, 12 +.set aw_sl, 16 +.set aw_fp, 20 +.set sizeof_aw, 24 + +@ os_error *awrender_init(byte **doc, size_t *doc_size, void *init_routine, void *init_workspace); + + .global awrender_init +awrender_init: MOV ip,sp + STMFD sp!,{a1,a2,v1,v2,fp,ip,lr,pc} + SUB fp,ip,#4 + SUB ip,sp,#512 + CMP ip,sl + BLMI __rt_stkovf_split_big + + LDR v2,=aw_temp + LDR a1,[a1] + MOV v1,a3 + LDR a3,[a2] + MOV ip,a4 + STR a1,[v2,#aw_rsz_block] + STR a3,[v2,#aw_rsz_size] + MOV a2,#-1 + STR a2,[v2,#aw_fixed_block] + STR a3,[v2,#aw_fixed_size] + STR sl,[v2,#aw_sl] + STR fp,[v2,#aw_fp] + ADR a2,aw_callback + MOV lr,pc + MOV pc,v1 + MOVVC a1,#0 + + @ return updated block ptr & size to caller + + LDR a2,[fp,#-28] + LDR a3,[fp,#-24] + LDR ip,[v2,#aw_rsz_block] + LDR lr,[v2,#aw_rsz_size] + STR ip,[a2] + STR lr,[a3] + + LDMEA fp,{v1,v2,fp,sp,pc} + + +@ os_error *awrender_render(const char *doc, +@ const struct awinfo_block *info, +@ const os_trfm *trans, +@ const int *vdu_vars, +@ char **rsz_block, +@ size_t *rsz_size, +@ int wysiwyg_setting, +@ int output_dest, +@ size_t doc_size, +@ void *routine, +@ void *workspace); + + .global awrender_render +awrender_render: MOV ip,sp + STMFD sp!,{v1-v4,fp,ip,lr,pc} + SUB fp,ip,#4 + SUB ip,sp,#512 + CMP ip,sl + BLMI __rt_stkovf_split_big + + LDR R12,[fp,#20] + LDR R14,=aw_temp + LDR R5,[fp,#4] + LDR R6,[fp,#12] + LDR R4,[R5] @ resizable block + LDR R7,[fp,#16] + STR R4,[R14,#aw_rsz_block] + STR R0,[R14,#aw_fixed_block] @ document ptr + STR R12,[R14,#aw_fixed_size] @ document size + LDR R12,[fp,#8] + + STR R5,[sp,#-4]! @ ptr to receive block + STR R12,[sp,#-4]! @ ptr to receive size + + LDR R12,[R12] + ADR R5,aw_callback + STR R12,[R14,#aw_rsz_size] + + STR sl,[R14,#aw_sl] + STR fp,[R14,#aw_fp] + + LDR R12,[fp,#28] + MOV lr,pc + LDR pc,[fp,#24] + MOVVC a1,#0 + + @ return updated block ptr & size to caller + + LDR R7,=aw_temp + LDR R12,[sp],#4 + LDR R4,[sp],#4 + LDR R5,[R7,#aw_rsz_size] + LDR R6,[R7,#aw_rsz_block] + STR R5,[R12] + STR R6,[R4] + + LDMEA fp,{v1-v4,fp,sp,pc} + + +@ Callback routine for block resizing +@ (passed to AWRender init and render routines) +@ +@ entry R11 = reason code +@ 0 = CallBackReason_Memory +@ 3 = CallBackReason_Interface +@ (0 => return capabilities) +@ exit R0 => base of resizable block +@ R1 = size of resizable block +@ R2 => base of fixed block (or -1 if no fixed block) +@ R3 = size of fixed block (or document in resizable block) +@ VC if resize successful, VS and R0 => error otherwise + +aw_callback: TEQ R11,#3 + TEQEQ R0,#0 + MOVEQ R0,#1<<10 @ background colour supplied + TEQ R11,#0 + LDREQ R11,=aw_temp + MOVNE PC,R14 + + CMP R0,#-1 @ read block size? + LDRNE R2,[R11,#aw_rsz_size] + MOVNE R1,R0 @ new block size + LDR R0,[R11,#aw_rsz_block] + BEQ aw_read + + @ Note: because ArtworksRenderer seems to call + @ this routine for every scanline rendered + @ we never call realloc unless we have to in + @ order to expand the block. Also it calls + @ us with a size request of 0 which we must + @ safely ignore otherwise rendering will stop. + + CMP R1,R2 + BLS aw_read + + STMFD R13!,{R1,R10-R12,R14} + LDR sl,[R11,#aw_sl] + LDR fp,[R11,#aw_fp] + BL realloc + LDMFD R13!,{R1,R10-R12,R14} + + CMP R0,#0 @ did it work? + BEQ aw_nomem + + STR R0,[R11] + STR R1,[R11,#aw_rsz_size] + +aw_read: @ return details of fixed block + + LDR R2,[R11,#aw_fixed_block] + LDR R3,[R11,#aw_fixed_size] + SUBS R11,R11,R11 @ clear V + MOV PC,R14 + +aw_nomem: STMFD R13!,{R10,R12,R14} + LDR sl,[R11,#aw_sl] + LDR fp,[R11,#aw_fp] + ADR R0,tok_nomem + BL messages_get + MOV a2,a1 + LDR a1,=errblk + 4 + BL strcpy + SUB R0,R0,#4 @ error number already 0 + MOV R11,#0 @ restore reason code + CMP PC,#1<<31 @ set V + LDMFD R13!,{R10,R12,PC} + +tok_nomem: .asciz "NoMemory" + .align + + .bss + +aw_temp: .space sizeof_aw + .type aw_temp, %object + .size aw_temp, . - aw_temp + +errblk: .space 256 + .type errblk, %object + .size errblk, . - errblk + + .end +#endif + diff --git a/frontends/riscos/content-handlers/draw.c b/frontends/riscos/content-handlers/draw.c new file mode 100644 index 000000000..f2bee16dc --- /dev/null +++ b/frontends/riscos/content-handlers/draw.c @@ -0,0 +1,254 @@ +/* + * Copyright 2003 John M Bell <jmb202@ecs.soton.ac.uk> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Content for image/x-drawfile (RISC OS implementation). + * + * The DrawFile module is used to plot the DrawFile. + */ + +#include "utils/config.h" +#ifdef WITH_DRAW + +#include <string.h> +#include <stdlib.h> +#include "oslib/drawfile.h" + +#include "utils/config.h" +#include "utils/log.h" +#include "utils/messages.h" +#include "utils/utils.h" +#include "content/content_protected.h" +#include "desktop/plotters.h" + +#include "riscos/content-handlers/draw.h" +#include "riscos/gui.h" + +typedef struct draw_content { + struct content base; + + int x0, y0; +} draw_content; + +static nserror draw_create(const content_handler *handler, + lwc_string *imime_type, const struct http_parameter *params, + llcache_handle *llcache, const char *fallback_charset, + bool quirks, struct content **c); +static bool draw_convert(struct content *c); +static void draw_destroy(struct content *c); +static bool draw_redraw(struct content *c, struct content_redraw_data *data, + const struct rect *clip, const struct redraw_context *ctx); +static nserror draw_clone(const struct content *old, struct content **newc); +static content_type draw_content_type(void); + +static const content_handler draw_content_handler = { + .create = draw_create, + .data_complete = draw_convert, + .destroy = draw_destroy, + .redraw = draw_redraw, + .clone = draw_clone, + .type = draw_content_type, + .no_share = false, +}; + +static const char *draw_types[] = { + "application/drawfile", + "application/x-drawfile", + "image/drawfile", + "image/x-drawfile" +}; + +CONTENT_FACTORY_REGISTER_TYPES(draw, draw_types, draw_content_handler) + +nserror draw_create(const content_handler *handler, + lwc_string *imime_type, const struct http_parameter *params, + llcache_handle *llcache, const char *fallback_charset, + bool quirks, struct content **c) +{ + draw_content *draw; + nserror error; + + draw = calloc(1, sizeof(draw_content)); + if (draw == NULL) + return NSERROR_NOMEM; + + error = content__init(&draw->base, handler, imime_type, params, + llcache, fallback_charset, quirks); + if (error != NSERROR_OK) { + free(draw); + return error; + } + + *c = (struct content *) draw; + + return NSERROR_OK; +} + +/** + * Convert a CONTENT_DRAW for display. + * + * No conversion is necessary. We merely read the DrawFile dimensions and + * bounding box bottom-left. + */ + +bool draw_convert(struct content *c) +{ + draw_content *draw = (draw_content *) c; + union content_msg_data msg_data; + const char *source_data; + unsigned long source_size; + const void *data; + os_box bbox; + os_error *error; + char *title; + + source_data = content__get_source_data(c, &source_size); + data = source_data; + + /* BBox contents in Draw units (256*OS unit) */ + error = xdrawfile_bbox(0, (drawfile_diagram *) data, + (int) source_size, 0, &bbox); + if (error) { + LOG("xdrawfile_bbox: 0x%x: %s", error->errnum, error->errmess); + msg_data.error = error->errmess; + content_broadcast(c, CONTENT_MSG_ERROR, msg_data); + return false; + } + + if (bbox.x1 > bbox.x0 && bbox.y1 > bbox.y0) { + /* c->width & c->height stored as (OS units/2) + => divide by 512 to convert from draw units */ + c->width = ((bbox.x1 - bbox.x0) / 512); + c->height = ((bbox.y1 - bbox.y0) / 512); + } + else + /* invalid/undefined bounding box */ + c->height = c->width = 0; + + draw->x0 = bbox.x0; + draw->y0 = bbox.y0; + + title = messages_get_buff("DrawTitle", + nsurl_access_leaf(llcache_handle_get_url(c->llcache)), + c->width, c->height); + if (title != NULL) { + content__set_title(c, title); + free(title); + } + + content_set_ready(c); + content_set_done(c); + /* Done: update status bar */ + content_set_status(c, ""); + return true; +} + + +/** + * Destroy a CONTENT_DRAW and free all resources it owns. + */ + +void draw_destroy(struct content *c) +{ +} + + +/** + * Redraw a CONTENT_DRAW. + */ + +bool draw_redraw(struct content *c, struct content_redraw_data *data, + const struct rect *clip, const struct redraw_context *ctx) +{ + draw_content *draw = (draw_content *) c; + os_trfm matrix; + const char *source_data; + unsigned long source_size; + const void *src_data; + os_error *error; + + if (ctx->plot->flush && !ctx->plot->flush()) + return false; + + if (!c->width || !c->height) + return false; + + source_data = content__get_source_data(c, &source_size); + src_data = source_data; + + /* Scaled image. Transform units (65536*OS units) */ + matrix.entries[0][0] = data->width * 65536 / c->width; + matrix.entries[0][1] = 0; + matrix.entries[1][0] = 0; + matrix.entries[1][1] = data->height * 65536 / c->height; + /* Draw units. (x,y) = bottom left */ + matrix.entries[2][0] = ro_plot_origin_x * 256 + data->x * 512 - + draw->x0 * data->width / c->width; + matrix.entries[2][1] = ro_plot_origin_y * 256 - + (data->y + data->height) * 512 - + draw->y0 * data->height / c->height; + + error = xdrawfile_render(0, (drawfile_diagram *) src_data, + (int) source_size, &matrix, 0, 0); + if (error) { + LOG("xdrawfile_render: 0x%x: %s", error->errnum, error->errmess); + return false; + } + + return true; +} + +/** + * Clone a CONTENT_DRAW + */ + +nserror draw_clone(const struct content *old, struct content **newc) +{ + draw_content *draw; + nserror error; + + draw = calloc(1, sizeof(draw_content)); + if (draw == NULL) + return NSERROR_NOMEM; + + error = content__clone(old, &draw->base); + if (error != NSERROR_OK) { + content_destroy(&draw->base); + return error; + } + + /* Simply rerun convert */ + if (old->status == CONTENT_STATUS_READY || + old->status == CONTENT_STATUS_DONE) { + if (draw_convert(&draw->base) == false) { + content_destroy(&draw->base); + return NSERROR_CLONE_FAILED; + } + } + + *newc = (struct content *) draw; + + return NSERROR_OK; +} + +content_type draw_content_type(void) +{ + return CONTENT_IMAGE; +} + +#endif diff --git a/frontends/riscos/content-handlers/draw.h b/frontends/riscos/content-handlers/draw.h new file mode 100644 index 000000000..9f5baf6dc --- /dev/null +++ b/frontends/riscos/content-handlers/draw.h @@ -0,0 +1,42 @@ +/* + * Copyright 2003 John M Bell <jmb202@ecs.soton.ac.uk> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Content for image/x-drawfile (RISC OS interface). + */ + +#ifndef _NETSURF_RISCOS_DRAW_H_ +#define _NETSURF_RISCOS_DRAW_H_ + +#include "utils/config.h" +#include "utils/errors.h" + +#ifdef WITH_DRAW + +nserror draw_init(void); + +#else + +static inline nserror draw_init(void) +{ + return NSERROR_OK; +} + +#endif /* WITH_DRAW */ + +#endif diff --git a/frontends/riscos/content-handlers/sprite.c b/frontends/riscos/content-handlers/sprite.c new file mode 100644 index 000000000..12fed4931 --- /dev/null +++ b/frontends/riscos/content-handlers/sprite.c @@ -0,0 +1,266 @@ +/* + * Copyright 2003 John M Bell <jmb202@ecs.soton.ac.uk> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Content for image/x-riscos-sprite (RISC OS implementation). + * + * No conversion is necessary: we can render RISC OS sprites directly under + * RISC OS. + */ + +#include <string.h> +#include <stdlib.h> +#include "oslib/osspriteop.h" + +#include "utils/config.h" +#include "utils/config.h" +#include "utils/log.h" +#include "utils/messages.h" +#include "utils/utils.h" +#include "content/content_protected.h" +#include "desktop/plotters.h" + +#include "riscos/gui.h" +#include "riscos/image.h" +#include "riscos/content-handlers/sprite.h" + +#ifdef WITH_SPRITE + +typedef struct sprite_content { + struct content base; + + void *data; +} sprite_content; + +static nserror sprite_create(const content_handler *handler, + lwc_string *imime_type, const struct http_parameter *params, + llcache_handle *llcache, const char *fallback_charset, + bool quirks, struct content **c); +static bool sprite_convert(struct content *c); +static void sprite_destroy(struct content *c); +static bool sprite_redraw(struct content *c, struct content_redraw_data *data, + const struct rect *clip, const struct redraw_context *ctx); +static nserror sprite_clone(const struct content *old, struct content **newc); +static content_type sprite_content_type(void); + +static const content_handler sprite_content_handler = { + .create = sprite_create, + .data_complete = sprite_convert, + .destroy = sprite_destroy, + .redraw = sprite_redraw, + .clone = sprite_clone, + .type = sprite_content_type, + .no_share = false, +}; + +static const char *sprite_types[] = { + "image/x-riscos-sprite" +}; + +CONTENT_FACTORY_REGISTER_TYPES(sprite, sprite_types, sprite_content_handler) + +nserror sprite_create(const content_handler *handler, + lwc_string *imime_type, const struct http_parameter *params, + llcache_handle *llcache, const char *fallback_charset, + bool quirks, struct content **c) +{ + sprite_content *sprite; + nserror error; + + sprite = calloc(1, sizeof(sprite_content)); + if (sprite == NULL) + return NSERROR_NOMEM; + + error = content__init(&sprite->base, handler, imime_type, params, + llcache, fallback_charset, quirks); + if (error != NSERROR_OK) { + free(sprite); + return error; + } + + *c = (struct content *) sprite; + + return NSERROR_OK; +} + +/** + * Convert a CONTENT_SPRITE for display. + * + * No conversion is necessary. We merely read the sprite dimensions. + */ + +bool sprite_convert(struct content *c) +{ + sprite_content *sprite = (sprite_content *) c; + os_error *error; + int w, h; + union content_msg_data msg_data; + const char *source_data; + unsigned long source_size; + const void *sprite_data; + char *title; + + source_data = content__get_source_data(c, &source_size); + + sprite_data = source_data - 4; + osspriteop_area *area = (osspriteop_area*) sprite_data; + sprite->data = area; + + /* check for bad data */ + if ((int)source_size + 4 != area->used) { + msg_data.error = messages_get("BadSprite"); + content_broadcast(c, CONTENT_MSG_ERROR, msg_data); + return false; + } + + error = xosspriteop_read_sprite_info(osspriteop_PTR, + (osspriteop_area *)0x100, + (osspriteop_id) ((char *) area + area->first), + &w, &h, NULL, NULL); + if (error) { + LOG("xosspriteop_read_sprite_info: 0x%x: %s", error->errnum, error->errmess); + msg_data.error = error->errmess; + content_broadcast(c, CONTENT_MSG_ERROR, msg_data); + return false; + } + + c->width = w; + c->height = h; + + /* set title text */ + title = messages_get_buff("SpriteTitle", + nsurl_access_leaf(llcache_handle_get_url(c->llcache)), + c->width, c->height); + if (title != NULL) { + content__set_title(c, title); + free(title); + } + content_set_ready(c); + content_set_done(c); + /* Done: update status bar */ + content_set_status(c, ""); + return true; +} + + +/** + * Destroy a CONTENT_SPRITE and free all resources it owns. + */ + +void sprite_destroy(struct content *c) +{ + /* do not free c->data.sprite.data at it is simply a pointer to + * 4 bytes beforec->source_data. */ +} + + +/** + * Redraw a CONTENT_SPRITE. + */ + +bool sprite_redraw(struct content *c, struct content_redraw_data *data, + const struct rect *clip, const struct redraw_context *ctx) +{ + sprite_content *sprite = (sprite_content *) c; + + if (ctx->plot->flush && !ctx->plot->flush()) + return false; + + return image_redraw(sprite->data, + ro_plot_origin_x + data->x * 2, + ro_plot_origin_y - data->y * 2, + data->width, data->height, + c->width, + c->height, + data->background_colour, + false, false, false, + IMAGE_PLOT_OS); +} + +nserror sprite_clone(const struct content *old, struct content **newc) +{ + sprite_content *sprite; + nserror error; + + sprite = calloc(1, sizeof(sprite_content)); + if (sprite == NULL) + return NSERROR_NOMEM; + + error = content__clone(old, &sprite->base); + if (error != NSERROR_OK) { + content_destroy(&sprite->base); + return error; + } + + /* Simply rerun convert */ + if (old->status == CONTENT_STATUS_READY || + old->status == CONTENT_STATUS_DONE) { + if (sprite_convert(&sprite->base) == false) { + content_destroy(&sprite->base); + return NSERROR_CLONE_FAILED; + } + } + + *newc = (struct content *) sprite; + + return NSERROR_OK; +} + +content_type sprite_content_type(void) +{ + return CONTENT_IMAGE; +} + +#endif + + +/** + * Returns the bit depth of a sprite + * + * \param s sprite + * \return depth in bpp + */ + +byte sprite_bpp(const osspriteop_header *s) +{ + /* bit 31 indicates the presence of a full alpha channel + * rather than a binary mask */ + int type = ((unsigned)s->mode >> osspriteop_TYPE_SHIFT) & 15; + byte bpp = 0; + + switch (type) { + case osspriteop_TYPE_OLD: + { + bits psr; + int val; + if (!xos_read_mode_variable(s->mode, + os_MODEVAR_LOG2_BPP, &val, &psr) && + !(psr & _C)) + bpp = 1 << val; + } + break; + case osspriteop_TYPE1BPP: bpp = 1; break; + case osspriteop_TYPE2BPP: bpp = 2; break; + case osspriteop_TYPE4BPP: bpp = 4; break; + case osspriteop_TYPE8BPP: bpp = 8; break; + case osspriteop_TYPE16BPP: bpp = 16; break; + case osspriteop_TYPE32BPP: bpp = 32; break; + case osspriteop_TYPE_CMYK: bpp = 32; break; + } + return bpp; +} diff --git a/frontends/riscos/content-handlers/sprite.h b/frontends/riscos/content-handlers/sprite.h new file mode 100644 index 000000000..ab6d312a5 --- /dev/null +++ b/frontends/riscos/content-handlers/sprite.h @@ -0,0 +1,44 @@ +/* + * Copyright 2003 John M Bell <jmb202@ecs.soton.ac.uk> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Content for image/x-riscos-sprite (RISC OS interface). + */ + +#ifndef _NETSURF_RISCOS_SPRITE_H_ +#define _NETSURF_RISCOS_SPRITE_H_ + +#include "utils/config.h" +#include "utils/errors.h" + +#ifdef WITH_SPRITE + +nserror sprite_init(void); + +#else + +static inline nserror sprite_init(void) +{ + return NSERROR_OK; +} + +#endif + +byte sprite_bpp(const osspriteop_header *s); + +#endif diff --git a/frontends/riscos/cookies.c b/frontends/riscos/cookies.c new file mode 100644 index 000000000..93c9f39cf --- /dev/null +++ b/frontends/riscos/cookies.c @@ -0,0 +1,385 @@ +/* + * Copyright 2006 Richard Wilson <info@tinct.net> + * Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Cookies (implementation). + */ + +#include <assert.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include "oslib/wimp.h" +#include "oslib/wimpspriteop.h" + +#include "utils/nsoption.h" +#include "utils/messages.h" +#include "utils/log.h" +#include "content/urldb.h" +#include "desktop/cookie_manager.h" +#include "desktop/tree.h" +#include "desktop/textinput.h" + +#include "riscos/cookies.h" +#include "riscos/dialog.h" +#include "riscos/menus.h" +#include "riscos/toolbar.h" +#include "riscos/treeview.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" + +static void ro_gui_cookies_toolbar_update_buttons(void); +static void ro_gui_cookies_toolbar_save_buttons(char *config); +static bool ro_gui_cookies_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_pointer *pointer); +static void ro_gui_cookies_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_selection *selection, menu_action action); +static bool ro_gui_cookies_menu_select(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_selection *selection, menu_action action); +static void ro_gui_cookies_toolbar_click(button_bar_action action); + +struct ro_treeview_callbacks ro_cookies_treeview_callbacks = { + ro_gui_cookies_toolbar_click, + ro_gui_cookies_toolbar_update_buttons, + ro_gui_cookies_toolbar_save_buttons +}; + +/* The RISC OS cookie window, toolbar and treeview data. */ + +static struct ro_cookies_window { + wimp_w window; + struct toolbar *toolbar; + ro_treeview *tv; + wimp_menu *menu; +} cookies_window; + +/** + * Pre-Initialise the cookies tree. This is called for things that + * need to be done at the gui_init() stage, such as loading templates. + */ + +void ro_gui_cookies_preinitialise(void) +{ + /* Create our window. */ + + cookies_window.window = ro_gui_dialog_create("tree"); + ro_gui_set_window_title(cookies_window.window, + messages_get("Cookies")); +} + +/** + * Initialise cookies tree, at the gui_init2() stage. + */ + +void ro_gui_cookies_postinitialise(void) +{ + /* Create our toolbar. */ + + cookies_window.toolbar = ro_toolbar_create(NULL, cookies_window.window, + THEME_STYLE_COOKIES_TOOLBAR, TOOLBAR_FLAGS_NONE, + ro_treeview_get_toolbar_callbacks(), NULL, + "HelpCookiesToolbar"); + if (cookies_window.toolbar != NULL) { + ro_toolbar_add_buttons(cookies_window.toolbar, + cookies_toolbar_buttons, + nsoption_charp(toolbar_cookies)); + ro_toolbar_rebuild(cookies_window.toolbar); + } + + /* Create the treeview with the window and toolbar. */ + + cookies_window.tv = ro_treeview_create(cookies_window.window, + cookies_window.toolbar, &ro_cookies_treeview_callbacks, + TREE_COOKIES); + if (cookies_window.tv == NULL) { + LOG("Failed to allocate treeview"); + return; + } + + ro_toolbar_update_client_data(cookies_window.toolbar, + cookies_window.tv); + + /* Build the cookies window menu. */ + + static const struct ns_menu cookies_definition = { + "Cookies", { + { "Cookies", NO_ACTION, 0 }, + { "Cookies.Expand", TREE_EXPAND_ALL, 0 }, + { "Cookies.Expand.All", TREE_EXPAND_ALL, 0 }, + { "Cookies.Expand.Folders", TREE_EXPAND_FOLDERS, 0 }, + { "Cookies.Expand.Links", TREE_EXPAND_LINKS, 0 }, + { "Cookies.Collapse", TREE_COLLAPSE_ALL, 0 }, + { "Cookies.Collapse.All", TREE_COLLAPSE_ALL, 0 }, + { "Cookies.Collapse.Folders", TREE_COLLAPSE_FOLDERS, 0 }, + { "Cookies.Collapse.Links", TREE_COLLAPSE_LINKS, 0 }, + { "Cookies.Toolbars", NO_ACTION, 0 }, + { "_Cookies.Toolbars.ToolButtons", TOOLBAR_BUTTONS, 0 }, + { "Cookies.Toolbars.EditToolbar",TOOLBAR_EDIT, 0 }, + { "Selection", TREE_SELECTION, 0 }, + { "Selection.Delete", TREE_SELECTION_DELETE, 0 }, + { "SelectAll", TREE_SELECT_ALL, 0 }, + { "Clear", TREE_CLEAR_SELECTION, 0 }, + {NULL, 0, 0} + } + }; + cookies_window.menu = ro_gui_menu_define_menu(&cookies_definition); + + ro_gui_wimp_event_register_menu(cookies_window.window, + cookies_window.menu, false, false); + ro_gui_wimp_event_register_menu_prepare(cookies_window.window, + ro_gui_cookies_menu_prepare); + ro_gui_wimp_event_register_menu_selection(cookies_window.window, + ro_gui_cookies_menu_select); + ro_gui_wimp_event_register_menu_warning(cookies_window.window, + ro_gui_cookies_menu_warning); +} + +/** + * Destroy the cookies window. + */ + +void ro_gui_cookies_destroy(void) +{ + if (cookies_window.tv == NULL) + return; + + ro_treeview_destroy(cookies_window.tv); +} + +/** + * Open the cookies window. + * + */ + +void ro_gui_cookies_open(void) +{ + ro_gui_cookies_toolbar_update_buttons(); + + if (!ro_gui_dialog_open_top(cookies_window.window, + cookies_window.toolbar, 600, 800)) { + ro_treeview_set_origin(cookies_window.tv, 0, + -(ro_toolbar_height(cookies_window.toolbar))); + } +} + + +/** + * Handle toolbar button clicks. + * + * \param action The action to handle + */ + +void ro_gui_cookies_toolbar_click(button_bar_action action) +{ + switch (action) { + case TOOLBAR_BUTTON_DELETE: + cookie_manager_keypress(NS_KEY_DELETE_LEFT); + break; + + case TOOLBAR_BUTTON_EXPAND: + cookie_manager_expand(false); + break; + + case TOOLBAR_BUTTON_COLLAPSE: + cookie_manager_contract(false); + break; + + case TOOLBAR_BUTTON_OPEN: + cookie_manager_expand(true); + break; + + case TOOLBAR_BUTTON_CLOSE: + cookie_manager_contract(true); + break; + + default: + break; + } +} + + +/** + * Update the button state in the cookies toolbar. + */ + +void ro_gui_cookies_toolbar_update_buttons(void) +{ + ro_toolbar_set_button_shaded_state(cookies_window.toolbar, + TOOLBAR_BUTTON_DELETE, + !cookie_manager_has_selection()); +} + + +/** + * Save a new button arrangement in the cookies toolbar. + * + * \param *config The new button configuration string. + */ + +void ro_gui_cookies_toolbar_save_buttons(char *config) +{ + nsoption_set_charp(toolbar_cookies, config); + ro_gui_save_options(); +} + + +/** + * Prepare the cookies menu for opening + * + * \param w The window owning the menu. + * \param i The icon owning the menu. + * \param *menu The menu about to be opened. + * \param *pointer Pointer to the relevant wimp event block, or + * NULL for an Adjust click. + * \return true if the event was handled; else false. + */ + +bool ro_gui_cookies_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_pointer *pointer) +{ + bool selection; + + if (menu != cookies_window.menu) + return false; + + selection = cookie_manager_has_selection(); + + ro_gui_menu_set_entry_shaded(cookies_window.menu, + TREE_SELECTION, !selection); + ro_gui_menu_set_entry_shaded(cookies_window.menu, + TREE_CLEAR_SELECTION, !selection); + + ro_gui_menu_set_entry_shaded(menu, TOOLBAR_BUTTONS, + ro_toolbar_menu_option_shade(cookies_window.toolbar)); + ro_gui_menu_set_entry_ticked(menu, TOOLBAR_BUTTONS, + ro_toolbar_menu_buttons_tick(cookies_window.toolbar)); + + ro_gui_menu_set_entry_shaded(menu, TOOLBAR_EDIT, + ro_toolbar_menu_edit_shade(cookies_window.toolbar)); + ro_gui_menu_set_entry_ticked(menu, TOOLBAR_EDIT, + ro_toolbar_menu_edit_tick(cookies_window.toolbar)); + + return true; +} + +/** + * Handle submenu warnings for the cookies menu + * + * \param w The window owning the menu. + * \param i The icon owning the menu. + * \param *menu The menu to which the warning applies. + * \param *selection The wimp menu selection data. + * \param action The selected menu action. + */ + +void ro_gui_cookies_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_selection *selection, menu_action action) +{ + /* Do nothing */ +} + +/** + * Handle selections from the cookies menu + * + * \param w The window owning the menu. + * \param i The icon owning the menu. + * \param *menu The menu from which the selection was made. + * \param *selection The wimp menu selection data. + * \param action The selected menu action. + * \return true if action accepted; else false. + */ + +bool ro_gui_cookies_menu_select(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_selection *selection, menu_action action) +{ + switch (action) { + case TREE_EXPAND_ALL: + cookie_manager_expand(false); + return true; + case TREE_EXPAND_FOLDERS: + cookie_manager_expand(true); + return true; + case TREE_EXPAND_LINKS: + cookie_manager_expand(false); + return true; + case TREE_COLLAPSE_ALL: + cookie_manager_contract(true); + return true; + case TREE_COLLAPSE_FOLDERS: + cookie_manager_contract(true); + return true; + case TREE_COLLAPSE_LINKS: + cookie_manager_contract(false); + return true; + case TREE_SELECTION_DELETE: + cookie_manager_keypress(NS_KEY_DELETE_LEFT); + return true; + case TREE_SELECT_ALL: + cookie_manager_keypress(NS_KEY_SELECT_ALL); + return true; + case TREE_CLEAR_SELECTION: + cookie_manager_keypress(NS_KEY_CLEAR_SELECTION); + return true; + case TOOLBAR_BUTTONS: + ro_toolbar_set_display_buttons(cookies_window.toolbar, + !ro_toolbar_get_display_buttons( + cookies_window.toolbar)); + return true; + case TOOLBAR_EDIT: + ro_toolbar_toggle_edit(cookies_window.toolbar); + return true; + default: + return false; + } + + return false; +} + +/** + * Check if a particular window handle is the cookies window + * + * \param window the window in question + * \return true if this window is the cookies + */ + +bool ro_gui_cookies_check_window(wimp_w window) +{ + if (cookies_window.window == window) + return true; + else + return false; +} + +/** + * Check if a particular menu handle is the cookies menu + * + * \param *menu The menu in question. + * \return true if this menu is the cookies menu + */ + +bool ro_gui_cookies_check_menu(wimp_menu *menu) +{ + if (cookies_window.menu == menu) + return true; + else + return false; +} + diff --git a/frontends/riscos/cookies.h b/frontends/riscos/cookies.h new file mode 100644 index 000000000..b7313393e --- /dev/null +++ b/frontends/riscos/cookies.h @@ -0,0 +1,38 @@ +/* + * Copyright 2006 Richard Wilson <info@tinct.net> + * Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Cookies (interface). + */ + +#ifndef _NETSURF_RISCOS_COOKIES_H_ +#define _NETSURF_RISCOS_COOKIES_H_ + +#include "riscos/menus.h" + +void ro_gui_cookies_preinitialise(void); +void ro_gui_cookies_postinitialise(void); +void ro_gui_cookies_destroy(void); +bool ro_gui_cookies_check_window(wimp_w window); +bool ro_gui_cookies_check_menu(wimp_menu *menu); + +void ro_gui_cookies_open(void); + +#endif + diff --git a/frontends/riscos/dialog.c b/frontends/riscos/dialog.c new file mode 100644 index 000000000..d4356086d --- /dev/null +++ b/frontends/riscos/dialog.c @@ -0,0 +1,816 @@ +/* + * Copyright 2003 Phil Mellor <monkeyson@users.sourceforge.net> + * Copyright 2005 James Bursa <bursa@users.sourceforge.net> + * Copyright 2003 John M Bell <jmb202@ecs.soton.ac.uk> + * Copyright 2005 Richard Wilson <info@tinct.net> + * Copyright 2004 Andrew Timmins <atimmins@blueyonder.co.uk> + * Copyright 2005 Adrian Lees <adrianl@users.sourceforge.net> + * Copyright 2014 Stephen Fryatt <stevef@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "utils/config.h" + +#include <assert.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <oslib/colourtrans.h> +#include <oslib/osfile.h> +#include <oslib/osgbpb.h> +#include <oslib/osspriteop.h> +#include <oslib/wimp.h> + +#include "utils/nsoption.h" +#include "utils/log.h" +#include "utils/messages.h" +#include "utils/nsurl.h" +#include "desktop/version.h" +#include "desktop/browser.h" + +#include "riscos/configure.h" +#include "riscos/cookies.h" +#include "riscos/dialog.h" +#include "riscos/global_history.h" +#include "riscos/gui.h" +#include "riscos/hotlist.h" +#include "riscos/menus.h" +#include "riscos/save.h" +#include "riscos/sslcert.h" +#include "riscos/toolbar.h" +#include "riscos/url_complete.h" +#include "riscos/url_suggest.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" +#include "riscos/wimputils.h" + +#define ICON_ZOOM_VALUE 1 +#define ICON_ZOOM_DEC 2 +#define ICON_ZOOM_INC 3 +#define ICON_ZOOM_FRAMES 5 +#define ICON_ZOOM_CANCEL 7 +#define ICON_ZOOM_OK 8 + +/* The maximum number of persistent dialogues +*/ +#define MAX_PERSISTENT 64 + + +wimp_w dialog_info, dialog_saveas, + dialog_401li, + dialog_zoom, dialog_pageinfo, dialog_objinfo, dialog_tooltip, + dialog_warning, + dialog_folder, dialog_entry, dialog_search, dialog_print, + dialog_url_complete, dialog_openurl; + +struct gui_window *ro_gui_current_zoom_gui; + + +/* A simple mapping of parent and child +*/ +static struct { + wimp_w dialog; + wimp_w parent; +} persistent_dialog[MAX_PERSISTENT]; + + +static bool ro_gui_dialog_open_url_init(void); +static bool ro_gui_dialog_openurl_apply(wimp_w w); +static bool ro_gui_dialog_open_url_menu_prepare(wimp_w w, wimp_i i, + wimp_menu *menu, wimp_pointer *pointer); + +static bool ro_gui_dialog_zoom_apply(wimp_w w); + +/** + * Load and create dialogs from template file. + */ + +void ro_gui_dialog_init(void) +{ + /* warning dialog */ + dialog_warning = ro_gui_dialog_create("warning"); + ro_gui_wimp_event_register_ok(dialog_warning, ICON_WARNING_CONTINUE, + NULL); + ro_gui_wimp_event_set_help_prefix(dialog_warning, "HelpWarning"); + + /* tooltip for history */ + dialog_tooltip = ro_gui_dialog_create("tooltip"); + + /* configure window */ + ro_gui_configure_initialise(); + + /* 401 login window */ + ro_gui_401login_init(); + + /* theme installation */ + dialog_theme_install = ro_gui_dialog_create("theme_inst"); + ro_gui_wimp_event_register_cancel(dialog_theme_install, + ICON_THEME_INSTALL_CANCEL); + ro_gui_wimp_event_register_ok(dialog_theme_install, + ICON_THEME_INSTALL_INSTALL, + ro_gui_theme_install_apply); + ro_gui_wimp_event_set_help_prefix(dialog_theme_install, "HelpThemeInst"); + + /* search */ + ro_gui_search_init(); + + /* print */ + ro_gui_print_init(); + + /* about us */ + dialog_info = ro_gui_dialog_create("info"); + ro_gui_set_icon_string(dialog_info, 4, netsurf_version, true); + ro_gui_wimp_event_set_help_prefix(dialog_info, "HelpAppInfo"); + + /* page info */ + dialog_pageinfo = ro_gui_dialog_create("pageinfo"); + ro_gui_wimp_event_set_help_prefix(dialog_pageinfo, "HelpPageInfo"); + + /* object info */ + dialog_objinfo = ro_gui_dialog_create("objectinfo"); + ro_gui_wimp_event_set_help_prefix(dialog_objinfo, "HelpObjInfo"); + + /* save as */ + dialog_saveas = ro_gui_saveas_create("saveas"); + ro_gui_wimp_event_register_button(dialog_saveas, ICON_SAVE_ICON, + ro_gui_save_start_drag); + ro_gui_wimp_event_register_text_field(dialog_saveas, ICON_SAVE_PATH); + ro_gui_wimp_event_register_cancel(dialog_saveas, ICON_SAVE_CANCEL); + ro_gui_wimp_event_register_ok(dialog_saveas, ICON_SAVE_OK, + ro_gui_save_ok); + ro_gui_wimp_event_set_help_prefix(dialog_saveas, "HelpSaveAs"); + + /* url suggestion */ + dialog_url_complete = ro_gui_dialog_create("url_suggest"); + ro_gui_wimp_event_register_mouse_click(dialog_url_complete, + ro_gui_url_complete_click); + ro_gui_wimp_event_register_pointer_entering_window(dialog_url_complete, + ro_gui_url_complete_entering); + ro_gui_wimp_event_register_redraw_window(dialog_url_complete, + ro_gui_url_complete_redraw); + ro_gui_wimp_event_set_help_prefix(dialog_url_complete, "HelpAutoURL"); + + /* open URL */ + ro_gui_dialog_open_url_init(); + + /* scale view */ + dialog_zoom = ro_gui_dialog_create("zoom"); + ro_gui_wimp_event_register_numeric_field(dialog_zoom, ICON_ZOOM_VALUE, + ICON_ZOOM_INC, ICON_ZOOM_DEC, 10, 1600, 10, 0); + ro_gui_wimp_event_register_checkbox(dialog_zoom, ICON_ZOOM_FRAMES); + ro_gui_wimp_event_register_cancel(dialog_zoom, ICON_ZOOM_CANCEL); + ro_gui_wimp_event_register_ok(dialog_zoom, ICON_ZOOM_OK, + ro_gui_dialog_zoom_apply); + ro_gui_wimp_event_set_help_prefix(dialog_zoom, "HelpScaleView"); + + /* Treeview initialisation has moved to the end, to allow any + * associated dialogues to be set up first. + */ + + /* certificate verification window */ + ro_gui_cert_preinitialise(); + + /* hotlist window */ + ro_gui_hotlist_preinitialise(); + + /* global history window */ + ro_gui_global_history_preinitialise(); + + /* cookies window */ + ro_gui_cookies_preinitialise(); +} + + +/** + * Create a window from a template. + * + * \param template_name name of template to load + * \return window handle + * + * Exits through die() on error. + */ + +wimp_w ro_gui_dialog_create(const char *template_name) +{ + wimp_window *window; + wimp_w w; + os_error *error; + + window = ro_gui_dialog_load_template(template_name); + + /* create window */ + window->sprite_area = gui_sprites; + error = xwimp_create_window(window, &w); + if (error) { + LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess); + xwimp_close_template(); + die(error->errmess); + } + + /* the window definition is copied by the wimp and may be freed */ + free(window); + + return w; +} + + +/** + * Load a template without creating a window. + * + * \param template_name name of template to load + * \return window block + * + * Exits through die() on error. + */ + +wimp_window * ro_gui_dialog_load_template(const char *template_name) +{ + char name[20]; + int context, window_size, data_size; + char *data; + wimp_window *window; + os_error *error; + + /* Template names must be <= 11 chars long */ + assert(strlen(template_name) <= 11); + + /* wimp_load_template won't accept a const char * */ + strncpy(name, template_name, sizeof name); + + /* find required buffer sizes */ + error = xwimp_load_template(wimp_GET_SIZE, 0, 0, wimp_NO_FONTS, + name, 0, &window_size, &data_size, &context); + if (error) { + LOG("xwimp_load_template: 0x%x: %s", error->errnum, error->errmess); + xwimp_close_template(); + die(error->errmess); + } + if (!context) { + LOG("template '%s' missing", template_name); + xwimp_close_template(); + die("Template"); + } + + /* allocate space for indirected data and temporary window buffer */ + data = malloc(data_size); + window = malloc(window_size); + if (!data || !window) { + xwimp_close_template(); + die("NoMemory"); + } + + /* load template */ + error = xwimp_load_template(window, data, data + data_size, + wimp_NO_FONTS, name, 0, 0, 0, 0); + if (error) { + LOG("xwimp_load_template: 0x%x: %s", error->errnum, error->errmess); + xwimp_close_template(); + die(error->errmess); + } + + return window; +} + + +/** + * Open a dialog box, centred on the screen. + */ + +void ro_gui_dialog_open(wimp_w w) +{ + int screen_x, screen_y, dx, dy; + wimp_window_state state; + os_error *error; + + /* find screen centre in os units */ + ro_gui_screen_size(&screen_x, &screen_y); + screen_x /= 2; + screen_y /= 2; + + /* centre and open */ + state.w = w; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + dx = (state.visible.x1 - state.visible.x0) / 2; + dy = (state.visible.y1 - state.visible.y0) / 2; + state.visible.x0 = screen_x - dx; + state.visible.x1 = screen_x + dx; + state.visible.y0 = screen_y - dy; + state.visible.y1 = screen_y + dy; + state.next = wimp_TOP; + ro_gui_open_window_request(PTR_WIMP_OPEN(&state)); + + /* Set the caret position */ + ro_gui_set_caret_first(w); +} + + +/** + * Close a dialog box. + */ + +void ro_gui_dialog_close(wimp_w close) +{ + int i; + wimp_caret caret; + os_error *error; + + /* Check if we're a persistent window */ + for (i = 0; i < MAX_PERSISTENT; i++) { + if (persistent_dialog[i].dialog == close) { + /* We are => invalidate record */ + persistent_dialog[i].parent = NULL; + persistent_dialog[i].dialog = NULL; + break; + } + } + + /* Close any child windows */ + ro_gui_dialog_close_persistent(close); + + /* Give the caret back to the parent window. This code relies on + the fact that only tree windows and browser windows open + persistent dialogues, as the caret gets placed to no icon. + */ + error = xwimp_get_caret_position(&caret); + if (error) { + LOG("xwimp_get_caret_position: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } else if (caret.w == close) { + /* Check if we are a persistent window */ + if (i < MAX_PERSISTENT) { + error = xwimp_set_caret_position( + persistent_dialog[i].parent, + wimp_ICON_WINDOW, -100, -100, + 32, -1); + /* parent may have been closed first */ + if ((error) && (error->errnum != 0x287)) { + LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + } + } + + error = xwimp_close_window(close); + if (error) { + LOG("xwimp_close_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } +} + + +/** + * Moves a window to the top of the stack. + * + * If the window is currently closed then: + * + * * The window is opened in the centre of the screen (at the supplied size) + * * Any toolbar editing session is stopped + * * The scroll position is set to the top of the window + * + * If the window is currently open then: + * + * * The window is brought to the top of the stack + * + * \param w the window to show + * \param toolbar the toolbar to consider + * \param width the window width if it is currently closed (or 0 to retain) + * \param height the window height if it is currently closed (or 0 to retain) + * \return true if the window was previously open + */ +bool ro_gui_dialog_open_top(wimp_w w, struct toolbar *toolbar, + int width, int height) { + os_error *error; + int screen_width, screen_height; + wimp_window_state state; + bool open; + + state.w = w; + error = xwimp_get_window_state(&state); + if (error) { + ro_warn_user("WimpError", error->errmess); + return false; + } + + /* if we're open we jump to the top of the stack, if not then we + * open in the centre of the screen. */ + open = state.flags & wimp_WINDOW_OPEN; + if (!open) { + int dimension; + int scroll_width; + /* cancel any editing */ + if (ro_toolbar_get_editing(toolbar)) + ro_toolbar_toggle_edit(toolbar); + + /* move to the centre */ + ro_gui_screen_size(&screen_width, &screen_height); + dimension = ((width == 0) ? + (state.visible.x1 - state.visible.x0) : width); + scroll_width = ro_get_vscroll_width(w); + state.visible.x0 = (screen_width - (dimension + scroll_width)) / 2; + state.visible.x1 = state.visible.x0 + dimension; + dimension = ((height == 0) ? + (state.visible.y1 - state.visible.y0) : height); + state.visible.y0 = (screen_height - dimension) / 2; + state.visible.y1 = state.visible.y0 + dimension; + state.xscroll = 0; + state.yscroll = 0; + if (toolbar) + state.yscroll = ro_toolbar_height(toolbar); + } + + /* open the window at the top of the stack */ + state.next = wimp_TOP; + ro_gui_open_window_request(PTR_WIMP_OPEN(&state)); + return open; +} + + +/** + * Open window at the location of the pointer. + */ + +void ro_gui_dialog_open_at_pointer(wimp_w w) +{ + wimp_pointer ptr; + os_error *error; + + /* get the pointer position */ + error = xwimp_get_pointer_info(&ptr); + if (error) { + LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + ro_gui_dialog_open_xy(w, ptr.pos.x - 64, ptr.pos.y); +} + + +/** + * Open window at a specified location. + */ + +void ro_gui_dialog_open_xy(wimp_w w, int x, int y) +{ + wimp_window_state state; + os_error *error; + int dx, dy; + + /* move the window */ + state.w = w; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + dx = (state.visible.x1 - state.visible.x0); + dy = (state.visible.y1 - state.visible.y0); + state.visible.x0 = x; + state.visible.x1 = x + dx; + state.visible.y0 = y - dy; + state.visible.y1 = y; + + /* if the window is already open, close it first so that it opens fully + * on screen */ + error = xwimp_close_window(w); + if (error) { + LOG("xwimp_close_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + /* open the window at the top of the stack */ + state.next = wimp_TOP; + ro_gui_open_window_request(PTR_WIMP_OPEN(&state)); +} + + +/** + * Opens a window at the centre of either another window or the screen + * + * /param parent the parent window (NULL for centre of screen) + * /param child the child window + */ +void ro_gui_dialog_open_centre_parent(wimp_w parent, wimp_w child) { + os_error *error; + wimp_window_state state; + int mid_x, mid_y; + int dimension, scroll_width; + + /* get the parent window state */ + if (parent) { + state.w = parent; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + scroll_width = ro_get_vscroll_width(parent); + mid_x = (state.visible.x0 + state.visible.x1 + scroll_width); + mid_y = (state.visible.y0 + state.visible.y1); + } else { + ro_gui_screen_size(&mid_x, &mid_y); + } + mid_x /= 2; + mid_y /= 2; + + /* get the child window state */ + state.w = child; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + /* move to the centre of the parent at the top of the stack */ + dimension = state.visible.x1 - state.visible.x0; + scroll_width = ro_get_vscroll_width(history_window); + state.visible.x0 = mid_x - (dimension + scroll_width) / 2; + state.visible.x1 = state.visible.x0 + dimension; + dimension = state.visible.y1 - state.visible.y0; + state.visible.y0 = mid_y - dimension / 2; + state.visible.y1 = state.visible.y0 + dimension; + state.next = wimp_TOP; + ro_gui_open_window_request(PTR_WIMP_OPEN(&state)); +} + + +/** + * Open a persistent dialog box relative to the pointer. + * + * \param parent the owning window (NULL for no owner) + * \param w the dialog window + * \param pointer open the window at the pointer (centre of the parent + * otherwise) + */ + +void ro_gui_dialog_open_persistent(wimp_w parent, wimp_w w, bool pointer) { + + if (pointer) + ro_gui_dialog_open_at_pointer(w); + else + ro_gui_dialog_open_centre_parent(parent, w); + + /* todo: use wimp_event definitions rather than special cases */ + if ((w == dialog_pageinfo) || (w == dialog_objinfo)) + ro_gui_wimp_update_window_furniture(w, wimp_WINDOW_CLOSE_ICON, + wimp_WINDOW_CLOSE_ICON); + ro_gui_dialog_add_persistent(parent, w); + ro_gui_set_caret_first(w); +} + + +void ro_gui_dialog_add_persistent(wimp_w parent, wimp_w w) { + int i; + + /* all persistant windows have a back icon */ + ro_gui_wimp_update_window_furniture(w, wimp_WINDOW_BACK_ICON, + wimp_WINDOW_BACK_ICON); + + /* Add a mapping + */ + if ((parent == NULL) || (parent == wimp_ICON_BAR)) + return; + for (i = 0; i < MAX_PERSISTENT; i++) { + if (persistent_dialog[i].dialog == NULL || + persistent_dialog[i].dialog == w) { + persistent_dialog[i].dialog = w; + persistent_dialog[i].parent = parent; + return; + } + } + LOG("Unable to map persistent dialog to parent."); + return; +} + + +/** + * Close persistent dialogs associated with a window. + * + * \param parent the window to close children of + */ + +void ro_gui_dialog_close_persistent(wimp_w parent) { + int i; + wimp_w w; + + /* Check our mappings. + * + * The window handle is copied into w before proceeding, as + * ro_gui_dialog_close() will NULL persistent_dialog[i].dialog as + * part of the closing process. This would mean that the subsequent + * event dispatch would fail. (These events are logged to allow + * side effects to be investigated -- this code hasn't worked before). + */ + for (i = 0; i < MAX_PERSISTENT; i++) { + if (persistent_dialog[i].parent == parent && + persistent_dialog[i].dialog != NULL) { + w = persistent_dialog[i].dialog; + ro_gui_dialog_close(w); + if (ro_gui_wimp_event_close_window(w)) + LOG("Persistent dialog close event: 0x%x", (unsigned)w); + persistent_dialog[i].parent = NULL; + persistent_dialog[i].dialog = NULL; + } + } +} + + +/** + * Save the current options. + */ + +void ro_gui_save_options(void) +{ + nsoption_write("<NetSurf$ChoicesSave>", NULL, NULL); +} + +bool ro_gui_dialog_zoom_apply(wimp_w w) { + unsigned int scale; + bool all; + + scale = atoi(ro_gui_get_icon_string(w, ICON_ZOOM_VALUE)); + all = ro_gui_get_icon_selected_state(w, ICON_ZOOM_FRAMES); + ro_gui_window_set_scale(ro_gui_current_zoom_gui, scale * 0.01); + return true; +} + + +/** + * Prepares the Scale view dialog. + */ + +void ro_gui_dialog_prepare_zoom(struct gui_window *g) +{ + char scale_buffer[8]; + sprintf(scale_buffer, "%.0f", browser_window_get_scale(g->bw) * 100); + ro_gui_set_icon_string(dialog_zoom, ICON_ZOOM_VALUE, scale_buffer, true); + ro_gui_set_icon_selected_state(dialog_zoom, ICON_ZOOM_FRAMES, true); + ro_gui_set_icon_shaded_state(dialog_zoom, ICON_ZOOM_FRAMES, true); + ro_gui_current_zoom_gui = g; + ro_gui_wimp_event_memorise(dialog_zoom); +} + +/** + * Update the Scale View dialog to reflect the current window settings + * + * \param g the gui_window to update for + */ +void ro_gui_dialog_update_zoom(struct gui_window *g) { + if (g == ro_gui_current_zoom_gui) + ro_gui_dialog_prepare_zoom(g); +} + + +/** + * Create the Open URL dialogue, allocating storage for the URL field icon + * as we go. + * + * \return true on success; false on failure (although errors with + * the templates or memory allocation will exit via die()). + */ + +static bool ro_gui_dialog_open_url_init(void) +{ + wimp_window *definition; + char *buffer; + os_error *error; + + definition = ro_gui_dialog_load_template("open_url"); + + /* _load_template() should die on any error, so we trust its data. */ + + assert(definition != NULL); + + /* Create the dialogue, with modifications. */ + + if ((definition->icons[ICON_OPENURL_URL].flags & wimp_ICON_INDIRECTED) + == 0) { + LOG("open_url URL icon not indirected"); + xwimp_close_template(); + die("Template"); + } + + buffer = malloc(RO_GUI_MAX_URL_SIZE); + if (buffer == NULL) { + xwimp_close_template(); + die("NoMemory"); + } + + definition->icons[ICON_OPENURL_URL].data.indirected_text.text = buffer; + definition->icons[ICON_OPENURL_URL].data.indirected_text.size = + RO_GUI_MAX_URL_SIZE; + definition->sprite_area = gui_sprites; + + error = xwimp_create_window(definition, &dialog_openurl); + if (error != NULL) { + LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess); + xwimp_close_template(); + die(error->errmess); + } + + free(definition); + + ro_gui_wimp_event_register_menu_gright(dialog_openurl, ICON_OPENURL_URL, + ICON_OPENURL_MENU, ro_gui_url_suggest_menu); + ro_gui_wimp_event_register_cancel(dialog_openurl, ICON_OPENURL_CANCEL); + ro_gui_wimp_event_register_ok(dialog_openurl, ICON_OPENURL_OPEN, + ro_gui_dialog_openurl_apply); + ro_gui_wimp_event_register_menu_prepare(dialog_openurl, + ro_gui_dialog_open_url_menu_prepare); + ro_gui_wimp_event_set_help_prefix(dialog_openurl, "HelpOpenURL"); + + return true; +} + + + +bool ro_gui_dialog_openurl_apply(wimp_w w) { + const char *urltxt; + char *url2; + nsurl *url; + nserror error; + + urltxt = ro_gui_get_icon_string(w, ICON_OPENURL_URL); + url2 = strdup(urltxt); /** @todo why is this copied */ + if (url2 == NULL) { + return false; + } + + error = nsurl_create(url2, &url); + free(url2); + if (error == NSERROR_OK) { + error = browser_window_create(BW_CREATE_HISTORY, + url, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + if (error != NSERROR_OK) { + ro_warn_user(messages_get_errorcode(error), 0); + return false; + } + + return true; + +} + + +/** + * Prepares the Open URL dialog. + */ + +void ro_gui_dialog_prepare_open_url(void) +{ + ro_gui_set_icon_string(dialog_openurl, ICON_OPENURL_URL, "", true); + ro_gui_set_icon_shaded_state(dialog_openurl, + ICON_OPENURL_MENU, !ro_gui_url_suggest_prepare_menu()); + ro_gui_wimp_event_memorise(dialog_openurl); +} + + +/** + * Callback to prepare menus in the Open URL dialog. At present, this + * only has to handle the URL Suggestion pop-up. + * + * \param w The window handle owning the menu. + * \param i The icon handle owning the menu. + * \param *menu The menu to be prepared. + * \param *pointer The associated mouse click event block, or NULL + * on an Adjust-click re-opening. + * \return true if the event was handled; false if not. + */ + +bool ro_gui_dialog_open_url_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_pointer *pointer) +{ + if (menu != ro_gui_url_suggest_menu || i != ICON_OPENURL_MENU) + return false; + + if (pointer != NULL) + return ro_gui_url_suggest_prepare_menu(); + + return true; +} diff --git a/frontends/riscos/dialog.h b/frontends/riscos/dialog.h new file mode 100644 index 000000000..463048436 --- /dev/null +++ b/frontends/riscos/dialog.h @@ -0,0 +1,55 @@ +/* + * Copyright 2005 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _NETSURF_RISCOS_DIALOG_H_ +#define _NETSURF_RISCOS_DIALOG_H_ + +struct toolbar; +struct gui_window; + +void ro_gui_dialog_init(void); +wimp_w ro_gui_dialog_create(const char *template_name); +wimp_window * ro_gui_dialog_load_template(const char *template_name); + +void ro_gui_dialog_open(wimp_w w); +void ro_gui_dialog_close(wimp_w close); + +bool ro_gui_dialog_open_top(wimp_w w, struct toolbar *toolbar, + int width, int height); +void ro_gui_dialog_open_at_pointer(wimp_w w); +void ro_gui_dialog_open_xy(wimp_w, int x, int y); +void ro_gui_dialog_open_centre_parent(wimp_w parent, wimp_w w); + +void ro_gui_dialog_open_persistent(wimp_w parent, wimp_w w, bool pointer); +void ro_gui_dialog_add_persistent(wimp_w parent, wimp_w w); +void ro_gui_dialog_close_persistent(wimp_w parent); + + + + +void ro_gui_dialog_click(wimp_pointer *pointer); +void ro_gui_dialog_prepare_zoom(struct gui_window *g); +void ro_gui_dialog_update_zoom(struct gui_window *g); +void ro_gui_dialog_prepare_open_url(void); +void ro_gui_save_options(void); +void ro_gui_dialog_open_config(void); +void ro_gui_dialog_proxyauth_menu_selection(int item); +void ro_gui_dialog_image_menu_selection(int item); +void ro_gui_dialog_languages_menu_selection(const char *lang); +void ro_gui_dialog_font_menu_selection(int item); +#endif diff --git a/frontends/riscos/distribution/!Boot/Resources/!Cache/!Boot,feb b/frontends/riscos/distribution/!Boot/Resources/!Cache/!Boot,feb new file mode 100644 index 000000000..485bd521d --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Cache/!Boot,feb @@ -0,0 +1,17 @@ +If (("<Cache$AppDir>" = "") OR ("<Cache$ForceVars>" = "1")) Then Set Cache$AppDir <Obey$Dir> + +IconSprites <Cache$AppDir>.!Sprites + +| Find and set up resource paths +WimpSlot -min 64k -max 64k +Run <Cache$AppDir>.Resources.ResFind CacheApp +If (("<Cache$Meta>" = "") OR ("<Cache$ForceVars>" = "1")) Then Set Cache$Meta CacheAppRes:!Meta + +| Work out where the cache directory should be -- use Choices$User if set or Default, otherwise. +Set Cache$Suffix "<Choices$User>" +If "<Cache$Suffix>" = "" Then Set Cache$Suffix "Default" +If (("<Cache$Dir>" = "") OR ("<Cache$ForceVars>" = "1")) Then Set Cache$Dir "<Cache$AppDir>.Caches.<Cache$Suffix>" +Unset Cache$Suffix + +| Ensure cache directory exists (sadly, unavoidable) +CDir <Cache$Dir> diff --git a/frontends/riscos/distribution/!Boot/Resources/!Cache/!Help,feb b/frontends/riscos/distribution/!Boot/Resources/!Cache/!Help,feb new file mode 100644 index 000000000..35eeeb31b --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Cache/!Help,feb @@ -0,0 +1,2 @@ +If "<CacheAppRes$Path>" = "" Then Run <Cache$AppDir>.Resources.ResFind CacheApp +Filer_Run CacheAppRes:Help
\ No newline at end of file diff --git a/frontends/riscos/distribution/!Boot/Resources/!Cache/!Run,feb b/frontends/riscos/distribution/!Boot/Resources/!Cache/!Run,feb new file mode 100644 index 000000000..8aead9733 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Cache/!Run,feb @@ -0,0 +1,9 @@ +Set Cache$ForceVars 1 +Run <Obey$Dir>.!Boot +Unset Cache$ForceVars + +RMEnsure SysLog 0.17 IfThere <SysLog$Dir>.!Run Then Run <SysLog$Dir>.!Run +RMEnsure SysLog 0.17 Set Cache$SysLogMissing "True" + +Wimpslot -min 128k -max 128k +Run <Cache$AppDir>.!RunImage diff --git a/frontends/riscos/distribution/!Boot/Resources/!Cache/!RunImage,ffb b/frontends/riscos/distribution/!Boot/Resources/!Cache/!RunImage,ffb Binary files differnew file mode 100644 index 000000000..61752af99 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Cache/!RunImage,ffb diff --git a/frontends/riscos/distribution/!Boot/Resources/!Cache/!Sprites,ff9 b/frontends/riscos/distribution/!Boot/Resources/!Cache/!Sprites,ff9 Binary files differnew file mode 100644 index 000000000..b71a51cf3 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Cache/!Sprites,ff9 diff --git a/frontends/riscos/distribution/!Boot/Resources/!Cache/!Sprites22,ff9 b/frontends/riscos/distribution/!Boot/Resources/!Cache/!Sprites22,ff9 Binary files differnew file mode 100644 index 000000000..e43f88c89 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Cache/!Sprites22,ff9 diff --git a/frontends/riscos/distribution/!Boot/Resources/!Cache/Caches/Blank b/frontends/riscos/distribution/!Boot/Resources/!Cache/Caches/Blank new file mode 100644 index 000000000..898dc5872 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Cache/Caches/Blank @@ -0,0 +1 @@ +This is here just to stop the directory structure getting lost when unzipping.
\ No newline at end of file diff --git a/frontends/riscos/distribution/!Boot/Resources/!Cache/Resources/MultiError,ffb b/frontends/riscos/distribution/!Boot/Resources/!Cache/Resources/MultiError,ffb Binary files differnew file mode 100644 index 000000000..ec348b0e9 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Cache/Resources/MultiError,ffb diff --git a/frontends/riscos/distribution/!Boot/Resources/!Cache/Resources/ResFind,ffb b/frontends/riscos/distribution/!Boot/Resources/!Cache/Resources/ResFind,ffb Binary files differnew file mode 100644 index 000000000..7766cc928 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Cache/Resources/ResFind,ffb diff --git a/frontends/riscos/distribution/!Boot/Resources/!Cache/Resources/UK/!Meta b/frontends/riscos/distribution/!Boot/Resources/!Cache/Resources/UK/!Meta new file mode 100644 index 000000000..2de40bd7c --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Cache/Resources/UK/!Meta @@ -0,0 +1,9 @@ +# Meta file for Cache +Help:<CacheAppRes$Dir>.Help +Version:1.13 +Web:http://www.snowstone.org.uk/riscos/ +Title:Cache +Publisher:Adam Richardson +Description:Cache provides a central location for semi-permanent data on your system. +Email:riscos@snowstone.org.uk + diff --git a/frontends/riscos/distribution/!Boot/Resources/!Cache/Resources/UK/Help b/frontends/riscos/distribution/!Boot/Resources/!Cache/Resources/UK/Help new file mode 100644 index 000000000..aad9bf0b1 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Cache/Resources/UK/Help @@ -0,0 +1,60 @@ +Cache +----- + +Cache provides a shared location for cached data. This location can be +used by application authors to store semi-permanent data. Cache can be +placed anywhere on your computer where it will be "seen" by the Filer +during start up. (For instance, the "Resources" directory inside !Boot.) + +Once "seen" it will set up a cache location, which can be shown by +double-clicking on !Cache. + + +Application Authors +----------- ------- + +Use Cache in a similar way to using Scrap. You *must not* assume that +Cache is present on the user's system however, as Cache is not an +official part of the system (like Scrap). + +To use Cache you should: + * Check for the presence of "<Cache$Dir>" before proceeding + * Read from and write data to "<Cache$Dir>.APPNAME" where APPNAME has + been allocated to you by the allocations service. See: + http://www.riscosopen.com/content/allocate + * If the APPNAME directory does not exist, you should create it. + +This version of Cache is published by Adam Richardson who can be +contacted at riscos@snowstone.org.uk. + +The website for Cache is: http://www.snowstone.org.uk/riscos/ + + +Credits +------- + +Cache is (c) Adam Richardson, 2007. +Thanks to Rob Kendrick for the initial idea and input. + + +License +------- + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/frontends/riscos/distribution/!Boot/Resources/!Cache/Resources/UK/Messages b/frontends/riscos/distribution/!Boot/Resources/!Cache/Resources/UK/Messages new file mode 100644 index 000000000..366122292 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Cache/Resources/UK/Messages @@ -0,0 +1,8 @@ +# Messages for Cache + +multiuser:Multi-user system present. +singleuser:No multi-user system present. +location:Cache directory set to: +opendir:Opening cache location... +fatalerror:Cache has suffered a fatal error and has quit. + diff --git a/frontends/riscos/distribution/!Boot/Resources/!Cache/Resources/UK/Templates,fec b/frontends/riscos/distribution/!Boot/Resources/!Cache/Resources/UK/Templates,fec Binary files differnew file mode 100644 index 000000000..22f910ad9 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Cache/Resources/UK/Templates,fec diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/!Boot,feb b/frontends/riscos/distribution/!Boot/Resources/!Unicode/!Boot,feb new file mode 100644 index 000000000..7c0c46241 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/!Boot,feb @@ -0,0 +1,5 @@ +| Unicode Boot file +| +Set Unicode$Dir <Obey$Dir> +SetMacro Unicode$Path <Unicode$Dir>.,Resources:$.Resources.Unicode. +IconSprites Unicode:!Sprites diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/!Help b/frontends/riscos/distribution/!Boot/Resources/!Unicode/!Help new file mode 100644 index 000000000..8c0488185 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/!Help @@ -0,0 +1 @@ +This application contains resources for Unicode support in applications. diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/!Run,feb b/frontends/riscos/distribution/!Boot/Resources/!Unicode/!Run,feb new file mode 100644 index 000000000..bd70e96ac --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/!Run,feb @@ -0,0 +1,5 @@ +| Unicode Run file +| +Set Unicode$Dir <Obey$Dir> +SetMacro Unicode$Path <Unicode$Dir>.,Resources:$.Resources.Unicode. +IconSprites Unicode:!Sprites diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/!Sprites,ff9 b/frontends/riscos/distribution/!Boot/Resources/!Unicode/!Sprites,ff9 Binary files differnew file mode 100644 index 000000000..3eb5b44b7 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/!Sprites,ff9 diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/!Sprites11,ff9 b/frontends/riscos/distribution/!Boot/Resources/!Unicode/!Sprites11,ff9 Binary files differnew file mode 100644 index 000000000..48986b41e --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/!Sprites11,ff9 diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/!Sprites22,ff9 b/frontends/riscos/distribution/!Boot/Resources/!Unicode/!Sprites22,ff9 Binary files differnew file mode 100644 index 000000000..63a6e6122 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/!Sprites22,ff9 diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Acorn/Latin1 b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Acorn/Latin1 Binary files differnew file mode 100644 index 000000000..bdf5d3b67 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Acorn/Latin1 diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Apple/CentEuro b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Apple/CentEuro Binary files differnew file mode 100644 index 000000000..5ab69ff2e --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Apple/CentEuro diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Apple/Cyrillic b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Apple/Cyrillic Binary files differnew file mode 100644 index 000000000..670fd6cdc --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Apple/Cyrillic diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Apple/Roman b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Apple/Roman Binary files differnew file mode 100644 index 000000000..254579e2c --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Apple/Roman diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Apple/Ukrainian b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Apple/Ukrainian Binary files differnew file mode 100644 index 000000000..a220587ba --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Apple/Ukrainian diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/BigFive b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/BigFive Binary files differnew file mode 100644 index 000000000..c659cef19 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/BigFive diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/C0/40[ISO646] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/C0/40[ISO646] Binary files differnew file mode 100644 index 000000000..cd92b5486 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/C0/40[ISO646] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/C1/43[IS6429] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/C1/43[IS6429] Binary files differnew file mode 100644 index 000000000..74002a168 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/C1/43[IS6429] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/40[646old] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/40[646old] Binary files differnew file mode 100644 index 000000000..00e2d1096 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/40[646old] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/41[646-GB] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/41[646-GB] Binary files differnew file mode 100644 index 000000000..c293f93d6 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/41[646-GB] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/42[646IRV] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/42[646IRV] Binary files differnew file mode 100644 index 000000000..e0b4bcadb --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/42[646IRV] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/43[FinSwe] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/43[FinSwe] Binary files differnew file mode 100644 index 000000000..7d4646905 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/43[FinSwe] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/47[646-SE] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/47[646-SE] Binary files differnew file mode 100644 index 000000000..a6b091a22 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/47[646-SE] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/48[646-SE] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/48[646-SE] Binary files differnew file mode 100644 index 000000000..9bd24ab29 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/48[646-SE] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/49[JS201K] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/49[JS201K] new file mode 100644 index 000000000..20ce8d498 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/49[JS201K] @@ -0,0 +1 @@ +aÿbÿcÿdÿeÿfÿgÿhÿiÿjÿkÿlÿmÿnÿoÿpÿqÿrÿsÿtÿuÿvÿwÿxÿyÿzÿ{ÿ|ÿ}ÿ~ÿÿ€ÿÿ‚ÿƒÿ„ÿ…ÿ†ÿ‡ÿˆÿ‰ÿŠÿ‹ÿŒÿÿŽÿÿÿ‘ÿ’ÿ“ÿ”ÿ•ÿ–ÿ—ÿ˜ÿ™ÿšÿ›ÿœÿÿžÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
\ No newline at end of file diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/4A[JS201R] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/4A[JS201R] Binary files differnew file mode 100644 index 000000000..21d2a479b --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/4A[JS201R] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/4B[646-DE] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/4B[646-DE] Binary files differnew file mode 100644 index 000000000..a2e284e1b --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/4B[646-DE] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/4C[646-PT] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/4C[646-PT] Binary files differnew file mode 100644 index 000000000..e076e2517 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/4C[646-PT] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/54[GB1988] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/54[GB1988] Binary files differnew file mode 100644 index 000000000..3b43719ce --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/54[GB1988] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/56[Teltxt] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/56[Teltxt] Binary files differnew file mode 100644 index 000000000..73ce49e17 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/56[Teltxt] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/59[646-IT] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/59[646-IT] Binary files differnew file mode 100644 index 000000000..f1ae81962 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/59[646-IT] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/5A[646-ES] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/5A[646-ES] Binary files differnew file mode 100644 index 000000000..674fc2d70 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/5A[646-ES] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/60[646-NO] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/60[646-NO] Binary files differnew file mode 100644 index 000000000..fc92892ee --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/60[646-NO] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/66[646-FR] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/66[646-FR] Binary files differnew file mode 100644 index 000000000..8dd604679 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/66[646-FR] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/69[646-HU] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/69[646-HU] Binary files differnew file mode 100644 index 000000000..65300b2c5 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/69[646-HU] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/6B[Arabic] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/6B[Arabic] Binary files differnew file mode 100644 index 000000000..c47689914 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/6B[Arabic] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/6C[IS6937] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/6C[IS6937] Binary files differnew file mode 100644 index 000000000..93453f5de --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/6C[IS6937] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/7A[SerbCr] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/7A[SerbCr] Binary files differnew file mode 100644 index 000000000..9740e784e --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94/7A[SerbCr] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/40[JS6226] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/40[JS6226] Binary files differnew file mode 100644 index 000000000..a677dfc3d --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/40[JS6226] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/41[GB2312] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/41[GB2312] Binary files differnew file mode 100644 index 000000000..679608ad2 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/41[GB2312] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/42[JIS208] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/42[JIS208] Binary files differnew file mode 100644 index 000000000..532b1f4f3 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/42[JIS208] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/43[KS1001] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/43[KS1001] Binary files differnew file mode 100644 index 000000000..36186c864 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/43[KS1001] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/44[JIS212] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/44[JIS212] Binary files differnew file mode 100644 index 000000000..f5343a30e --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/44[JIS212] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/47[CNS1] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/47[CNS1] Binary files differnew file mode 100644 index 000000000..da07f45d3 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/47[CNS1] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/48[CNS2] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/48[CNS2] Binary files differnew file mode 100644 index 000000000..44ee24c91 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/48[CNS2] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/49[CNS3] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/49[CNS3] Binary files differnew file mode 100644 index 000000000..a8464e5aa --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/49[CNS3] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/4A[CNS4] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/4A[CNS4] Binary files differnew file mode 100644 index 000000000..a8f3e3270 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/4A[CNS4] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/4B[CNS5] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/4B[CNS5] Binary files differnew file mode 100644 index 000000000..535b0f4b5 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/4B[CNS5] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/4C[CNS6] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/4C[CNS6] Binary files differnew file mode 100644 index 000000000..7bfb2b1d4 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/4C[CNS6] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/4D[CNS7] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/4D[CNS7] new file mode 100644 index 000000000..be14c7279 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G94x94/4D[CNS7] @@ -0,0 +1,2 @@ +ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿö5ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿUVÿÿÿÿÿÿÿÿÿÿÿÿg6ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿaÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ’9ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿE:ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉ;ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿU=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿè>ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¶?ÿÿÿÿÿÿ½?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÖ@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿqAÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ˜BÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÍEÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöFÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿzGÿÿÿÿÿÿÿÿÿÿÿÿ¸GÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿHÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ/Iÿÿÿÿÿÿÿÿÿÿ1IÿÿÿÿÿÿÿÿÿÿÿÿÿÿœIÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿæIÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ8Kÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ:Lÿÿÿÿ±LÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿGMÿÿQMÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿG7ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ8ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ£8ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ;ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×qÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿš>ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÂ?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜ@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ³Aÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿf†ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙEÿÿÝEÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüFÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ:ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿIÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ=“ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¨IÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÊJÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿKÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀLÿÿÿÿÿÿÿÿÿÿÿÿÊLÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ%MÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿJMÿÿSMÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ6ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿð;ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ>ÿÿÿÿÿÿÿÿÿÿÿÿ#>ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿCÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ]EÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿZFÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ…GÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿIÿÿÿÿÿÿÿÿÿÿÿÿ9Iÿÿÿÿÿÿ7IÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿkJÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÍJÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿMLÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ5ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ{6ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ8ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõdÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ';ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏ?ÿÿÿÿÿÿÍ?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‚AÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿRBÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿQDÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿZEÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿeFÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯HÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿAIÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ)Jÿÿÿÿÿÿÿÿÿÿÿÿÿÿ*Jÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ–JÿÿÿÿÿÿÿÿÿÿÿÿKÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~6áXÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ§9ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ Cÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿé|ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿËÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿeEÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿGÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿdGÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ#HÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙ•ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¹4ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿK<ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñ@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿgFÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿGÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‰HÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿLÿÿÿÿÿÿLÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿmLÿÿpLÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíLÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿMÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ§4ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿgÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿZ>ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯BÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿkEÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿGÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿcIÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€J„JJÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñJÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿGšÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿMÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¨4ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‹Aÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ+CÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿzEÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ FÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿmFÿÿÿÿÿÿÿÿÿÿGÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿjIlIÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ²KÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿLÿÿÿÿÿÿ-LÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿEMÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ +FÿÿÿÿÿÿÿÿFÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ.HÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿLÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ1Cÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¼K»KÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿLÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ6ÿÿÿÿÿÿÿÿÿÿr7ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿMÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿtvÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿìKÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿyBÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
\ No newline at end of file diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/41[Lat1] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/41[Lat1] Binary files differnew file mode 100644 index 000000000..97e6b1106 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/41[Lat1] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/42[Lat2] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/42[Lat2] Binary files differnew file mode 100644 index 000000000..b753c40fe --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/42[Lat2] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/43[Lat3] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/43[Lat3] Binary files differnew file mode 100644 index 000000000..88d477886 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/43[Lat3] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/44[Lat4] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/44[Lat4] Binary files differnew file mode 100644 index 000000000..a40662d45 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/44[Lat4] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/46[Greek] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/46[Greek] Binary files differnew file mode 100644 index 000000000..c42397388 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/46[Greek] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/47[Arabic] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/47[Arabic] Binary files differnew file mode 100644 index 000000000..4507f467a --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/47[Arabic] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/48[Hebrew] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/48[Hebrew] Binary files differnew file mode 100644 index 000000000..70f39cca6 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/48[Hebrew] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/4C[Cyrill] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/4C[Cyrill] Binary files differnew file mode 100644 index 000000000..8ff0115e4 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/4C[Cyrill] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/4D[Lat5] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/4D[Lat5] Binary files differnew file mode 100644 index 000000000..6381e607e --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/4D[Lat5] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/50[LatSup] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/50[LatSup] Binary files differnew file mode 100644 index 000000000..a320c7fe8 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/50[LatSup] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/52[IS6937] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/52[IS6937] Binary files differnew file mode 100644 index 000000000..dff6ccba4 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/52[IS6937] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/54[Thai] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/54[Thai] Binary files differnew file mode 100644 index 000000000..d74377759 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/54[Thai] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/56[Lat6] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/56[Lat6] Binary files differnew file mode 100644 index 000000000..4e3e4f313 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/56[Lat6] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/58[L6Sami] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/58[L6Sami] Binary files differnew file mode 100644 index 000000000..4dfd9188c --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/58[L6Sami] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/59[Lat7] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/59[Lat7] Binary files differnew file mode 100644 index 000000000..256a88e76 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/59[Lat7] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/5C[Welsh] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/5C[Welsh] Binary files differnew file mode 100644 index 000000000..b5e00509f --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/5C[Welsh] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/5D[Sami] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/5D[Sami] Binary files differnew file mode 100644 index 000000000..15734c036 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/5D[Sami] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/5E[Hebrew] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/5E[Hebrew] Binary files differnew file mode 100644 index 000000000..a6593b071 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/5E[Hebrew] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/5F[Lat8] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/5F[Lat8] Binary files differnew file mode 100644 index 000000000..c15713e82 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/5F[Lat8] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/62[Lat9] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/62[Lat9] Binary files differnew file mode 100644 index 000000000..5bf449d58 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/62[Lat9] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/66[Lat10] b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/66[Lat10] Binary files differnew file mode 100644 index 000000000..e8ba925d3 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/ISO2022/G96/66[Lat10] diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/KOI8-R b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/KOI8-R Binary files differnew file mode 100644 index 000000000..8063cd4bc --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/KOI8-R diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Microsoft/CP1250 b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Microsoft/CP1250 Binary files differnew file mode 100644 index 000000000..7a0d35ceb --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Microsoft/CP1250 diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Microsoft/CP1251 b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Microsoft/CP1251 Binary files differnew file mode 100644 index 000000000..3d6009cab --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Microsoft/CP1251 diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Microsoft/CP1252 b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Microsoft/CP1252 Binary files differnew file mode 100644 index 000000000..6d3bf293d --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Microsoft/CP1252 diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Microsoft/CP1253 b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Microsoft/CP1253 Binary files differnew file mode 100644 index 000000000..50a48be13 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Microsoft/CP1253 diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Microsoft/CP1254 b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Microsoft/CP1254 Binary files differnew file mode 100644 index 000000000..45ecfe907 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Microsoft/CP1254 diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Microsoft/CP1256 b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Microsoft/CP1256 Binary files differnew file mode 100644 index 000000000..7fc95a92f --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Microsoft/CP1256 diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Microsoft/CP866 b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Microsoft/CP866 Binary files differnew file mode 100644 index 000000000..cd214d24b --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Microsoft/CP866 diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Microsoft/CP874 b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Microsoft/CP874 Binary files differnew file mode 100644 index 000000000..26a6fc8c3 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Microsoft/CP874 diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Microsoft/CP932 b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Microsoft/CP932 Binary files differnew file mode 100644 index 000000000..2c0c111f9 --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Encodings/Microsoft/CP932 diff --git a/frontends/riscos/distribution/!Boot/Resources/!Unicode/Files/Aliases b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Files/Aliases new file mode 100644 index 000000000..8978ede4c --- /dev/null +++ b/frontends/riscos/distribution/!Boot/Resources/!Unicode/Files/Aliases @@ -0,0 +1,303 @@ +# > Unicode:Files.Aliases +# Mapping of character set encoding names to their canonical form +# +# Lines starting with a '#' are comments, blank lines are ignored. +# +# Based on http://www.iana.org/assignments/character-sets and +# http://www.iana.org/assignments/ianacharset-mib +# +# Canonical Form MIBenum Aliases... +# +US-ASCII 3 iso-ir-6 ANSI_X3.4-1986 ISO_646.irv:1991 ASCII ISO646-US ANSI_X3.4-1968 us IBM367 cp367 csASCII +ISO-10646-UTF-1 27 csISO10646UTF1 +ISO_646.basic:1983 28 ref csISO646basic1983 +INVARIANT 29 csINVARIANT +ISO_646.irv:1983 30 iso-ir-2 irv csISO2IntlRefVersion +BS_4730 20 iso-ir-4 ISO646-GB gb uk csISO4UnitedKingdom +NATS-SEFI 31 iso-ir-8-1 csNATSSEFI +NATS-SEFI-ADD 32 iso-ir-8-2 csNATSSEFIADD +NATS-DANO 33 iso-ir-9-1 csNATSDANO +NATS-DANO-ADD 34 iso-ir-9-2 csNATSDANOADD +SEN_850200_B 35 iso-ir-10 FI ISO646-FI ISO646-SE se csISO10Swedish +SEN_850200_C 21 iso-ir-11 ISO646-SE2 se2 csISO11SwedishForNames +KS_C_5601-1987 36 iso-ir-149 KS_C_5601-1989 KSC_5601 korean csKSC56011987 +ISO-2022-KR 37 csISO2022KR +EUC-KR 38 csEUCKR EUCKR +ISO-2022-JP 39 csISO2022JP +ISO-2022-JP-2 40 csISO2022JP2 +ISO-2022-CN 104 +ISO-2022-CN-EXT 105 +JIS_C6220-1969-jp 41 JIS_C6220-1969 iso-ir-13 katakana x0201-7 csISO13JISC6220jp +JIS_C6220-1969-ro 42 iso-ir-14 jp ISO646-JP csISO14JISC6220ro +IT 22 iso-ir-15 ISO646-IT csISO15Italian +PT 43 iso-ir-16 ISO646-PT csISO16Portuguese +ES 23 iso-ir-17 ISO646-ES csISO17Spanish +greek7-old 44 iso-ir-18 csISO18Greek7Old +latin-greek 45 iso-ir-19 csISO19LatinGreek +DIN_66003 24 iso-ir-21 de ISO646-DE csISO21German +NF_Z_62-010_(1973) 46 iso-ir-25 ISO646-FR1 csISO25French +Latin-greek-1 47 iso-ir-27 csISO27LatinGreek1 +ISO_5427 48 iso-ir-37 csISO5427Cyrillic +JIS_C6226-1978 49 iso-ir-42 csISO42JISC62261978 +BS_viewdata 50 iso-ir-47 csISO47BSViewdata +INIS 51 iso-ir-49 csISO49INIS +INIS-8 52 iso-ir-50 csISO50INIS8 +INIS-cyrillic 53 iso-ir-51 csISO51INISCyrillic +ISO_5427:1981 54 iso-ir-54 ISO5427Cyrillic1981 +ISO_5428:1980 55 iso-ir-55 csISO5428Greek +GB_1988-80 56 iso-ir-57 cn ISO646-CN csISO57GB1988 +GB_2312-80 57 iso-ir-58 chinese csISO58GB231280 +NS_4551-1 25 iso-ir-60 ISO646-NO no csISO60DanishNorwegian csISO60Norwegian1 +NS_4551-2 58 ISO646-NO2 iso-ir-61 no2 csISO61Norwegian2 +NF_Z_62-010 26 iso-ir-69 ISO646-FR fr csISO69French +videotex-suppl 59 iso-ir-70 csISO70VideotexSupp1 +PT2 60 iso-ir-84 ISO646-PT2 csISO84Portuguese2 +ES2 61 iso-ir-85 ISO646-ES2 csISO85Spanish2 +MSZ_7795.3 62 iso-ir-86 ISO646-HU hu csISO86Hungarian +JIS_C6226-1983 63 iso-ir-87 x0208 JIS_X0208-1983 csISO87JISX0208 +greek7 64 iso-ir-88 csISO88Greek7 +ASMO_449 65 ISO_9036 arabic7 iso-ir-89 csISO89ASMO449 +iso-ir-90 66 csISO90 +JIS_C6229-1984-a 67 iso-ir-91 jp-ocr-a csISO91JISC62291984a +JIS_C6229-1984-b 68 iso-ir-92 ISO646-JP-OCR-B jp-ocr-b csISO92JISC62991984b +JIS_C6229-1984-b-add 69 iso-ir-93 jp-ocr-b-add csISO93JIS62291984badd +JIS_C6229-1984-hand 70 iso-ir-94 jp-ocr-hand csISO94JIS62291984hand +JIS_C6229-1984-hand-add 71 iso-ir-95 jp-ocr-hand-add csISO95JIS62291984handadd +JIS_C6229-1984-kana 72 iso-ir-96 csISO96JISC62291984kana +ISO_2033-1983 73 iso-ir-98 e13b csISO2033 +ANSI_X3.110-1983 74 iso-ir-99 CSA_T500-1983 NAPLPS csISO99NAPLPS +ISO-8859-1 4 iso-ir-100 ISO_8859-1 ISO_8859-1:1987 latin1 l1 IBM819 CP819 csISOLatin1 8859_1 ISO8859-1 +ISO-8859-2 5 iso-ir-101 ISO_8859-2 ISO_8859-2:1987 latin2 l2 csISOLatin2 8859_2 ISO8859-2 +T.61-7bit 75 iso-ir-102 csISO102T617bit +T.61-8bit 76 T.61 iso-ir-103 csISO103T618bit +ISO-8859-3 6 iso-ir-109 ISO_8859-3 ISO_8859-3:1988 latin3 l3 csISOLatin3 8859_3 ISO8859-3 +ISO-8859-4 7 iso-ir-110 ISO_8859-4 ISO_8859-4:1988 latin4 l4 csISOLatin4 8859_4 ISO8859-4 +ECMA-cyrillic 77 iso-ir-111 KOI8-E csISO111ECMACyrillic +CSA_Z243.4-1985-1 78 iso-ir-121 ISO646-CA csa7-1 ca csISO121Canadian1 +CSA_Z243.4-1985-2 79 iso-ir-122 ISO646-CA2 csa7-2 csISO122Canadian2 +CSA_Z243.4-1985-gr 80 iso-ir-123 csISO123CSAZ24341985gr +ISO-8859-6 9 iso-ir-127 ISO_8859-6 ISO_8859-6:1987 ECMA-114 ASMO-708 arabic csISOLatinArabic +ISO-8859-6-E 81 csISO88596E ISO_8859-6-E +ISO-8859-6-I 82 csISO88596I ISO_8859-6-I +ISO-8859-7 10 iso-ir-126 ISO_8859-7 ISO_8859-7:1987 ELOT_928 ECMA-118 greek greek8 csISOLatinGreek 8859_7 ISO8859-7 +T.101-G2 83 iso-ir-128 csISO128T101G2 +ISO-8859-8 11 iso-ir-138 ISO_8859-8 ISO_8859-8:1988 hebrew csISOLatinHebrew 8859_8 ISO8859-8 +ISO-8859-8-E 84 csISO88598E ISO_8859-8-E +ISO-8859-8-I 85 csISO88598I ISO_8859-8-I +CSN_369103 86 iso-ir-139 csISO139CSN369103 +JUS_I.B1.002 87 iso-ir-141 ISO646-YU js yu csISO141JUSIB1002 +ISO_6937-2-add 14 iso-ir-142 csISOTextComm +IEC_P27-1 88 iso-ir-143 csISO143IECP271 +ISO-8859-5 8 iso-ir-144 ISO_8859-5 ISO_8859-5:1988 cyrillic csISOLatinCyrillic 8859_5 ISO8859-5 +JUS_I.B1.003-serb 89 iso-ir-146 serbian csISO146Serbian +JUS_I.B1.003-mac 90 macedonian iso-ir-147 csISO147Macedonian +ISO-8859-9 12 iso-ir-148 ISO_8859-9 ISO_8859-9:1989 latin5 l5 csISOLatin5 8859_9 ISO8859-9 +greek-ccitt 91 iso-ir-150 csISO150 csISO150GreekCCITT +NC_NC00-10:81 92 cuba iso-ir-151 ISO646-CU csISO151Cuba +ISO_6937-2-25 93 iso-ir-152 csISO6937Add +GOST_19768-74 94 ST_SEV_358-88 iso-ir-153 csISO153GOST1976874 +ISO_8859-supp 95 iso-ir-154 latin1-2-5 csISO8859Supp +ISO_10367-box 96 iso-ir-155 csISO10367Box +ISO-8859-10 13 iso-ir-157 l6 ISO_8859-10:1992 csISOLatin6 latin6 8859_10 ISO8859-10 +latin-lap 97 lap iso-ir-158 csISO158Lap +JIS_X0212-1990 98 x0212 iso-ir-159 csISO159JISX02121990 +DS_2089 99 DS2089 ISO646-DK dk csISO646Danish +us-dk 100 csUSDK +dk-us 101 csDKUS +JIS_X0201 15 X0201 csHalfWidthKatakana +KSC5636 102 ISO646-KR csKSC5636 +ISO-10646-UCS-2 1000 csUnicode UCS-2 UCS2 +ISO-10646-UCS-4 1001 csUCS4 UCS-4 UCS4 +DEC-MCS 2008 dec csDECMCS +hp-roman8 2004 roman8 r8 csHPRoman8 +macintosh 2027 mac csMacintosh MACROMAN MAC-ROMAN X-MAC-ROMAN +IBM037 2028 cp037 ebcdic-cp-us ebcdic-cp-ca ebcdic-cp-wt ebcdic-cp-nl csIBM037 +IBM038 2029 EBCDIC-INT cp038 csIBM038 +IBM273 2030 CP273 csIBM273 +IBM274 2031 EBCDIC-BE CP274 csIBM274 +IBM275 2032 EBCDIC-BR cp275 csIBM275 +IBM277 2033 EBCDIC-CP-DK EBCDIC-CP-NO csIBM277 +IBM278 2034 CP278 ebcdic-cp-fi ebcdic-cp-se csIBM278 +IBM280 2035 CP280 ebcdic-cp-it csIBM280 +IBM281 2036 EBCDIC-JP-E cp281 csIBM281 +IBM284 2037 CP284 ebcdic-cp-es csIBM284 +IBM285 2038 CP285 ebcdic-cp-gb csIBM285 +IBM290 2039 cp290 EBCDIC-JP-kana csIBM290 +IBM297 2040 cp297 ebcdic-cp-fr csIBM297 +IBM420 2041 cp420 ebcdic-cp-ar1 csIBM420 +IBM423 2042 cp423 ebcdic-cp-gr csIBM423 +IBM424 2043 cp424 ebcdic-cp-he csIBM424 +IBM437 2011 cp437 437 csPC8CodePage437 +IBM500 2044 CP500 ebcdic-cp-be ebcdic-cp-ch csIBM500 +IBM775 2087 cp775 csPC775Baltic +IBM850 2009 cp850 850 csPC850Multilingual +IBM851 2045 cp851 851 csIBM851 +IBM852 2010 cp852 852 csPCp852 +IBM855 2046 cp855 855 csIBM855 +IBM857 2047 cp857 857 csIBM857 +IBM860 2048 cp860 860 csIBM860 +IBM861 2049 cp861 861 cp-is csIBM861 +IBM862 2013 cp862 862 csPC862LatinHebrew +IBM863 2050 cp863 863 csIBM863 +IBM864 2051 cp864 csIBM864 +IBM865 2052 cp865 865 csIBM865 +IBM866 2086 cp866 866 csIBM866 +IBM868 2053 CP868 cp-ar csIBM868 +IBM869 2054 cp869 869 cp-gr csIBM869 +IBM870 2055 CP870 ebcdic-cp-roece ebcdic-cp-yu csIBM870 +IBM871 2056 CP871 ebcdic-cp-is csIBM871 +IBM880 2057 cp880 EBCDIC-Cyrillic csIBM880 +IBM891 2058 cp891 csIBM891 +IBM903 2059 cp903 csIBM903 +IBM904 2060 cp904 904 csIBBM904 +IBM905 2061 CP905 ebcdic-cp-tr csIBM905 +IBM918 2062 CP918 ebcdic-cp-ar2 csIBM918 +IBM1026 2063 CP1026 csIBM1026 +EBCDIC-AT-DE 2064 csIBMEBCDICATDE +EBCDIC-AT-DE-A 2065 csEBCDICATDEA +EBCDIC-CA-FR 2066 csEBCDICCAFR +EBCDIC-DK-NO 2067 csEBCDICDKNO +EBCDIC-DK-NO-A 2068 csEBCDICDKNOA +EBCDIC-FI-SE 2069 csEBCDICFISE +EBCDIC-FI-SE-A 2070 csEBCDICFISEA +EBCDIC-FR 2071 csEBCDICFR +EBCDIC-IT 2072 csEBCDICIT +EBCDIC-PT 2073 csEBCDICPT +EBCDIC-ES 2074 csEBCDICES +EBCDIC-ES-A 2075 csEBCDICESA +EBCDIC-ES-S 2076 csEBCDICESS +EBCDIC-UK 2077 csEBCDICUK +EBCDIC-US 2078 csEBCDICUS +UNKNOWN-8BIT 2079 csUnknown8BiT +MNEMONIC 2080 csMnemonic +MNEM 2081 csMnem +VISCII 2082 csVISCII +VIQR 2083 csVIQR +KOI8-R 2084 csKOI8R +KOI8-U 2088 +IBM00858 2089 CCSID00858 CP00858 PC-Multilingual-850+euro +IBM00924 2090 CCSID00924 CP00924 ebcdic-Latin9--euro +IBM01140 2091 CCSID01140 CP01140 ebcdic-us-37+euro +IBM01141 2092 CCSID01141 CP01141 ebcdic-de-273+euro +IBM01142 2093 CCSID01142 CP01142 ebcdic-dk-277+euro ebcdic-no-277+euro +IBM01143 2094 CCSID01143 CP01143 ebcdic-fi-278+euro ebcdic-se-278+euro +IBM01144 2095 CCSID01144 CP01144 ebcdic-it-280+euro +IBM01145 2096 CCSID01145 CP01145 ebcdic-es-284+euro +IBM01146 2097 CCSID01146 CP01146 ebcdic-gb-285+euro +IBM01147 2098 CCSID01147 CP01147 ebcdic-fr-297+euro +IBM01148 2099 CCSID01148 CP01148 ebcdic-international-500+euro +IBM01149 2100 CCSID01149 CP01149 ebcdic-is-871+euro +Big5-HKSCS 2101 +IBM1047 2102 IBM-1047 +PTCP154 2103 csPTCP154 PT154 CP154 Cyrillic-Asian +Amiga-1251 2104 Ami1251 Amiga1251 Ami-1251 +KOI7-switched 2105 +UNICODE-1-1 1010 csUnicode11 +SCSU 1011 +UTF-7 1012 +UTF-16BE 1013 +UTF-16LE 1014 +UTF-16 1015 +CESU-8 1016 csCESU-8 +UTF-32 1017 +UTF-32BE 1018 +UTF-32LE 1019 +BOCU-1 1020 csBOCU-1 +UNICODE-1-1-UTF-7 103 csUnicode11UTF7 +UTF-8 106 UNICODE-1-1-UTF-8 UNICODE-2-0-UTF-8 utf8 +ISO-8859-13 109 8859_13 ISO8859-13 +ISO-8859-14 110 iso-ir-199 ISO_8859-14:1998 ISO_8859-14 latin8 iso-celtic l8 8859_14 ISO8859-14 +ISO-8859-15 111 ISO_8859-15 Latin-9 8859_15 ISO8859-15 +ISO-8859-16 112 iso-ir-226 ISO_8859-16:2001 ISO_8859-16 latin10 l10 +GBK 113 CP936 MS936 windows-936 +GB18030 114 +OSD_EBCDIC_DF04_15 115 +OSD_EBCDIC_DF03_IRV 116 +OSD_EBCDIC_DF04_1 117 +JIS_Encoding 16 csJISEncoding +Shift_JIS 17 MS_Kanji csShiftJIS X-SJIS Shift-JIS +EUC-JP 18 csEUCPkdFmtJapanese Extended_UNIX_Code_Packed_Format_for_Japanese EUCJP +Extended_UNIX_Code_Fixed_Width_for_Japanese 19 csEUCFixWidJapanese +ISO-10646-UCS-Basic 1002 csUnicodeASCII +ISO-10646-Unicode-Latin1 1003 csUnicodeLatin1 ISO-10646 +ISO-Unicode-IBM-1261 1005 csUnicodeIBM1261 +ISO-Unicode-IBM-1268 1006 csUnicodeIBM1268 +ISO-Unicode-IBM-1276 1007 csUnicodeIBM1276 +ISO-Unicode-IBM-1264 1008 csUnicodeIBM1264 +ISO-Unicode-IBM-1265 1009 csUnicodeIBM1265 +ISO-8859-1-Windows-3.0-Latin-1 2000 csWindows30Latin1 +ISO-8859-1-Windows-3.1-Latin-1 2001 csWindows31Latin1 +ISO-8859-2-Windows-Latin-2 2002 csWindows31Latin2 +ISO-8859-9-Windows-Latin-5 2003 csWindows31Latin5 +Adobe-Standard-Encoding 2005 csAdobeStandardEncoding +Ventura-US 2006 csVenturaUS +Ventura-International 2007 csVenturaInternational +PC8-Danish-Norwegian 2012 csPC8DanishNorwegian +PC8-Turkish 2014 csPC8Turkish +IBM-Symbols 2015 csIBMSymbols +IBM-Thai 2016 csIBMThai +HP-Legal 2017 csHPLegal +HP-Pi-font 2018 csHPPiFont +HP-Math8 2019 csHPMath8 +Adobe-Symbol-Encoding 2020 csHPPSMath +HP-DeskTop 2021 csHPDesktop +Ventura-Math 2022 csVenturaMath +Microsoft-Publishing 2023 csMicrosoftPublishing +Windows-31J 2024 csWindows31J +GB2312 2025 csGB2312 EUC-CN EUCCN CN-GB +Big5 2026 csBig5 BIG-FIVE BIG-5 CN-BIG5 BIG_FIVE x-x-big5 +windows-1250 2250 CP1250 MS-EE +windows-1251 2251 CP1251 MS-CYRL +windows-1252 2252 CP1252 MS-ANSI +windows-1253 2253 CP1253 MS-GREEK +windows-1254 2254 CP1254 MS-TURK +windows-1255 2255 +windows-1256 2256 CP1256 MS-ARAB +windows-1257 2257 CP1257 WINBALTRIM +windows-1258 2258 +TIS-620 2259 +HZ-GB-2312 2085 + +# Additional encodings not defined by IANA + +# Arbitrary allocations +#CP737 3001 +#CP853 3002 +#CP856 3003 +CP874 3004 WINDOWS-874 +#CP922 3005 +#CP1046 3006 +#CP1124 3007 +#CP1125 3008 WINDOWS-1125 +#CP1129 3009 +#CP1133 3010 IBM-CP1133 +#CP1161 3011 IBM-1161 IBM1161 CSIBM1161 +#CP1162 3012 IBM-1162 IBM1162 CSIBM1162 +#CP1163 3013 IBM-1163 IBM1163 CSIBM1163 +#GEORGIAN-ACADEMY 3014 +#GEORGIAN-PS 3015 +#KOI8-RU 3016 +#KOI8-T 3017 +#MACARABIC 3018 X-MAC-ARABIC MAC-ARABIC +#MACCROATIAN 3019 X-MAC-CROATIAN MAC-CROATIAN +#MACGREEK 3020 X-MAC-GREEK MAC-GREEK +#MACHEBREW 3021 X-MAC-HEBREW MAC-HEBREW +#MACICELAND 3022 X-MAC-ICELAND MAC-ICELAND +#MACROMANIA 3023 X-MAC-ROMANIA MAC-ROMANIA +#MACTHAI 3024 X-MAC-THAI MAC-THAI +#MACTURKISH 3025 X-MAC-TURKISH MAC-TURKISH +#MULELAO-1 3026 +CP949 3027 WINDOWS-949 + +# From Unicode Lib +ISO-IR-182 4000 +ISO-IR-197 4002 +ISO-2022-JP-1 4008 +MACCYRILLIC 4009 X-MAC-CYRILLIC MAC-CYRILLIC +MACUKRAINE 4010 X-MAC-UKRAINIAN MAC-UKRAINIAN +MACCENTRALEUROPE 4011 X-MAC-CENTRALEURROMAN MAC-CENTRALEURROMAN +JOHAB 4012 +ISO-8859-11 4014 iso-ir-166 ISO_8859-11 ISO8859-11 8859_11 +X-CURRENT 4999 X-SYSTEM +X-ACORN-LATIN1 5001 +X-ACORN-FUZZY 5002 diff --git a/frontends/riscos/distribution/!System/310/Modules/CryptRand,ffa b/frontends/riscos/distribution/!System/310/Modules/CryptRand,ffa Binary files differnew file mode 100644 index 000000000..f403843b3 --- /dev/null +++ b/frontends/riscos/distribution/!System/310/Modules/CryptRand,ffa diff --git a/frontends/riscos/distribution/!System/310/Modules/Iconv,ffa b/frontends/riscos/distribution/!System/310/Modules/Iconv,ffa Binary files differnew file mode 100644 index 000000000..8a9cc3adb --- /dev/null +++ b/frontends/riscos/distribution/!System/310/Modules/Iconv,ffa diff --git a/frontends/riscos/distribution/!System/310/Modules/Network/URI,ffa b/frontends/riscos/distribution/!System/310/Modules/Network/URI,ffa Binary files differnew file mode 100644 index 000000000..431535e21 --- /dev/null +++ b/frontends/riscos/distribution/!System/310/Modules/Network/URI,ffa diff --git a/frontends/riscos/distribution/!System/310/Modules/SharedULib,ffa b/frontends/riscos/distribution/!System/310/Modules/SharedULib,ffa Binary files differnew file mode 100755 index 000000000..8dd0dd2c9 --- /dev/null +++ b/frontends/riscos/distribution/!System/310/Modules/SharedULib,ffa diff --git a/frontends/riscos/distribution/!System/310/Modules/Tinct,ffa b/frontends/riscos/distribution/!System/310/Modules/Tinct,ffa Binary files differnew file mode 100644 index 000000000..b8fda27b8 --- /dev/null +++ b/frontends/riscos/distribution/!System/310/Modules/Tinct,ffa diff --git a/frontends/riscos/distribution/3rdParty/AcornURI/!ReadMe b/frontends/riscos/distribution/3rdParty/AcornURI/!ReadMe new file mode 100644 index 000000000..4f4ca1e24 --- /dev/null +++ b/frontends/riscos/distribution/3rdParty/AcornURI/!ReadMe @@ -0,0 +1,34 @@ +AcornURI 1.04 +------------- + +Hi. This is a complete reimplementation of Acorn's URI module such that it +works on Iyonix. This allows simple URI / URL launching from applications. +Merge this !System with your own, then (re)launch your favourite browser to +ensure it's running. + +This has a few advantages over the official offering: it's smaller, +compatible with more browsers and more tolerant of errors. + +This is released under the terms of the LGPL, which is included in this +archive as the file Copying. Previous versions of this module were released +under the GPL, and are still available from sudden.recoil.org. + +Source is available from the same place you downloaded this archive, ie +<http://sudden.recoil.org/others/acornuri/acornuri104src.zip> + + +Changelog +--------- + +v1.04 20-May-06 Relicensed under the LGPL (rather than GPL) + +v1.03 11-May-04 Changed the order of things to try, so it now + always prefers browsers which are already loaded + +v1.02 19-Feb-04 Fixed claiming of URIs where I'd misread the spec + Added automatic fall-back to the ANT protocol + Removed some service calls to improve reliability + +-- +Christian Ludlam +chris@recoil.org
\ No newline at end of file diff --git a/frontends/riscos/distribution/3rdParty/AcornURI/Copying b/frontends/riscos/distribution/3rdParty/AcornURI/Copying new file mode 100644 index 000000000..5ab7695ab --- /dev/null +++ b/frontends/riscos/distribution/3rdParty/AcornURI/Copying @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/frontends/riscos/distribution/3rdParty/CryptRand/Copyright b/frontends/riscos/distribution/3rdParty/CryptRand/Copyright new file mode 100644 index 000000000..abb4a9b80 --- /dev/null +++ b/frontends/riscos/distribution/3rdParty/CryptRand/Copyright @@ -0,0 +1,46 @@ +CryptRandom + +Upstream sources were downloaded and built by +the GCCSDK Autobuilder. + +For information on the autobuilder see the URL: + +http://www.riscos.info/index.php/GCCSDK#GCCSDK_Autobuilder + +The source used for this build can be found at + +http://www.riscos.info/packages/src/System + +Upstream source fetched by CVS with + +CVS root theom@chiark.greenend.org.uk:/u3/theom/cvs-pub +Module cryptrandom +Upstream source fetched using SVN from + + +# For AOF builds needing another branch (if this is not defined AB_SVN is + +Copyright +--------- + +Copyright 2000-11 Theo Markettos <theo@markettos.org.uk> +Portions copyright Simon Tatham, Gary S. Brown and Eric Young + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including without +limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +SIMON TATHAM OR THEO MARKETTOS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/frontends/riscos/distribution/3rdParty/Iconv/ReadMe b/frontends/riscos/distribution/3rdParty/Iconv/ReadMe new file mode 100644 index 000000000..907c2c7c8 --- /dev/null +++ b/frontends/riscos/distribution/3rdParty/Iconv/ReadMe @@ -0,0 +1,45 @@ +What is Iconv? +============== + +Iconv is a module which provides character set conversion akin to that provided +by the C iconv() function. + +Iconv Installation instructions +=============================== + +To install the Iconv module, simply use the System merge utility provided by +Configure to merge the !System directory provided with the one on your system. + +Use the Boot merge facility in Configure to merge the provided !Boot directory +with the one on your system. If there is no !Boot merge facility provided on +your system, simply drag the !Boot directory over your existing boot structure. + +Further documentation can be found in the "doc" directory. + +Note for developers: +~~~~~~~~~~~~~~~~~~~~ +The "stubs" directory contains source for a set of C stubs. +See the ReadMe file in that directory for further information. + +Licence +======= + +Iconv is Copyright © 2004-13 J-M Bell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/frontends/riscos/distribution/3rdParty/Iconv/doc/API b/frontends/riscos/distribution/3rdParty/Iconv/doc/API new file mode 100644 index 000000000..13fa22fce --- /dev/null +++ b/frontends/riscos/distribution/3rdParty/Iconv/doc/API @@ -0,0 +1,132 @@ +Iconv Module API +================ + +If using C, then you really should be using the libiconv stubs provided +(or UnixLib, if appropriate). See the iconv.h header file for further +documentation of these calls. + +Iconv_Open (&57540) +------------------- + + Create a conversion descriptor + + On Entry: r0 -> string containing name of destination encoding (eg "UTF-8") + r1 -> string containing name of source encoding (eg "CP1252") + + On Exit: r0 = conversion descriptor + All others preserved + + Either encoding name may have a number of parameters appended to them. + Parameters are separated by a pair of forward-slashes ("//"). + Currently defined parameters are: + + Parameter: Destination: Source: + + TRANSLIT Transliterate unrepresentable None + output. + + The conversion descriptor is an opaque value. The user should not, + therefore, assume anything about its meaning, nor modify it in any way. + Doing so is guaranteed to result in undefined behaviour. + + +Iconv_Iconv (&57541) +-------------------- + + This SWI is deprecated and Iconv_Convert should be used instead. + + +Iconv_Close (&57542) +-------------------- + + Destroy a conversion descriptor + + On Entry: r0 = conversion descriptor to destroy + + On Exit: r0 = 0 + All others preserved + + +Iconv_Convert (&57543) +--------------------- + + Convert a byte sequence to another encoding + + On Entry: r0 = conversion descriptor returned by Iconv_Open + r1 -> input buffer (or NULL to reset encoding context) + r2 = length of buffer pointed to by r1 + r3 -> output buffer + r4 = length of buffer pointed to by r3 + + On Exit: r0 = number of non-reversible conversions performed (always 0) + r1 -> updated input buffer pointer (after last input read) + r2 = number of bytes remaining in input buffer + r3 -> updated output buffer pointer (i.e. end of output) + r4 = number of free bytes in the output buffer + All others preserved + + Note that all strings should be NUL-terminated so, if calling from BASIC, + some terminating character munging may be needed. + + +Errors: + +Should an error occur, the SWI will return with V set and r0 -> error buffer. +Note that only the error number will be filled in and may be one of: + + ICONV_NOMEM (&81b900) + ICONV_INVAL (&81b901) + ICONV_2BIG (&81b902) + ICONV_ILSEQ (&81b903) + +These map directly to the corresponding C errno values. + + +Iconv_CreateMenu (&57544) +------------------------- + + Create a menu data structure containing all available encodings. + + On Entry: r0 = flags. All bits reserved, must be 0 + r1 -> buffer, or 0 to read required length + r2 = length of buffer in r1 + r3 -> currently selected encoding name, or 0 if none selected + r4 -> buffer for indirected data, or 0 to read length + r5 = length of buffer in r4 + + On Exit: r2 = required size of buffer in r1 if r1 = 0 on entry, + or length of data placed in buffer + r5 = required size of buffer in r4 if r4 = 0 on entry, + or length of data placed in buffer + + Menu titles are direct form text buffers. Menu entries are indirect text. + Entry text is stored in the buffer pointed to by R4 on entry to this call. + + +Iconv_DecodeMenu (&57545) +------------------------- + + Decode a selection in a menu generated by Iconv_CreateMenu. + Places the corresponding encoding name in the result buffer. + + On Entry: r0 = flags. All bits reserved, must be 0 + r1 -> menu definition + r2 -> menu selections, as per Wimp_Poll + r3 -> buffer for result or 0 to read required length + r4 = buffer length + + On Exit: r4 = required size of buffer if r3 = 0 on entry, + or length of data placed in buffer (0 if no selected + encoding) + + The menu selections block pointed to by r2 on entry should be based at + the root of the encodings menu structure (i.e. index 0 in the block + should correspond to the selection in the main encoding menu). + + This call will update the selection status of the menu(s) appropriately. + + +Example Code: +============= + +Example code may be found in the IconvEg BASIC file. diff --git a/frontends/riscos/distribution/3rdParty/Iconv/doc/ChangeLog b/frontends/riscos/distribution/3rdParty/Iconv/doc/ChangeLog new file mode 100644 index 000000000..3a22a45fa --- /dev/null +++ b/frontends/riscos/distribution/3rdParty/Iconv/doc/ChangeLog @@ -0,0 +1,114 @@ +Iconv Changelog +=============== + +0.01 10-Sep-2004 +---------------- + + - Initial version - unreleased. + +0.02 27-Sep-2004 +---------------- + + - Use allocated SWI & error chunks. + - Fix issues in 8bit encoding handling. + - First public release. + +0.03 22-Jan-2005 +---------------- + + - Add Iconv_Convert SWI with improved interface. + - Deprecate Iconv_Iconv SWI. + - Add encoding name alias handling. + - Bundle !Unicode resource. + +0.04 08-Apr-2005 +---------------- + + - Improve parameter checking. + - Fix potential memory leaks. + - Add encoding menu creation and selection handling. + +0.05 27-Jun-2005 +---------------- + + - Improve encoding alias support, using external data file. + - Add StubsG build for A9home users. + +0.06 05-Nov-2005 +---------------- + + - Modified menu creation API to store indirected text in a + user-provided buffer. This change is backwards incompatible. + +0.07 11-Feb-2006 +---------------- + + - Corrected output values for E2BIG errors. + - Fixed input pointer update after successful conversion. + +0.08 11-Mar-2007 +---------------- + + - Tightened up parameter checking in various places. + - Improve aliases hash function. + - Make 8bit write function's return values match encoding_write + with encoding_WRITE_STRICT set. + - Fix bug in 8bit writing which resulted in the remaining buffer + size being reduced even if nothing was written. + - Improve support for endian-specific Unicode variants. + - Work around issue in UnicodeLib where remaining buffer size is + reduced if an attempt is made to write an unrepresentable character. + - Add rudimentary //TRANSLIT support - simply replaces with '?' for now. + - Make UnicodeLib handle raw ISO-8859-{1,2,9,10,15} and not attempt + ISO-6937-2-25 shift sequences. + - Remove StubsG build as A9home now has a C99 capable C library. + - Overhaul documentation. + +0.09 20-Nov-2008 +---------------- + + - Restructured source tree into cross-platform and RO-specific parts. + - New build system to go with this. + - Fixes for compiling with GCC4. + - Introduce *Iconv command which performs command line conversion. + - Fixes/improvements to the handlers for: + + US-ASCII + + UTF-8 + + ISO-8859-7 + + ISO-8859-8 + + ISO-8859-11 + + Windows-1256 + + MacRoman + + JIS X 0208 + + JIS X 0212 + + KS X 1001 + + EUC-JP + + Any ISO-2022 based charset that uses a 94x94 table in GR + + Johab + + ShiftJIS + - Add support for ISO-8859-16 (Latin 10) + - Significantly improve detection and reporting of error conditions + +0.10 29-Nov-2008 +---------------- + + - Fixes to the *Iconv command parameter parsing + - Ensure *Iconv outputs all converted data when the input is invalid + - Fix handling of illegal UTF-8 byte sequences + - Fix handling of incomplete multibyte input sequences. + +0.11 04-Jan-2011 +---------------- + + - Detect missing mapping file when using 8bit codecs. This prevents spurious + memory exhaustion errors. + - Toolchain used to build 0.10 turns out to have produced broken code. + - Minor additions to the charset alias mapping file. + +0.12 20-Jan-2013 +--------------- + + - Master alias mapping file now lives in ROOL repository. + - Correct handling of trailing valid shift sequences. Previously would + erroneously report EINVAL, instead of silently accepting them. + - Add proper transliteration behaviour when requested using //TRANSLIT. diff --git a/frontends/riscos/distribution/3rdParty/Iconv/doc/Uni-iconv b/frontends/riscos/distribution/3rdParty/Iconv/doc/Uni-iconv new file mode 100644 index 000000000..caea2d0f1 --- /dev/null +++ b/frontends/riscos/distribution/3rdParty/Iconv/doc/Uni-iconv @@ -0,0 +1,204 @@ +Introduction: +============= + +This file documents an approximate correlation between the data files +provided in the !Unicode distribution and the encoding headers in GNU +libiconv 1.9.1. + +Those with '?' in the iconv column either are not represented in iconv +or I've missed the relevant header file ;) + +A number of encodings are present in the iconv distribution but not +in !Unicode. These are documented at the end of this file. + +Changelog: +========== + +v 0.01 (09-Sep-2004) +~~~~~~~~~~~~~~~~~~~~ +Initial Incarnation + +v 0.02 (11-Sep-2004) +~~~~~~~~~~~~~~~~~~~~ +Documented additional encodings supported by the Iconv module. +Corrected list of !Unicode deficiencies. + + +!Unicode->iconv: +================ + +Unicode: iconv: notes: + +Acorn.Latin1 riscos1.h + +Apple.CentEuro mac_centraleurope.h +Apple.Cyrillic mac_cyrillic.h +Apple.Roman mac_roman.h +Apple.Ukrainian mac_ukraine.h + +BigFive big5.h + +ISO2022.C0.40[ISO646] ? + +ISO2022.C1.43[IS6429] ? + +ISO2022.G94.40[646old] iso646_cn.h +ISO2022.G94.41[646-GB] ? +ISO2022.G94.42[646IRV] ? +ISO2022.G94.43[FinSwe] ? +ISO2022.G94.47[646-SE] ? +ISO2022.G94.48[646-SE] ? +ISO2022.G94.49[JS201K] jisx0201.h top of JIS range +ISO2022.G94.4A[JS201R] jisx0201.h iso646_jp.h bottom of JIS range +ISO2022.G94.4B[646-DE] ? +ISO2022.G94.4C[646-PT] ? +ISO2022.G94.54[GB1988] ? +ISO2022.G94.56[Teltxt] ? +ISO2022.G94.59[646-IT] ? +ISO2022.G94.5A[646-ES] ? +ISO2022.G94.60[646-NO] ? +ISO2022.G94.66[646-FR] ? +ISO2022.G94.69[646-HU] ? +ISO2022.G94.6B[Arabic] ? +ISO2022.G94.6C[IS6397] ? +ISO2022.G94.7A[SerbCr] ? + +ISO2022.G94x94.40[JS6226] ? +ISO2022.G94x94.41[GB2312] gb2312.h +ISO2022.G94x94.42[JIS208] jis0x208.h +ISO2022.G94x94.43[KS1001] ksc5601.h +ISO2022.G94x94.44[JIS212] jis0x212.h +ISO2022.G94x94.47[CNS1] cns11643_1.h the tables differ +ISO2022.G94x94.48[CNS2] cns11643_2.h +ISO2022.G94x94.49[CNS3] cns11643_3.h +ISO2022.G94x94.4A[CNS4] cns11643_4.h +ISO2022.G94x94.4B[CNS5] cns11643_5.h +ISO2022.G94x94.4C[CNS6] cns11643_6.h +ISO2022.G94x94.4D[CNS7] cns11643_7.h + +ISO2022.G96.41[Lat1] iso8859_1.h +ISO2022.G96.42[Lat2] iso8859_2.h +ISO2022.G96.43[Lat3] iso8859_3.h +ISO2022.G96.44[Lat4] iso8859_4.h +ISO2022.G96.46[Greek] ? +ISO2022.G96.47[Arabic] iso8859_6.h ISO-8859-6 ignored +ISO2022.G96.48[Hebrew] ? +ISO2022.G96.4C[Cyrill] ? +ISO2022.G96.4D[Lat5] iso8859_5.h +ISO2022.G96.50[LatSup] ? +ISO2022.G96.52[IS6397] ? +ISO2022.G96.54[Thai] tis620.h +ISO2022.G96.56[Lat6] iso8859_6.h +ISO2022.G96.58[L6Sami] ? +ISO2022.G96.59[Lat7] iso8859_7.h +ISO2022.G96.5C[Welsh] ? +ISO2022.G96.5D[Sami] ? +ISO2022.G96.5E[Hebrew] ? +ISO2022.G96.5F[Lat8] iso8859_8.h +ISO2022.G96.62[Lat9] iso8859_9.h + +KOI8-R koi8_r.h + +Microsoft.CP1250 cp1250.h +Microsoft.CP1251 cp1251.h +Microsoft.CP1252 cp1252.h +Microsoft.CP1254 cp1254.h +Microsoft.CP866 cp866.h +Microsoft.CP932 cp932.h cp932ext.h + +iconv->!Unicode: +================ + +Iconv has the following encodings, which are not present in !Unicode. +Providing a suitable data file for !Unicode is trivial. Whether UnicodeLib +will then act upon the addition of these is unknown. +This list is ordered as per libiconv's NOTES file. + +European & Semitic languages: + + ISO-8859-16 (iso8859_16.h) + KOI8-{U,RU,T} (koi8_xx.h) + CP125{3,5,6,7} (cp125n.h) + CP850 (cp850.h) + CP862 (cp862.h) + Mac{Croatian,Romania,Greek,Turkish,Hebrew,Arabic} (mac_foo.h) + +Japanese: + + None afaikt. + +Simplified Chinese: + + GB18030 (gb18030.h, gb18030ext.h) + HZ-GB-2312 (hz.h) + +Traditional Chinese: + + CP950 (cp950.h) + BIG5-HKSCS (big5hkscs.h) + +Korean: + + CP949 (cp949.h) + +Armenian: + + ARMSCII-8 (armscii_8.h) + +Georgian: + + Georgian-Academy, Georgian-PS (georgian_academy.h, georgian_ps.h) + +Thai: + + CP874 (cp874.h) + MacThai (mac_thai.h) + +Laotian: + + MuleLao-1, CP1133 (mulelao.h, cp1133.h) + +Vietnamese: + + VISCII, TCVN (viscii.h, tcvn.h) + CP1258 (cp1258.h) + +Unicode: + + BE/LE variants of normal encodings. I assume UnicodeLib handles + these, but can't be sure. + C99 / JAVA - well, yes. + + +Iconv Module: +============= + +The iconv module is effectively a thin veneer around UnicodeLib. However, +8bit encodings are implemented within the module rather than using the +support in UnicodeLib. The rationale for this is simply that, although +UnicodeLib will understand (and act upon - reportedly...) additions to +the ISO2022 Unicode resource, other encodings are ignored. As the vast +majority of outstanding encodings fall into this category, and the code +is fairly simple, it made sense to implement it within the module. + +With use of the iconv module, the list of outstanding encodings is +reduced to: + + CP1255 (requires state-based transcoding) + + GB18030 (not 8bit - reportedly a requirement of PRC) + HZ-GB-2312 (not 8bit - supported by IE4) + + CP950 (not 8bit - a (MS) variant of Big5) + BIG5-HKSCS (not 8bit - again, a Big5 variant) + + CP949 (not 8bit) + + ARMSCII-8 (easily implemented, if required) + + VISCII (easily implemented, if required) + CP1258, TCVN (requires state-based transcoding) + +Additionally, the rest of the CodePage encodings implemented in iconv +but not listed above (due to omissions from the iconv documentation) +are implemented by the iconv module. diff --git a/frontends/riscos/distribution/3rdParty/SharedULib/Copyright b/frontends/riscos/distribution/3rdParty/SharedULib/Copyright new file mode 100644 index 000000000..b6784ed06 --- /dev/null +++ b/frontends/riscos/distribution/3rdParty/SharedULib/Copyright @@ -0,0 +1,761 @@ +UnixLib Copyright +----------------- + +UnixLib is Copyright (c) 1995-1999 Simon Callan, Nick Burrett, +Nicholas Clark and Peter Burwood. + +These contributors have expressed "no interest" in any further licensing or +copyright in regards to UnixLib. + +Other sections are (c) 1999-2006 Nick Burrett, John Tytgat, Peter Naulls, +Peter Teichmann, Alex Waugh, Christian Ludlam, Theo Markettos, Graham Shaw, +James Bursa and John-Mark Bell. + +In January 2005, permission was obtained from all relevant contributors +by Peter Naulls to license all past and present contributions to UnixLib +(where possible) under the revised BSD license. The license is included +in the next section and is applicable to all code in UnixLib that does not +have an explicit license in its source. + +Prior to 4th January 2005 and after May 2001, UnixLib contained code licensed +under the GNU General Public License, and versions of UnixLib produced +between these dates are subject to the provisions of the GPL. We realised +that this might cause potential problems with the wider use of UnixLib in +RISC OS, and along with the desire to clarify the overall licensing status of +UnixLib, GPL code was removed from UnixLib and the above permission from all +copyright holders allowed UnixLib contributions to be relicensed as per the +revised BSD license. The GPL is therefore not included in this notice +as it is no longer relevant to UnixLib. + + +Practical notes on using UnixLib in your own programs: + +This is a plain English version of guidelines for use of UnixLib in +your programs. It does not override any of the licenses included +below, but is intended to state instances when it may be used in +free and non-free software. Where there is contradiction or +ambiguity in this wording, please refer to the specifics of the licence +in question. These recommendations are based upon our understading +of the GPL/LGPL and BSD licenses and are subject to change should +our understanding of the topics improve. + + - Because UnixLib contains code that is subject to the Lesser GNU + Public License, the LGPL is the overriding consideration when + linking UnixLib to programs (unless the program itself is GPL). + + - You are free to use sections of UnixLib in your own programs + subject to the conditions of that code. If the entirety of + that code is under a BSD license, then you can generally use + that code as you see fit, and there is no further obligation + from you as long as the copyright notice remains. If you + use LGPL code in your program, then your program must also be + distributed under the LGPL (or GPL). + + - If you use UnixLib in its intended original form - that is as a + supporting library for ported programs to RISC OS - then your program + is subject to the LGPL; or the GPL if the program is covered by that. + Note that you must make the source and any modifications available to for + both if requested. This is of course equally true if you write an original + GPL program using UnixLib. In most cases, no additional action is + required of you, especially since source is usually readibly available. + + - If you use UnixLib for a non-free program - whether that's commercial or + otherwise, then you should carefully read section 6 of the LGPL. This + applies, because at the present time, there is no practical method of + dynamic linking on RISC OS. At such time that UnixLib is available as a + shared library, then programs dynamically linking to it will no longer be + subject to the LPGL as applied to UnixLib. + + - Section 6 means that in practice, you must supply, or offer to + supply either source or object code for your program. + This is mainly to allow rebuilding of the executable program + with later or modified versions of UnixLib. You must of course + supply (or better, contribute to the GCCSDK project) any + modifications you make to UnixLib upon request. + + +Recommended reading: + +Frequently Asked Questions about the GNU GPL +http://www.fsf.org/licenses/gpl-faq.html (has some sections on LGPL) + +About the justifications for using LGPL +http://www.fsf.org/licenses/why-not-lgpl.html + + + +=========================================================================== + + Copyright (c) 1995-2005 UnixLib Developers + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================== + +Portions of UnixLib are copyright The Regents of the University of +California. + +Portions of this library are copyright Sun Microsystems, Inc. The + +Portions of this library are derived from the GNU C Library and fall under +the GNU Library General Public License. + +Portions of this library are copyright Henry Spencer. + +Portions of this library are copyright The Regents of the University of +California, Sun Microsystems, Inc., Scriptics Corporation, ActiveState +Corporation and other parties. + +Portions of this library are copyright PostgreSQL Global Development Group. + +The licenses for the above are duplicated below. + + +=========================================================================== + + Copyright (c) The Regents of the University of California. + All rights reserved. + + This code is derived from software contributed to Berkeley by + Chris Torek. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. All advertising materials mentioning features or use of this software + must display the following acknowledgement: + This product includes software developed by the University of + California, Berkeley and its contributors. + 4. Neither the name of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +=========================================================================== + + Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + + Developed at SunPro, a Sun Microsystems, Inc. business. + Permission to use, copy, modify, and distribute this + software is freely granted, provided that this notice + is preserved. + +=========================================================================== + + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + +=========================================================================== + +Copyright (c) 1998, 1999 Henry Spencer. All rights reserved. + +Development of this software was funded, in part, by Cray Research Inc., +UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics +Corporation, none of whom are responsible for the results. The author +thanks all of them. + +Redistribution and use in source and binary forms -- with or without +modification -- are permitted for any purpose, provided that +redistributions in source form retain this entire copyright notice and +indicate the origin and nature of any modifications. + +I'd appreciate being given credit for this package in the documentation +of software which uses it, but that is not a requirement. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================== + +This software is copyrighted by the Regents of the University of +California, Sun Microsystems, Inc., Scriptics Corporation, ActiveState +Corporation and other parties. The following terms apply to all files +associated with the software unless explicitly disclaimed in +individual files. + +The authors hereby grant permission to use, copy, modify, distribute, +and license this software and its documentation for any purpose, provided +that existing copyright notices are retained in all copies and that this +notice is included verbatim in any distributions. No written agreement, +license, or royalty fee is required for any of the authorized uses. +Modifications to this software may be copyrighted by their authors +and need not follow the licensing terms described here, provided that +the new terms are clearly indicated on the first page of each file where +they apply. + +IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +MODIFICATIONS. + +GOVERNMENT USE: If you are acquiring this software on behalf of the +U.S. government, the Government shall have only "Restricted Rights" +in the software and related documentation as defined in the Federal +Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you +are acquiring the software on behalf of the Department of Defense, the +software shall be classified as "Commercial Computer Software" and the +Government shall have only "Restricted Rights" as defined in Clause +252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the +authors grant the U.S. Government and others acting in its behalf +permission to use and distribute the software in accordance with the +terms specified in this license. + +=========================================================================== + +PostgreSQL Database Management System +(formerly known as Postgres, then as Postgres95) + +Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group + +Portions Copyright (c) 1994, The Regents of the University of California + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose, without fee, and without a written agreement +is hereby granted, provided that the above copyright notice and this +paragraph and the following two paragraphs appear in all copies. + +IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR +DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING +LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS +ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO +PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. diff --git a/frontends/riscos/distribution/3rdParty/Tinct/!Help b/frontends/riscos/distribution/3rdParty/Tinct/!Help new file mode 100644 index 000000000..2e27e354f --- /dev/null +++ b/frontends/riscos/distribution/3rdParty/Tinct/!Help @@ -0,0 +1,304 @@ +Tinct +===== +This module provides the necessary functionality to display alpha-blended +sprites both scaled and otherwise. It also provides functions for dithering, +error diffusion and performing bi-linear filtering to improve their appearance. + + +Technical information +¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ +To ensure future compatibility, this module does not patch the OS in any way +and works in a totally legal way. It also does not write to itself in any +way, so is suitable for running from ROM. + Redirection to sprites is supported, although due to the overheads involved +with caching the colour translation tables it is not recommended that this is +done frequently. There are some exceptions to this, however, as redirecting to +a 16bpp or 32bpp mode sprite does not require any translation tables, and +redirecting to a sprite that has the same mode and palette as the previous +destination that Tinct was used for causes a minimum overhead as the +translation tables are checked and cached values are used if possible. + +Format of a sprite with 8-bit alpha channel +¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ +The sprite format used by Tinct differs from those used by RISC OS Select, +and whilst facilities are supplied to convert sprites into the required format, +no facilities are provided to manipulate them. + All sprites used by Tinct must be 32bpp, and cannot have a standard RISC OS +mask specified. The basic format of the sprite is shown below, with the +restrictions to the standard sprite format marked with an asterisk (*): + + [+0] Offset to next sprite + [+4] Sprite name, up to 12 characters with trailing zeroes + [+16] Width in words - 1 + [+20] Height in scan lines - 1 + [+24] First bit used + [+28] Last bit used + [+32] Offset to sprite image + [+36] * Offset to sprite image (no mask allowed) + [+40] * Sprite type (must be 0x301680B5) + +Whereas for normal sprites the sprite image would be a series of colour words +of the format RrGgBb00, alpha-blended sprites use the empty byte to specify +the alpha value, ie RrGgBbAa. + The alpha values represent the blending level on a linear scale where 0x00 +represents that the source pixel is totally transparent and 0xff that it is +totally opaque. It should be noted that as a standard 32bpp sprite (eg as +created with !Paint) will have the alpha channel set to 0x00 by default no +output will be visible when plotting as an alpha-blended sprite. + +Error handling +¨¨¨¨¨¨¨¨¨¨¨¨¨¨ +If an incorrect sprite is attempted to be used, Tinct currently always returns +error number 0x700 (SBadSpriteFile) rather than the specific cause of the +problem (eg. BadDPI, BadMSFlags or BadPixelDepth) as OS_SpriteOp would do. +There are several technical reasons for this behaviour, and future versions of +Tinct may return more descriptive errors depending on the cause. + + +SWIs provided +¯¯¯¯¯¯¯¯¯¯¯¯¯ +Tinct provides four SWIs to plot sprites and one to convert sprites to their +32bpp equivalent. All values supplied to Tinct must be in OS units, and the +current OS clipping rectangle is used. + The sprite pointers provided are equivalent to calling OS_SpriteOp with +bit 9 of the reason code set. To plot a sprite by name, the sprite should +first be found by using OS_SpriteOp with reason code 0x18 and using the +returned sprite address. + +Tinct_PlotAlpha (0x57240) +¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ +Plots an alpha-blended sprite at the specified coordinates. + +-> R2 Sprite pointer + R3 X coordinate + R4 Y coordinate + R7 Flag word + + +Tinct_PlotScaledAlpha (0x57241) +¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ +Plots a scaled alpha-blended sprite at the specified coordinates. + +-> R2 Sprite pointer + R3 X coordinate + R4 Y coordinate + R5 Scaled sprite width + R6 Scaled sprite height + R7 Flag word + + +Tinct_Plot (0x57242) +¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ +Plots a sprite at the specified coordinates with a constant 0xff value for +the alpha channel, ie without a mask. + +-> R2 Sprite pointer + R3 X coordinate + R4 Y coordinate + R7 Flag word + + +Tinct_PlotScaled (0x57243) +¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ +Plots a scaled sprite at the specified coordinates with a constant 0xff value +for the alpha channel, ie without a mask. + +-> R2 Sprite pointer + R3 X coordinate + R4 Y coordinate + R5 Scaled sprite width + R6 Scaled sprite height + R7 Flag word + + +Tinct_ConvertSprite (0x57244) +¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ +Converts a paletted sprite into its 32bpp equivalent. Sufficient memory must +have previously been allocated for the sprite (44 + width * height * 4). + As sprites with 16bpp or 32bpp do not have palettes, conversion cannot be +performed on these variants. All sprites must be supplied with a full palette, +eg 8bpp must have 256 palette entries. + +-> R2 Source sprite pointer + R3 Destination sprite pointer + + +Tinct_AvailableFeatures (0x57245) +¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ +Returns the features available to the caller by specifying bits in the flag +word. The features available are unique for each mode, although the current +version of Tinct supports the same subset of features for all modes. + +-> R0 Feature to test for, or 0 for all features +<- R0 Features available + + +Tinct_Compress (0x57246) +¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ +Compresses an image using a fast algorithm. Sufficient memory must have been +previously allocated for the maximum possible compressed size. This value is +equal to 28 + (width * height * 4) * 33 / 32. + +-> R0 Source sprite pointer + R2 Output data buffer + R3 Output bytes available + R7 Flag word +<- R0 Size of compressed data + + +Tinct_Decompress (0x57247) +¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ +Decompresses an image previously compressed. Sufficient memory must have been +previously allocated for the decompressed data (44 + width * height * 4) where +width and height are available at +0 and +4 of the compressed data respectively. + +-> R0 Input data buffer + R2 Output data buffer + R7 Flag word (currently 0) +<- R0 Size of decompressed data + + +Flag word (plotting) +¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ +All the SWIs provided by Tinct for plotting use a common flag word to +describe the manner in which the plot is performed. Each bit controls a +particular characteristic of the plotting: + + 0 Forcibly read the screen base (only use if hardware scrolling) + 1 Use bi-linear filtering when scaling sprites + 2 Dither colours in 16bpp and below + 3 Perform error diffusion if bit 2 clear, invert dither pattern if set + 4 Horizontally fill the current graphics window with the sprite + 5 Vertically fill the current graphics window with the sprite + 6 Forcibly read the palette (only use if changing palette outside of + the WIMP) + 7 Use OS_SpriteOp to perform final plotting (see note) + 8+ Reserved (must be 0) if bit 7 is clear, background colour to + blend the alpha channel to otherwise + +If a bit is set in the flag word that cannot be honoured by the current +version of Tinct then it is ignored. Tinct_AvailableFeatures can be used +to test in advance what flags will be honoured. + +Bi-linear filtering +¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ +Although bi-linear filtering is only relevant during scaled plotting, this +situation occurs when the EigFactors of the mode are not equal. As such, an +application should always set their preferred flags to ensure consistency. The +case of XEig * 2 = YEig (rectangular pixel modes) for even height sprites is a +special case and has optimised code implemented. + There is an upper limit to the size of sprite that can be bi-linear filtered. +The checks that are currently made are: + + scaled_width / sprite_width < 256 + scaled_height / sprite_height < 256 + scaled_width * max(sprite_height, scaled_height) < 32,768 + + It should be noted that as bi-linear filtering is performed as a pre-filter, +it carries a sizable overhead. However, as all scaling calculations are +performed during this filter, tiled plotting (bits 4 and 5) are affected by +a smaller margin (in certain cases a speed gain can be achieved). + As bi-linear filtering is performed using a pre-filter, it can be used in +association with OS_SpriteOp rendering. + +Error diffusion and dithering +¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ +If both error diffusion and dithering are enabled then the image is plotted +using only dithering, but with the dither pattern inverted. This enables an +application to provide the user with what appears to be a higher quality image +by redrawing every frame with the flag toggled. + There is a significant speed difference between dithering and error diffusion, +and Tinct does not support error diffusion in all colour depths. If error +diffusion is requested, but cannot be performed by Tinct then dithering with +an inverted pattern is used (as if bits 2 and 3 were set). + There is an upper limit to the size of sprite that Tinct can perform error +diffusion on. This is currently set to a display width of 2047 pixels wide with +an unlimited height. Any attempt to use a higher resolution will result in +dithered rendering with an inverted pattern (ie bits 2 and 3 set). + As error diffusion and dithering are implemented during the plot cycle, it is +not possible to use them in association with OS_SpriteOp rendering. However, +the bits should be set as future versions of Tinct may respect them for users +of RISC OS 3.1 where true colour sprites are not supported. + +Sprite filling +¨¨¨¨¨¨¨¨¨¨¨¨¨¨ +If filling is specified, then the supplied co-ordinate is the offset of the +pattern relative to (0, 0) used for the fill. For example, a 64x64 sprite that +is plotted with bits 4 and 5 set and a position of (32, 16) would fill the +current graphics window with multiple copies of the image stating with the +first image plotted at (-32, -48). + The caller should not concern itself with the size of the image being tiled +as small images are internally optimised where possible to maximise the +plotting speed. + +Rendering using OS_SpriteOp +¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ +It can be useful to use Tinct to perform the rendering to using OS_SpriteOp. +There are two general situations where this may be useful: + + 1) To output to a printer driver + 2) To allow hardware acceleraton (such as a ViewFinder card) + +By using Tinct rather than a direct OS_SpriteOp call, it allows the caller to +retain certain features Tinct provides (such as sprite filling and a limited +version of the standard alpha blending) and allows the caller to have a common +plotting interface. + When using this feature for alpha-blended sprites, the background colour +specified in the top 24-bits of the flag word is used for blending with any +pixels that are not transparent. This requires that Tinct requires a second +copy of the sprite in memory to modify which may present a significant overhead +in some situations. Plotting opaquely does not have any such overheads. + Using OS_SpriteOp rendering does not currently work on RISC OS 3.1 or earlier +due to the lack of support for true colour sprites. Future versions of Tinct +may remove this restriction. + + +Flag word (compression) +¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ +The flag word used by Tinct_Compress can be used to improve the compression +ratio by performing pre-filtering on the data. The flags below relate only to +compression and should not be passed to Tinct_Decompress. + + 0 Image is opaque, remove the alpha channel prior to compression + +All unspecified bits are reserved for future expansion and as such should be +set to 0. + +Compressed data format +¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ +Certain aspects of the compressed data format are guaranteed to remain constant, +so may be used by applications. + + +0 Sprite width + +4 Sprite height + +8 Sprite name (12 chars) + +20 Compression flags + +24 Number of bytes of data following + +The method of compression is not guaranteed to remain constant over future +revisions of Tinct, but subsequent versions will decompress data compressed +with previous versions. + + +Contact details +¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ +If you would like to report a problem relating to Tinct, provide feedback, or +request a licence for a commercial product, please use the details below: + +Address: 5 Queens Close, East Markham, Newark, Nottinghamshire, NG22 0QY. UK +E-mail: info@tinct.net +Website: www.tinct.net + + +Copyright and licence details +¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ +Tinct is © copyright Richard Wilson, 2004. + +Distribution and usage +¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ +Unrestricted use of Tinct is hereby granted for any non-commercial product. Any +use as part of a commercial product requires written consent from the author. +No charge may be made relating to the distribution of this software, and this +copyright information should be included in all copies of the software. + Modified versions of this program may not be distributed without the authors +consent, nor may modified versions of the source code or relating files.
\ No newline at end of file diff --git a/frontends/riscos/distribution/LeesMij b/frontends/riscos/distribution/LeesMij new file mode 100644 index 000000000..a0d3ff41f --- /dev/null +++ b/frontends/riscos/distribution/LeesMij @@ -0,0 +1,73 @@ +NetSurf +======= + +Dit is een ontwikkelversie van NetSurf, een webbrowser met open +broncode. + +De nieuwste versie van NetSurf is verkrijgbaar via: + + http://www.netsurf-browser.org/ + + +Installatie +----------- + +De installatie gaat in drie stappen: + + 1. Gebruik de samenvoegfaciliteit van !Boot (te openen via de + besturingssysteeminstellingen -> !Boot) om de meegeleverde + !Boot-map samen te voegen met die van het systeem. + + Als het besturingssysteem geen !Boot-samenvoegfaciliteit + ondersteund, sleep dan de meegeleverde !Boot-map in de map + waarin de bestaande !Boot-structuur staat. + + 2. Gebruik de samenvoegfaciliteit van !System (te openen via de + besturingssysteeminstellingen -> !System) om de meegeleverde + !System-map samen te voegen met die van het systeem. + + 3. Sleep de !NetSurf-programmamap naar de gewenste map op de + harde schijf. + +Dubbelklik op het programma !NetSurf in de gekozen locatie om de +NetSurf-browser te starten. + + +Opmerking NetSurf vereist de WindowManager-module 3.80 of een + recentere versie. Deze is standaard aanwezig in RISC OS 4 + of een recentere versie. Voor RISC OS 3-gebruikers zijn + er twee mogelijkheden om NetSurf te kunnen gebruiken: + + - De 'Universal !Boot Sequence' van Acorn: + http://www.riscos.com/ftp_space/generic/uniboot/ + - HardDisc4-schijfstructuur van RISC OS Open: + https://www.riscosopen.org/content/downloads/common/ + + +Opmerking RISC OS 3.1 of oudere versies worden niet ondersteund. + + +Licenties +--------- + +NetSurf wordt geleverd onder de GPL, evenals verschillende andere +licenties voor de verschillende componenten die het programma +gebruikt. Bezoek in de NetSurf-browser het URL-adres 'about:licence' +voor meer informatie. + + +De meegeleverde !Boot- en !System-mappen bevatten items die door +derden zijn geproduceerd. De bijbehorende licenties zijn meegeleverd +in de map '3rdParty'. + +AcornURI + http://sudden.recoil.org/others/ + +Iconv + http://www.netsurf-browser.org/iconv/ + +SharedUnixLibrary + http://www.riscos.info/downloads/gccsdk/sharedunixlib/system.zip + +Tinct + http://www.tinct.net/tinct.asp diff --git a/frontends/riscos/distribution/ReadMe b/frontends/riscos/distribution/ReadMe new file mode 100644 index 000000000..eec39d6ab --- /dev/null +++ b/frontends/riscos/distribution/ReadMe @@ -0,0 +1,61 @@ +NetSurf +======= + +This is a development build of NetSurf, an open source web browser. + +The latest version of NetSurf is available from: + + http://www.netsurf-browser.org/ + + +Installation +------------ + +Installation is a three step process: + + 1. Use the Boot Merge facility provided by Configure to merge + the supplied !Boot directory with the one on your system. + + If there is no !Boot merge facility on your system, simply + drag the supplied !Boot over your existing boot structure. + + 2. Use the System Merge facility provided by Configure to merge + the supplied !System directory with the one on your system. + + 3. Drag the !NetSurf application directory to a place on your + hard disc. + +Double click on !NetSurf in your chosen location to launch NetSurf. + + +Note NetSurf requires WindowManager 3.80 or later. This comes + with RISC OS 4 and above. RISC OS 3 users should install + the Universal Boot Sequence from: + http://acorn.riscos.com/riscos/releases/UniBoot/ + +Note RISC OS 3.1 and earlier are not supported. + + +Licences +-------- + +NetSurf is provided under the GPL, as well as several other licences +for different components it uses. Visit NetSurf's about:licence URL +for details. + + +The !Boot and !System directories contain items provided produced +by third parties. Their licences are provided in the 3rd Party +directory. + +AcornURI + http://sudden.recoil.org/others/ + +Iconv + http://www.netsurf-browser.org/iconv/ + +SharedUnixLibrary + http://www.riscos.info/downloads/gccsdk/sharedunixlib/system.zip + +Tinct + http://www.tinct.net/tinct.asp diff --git a/frontends/riscos/download.c b/frontends/riscos/download.c new file mode 100644 index 000000000..cddb449de --- /dev/null +++ b/frontends/riscos/download.c @@ -0,0 +1,1629 @@ +/* + * Copyright 2004 James Bursa <bursa@users.sourceforge.net> + * Copyright 2003 Rob Jackson <jacko@xms.ms> + * Copyright 2005 Adrian Lees <adrianl@users.sourceforge.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * \file + * RISC OS download windows implementation. + * + * This file implements the interface given by desktop/gui_download.h + * for download windows. Each download window has an associated + * fetch. Downloads start by writing received data to a temporary + * file. At some point the user chooses a destination (by drag & + * drop), and the temporary file is then moved to the destination and + * the download continues until complete. + */ + +#include <assert.h> +#include <string.h> +#include <time.h> +#include <curl/curl.h> +#include <libwapcaplet/libwapcaplet.h> + +#include "oslib/mimemap.h" +#include "oslib/osargs.h" +#include "oslib/osfile.h" +#include "oslib/osfind.h" +#include "oslib/osfscontrol.h" +#include "oslib/osgbpb.h" +#include "oslib/wimp.h" +#include "oslib/wimpspriteop.h" + +#include "utils/sys_time.h" +#include "utils/nsoption.h" +#include "utils/log.h" +#include "utils/messages.h" +#include "utils/nsurl.h" +#include "utils/utf8.h" +#include "utils/utils.h" +#include "utils/string.h" +#include "utils/corestrings.h" +#include "desktop/gui_download.h" +#include "desktop/download.h" + +#include "riscos/gui.h" +#include "riscos/dialog.h" +#include "riscos/mouse.h" +#include "riscos/save.h" +#include "riscos/query.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" +#include "riscos/ucstables.h" +#include "riscos/filetype.h" + +#define ICON_DOWNLOAD_ICON 0 +#define ICON_DOWNLOAD_URL 1 +#define ICON_DOWNLOAD_PATH 2 +#define ICON_DOWNLOAD_DESTINATION 3 +#define ICON_DOWNLOAD_PROGRESS 5 +#define ICON_DOWNLOAD_STATUS 6 + +#define RO_DOWNLOAD_MAX_PATH_LEN 255 + +typedef enum +{ + QueryRsn_Quit, + QueryRsn_Abort, + QueryRsn_Overwrite +} query_reason; + + +/** Data for a download window. */ +struct gui_download_window { + /** Associated context, or 0 if the fetch has completed or aborted. */ + download_context *ctx; + unsigned int received; /**< Amount of data received so far. */ + unsigned int total_size; /**< Size of resource, or 0 if unknown. */ + + wimp_w window; /**< RISC OS window handle. */ + bits file_type; /**< RISC OS file type. */ + + char url[256]; /**< Buffer for URL icon. */ + char sprite_name[20]; /**< Buffer for sprite icon. */ + char path[RO_DOWNLOAD_MAX_PATH_LEN]; /**< Buffer for pathname icon. */ + char status[256]; /**< Buffer for status icon. */ + + /** User has chosen the destination, and it is being written. */ + bool saved; + bool close_confirmed; + bool error; /**< Error occurred, aborted. */ + + /** RISC OS file handle, of temporary file when !saved, and of + * destination when saved. */ + os_fw file; + + query_id query; + query_reason query_rsn; + + struct timeval start_time; /**< Time download started. */ + struct timeval last_time; /**< Time status was last updated. */ + unsigned int last_received; /**< Value of received at last_time. */ + float average_rate; /**< Moving average download rate. */ + unsigned int average_points; /**< Number of points in the average. */ + + bool send_dataload; /**< Should send DataLoad message when finished */ + wimp_message save_message; /**< Copy of wimp DataSaveAck message */ + + struct gui_download_window *prev; /**< Previous in linked list. */ + struct gui_download_window *next; /**< Next in linked list. */ +}; + + +/** List of all download windows. */ +static struct gui_download_window *download_window_list = 0; +/** Download window with current save operation. */ +static struct gui_download_window *download_window_current = 0; + +/** Template for a download window. */ +static wimp_window *download_template; + +/** Width of progress bar at 100%. */ +static int download_progress_width; +/** Coordinates of progress bar. */ +static int download_progress_x0; +static int download_progress_y0; +static int download_progress_y1; + +/** Current download directory. */ +static char *download_dir = NULL; +static size_t download_dir_len; + +static void ro_gui_download_drag_end(wimp_dragged *drag, void *data); +static const char *ro_gui_download_temp_name(struct gui_download_window *dw); +static void ro_gui_download_update_status(struct gui_download_window *dw); +static void ro_gui_download_update_status_wrapper(void *p); +static void ro_gui_download_window_hide_caret(struct gui_download_window *dw); +static char *ro_gui_download_canonicalise(const char *path); +static bool ro_gui_download_check_space(struct gui_download_window *dw, + const char *dest_file, const char *orig_file); +static os_error *ro_gui_download_move(struct gui_download_window *dw, + const char *dest_file, const char *src_file); +static void ro_gui_download_remember_dir(const char *path); +static bool ro_gui_download_save(struct gui_download_window *dw, + const char *file_name, bool force_overwrite); +static void ro_gui_download_send_dataload(struct gui_download_window *dw); +static void ro_gui_download_window_destroy_wrapper(void *p); +static bool ro_gui_download_window_destroy(struct gui_download_window *dw, bool quit); +static void ro_gui_download_close_confirmed(query_id, enum query_response res, void *p); +static void ro_gui_download_close_cancelled(query_id, enum query_response res, void *p); +static void ro_gui_download_overwrite_confirmed(query_id, enum query_response res, void *p); +static void ro_gui_download_overwrite_cancelled(query_id, enum query_response res, void *p); + +static bool ro_gui_download_click(wimp_pointer *pointer); +static bool ro_gui_download_keypress(wimp_key *key); +static void ro_gui_download_close(wimp_w w); + +static const query_callback close_funcs = +{ + ro_gui_download_close_confirmed, + ro_gui_download_close_cancelled +}; + +static const query_callback overwrite_funcs = +{ + ro_gui_download_overwrite_confirmed, + ro_gui_download_overwrite_cancelled +}; + + +/** + * Load the download window template. + */ + +void ro_gui_download_init(void) +{ + download_template = ro_gui_dialog_load_template("download"); + download_progress_width = + download_template->icons[ICON_DOWNLOAD_STATUS].extent.x1 - + download_template->icons[ICON_DOWNLOAD_STATUS].extent.x0; + download_progress_x0 = + download_template->icons[ICON_DOWNLOAD_PROGRESS].extent.x0; + download_progress_y0 = + download_template->icons[ICON_DOWNLOAD_PROGRESS].extent.y0; + download_progress_y1 = + download_template->icons[ICON_DOWNLOAD_PROGRESS].extent.y1; +} + + +/** + * Returns the pathname of a temporary file for this download. + * + * \param dw download window + * \return ptr to pathname + */ + +const char *ro_gui_download_temp_name(struct gui_download_window *dw) +{ + static char temp_name[40]; + snprintf(temp_name, sizeof temp_name, "<Wimp$ScrapDir>.ns%x", + (unsigned int) dw); + return temp_name; +} + +/** + * Try and find the correct RISC OS filetype from a download context. + */ +static nserror download_ro_filetype(download_context *ctx, bits *ftype_out) +{ + nsurl *url = download_context_get_url(ctx); + bits ftype = 0; + lwc_string *scheme; + + /* If the file is local try and read its filetype */ + scheme = nsurl_get_component(url, NSURL_SCHEME); + if (scheme != NULL) { + bool filescheme; + if (lwc_string_isequal(scheme, + corestring_lwc_file, + &filescheme) != lwc_error_ok) { + filescheme = false; + } + + if (filescheme) { + lwc_string *path = nsurl_get_component(url, NSURL_PATH); + if (path != NULL && lwc_string_length(path) != 0) { + char *raw_path; + raw_path = curl_unescape(lwc_string_data(path), + lwc_string_length(path)); + if (raw_path != NULL) { + ftype = ro_filetype_from_unix_path(raw_path); + curl_free(raw_path); + } + } + } + } + + /* If we still don't have a filetype (i.e. failed reading local + * one or fetching a remote object), then use the MIME type. + */ + if (ftype == 0) { + /* convert MIME type to RISC OS file type */ + os_error *error; + const char *mime_type; + + mime_type = download_context_get_mime_type(ctx); + error = xmimemaptranslate_mime_type_to_filetype(mime_type, &ftype); + if (error) { + LOG("xmimemaptranslate_mime_type_to_filetype: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MiscError", error->errmess); + ftype = 0xffd; + } + } + + *ftype_out = ftype; + return NSERROR_OK; +} + +/** + * Create and open a download progress window. + * + * \param ctx Download context + * \param gui The RISCOS gui window to download for. + * \return A new gui_download_window structure, or NULL on error and error + * reported + */ + +static struct gui_download_window * +gui_download_window_create(download_context *ctx, struct gui_window *gui) +{ + nsurl *url = download_context_get_url(ctx); + const char *temp_name; + char *filename = NULL; + struct gui_download_window *dw; + bool space_warning = false; + os_error *error; + char *local_path; + nserror err; + size_t i, last_dot; + + dw = malloc(sizeof *dw); + if (!dw) { + ro_warn_user("NoMemory", 0); + return 0; + } + + dw->ctx = ctx; + dw->saved = false; + dw->close_confirmed = false; + dw->error = false; + dw->query = QUERY_INVALID; + dw->received = 0; + dw->total_size = download_context_get_total_length(ctx); + + /** @todo change this to take a reference to the nsurl and use + * that value directly rather than using a fixed buffer. + */ + strncpy(dw->url, nsurl_access(url), sizeof dw->url); + dw->url[sizeof dw->url - 1] = 0; + + dw->status[0] = 0; + gettimeofday(&dw->start_time, 0); + dw->last_time = dw->start_time; + dw->last_received = 0; + dw->file_type = 0; + dw->average_rate = 0; + dw->average_points = 0; + + /* get filetype */ + err = download_ro_filetype(ctx, &dw->file_type); + if (err != NSERROR_OK) { + ro_warn_user(messages_get_errorcode(err), 0); + free(dw); + return 0; + } + + /* open temporary output file */ + temp_name = ro_gui_download_temp_name(dw); + if (!ro_gui_download_check_space(dw, temp_name, NULL)) { + /* issue a warning but continue with the download because the + user can save it to another medium whilst it's downloading */ + space_warning = true; + } + error = xosfind_openoutw(osfind_NO_PATH | osfind_ERROR_IF_DIR, + temp_name, 0, &dw->file); + if (error) { + LOG("xosfind_openoutw: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("SaveError", error->errmess); + free(dw); + return 0; + } + + /* fill in download window icons */ + download_template->icons[ICON_DOWNLOAD_URL].data.indirected_text.text = + dw->url; + download_template->icons[ICON_DOWNLOAD_URL].data.indirected_text.size = + sizeof dw->url; + + download_template->icons[ICON_DOWNLOAD_STATUS].data.indirected_text. + text = dw->status; + download_template->icons[ICON_DOWNLOAD_STATUS].data.indirected_text. + size = sizeof dw->status; + + sprintf(dw->sprite_name, "file_%.3x", dw->file_type); + if (!ro_gui_wimp_sprite_exists(dw->sprite_name)) + strcpy(dw->sprite_name, "file_xxx"); + download_template->icons[ICON_DOWNLOAD_ICON].data.indirected_sprite.id = + (osspriteop_id) dw->sprite_name; + + /* Get a suitable path- and leafname for the download. */ + temp_name = download_context_get_filename(dw->ctx); + + if (temp_name == NULL) + temp_name = messages_get("SaveObject"); + + if (temp_name != NULL) + filename = strdup(temp_name); + + if (filename == NULL) { + LOG("Failed to establish download filename."); + ro_warn_user("SaveError", error->errmess); + free(dw); + return 0; + } + + for (i = 0, last_dot = (size_t) -1; filename[i] != '\0'; i++) { + const char c = filename[i]; + + if (c == '.') { + last_dot = i; + filename[i] = '/'; + } else if (c <= ' ' || strchr(":*#$&@^%\\", c) != NULL) + filename[i] = '_'; + } + + if (nsoption_bool(strip_extensions) && last_dot != (size_t) -1) + filename[last_dot] = '\0'; + + if (download_dir != NULL && strlen(download_dir) > 0) + snprintf(dw->path, RO_DOWNLOAD_MAX_PATH_LEN, "%s.%s", + download_dir, filename); + else + snprintf(dw->path, RO_DOWNLOAD_MAX_PATH_LEN, "%s", + filename); + + free(filename); + + err = utf8_to_local_encoding(dw->path, 0, &local_path); + if (err != NSERROR_OK) { + /* badenc should never happen */ + assert(err !=NSERROR_BAD_ENCODING); + LOG("utf8_to_local_encoding failed"); + ro_warn_user("NoMemory", 0); + free(dw); + return 0; + } + else { + strncpy(dw->path, local_path, sizeof dw->path); + free(local_path); + } + + download_template->icons[ICON_DOWNLOAD_PATH].data.indirected_text.text = + dw->path; + download_template->icons[ICON_DOWNLOAD_PATH].data.indirected_text.size = + sizeof dw->path; + + download_template->icons[ICON_DOWNLOAD_DESTINATION].data. + indirected_text.text = dw->path; + download_template->icons[ICON_DOWNLOAD_DESTINATION].data. + indirected_text.size = sizeof dw->path; + + download_template->icons[ICON_DOWNLOAD_DESTINATION].flags |= + wimp_ICON_DELETED; + + /* create and open the download window */ + error = xwimp_create_window(download_template, &dw->window); + if (error) { + LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + free(dw); + return 0; + } + + dw->prev = 0; + dw->next = download_window_list; + if (download_window_list) + download_window_list->prev = dw; + download_window_list = dw; + + ro_gui_download_update_status(dw); + + ro_gui_dialog_open(dw->window); + + ro_gui_wimp_event_set_user_data(dw->window, dw); + ro_gui_wimp_event_register_mouse_click(dw->window, ro_gui_download_click); + ro_gui_wimp_event_register_keypress(dw->window, ro_gui_download_keypress); + ro_gui_wimp_event_register_close_window(dw->window, ro_gui_download_close); + + /* issue the warning now, so that it appears in front of the download + * window! */ + if (space_warning) + ro_warn_user("DownloadWarn", messages_get("NoDiscSpace")); + + return dw; +} + +/** + * Handle failed downloads. + * + * \param dw download window + * \param error_msg error message + */ + +static void gui_download_window_error(struct gui_download_window *dw, + const char *error_msg) +{ + os_error *error; + + if (dw->ctx != NULL) + download_context_destroy(dw->ctx); + dw->ctx = NULL; + dw->error = true; + + riscos_schedule(-1, ro_gui_download_update_status_wrapper, dw); + + /* place error message in status icon in red */ + strncpy(dw->status, error_msg, sizeof dw->status); + error = xwimp_set_icon_state(dw->window, + ICON_DOWNLOAD_STATUS, + wimp_COLOUR_RED << wimp_ICON_FG_COLOUR_SHIFT, + wimp_ICON_FG_COLOUR); + if (error) { + LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + + /* grey out pathname icon */ + error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_PATH, + wimp_ICON_SHADED, 0); + if (error) { + LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + + /* grey out file icon */ + error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_ICON, + wimp_ICON_SHADED, wimp_ICON_SHADED); + if (error) { + LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + + ro_gui_download_window_hide_caret(dw); +} + +/** + * Handle received download data. + * + * \param dw download window + * \param data pointer to block of data received + * \param size size of data + * \return NSERROR_OK on success, appropriate error otherwise + */ + +static nserror gui_download_window_data(struct gui_download_window *dw, + const char *data, unsigned int size) +{ + while (true) { + const char *msg; + int unwritten; + os_error *error; + + error = xosgbpb_writew(dw->file, (const byte *) data, size, + &unwritten); + if (error) { + LOG("xosgbpb_writew: 0x%x: %s", error->errnum, error->errmess); + msg = error->errmess; + + } else if (unwritten) { + LOG("xosgbpb_writew: unwritten %i", unwritten); + msg = messages_get("Unwritten"); + } + else { + dw->received += size; + return NSERROR_OK; + } + + ro_warn_user("SaveError", msg); + + if (dw->saved) { + /* try to continue with the temporary file */ + const char *temp_name = ro_gui_download_temp_name(dw); + + error = ro_gui_download_move(dw, temp_name, dw->path); + if (!error) { + + /* re-allow saving */ + dw->saved = false; + + error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_ICON, + wimp_ICON_SHADED, 0); + if (error) { + LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + + error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_DESTINATION, + wimp_ICON_DELETED, wimp_ICON_DELETED); + if (error) { + LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + error = xwimp_set_icon_state(dw->window, + ICON_DOWNLOAD_PATH, wimp_ICON_DELETED, 0); + if (error) { + LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + + continue; + } + } + + /* give up then */ + assert(dw->ctx); + download_context_abort(dw->ctx); + gui_download_window_error(dw, msg); + + return NSERROR_SAVE_FAILED; + } +} + + +/** + * Update the status text and progress bar. + * + * \param dw download window + */ + +void ro_gui_download_update_status(struct gui_download_window *dw) +{ + char *total_size; + char *speed; + char time[20] = "?"; + struct timeval t; + float dt; + unsigned int left; + float rate; + os_error *error; + int width; + char *local_status; + nserror err; + + gettimeofday(&t, 0); + dt = (t.tv_sec + 0.000001 * t.tv_usec) - (dw->last_time.tv_sec + + 0.000001 * dw->last_time.tv_usec); + if (dt == 0) + dt = 0.001; + + total_size = human_friendly_bytesize(max(dw->received, dw->total_size)); + + if (dw->ctx) { + char *received; + rate = (dw->received - dw->last_received) / dt; + received = human_friendly_bytesize(dw->received); + /* A simple 'modified moving average' download rate calculation + * to smooth out rate fluctuations: chosen for simplicity. + */ + dw->average_points++; + dw->average_rate = + ((dw->average_points - 1) * + dw->average_rate + rate) / + dw->average_points; + speed = human_friendly_bytesize(dw->average_rate); + if (dw->total_size) { + float f; + + if (dw->average_rate > 0) { + left = (dw->total_size - dw->received) / + dw->average_rate; + sprintf(time, "%u:%.2u", left / 60, left % 60); + } + + /* convert to local encoding */ + err = utf8_to_local_encoding( + messages_get("Download"), 0, &local_status); + if (err != NSERROR_OK) { + /* badenc should never happen */ + assert(err != NSERROR_BAD_ENCODING); + /* hide nomem error */ + snprintf(dw->status, sizeof dw->status, + messages_get("Download"), + received, total_size, speed, time); + } + else { + snprintf(dw->status, sizeof dw->status, + local_status, + received, total_size, speed, time); + free(local_status); + } + + f = (float) dw->received / (float) dw->total_size; + width = download_progress_width * f; + } else { + left = t.tv_sec - dw->start_time.tv_sec; + sprintf(time, "%u:%.2u", left / 60, left % 60); + + err = utf8_to_local_encoding( + messages_get("DownloadU"), 0, &local_status); + if (err != NSERROR_OK) { + /* badenc should never happen */ + assert(err != NSERROR_BAD_ENCODING); + /* hide nomem error */ + snprintf(dw->status, sizeof dw->status, + messages_get("DownloadU"), + received, speed, time); + } + else { + snprintf(dw->status, sizeof dw->status, + local_status, + received, speed, time); + free(local_status); + } + + /* length unknown, stay at 0 til finished */ + width = 0; + } + } else { + left = dw->last_time.tv_sec - dw->start_time.tv_sec; + if (left == 0) + left = 1; + rate = (float) dw->received / (float) left; + sprintf(time, "%u:%.2u", left / 60, left % 60); + speed = human_friendly_bytesize(rate); + + err = utf8_to_local_encoding(messages_get("Downloaded"), 0, + &local_status); + if (err != NSERROR_OK) { + /* badenc should never happen */ + assert(err != NSERROR_BAD_ENCODING); + /* hide nomem error */ + snprintf(dw->status, sizeof dw->status, + messages_get("Downloaded"), + total_size, speed, time); + } + else { + snprintf(dw->status, sizeof dw->status, local_status, + total_size, speed, time); + free(local_status); + } + + /* all done */ + width = download_progress_width; + } + + dw->last_time = t; + dw->last_received = dw->received; + + error = xwimp_resize_icon(dw->window, ICON_DOWNLOAD_PROGRESS, + download_progress_x0, + download_progress_y0, + download_progress_x0 + width, + download_progress_y1); + if (error) { + LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + + error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_STATUS, 0, 0); + if (error) { + LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + + if (dw->ctx) { + riscos_schedule(1000, ro_gui_download_update_status_wrapper, dw); + } else { + riscos_schedule(-1, ro_gui_download_update_status_wrapper, dw); + } +} + + +/** + * Wrapper for ro_gui_download_update_status(), suitable for riscos_schedule(). + */ + +void ro_gui_download_update_status_wrapper(void *p) +{ + ro_gui_download_update_status((struct gui_download_window *) p); +} + + + +/** + * Hide the caret but preserve input focus. + * + * \param dw download window + */ + +void ro_gui_download_window_hide_caret(struct gui_download_window *dw) +{ + wimp_caret caret; + os_error *error; + + error = xwimp_get_caret_position(&caret); + if (error) { + LOG("xwimp_get_caret_position: 0x%x : %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + else if (caret.w == dw->window) { + error = xwimp_set_caret_position(dw->window, (wimp_i)-1, 0, 0, 1 << 25, -1); + if (error) { + LOG("xwimp_get_caret_position: 0x%x : %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + } +} + + + + +/** + * Handle completed downloads. + * + * \param dw download window + */ + +static void gui_download_window_done(struct gui_download_window *dw) +{ + os_error *error; + + if (dw->ctx != NULL) + download_context_destroy(dw->ctx); + dw->ctx = NULL; + ro_gui_download_update_status(dw); + + error = xosfind_closew(dw->file); + if (error) { + LOG("xosfind_closew: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("SaveError", error->errmess); + } + dw->file = 0; + + if (dw->saved) { + error = xosfile_set_type(dw->path, + dw->file_type); + if (error) { + LOG("xosfile_set_type: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("SaveError", error->errmess); + } + + if (dw->send_dataload) { + ro_gui_download_send_dataload(dw); + } + + riscos_schedule(2000, ro_gui_download_window_destroy_wrapper, dw); + } +} + + +/** + * Handle Mouse_Click events in a download window. + * + * \param pointer block returned by Wimp_Poll + */ + +bool ro_gui_download_click(wimp_pointer *pointer) +{ + struct gui_download_window *dw; + + dw = (struct gui_download_window *)ro_gui_wimp_event_get_user_data(pointer->w); + if ((pointer->buttons & (wimp_DRAG_SELECT | wimp_DRAG_ADJUST)) && + pointer->i == ICON_DOWNLOAD_ICON && + !dw->error && !dw->saved) { + const char *sprite = ro_gui_get_icon_string(pointer->w, pointer->i); + int x = pointer->pos.x, y = pointer->pos.y; + wimp_window_state wstate; + wimp_icon_state istate; + /* start the drag from the icon's exact location, rather than the pointer */ + istate.w = wstate.w = pointer->w; + istate.i = pointer->i; + if (!xwimp_get_window_state(&wstate) && !xwimp_get_icon_state(&istate)) { + x = (istate.icon.extent.x1 + istate.icon.extent.x0)/2 + + wstate.visible.x0 - wstate.xscroll; + y = (istate.icon.extent.y1 + istate.icon.extent.y0)/2 + + wstate.visible.y1 - wstate.yscroll; + } + ro_mouse_drag_start(ro_gui_download_drag_end, NULL, NULL, NULL); + download_window_current = dw; + ro_gui_drag_icon(x, y, sprite); + + } else if (pointer->i == ICON_DOWNLOAD_DESTINATION) { + char command[256] = "Filer_OpenDir "; + char *dot; + + strncpy(command + 14, dw->path, 242); + command[255] = 0; + dot = strrchr(command, '.'); + if (dot) { + os_error *error; + *dot = 0; + error = xos_cli(command); + if (error) { + LOG("xos_cli: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MiscError", error->errmess); + } + } + } + return true; +} + + +/** + * Handler Key_Press events in a download window. + * + * \param key key press returned by Wimp_Poll + * \return true iff key press handled + */ + +bool ro_gui_download_keypress(wimp_key *key) +{ + struct gui_download_window *dw; + + dw = (struct gui_download_window *)ro_gui_wimp_event_get_user_data(key->w); + switch (key->c) + { + case wimp_KEY_ESCAPE: + ro_gui_download_window_destroy(dw, false); + return true; + + case wimp_KEY_RETURN: { + const char *name = ro_gui_get_icon_string(dw->window, + ICON_DOWNLOAD_PATH); + if (!strrchr(name, '.')) { + ro_warn_user("NoPathError", NULL); + return true; + } + ro_gui_convert_save_path(dw->path, sizeof dw->path, name); + + dw->send_dataload = false; + if (ro_gui_download_save(dw, dw->path, + !nsoption_bool(confirm_overwrite)) && !dw->ctx) + { + /* finished already */ + riscos_schedule(2000, ro_gui_download_window_destroy_wrapper, dw); + } + return true; + } + break; + } + + /* ignore all other keypresses (F12 etc) */ + return false; +} + + +/** + * Handle User_Drag_Box event for a drag from a download window. + * + * \param *drag block returned by Wimp_Poll + * \param *data NULL data to allow use as callback from ro_mouse. + */ + +static void ro_gui_download_drag_end(wimp_dragged *drag, void *data) +{ + wimp_pointer pointer; + wimp_message message; + struct gui_download_window *dw = download_window_current; + const char *leaf; + os_error *error; + + if (dw->saved || dw->error) + return; + + error = xwimp_get_pointer_info(&pointer); + if (error) { + LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + /* ignore drags to the download window itself */ + if (pointer.w == dw->window) return; + + leaf = strrchr(dw->path, '.'); + if (leaf) + leaf++; + else + leaf = dw->path; + ro_gui_convert_save_path(message.data.data_xfer.file_name, 212, leaf); + + message.your_ref = 0; + message.action = message_DATA_SAVE; + message.data.data_xfer.w = pointer.w; + message.data.data_xfer.i = pointer.i; + message.data.data_xfer.pos.x = pointer.pos.x; + message.data.data_xfer.pos.y = pointer.pos.y; + message.data.data_xfer.est_size = dw->total_size ? dw->total_size : + dw->received; + message.data.data_xfer.file_type = dw->file_type; + message.size = 44 + ((strlen(message.data.data_xfer.file_name) + 4) & + (~3u)); + + error = xwimp_send_message_to_window(wimp_USER_MESSAGE, &message, + pointer.w, pointer.i, 0); + if (error) { + LOG("xwimp_send_message_to_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + + gui_current_drag_type = GUI_DRAG_DOWNLOAD_SAVE; +} + + +/** + * Handle Message_DataSaveAck for a drag from a download window. + * + * \param message block returned by Wimp_Poll + */ + +void ro_gui_download_datasave_ack(wimp_message *message) +{ + struct gui_download_window *dw = download_window_current; + + dw->send_dataload = true; + memcpy(&dw->save_message, message, sizeof(wimp_message)); + + if (!ro_gui_download_save(dw, message->data.data_xfer.file_name, + !nsoption_bool(confirm_overwrite))) + return; + + if (!dw->ctx) { + /* Ack successful completed save with message_DATA_LOAD immediately + to reduce the chance of the target app getting confused by it + being delayed */ + + ro_gui_download_send_dataload(dw); + + riscos_schedule(2000, ro_gui_download_window_destroy_wrapper, dw); + } +} + + +/** + * Return a pathname in canonical form + * + * \param path pathnamee to be canonicalised + * \return ptr to pathname in malloc block, or NULL + */ + +char *ro_gui_download_canonicalise(const char *path) +{ + os_error *error; + int spare = 0; + char *buf; + + error = xosfscontrol_canonicalise_path(path, NULL, NULL, NULL, 0, &spare); + if (error) { + LOG("xosfscontrol_canonicalise_path: 0x%x: %s", error->errnum, error->errmess); + return NULL; + } + + buf = malloc(1 - spare); + if (buf) { + error = xosfscontrol_canonicalise_path(path, buf, NULL, NULL, + 1 - spare, NULL); + if (error) { + LOG("xosfscontrol_canonicalise_path: 0x%x: %s", error->errnum, error->errmess); + + free(buf); + return NULL; + } + } + + return buf; +} + + +/** + * Check the available space on the medium containing the destination file, + * taking into account any space currently occupied by the file at its + * original location. + * + * \param dw download window + * \param dest_file destination pathname + * \param orig_file current pathname, NULL if no existing file + * \return true iff there's enough space + */ + +bool ro_gui_download_check_space(struct gui_download_window *dw, + const char *dest_file, const char *orig_file) +{ + /* is there enough free space for this file? */ + int dest_len = strlen(dest_file); + os_error *error; + int max_file; + bits free_lo; + int free_hi; + char *dir; + + dir = malloc(dest_len + 1); + if (!dir) return true; + + while (dest_len > 0 && dest_file[--dest_len] != '.'); + + memcpy(dir, dest_file, dest_len); + dir[dest_len] = '\0'; + + /* try the 64-bit variant first (RO 3.6+) */ + error = xosfscontrol_free_space64(dir, &free_lo, &free_hi, + &max_file, NULL, NULL); + if (error) { + LOG("xosfscontrol_free_space64: 0x%x: %s", error->errnum, error->errmess); + + free_hi = 0; + error = xosfscontrol_free_space(dir, (int*)&free_lo, + &max_file, NULL); + if (error) { + LOG("xosfscontrol_free_space: 0x%x: %s", error->errnum, error->errmess); + /* close our eyes and hope */ + free(dir); + return true; + } + } + + free(dir); + + if ((bits)max_file < dw->total_size || (!free_hi && free_lo < dw->total_size)) { + char *dest_canon, *orig_canon; + bits space; + + if (!orig_file || !dw->file) { + /* no original file to take into account */ + return false; + } + + space = min((bits)max_file, free_lo); + + dest_canon = ro_gui_download_canonicalise(dest_file); + if (!dest_canon) dest_canon = (char*)dest_file; + + orig_canon = ro_gui_download_canonicalise(orig_file); + if (!orig_canon) orig_canon = (char*)orig_file; + + /* not enough space; allow for the file's original location + when space is tight by comparing the first part of the two + pathnames (and assuming the FS isn't brain damaged!) */ + + char *dot = strchr(orig_canon, '.'); + if (dot && !strncasecmp(dest_canon, orig_canon, (dot + 1) - orig_canon)) { + int allocation; + + error = xosargs_read_allocation(dw->file, + &allocation); + if (error) { + LOG("xosargs_read_allocation: 0x%x : %s", error->errnum, error->errmess); + } + else { + space += allocation; + } + } + + if (dest_canon != dest_file) free(dest_canon); + if (orig_canon != orig_file) free(orig_canon); + + if (space >= dw->total_size) { + /* OK, renaming should work */ + return true; + } + + return false; + } + return true; +} + +/** + * Move the downloading file to a new location and continue downloading there. + * + * \param dw download window + * \param dest_file new location + * \param src_file old location + * \return error iff failed to move file + */ + +os_error *ro_gui_download_move(struct gui_download_window *dw, + const char *dest_file, const char *src_file) +{ + os_error *error; + + /* close temporary file */ + if (dw->file) { + error = xosfind_closew(dw->file); + dw->file = 0; + if (error) { + LOG("xosfind_closew: 0x%x: %s", error->errnum, error->errmess); + return error; + } + } + + /* move or copy temporary file to destination file */ + error = xosfscontrol_rename(src_file, dest_file); + /* Errors from a filing system have number 0x1XXnn, where XX is the FS + * number, and nn the error number. 0x9F is "Not same disc". */ + if (error && (error->errnum == error_BAD_RENAME || + (error->errnum & 0xFF00FFu) == 0x1009Fu)) { + /* rename failed: copy with delete */ + error = xosfscontrol_copy(src_file, dest_file, + osfscontrol_COPY_FORCE | + osfscontrol_COPY_DELETE | + osfscontrol_COPY_LOOK, + 0, 0, 0, 0, 0); + if (error) { + LOG("xosfscontrol_copy: 0x%x: %s", error->errnum, error->errmess); + return error; + } + } else if (error) { + LOG("xosfscontrol_rename: 0x%x: %s", error->errnum, error->errmess); + return error; + } + + if (dw->ctx) { + /* open new destination file if still fetching */ + error = xosfile_write(dest_file, 0xdeaddead, 0xdeaddead, + fileswitch_ATTR_OWNER_READ | + fileswitch_ATTR_OWNER_WRITE); + if (error) { + LOG("xosfile_write: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("SaveError", error->errmess); + } + + error = xosfind_openupw(osfind_NO_PATH | osfind_ERROR_IF_DIR, + dest_file, 0, &dw->file); + if (error) { + LOG("xosfind_openupw: 0x%x: %s", error->errnum, error->errmess); + return error; + } + + error = xosargs_set_ptrw(dw->file, dw->received); + if (error) { + LOG("xosargs_set_ptrw: 0x%x: %s", error->errnum, error->errmess); + return error; + } + + } else { + /* otherwise just set the file type */ + error = xosfile_set_type(dest_file, + dw->file_type); + if (error) { + LOG("xosfile_set_type: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("SaveError", error->errmess); + } + } + + /* success */ + return NULL; +} + + +/** + * Remember the directory containing the given file, + * for use in further downloads. + * + * \param path pathname of downloaded file + * \return none + */ + +void ro_gui_download_remember_dir(const char *path) +{ + const char *lastdot = NULL; + const char *p = path; + + while (*p >= 0x20) { + if (*p == '.') { + /* don't remember the directory if it's a temporary file */ + if (!lastdot && p == path + 12 && + !memcmp(path, "<Wimp$Scrap>", 12)) break; + lastdot = p; + } + p++; + } + + if (lastdot) { + /* remember the directory */ + char *new_dir = realloc(download_dir, (lastdot+1)-path); + if (new_dir) { + download_dir_len = lastdot - path; + memcpy(new_dir, path, download_dir_len); + new_dir[download_dir_len] = '\0'; + download_dir = new_dir; + } + } +} + +/** + * Start of save operation, user has specified where the file should be saved. + * + * \param dw download window + * \param file_name pathname of destination file + & \param force_overwrite true iff required to overwrite without prompting + * \return true iff save successfully initiated + */ + +bool ro_gui_download_save(struct gui_download_window *dw, + const char *file_name, bool force_overwrite) +{ + fileswitch_object_type obj_type; + const char *temp_name; + os_error *error; + + if (dw->saved || dw->error) + return true; + + temp_name = ro_gui_download_temp_name(dw); + + /* does the user want to check for collisions when saving? */ + if (!force_overwrite) { + /* check whether the destination file/dir already exists */ + error = xosfile_read_stamped(file_name, &obj_type, + NULL, NULL, NULL, NULL, NULL); + if (error) { + LOG("xosfile_read_stamped: 0x%x:%s", error->errnum, error->errmess); + return false; + } + + switch (obj_type) { + case osfile_NOT_FOUND: + break; + + case osfile_IS_FILE: + dw->query = query_user("OverwriteFile", NULL, &overwrite_funcs, dw, + messages_get("Replace"), messages_get("DontReplace")); + dw->query_rsn = QueryRsn_Overwrite; + return false; + + default: + error = xosfile_make_error(file_name, obj_type); + assert(error); + ro_warn_user("SaveError", error->errmess); + return false; + } + } + + if (!ro_gui_download_check_space(dw, file_name, temp_name)) { + ro_warn_user("SaveError", messages_get("NoDiscSpace")); + return false; + } + + error = ro_gui_download_move(dw, file_name, temp_name); + if (error) { + ro_warn_user("SaveError", error->errmess); + + /* try to reopen at old location so that the download can continue + to the temporary file */ + error = xosfind_openupw(osfind_NO_PATH | osfind_ERROR_IF_DIR, + temp_name, 0, &dw->file); + if (error) { + LOG("xosfind_openupw: 0x%x: %s", error->errnum, error->errmess); + + } else { + error = xosargs_set_ptrw(dw->file, dw->received); + if (error) { + LOG("xosargs_set_ptrw: 0x%x: %s", error->errnum, error->errmess); + } + } + + if (error) { + if (dw->ctx) + download_context_abort(dw->ctx); + gui_download_window_error(dw, error->errmess); + } + return false; + } + + dw->saved = true; + strncpy(dw->path, file_name, sizeof dw->path); + + if (!dw->send_dataload || dw->save_message.data.data_xfer.est_size != -1) + ro_gui_download_remember_dir(file_name); + + /* grey out file icon */ + error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_ICON, + wimp_ICON_SHADED, wimp_ICON_SHADED); + if (error) { + LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + + /* hide writeable path icon and show destination icon + Note: must redraw icon bounding box because the destination icon + has rounded edges on RISC OS Select/Adjust and doesn't + completely cover the writeable icon */ + + ro_gui_force_redraw_icon(dw->window, ICON_DOWNLOAD_PATH); + error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_PATH, + wimp_ICON_DELETED, wimp_ICON_DELETED); + if (error) { + LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + error = xwimp_set_icon_state(dw->window, + ICON_DOWNLOAD_DESTINATION, wimp_ICON_DELETED, 0); + if (error) { + LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + + ro_gui_download_window_hide_caret(dw); + + return true; +} + + +/** + * Send DataLoad message in response to DataSaveAck, informing the + * target application that the transfer is complete. + * + * \param dw download window + */ + +void ro_gui_download_send_dataload(struct gui_download_window *dw) +{ + /* Ack successful save with message_DATA_LOAD */ + wimp_message *message = &dw->save_message; + os_error *error; + + assert(dw->send_dataload); + dw->send_dataload = false; + + message->action = message_DATA_LOAD; + message->your_ref = message->my_ref; + error = xwimp_send_message_to_window(wimp_USER_MESSAGE, message, + message->data.data_xfer.w, + message->data.data_xfer.i, 0); + /* The window we just attempted to send a message to may + * have been closed before the message was sent. As we've + * no clean way of detecting this, we'll just detect the + * error return from the message send attempt and judiciously + * ignore it. + * + * Ideally, we would have registered to receive Message_WindowClosed + * and then cleared dw->send_dataload flag for the appropriate + * window. Unfortunately, however, a long-standing bug in the + * Pinboard module prevents this from being a viable solution. + * + * See http://groups.google.co.uk/group/comp.sys.acorn.tech/msg/e3fbf70d8393e6cf?dmode=source&hl=en + * for the rather depressing details. + */ + if (error && error->errnum != error_WIMP_BAD_HANDLE) { + LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + + riscos_schedule(2000, ro_gui_download_window_destroy_wrapper, dw); +} + + +/** + * Handle closing of download window + */ +void ro_gui_download_close(wimp_w w) +{ + struct gui_download_window *dw; + + dw = (struct gui_download_window *)ro_gui_wimp_event_get_user_data(w); + ro_gui_download_window_destroy(dw, false); +} + + +/** + * Close a download window and free any related resources. + * + * \param dw download window + * \param quit destroying because we're quitting the whole app + * \return true if window destroyed, not waiting for user confirmation + */ + +bool ro_gui_download_window_destroy(struct gui_download_window *dw, bool quit) +{ + bool safe = dw->saved && !dw->ctx; + os_error *error; + + if (!safe && !dw->close_confirmed) + { + query_reason rsn = quit ? QueryRsn_Quit : QueryRsn_Abort; + + if (dw->query != QUERY_INVALID) { + + /* can we just reuse the existing query? */ + if (rsn == dw->query_rsn) { + ro_gui_query_window_bring_to_front(dw->query); + return false; + } + + query_close(dw->query); + dw->query = QUERY_INVALID; + } + + if (quit) { + /* bring all download windows to the front of the desktop as + a convenience if there are lots of windows open */ + + struct gui_download_window *d = download_window_list; + while (d) { + ro_gui_dialog_open_top(d->window, NULL, 0, 0); + d = d->next; + } + } + + dw->query_rsn = rsn; + dw->query = query_user(quit ? "QuitDownload" : "AbortDownload", + NULL, &close_funcs, dw, NULL, NULL); + + return false; + } + + riscos_schedule(-1, ro_gui_download_update_status_wrapper, dw); + riscos_schedule(-1, ro_gui_download_window_destroy_wrapper, dw); + + /* remove from list */ + if (dw->prev) + dw->prev->next = dw->next; + else + download_window_list = dw->next; + if (dw->next) + dw->next->prev = dw->prev; + + /* delete window */ + error = xwimp_delete_window(dw->window); + if (error) { + LOG("xwimp_delete_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + ro_gui_wimp_event_finalise(dw->window); + + /* close download file */ + if (dw->file) { + error = xosfind_closew(dw->file); + if (error) { + LOG("xosfind_closew: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("SaveError", error->errmess); + } + } + + /* delete temporary file */ + if (!dw->saved) { + const char *temp_name = ro_gui_download_temp_name(dw); + + error = xosfile_delete(temp_name, 0, 0, 0, 0, 0); + if (error) { + LOG("xosfile_delete: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("SaveError", error->errmess); + } + } + + if (dw->ctx) { + download_context_abort(dw->ctx); + download_context_destroy(dw->ctx); + } + + free(dw); + + return true; +} + + +/** + * Wrapper for ro_gui_download_window_destroy(), suitable for riscos_schedule(). + */ + +void ro_gui_download_window_destroy_wrapper(void *p) +{ + struct gui_download_window *dw = p; + if (dw->query != QUERY_INVALID) + query_close(dw->query); + dw->query = QUERY_INVALID; + dw->close_confirmed = true; + ro_gui_download_window_destroy(dw, false); +} + + +/** + * User has opted to cancel the close, leaving the download to continue. + */ + +void ro_gui_download_close_cancelled(query_id id, enum query_response res, void *p) +{ + struct gui_download_window *dw = p; + dw->query = QUERY_INVALID; +} + + +/** + * Download aborted, close window and tidy up. + */ + +void ro_gui_download_close_confirmed(query_id id, enum query_response res, void *p) +{ + struct gui_download_window *dw = p; + dw->query = QUERY_INVALID; + dw->close_confirmed = true; + if (dw->query_rsn == QueryRsn_Quit) { + + /* destroy all our downloads */ + while (download_window_list) + ro_gui_download_window_destroy_wrapper(download_window_list); + + /* and restart the shutdown */ + if (ro_gui_prequit()) + riscos_done = true; + } + else + ro_gui_download_window_destroy(dw, false); +} + + +/** + * User has opted not to overwrite the existing file. + */ + +void ro_gui_download_overwrite_cancelled(query_id id, enum query_response res, void *p) +{ + struct gui_download_window *dw = p; + dw->query = QUERY_INVALID; +} + + +/** + * Overwrite of existing file confirmed, proceed with the save. + */ + +void ro_gui_download_overwrite_confirmed(query_id id, enum query_response res, void *p) +{ + struct gui_download_window *dw = p; + dw->query = QUERY_INVALID; + + if (!ro_gui_download_save(dw, dw->save_message.data.data_xfer.file_name, true)) + return; + + if (!dw->ctx) { + /* Ack successful completed save with message_DATA_LOAD immediately + to reduce the chance of the target app getting confused by it + being delayed */ + + ro_gui_download_send_dataload(dw); + + riscos_schedule(2000, ro_gui_download_window_destroy_wrapper, dw); + } +} + + +/** + * Respond to PreQuit message, displaying a prompt message if we need + * the user to confirm the shutdown. + * + * \return true if we can shutdown straightaway + */ + +bool ro_gui_download_prequit(void) +{ + while (download_window_list) + { + if (!ro_gui_download_window_destroy(download_window_list, true)) + return false; /* awaiting user confirmation */ + } + return true; +} + +static struct gui_download_table download_table = { + .create = gui_download_window_create, + .data = gui_download_window_data, + .error = gui_download_window_error, + .done = gui_download_window_done, +}; + +struct gui_download_table *riscos_download_table = &download_table; diff --git a/frontends/riscos/filetype.c b/frontends/riscos/filetype.c new file mode 100644 index 000000000..99a44ae30 --- /dev/null +++ b/frontends/riscos/filetype.c @@ -0,0 +1,352 @@ +/* + * Copyright 2004 James Bursa <bursa@users.sourceforge.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <string.h> +#include <unixlib/local.h> +#include "oslib/mimemap.h" +#include "oslib/osfile.h" + +#include "utils/config.h" +#include "utils/log.h" +#include "content/content.h" +#include "content/fetch.h" +#include "content/hlcache.h" + +#include "riscos/filetype.h" +#include "riscos/gui.h" + +/* type_map must be in sorted order by file_type */ +struct type_entry { + bits file_type; + char mime_type[40]; +}; +static const struct type_entry type_map[] = { + {0x132, "image/ico"}, + {0x188, "application/x-shockwave-flash"}, + {0x695, "image/gif"}, + {0x69c, "image/x-ms-bmp"}, + {0xaad, "image/svg+xml"}, + {0xaff, "image/x-drawfile"}, + {0xb60, "image/png"}, + {0xc85, "image/jpeg"}, + {0xd94, "image/x-artworks"}, + {0xf78, "image/jng"}, + {0xf79, "text/css"}, + {0xf81, "application/javascript"}, + {0xf83, "image/mng"}, + {0xfaf, "text/html"}, + {0xff9, "image/x-riscos-sprite"}, + {0xfff, "text/plain"}, +}; +#define TYPE_MAP_COUNT (sizeof(type_map) / sizeof(type_map[0])) + +#define BUF_SIZE (256) +static char type_buf[BUF_SIZE]; + + +static int cmp_type(const void *x, const void *y); + +/* exported interface documented in riscos/filetype.h */ +const char *fetch_filetype(const char *unix_path) +{ + struct type_entry *t; + unsigned int len = strlen(unix_path) + 100; + char *path = calloc(len, 1); + char *r; + os_error *error; + bits file_type, temp; + int objtype; + + if (!path) { + LOG("Insufficient memory for calloc"); + ro_warn_user("NoMemory", 0); + return "application/riscos"; + } + + /* convert path to RISC OS format and read file type */ + r = __riscosify(unix_path, 0, __RISCOSIFY_NO_SUFFIX, path, len, 0); + if (r == 0) { + LOG("__riscosify failed"); + free(path); + return "application/riscos"; + } + + error = xosfile_read_stamped_no_path(path, &objtype, 0, 0, 0, 0, + &file_type); + if (error) { + LOG("xosfile_read_stamped_no_path failed: %s", error->errmess); + free(path); + return "application/riscos"; + } + + if (objtype == osfile_IS_DIR) { + sprintf(type_buf, "application/x-netsurf-directory"); + free(path); + return (const char *)type_buf; + } + + /* If filetype is text or data, and the file has an extension, try to + * map the extension to a filetype via the MimeMap file. */ + if (file_type == osfile_TYPE_TEXT || file_type == osfile_TYPE_DATA) { + char *slash = strrchr(path, '/'); + if (slash) { + error = xmimemaptranslate_extension_to_filetype( + slash+1, &temp); + if (error) + /* ignore error and leave file_type alone */ + LOG("xmimemaptranslate_extension_to_filetype: ""0x%x %s", error->errnum, error->errmess); + else + file_type = temp; + } + } + + /* search for MIME type in our internal table */ + t = bsearch(&file_type, type_map, TYPE_MAP_COUNT, + sizeof(type_map[0]), cmp_type); + if (t) { + /* found, so return it */ + free(path); + return t->mime_type; + } + + /* not in internal table, so ask MimeMap */ + error = xmimemaptranslate_filetype_to_mime_type(file_type, type_buf); + if (error) { + LOG("0x%x %s", error->errnum, error->errmess); + free(path); + return "application/riscos"; + } + /* make sure we're NULL terminated. If we're not, the MimeMap + * module's probably written past the end of the buffer from + * SVC mode. Short of rewriting MimeMap with an incompatible API, + * there's nothing we can do about it. + */ + type_buf[BUF_SIZE - 1] = '\0'; + + free(path); + + LOG("mime type '%s'", type_buf); + return (const char *)type_buf; + +} + +/* exported interface documented in riscos/filetype.h */ +char *fetch_mimetype(const char *ro_path) +{ + os_error *e; + bits filetype = 0, load; + int objtype; + char *mime = calloc(BUF_SIZE, sizeof(char)); + char *slash; + struct type_entry *t; + + if (!mime) { + LOG("Insufficient memory for calloc"); + ro_warn_user("NoMemory", 0); + return 0; + } + + e = xosfile_read_no_path(ro_path, &objtype, &load, 0, 0, 0); + if (e) { + LOG("xosfile_read_no_path: 0x%x: %s", e->errnum, e->errmess); + free(mime); + return 0; + } + + if (objtype == osfile_IS_DIR) { + free(mime); + return 0; /* directories are pointless */ + } + + if ((load >> 20) & 0xFFF) { + filetype = (load>>8) & 0x000FFF; + } + else { + free(mime); + return 0; /* no idea */ + } + + /* If filetype is text and the file has an extension, try to map the + * extension to a filetype via the MimeMap file. */ + slash = strrchr(ro_path, '/'); + if (slash && filetype == osfile_TYPE_TEXT) { + e = xmimemaptranslate_extension_to_filetype(slash+1, &load); + if (e) + /* if we get an error here, simply ignore it and + * leave filetype unchanged */ + LOG("0x%x %s", e->errnum, e->errmess); + else + filetype = load; + } + + /* search for MIME type in our internal table */ + t = bsearch(&filetype, type_map, TYPE_MAP_COUNT, + sizeof(type_map[0]), cmp_type); + if (t) { + /* found, so return it */ + strncpy(mime, t->mime_type, BUF_SIZE); + return mime; + } + + /* not in internal table, so ask MimeMap */ + e = xmimemaptranslate_filetype_to_mime_type(filetype, mime); + if (e) { + LOG("xmimemaptranslate_filetype_to_mime_type: 0x%x: %s", e->errnum, e->errmess); + free(mime); + return 0; + } + /* make sure we're NULL terminated. If we're not, the MimeMap + * module's probably written past the end of the buffer from + * SVC mode. Short of rewriting MimeMap with an incompatible API, + * there's nothing we can do about it. + */ + mime[BUF_SIZE - 1] = '\0'; + + return mime; +} + +/** + * Comparison function for bsearch + */ +int cmp_type(const void *x, const void *y) +{ + const bits *p = x; + const struct type_entry *q = y; + return *p < q->file_type ? -1 : (*p == q->file_type ? 0 : +1); +} + +/* exported interface documented in riscos/filetype.h */ +int ro_content_filetype(hlcache_handle *c) +{ + lwc_string *mime_type; + int file_type; + + file_type = ro_content_filetype_from_type(content_get_type(c)); + if (file_type != 0) + return file_type; + + mime_type = content_get_mime_type(c); + + file_type = ro_content_filetype_from_mime_type(mime_type); + + lwc_string_unref(mime_type); + + return file_type; +} + + +/* exported interface documented in riscos/filetype.h */ +int ro_content_native_type(hlcache_handle *c) +{ + switch (ro_content_filetype(c)) { + case FILETYPE_JPEG: /* jpeg */ + case FILETYPE_JNG: /* jng */ + case FILETYPE_MNG: /* mng */ + case FILETYPE_GIF: /* gif */ + case FILETYPE_BMP: /* bmp */ + case FILETYPE_ICO: /* ico */ + case FILETYPE_PNG: /* png */ + case 0xff9: /* sprite */ + return osfile_TYPE_SPRITE; + case FILETYPE_SVG: /* svg */ + case 0xaff: /* draw */ + return osfile_TYPE_DRAW; + default: + break; + } + + return osfile_TYPE_DATA; +} + + +/* exported interface documented in riscos/filetype.h */ +int ro_content_filetype_from_mime_type(lwc_string *mime_type) +{ + int file_type, index; + os_error *error; + + /* Search internal type map */ + for (index = TYPE_MAP_COUNT; index > 0; index--) { + const struct type_entry *e = &type_map[index - 1]; + + if (strlen(e->mime_type) == lwc_string_length(mime_type) && + strncasecmp(e->mime_type, + lwc_string_data(mime_type), + lwc_string_length(mime_type)) == 0) + return e->file_type; + } + + /* Ask MimeMap module */ + error = xmimemaptranslate_mime_type_to_filetype( + lwc_string_data(mime_type), (bits *) &file_type); + if (error) + file_type = 0xffd; + + return file_type; +} + + +/* exported interface documented in riscos/filetype.h */ +int ro_content_filetype_from_type(content_type type) { + switch (type) { + case CONTENT_HTML: return FILETYPE_HTML; + case CONTENT_TEXTPLAIN: return 0xfff; + case CONTENT_CSS: return 0xf79; + default: break; + } + return 0; +} + + +/* exported interface documented in riscos/filetype.h */ +bits ro_filetype_from_unix_path(const char *unix_path) +{ + unsigned int len = strlen(unix_path) + 100; + char *path = calloc(len, 1); + char *r; + os_error *error; + bits file_type; + + if (!path) { + LOG("Insufficient memory for calloc"); + ro_warn_user("NoMemory", 0); + return osfile_TYPE_DATA; + } + + /* convert path to RISC OS format and read file type */ + r = __riscosify(unix_path, 0, __RISCOSIFY_NO_SUFFIX, path, len, 0); + if (r == 0) { + LOG("__riscosify failed"); + free(path); + return osfile_TYPE_DATA; + } + + error = xosfile_read_stamped_no_path(path, 0, 0, 0, 0, 0, + &file_type); + if (error) { + LOG("xosfile_read_stamped_no_path failed: %s", error->errmess); + free(path); + return osfile_TYPE_DATA; + } + + free(path); + + return file_type; +} + diff --git a/frontends/riscos/filetype.h b/frontends/riscos/filetype.h new file mode 100644 index 000000000..3ba613033 --- /dev/null +++ b/frontends/riscos/filetype.h @@ -0,0 +1,128 @@ +/* + * Copyright 2014 Vincent Sanders <vince@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file riscos/filetype.h + * RISC OS filetpe interface. + */ + +#ifndef _NETSURF_RISCOS_FILETYPE_H_ +#define _NETSURF_RISCOS_FILETYPE_H_ + +#include "content/content_type.h" + +#ifndef FILETYPE_ACORN_URI +#define FILETYPE_ACORN_URI 0xf91 +#endif +#ifndef FILETYPE_ANT_URL +#define FILETYPE_ANT_URL 0xb28 +#endif +#ifndef FILETYPE_IEURL +#define FILETYPE_IEURL 0x1ba +#endif +#ifndef FILETYPE_HTML +#define FILETYPE_HTML 0xfaf +#endif +#ifndef FILETYPE_JNG +#define FILETYPE_JNG 0xf78 +#endif +#ifndef FILETYPE_CSS +#define FILETYPE_CSS 0xf79 +#endif +#ifndef FILETYPE_MNG +#define FILETYPE_MNG 0xf83 +#endif +#ifndef FILETYPE_GIF +#define FILETYPE_GIF 0x695 +#endif +#ifndef FILETYPE_BMP +#define FILETYPE_BMP 0x69c +#endif +#ifndef FILETYPE_ICO +#define FILETYPE_ICO 0x132 +#endif +#ifndef FILETYPE_PNG +#define FILETYPE_PNG 0xb60 +#endif +#ifndef FILETYPE_JPEG +#define FILETYPE_JPEG 0xc85 +#endif +#ifndef FILETYPE_ARTWORKS +#define FILETYPE_ARTWORKS 0xd94 +#endif +#ifndef FILETYPE_SVG +#define FILETYPE_SVG 0xaad +#endif + +/** + * Determine the MIME type of a local file. + * + * \param unix_path Unix style path to file on disk + * \return Pointer to MIME type string (should not be freed) - invalidated + * on next call to fetch_filetype. + */ +const char *fetch_filetype(const char *unix_path); + +/** + * Find a MIME type for a local file + * + * \param ro_path RISC OS style path to file on disk + * \return MIME type string (on heap, caller should free), or NULL + */ +char *fetch_mimetype(const char *ro_path); + +/** + * Determine the RISC OS filetype for a content. + * + * \param h The handle of the content to examine. + * \return The RISC OS filetype corresponding to the content + */ +int ro_content_filetype(struct hlcache_handle *h); + +/** + * Determine the native RISC OS filetype to export a content as + * + * \param c The content to examine + * \return Native RISC OS filetype for export + */ +int ro_content_native_type(struct hlcache_handle *c); + +/** + * Determine the RISC OS filetype for a MIME type + * + * \param mime_type MIME type to consider + * \return Corresponding RISC OS filetype + */ +int ro_content_filetype_from_mime_type(lwc_string *mime_type); + +/** + * Determine the RISC OS filetype from a content type. + * + * \param type The content type to examine. + * \return The RISC OS filetype corresponding to the content, or 0 for unknown + */ +int ro_content_filetype_from_type(content_type type); + +/** + * Determine the type of a local file. + * + * \param unix_path Unix style path to file on disk + * \return File type + */ +bits ro_filetype_from_unix_path(const char *unix_path); + +#endif diff --git a/frontends/riscos/font.c b/frontends/riscos/font.c new file mode 100644 index 000000000..2f2ba9a35 --- /dev/null +++ b/frontends/riscos/font.c @@ -0,0 +1,598 @@ +/* + * Copyright 2006 James Bursa <bursa@users.sourceforge.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * \file + * RISC OS implementation of Font handling. + * + * The RUfl is used to handle and render fonts. + */ + +#include "utils/config.h" + +#include <assert.h> +#include <string.h> +#include <oslib/wimp.h> +#include <oslib/wimpreadsysinfo.h> + +#include "utils/nsoption.h" +#include "utils/log.h" +#include "utils/messages.h" +#include "utils/utils.h" +#include "desktop/gui_layout.h" + +#include "riscos/gui.h" +#include "riscos/font.h" + + +/** desktop font, size and style being used */ +char ro_gui_desktop_font_family[80]; +int ro_gui_desktop_font_size = 12; +rufl_style ro_gui_desktop_font_style = rufl_WEIGHT_400; +bool no_font_blending = false; + + +/** + * Check that at least Homerton.Medium is available. + */ +static void nsfont_check_fonts(void) +{ + char s[252]; + font_f font; + os_error *error; + + error = xfont_find_font("Homerton.Medium\\ELatin1", + 160, 160, 0, 0, &font, 0, 0); + if (error) { + if (error->errnum == error_FILE_NOT_FOUND) { + xwimp_start_task("TaskWindow -wimpslot 200K -quit " + "<NetSurf$Dir>.FixFonts", 0); + die("FontBadInst"); + } else { + LOG("xfont_find_font: 0x%x: %s", error->errnum, error->errmess); + snprintf(s, sizeof s, messages_get("FontError"), + error->errmess); + die(s); + } + } + + error = xfont_lose_font(font); + if (error) { + LOG("xfont_lose_font: 0x%x: %s", error->errnum, error->errmess); + snprintf(s, sizeof s, messages_get("FontError"), + error->errmess); + die(s); + } +} + + +/** + * Check that a font option is valid, and fix it if not. + * + * \param option pointer to option, as used by options.[ch] + * \param family font family to use if option is not set, or the set + * family is not available + * \param fallback font family to use if family is not available either + */ +static void nsfont_check_option(char **option, const char *family, + const char *fallback) +{ + if (*option && !nsfont_exists(*option)) { + free(*option); + *option = 0; + } + if (!*option) { + if (nsfont_exists(family)) + *option = strdup(family); + else + *option = strdup(fallback); + } +} + + +/** + * Initialize font handling. + * + * Exits through die() on error. + */ +void nsfont_init(void) +{ + const char *fallback; + rufl_code code; + + nsfont_check_fonts(); + + LOG("Initialise RUfl"); + code = rufl_init(); + if (code != rufl_OK) { + if (code == rufl_FONT_MANAGER_ERROR) + LOG("rufl_init: rufl_FONT_MANAGER_ERROR: 0x%x: %s", rufl_fm_error->errnum, rufl_fm_error->errmess); + else + LOG("rufl_init: 0x%x", code); + die("The Unicode font library could not be initialized. " + "Please report this to the developers."); + } + LOG("RUfl initialised"); + + if (rufl_family_list_entries == 0) + die("No fonts could be found. At least one font must be " + "installed."); + + fallback = nsfont_fallback_font(); + + nsfont_check_option(&nsoption_charp(font_sans), "Homerton", fallback); + nsfont_check_option(&nsoption_charp(font_serif), "Trinity", fallback); + nsfont_check_option(&nsoption_charp(font_mono), "Corpus", fallback); + nsfont_check_option(&nsoption_charp(font_cursive), "Churchill", fallback); + nsfont_check_option(&nsoption_charp(font_fantasy), "Sassoon", fallback); + + if (nsoption_int(font_default) != PLOT_FONT_FAMILY_SANS_SERIF && + nsoption_int(font_default) != PLOT_FONT_FAMILY_SERIF && + nsoption_int(font_default) != PLOT_FONT_FAMILY_MONOSPACE && + nsoption_int(font_default) != PLOT_FONT_FAMILY_CURSIVE && + nsoption_int(font_default) != PLOT_FONT_FAMILY_FANTASY) { + nsoption_set_int(font_default, PLOT_FONT_FAMILY_SANS_SERIF); + } +} + + +/** + * Retrieve the fallback font name + * + * \return Fallback font name + */ +const char *nsfont_fallback_font(void) +{ + const char *fallback = "Homerton"; + + if (!nsfont_exists(fallback)) { + LOG("Homerton not found, dumping RUfl family list"); + for (unsigned int i = 0; i < rufl_family_list_entries; i++) { + LOG("'%s'", rufl_family_list[i]); + } + fallback = rufl_family_list[0]; + } + + return fallback; +} + + +/** + * bsearch comparison routine + */ +static int nsfont_list_cmp(const void *keyval, const void *datum) +{ + const char *key = keyval; + const char * const *entry = datum; + return strcasecmp(key, *entry); +} + + +/** + * Check if a font family is available. + * + * \param font_family name of font family + * \return true if the family is available + */ +bool nsfont_exists(const char *font_family) +{ + if (bsearch(font_family, rufl_family_list, + rufl_family_list_entries, sizeof rufl_family_list[0], + nsfont_list_cmp)) + return true; + return false; +} + + +/** + * Measure the width of a string. + * + * \param fstyle plot style for this text + * \param string UTF-8 string to measure + * \param length length of string + * \param width updated to width of string[0..length) + * \return true on success, false on error and error reported + */ +static nserror +ro_font_width(const plot_font_style_t *fstyle, + const char *string, size_t length, + int *width) +{ + const char *font_family; + unsigned int font_size; + rufl_style font_style; + rufl_code code; + + nsfont_read_style(fstyle, &font_family, &font_size, &font_style); + if (font_size == 0) { + *width = 0; + return NSERROR_OK; + } + + code = rufl_width(font_family, font_style, font_size, + string, length, + width); + if (code != rufl_OK) { + if (code == rufl_FONT_MANAGER_ERROR) + LOG("rufl_width: rufl_FONT_MANAGER_ERROR: 0x%x: %s", rufl_fm_error->errnum, rufl_fm_error->errmess); + else + LOG("rufl_width: 0x%x", code); +/* ro_warn_user("MiscError", "font error"); */ + *width = 0; + return NSERROR_INVALID; + } + + *width /= 2; + return NSERROR_OK; +} + + +/** + * Find the position in a string where an x coordinate falls. + * + * \param fstyle style for this text + * \param string UTF-8 string to measure + * \param length length of string + * \param x x coordinate to search for + * \param char_offset updated to offset in string of actual_x, [0..length] + * \param actual_x updated to x coordinate of character closest to x + * \return true on success, false on error and error reported + */ +static nserror +ro_font_position(const plot_font_style_t *fstyle, + const char *string, size_t length, + int x, size_t *char_offset, int *actual_x) +{ + const char *font_family; + unsigned int font_size; + rufl_style font_style; + rufl_code code; + + nsfont_read_style(fstyle, &font_family, &font_size, &font_style); + if (font_size == 0) { + *char_offset = 0; + *actual_x = 0; + return NSERROR_OK; + } + + code = rufl_x_to_offset(font_family, font_style, font_size, + string, length, + x * 2, char_offset, actual_x); + if (code != rufl_OK) { + if (code == rufl_FONT_MANAGER_ERROR) + LOG("rufl_x_to_offset: rufl_FONT_MANAGER_ERROR: ""0x%x: %s", rufl_fm_error->errnum, rufl_fm_error->errmess); + else + LOG("rufl_x_to_offset: 0x%x", code); +/* ro_warn_user("MiscError", "font error"); */ + *char_offset = 0; + *actual_x = 0; + return NSERROR_INVALID; + } + + *actual_x /= 2; + + return NSERROR_OK; +} + + +/** + * Find where to split a string to make it fit a width. + * + * \param fstyle style for this text + * \param string UTF-8 string to measure + * \param length length of string, in bytes + * \param x width available + * \param char_offset updated to offset in string of actual_x, [1..length] + * \param actual_x updated to x coordinate of character closest to x + * \return true on success, false on error and error reported + * + * On exit, char_offset indicates first character after split point. + * + * Note: char_offset of 0 should never be returned. + * + * Returns: + * char_offset giving split point closest to x, where actual_x <= x + * else + * char_offset giving split point closest to x, where actual_x > x + * + * Returning char_offset == length means no split possible + */ +static nserror +ro_font_split(const plot_font_style_t *fstyle, + const char *string, size_t length, + int x, size_t *char_offset, int *actual_x) +{ + const char *font_family; + unsigned int font_size; + rufl_style font_style; + rufl_code code; + + nsfont_read_style(fstyle, &font_family, &font_size, &font_style); + if (font_size == 0) { + *char_offset = 0; + *actual_x = 0; + return NSERROR_OK; + } + + code = rufl_split(font_family, font_style, font_size, + string, length, + x * 2, char_offset, actual_x); + if (code != rufl_OK) { + if (code == rufl_FONT_MANAGER_ERROR) { + LOG("rufl_split: rufl_FONT_MANAGER_ERROR: ""0x%x: %s", + rufl_fm_error->errnum, rufl_fm_error->errmess); + } else { + LOG("rufl_split: 0x%x", code); + } +/* ro_warn_user("MiscError", "font error"); */ + *char_offset = 0; + *actual_x = 0; + return NSERROR_INVALID; + } + + if (*char_offset != length) { + /* we found something to split at */ + size_t orig = *char_offset; + + /* ensure a space at <= the split point we found */ + while (*char_offset && string[*char_offset] != ' ') { + (*char_offset)--; + } + + /* nothing valid found <= split point, advance to next space */ + if (*char_offset == 0) { + *char_offset = orig; + while ((*char_offset != length) && + (string[*char_offset] != ' ')) { + (*char_offset)++; + } + } + } + + code = rufl_width(font_family, font_style, font_size, + string, *char_offset, + actual_x); + if (code != rufl_OK) { + if (code == rufl_FONT_MANAGER_ERROR) { + LOG("rufl_width: rufl_FONT_MANAGER_ERROR: 0x%x: %s", + rufl_fm_error->errnum, rufl_fm_error->errmess); + } else { + LOG("rufl_width: 0x%x", code); + } +/* ro_warn_user("MiscError", "font error"); */ + *char_offset = 0; + *actual_x = 0; + return NSERROR_INVALID; + } + + *actual_x /= 2; + return NSERROR_OK; +} + + +/** + * Paint a string. + * + * \param fstyle plot style for this text + * \param string UTF-8 string to measure + * \param length length of string + * \param x x coordinate + * \param y y coordinate + * \return true on success, false on error and error reported + */ +bool nsfont_paint(const plot_font_style_t *fstyle, const char *string, + size_t length, int x, int y) +{ + const char *font_family; + unsigned int font_size; + unsigned int flags = rufl_BLEND_FONT; + rufl_style font_style; + rufl_code code; + + nsfont_read_style(fstyle, &font_family, &font_size, &font_style); + if (font_size == 0) + return true; + + if (no_font_blending || print_active) + flags = 0; + + code = rufl_paint(font_family, font_style, font_size, + string, length, x, y, flags); + if (code != rufl_OK) { + if (code == rufl_FONT_MANAGER_ERROR) { + LOG("rufl_paint: rufl_FONT_MANAGER_ERROR: 0x%x: %s", rufl_fm_error->errnum, rufl_fm_error->errmess); + } else { + LOG("rufl_paint: 0x%x", code); + } + } + + return true; +} + + +/** + * Convert a font style to a font family, size and rufl_style. + * + * \param fstyle plot style for this text + * \param font_family updated to font family + * \param font_size updated to font size + * \param font_style updated to font style + */ +void nsfont_read_style(const plot_font_style_t *fstyle, + const char **font_family, unsigned int *font_size, + rufl_style *font_style) +{ + static const rufl_style weight_table[] = { + rufl_WEIGHT_100, + rufl_WEIGHT_200, + rufl_WEIGHT_300, + rufl_WEIGHT_400, + rufl_WEIGHT_500, + rufl_WEIGHT_600, + rufl_WEIGHT_700, + rufl_WEIGHT_800, + rufl_WEIGHT_900 + }; + + *font_size = (fstyle->size * 16) / FONT_SIZE_SCALE; + if (1600 < *font_size) + *font_size = 1600; + + switch (fstyle->family) { + case PLOT_FONT_FAMILY_SANS_SERIF: + *font_family = nsoption_charp(font_sans); + break; + case PLOT_FONT_FAMILY_SERIF: + *font_family = nsoption_charp(font_serif); + break; + case PLOT_FONT_FAMILY_MONOSPACE: + *font_family = nsoption_charp(font_mono); + break; + case PLOT_FONT_FAMILY_CURSIVE: + *font_family = nsoption_charp(font_cursive); + break; + case PLOT_FONT_FAMILY_FANTASY: + *font_family = nsoption_charp(font_fantasy); + break; + default: + *font_family = nsoption_charp(font_sans); + break; + } + + if ((fstyle->flags & FONTF_ITALIC) || (fstyle->flags & FONTF_OBLIQUE)) { + *font_style = rufl_SLANTED; + } else { + *font_style = 0; + } + + *font_style |= weight_table[(fstyle->weight / 100) - 1]; +} + + +/** + * Looks up the current desktop font and converts that to a family name, + * font size and style flags suitable for passing directly to rufl + * + * \param family buffer to receive font family + * \param family_size buffer size + * \param psize receives the font size in 1/16 points + * \param pstyle receives the style settings to be passed to rufl + */ +static void +ro_gui_wimp_desktop_font(char *family, + size_t family_size, + int *psize, + rufl_style *pstyle) +{ + rufl_style style = rufl_WEIGHT_400; + os_error *error; + int ptx, pty; + font_f font_handle; + int used; + + assert(family); + assert(20 < family_size); + assert(psize); + assert(pstyle); + + error = xwimpreadsysinfo_font(&font_handle, NULL); + if (error) { + LOG("xwimpreadsysinfo_font: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + goto failsafe; + } + + if (font_handle == font_SYSTEM) { + /* Er, yeah; like that's ever gonna work with RUfl */ + goto failsafe; + } + + error = xfont_read_identifier(font_handle, NULL, &used); + if (error) { + LOG("xfont_read_identifier: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MiscError", error->errmess); + goto failsafe; + } + + if (family_size < (size_t) used + 1) { + LOG("desktop font name too long"); + goto failsafe; + } + + error = xfont_read_defn(font_handle, (byte *) family, + &ptx, &pty, NULL, NULL, NULL, NULL); + if (error) { + LOG("xfont_read_defn: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MiscError", error->errmess); + goto failsafe; + } + + for (size_t i = 0; i != (size_t) used; i++) { + if (family[i] < ' ') { + family[i] = 0; + break; + } + } + + LOG("desktop font \"%s\"", family); + + if (strcasestr(family, ".Medium")) + style = rufl_WEIGHT_500; + else if (strcasestr(family, ".Bold")) + style = rufl_WEIGHT_700; + if (strcasestr(family, ".Italic") || strcasestr(family, ".Oblique")) + style |= rufl_SLANTED; + + char *dot = strchr(family, '.'); + if (dot) + *dot = 0; + + *psize = max(ptx, pty); + *pstyle = style; + + LOG("family \"%s\", size %i, style %i", family, *psize, style); + + return; + +failsafe: + strcpy(family, "Homerton"); + *psize = 12*16; + *pstyle = rufl_WEIGHT_400; +} + + +/** + * Retrieve the current desktop font family, size and style from + * the WindowManager in a form suitable for passing to rufl + */ +void ro_gui_wimp_get_desktop_font(void) +{ + ro_gui_wimp_desktop_font(ro_gui_desktop_font_family, + sizeof(ro_gui_desktop_font_family), + &ro_gui_desktop_font_size, + &ro_gui_desktop_font_style); +} + + +static struct gui_layout_table layout_table = { + .width = ro_font_width, + .position = ro_font_position, + .split = ro_font_split, +}; + +struct gui_layout_table *riscos_layout_table = &layout_table; diff --git a/frontends/riscos/font.h b/frontends/riscos/font.h new file mode 100644 index 000000000..0319a7ee3 --- /dev/null +++ b/frontends/riscos/font.h @@ -0,0 +1,45 @@ +/* + * Copyright 2014 Vincent Sanders <vince@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file riscos/font.h + * RISC OS font interface. + */ + +#ifndef _NETSURF_RISCOS_FONT_H_ +#define _NETSURF_RISCOS_FONT_H_ + +#include <rufl.h> + +struct gui_layout_table *riscos_layout_table; + +/** desktop font, size and style being used */ +extern char ro_gui_desktop_font_family[]; +extern int ro_gui_desktop_font_size; +extern rufl_style ro_gui_desktop_font_style; + +void nsfont_init(void); +bool nsfont_exists(const char *font_family); +const char *nsfont_fallback_font(void); +bool nsfont_paint(const plot_font_style_t *fstyle, const char *string, + size_t length, int x, int y); +void nsfont_read_style(const plot_font_style_t *fstyle, + const char **font_family, unsigned int *font_size, + rufl_style *font_style); +void ro_gui_wimp_get_desktop_font(void); + +#endif diff --git a/frontends/riscos/global_history.c b/frontends/riscos/global_history.c new file mode 100644 index 000000000..c469847e0 --- /dev/null +++ b/frontends/riscos/global_history.c @@ -0,0 +1,413 @@ +/* + * Copyright 2005 Richard Wilson <info@tinct.net> + * Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Global history (implementation). + */ + +#include <assert.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include "oslib/wimp.h" +#include "oslib/wimpspriteop.h" + +#include "content/urldb.h" +#include "utils/nsoption.h" +#include "utils/messages.h" +#include "utils/log.h" +#include "desktop/global_history.h" +#include "desktop/tree.h" +#include "desktop/gui_window.h" + +#include "riscos/dialog.h" +#include "riscos/global_history.h" +#include "riscos/gui.h" +#include "riscos/menus.h" +#include "riscos/save.h" +#include "riscos/toolbar.h" +#include "riscos/treeview.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" + +static void ro_gui_global_history_toolbar_update_buttons(void); +static void ro_gui_global_history_toolbar_save_buttons(char *config); +static bool ro_gui_global_history_menu_prepare(wimp_w w, wimp_i i, + wimp_menu *menu, wimp_pointer *pointer); +static void ro_gui_global_history_menu_warning(wimp_w w, wimp_i i, + wimp_menu *menu, wimp_selection *selection, menu_action action); +static bool ro_gui_global_history_menu_select(wimp_w w, wimp_i i, + wimp_menu *menu, wimp_selection *selection, menu_action action); +static void ro_gui_global_history_toolbar_click(button_bar_action action); + +struct ro_treeview_callbacks ro_global_history_treeview_callbacks = { + ro_gui_global_history_toolbar_click, + ro_gui_global_history_toolbar_update_buttons, + ro_gui_global_history_toolbar_save_buttons +}; + +/* The RISC OS global history window, toolbar and treeview data */ + +static struct ro_global_history_window { + wimp_w window; + struct toolbar *toolbar; + ro_treeview *tv; + wimp_menu *menu; +} global_history_window; + +/** + * Pre-Initialise the global history tree. This is called for things that + * need to be done at the gui_init() stage, such as loading templates. + */ + +void ro_gui_global_history_preinitialise(void) +{ + /* Create our window. */ + + global_history_window.window = ro_gui_dialog_create("tree"); + ro_gui_set_window_title(global_history_window.window, + messages_get("GlobalHistory")); +} + +/** + * Initialise global history tree, at the gui_init2() stage. + */ + +void ro_gui_global_history_postinitialise(void) +{ + /* Create our toolbar. */ + + global_history_window.toolbar = ro_toolbar_create(NULL, + global_history_window.window, + THEME_STYLE_GLOBAL_HISTORY_TOOLBAR, TOOLBAR_FLAGS_NONE, + ro_treeview_get_toolbar_callbacks(), NULL, + "HelpGHistoryToolbar"); + if (global_history_window.toolbar != NULL) { + ro_toolbar_add_buttons(global_history_window.toolbar, + global_history_toolbar_buttons, + nsoption_charp(toolbar_history)); + ro_toolbar_rebuild(global_history_window.toolbar); + } + + /* Create the treeview with the window and toolbar. */ + + global_history_window.tv = + ro_treeview_create(global_history_window.window, + global_history_window.toolbar, + &ro_global_history_treeview_callbacks, + TREE_HISTORY); + if (global_history_window.tv == NULL) { + LOG("Failed to allocate treeview"); + return; + } + + ro_toolbar_update_client_data(global_history_window.toolbar, + global_history_window.tv); + + /* Build the global history window menu. */ + + static const struct ns_menu global_history_definition = { + "History", { + { "History", NO_ACTION, 0 }, + { "_History.Export", HISTORY_EXPORT, &dialog_saveas }, + { "History.Expand", TREE_EXPAND_ALL, 0 }, + { "History.Expand.All", TREE_EXPAND_ALL, 0 }, + { "History.Expand.Folders", TREE_EXPAND_FOLDERS, 0 }, + { "History.Expand.Links", TREE_EXPAND_LINKS, 0 }, + { "History.Collapse", TREE_COLLAPSE_ALL, 0 }, + { "History.Collapse.All", TREE_COLLAPSE_ALL, 0 }, + { "History.Collapse.Folders", TREE_COLLAPSE_FOLDERS, 0 }, + { "History.Collapse.Links", TREE_COLLAPSE_LINKS, 0 }, + { "History.Toolbars", NO_ACTION, 0 }, + { "_History.Toolbars.ToolButtons", TOOLBAR_BUTTONS, 0 }, + { "History.Toolbars.EditToolbar",TOOLBAR_EDIT, 0 }, + { "Selection", TREE_SELECTION, 0 }, + { "Selection.Launch", TREE_SELECTION_LAUNCH, 0 }, + { "Selection.Delete", TREE_SELECTION_DELETE, 0 }, + { "SelectAll", TREE_SELECT_ALL, 0 }, + { "Clear", TREE_CLEAR_SELECTION, 0 }, + {NULL, 0, 0} + } + }; + global_history_window.menu = ro_gui_menu_define_menu( + &global_history_definition); + + ro_gui_wimp_event_register_menu(global_history_window.window, + global_history_window.menu, false, false); + ro_gui_wimp_event_register_menu_prepare(global_history_window.window, + ro_gui_global_history_menu_prepare); + ro_gui_wimp_event_register_menu_selection(global_history_window.window, + ro_gui_global_history_menu_select); + ro_gui_wimp_event_register_menu_warning(global_history_window.window, + ro_gui_global_history_menu_warning); +} + +/** + * Destroy the global history window. + */ + +void ro_gui_global_history_destroy(void) +{ + if (global_history_window.tv == NULL) + return; + + ro_treeview_destroy(global_history_window.tv); +} + +/** + * Open the global history window. + */ + +void ro_gui_global_history_open(void) +{ + ro_gui_global_history_toolbar_update_buttons(); + + if (!ro_gui_dialog_open_top(global_history_window.window, + global_history_window.toolbar, 600, 800)) { + ro_treeview_set_origin(global_history_window.tv, 0, + -(ro_toolbar_height( + global_history_window.toolbar))); + } +} + +/** + * Handle toolbar button clicks. + * + * \param action The action to handle + */ + +void ro_gui_global_history_toolbar_click(button_bar_action action) +{ + switch (action) { + case TOOLBAR_BUTTON_DELETE: + global_history_keypress(NS_KEY_DELETE_LEFT); + break; + + case TOOLBAR_BUTTON_EXPAND: + global_history_expand(false); + break; + + case TOOLBAR_BUTTON_COLLAPSE: + global_history_contract(false); + break; + + case TOOLBAR_BUTTON_OPEN: + global_history_expand(true); + break; + + case TOOLBAR_BUTTON_CLOSE: + global_history_contract(true); + break; + + case TOOLBAR_BUTTON_LAUNCH: + global_history_keypress(NS_KEY_CR); + break; + + default: + break; + } +} + + +/** + * Update the button state in the global history toolbar. + */ + +void ro_gui_global_history_toolbar_update_buttons(void) +{ + ro_toolbar_set_button_shaded_state(global_history_window.toolbar, + TOOLBAR_BUTTON_DELETE, + !global_history_has_selection()); + + ro_toolbar_set_button_shaded_state(global_history_window.toolbar, + TOOLBAR_BUTTON_LAUNCH, + !global_history_has_selection()); +} + + +/** + * Save a new button arrangement in the global history toolbar. + * + * \param *config The new button configuration string. + */ + +void ro_gui_global_history_toolbar_save_buttons(char *config) +{ + nsoption_set_charp(toolbar_history, config); + ro_gui_save_options(); +} + + +/** + * Prepare the global history menu for opening + * + * \param w The window owning the menu. + * \param i The icon owning the menu. + * \param *menu The menu about to be opened. + * \param *pointer Pointer to the relevant wimp event block, or + * NULL for an Adjust click. + * \return true if the event was handled; else false. + */ + +bool ro_gui_global_history_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_pointer *pointer) +{ + bool selection; + + if (menu != global_history_window.menu) + return false; + + selection = global_history_has_selection(); + + ro_gui_menu_set_entry_shaded(global_history_window.menu, + TREE_SELECTION, !selection); + ro_gui_menu_set_entry_shaded(global_history_window.menu, + TREE_CLEAR_SELECTION, !selection); + + ro_gui_save_prepare(GUI_SAVE_HISTORY_EXPORT_HTML, + NULL, NULL, NULL, NULL); + + ro_gui_menu_set_entry_shaded(menu, TOOLBAR_BUTTONS, + ro_toolbar_menu_option_shade( + global_history_window.toolbar)); + ro_gui_menu_set_entry_ticked(menu, TOOLBAR_BUTTONS, + ro_toolbar_menu_buttons_tick( + global_history_window.toolbar)); + + ro_gui_menu_set_entry_shaded(menu, TOOLBAR_EDIT, + ro_toolbar_menu_edit_shade( + global_history_window.toolbar)); + ro_gui_menu_set_entry_ticked(menu, TOOLBAR_EDIT, + ro_toolbar_menu_edit_tick( + global_history_window.toolbar)); + + return true; +} + +/** + * Handle submenu warnings for the global_hostory menu + * + * \param w The window owning the menu. + * \param i The icon owning the menu. + * \param *menu The menu to which the warning applies. + * \param *selection The wimp menu selection data. + * \param action The selected menu action. + */ + +void ro_gui_global_history_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_selection *selection, menu_action action) +{ + /* Do nothing */ +} + +/** + * Handle selections from the global history menu + * + * \param w The window owning the menu. + * \param i The icon owning the menu. + * \param *menu The menu from which the selection was made. + * \param *selection The wimp menu selection data. + * \param action The selected menu action. + * \return true if action accepted; else false. + */ + +bool ro_gui_global_history_menu_select(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_selection *selection, menu_action action) +{ + switch (action) { + case HISTORY_EXPORT: + ro_gui_dialog_open_persistent(w, dialog_saveas, true); + return true; + case TREE_EXPAND_ALL: + global_history_expand(false); + return true; + case TREE_EXPAND_FOLDERS: + global_history_expand(true); + return true; + case TREE_EXPAND_LINKS: + global_history_expand(false); + return true; + case TREE_COLLAPSE_ALL: + global_history_contract(true); + return true; + case TREE_COLLAPSE_FOLDERS: + global_history_contract(true); + return true; + case TREE_COLLAPSE_LINKS: + global_history_contract(false); + return true; + case TREE_SELECTION_LAUNCH: + global_history_keypress(NS_KEY_CR); + return true; + case TREE_SELECTION_DELETE: + global_history_keypress(NS_KEY_DELETE_LEFT); + return true; + case TREE_SELECT_ALL: + global_history_keypress(NS_KEY_SELECT_ALL); + return true; + case TREE_CLEAR_SELECTION: + global_history_keypress(NS_KEY_CLEAR_SELECTION); + return true; + case TOOLBAR_BUTTONS: + ro_toolbar_set_display_buttons(global_history_window.toolbar, + !ro_toolbar_get_display_buttons( + global_history_window.toolbar)); + return true; + case TOOLBAR_EDIT: + ro_toolbar_toggle_edit(global_history_window.toolbar); + return true; + default: + return false; + } + + return false; +} + +/** + * Check if a particular window handle is the global history window + * + * \param window the window in question + * \return true if this window is the global history + */ + +bool ro_gui_global_history_check_window(wimp_w window) +{ + if (global_history_window.window == window) + return true; + else + return false; +} + +/** + * Check if a particular menu handle is the global history menu + * + * \param *menu The menu in question. + * \return true if this menu is the global history menu + */ + +bool ro_gui_global_history_check_menu(wimp_menu *menu) +{ + if (global_history_window.menu == menu) + return true; + else + return false; +} + diff --git a/frontends/riscos/global_history.h b/frontends/riscos/global_history.h new file mode 100644 index 000000000..6f5ba11eb --- /dev/null +++ b/frontends/riscos/global_history.h @@ -0,0 +1,38 @@ +/* + * Copyright 2005 Richard Wilson <info@tinct.net> + * Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Global history (interface). + */ + +#ifndef _NETSURF_RISCOS_GLOBALHISTORY_H_ +#define _NETSURF_RISCOS_GLOBALHISTORY_H_ + +#include "riscos/menus.h" + +void ro_gui_global_history_preinitialise(void); +void ro_gui_global_history_postinitialise(void); +void ro_gui_global_history_destroy(void); +void ro_gui_global_history_open(void); +void ro_gui_global_history_save(void); +bool ro_gui_global_history_check_window(wimp_w window); +bool ro_gui_global_history_check_menu(wimp_menu *menu); + +#endif + diff --git a/frontends/riscos/gui.c b/frontends/riscos/gui.c new file mode 100644 index 000000000..309f27bdb --- /dev/null +++ b/frontends/riscos/gui.c @@ -0,0 +1,2522 @@ +/* + * Copyright 2003 Phil Mellor <monkeyson@users.sourceforge.net> + * Copyright 2004-2008 James Bursa <bursa@users.sourceforge.net> + * Copyright 2003 John M Bell <jmb202@ecs.soton.ac.uk> + * Copyright 2005 Richard Wilson <info@tinct.net> + * Copyright 2004 Andrew Timmins <atimmins@blueyonder.co.uk> + * Copyright 2004-2009 John Tytgat <joty@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdbool.h> +#include <string.h> +#include <assert.h> +#include <errno.h> +#include <signal.h> +#include <unixlib/local.h> +#include <fpu_control.h> +#include <oslib/help.h> +#include <oslib/uri.h> +#include <oslib/inetsuite.h> +#include <oslib/pdriver.h> +#include <oslib/osfile.h> +#include <oslib/hourglass.h> +#include <oslib/osgbpb.h> +#include <oslib/osbyte.h> +#include <oslib/osmodule.h> +#include <oslib/osfscontrol.h> + +#include "utils/utils.h" +#include "utils/nsoption.h" +#include "utils/log.h" +#include "utils/messages.h" +#include "utils/file.h" +#include "utils/filename.h" +#include "utils/url.h" +#include "utils/corestrings.h" +#include "desktop/gui_fetch.h" +#include "desktop/gui_misc.h" +#include "desktop/save_complete.h" +#include "desktop/treeview.h" +#include "desktop/netsurf.h" +#include "desktop/browser.h" +#include "content/urldb.h" +#include "content/hlcache.h" +#include "content/backing_store.h" + +#include "riscos/gui.h" +#include "riscos/bitmap.h" +#include "riscos/wimputils.h" +#include "riscos/hotlist.h" +#include "riscos/buffer.h" +#include "riscos/textselection.h" +#include "riscos/print.h" +#include "riscos/save.h" +#include "riscos/dialog.h" +#include "riscos/wimp.h" +#include "riscos/message.h" +#include "riscos/help.h" +#include "riscos/query.h" +#include "riscos/window.h" +#include "riscos/iconbar.h" +#include "riscos/sslcert.h" +#include "riscos/global_history.h" +#include "riscos/cookies.h" +#include "riscos/wimp_event.h" +#include "riscos/uri.h" +#include "riscos/url_protocol.h" +#include "riscos/mouse.h" +#include "riscos/ucstables.h" +#include "riscos/filetype.h" +#include "riscos/font.h" +#include "riscos/toolbar.h" +#include "riscos/content-handlers/artworks.h" +#include "riscos/content-handlers/draw.h" +#include "riscos/content-handlers/sprite.h" + +bool riscos_done = false; + +extern bool ro_plot_patterned_lines; + +int os_version = 0; + +const char * const __dynamic_da_name = "NetSurf"; /**< For UnixLib. */ +int __dynamic_da_max_size = 128 * 1024 * 1024; /**< For UnixLib. */ +int __feature_imagefs_is_file = 1; /**< For UnixLib. */ +/* default filename handling */ +int __riscosify_control = __RISCOSIFY_NO_SUFFIX | + __RISCOSIFY_NO_REVERSE_SUFFIX; +#ifndef __ELF__ +extern int __dynamic_num; +#endif + +const char * NETSURF_DIR; + +static const char *task_name = "NetSurf"; +#define CHOICES_PREFIX "<Choices$Write>.WWW.NetSurf." + +ro_gui_drag_type gui_current_drag_type; +wimp_t task_handle; /**< RISC OS wimp task handle. */ +static clock_t gui_last_poll; /**< Time of last wimp_poll. */ +osspriteop_area *gui_sprites; /**< Sprite area containing pointer and hotlist sprites */ + +#define DIR_SEP ('.') + +/** + * Accepted wimp user messages. + */ +static ns_wimp_message_list task_messages = { + message_HELP_REQUEST, + { + message_DATA_SAVE, + message_DATA_SAVE_ACK, + message_DATA_LOAD, + message_DATA_LOAD_ACK, + message_DATA_OPEN, + message_PRE_QUIT, + message_SAVE_DESKTOP, + message_MENU_WARNING, + message_MENUS_DELETED, + message_WINDOW_INFO, + message_CLAIM_ENTITY, + message_DATA_REQUEST, + message_DRAGGING, + message_DRAG_CLAIM, + message_MODE_CHANGE, + message_PALETTE_CHANGE, + message_FONT_CHANGED, + message_URI_PROCESS, + message_URI_RETURN_RESULT, + message_INET_SUITE_OPEN_URL, +#ifdef WITH_PLUGIN + message_PLUG_IN_OPENING, + message_PLUG_IN_CLOSED, + message_PLUG_IN_RESHAPE_REQUEST, + message_PLUG_IN_FOCUS, + message_PLUG_IN_URL_ACCESS, + message_PLUG_IN_STATUS, + message_PLUG_IN_BUSY, + message_PLUG_IN_STREAM_NEW, + message_PLUG_IN_STREAM_WRITE, + message_PLUG_IN_STREAM_WRITTEN, + message_PLUG_IN_STREAM_DESTROY, + message_PLUG_IN_OPEN, + message_PLUG_IN_CLOSE, + message_PLUG_IN_RESHAPE, + message_PLUG_IN_STREAM_AS_FILE, + message_PLUG_IN_NOTIFY, + message_PLUG_IN_ABORT, + message_PLUG_IN_ACTION, + /* message_PLUG_IN_INFORMED, (not provided by oslib) */ +#endif + message_PRINT_SAVE, + message_PRINT_ERROR, + message_PRINT_TYPE_ODD, + message_HOTLIST_ADD_URL, + message_HOTLIST_CHANGED, + 0 + } +}; + + +static struct +{ + int width; /* in OS units */ + int height; +} screen_info; + + +/** + * Callback to translate resource to full url for RISC OS. + * + * Transforms a resource: path into a full URL. The returned URL is + * used as the target for a redirect. The caller takes ownership of + * the returned nsurl including unrefing it when finished with it. + * + * \param path The path of the resource to locate. + * \return A string containing the full URL of the target object or + * NULL if no suitable resource can be found. + */ +static nsurl *gui_get_resource_url(const char *path) +{ + static const char base_url[] = "file:///NetSurf:/Resources/"; + size_t path_len, length; + char *raw; + nsurl *url = NULL; + + /* Map paths first */ + if (strcmp(path, "adblock.css") == 0) { + path = "AdBlock"; + + } else if (strcmp(path, "default.css") == 0) { + path = "CSS"; + + } else if (strcmp(path, "quirks.css") == 0) { + path = "Quirks"; + + } else if (strcmp(path, "favicon.ico") == 0) { + path = "Icons/content.png"; + + } else if (strcmp(path, "user.css") == 0) { + /* Special case; this file comes from Choices: */ + nsurl_create("file:///Choices:WWW/NetSurf/User", &url); + return url; + } + + path_len = strlen(path); + + /* Find max URL length */ + length = SLEN(base_url) + SLEN("xx/") + path_len + 1; + + raw = malloc(length); + if (raw != NULL) { + /* Insert base URL */ + char *ptr = memcpy(raw, base_url, SLEN(base_url)); + ptr += SLEN(base_url); + + /* Add language directory to URL, for translated files */ + /* TODO: handle non-en langauages + * handle non-html translated files */ + if (path_len > SLEN(".html") && + strncmp(path + path_len - SLEN(".html"), + ".html", SLEN(".html")) == 0) { + memcpy(ptr, "en/", SLEN("en/")); + ptr += SLEN("en/"); + } + + /* Add filename to URL */ + memcpy(ptr, path, path_len); + ptr += path_len; + + /* Terminate string */ + *ptr = '\0'; + + nsurl_create(raw, &url); + free(raw); + } + + return url; +} + + +/** + * Set colour option from wimp. + * + * \param opts The netsurf options. + * \param wimp wimp colour value + * \param option the netsurf option enum. + * \param def_colour The default colour value to use. + * \return NSERROR_OK on success or error code. + */ +static nserror +set_colour_from_wimp(struct nsoption_s *opts, + wimp_colour wimp, + enum nsoption_e option, + colour def_colour) +{ + os_error *error; + os_PALETTE(20) palette; + + error = xwimp_read_true_palette((os_palette *) &palette); + if (error != NULL) { + LOG("xwimp_read_palette: 0x%x: %s", + error->errnum, error->errmess); + } else { + /* entries are in B0G0R0LL */ + def_colour = palette.entries[wimp] >> 8; + } + + opts[option].value.c = def_colour; + + return NSERROR_OK; +} + + +/** + * Set option defaults for riscos frontend + * + * @param defaults The option table to update. + * @return error status. + * + * @todo The wimp_COLOUR_... values here map the colour definitions to + * parts of the RISC OS desktop palette. In places this is fairly + * arbitrary, and could probably do with re-checking. + */ +static nserror set_defaults(struct nsoption_s *defaults) +{ + /* Set defaults for absent option strings */ + nsoption_setnull_charp(ca_bundle, strdup("NetSurf:Resources.ca-bundle")); + nsoption_setnull_charp(cookie_file, strdup("NetSurf:Cookies")); + nsoption_setnull_charp(cookie_jar, strdup(CHOICES_PREFIX "Cookies")); + + if (nsoption_charp(ca_bundle) == NULL || + nsoption_charp(cookie_file) == NULL || + nsoption_charp(cookie_jar) == NULL) { + LOG("Failed initialising default options"); + return NSERROR_BAD_PARAMETER; + } + + /* RISC OS platform does not generally benefit from disc cache + * so the default should be off. + */ + nsoption_set_uint(disc_cache_size, 0); + + /* set default system colours for riscos ui */ + set_colour_from_wimp(defaults, wimp_COLOUR_BLACK, NSOPTION_sys_colour_ActiveBorder, 0x00000000); + set_colour_from_wimp(defaults, wimp_COLOUR_CREAM, NSOPTION_sys_colour_ActiveCaption, 0x00dddddd); + set_colour_from_wimp(defaults, wimp_COLOUR_VERY_LIGHT_GREY, NSOPTION_sys_colour_AppWorkspace, 0x00eeeeee); + set_colour_from_wimp(defaults, wimp_COLOUR_VERY_LIGHT_GREY, NSOPTION_sys_colour_Background, 0x00aa0000);/* \TODO -- Check */ + set_colour_from_wimp(defaults, wimp_COLOUR_VERY_LIGHT_GREY, NSOPTION_sys_colour_ButtonFace, 0x00aaaaaa); + set_colour_from_wimp(defaults, wimp_COLOUR_DARK_GREY, NSOPTION_sys_colour_ButtonHighlight, 0x00cccccc);/* \TODO -- Check */ + set_colour_from_wimp(defaults, wimp_COLOUR_MID_DARK_GREY, NSOPTION_sys_colour_ButtonShadow, 0x00bbbbbb); + set_colour_from_wimp(defaults, wimp_COLOUR_BLACK, NSOPTION_sys_colour_ButtonText, 0x00000000); + set_colour_from_wimp(defaults, wimp_COLOUR_BLACK, NSOPTION_sys_colour_CaptionText, 0x00000000); + set_colour_from_wimp(defaults, wimp_COLOUR_MID_LIGHT_GREY, NSOPTION_sys_colour_GrayText, 0x00777777);/* \TODO -- Check */ + set_colour_from_wimp(defaults, wimp_COLOUR_BLACK, NSOPTION_sys_colour_Highlight, 0x00ee0000); + set_colour_from_wimp(defaults, wimp_COLOUR_WHITE, NSOPTION_sys_colour_HighlightText, 0x00000000); + set_colour_from_wimp(defaults, wimp_COLOUR_BLACK, NSOPTION_sys_colour_InactiveBorder, 0x00000000); + set_colour_from_wimp(defaults, wimp_COLOUR_LIGHT_GREY, NSOPTION_sys_colour_InactiveCaption, 0x00ffffff); + set_colour_from_wimp(defaults, wimp_COLOUR_BLACK, NSOPTION_sys_colour_InactiveCaptionText, 0x00cccccc); + set_colour_from_wimp(defaults, wimp_COLOUR_CREAM, NSOPTION_sys_colour_InfoBackground, 0x00aaaaaa); + set_colour_from_wimp(defaults, wimp_COLOUR_BLACK, NSOPTION_sys_colour_InfoText, 0x00000000); + set_colour_from_wimp(defaults, wimp_COLOUR_WHITE, NSOPTION_sys_colour_Menu, 0x00aaaaaa); + set_colour_from_wimp(defaults, wimp_COLOUR_BLACK, NSOPTION_sys_colour_MenuText, 0x00000000); + set_colour_from_wimp(defaults, wimp_COLOUR_LIGHT_GREY, NSOPTION_sys_colour_Scrollbar, 0x00aaaaaa);/* \TODO -- Check */ + set_colour_from_wimp(defaults, wimp_COLOUR_MID_DARK_GREY, NSOPTION_sys_colour_ThreeDDarkShadow, 0x00555555); + set_colour_from_wimp(defaults, wimp_COLOUR_VERY_LIGHT_GREY, NSOPTION_sys_colour_ThreeDFace, 0x00dddddd); + set_colour_from_wimp(defaults, wimp_COLOUR_WHITE, NSOPTION_sys_colour_ThreeDHighlight, 0x00aaaaaa); + set_colour_from_wimp(defaults, wimp_COLOUR_WHITE, NSOPTION_sys_colour_ThreeDLightShadow, 0x00999999); + set_colour_from_wimp(defaults, wimp_COLOUR_MID_DARK_GREY, NSOPTION_sys_colour_ThreeDShadow, 0x00777777); + set_colour_from_wimp(defaults, wimp_COLOUR_VERY_LIGHT_GREY, NSOPTION_sys_colour_Window, 0x00aaaaaa); + set_colour_from_wimp(defaults, wimp_COLOUR_BLACK, NSOPTION_sys_colour_WindowFrame, 0x00000000); + set_colour_from_wimp(defaults, wimp_COLOUR_BLACK, NSOPTION_sys_colour_WindowText, 0x00000000); + + return NSERROR_OK; +} + + + + +/** + * Create intermediate directories for Choices and User Data files + */ +static void ro_gui_create_dirs(void) +{ + char buf[256]; + char *path; + + /* Choices */ + path = getenv("NetSurf$ChoicesSave"); + if (!path) + die("Failed to find NetSurf Choices save path"); + + snprintf(buf, sizeof(buf), "%s", path); + netsurf_mkdir_all(buf); + + /* URL */ + snprintf(buf, sizeof(buf), "%s", nsoption_charp(url_save)); + netsurf_mkdir_all(buf); + + /* Hotlist */ + snprintf(buf, sizeof(buf), "%s", nsoption_charp(hotlist_save)); + netsurf_mkdir_all(buf); + + /* Recent */ + snprintf(buf, sizeof(buf), "%s", nsoption_charp(recent_save)); + netsurf_mkdir_all(buf); + + /* Theme */ + snprintf(buf, sizeof(buf), "%s", nsoption_charp(theme_save)); + netsurf_mkdir_all(buf); + /* and the final directory part (as theme_save is a directory) */ + xosfile_create_dir(buf, 0); +} + + +/** + * Ensures the gui exits cleanly. + */ +static void ro_gui_cleanup(void) +{ + ro_gui_buffer_close(); + xhourglass_off(); + /* Uninstall NetSurf-specific fonts */ + xos_cli("FontRemove NetSurf:Resources.Fonts."); +} + + +/** + * Handles a signal + */ +static void ro_gui_signal(int sig) +{ + static const os_error error = { 1, "NetSurf has detected a serious " + "error and must exit. Please submit a bug report, " + "attaching the browser log file." }; + os_colour old_sand, old_glass; + + ro_gui_cleanup(); + + xhourglass_on(); + xhourglass_colours(0x0000ffff, 0x000000ff, &old_sand, &old_glass); + nsoption_dump(stderr, NULL); + /*rufl_dump_state();*/ + +#ifndef __ELF__ + /* save WimpSlot and DA to files if NetSurf$CoreDump exists */ + int used; + xos_read_var_val_size("NetSurf$CoreDump", 0, 0, &used, 0, 0); + if (used) { + int curr_slot; + xwimp_slot_size(-1, -1, &curr_slot, 0, 0); + LOG("saving WimpSlot, size 0x%x", curr_slot); + xosfile_save("$.NetSurf_Slot", 0x8000, 0, + (byte *) 0x8000, + (byte *) 0x8000 + curr_slot); + + if (__dynamic_num != -1) { + int size; + byte *base_address; + xosdynamicarea_read(__dynamic_num, &size, + &base_address, 0, 0, 0, 0, 0); + LOG("saving DA %i, base %p, size 0x%x", __dynamic_num, base_address, size); + xosfile_save("$.NetSurf_DA", + (bits) base_address, 0, + base_address, + base_address + size); + } + } +#else + /* Save WimpSlot and UnixLib managed DAs when UnixEnv$coredump + * defines a coredump directory. */ + const _kernel_oserror *err = __unixlib_write_coredump (NULL); + if (err != NULL) + LOG("Coredump failed: %s", err->errmess); +#endif + + xhourglass_colours(old_sand, old_glass, 0, 0); + xhourglass_off(); + + __write_backtrace(sig); + + xwimp_report_error_by_category(&error, + wimp_ERROR_BOX_GIVEN_CATEGORY | + wimp_ERROR_BOX_CATEGORY_ERROR << + wimp_ERROR_BOX_CATEGORY_SHIFT, + "NetSurf", "!netsurf", + (osspriteop_area *) 1, "Quit", 0); + xos_cli("Filer_Run <Wimp$ScrapDir>.WWW.NetSurf.Log"); + + _Exit(sig); +} + + +/** + * Read a "line" from an Acorn URI file. + * + * \param fp file pointer to read from + * \param b buffer for line, size 400 bytes + * \return true on success, false on EOF + */ +static bool ro_gui_uri_file_parse_line(FILE *fp, char *b) +{ + int c; + unsigned int i = 0; + + c = getc(fp); + if (c == EOF) + return false; + + /* skip comment lines */ + while (c == '#') { + do { c = getc(fp); } while (c != EOF && 32 <= c); + if (c == EOF) + return false; + do { c = getc(fp); } while (c != EOF && c < 32); + if (c == EOF) + return false; + } + + /* read "line" */ + do { + if (i == 399) + return false; + b[i++] = c; + c = getc(fp); + } while (c != EOF && 32 <= c); + + /* skip line ending control characters */ + while (c != EOF && c < 32) + c = getc(fp); + + if (c != EOF) + ungetc(c, fp); + + b[i] = 0; + return true; +} + + +/** + * Parse an Acorn URI file. + * + * \param file_name file to read + * \param uri_title pointer to receive title data, or NULL for no data + * \return URL from file, or 0 on error and error reported + */ +static char *ro_gui_uri_file_parse(const char *file_name, char **uri_title) +{ + /* See the "Acorn URI Handler Functional Specification" for the + * definition of the URI file format. */ + char line[400]; + char *url = NULL; + FILE *fp; + + *uri_title = NULL; + fp = fopen(file_name, "rb"); + if (!fp) { + LOG("fopen(\"%s\", \"rb\"): %i: %s", file_name, errno, strerror(errno)); + ro_warn_user("LoadError", strerror(errno)); + return 0; + } + + /* "URI" */ + if (!ro_gui_uri_file_parse_line(fp, line) || strcmp(line, "URI") != 0) + goto uri_syntax_error; + + /* version */ + if (!ro_gui_uri_file_parse_line(fp, line) || + strspn(line, "0123456789") != strlen(line)) + goto uri_syntax_error; + + /* URI */ + if (!ro_gui_uri_file_parse_line(fp, line)) + goto uri_syntax_error; + + url = strdup(line); + if (!url) { + ro_warn_user("NoMemory", 0); + fclose(fp); + return 0; + } + + /* title */ + if (!ro_gui_uri_file_parse_line(fp, line)) + goto uri_free; + if (uri_title && line[0] && ((line[0] != '*') || line[1])) { + *uri_title = strdup(line); + if (!*uri_title) /* non-fatal */ + ro_warn_user("NoMemory", 0); + } + fclose(fp); + + return url; + +uri_free: + free(url); + +uri_syntax_error: + fclose(fp); + ro_warn_user("URIError", 0); + return 0; +} + + +/** + * Parse an ANT URL file. + * + * \param file_name file to read + * \return URL from file, or 0 on error and error reported + */ +static char *ro_gui_url_file_parse(const char *file_name) +{ + char line[400]; + char *url; + FILE *fp; + + fp = fopen(file_name, "r"); + if (!fp) { + LOG("fopen(\"%s\", \"r\"): %i: %s", file_name, errno, strerror(errno)); + ro_warn_user("LoadError", strerror(errno)); + return 0; + } + + if (!fgets(line, sizeof line, fp)) { + if (ferror(fp)) { + LOG("fgets: %i: %s", errno, strerror(errno)); + ro_warn_user("LoadError", strerror(errno)); + } else + ro_warn_user("LoadError", messages_get("EmptyError")); + fclose(fp); + return 0; + } + + fclose(fp); + + if (line[strlen(line) - 1] == '\n') + line[strlen(line) - 1] = '\0'; + + url = strdup(line); + if (!url) { + ro_warn_user("NoMemory", 0); + return 0; + } + + return url; +} + + +/** + * Parse an IEURL file. + * + * \param file_name file to read + * \return URL from file, or 0 on error and error reported + */ +static char *ro_gui_ieurl_file_parse(const char *file_name) +{ + char line[400]; + char *url = 0; + FILE *fp; + + fp = fopen(file_name, "r"); + if (!fp) { + LOG("fopen(\"%s\", \"r\"): %i: %s", file_name, errno, strerror(errno)); + ro_warn_user("LoadError", strerror(errno)); + return 0; + } + + while (fgets(line, sizeof line, fp)) { + if (strncmp(line, "URL=", 4) == 0) { + if (line[strlen(line) - 1] == '\n') + line[strlen(line) - 1] = '\0'; + url = strdup(line + 4); + if (!url) { + fclose(fp); + ro_warn_user("NoMemory", 0); + return 0; + } + break; + } + } + if (ferror(fp)) { + LOG("fgets: %i: %s", errno, strerror(errno)); + ro_warn_user("LoadError", strerror(errno)); + fclose(fp); + return 0; + } + + fclose(fp); + + if (!url) + ro_warn_user("URIError", 0); + + return url; +} + + +/** + * Handle Message_DataOpen (double-click on file in the Filer). + * + * \param message The wimp message to open. + */ +static void ro_msg_dataopen(wimp_message *message) +{ + int file_type = message->data.data_xfer.file_type; + char *url = 0; + os_error *oserror; + nsurl *urlns; + nserror error; + size_t len; + + switch (file_type) { + case 0xb28: /* ANT URL file */ + url = ro_gui_url_file_parse(message->data.data_xfer.file_name); + error = nsurl_create(url, &urlns); + free(url); + break; + + case 0xfaf: /* HTML file */ + error = netsurf_path_to_nsurl(message->data.data_xfer.file_name, + &urlns); + break; + + case 0x1ba: /* IEURL file */ + url = ro_gui_ieurl_file_parse(message-> + data.data_xfer.file_name); + error = nsurl_create(url, &urlns); + free(url); + break; + + case 0x2000: /* application */ + len = strlen(message->data.data_xfer.file_name); + if (len < 9 || strcmp(".!NetSurf", + message->data.data_xfer.file_name + len - 9)) + return; + + if (nsoption_charp(homepage_url) && + nsoption_charp(homepage_url)[0]) { + error = nsurl_create(nsoption_charp(homepage_url), + &urlns); + } else { + error = nsurl_create(NETSURF_HOMEPAGE, &urlns); + } + break; + + default: + return; + } + + /* send DataLoadAck */ + message->action = message_DATA_LOAD_ACK; + message->your_ref = message->my_ref; + oserror = xwimp_send_message(wimp_USER_MESSAGE, message, message->sender); + if (oserror) { + LOG("xwimp_send_message: 0x%x: %s", oserror->errnum, oserror->errmess); + ro_warn_user("WimpError", oserror->errmess); + return; + } + + if (error != NSERROR_OK) { + ro_warn_user(messages_get_errorcode(error), 0); + return; + } + + /* create a new window with the file */ + error = browser_window_create(BW_CREATE_HISTORY, + urlns, + NULL, + NULL, + NULL); + nsurl_unref(urlns); + if (error != NSERROR_OK) { + ro_warn_user(messages_get_errorcode(error), 0); + } +} + + +/** + * Handle Message_DataLoad (file dragged in). + */ +static void ro_msg_dataload(wimp_message *message) +{ + int file_type = message->data.data_xfer.file_type; + char *urltxt = NULL; + char *title = NULL; + struct gui_window *g; + os_error *oserror; + nsurl *url; + nserror error; + + g = ro_gui_window_lookup(message->data.data_xfer.w); + if (g) { + if (ro_gui_window_dataload(g, message)) + return; + } + else { + g = ro_gui_toolbar_lookup(message->data.data_xfer.w); + if (g && ro_gui_toolbar_dataload(g, message)) + return; + } + + switch (file_type) { + case FILETYPE_ACORN_URI: + urltxt = ro_gui_uri_file_parse(message->data.data_xfer.file_name, + &title); + error = nsurl_create(urltxt, &url); + free(urltxt); + break; + + case FILETYPE_ANT_URL: + urltxt = ro_gui_url_file_parse(message->data.data_xfer.file_name); + error = nsurl_create(urltxt, &url); + free(urltxt); + break; + + case FILETYPE_IEURL: + urltxt = ro_gui_ieurl_file_parse(message->data.data_xfer.file_name); + error = nsurl_create(urltxt, &url); + free(urltxt); + break; + + case FILETYPE_HTML: + case FILETYPE_JNG: + case FILETYPE_CSS: + case FILETYPE_MNG: + case FILETYPE_GIF: + case FILETYPE_BMP: + case FILETYPE_ICO: + case osfile_TYPE_DRAW: + case FILETYPE_PNG: + case FILETYPE_JPEG: + case osfile_TYPE_SPRITE: + case osfile_TYPE_TEXT: + case FILETYPE_ARTWORKS: + case FILETYPE_SVG: + /* display the actual file */ + error = netsurf_path_to_nsurl(message->data.data_xfer.file_name, &url); + break; + + default: + return; + } + + /* report error to user */ + if (error != NSERROR_OK) { + ro_warn_user(messages_get_errorcode(error), 0); + return; + } + + + if (g) { + error = browser_window_navigate(g->bw, + url, + NULL, + BW_NAVIGATE_HISTORY, + NULL, + NULL, + NULL); + } else { + error = browser_window_create(BW_CREATE_HISTORY, + url, + NULL, + NULL, + NULL); + } + nsurl_unref(url); + if (error != NSERROR_OK) { + ro_warn_user(messages_get_errorcode(error), 0); + } + + + /* send DataLoadAck */ + message->action = message_DATA_LOAD_ACK; + message->your_ref = message->my_ref; + oserror = xwimp_send_message(wimp_USER_MESSAGE, message, + message->sender); + if (oserror) { + LOG("xwimp_send_message: 0x%x: %s", oserror->errnum, oserror->errmess); + ro_warn_user("WimpError", oserror->errmess); + return; + } + +} + + +/** + * Ensure that the filename in a data transfer message is NULL terminated + * (some applications, especially BASIC programs use CR) + * + * \param message message to be corrected + */ +static void ro_msg_terminate_filename(wimp_full_message_data_xfer *message) +{ + const char *ep = (char*)message + message->size; + char *p = message->file_name; + + if ((size_t)message->size >= sizeof(*message)) + ep = (char*)message + sizeof(*message) - 1; + + while (p < ep && *p >= ' ') p++; + *p = '\0'; +} + + +/** + * Handle Message_DataSave + */ +static void ro_msg_datasave(wimp_message *message) +{ + wimp_full_message_data_xfer *dataxfer = (wimp_full_message_data_xfer*)message; + + /* remove ghost caret if drag-and-drop protocol was used */ +// ro_gui_selection_drag_reset(); + + ro_msg_terminate_filename(dataxfer); + + if (ro_gui_selection_prepare_paste_datasave(dataxfer)) + return; + + switch (dataxfer->file_type) { + case FILETYPE_ACORN_URI: + case FILETYPE_ANT_URL: + case FILETYPE_IEURL: + case FILETYPE_HTML: + case FILETYPE_JNG: + case FILETYPE_CSS: + case FILETYPE_MNG: + case FILETYPE_GIF: + case FILETYPE_BMP: + case FILETYPE_ICO: + case osfile_TYPE_DRAW: + case FILETYPE_PNG: + case FILETYPE_JPEG: + case osfile_TYPE_SPRITE: + case osfile_TYPE_TEXT: + case FILETYPE_ARTWORKS: + case FILETYPE_SVG: { + os_error *error; + + dataxfer->your_ref = dataxfer->my_ref; + dataxfer->size = offsetof(wimp_full_message_data_xfer, file_name) + 16; + dataxfer->action = message_DATA_SAVE_ACK; + dataxfer->est_size = -1; + memcpy(dataxfer->file_name, "<Wimp$Scrap>", 13); + + error = xwimp_send_message(wimp_USER_MESSAGE, (wimp_message*)dataxfer, message->sender); + if (error) { + LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + } + break; + } +} + + +/** + * Handle Message_DataSaveAck. + */ +static void ro_msg_datasave_ack(wimp_message *message) +{ + ro_msg_terminate_filename((wimp_full_message_data_xfer*)message); + + if (ro_print_ack(message)) + return; + + switch (gui_current_drag_type) { + case GUI_DRAG_DOWNLOAD_SAVE: + ro_gui_download_datasave_ack(message); + break; + + case GUI_DRAG_SAVE: + ro_gui_save_datasave_ack(message); + gui_current_drag_type = GUI_DRAG_NONE; + break; + + default: + break; + } + + gui_current_drag_type = GUI_DRAG_NONE; +} + + +/** + * Handle PreQuit message + * + * \param message PreQuit message from Wimp + */ +static void ro_msg_prequit(wimp_message *message) +{ + if (!ro_gui_prequit()) { + os_error *error; + + /* we're objecting to the close down */ + message->your_ref = message->my_ref; + error = xwimp_send_message(wimp_USER_MESSAGE_ACKNOWLEDGE, + message, message->sender); + if (error) { + LOG("xwimp_send_message: 0x%x:%s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + } +} + + +/** + * Handle SaveDesktop message. + * + * \param message SaveDesktop message from Wimp. + */ +static void ro_msg_save_desktop(wimp_message *message) +{ + os_error *error; + + error = xosgbpb_writew(message->data.save_desktopw.file, + (const byte*)"Run ", 4, NULL); + if (!error) { + error = xosgbpb_writew(message->data.save_desktopw.file, + (const byte*)NETSURF_DIR, strlen(NETSURF_DIR), NULL); + if (!error) + error = xos_bputw('\n', message->data.save_desktopw.file); + } + + if (error) { + LOG("xosgbpb_writew/xos_bputw: 0x%x:%s", error->errnum, error->errmess); + ro_warn_user("SaveError", error->errmess); + + /* we must cancel the save by acknowledging the message */ + message->your_ref = message->my_ref; + error = xwimp_send_message(wimp_USER_MESSAGE_ACKNOWLEDGE, + message, message->sender); + if (error) { + LOG("xwimp_send_message: 0x%x:%s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + } +} + + +/** + * Handle WindowInfo message (part of the iconising protocol) + * + * \param message WindowInfo message from the Iconiser + */ +static void ro_msg_window_info(wimp_message *message) +{ + wimp_full_message_window_info *wi; + struct gui_window *g; + + /* allow the user to turn off thumbnail icons */ + if (!nsoption_bool(thumbnail_iconise)) + return; + + wi = (wimp_full_message_window_info*)message; + g = ro_gui_window_lookup(wi->w); + + /* ic_<task name> will suffice for our other windows */ + if (g) { + ro_gui_window_iconise(g, wi); + ro_gui_dialog_close_persistent(wi->w); + } +} + + +/** + * Get screen properties following a mode change. + */ +static void ro_gui_get_screen_properties(void) +{ + static const ns_os_vdu_var_list vars = { + os_MODEVAR_XWIND_LIMIT, + { + os_MODEVAR_YWIND_LIMIT, + os_MODEVAR_XEIG_FACTOR, + os_MODEVAR_YEIG_FACTOR, + os_VDUVAR_END_LIST + } + }; + os_error *error; + int vals[4]; + + error = xos_read_vdu_variables(PTR_OS_VDU_VAR_LIST(&vars), vals); + if (error) { + LOG("xos_read_vdu_variables: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MiscError", error->errmess); + return; + } + screen_info.width = (vals[0] + 1) << vals[2]; + screen_info.height = (vals[1] + 1) << vals[3]; +} + + +/** + * Warn the user if Inet$Resolvers is not set. + */ +static void ro_gui_check_resolvers(void) +{ + char *resolvers; + resolvers = getenv("Inet$Resolvers"); + if (resolvers && resolvers[0]) { + LOG("Inet$Resolvers '%s'", resolvers); + } else { + LOG("Inet$Resolvers not set or empty"); + ro_warn_user("Resolvers", 0); + } +} + + +/** + * Initialise the RISC OS specific GUI. + * + * \param argc The number of command line arguments. + * \param argv The string vector of command line arguments. + */ +static nserror gui_init(int argc, char** argv) +{ + struct { + void (*sigabrt)(int); + void (*sigfpe)(int); + void (*sigill)(int); + void (*sigint)(int); + void (*sigsegv)(int); + void (*sigterm)(int); + void (*sigoserror)(int); + } prev_sigs; + char path[40]; + os_error *error; + int length; + char *nsdir_temp; + byte *base; + nsurl *url; + nserror ret; + bool open_window; + + /* re-enable all FPU exceptions/traps except inexact operations, + * which we're not interested in, and underflow which is incorrectly + * raised when converting an exact value of 0 from double-precision + * to single-precision on FPEmulator v4.09-4.11 (MVFD F0,#0:MVFS F0,F0) + * - UnixLib disables all FP exceptions by default */ + + _FPU_SETCW(_FPU_IEEE & ~(_FPU_MASK_PM | _FPU_MASK_UM)); + + xhourglass_start(1); + + /* read OS version for code that adapts to conform to the OS + * (remember that it's preferable to check for specific features + * being present) */ + xos_byte(osbyte_IN_KEY, 0, 0xff, &os_version, NULL); + + /* the first release version of the A9home OS is incapable of + plotting patterned lines (presumably a fault in the hw acceleration) */ + if (!xosmodule_lookup("VideoHWSMI", NULL, NULL, &base, NULL, NULL)) { +#if 0 // this fault still hasn't been fixed, so disable patterned lines for all versions until it has + const char *help = (char*)base + ((int*)base)[5]; + while (*help > 9) help++; + while (*help == 9) help++; + if (!memcmp(help, "0.55", 4)) +#endif + ro_plot_patterned_lines = false; + } + + /* Create our choices directories */ + ro_gui_create_dirs(); + + /* Register exit and signal handlers */ + atexit(ro_gui_cleanup); + prev_sigs.sigabrt = signal(SIGABRT, ro_gui_signal); + prev_sigs.sigfpe = signal(SIGFPE, ro_gui_signal); + prev_sigs.sigill = signal(SIGILL, ro_gui_signal); + prev_sigs.sigint = signal(SIGINT, ro_gui_signal); + prev_sigs.sigsegv = signal(SIGSEGV, ro_gui_signal); + prev_sigs.sigterm = signal(SIGTERM, ro_gui_signal); + prev_sigs.sigoserror = signal(SIGOSERROR, ro_gui_signal); + + if (prev_sigs.sigabrt == SIG_ERR || prev_sigs.sigfpe == SIG_ERR || + prev_sigs.sigill == SIG_ERR || + prev_sigs.sigint == SIG_ERR || + prev_sigs.sigsegv == SIG_ERR || + prev_sigs.sigterm == SIG_ERR || + prev_sigs.sigoserror == SIG_ERR) + die("Failed registering signal handlers"); + + /* Load in UI sprites */ + gui_sprites = ro_gui_load_sprite_file("NetSurf:Resources.Sprites"); + if (!gui_sprites) + die("Unable to load Sprites."); + + /* Find NetSurf directory */ + nsdir_temp = getenv("NetSurf$Dir"); + if (!nsdir_temp) + die("Failed to locate NetSurf directory"); + NETSURF_DIR = strdup(nsdir_temp); + if (!NETSURF_DIR) + die("Failed duplicating NetSurf directory string"); + + /* Initialise filename allocator */ + filename_initialise(); + + /* Initialise save complete functionality */ + save_complete_init(); + + /* Load in visited URLs and Cookies */ + urldb_load(nsoption_charp(url_path)); + urldb_load_cookies(nsoption_charp(cookie_file)); + + /* Initialise with the wimp */ + error = xwimp_initialise(wimp_VERSION_RO38, task_name, + PTR_WIMP_MESSAGE_LIST(&task_messages), 0, + &task_handle); + if (error) { + LOG("xwimp_initialise: 0x%x: %s", error->errnum, error->errmess); + die(error->errmess); + } + /* Register message handlers */ + ro_message_register_route(message_HELP_REQUEST, + ro_gui_interactive_help_request); + ro_message_register_route(message_DATA_OPEN, + ro_msg_dataopen); + ro_message_register_route(message_DATA_SAVE, + ro_msg_datasave); + ro_message_register_route(message_DATA_SAVE_ACK, + ro_msg_datasave_ack); + ro_message_register_route(message_PRE_QUIT, + ro_msg_prequit); + ro_message_register_route(message_SAVE_DESKTOP, + ro_msg_save_desktop); + ro_message_register_route(message_DRAGGING, + ro_gui_selection_dragging); + ro_message_register_route(message_DRAG_CLAIM, + ro_gui_selection_drag_claim); + ro_message_register_route(message_WINDOW_INFO, + ro_msg_window_info); + + /* Initialise the font subsystem */ + nsfont_init(); + + /* Initialise global information */ + ro_gui_get_screen_properties(); + ro_gui_wimp_get_desktop_font(); + + /* Issue a *Desktop to poke AcornURI into life */ + if (getenv("NetSurf$Start_URI_Handler")) + xwimp_start_task("Desktop", 0); + + /* Open the templates */ + if ((length = snprintf(path, sizeof(path), + "NetSurf:Resources.%s.Templates", + nsoption_charp(language))) < 0 || length >= (int)sizeof(path)) + die("Failed to locate Templates resource."); + error = xwimp_open_template(path); + if (error) { + LOG("xwimp_open_template failed: 0x%x: %s", error->errnum, error->errmess); + die(error->errmess); + } + + ret = treeview_init(12); + if (ret != NSERROR_OK) { + die("Failed to initialise treeview"); + } + + /* Initialise themes before dialogs */ + ro_gui_theme_initialise(); + + /* Initialise dialog windows (must be after UI sprites are loaded) */ + ro_gui_dialog_init(); + + /* Initialise download window */ + ro_gui_download_init(); + + /* Initialise menus */ + ro_gui_menu_init(); + + /* Initialise query windows */ + ro_gui_query_init(); + + /* Initialise the history subsystem */ + ro_gui_history_init(); + + /* Initialise toolbars */ + ro_toolbar_init(); + + /* Initialise url bar module */ + ro_gui_url_bar_init(); + + /* Initialise browser windows */ + ro_gui_window_initialise(); + + /* Done with the templates file */ + wimp_close_template(); + + /* Create Iconbar icon and menus */ + ro_gui_iconbar_initialise(); + + /* Finally, check Inet$Resolvers for sanity */ + ro_gui_check_resolvers(); + + /* certificate verification window */ + ro_gui_cert_postinitialise(); + + /* hotlist window */ + ro_gui_hotlist_postinitialise(); + + /* global history window */ + ro_gui_global_history_postinitialise(); + + /* cookies window */ + ro_gui_cookies_postinitialise(); + + open_window = nsoption_bool(open_browser_at_startup); + + /* parse command-line arguments */ + if (argc == 2) { + LOG("parameters: '%s'", argv[1]); + /* this is needed for launching URI files */ + if (strcasecmp(argv[1], "-nowin") == 0) { + return NSERROR_OK; + } + ret = nsurl_create(NETSURF_HOMEPAGE, &url); + } + else if (argc == 3) { + LOG("parameters: '%s' '%s'", argv[1], argv[2]); + open_window = true; + + /* HTML files */ + if (strcasecmp(argv[1], "-html") == 0) { + ret = netsurf_path_to_nsurl(argv[2], &url); + } + /* URL files */ + else if (strcasecmp(argv[1], "-urlf") == 0) { + char *urlf = ro_gui_url_file_parse(argv[2]); + if (!urlf) { + LOG("allocation failed"); + die("Insufficient memory for URL"); + } + ret = nsurl_create(urlf, &url); + free(urlf); + } + /* ANT URL Load */ + else if (strcasecmp(argv[1], "-url") == 0) { + ret = nsurl_create(argv[2], &url); + } + /* Unknown => exit here. */ + else { + LOG("Unknown parameters: '%s' '%s'", argv[1], argv[2]); + return NSERROR_BAD_PARAMETER; + } + } + /* get user's homepage (if configured) */ + else if (nsoption_charp(homepage_url) && + nsoption_charp(homepage_url)[0]) { + ret = nsurl_create(nsoption_charp(homepage_url), &url); + } + /* default homepage */ + else { + ret = nsurl_create(NETSURF_HOMEPAGE, &url); + } + + /* check for url creation error */ + if (ret != NSERROR_OK) { + return ret; + } + + if (open_window) { + ret = browser_window_create(BW_CREATE_HISTORY, + url, + NULL, + NULL, + NULL); + } + nsurl_unref(url); + + return ret; +} + + +/** + * Determine the default language to use. + * + * RISC OS has no standard way of determining which language the user prefers. + * We have to guess from the 'Country' setting. + */ +const char *ro_gui_default_language(void) +{ + char path[40]; + const char *lang; + int country; + os_error *error; + + /* choose a language from the configured country number */ + error = xosbyte_read(osbyte_VAR_COUNTRY_NUMBER, &country); + if (error) { + LOG("xosbyte_read failed: 0x%x: %s", error->errnum, error->errmess); + country = 1; + } + switch (country) { + case 7: /* Germany */ + case 30: /* Austria */ + case 35: /* Switzerland (70% German-speaking) */ + lang = "de"; + break; + case 6: /* France */ + case 18: /* Canada2 (French Canada?) */ + lang = "fr"; + break; + case 34: /* Netherlands */ + lang = "nl"; + break; + default: + lang = "en"; + break; + } + sprintf(path, "NetSurf:Resources.%s", lang); + if (is_dir(path)) + return lang; + return "en"; +} + + +/** + * Create a nsurl from a RISC OS pathname. + * + * Perform the necessary operations on a path to generate a nsurl. + * + * @param[in] path The RISC OS pathname to convert. + * @param[out] url_out pointer to recive the nsurl, The returned url must be + * unreferenced by the caller. + * @return NSERROR_OK and the url is placed in \a url or error code on faliure. + */ +static nserror ro_path_to_nsurl(const char *path, struct nsurl **url_out) +{ + int spare; + char *canonical_path; /* canonicalised RISC OS path */ + char *unix_path; /* unix path */ + char *escurl; + os_error *error; + nserror ret; + int urllen; + char *url; /* resulting url */ + + /* calculate the canonical risc os path */ + error = xosfscontrol_canonicalise_path(path, 0, 0, 0, 0, &spare); + if (error) { + LOG("xosfscontrol_canonicalise_path failed: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("PathToURL", error->errmess); + return NSERROR_NOT_FOUND; + } + + canonical_path = malloc(1 - spare); + if (canonical_path == NULL) { + free(canonical_path); + return NSERROR_NOMEM; + } + + error = xosfscontrol_canonicalise_path(path, canonical_path, 0, 0, 1 - spare, 0); + if (error) { + LOG("xosfscontrol_canonicalise_path failed: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("PathToURL", error->errmess); + free(canonical_path); + return NSERROR_NOT_FOUND; + } + + /* create a unix path from the cananocal risc os one */ + unix_path = __unixify(canonical_path, __RISCOSIFY_NO_REVERSE_SUFFIX, NULL, 0, 0); + + if (unix_path == NULL) { + LOG("__unixify failed: %s", canonical_path); + free(canonical_path); + return NSERROR_BAD_PARAMETER; + } + free(canonical_path); + + /* convert the unix path into a url */ + urllen = strlen(unix_path) + FILE_SCHEME_PREFIX_LEN + 1; + url = malloc(urllen); + if (url == NULL) { + LOG("Unable to allocate url"); + free(unix_path); + return NSERROR_NOMEM; + } + + if (*unix_path == '/') { + snprintf(url, urllen, "%s%s", FILE_SCHEME_PREFIX, unix_path + 1); + } else { + snprintf(url, urllen, "%s%s", FILE_SCHEME_PREFIX, unix_path); + } + free(unix_path); + + /* We don't want '/' to be escaped. */ + ret = url_escape(url, FILE_SCHEME_PREFIX_LEN, false, "/", &escurl); + free(url); + if (ret != NSERROR_OK) { + return ret; + } + + ret = nsurl_create(escurl, url_out); + free(escurl); + + return ret; +} + + +/** + * Create a path from a nsurl using posix file handling. + * + * @param[in] url The url to encode. + * @param[out] path_out A string containing the result path which should + * be freed by the caller. + * @return NSERROR_OK and the path is written to \a path or error code + * on faliure. + */ +static nserror ro_nsurl_to_path(struct nsurl *url, char **path_out) +{ + lwc_string *urlpath; + char *unpath; + char *path; + bool match; + lwc_string *scheme; + nserror res; + char *r; + + if ((url == NULL) || (path_out == NULL)) { + return NSERROR_BAD_PARAMETER; + } + + scheme = nsurl_get_component(url, NSURL_SCHEME); + + if (lwc_string_caseless_isequal(scheme, corestring_lwc_file, + &match) != lwc_error_ok) + { + return NSERROR_BAD_PARAMETER; + } + lwc_string_unref(scheme); + if (match == false) { + return NSERROR_BAD_PARAMETER; + } + + urlpath = nsurl_get_component(url, NSURL_PATH); + if (urlpath == NULL) { + return NSERROR_BAD_PARAMETER; + } + + res = url_unescape(lwc_string_data(urlpath), &unpath); + lwc_string_unref(urlpath); + if (res != NSERROR_OK) { + return res; + } + + /* RISC OS path should not be more than 100 characters longer */ + path = malloc(strlen(unpath) + 100); + if (path == NULL) { + free(unpath); + return NSERROR_NOMEM; + } + + r = __riscosify(unpath, 0, __RISCOSIFY_NO_SUFFIX, + path, strlen(unpath) + 100, 0); + free(unpath); + if (r == NULL) { + free(path); + return NSERROR_NOMEM; + } + + *path_out = path; + + return NSERROR_OK; +} + + +/** + * Ensures output logging stream is correctly configured. + */ +static bool nslog_stream_configure(FILE *fptr) +{ + /* set log stream to be non-buffering */ + setbuf(fptr, NULL); + + return true; +} + + +/** + * Close down the gui (RISC OS). + */ +static void gui_quit(void) +{ + urldb_save_cookies(nsoption_charp(cookie_jar)); + urldb_save(nsoption_charp(url_save)); + ro_gui_window_quit(); + ro_gui_global_history_destroy(); + ro_gui_hotlist_destroy(); + ro_gui_cookies_destroy(); + ro_gui_saveas_quit(); + ro_gui_url_bar_fini(); + rufl_quit(); + free(gui_sprites); + xwimp_close_down(task_handle); + xhourglass_off(); +} + + +/** + * Handle Close_Window_Request events. + */ +static void ro_gui_close_window_request(wimp_close *close) +{ + if (ro_gui_alt_pressed()) + ro_gui_window_close_all(); + else { + if (ro_gui_wimp_event_close_window(close->w)) + return; + ro_gui_dialog_close(close->w); + } +} + + +/** + * Handle key press paste callback. + */ +static void ro_gui_keypress_cb(void *pw) +{ + wimp_key *key = (wimp_key *) pw; + + if (ro_gui_wimp_event_keypress(key) == false) { + os_error *error = xwimp_process_key(key->c); + if (error) { + LOG("xwimp_process_key: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + } + + free(key); +} + + +/** + * Handle gui keypress. + */ +static void ro_gui_keypress(wimp_key *key) +{ + if (key->c == wimp_KEY_ESCAPE && + (gui_current_drag_type == GUI_DRAG_SAVE || + gui_current_drag_type == GUI_DRAG_DOWNLOAD_SAVE)) { + + /* Allow Escape key to be used for cancelling a drag + * save (easier than finding somewhere safe to abort + * the drag) + */ + ro_gui_drag_box_cancel(); + gui_current_drag_type = GUI_DRAG_NONE; + } else if (key->c == 22 /* Ctrl-V */) { + wimp_key *copy; + + /* Must copy the keypress as it's on the stack */ + copy = malloc(sizeof(wimp_key)); + if (copy == NULL) + return; + memcpy(copy, key, sizeof(wimp_key)); + + ro_gui_selection_prepare_paste(key->w, ro_gui_keypress_cb, copy); + } else if (ro_gui_wimp_event_keypress(key) == false) { + os_error *error = xwimp_process_key(key->c); + if (error) { + LOG("xwimp_process_key: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + } +} + + +/** + * Handle the three User_Message events. + */ +static void ro_gui_user_message(wimp_event_no event, wimp_message *message) +{ + /* attempt automatic routing */ + if (ro_message_handle_message(event, message)) + return; + + switch (message->action) { + case message_DATA_LOAD: + ro_msg_terminate_filename((wimp_full_message_data_xfer*)message); + + if (event == wimp_USER_MESSAGE_ACKNOWLEDGE) { + if (ro_print_current_window) + ro_print_dataload_bounce(message); + } else if (ro_gui_selection_prepare_paste_dataload( + (wimp_full_message_data_xfer *) message) == false) { + ro_msg_dataload(message); + } + break; + + case message_DATA_LOAD_ACK: + if (ro_print_current_window) + ro_print_cleanup(); + break; + + case message_MENU_WARNING: + ro_gui_menu_warning((wimp_message_menu_warning *) + &message->data); + break; + + case message_MENUS_DELETED: + ro_gui_menu_message_deleted((wimp_message_menus_deleted *) + &message->data); + break; + + case message_CLAIM_ENTITY: + ro_gui_selection_claim_entity((wimp_full_message_claim_entity*)message); + break; + + case message_DATA_REQUEST: + ro_gui_selection_data_request((wimp_full_message_data_request*)message); + break; + + case message_MODE_CHANGE: + ro_gui_get_screen_properties(); + rufl_invalidate_cache(); + break; + + case message_PALETTE_CHANGE: + break; + + case message_FONT_CHANGED: + ro_gui_wimp_get_desktop_font(); + break; + + case message_URI_PROCESS: + if (event != wimp_USER_MESSAGE_ACKNOWLEDGE) + ro_uri_message_received(message); + break; + case message_URI_RETURN_RESULT: + ro_uri_bounce(message); + break; + case message_INET_SUITE_OPEN_URL: + if (event == wimp_USER_MESSAGE_ACKNOWLEDGE) { + ro_url_bounce(message); + } + else { + ro_url_message_received(message); + } + break; +#ifdef WITH_PLUGIN + case message_PLUG_IN_OPENING: + plugin_opening(message); + break; + case message_PLUG_IN_CLOSED: + plugin_closed(message); + break; + case message_PLUG_IN_RESHAPE_REQUEST: + plugin_reshape_request(message); + break; + case message_PLUG_IN_FOCUS: + break; + case message_PLUG_IN_URL_ACCESS: + plugin_url_access(message); + break; + case message_PLUG_IN_STATUS: + plugin_status(message); + break; + case message_PLUG_IN_BUSY: + break; + case message_PLUG_IN_STREAM_NEW: + plugin_stream_new(message); + break; + case message_PLUG_IN_STREAM_WRITE: + break; + case message_PLUG_IN_STREAM_WRITTEN: + plugin_stream_written(message); + break; + case message_PLUG_IN_STREAM_DESTROY: + break; + case message_PLUG_IN_OPEN: + if (event == wimp_USER_MESSAGE_ACKNOWLEDGE) + plugin_open_msg(message); + break; + case message_PLUG_IN_CLOSE: + if (event == wimp_USER_MESSAGE_ACKNOWLEDGE) + plugin_close_msg(message); + break; + case message_PLUG_IN_RESHAPE: + case message_PLUG_IN_STREAM_AS_FILE: + case message_PLUG_IN_NOTIFY: + case message_PLUG_IN_ABORT: + case message_PLUG_IN_ACTION: + break; +#endif + case message_PRINT_SAVE: + if (event == wimp_USER_MESSAGE_ACKNOWLEDGE) + ro_print_save_bounce(message); + break; + case message_PRINT_ERROR: + ro_print_error(message); + break; + case message_PRINT_TYPE_ODD: + ro_print_type_odd(message); + break; + case message_HOTLIST_CHANGED: + ro_gui_hotlist_add_cleanup(); + break; + case message_QUIT: + riscos_done = true; + break; + } +} + + +/** + * Process a Wimp_Poll event. + * + * \param event wimp event number + * \param block parameter block + */ +static void ro_gui_handle_event(wimp_event_no event, wimp_block *block) +{ + switch (event) { + case wimp_NULL_REASON_CODE: + ro_gui_throb(); + ro_mouse_poll(); + break; + + case wimp_REDRAW_WINDOW_REQUEST: + ro_gui_wimp_event_redraw_window(&block->redraw); + break; + + case wimp_OPEN_WINDOW_REQUEST: + ro_gui_open_window_request(&block->open); + break; + + case wimp_CLOSE_WINDOW_REQUEST: + ro_gui_close_window_request(&block->close); + break; + + case wimp_POINTER_LEAVING_WINDOW: + ro_mouse_pointer_leaving_window(&block->leaving); + break; + + case wimp_POINTER_ENTERING_WINDOW: + ro_gui_wimp_event_pointer_entering_window(&block->entering); + break; + + case wimp_MOUSE_CLICK: + ro_gui_wimp_event_mouse_click(&block->pointer); + break; + + case wimp_USER_DRAG_BOX: + ro_mouse_drag_end(&block->dragged); + break; + + case wimp_KEY_PRESSED: + ro_gui_keypress(&(block->key)); + break; + + case wimp_MENU_SELECTION: + ro_gui_menu_selection(&(block->selection)); + break; + + /* Scroll requests fall back to a generic handler because we + * might get these events for any window from a scroll-wheel. + */ + + case wimp_SCROLL_REQUEST: + if (!ro_gui_wimp_event_scroll_window(&(block->scroll))) + ro_gui_scroll(&(block->scroll)); + break; + + case wimp_USER_MESSAGE: + case wimp_USER_MESSAGE_RECORDED: + case wimp_USER_MESSAGE_ACKNOWLEDGE: + ro_gui_user_message(event, &(block->message)); + break; + } +} + + +/** + * Poll the RISC OS wimp for events. + */ +static void riscos_poll(void) +{ + wimp_event_no event; + wimp_block block; + const wimp_poll_flags mask = wimp_MASK_LOSE | wimp_MASK_GAIN | wimp_SAVE_FP; + os_t track_poll_offset; + + /* Poll wimp. */ + xhourglass_off(); + track_poll_offset = ro_mouse_poll_interval(); + if (sched_active || (track_poll_offset > 0)) { + os_t t = os_read_monotonic_time(); + + if (track_poll_offset > 0) { + t += track_poll_offset; + } else { + t += 10; + } + + if (sched_active && (sched_time - t) < 0) { + t = sched_time; + } + + event = wimp_poll_idle(mask, &block, t, 0); + } else { + event = wimp_poll(wimp_MASK_NULL | mask, &block, 0); + } + + xhourglass_on(); + gui_last_poll = clock(); + ro_gui_handle_event(event, &block); + + /* Only run scheduled callbacks on a null poll + * We cannot do this in the null event handler, as that may be called + * from gui_multitask(). Scheduled callbacks must only be run from the + * top-level. + */ + if (event == wimp_NULL_REASON_CODE) { + schedule_run(); + } + + ro_gui_window_update_boxes(); +} + + +/** + * Handle Open_Window_Request events. + */ +void ro_gui_open_window_request(wimp_open *open) +{ + os_error *error; + + if (ro_gui_wimp_event_open_window(open)) + return; + + error = xwimp_open_window(open); + if (error) { + LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } +} + + +/** + * source bounce callback. + */ +static void ro_gui_view_source_bounce(wimp_message *message) +{ + char *filename; + os_error *error; + char command[256]; + + /* run the file as text */ + filename = ((wimp_full_message_data_xfer *)message)->file_name; + sprintf(command, "@RunType_FFF %s", filename); + error = xwimp_start_task(command, 0); + if (error) { + LOG("xwimp_start_task failed: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } +} + + +/** + * Send the source of a content to a text editor. + */ +void ro_gui_view_source(hlcache_handle *c) +{ + os_error *error; + char *temp_name; + wimp_full_message_data_xfer message; + int objtype; + bool done = false; + + const char *source_data; + unsigned long source_size; + + if (!c) { + ro_warn_user("MiscError", "No document source"); + return; + } + + source_data = content_get_source_data(c, &source_size); + + if (!source_data) { + ro_warn_user("MiscError", "No document source"); + return; + } + + /* try to load local files directly. */ + if (netsurf_nsurl_to_path(hlcache_handle_get_url(c), &temp_name) == NSERROR_OK) { + error = xosfile_read_no_path(temp_name, &objtype, 0, 0, 0, 0); + if ((!error) && (objtype == osfile_IS_FILE)) { + snprintf(message.file_name, 212, "%s", temp_name); + message.file_name[211] = '\0'; + done = true; + } + free(temp_name); + } + if (!done) { + /* We cannot release the requested filename until after it + * has finished being used. As we can't easily find out when + * this is, we simply don't bother releasing it and simply + * allow it to be re-used next time NetSurf is started. The + * memory overhead from doing this is under 1 byte per + * filename. */ + char *r; + char full_name[256]; + const char *filename = filename_request(); + if (!filename) { + ro_warn_user("NoMemory", 0); + return; + } + + snprintf(full_name, 256, "%s/%s", TEMP_FILENAME_PREFIX, + filename); + full_name[255] = '\0'; + r = __riscosify(full_name, 0, __RISCOSIFY_NO_SUFFIX, + message.file_name, 212, 0); + if (r == 0) { + LOG("__riscosify failed"); + return; + } + message.file_name[211] = '\0'; + + error = xosfile_save_stamped(message.file_name, + ro_content_filetype(c), + (byte *) source_data, + (byte *) source_data + source_size); + if (error) { + LOG("xosfile_save_stamped failed: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MiscError", error->errmess); + return; + } + } + + /* begin the DataOpen protocol */ + message.your_ref = 0; + message.size = 44 + ((strlen(message.file_name) + 4) & (~3u)); + message.action = message_DATA_OPEN; + message.w = 0; + message.i = 0; + message.pos.x = 0; + message.pos.y = 0; + message.est_size = 0; + message.file_type = 0xfff; + ro_message_send_message(wimp_USER_MESSAGE_RECORDED, + (wimp_message*)&message, 0, + ro_gui_view_source_bounce); +} + + +/** + * Broadcast an URL that we can't handle. + */ +static nserror gui_launch_url(struct nsurl *url) +{ + /* Try ant broadcast */ + ro_url_broadcast(nsurl_access(url)); + return NSERROR_OK; +} + + +/** + * Choose the language to use. + */ +static void ro_gui_choose_language(void) +{ + /* if option_language exists and is valid, use that */ + if (nsoption_charp(language)) { + char path[40]; + if (2 < strlen(nsoption_charp(language))) + nsoption_charp(language)[2] = 0; + sprintf(path, "NetSurf:Resources.%s", nsoption_charp(language)); + + if (is_dir(path)) { + nsoption_setnull_charp(accept_language, + strdup(nsoption_charp(language))); + return; + } + nsoption_set_charp(language, NULL); + } + + nsoption_set_charp(language, strdup(ro_gui_default_language())); + if (nsoption_charp(language) == NULL) + die("Out of memory"); + nsoption_set_charp(accept_language, strdup(nsoption_charp(language))); + if (nsoption_charp(accept_language) == NULL) + die("Out of memory"); +} + + +/** + * Display a warning for a serious problem (eg memory exhaustion). + * + * \param warning message key for warning message + * \param detail additional message, or 0 + */ +nserror ro_warn_user(const char *warning, const char *detail) +{ + LOG("%s %s", warning, detail); + + if (dialog_warning) { + char warn_buffer[300]; + snprintf(warn_buffer, sizeof warn_buffer, "%s %s", + messages_get(warning), + detail ? detail : ""); + warn_buffer[sizeof warn_buffer - 1] = 0; + ro_gui_set_icon_string(dialog_warning, ICON_WARNING_MESSAGE, + warn_buffer, true); + xwimp_set_icon_state(dialog_warning, ICON_WARNING_HELP, + wimp_ICON_DELETED, wimp_ICON_DELETED); + ro_gui_dialog_open(dialog_warning); + xos_bell(); + } else { + /* probably haven't initialised (properly), use a + non-multitasking error box */ + os_error error; + snprintf(error.errmess, sizeof error.errmess, "%s %s", + messages_get(warning), + detail ? detail : ""); + error.errmess[sizeof error.errmess - 1] = 0; + xwimp_report_error_by_category(&error, + wimp_ERROR_BOX_OK_ICON | + wimp_ERROR_BOX_GIVEN_CATEGORY | + wimp_ERROR_BOX_CATEGORY_ERROR << + wimp_ERROR_BOX_CATEGORY_SHIFT, + "NetSurf", "!netsurf", + (osspriteop_area *) 1, 0, 0); + } + + return NSERROR_OK; +} + + +/** + * Display an error and exit. + * + * Should only be used during initialisation. + */ +void die(const char * const error) +{ + os_error warn_error; + + LOG("%s", error); + + warn_error.errnum = 1; /* \todo: reasonable ? */ + strncpy(warn_error.errmess, messages_get(error), + sizeof(warn_error.errmess)-1); + warn_error.errmess[sizeof(warn_error.errmess)-1] = '\0'; + xwimp_report_error_by_category(&warn_error, + wimp_ERROR_BOX_OK_ICON | + wimp_ERROR_BOX_GIVEN_CATEGORY | + wimp_ERROR_BOX_CATEGORY_ERROR << + wimp_ERROR_BOX_CATEGORY_SHIFT, + "NetSurf", "!netsurf", + (osspriteop_area *) 1, 0, 0); + exit(EXIT_FAILURE); +} + + +/** + * Test whether it's okay to shutdown, prompting the user if not. + * + * \return true iff it's okay to shutdown immediately + */ +bool ro_gui_prequit(void) +{ + return ro_gui_download_prequit(); +} + + +/** + * Generate a riscos path from one or more component elemnts. + * + * Constructs a complete path element from passed components. The + * second (and subsequent) components have a slash substituted for all + * riscos directory separators. + * + * If a string is allocated it must be freed by the caller. + * + * @param[in,out] str pointer to string pointer if this is NULL enough + * storage will be allocated for the complete path. + * @param[in,out] size The size of the space available if \a str not + * NULL on input and if not NULL set to the total + * output length on output. + * @param[in] nelm The number of elements. + * @param[in] ap The elements of the path as string pointers. + * @return NSERROR_OK and the complete path is written to str + * or error code on faliure. + */ +static nserror riscos_mkpath(char **str, size_t *size, size_t nelm, va_list ap) +{ + const char *elm[16]; + size_t elm_len[16]; + size_t elm_idx; + char *fname; + size_t fname_len = 0; + char *curp; + size_t idx; + + /* check the parameters are all sensible */ + if ((nelm == 0) || (nelm > 16)) { + return NSERROR_BAD_PARAMETER; + } + if ((*str != NULL) && (size == NULL)) { + /* if the caller is providing the buffer they must say + * how much space is available. + */ + return NSERROR_BAD_PARAMETER; + } + + /* calculate how much storage we need for the complete path + * with all the elements. + */ + for (elm_idx = 0; elm_idx < nelm; elm_idx++) { + elm[elm_idx] = va_arg(ap, const char *); + /* check the argument is not NULL */ + if (elm[elm_idx] == NULL) { + return NSERROR_BAD_PARAMETER; + } + elm_len[elm_idx] = strlen(elm[elm_idx]); + fname_len += elm_len[elm_idx]; + } + fname_len += nelm; /* allow for separators and terminator */ + + /* ensure there is enough space */ + fname = *str; + if (fname != NULL) { + if (fname_len > *size) { + return NSERROR_NOSPACE; + } + } else { + fname = malloc(fname_len); + if (fname == NULL) { + return NSERROR_NOMEM; + } + } + + /* copy the elements in with directory separator */ + curp = fname; + + /* first element is not altered */ + memmove(curp, elm[0], elm_len[0]); + curp += elm_len[0]; + /* ensure there is a delimiter */ + if (curp[-1] != DIR_SEP) { + *curp = DIR_SEP; + curp++; + } + + /* subsequent elemnts have slashes substituted with directory + * separators. + */ + for (elm_idx = 1; elm_idx < nelm; elm_idx++) { + for (idx = 0; idx < elm_len[elm_idx]; idx++) { + if (elm[elm_idx][idx] == DIR_SEP) { + *curp = '/'; + } else { + *curp = elm[elm_idx][idx]; + } + curp++; + } + *curp = DIR_SEP; + curp++; + } + curp[-1] = 0; /* NULL terminate */ + + assert((curp - fname) <= (int)fname_len); + + *str = fname; + if (size != NULL) { + *size = fname_len; + } + + return NSERROR_OK; + +} + + +/** + * Get the basename of a file using posix path handling. + * + * This gets the last element of a path and returns it. The returned + * element has all forward slashes translated into riscos directory + * separators. + * + * @param[in] path The path to extract the name from. + * @param[in,out] str Pointer to string pointer if this is NULL enough + * storage will be allocated for the path element. + * @param[in,out] size The size of the space available if \a + * str not NULL on input and set to the total + * output length on output. + * @return NSERROR_OK and the complete path is written to str + * or error code on faliure. + */ +static nserror riscos_basename(const char *path, char **str, size_t *size) +{ + const char *leafname; + char *fname; + char *temp; + + if (path == NULL) { + return NSERROR_BAD_PARAMETER; + } + + leafname = strrchr(path, DIR_SEP); + if (!leafname) { + leafname = path; + } else { + leafname += 1; + } + + fname = strdup(leafname); + if (fname == NULL) { + return NSERROR_NOMEM; + } + + /** @todo check this leafname translation is actually required */ + /* and s/\//\./g */ + for (temp = fname; *temp != 0; temp++) { + if (*temp == '/') { + *temp = DIR_SEP; + } + } + + *str = fname; + if (size != NULL) { + *size = strlen(fname); + } + return NSERROR_OK; +} + + +/** + * Ensure that all directory elements needed to store a filename exist. + * + * Given a path of x.y.z directories x and x.y will be created. + * + * @param fname The filename to ensure the path to exists. + * @return NSERROR_OK on success or error code on failure. + */ +static nserror riscos_mkdir_all(const char *fname) +{ + char *dname; + char *cur; + + dname = strdup(fname); + + cur = dname; + while ((cur = strchr(cur, '.'))) { + *cur = '\0'; + xosfile_create_dir(dname, 0); + *cur++ = '.'; + } + + free(dname); + + return NSERROR_OK; +} + +/** + * Find screen size in OS units. + */ +void ro_gui_screen_size(int *width, int *height) +{ + *width = screen_info.width; + *height = screen_info.height; +} + + +/** + * Send the debug dump of a content to a text editor. + */ +void ro_gui_dump_browser_window(struct browser_window *bw) +{ + os_error *error; + + /* open file for dump */ + FILE *stream = fopen("<Wimp$ScrapDir>.WWW.NetSurf.dump", "w"); + if (!stream) { + LOG("fopen: errno %i", errno); + ro_warn_user("SaveError", strerror(errno)); + return; + } + + browser_window_debug_dump(bw, stream, CONTENT_DEBUG_RENDER); + + fclose(stream); + + /* launch file in editor */ + error = xwimp_start_task("Filer_Run <Wimp$ScrapDir>.WWW.NetSurf.dump", + 0); + if (error) { + LOG("xwimp_start_task failed: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } +} + + +static struct gui_file_table riscos_file_table = { + .mkpath = riscos_mkpath, + .basename = riscos_basename, + .nsurl_to_path = ro_nsurl_to_path, + .path_to_nsurl = ro_path_to_nsurl, + .mkdir_all = riscos_mkdir_all, +}; + +static struct gui_fetch_table riscos_fetch_table = { + .filetype = fetch_filetype, + + .get_resource_url = gui_get_resource_url, + .mimetype = fetch_mimetype, +}; + +static struct gui_misc_table riscos_misc_table = { + .schedule = riscos_schedule, + .warning = ro_warn_user, + + .quit = gui_quit, + .launch_url = gui_launch_url, + .cert_verify = gui_cert_verify, + .login = gui_401login_open, +}; + + +static char *get_cachepath(void) +{ + char *cachedir; + char *cachepath = NULL; + nserror ret; + + cachedir = getenv("Cache$Dir"); + if ((cachedir == NULL) || (cachedir[0] == 0)) { + LOG("cachedir was null"); + return NULL; + } + ret = netsurf_mkpath(&cachepath, NULL, 2, cachedir, "NetSurf"); + if (ret != NSERROR_OK) { + return NULL; + } + return cachepath; +} + +/** + * Normal entry point from RISC OS. + */ +int main(int argc, char** argv) +{ + char *cachepath; + char path[40]; + int length; + os_var_type type; + int used = -1; /* slightly better with older OSLib versions */ + os_error *error; + nserror ret; + struct netsurf_table riscos_table = { + .misc = &riscos_misc_table, + .window = riscos_window_table, + .clipboard = riscos_clipboard_table, + .download = riscos_download_table, + .fetch = &riscos_fetch_table, + .file = &riscos_file_table, + .utf8 = riscos_utf8_table, + .search = riscos_search_table, + .llcache = filesystem_llcache_table, + .bitmap = riscos_bitmap_table, + .layout = riscos_layout_table, + }; + + ret = netsurf_register(&riscos_table); + if (ret != NSERROR_OK) { + die("NetSurf operation table failed registration"); + } + + /* Consult NetSurf$Logging environment variable to decide if logging + * is required. */ + error = xos_read_var_val_size("NetSurf$Logging", 0, os_VARTYPE_STRING, + &used, NULL, &type); + if (error != NULL || type != os_VARTYPE_STRING || used != -2) { + verbose_log = true; + } else { + char logging_env[2]; + error = xos_read_var_val("NetSurf$Logging", logging_env, + sizeof(logging_env), 0, os_VARTYPE_STRING, + &used, NULL, &type); + if (error != NULL || logging_env[0] != '0') { + verbose_log = true; + } else { + verbose_log = false; + } + } + + /* initialise logging. Not fatal if it fails but not much we + * can do about it either. + */ + nslog_init(nslog_stream_configure, &argc, argv); + + /* user options setup */ + ret = nsoption_init(set_defaults, &nsoptions, &nsoptions_default); + if (ret != NSERROR_OK) { + die("Options failed to initialise"); + } + nsoption_read("NetSurf:Choices", NULL); + nsoption_commandline(&argc, argv, NULL); + + /* Choose the interface language to use */ + ro_gui_choose_language(); + + /* select language-specific Messages */ + if (((length = snprintf(path, + sizeof(path), + "NetSurf:Resources.%s.Messages", + nsoption_charp(language))) < 0) || + (length >= (int)sizeof(path))) { + die("Failed to locate Messages resource."); + } + + /* initialise messages */ + messages_add_from_file(path); + + /* obtain cache path */ + cachepath = get_cachepath(); + + /* common initialisation */ + ret = netsurf_init(cachepath); + free(cachepath); + if (ret != NSERROR_OK) { + die("NetSurf failed to initialise core"); + } + + artworks_init(); + draw_init(); + sprite_init(); + + /* Load some extra RISC OS specific Messages */ + messages_add_from_file("NetSurf:Resources.LangNames"); + + ret = gui_init(argc, argv); + if (ret != NSERROR_OK) { + ro_warn_user(messages_get_errorcode(ret), 0); + } + + while (!riscos_done) { + riscos_poll(); + } + + netsurf_exit(); + + return 0; +} diff --git a/frontends/riscos/gui.h b/frontends/riscos/gui.h new file mode 100644 index 000000000..624f9e2fb --- /dev/null +++ b/frontends/riscos/gui.h @@ -0,0 +1,271 @@ +/* + * Copyright 2003 Phil Mellor <monkeyson@users.sourceforge.net> + * Copyright 2004 James Bursa <bursa@users.sourceforge.net> + * Copyright 2004 Andrew Timmins <atimmins@blueyonder.co.uk> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _NETSURF_RISCOS_GUI_H_ +#define _NETSURF_RISCOS_GUI_H_ + +#include <oslib/wimp.h> + +#define RISCOS5 0xAA + +#define THUMBNAIL_WIDTH 100 +#define THUMBNAIL_HEIGHT 86 + +/* The maximum size for user-editable URLs in the RISC OS GUI. */ + +#define RO_GUI_MAX_URL_SIZE 2048 + +extern int os_version; + +extern const char * NETSURF_DIR; + +struct toolbar; +struct status_bar; +struct plotter_table; +struct gui_window; +struct tree; +struct node; +struct history; +struct css_style; +struct ssl_cert_info; +struct nsurl; +struct hlcache_handle; + +enum gui_pointer_shape; + +extern wimp_t task_handle; /**< RISC OS wimp task handle. */ + +extern wimp_w dialog_info, dialog_saveas, dialog_zoom, dialog_pageinfo, + dialog_objinfo, dialog_tooltip, dialog_warning, dialog_openurl, + dialog_folder, dialog_entry, dialog_url_complete, + dialog_search, dialog_print, dialog_theme_install; +extern wimp_w current_menu_window; +extern bool current_menu_open; +extern wimp_menu *recent_search_menu; /* search.c */ +extern wimp_w history_window; +extern bool gui_redraw_debug; +extern osspriteop_area *gui_sprites; +extern bool dialog_folder_add, dialog_entry_add, hotlist_insert; +extern bool print_active, print_text_black; +extern bool no_font_blending; + +typedef enum { GUI_DRAG_NONE, GUI_DRAG_DOWNLOAD_SAVE, GUI_DRAG_SAVE } + ro_gui_drag_type; + +extern ro_gui_drag_type gui_current_drag_type; + +extern bool riscos_done; + +/** RISC OS data for a browser window. */ +struct gui_window { + /** Associated platform-independent browser window data. */ + struct browser_window *bw; + + struct toolbar *toolbar; /**< Toolbar, or 0 if not present. */ + struct status_bar *status_bar; /**< Status bar, or 0 if not present. */ + + wimp_w window; /**< RISC OS window handle. */ + + int old_width; /**< Width when last opened / os units. */ + int old_height; /**< Height when last opened / os units. */ + bool update_extent; /**< Update the extent on next opening */ + bool active; /**< Whether the throbber should be active */ + + char title[256]; /**< Buffer for window title. */ + + int iconise_icon; /**< ID number of icon when window is iconised */ + + char validation[12]; /**< Validation string for colours */ + + float scale; /**< Browser window scale */ + + /** Options. */ + struct { + bool buffer_animations; /**< Use screen buffering for animations. */ + bool buffer_everything; /**< Use screen buffering for everything. */ + } option; + + struct gui_window *prev; /**< Previous in linked list. */ + struct gui_window *next; /**< Next in linked list. */ +}; + + +extern struct gui_window *ro_gui_current_redraw_gui; + + +/* in gui.c */ +void ro_gui_open_window_request(wimp_open *open); +void ro_gui_screen_size(int *width, int *height); +void ro_gui_view_source(struct hlcache_handle *c); +void ro_gui_dump_browser_window(struct browser_window *bw); +void ro_gui_drag_box_start(wimp_pointer *pointer); +bool ro_gui_prequit(void); +const char *ro_gui_default_language(void); +nserror ro_warn_user(const char *warning, const char *detail); + +/** + * Cause an abnormal program termination. + * + * \note This never returns and is intended to terminate without any cleanup. + * + * \param error The message to display to the user. + */ +void die(const char * const error) __attribute__ ((noreturn)); + +/* in download.c */ +void ro_gui_download_init(void); +void ro_gui_download_datasave_ack(wimp_message *message); +bool ro_gui_download_prequit(void); +extern struct gui_download_table *riscos_download_table; + +/* in 401login.c */ +void ro_gui_401login_init(void); +void gui_401login_open(struct nsurl *url, const char *realm, + nserror (*cb)(bool proceed, void *pw), void *cbpw); + +/* in window.c */ +void ro_gui_window_set_scale(struct gui_window *g, float scale); +bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message); +void ro_gui_window_mouse_at(wimp_pointer *pointer, void *data); +void ro_gui_window_iconise(struct gui_window *g, + wimp_full_message_window_info *wi); +bool ro_gui_toolbar_dataload(struct gui_window *g, wimp_message *message); +void ro_gui_window_redraw_all(void); +void ro_gui_window_update_boxes(void); +void ro_gui_window_quit(void); +/* void ro_gui_window_close_all(void); */ +#define ro_gui_window_close_all ro_gui_window_quit /* no need for a separate fn */ +void ro_gui_throb(void); +void ro_gui_window_default_options(struct gui_window *gui); +struct gui_window *ro_gui_window_lookup(wimp_w window); +struct gui_window *ro_gui_toolbar_lookup(wimp_w window); +bool ro_gui_window_to_window_pos(struct gui_window *g, int x, int y, + os_coord *pos); +bool ro_gui_window_to_screen_pos(struct gui_window *g, int x, int y, + os_coord *pos); +enum browser_mouse_state ro_gui_mouse_click_state(wimp_mouse_state buttons, + wimp_icon_flags type); +enum browser_mouse_state ro_gui_mouse_drag_state(wimp_mouse_state buttons, + wimp_icon_flags type); +bool ro_gui_shift_pressed(void); +bool ro_gui_ctrl_pressed(void); +bool ro_gui_alt_pressed(void); +void gui_window_set_pointer(struct gui_window *g, enum gui_pointer_shape shape); + +/* in history.c */ +void ro_gui_history_init(void); +void ro_gui_history_open(struct gui_window *g, bool pointer); + +/* in schedule.c */ +extern bool sched_active; +extern os_t sched_time; + +/** + * Process events up to current time. + */ +bool schedule_run(void); + +/** + * Schedule a callback. + * + * \param t interval before the callback should be made in ms + * \param callback callback function + * \param p user parameter, passed to callback function + * + * The callback function will be called as soon as possible after t ms have + * passed. + */ +nserror riscos_schedule(int t, void (*callback)(void *p), void *p); + +/* in search.c */ +void ro_gui_search_init(void); +void ro_gui_search_prepare(struct browser_window *g); +struct gui_search_table *riscos_search_table; + +/* in print.c */ +void ro_gui_print_init(void); +void ro_gui_print_prepare(struct gui_window *g); + +/* in plotters.c */ +extern const struct plotter_table ro_plotters; +extern int ro_plot_origin_x; +extern int ro_plot_origin_y; + +/* in theme_install.c */ +bool ro_gui_theme_install_apply(wimp_w w); + +/* in sslcert.c */ +void gui_cert_verify(struct nsurl *url, + const struct ssl_cert_info *certs, unsigned long num, + nserror (*cb)(bool proceed, void *pw), void *cbpw); + +/* icon numbers */ +#define ICON_STATUS_RESIZE 0 +#define ICON_STATUS_TEXT 1 + +#define ICON_SAVE_ICON 0 +#define ICON_SAVE_PATH 1 +#define ICON_SAVE_OK 2 +#define ICON_SAVE_CANCEL 3 + +#define ICON_PAGEINFO_TITLE 0 +#define ICON_PAGEINFO_URL 1 +#define ICON_PAGEINFO_ENC 2 +#define ICON_PAGEINFO_TYPE 3 +#define ICON_PAGEINFO_ICON 4 + +#define ICON_OBJINFO_URL 0 +#define ICON_OBJINFO_TARGET 1 +#define ICON_OBJINFO_TYPE 2 +#define ICON_OBJINFO_ICON 3 + +#define ICON_WARNING_MESSAGE 0 +#define ICON_WARNING_CONTINUE 1 +#define ICON_WARNING_HELP 2 + +#define ICON_SEARCH_TEXT 0 +#define ICON_SEARCH_CASE_SENSITIVE 1 +#define ICON_SEARCH_FIND_NEXT 2 +#define ICON_SEARCH_FIND_PREV 3 +#define ICON_SEARCH_CANCEL 4 +#define ICON_SEARCH_STATUS 5 +#define ICON_SEARCH_MENU 8 +#define ICON_SEARCH_SHOW_ALL 9 + +#define ICON_THEME_INSTALL_MESSAGE 0 +#define ICON_THEME_INSTALL_INSTALL 1 +#define ICON_THEME_INSTALL_CANCEL 2 + +#define ICON_OPENURL_URL 1 +#define ICON_OPENURL_CANCEL 2 +#define ICON_OPENURL_OPEN 3 +#define ICON_OPENURL_MENU 4 + +#define ICON_ENTRY_NAME 1 +#define ICON_ENTRY_URL 3 +#define ICON_ENTRY_CANCEL 4 +#define ICON_ENTRY_OK 5 +#define ICON_ENTRY_RECENT 6 + +#define ICON_FOLDER_NAME 1 +#define ICON_FOLDER_CANCEL 2 +#define ICON_FOLDER_OK 3 + +#endif diff --git a/frontends/riscos/gui/button_bar.c b/frontends/riscos/gui/button_bar.c new file mode 100644 index 000000000..6ecd7cffa --- /dev/null +++ b/frontends/riscos/gui/button_bar.c @@ -0,0 +1,1229 @@ +/* + * Copyright 2004, 2005 Richard Wilson <info@tinct.net> + * Copyright 2011 Stephen Fryatt <stevef@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Button bars (implementation). + */ + +#include <assert.h> +#include <stdio.h> +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> +#include <oslib/dragasprite.h> +#include <oslib/os.h> +#include <oslib/osspriteop.h> +#include <oslib/wimp.h> +#include <oslib/wimpspriteop.h> + +#include "utils/log.h" + +#include "riscos/gui/button_bar.h" +#include "riscos/gui.h" +#include "riscos/mouse.h" +#include "riscos/theme.h" +#include "riscos/wimp.h" + +#define BUTTONBAR_SPRITE_NAME_LENGTH 12 +#define BUTTONBAR_VALIDATION_LENGTH 40 + +struct button_bar_button { + wimp_i icon; + bool shaded; + bool separator; + + button_bar_action select_action; + button_bar_action adjust_action; + + int x_pos, y_pos; + int x_size, y_size; + + char sprite[BUTTONBAR_SPRITE_NAME_LENGTH]; + char validation[BUTTONBAR_VALIDATION_LENGTH]; + char opt_key; + const char *help_suffix; + + struct button_bar_button *bar_next; + struct button_bar_button *next; +}; + + +struct button_bar { + /** The applied theme (or NULL to use the default) */ + struct theme_descriptor *theme; + + /** The widget dimensions. */ + int x_min, y_min; + int separator_width; + int vertical_offset; + + bool separators; + + /** The window details and bar position. */ + wimp_w window; + os_box extent; + osspriteop_area *sprites; + int background; + + bool hidden; + + bool edit; + struct button_bar *edit_target; + struct button_bar *edit_source; + void (*edit_refresh)(void *); + void *edit_client_data; + + /** The list of all the defined buttons. */ + + struct button_bar_button *buttons; + + /** The list of the buttons in the current bar. */ + + struct button_bar_button *bar; +}; + +static char null_text_string[] = ""; +static char separator_name[] = "separator"; + +static struct button_bar *drag_start = NULL; +static char drag_opt = '\0'; +static bool drag_separator = false; + +/* + * Private function prototypes. + */ + +static bool ro_gui_button_bar_place_buttons(struct button_bar *button_bar); +static bool ro_gui_button_bar_icon_update(struct button_bar *button_bar); +static bool ro_gui_button_bar_icon_resize(struct button_bar *button_bar); +static void ro_gui_button_bar_drag_end(wimp_dragged *drag, void *data); +static void ro_gui_button_bar_sync_editors(struct button_bar *target, + struct button_bar *source); +static struct button_bar_button *ro_gui_button_bar_find_icon( + struct button_bar *button_bar, wimp_i icon); +static struct button_bar_button *ro_gui_button_bar_find_opt_key( + struct button_bar *button_bar, char opt_key); +static struct button_bar_button *ro_gui_button_bar_find_action( + struct button_bar *button_bar, button_bar_action action); +static struct button_bar_button *ro_gui_button_bar_find_coords( + struct button_bar *button_bar, os_coord pos, + bool *separator, bool *right); + +/* This is an exported interface documented in button_bar.h */ + +struct button_bar *ro_gui_button_bar_create(struct theme_descriptor *theme, + const struct button_bar_buttons buttons[]) +{ + struct button_bar *button_bar; + struct button_bar_button *icon, *new_icon; + int def; + + /* Allocate memory. */ + + button_bar = malloc(sizeof(struct button_bar)); + if (button_bar == NULL) { + LOG("No memory for malloc()"); + return NULL; + } + + /* Set up default parameters. */ + + button_bar->theme = theme; + button_bar->sprites = ro_gui_theme_get_sprites(theme); + button_bar->background = wimp_COLOUR_VERY_LIGHT_GREY; + + button_bar->x_min = -1; + button_bar->y_min = -1; + button_bar->separator_width = 0; + button_bar->vertical_offset = 0; + + button_bar->separators = false; + + button_bar->window = NULL; + + button_bar->hidden = false; + + button_bar->edit = false; + button_bar->edit_target = NULL; + button_bar->edit_source = NULL; + button_bar->edit_refresh = NULL; + button_bar->edit_client_data = NULL; + + button_bar->buttons = NULL; + + /* Process the button icon definitions */ + + icon = NULL; + + for (def = 0; buttons[def].icon != NULL; def++) { + new_icon = malloc(sizeof(struct button_bar_button)); + if (new_icon == NULL) { + break; + } + + if (icon == NULL) { + button_bar->buttons = new_icon; + button_bar->bar = new_icon; + } else { + icon->next = new_icon; + icon->bar_next = new_icon; + } + icon = new_icon; + icon->next = NULL; + icon->bar_next = NULL; + + strncpy(icon->sprite, buttons[def].icon, + BUTTONBAR_SPRITE_NAME_LENGTH); + snprintf(icon->validation, BUTTONBAR_VALIDATION_LENGTH, + "R5;S%s,p%s", icon->sprite, icon->sprite); + + icon->icon = -1; + icon->shaded = false; + icon->separator = false; + + icon->select_action = buttons[def].select; + icon->adjust_action = buttons[def].adjust; + icon->opt_key = buttons[def].opt_key; + icon->help_suffix = buttons[def].help; + } + + /* Add a separator after the last entry. This will be lost if the + * buttons are subsequently set, but is used for the edit source bar. + */ + + if (icon != NULL) + icon->separator = true; + + return button_bar; +} + + +/* This is an exported interface documented in button_bar.h */ + +bool ro_gui_button_bar_link_editor(struct button_bar *target, + struct button_bar *source, void (* refresh)(void *), + void *client_data) +{ + if (target == NULL || source == NULL || + target->edit_target != NULL || + target->edit_source != NULL || + source->edit_target != NULL || + source->edit_source != NULL) + return false; + + target->edit_source = source; + source->edit_target = target; + + /* Store the callback data in the editor bar. */ + + source->edit_refresh = refresh; + source->edit_client_data = client_data; + + return true; +} + + +/* This is an exported interface documented in button_bar.h */ + +bool ro_gui_button_bar_rebuild(struct button_bar *button_bar, + struct theme_descriptor *theme, theme_style style, + wimp_w window, bool edit) +{ + struct button_bar_button *button; + int height; + + + if (button_bar == NULL) + return false; + + button_bar->theme = theme; + button_bar->window = window; + button_bar->sprites = ro_gui_theme_get_sprites(theme); + button_bar->background = ro_gui_theme_get_style_element(theme, style, + THEME_ELEMENT_BACKGROUND); + + button_bar->edit = edit; + + height = 0; + button_bar->separator_width = 16; + ro_gui_wimp_get_sprite_dimensions(button_bar->sprites, separator_name, + &button_bar->separator_width, &height); + + /* If the separator height is 0, then either the sprite really is + * zero pixels high or the default was used as no sprite was found. + * Either way, we don't have a separator. + */ + + button_bar->separators = (height == 0) ? false : true; + + button = button_bar->buttons; + + while (button != NULL) { + button->x_size = 0; + button->y_size = 0; + button->icon = -1; + + ro_gui_wimp_get_sprite_dimensions(button_bar->sprites, + button->sprite, + &button->x_size, &button->y_size); + + button = button->next; + } + + if (!ro_gui_button_bar_place_buttons(button_bar)) + return false; + + if (button_bar->edit && button_bar->edit_target != NULL) + ro_gui_button_bar_sync_editors(button_bar->edit_target, + button_bar); + + return ro_gui_button_bar_icon_update(button_bar); +} + + +/* This is an exported interface documented in button_bar.h */ + +bool ro_gui_button_bar_arrange_buttons(struct button_bar *button_bar, + char order[]) +{ + struct button_bar_button *button, *new; + int i; + + if (button_bar == NULL || order == NULL) + return false; + + /* Delete any existing button arrangement. */ + + button_bar->bar = NULL; + + for (button = button_bar->buttons; button != NULL; + button = button->next) { + button->bar_next = NULL; + button->separator = false; + } + + /* Parse the config string and link up the new buttons. */ + + button = NULL; + + for (i = 0; order[i] != '\0'; i++) { + if (order[i] != '|') { + new = ro_gui_button_bar_find_opt_key(button_bar, + order[i]); + + if (new != NULL) { + if (button == NULL) + button_bar->bar = new; + else + button->bar_next = new; + + button = new; + } + } else { + if (button != NULL) + button->separator = true; + } + } + + if (!ro_gui_button_bar_place_buttons(button_bar)) + return false; + + return ro_gui_button_bar_place_buttons(button_bar); +} + +/** + * Place the buttons on a button bar, taking into account the button arrangement + * and the current theme, and update the bar extent details. + * + * \param *button_bar The button bar to update. + * \return true if successful; else false. + */ + +bool ro_gui_button_bar_place_buttons(struct button_bar *button_bar) +{ + struct button_bar_button *button; + int x_pos, y_pos, height; + + if (button_bar == NULL) + return false; + + button = button_bar->bar; + x_pos = 0; + y_pos = 0; + height = 0; + + while (button != NULL) { + button->x_pos = x_pos; + button->y_pos = y_pos; + + x_pos += button->x_size; + if (button->separator) + x_pos += button_bar->separator_width; + + if (button->y_size > height) + height = button->y_size; + + button = button->bar_next; + } + + button_bar->x_min = x_pos; + button_bar->y_min = height; + + return true; +} + + +/* This is an exported interface documented in button_bar.h */ + +void ro_gui_button_bar_destroy(struct button_bar *button_bar) +{ + struct button_bar_button *button; + + if (button_bar == NULL) + return; + + /* Free the button definitions. */ + + while (button_bar->buttons != NULL) { + button = button_bar->buttons; + button_bar->buttons = button->next; + free(button); + } + + free(button_bar); +} + + +/* This is an exported interface documented in button_bar.h */ + +bool ro_gui_button_bar_get_dims(struct button_bar *button_bar, + int *width, int *height) +{ + if (button_bar == NULL) + return false; + + if (button_bar->x_min != -1 && button_bar->y_min != -1) { + if (width != NULL) + *width = button_bar->x_min; + if (height != NULL) + *height = button_bar->y_min; + + return true; + } + + return false; +} + + +/* This is an exported interface documented in button_bar.h */ + +bool ro_gui_button_bar_set_extent(struct button_bar *button_bar, + int x0, int y0, int x1, int y1) +{ + if (button_bar == NULL) + return false; + + if ((x1 - x0) < button_bar->x_min || (y1 - y0) < button_bar->y_min) + return false; + + if (button_bar->extent.x0 == x0 && button_bar->extent.y0 == y0 && + button_bar->extent.x1 == x1 && + button_bar->extent.y1 == y1) + return true; + + /* Redraw the relevant bits of the toolbar. We can't optimise for + * stretching the X-extent, as this probably means the button + * arrangement has changed which necessitates a full redraw anyway. + */ + + if (button_bar->window != NULL) { + xwimp_force_redraw(button_bar->window, + button_bar->extent.x0, button_bar->extent.y0, + button_bar->extent.x1, button_bar->extent.y1); + xwimp_force_redraw(button_bar->window, x0, y0, x1, y1); + } + + button_bar->extent.x0 = x0; + button_bar->extent.y0 = y0; + button_bar->extent.x1 = x1; + button_bar->extent.y1 = y1; + + if ((y1 - y0) > button_bar->y_min) + button_bar->vertical_offset = + ((y1 - y0) - button_bar->y_min) / 2; + else + button_bar->vertical_offset = 0; + + return ro_gui_button_bar_icon_resize(button_bar); +} + + +/** + * Update the icons on a button bar, creating or deleting them from the window + * as necessary. + */ + +bool ro_gui_button_bar_icon_update(struct button_bar *button_bar) +{ + wimp_icon_create icon; + struct button_bar_button *button, *b; + os_error *error; + + + if (button_bar == NULL || button_bar->window == NULL) + return (button_bar == NULL) ? false : true; + + button = button_bar->buttons; + + while (button != NULL) { + bool on_bar = false; + + /* Check if the icon is currently on the bar. */ + + for (b = button_bar->bar; b != NULL; b = b->bar_next) { + if (b == button) { + on_bar = true; + break; + } + } + + if (on_bar && !button_bar->hidden && button->icon == -1) { + icon.w = button_bar->window; + icon.icon.extent.x0 = 0; + icon.icon.extent.y0 = 0; + icon.icon.extent.x1 = 0; + icon.icon.extent.y1 = 0; + icon.icon.flags = wimp_ICON_TEXT | wimp_ICON_SPRITE | + wimp_ICON_INDIRECTED | + wimp_ICON_HCENTRED | + wimp_ICON_VCENTRED | + (button_bar->background + << wimp_ICON_BG_COLOUR_SHIFT); + icon.icon.data.indirected_text.size = 1; + + /* We don't actually shade buttons unless there's no + * editor active or this is the source bar. + */ + + if (button->shaded && (!button_bar->edit || + button_bar->edit_target != NULL)) + icon.icon.flags |= wimp_ICON_SHADED; + + if (button_bar->edit) + icon.icon.flags |= (wimp_BUTTON_CLICK_DRAG << + wimp_ICON_BUTTON_TYPE_SHIFT); + else + icon.icon.flags |= (wimp_BUTTON_CLICK << + wimp_ICON_BUTTON_TYPE_SHIFT); + + icon.icon.data.indirected_text.text = null_text_string; + icon.icon.data.indirected_text.validation = + button->validation; + + error = xwimp_create_icon(&icon, &button->icon); + if (error) { + LOG("xwimp_create_icon: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + button->icon = -1; + return false; + } + } else if ((!on_bar || button_bar->hidden) + && button->icon != -1) { + error = xwimp_delete_icon(button_bar->window, + button->icon); + if (error != NULL) { + LOG("xwimp_delete_icon: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + + button->icon = -1; + } + + button = button->next; + } + + return ro_gui_button_bar_icon_resize(button_bar); +} + + +/** + * Position the icons in the button bar to take account of the currently + * configured extent. + * + * \param *button_bar The button bar to update. + * \return true if successful; else false. + */ + +bool ro_gui_button_bar_icon_resize(struct button_bar *button_bar) +{ + os_error *error; + struct button_bar_button *button; + + if (button_bar == NULL || button_bar->hidden) + return (button_bar == NULL) ? false : true; + + /* Reposition all the icons. */ + + button = button_bar->bar; + + while (button != NULL) { + if(button->icon != -1) { + error = xwimp_resize_icon(button_bar->window, + button->icon, + button_bar->extent.x0 + button->x_pos, + button_bar->extent.y0 + + button_bar->vertical_offset + + button->y_pos, + button_bar->extent.x0 + button->x_pos + + button->x_size, + button_bar->extent.y0 + + button_bar->vertical_offset + + button->y_pos + + button->y_size); + if (error != NULL) { + LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + button->icon = -1; + return false; + } + } + + button = button->bar_next; + } + + return true; +} + + +/* This is an exported interface documented in button_bar.h */ + +bool ro_gui_button_bar_hide(struct button_bar *button_bar, bool hide) +{ + if (button_bar == NULL || button_bar->hidden == hide) + return (button_bar == NULL) ? false : true; + + button_bar->hidden = hide; + + return ro_gui_button_bar_icon_update(button_bar); +} + + +/* This is an exported interface documented in button_bar.h */ + +bool ro_gui_button_bar_shade_button(struct button_bar *button_bar, + button_bar_action action, bool shaded) +{ + struct button_bar_button *button; + + if (button_bar == NULL) + return false; + + button = ro_gui_button_bar_find_action(button_bar, action); + if (button == NULL) + return false; + + if (button->shaded == shaded) + return true; + + button->shaded = shaded; + + /* We don't actually shade buttons unless there's no editor active + * or this is the source bar. + */ + + if (button->icon != -1 && + (!button_bar->edit || button_bar->edit_target != NULL)) + ro_gui_set_icon_shaded_state(button_bar->window, button->icon, + shaded); + + return true; +} + + +/* This is an exported interface documented in button_bar.h */ + +void ro_gui_button_bar_redraw(struct button_bar *button_bar, + wimp_draw *redraw) +{ + wimp_icon icon; + struct button_bar_button *button; + + /* Test for a valid button bar, and then check that the redraw box + * coincides with the bar's extent. + */ + + if (button_bar == NULL || button_bar->hidden || + (redraw->clip.x0 - (redraw->box.x0 - redraw->xscroll)) + > button_bar->extent.x1 || + (redraw->clip.y0 - (redraw->box.y1 - redraw->yscroll)) + > button_bar->extent.y1 || + (redraw->clip.x1 - (redraw->box.x0 - redraw->xscroll)) + < button_bar->extent.x0 || + (redraw->clip.y1 - (redraw->box.y1 - redraw->yscroll)) + < button_bar->extent.y0 || + (!button_bar->edit && !button_bar->separators)) + return; + + icon.flags = wimp_ICON_SPRITE | wimp_ICON_INDIRECTED | + wimp_ICON_HCENTRED | wimp_ICON_VCENTRED; + if (button_bar->edit) + icon.flags |= wimp_ICON_BORDER | wimp_COLOUR_DARK_GREY << + wimp_ICON_FG_COLOUR_SHIFT; + if (!button_bar->separators) + icon.flags |= wimp_ICON_FILLED | wimp_COLOUR_LIGHT_GREY << + wimp_ICON_BG_COLOUR_SHIFT; + icon.data.indirected_sprite.id = (osspriteop_id) separator_name; + icon.data.indirected_sprite.area = button_bar->sprites; + icon.data.indirected_sprite.size = 12; + icon.extent.y0 = button_bar->extent.y0 + button_bar->vertical_offset; + icon.extent.y1 = icon.extent.y0 + button_bar->y_min; + + for (button = button_bar->bar; button != NULL; + button = button->bar_next) { + if (button->separator) { + icon.extent.x0 = button_bar->extent.x0 + + button->x_pos + button->x_size; + icon.extent.x1 = icon.extent.x0 + + button_bar->separator_width; + xwimp_plot_icon(&icon); + } + } +} + + +/* This is an exported interface documented in button_bar.h */ + +bool ro_gui_button_bar_click(struct button_bar *button_bar, + wimp_pointer *pointer, wimp_window_state *state, + button_bar_action *action) +{ + struct button_bar_button *button; + os_coord pos; + os_box box; + + if (button_bar == NULL || button_bar->hidden) + return false; + + /* Check that the click was within our part of the window. */ + + pos.x = pointer->pos.x - state->visible.x0 + state->xscroll; + pos.y = pointer->pos.y - state->visible.y1 + state->yscroll; + + if (pos.x < button_bar->extent.x0 || pos.x > button_bar->extent.x1 || + pos.y < button_bar->extent.y0 || + pos.y > button_bar->extent.y1) + return false; + + if (button_bar->edit && pointer->buttons == wimp_DRAG_SELECT) { + /* This is an editor click, so we need to check for drags on + * icons (buttons) and work area (separators). + */ + + button = ro_gui_button_bar_find_coords(button_bar, pos, + &drag_separator, NULL); + + if (button != NULL && (!button->shaded || drag_separator || + button_bar->edit_source != NULL)) { + char *sprite; + os_error *error; + + drag_start = button_bar; + drag_opt = button->opt_key; + + if (drag_separator) { + box.x0 = pointer->pos.x - + button_bar->separator_width / 2; + box.x1 = box.x0 + button_bar->separator_width; + sprite = separator_name; + } else { + box.x0 = pointer->pos.x - button->x_size / 2; + box.x1 = box.x0 + button->x_size; + sprite = button->sprite; + } + + box.y0 = pointer->pos.y - button->y_size / 2; + box.y1 = box.y0 + button->y_size; + + error = xdragasprite_start(dragasprite_HPOS_CENTRE | + dragasprite_VPOS_CENTRE | + dragasprite_BOUND_SPRITE | + dragasprite_BOUND_TO_WINDOW | + dragasprite_DROP_SHADOW, + button_bar->sprites, + sprite, &box, NULL); + if (error) + LOG("xdragasprite_start: 0x%x: %s", error->errnum, error->errmess); + + ro_mouse_drag_start(ro_gui_button_bar_drag_end, + NULL, NULL, NULL); + + + return true; + } + + } else if (!button_bar->edit && pointer->i != -1 && + (pointer->buttons == wimp_CLICK_SELECT || + pointer->buttons == wimp_CLICK_ADJUST)) { + /* This isn't an editor click, so we're only interested in + * Select or Adjust clicks that occur on physical icons. + */ + + button = ro_gui_button_bar_find_icon(button_bar, pointer->i); + + if (button != NULL) { + if (action != NULL) { + switch (pointer->buttons) { + case wimp_CLICK_SELECT: + *action = button->select_action; + break; + case wimp_CLICK_ADJUST: + *action = button->adjust_action; + break; + default: + break; + } + } + return true; + } + } + + return false; +} + + +/* This is an exported interface documented in button_bar.h */ + +bool ro_gui_button_bar_help_suffix(struct button_bar *button_bar, wimp_i i, + os_coord *mouse, wimp_window_state *state, + wimp_mouse_state buttons, const char **suffix) +{ + os_coord pos; + struct button_bar_button *button; + + if (button_bar == NULL || button_bar->hidden) + return false; + + /* Check that the click was within our part of the window. */ + + pos.x = mouse->x - state->visible.x0 + state->xscroll; + pos.y = mouse->y - state->visible.y1 + state->yscroll; + + if (pos.x < button_bar->extent.x0 || pos.x > button_bar->extent.x1 || + pos.y < button_bar->extent.y0 || + pos.y > button_bar->extent.y1) + return false; + + /* Look up and return the help suffix assocuated with the button. */ + + button = ro_gui_button_bar_find_icon(button_bar, i); + + if (button != NULL) + *suffix = button->help_suffix; + else + *suffix = ""; + + return true; +} + + +/** + * Terminate a drag event that was initiated by a button bar. + * + * \param *drag The drag event data. + * \param *data NULL data to satisfy callback syntax. + */ + +void ro_gui_button_bar_drag_end(wimp_dragged *drag, void *data) +{ + struct button_bar *drag_end = NULL; + struct button_bar *source = NULL, *target = NULL; + struct button_bar_button *button, *drop, *previous; + bool right, separator; + wimp_window_state state; + wimp_pointer pointer; + os_coord pos; + os_error *error; + + xdragasprite_stop(); + + if (drag_start == NULL) + return; + + /* Sort out the window coordinates of the drag end. */ + + error = xwimp_get_pointer_info(&pointer); + if (error) { + LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + assert(pointer.w = drag_start->window); + + state.w = drag_start->window; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + pos.x = pointer.pos.x - state.visible.x0 + state.xscroll; + pos.y = pointer.pos.y - state.visible.y1 + state.yscroll; + + /* Work out the destination bar, and establish source and target. */ + + if (drag_start->edit_target != NULL) { + source = drag_start; + target = drag_start->edit_target; + if (pos.x >= target->extent.x0 && pos.x <= target->extent.x1 && + pos.y >= target->extent.y0 && + pos.y <= target->extent.y1) + drag_end = target; + } else if (drag_start->edit_source != NULL) { + source = drag_start->edit_source; + target = drag_start; + if (pos.x >= target->extent.x0 && pos.x <= target->extent.x1 && + pos.y >= target->extent.y0 && + pos.y <= target->extent.y1) + drag_end = target; + /* drag_end == source and drag_end == NULL are both equivalent + * as far as the following code are concerned, and we don't need + * to identify either case. */ + } + + button = ro_gui_button_bar_find_opt_key(target, drag_opt); + assert(button != NULL); + + /* The drag finished in the target bar, so find out where. */ + + if (drag_end == target) { + drop = ro_gui_button_bar_find_coords(target, pos, + &separator, &right); + } else { + drop = NULL; + } + + /* If the button is dropped on itself, there's no change and it's + * less messy to get out now. + */ + + if (drag_start == target && drag_end == target && button == drop) { + drag_start = NULL; + return; + } + + /* The drag started in the target bar, so remove the dragged button. */ + + if (drag_start == target) { + if (drag_separator) { + button->separator = false; + } else if (target->bar == button) { + target->bar = button->bar_next; + } else { + for (previous = target->bar; previous != NULL && + previous->bar_next != button; + previous = previous->bar_next); + assert(previous != NULL); + previous->bar_next = button->bar_next; + if (button->separator) // ?? + previous->separator = true; // ?? + } + } + + /* The drag ended in the target bar, so add the dragged button in. */ + + if (drop != NULL) { + if (right) { + if (drag_separator) { + drop->separator = true; + } else { + button->bar_next = drop->bar_next; + drop->bar_next = button; + if (drop->separator && !separator) { + drop->separator = false; + button->separator = true; + } else { + button->separator = false; + } + } + } else if (target->bar == drop && !drag_separator) { + button->separator = false; + button->bar_next = target->bar; + target->bar = button; + } else if (target->bar != drop) { + for (previous = target->bar; previous != NULL && + previous->bar_next != drop; + previous = previous->bar_next); + assert(previous != NULL); + + if (drag_separator) { + previous->separator = true; + } else { + if (separator) { + previous->separator = false; + button->separator = true; + } else { + button->separator = false; + } + button->bar_next = previous->bar_next; + previous->bar_next = button; + } + } + } + + /* Reposition the buttons and force our client to update. */ + + ro_gui_button_bar_place_buttons(target); + ro_gui_button_bar_icon_update(target); + ro_gui_button_bar_sync_editors(target, source); + + xwimp_force_redraw(target->window, + target->extent.x0, target->extent.y0, + target->extent.x1, target->extent.y1); + + if (source->edit_refresh != NULL) + source->edit_refresh(source->edit_client_data); + + drag_start = NULL; +} + + +/** + * Synchronise the shading of a button bar editor source bar with the currently + * defined buttons in its target bar. + * + * \param *target The editor target bar. + * \param *source The editor source bar. + */ + +void ro_gui_button_bar_sync_editors(struct button_bar *target, + struct button_bar *source) +{ + struct button_bar_button *sb, *tb; + + if (source == NULL || target == NULL) + return; + + /* Unshade all of the buttons in the source bar. */ + + for (sb = source->bar; sb != NULL; sb = sb->bar_next) + sb->shaded = false; + + /* Step through the target bar and shade each corresponding + * button in the source. + */ + + for (tb = target->bar; tb != NULL; tb = tb->bar_next) { + sb = ro_gui_button_bar_find_opt_key(source, tb->opt_key); + + if (sb != NULL) + sb->shaded = true; + } + + /* Phyically shade the necessary buttons in the toolbar. */ + + for (sb = source->bar; sb != NULL; sb = sb->bar_next) + if (sb->icon != -1) + ro_gui_set_icon_shaded_state(source->window, sb->icon, + sb->shaded); +} + + +/* This is an exported interface documented in button_bar.h */ + +char *ro_gui_button_bar_get_config(struct button_bar *button_bar) +{ + struct button_bar_button *button; + size_t size; + char *config; + int i; + + if (button_bar == NULL) + return NULL; + + for (size = 1, button = button_bar->bar; button != NULL; + button = button->bar_next) { + size++; + if (button->separator) + size++; + } + + config = malloc(size); + if (config == NULL) { + LOG("No memory for malloc()"); + ro_warn_user("NoMemory", 0); + return NULL; + } + + for (i = 0, button = button_bar->bar; button != NULL; + button = button->bar_next) { + config[i++] = button->opt_key; + if (button->separator) + config[i++] = '|'; + } + + config[i] = '\0'; + + return config; +} + + +/** + * Find a button bar icon definition from an icon handle. + * + * \param *button_bar The button bar to use. + * \param icon The icon handle. + * \return Pointer to the button bar icon, or NULL. + */ + +struct button_bar_button *ro_gui_button_bar_find_icon( + struct button_bar *button_bar, wimp_i icon) +{ + struct button_bar_button *button; + + if (button_bar == NULL || icon == -1) + return NULL; + + button = button_bar->buttons; + + while (button != NULL && button->icon != icon) + button = button->next; + + return button; +} + + +/** + * Find a button bar icon definition from an options key code. + * + * \param *button_bar The button bar to use. + * \param opt_key The option key character code. + * \return Pointer to the button bar icon, or NULL. + */ + +struct button_bar_button *ro_gui_button_bar_find_opt_key( + struct button_bar *button_bar, char opt_key) +{ + struct button_bar_button *button; + + if (button_bar == NULL) + return NULL; + + button = button_bar->buttons; + + while (button != NULL && button->opt_key != opt_key) + button = button->next; + + return button; +} + + +/** + * Find a button bar icon definition from an action code. + * + * \param *button_bar The button bar to use. + * \param action The button action to find. + * \return Pointer to the button bar icon, or NULL. + */ + +struct button_bar_button *ro_gui_button_bar_find_action( + struct button_bar *button_bar, button_bar_action action) +{ + struct button_bar_button *button; + + if (button_bar == NULL) + return NULL; + + button = button_bar->buttons; + + while (button != NULL && + button->select_action != action && + button->adjust_action != action) + button = button->next; + + return button; +} + + +/** + * Find a button bar icon definition from coordinates. + * + * \param *button_bar The button bar to use. + * \param pos The coordinates to find, work area relative. + * \param *separator Returns true if the associated separator was + * matched; else false. + * \param *right Returns true if the coordinates were in the + * right hand side of the target; else false. + * \return Pointer to the button bar icon, or NULL. + */ + +struct button_bar_button *ro_gui_button_bar_find_coords( + struct button_bar *button_bar, os_coord pos, + bool *separator, bool *right) +{ + struct button_bar_button *button; + + if (button_bar == NULL) + return NULL; + + button = button_bar->bar; + + while (button != NULL) { + /* Match button extents. */ + int x0, y0, x1, y1; + + x0 = button_bar->extent.x0 + button->x_pos; + y0 = button_bar->extent.y0 + button->y_pos; + x1 = x0 + button->x_size; + y1 = y0 + button->y_size; + + if (pos.x > x0 && pos.y > y0 && pos.x < x1 && pos.y < y1) { + if (separator != NULL) + *separator = false; + + if (right != NULL) + *right = (pos.x > x0 + button->x_size/2) ? + true : false; + return button; + } + + x0 = x1; + x1 = x0 + button_bar->separator_width; + + /* Match separator extents. */ + + if (pos.x > x0 && pos.y > y0 && pos.x < x1 && pos.y < y1 && + button->separator) { + if (separator != NULL) + *separator = true; + + if (right != NULL) + *right = (x0 + button_bar->separator_width/2) ? + true : false; + return button; + } + + button = button->bar_next; + } + + return NULL; +} + diff --git a/frontends/riscos/gui/button_bar.h b/frontends/riscos/gui/button_bar.h new file mode 100644 index 000000000..a1f7e8b9f --- /dev/null +++ b/frontends/riscos/gui/button_bar.h @@ -0,0 +1,309 @@ +/* + * Copyright 2005 Richard Wilson <info@tinct.net> + * Copyright 2011 Stephen Fryatt <stevef@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Button bars (interface). + */ + +#ifndef _NETSURF_RISCOS_BUTTONBAR_H_ +#define _NETSURF_RISCOS_BUTTONBAR_H_ + +#include <stdbool.h> +#include "riscos/theme.h" + +/* A list of possible toolbar actions. */ + +typedef enum { + TOOLBAR_BUTTON_NONE = 0, /* Special case: no action */ + TOOLBAR_BUTTON_BACK, + TOOLBAR_BUTTON_BACK_NEW, + TOOLBAR_BUTTON_UP, + TOOLBAR_BUTTON_UP_NEW, + TOOLBAR_BUTTON_FORWARD, + TOOLBAR_BUTTON_FORWARD_NEW, + TOOLBAR_BUTTON_STOP, + TOOLBAR_BUTTON_RELOAD, + TOOLBAR_BUTTON_RELOAD_ALL, + TOOLBAR_BUTTON_HOME, + TOOLBAR_BUTTON_HISTORY_LOCAL, + TOOLBAR_BUTTON_HISTORY_GLOBAL, + TOOLBAR_BUTTON_SAVE_SOURCE, + TOOLBAR_BUTTON_SAVE_COMPLETE, + TOOLBAR_BUTTON_PRINT, + TOOLBAR_BUTTON_BOOKMARK_OPEN, + TOOLBAR_BUTTON_BOOKMARK_ADD, + TOOLBAR_BUTTON_SCALE, + TOOLBAR_BUTTON_SEARCH, + TOOLBAR_BUTTON_DELETE, + TOOLBAR_BUTTON_EXPAND, + TOOLBAR_BUTTON_COLLAPSE, + TOOLBAR_BUTTON_OPEN, + TOOLBAR_BUTTON_CLOSE, + TOOLBAR_BUTTON_LAUNCH, + TOOLBAR_BUTTON_CREATE +} button_bar_action; + +/* Button bar button source definitions. + * + * Help tokens are added to the help prefix for the given toolbar by the + * help system, and correspond to the hard-coded icon numbers that were + * assigned to the different buttons in the original toolbar implementation. + * If the Messages file can be updated, these can change to something more + * meaningful. + */ + +struct button_bar_buttons { + const char *icon; /**< The sprite used for the icon. */ + button_bar_action select; /**< The action for select clicks. */ + button_bar_action adjust; /**< The action for Adjust clicks. */ + const char opt_key; /**< The char used in option strings. */ + const char *help; /**< The interactive help token. */ +}; + +/* \TODO -- Move these to the correct modules. + */ + +static const struct button_bar_buttons brower_toolbar_buttons[] = { + {"back", TOOLBAR_BUTTON_BACK, TOOLBAR_BUTTON_BACK_NEW, '0', "0"}, + {"up", TOOLBAR_BUTTON_UP, TOOLBAR_BUTTON_UP_NEW, 'b', "11"}, + {"forward", TOOLBAR_BUTTON_FORWARD, TOOLBAR_BUTTON_FORWARD_NEW, '1', "1"}, + {"stop", TOOLBAR_BUTTON_STOP, TOOLBAR_BUTTON_NONE, '2', "2"}, + {"reload", TOOLBAR_BUTTON_RELOAD, TOOLBAR_BUTTON_RELOAD_ALL, '3', "3"}, + {"home", TOOLBAR_BUTTON_HOME, TOOLBAR_BUTTON_NONE, '4', "4"}, + {"history", TOOLBAR_BUTTON_HISTORY_LOCAL, TOOLBAR_BUTTON_HISTORY_GLOBAL, '5', "5"}, + {"save", TOOLBAR_BUTTON_SAVE_SOURCE, TOOLBAR_BUTTON_SAVE_COMPLETE, '6', "6"}, + {"print", TOOLBAR_BUTTON_PRINT, TOOLBAR_BUTTON_NONE, '7', "7"}, + {"hotlist", TOOLBAR_BUTTON_BOOKMARK_OPEN, TOOLBAR_BUTTON_BOOKMARK_ADD, '8', "8"}, + {"scale", TOOLBAR_BUTTON_SCALE, TOOLBAR_BUTTON_NONE, '9', "9"}, + {"search", TOOLBAR_BUTTON_SEARCH, TOOLBAR_BUTTON_NONE, 'a', "10"}, + {NULL, TOOLBAR_BUTTON_NONE, TOOLBAR_BUTTON_NONE, '\0', ""} +}; + +static const struct button_bar_buttons cookies_toolbar_buttons[] = { + {"delete", TOOLBAR_BUTTON_DELETE, TOOLBAR_BUTTON_NONE, '0', "0"}, + {"expand", TOOLBAR_BUTTON_EXPAND, TOOLBAR_BUTTON_COLLAPSE, '1', "1"}, + {"open", TOOLBAR_BUTTON_OPEN, TOOLBAR_BUTTON_CLOSE, '2', "2"}, + {NULL, TOOLBAR_BUTTON_NONE, TOOLBAR_BUTTON_NONE, '\0', ""} +}; + +static const struct button_bar_buttons global_history_toolbar_buttons[] = { + {"delete", TOOLBAR_BUTTON_DELETE, TOOLBAR_BUTTON_NONE, '0', "0"}, + {"expand", TOOLBAR_BUTTON_EXPAND, TOOLBAR_BUTTON_COLLAPSE, '1', "1"}, + {"open", TOOLBAR_BUTTON_OPEN, TOOLBAR_BUTTON_CLOSE, '2', "2"}, + {"launch", TOOLBAR_BUTTON_LAUNCH, TOOLBAR_BUTTON_NONE, '3', "3"}, + {NULL, TOOLBAR_BUTTON_NONE, TOOLBAR_BUTTON_NONE, '\0', ""} +}; + +static const struct button_bar_buttons hotlist_toolbar_buttons[] = { + {"delete", TOOLBAR_BUTTON_DELETE, TOOLBAR_BUTTON_NONE, '0', "0"}, + {"expand", TOOLBAR_BUTTON_EXPAND, TOOLBAR_BUTTON_COLLAPSE, '1', "1"}, + {"open", TOOLBAR_BUTTON_OPEN, TOOLBAR_BUTTON_CLOSE, '2', "2"}, + {"launch", TOOLBAR_BUTTON_LAUNCH, TOOLBAR_BUTTON_NONE, '3', "3"}, + {"create", TOOLBAR_BUTTON_CREATE, TOOLBAR_BUTTON_NONE, '4', "4"}, + {NULL, TOOLBAR_BUTTON_NONE, TOOLBAR_BUTTON_NONE, '\0', ""} +}; + +struct button_bar; + + +/** + * Create a new button bar widget. + * + * \param *theme The theme to apply (or NULL for the default). + * \param buttons[] An array of button definitions for the bar. + * \return A button bar handle, or NULL on failure. + */ + +struct button_bar *ro_gui_button_bar_create(struct theme_descriptor *theme, + const struct button_bar_buttons buttons[]); + + +/** + * Link two button bars together + * + * Join two button bars the target being the active bar, and the + * source being the editing bar used to supply valid buttons. The bars are + * checked to ensure that they are not already part of an edit pair, but are + * not checked for button-compatibility. + * + * \param target The target button bar. + * \param source The source button bar. + * \param refresh The refresh callback. + * \param client_data context passed to the refresh callback + * \return true if successful; else false. + */ + +bool ro_gui_button_bar_link_editor(struct button_bar *target, + struct button_bar *source, void (* refresh)(void *), + void *client_data); + +/** + * Place a button bar into a toolbar window and initialise any theme-specific + * settings. Any previous incarnation of the bar will be forgotten: this + * is for use when a new toolbar is being created, or when a toolbar has been + * deleted and rebuilt following a theme change. + * + * \param *button_bar The button bar to rebuild. + * \param *theme The theme to apply (or NULL for current). + * \param style The theme style to apply. + * \param window The window that the bar is in. + * \param edit The edit mode of the button bar. + * \return true on success; else false. + */ + +bool ro_gui_button_bar_rebuild(struct button_bar *button_bar, + struct theme_descriptor *theme, theme_style style, + wimp_w window, bool edit); + + +/** + * Arrange buttons on a button bar, using an order string to specify the + * required button and separator layout. + * + * \param *button_bar The button bar to update. + * \param order[] The button order configuration string. + * \return true if successful; else false. + */ + +bool ro_gui_button_bar_arrange_buttons(struct button_bar *button_bar, + char order[]); + + +/** + * Destroy a button bar widget. + * + * \param *button_bar The button bar to destroy. + */ + +void ro_gui_button_bar_destroy(struct button_bar *button_bar); + + +/** + * Return the MINIMUM dimensions required by the button bar, in RO units, + * allowing for the current theme. + * + * \param *button_bar The button bar of interest. + * \param *width Return the required width. + * \param *height Return the required height. + * \return true if values are returned; else false. + */ + +bool ro_gui_button_bar_get_dims(struct button_bar *button_bar, + int *width, int *height); + + +/** + * Set or update the dimensions to be used by the button bar, in RO units. + * If these are greater than the minimum required, the button bar will fill + * the extended space; if less, the call will fail. + * + * \param *button_bar The button bar to update. + * \param x0 The minimum X window position. + * \param y0 The minimum Y window position. + * \param x1 The maximum X window position. + * \param y1 The maximum Y window position. + * \return true if size updated; else false. + */ + +bool ro_gui_button_bar_set_extent(struct button_bar *button_bar, + int x0, int y0, int x1, int y1); + + +/** + * Show or hide a button bar. + * + * \param *button_bar The button bar to hide. + * \param hide true to hide the bar; false to show it. + * \return true if successful; else false. + */ + +bool ro_gui_button_bar_hide(struct button_bar *button_bar, bool hide); + + +/** + * Shade or unshade a button in a bar corresponding to the given action. + * + * \param *button_bar The button bar to update. + * \param action The action to update. + * \param shaded true to shade the button; false to unshade. + * \return true if successful; else false. + */ + +bool ro_gui_button_bar_shade_button(struct button_bar *button_bar, + button_bar_action action, bool shaded); + + +/** + * Handle redraw event rectangles in a button bar. + * + * \param *button_bar The button bar to use. + * \param *redraw The Wimp redraw rectangle to process. + */ + +void ro_gui_button_bar_redraw(struct button_bar *button_bar, + wimp_draw *redraw); + + +/** + * Handle mouse clicks in a button bar. + * + * \param *button_bar The button bar to use. + * \param *pointer The Wimp mouse click event data. + * \param *state The toolbar window state. + * \param *action Returns the selected action, or + * TOOLBAR_BUTTON_NONE. + * \return true if the event was handled exclusively; + * else false. + */ + +bool ro_gui_button_bar_click(struct button_bar *button_bar, + wimp_pointer *pointer, wimp_window_state *state, + button_bar_action *action); + + +/** + * Translate mouse data into an interactive help message for a button bar. + * + * \param *button_bar The button bar to process. + * \param i The wimp icon under the pointer. + * \param *mouse The mouse position. + * \param *state The toolbar window state. + * \param buttons The mouse button state. + * \param **suffix Return a help token suffix, or "" for none. + * \return true if handled exclusively; else false. + */ + +bool ro_gui_button_bar_help_suffix(struct button_bar *button_bar, wimp_i i, + os_coord *mouse, wimp_window_state *state, + wimp_mouse_state buttons, const char **suffix); + + +/** + * Return a config string reflecting the configured order of buttons + * and spacers. The string is allocated with malloc(), and should be + * free()d after use. + * + * \param *button_bar The button bar of interest. + * \return Pointer to a config string, or NULL on failure. + */ + +char *ro_gui_button_bar_get_config(struct button_bar *button_bar); + +#endif + diff --git a/frontends/riscos/gui/progress_bar.c b/frontends/riscos/gui/progress_bar.c new file mode 100644 index 000000000..3ec6b3aa8 --- /dev/null +++ b/frontends/riscos/gui/progress_bar.c @@ -0,0 +1,535 @@ +/* + * Copyright 2006 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Progress bar (implementation). + */ + +#include <assert.h> +#include <stdbool.h> +#include <string.h> +#include "swis.h" +#include "oslib/colourtrans.h" +#include "oslib/os.h" +#include "oslib/osspriteop.h" +#include "oslib/wimp.h" +#include "oslib/wimpspriteop.h" + +#include "desktop/plotters.h" +#include "utils/log.h" +#include "utils/utils.h" + +#include "riscos/gui.h" +#include "riscos/tinct.h" +#include "riscos/wimp_event.h" +#include "riscos/gui/progress_bar.h" + +#define MARGIN 6 + +struct progress_bar { + wimp_w w; /**< progress bar window handle */ + unsigned int range; /**< progress bar range */ + unsigned int value; /**< progress bar value */ + char icon[13]; /**< current icon */ + int offset; /**< progress bar rotation */ + os_box visible; /**< progress bar position */ + int icon_x0; /**< icon x0 */ + int icon_y0; /**< icon y0 */ + osspriteop_header *icon_img; /**< icon image */ + bool animating; /**< progress bar is animating */ + bool recalculate; /**< recalculation required */ + int cur_width; /**< current calculated width */ + int cur_height; /**< current calculated height */ + bool icon_obscured; /**< icon is partially obscured */ +}; + +static char progress_animation_sprite[] = "progress"; +static osspriteop_header *progress_icon; +static unsigned int progress_width; +static unsigned int progress_height; + +struct wimp_window_base progress_bar_definition = { + {0, 0, 1, 1}, + 0, + 0, + wimp_TOP, + wimp_WINDOW_NEW_FORMAT | wimp_WINDOW_MOVEABLE | wimp_WINDOW_NO_BOUNDS, + 0xff, + wimp_COLOUR_LIGHT_GREY, + wimp_COLOUR_LIGHT_GREY, + wimp_COLOUR_VERY_LIGHT_GREY, + wimp_COLOUR_DARK_GREY, + wimp_COLOUR_MID_LIGHT_GREY, + wimp_COLOUR_CREAM, + wimp_WINDOW_NEVER3D | 0x16u /* RISC OS 5.03+ */, + {0, 0, 65535, 65535}, + 0, + 0, + wimpspriteop_AREA, + 1, + 1, + {""}, + 0 +}; + + +static void ro_gui_progress_bar_calculate(struct progress_bar *pb, int width, + int height); +static void ro_gui_progress_bar_redraw(wimp_draw *redraw); +static void ro_gui_progress_bar_redraw_window(wimp_draw *redraw, + struct progress_bar *pb); +static void ro_gui_progress_bar_animate(void *p); + + +/** + * Initialise the progress bar + * + * \param icons the sprite area to use for icons + */ +void ro_gui_progress_bar_init(osspriteop_area *icons) +{ + const char *name = progress_animation_sprite; + os_error *error; + + progress_bar_definition.sprite_area = icons; + + progress_icon = NULL; + error = xosspriteop_select_sprite(osspriteop_USER_AREA, + progress_bar_definition.sprite_area, + (osspriteop_id) name, &progress_icon); + if (!error) { + xosspriteop_read_sprite_info(osspriteop_USER_AREA, + progress_bar_definition.sprite_area, + (osspriteop_id) name, + (int *) &progress_width, (int *) &progress_height, + 0, 0); + } +} + + +/** + * Create a new progress bar + */ +struct progress_bar *ro_gui_progress_bar_create(void) +{ + struct progress_bar *pb; + os_error *error; + + pb = calloc(1, sizeof(*pb)); + if (!pb) + return NULL; + + error = xwimp_create_window((wimp_window *)&progress_bar_definition, + &pb->w); + if (error) { + LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess); + free(pb); + return NULL; + } + + ro_gui_wimp_event_register_redraw_window(pb->w, + ro_gui_progress_bar_redraw); + ro_gui_wimp_event_set_user_data(pb->w, pb); + return pb; +} + + +/** + * Destroy a progress bar and free all associated resources + * + * \param pb the progress bar to destroy + */ +void ro_gui_progress_bar_destroy(struct progress_bar *pb) +{ + os_error *error; + assert(pb); + + if (pb->animating) { + riscos_schedule(-1, ro_gui_progress_bar_animate, pb); + } + ro_gui_wimp_event_finalise(pb->w); + error = xwimp_delete_window(pb->w); + if (error) { + LOG("xwimp_delete_window: 0x%x:%s", error->errnum, error->errmess); + } + + free(pb); +} + + +/** + * Get the handle of the window that represents a progress bar + * + * \param pb the progress bar to get the window handle of + * \return the progress bar's window handle + */ +wimp_w ro_gui_progress_bar_get_window(struct progress_bar *pb) +{ + assert(pb); + + return pb->w; +} + + +/** + * Set the icon for a progress bar + * + * \param pb the progress bar to set the icon for + * \param icon the icon to use, or NULL for no icon + */ +void ro_gui_progress_bar_set_icon(struct progress_bar *pb, const char *icon) +{ + assert(pb); + + if (!strcmp(icon, pb->icon)) + return; + if (!icon) + pb->icon[0] = '\0'; + else { + strncpy(pb->icon, icon, 12); + pb->icon[12] = '\0'; + } + pb->recalculate = true; + xwimp_force_redraw(pb->w, 0, 0, 32, 32); + ro_gui_progress_bar_update(pb, pb->cur_width, pb->cur_height); +} + + +/** + * Set the value of a progress bar + * + * \param pb the progress bar to set the value for + * \param value the value to use + */ +void ro_gui_progress_bar_set_value(struct progress_bar *pb, unsigned int value) +{ + assert(pb); + + pb->value = value; + if (pb->value > pb->range) + pb->range = pb->value; + ro_gui_progress_bar_update(pb, pb->cur_width, pb->cur_height); +} + + +/** + * Get the value of a progress bar + * + * \param pb the progress bar to get the value of + * \return the current value + */ +unsigned int ro_gui_progress_bar_get_value(struct progress_bar *pb) +{ + assert(pb); + + return pb->value; +} + + +/** + * Set the range of a progress bar + * + * \param pb the progress bar to set the range for + * \param range the range to use + */ +void ro_gui_progress_bar_set_range(struct progress_bar *pb, unsigned int range) +{ + assert(pb); + + pb->range = range; + if (pb->value > pb->range) + pb->value = pb->range; + ro_gui_progress_bar_update(pb, pb->cur_width, pb->cur_height); +} + + +/** + * Get the range of a progress bar + * + * \param pb the progress bar to get the range of + * \return the current range + */ +unsigned int ro_gui_progress_bar_get_range(struct progress_bar *pb) +{ + assert(pb); + + return pb->range; +} + + +/** + * Update the progress bar to a new dimension. + * + * \param pb the progress bar to update + * \param width the new progress bar width + * \param height the new progress bar height + */ +void ro_gui_progress_bar_update(struct progress_bar *pb, int width, int height) +{ + wimp_draw redraw; + os_error *error; + osbool more; + os_box cur; + + /* don't allow negative dimensions */ + width = max(width, 0); + height = max(height, 0); + + /* update the animation state */ + if ((pb->value == 0) || (pb->value == pb->range)) { + if (pb->animating) { + riscos_schedule(-1, ro_gui_progress_bar_animate, pb); + } + pb->animating = false; + } else { + if (!pb->animating) { + riscos_schedule(200, ro_gui_progress_bar_animate, pb); + } + pb->animating = true; + } + + /* get old and new positions */ + cur = pb->visible; + pb->recalculate = true; + ro_gui_progress_bar_calculate(pb, width, height); + + /* see if the progress bar hasn't moved. we don't need to consider + * the left edge moving as this is handled by the icon setting + * function */ + if (cur.x1 == pb->visible.x1) + return; + + /* if size has decreased then we must force a redraw */ + if (cur.x1 > pb->visible.x1) { + xwimp_force_redraw(pb->w, pb->visible.x1, pb->visible.y0, + cur.x1, pb->visible.y1); + return; + } + + /* perform a minimal redraw update */ + redraw.w = pb->w; + redraw.box = pb->visible; + redraw.box.x0 = cur.x1; + error = xwimp_update_window(&redraw, &more); + if (error) { + LOG("Error getting update window: 0x%x: %s", error->errnum, error->errmess); + return; + } + if (more) + ro_gui_progress_bar_redraw_window(&redraw, pb); +} + + +/** + * Process a WIMP redraw request + * + * \param redraw the redraw request to process + */ +void ro_gui_progress_bar_redraw(wimp_draw *redraw) +{ + struct progress_bar *pb; + os_error *error; + osbool more; + + pb = (struct progress_bar *)ro_gui_wimp_event_get_user_data(redraw->w); + assert(pb); + + error = xwimp_redraw_window(redraw, &more); + if (error) { + LOG("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess); + return; + } + if (more) + ro_gui_progress_bar_redraw_window(redraw, pb); +} + + +/** + * Animate the progress bar + * + * \param p the progress bar to animate + */ +void ro_gui_progress_bar_animate(void *p) +{ + wimp_draw redraw; + os_error *error; + osbool more; + struct progress_bar *pb = p; + + if (!progress_icon) + return; + pb->offset -= 6; + if (pb->offset < 0) + pb->offset += progress_width * 2; + + if (pb->animating) { + riscos_schedule(200, ro_gui_progress_bar_animate, pb); + } + + redraw.w = pb->w; + redraw.box = pb->visible; + error = xwimp_update_window(&redraw, &more); + if (error != NULL) { + LOG("Error getting update window: '%s'", error->errmess); + return; + } + if (more) + ro_gui_progress_bar_redraw_window(&redraw, pb); +} + + +/** + * Calculate the position of the progress bar + * + * \param pb the progress bar to recalculate + * \param width the width of the progress bar + * \param height the height of the progress bar + * \return the address of the associated icon, or NULL + */ +void ro_gui_progress_bar_calculate(struct progress_bar *pb, int width, + int height) +{ + int icon_width, icon_height; + int icon_x0 = 0, icon_y0 = 0, progress_x0, progress_x1; + osspriteop_header *icon = NULL; + bool icon_redraw = false; + + /* try to use cached values */ + if ((!pb->recalculate) && (pb->cur_width == width) && + (pb->cur_height == height)) + return; + + /* update cache status */ + pb->recalculate = false; + pb->cur_width = width; + pb->cur_height = height; + + /* get the window dimensions */ + width -= MARGIN * 2; + icon_width = icon_height = 0; + progress_x0 = MARGIN; + + /* get the icon information */ + if (progress_bar_definition.sprite_area != wimpspriteop_AREA) { + int progress_ymid = height / 2; + os_error *error; + error = xosspriteop_read_sprite_info(osspriteop_USER_AREA, + progress_bar_definition.sprite_area, + (osspriteop_id)pb->icon, + &icon_width, &icon_height, 0, 0); + if (!error) { + error = xosspriteop_select_sprite(osspriteop_USER_AREA, + progress_bar_definition.sprite_area, + (osspriteop_id)pb->icon, &icon); + } + if (!error) { + progress_x0 += 32 + MARGIN; + width -= 32 + MARGIN; + icon_x0 = MARGIN + 16 - icon_width; + icon_y0 = progress_ymid - icon_height; + if (width < -MARGIN) { + icon_x0 += width + MARGIN; + icon_redraw = true; + } + } + } + + /* update the icon */ + if ((pb->icon_obscured) || (icon_redraw)) { + if (icon_x0 != pb->icon_x0) + xwimp_force_redraw(pb->w, 0, 0, 32 + MARGIN, 65536); + } + pb->icon_obscured = icon_redraw; + + progress_x1 = progress_x0; + if ((pb->range > 0) && (width > 0)) + progress_x1 += (width * pb->value) / pb->range; + + pb->visible.x0 = progress_x0; + pb->visible.y0 = MARGIN; + pb->visible.x1 = progress_x1; + pb->visible.y1 = height - MARGIN; + pb->icon_x0 = icon_x0; + pb->icon_y0 = icon_y0; + pb->icon_img = icon; +} + + +/** + * Redraw a section of a progress bar window + * + * \param redraw the section of the window to redraw + * \param pb the progress bar to redraw + */ +void ro_gui_progress_bar_redraw_window(wimp_draw *redraw, + struct progress_bar *pb) +{ + osbool more = true; + struct rect clip; + int progress_ymid; + + /* initialise the plotters */ + ro_plot_origin_x = 0; + ro_plot_origin_y = 0; + + /* recalculate the progress bar */ + ro_gui_progress_bar_calculate(pb, redraw->box.x1 - redraw->box.x0, + redraw->box.y1 - redraw->box.y0); + progress_ymid = redraw->box.y0 + pb->visible.y0 + + ((pb->visible.y1 - pb->visible.y0) >> 1); + + /* redraw the window */ + while (more) { + os_error *error; + if (pb->icon) + _swix(Tinct_PlotAlpha, _IN(2) | _IN(3) | _IN(4) | _IN(7), + pb->icon_img, + redraw->box.x0 + pb->icon_x0, + redraw->box.y0 + pb->icon_y0, + tinct_ERROR_DIFFUSE); + if (!pb->icon_obscured) { + clip.x0 = max(redraw->clip.x0, + redraw->box.x0 + pb->visible.x0) >> 1; + clip.y0 = -min(redraw->clip.y1, + redraw->box.y0 + pb->visible.y1) >> 1; + clip.x1 = min(redraw->clip.x1, + redraw->box.x0 + pb->visible.x1) >> 1; + clip.y1 = -max(redraw->clip.y0, + redraw->box.y0 + pb->visible.y0) >> 1; + if ((clip.x0 < clip.x1) && (clip.y0 < clip.y1)) { + if (progress_icon) { + ro_plotters.clip(&clip); + _swix(Tinct_Plot, _IN(2) | _IN(3) | _IN(4) | _IN(7), + progress_icon, + redraw->box.x0 - pb->offset, + progress_ymid - progress_height, + tinct_FILL_HORIZONTALLY); + } else { + ro_plotters.rectangle(clip.x0, clip.y0, + clip.x1, clip.y1, + plot_style_fill_red); + } + } + } + error = xwimp_get_rectangle(redraw, &more); + if (error) { + LOG("xwimp_get_rectangle: 0x%x: %s", error->errnum, error->errmess); + return; + } + } +} diff --git a/frontends/riscos/gui/progress_bar.h b/frontends/riscos/gui/progress_bar.h new file mode 100644 index 000000000..e4cec1369 --- /dev/null +++ b/frontends/riscos/gui/progress_bar.h @@ -0,0 +1,44 @@ +/* + * Copyright 2006 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Progress bar (interface). + */ + +#ifndef _NETSURF_RISCOS_PROGRESS_BAR_H_ +#define _NETSURF_RISCOS_PROGRESS_BAR_H_ + +#include <stdbool.h> +#include "oslib/osspriteop.h" +#include "oslib/wimp.h" + +struct progress_bar; + +void ro_gui_progress_bar_init(osspriteop_area *icons); + +struct progress_bar *ro_gui_progress_bar_create(void); +void ro_gui_progress_bar_destroy(struct progress_bar *pb); +void ro_gui_progress_bar_update(struct progress_bar *pb, int width, int height); + +wimp_w ro_gui_progress_bar_get_window(struct progress_bar *pb); +void ro_gui_progress_bar_set_icon(struct progress_bar *pb, const char *icon); +void ro_gui_progress_bar_set_value(struct progress_bar *pb, unsigned int value); +unsigned int ro_gui_progress_bar_get_value(struct progress_bar *pb); +void ro_gui_progress_bar_set_range(struct progress_bar *pb, unsigned int range); +unsigned int ro_gui_progress_bar_get_range(struct progress_bar *pb); +#endif diff --git a/frontends/riscos/gui/status_bar.c b/frontends/riscos/gui/status_bar.c new file mode 100644 index 000000000..cbc404658 --- /dev/null +++ b/frontends/riscos/gui/status_bar.c @@ -0,0 +1,625 @@ +/* + * Copyright 2006 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * UTF8 status bar (implementation). + */ + +#include <assert.h> +#include <stdbool.h> +#include <string.h> +#include "swis.h" +#include "oslib/colourtrans.h" +#include "oslib/os.h" +#include "oslib/wimp.h" +#include "oslib/wimpspriteop.h" +#include "desktop/plotters.h" +#include "utils/log.h" +#include "utils/utils.h" + +#include "riscos/gui.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" +#include "riscos/wimputils.h" +#include "riscos/font.h" +#include "riscos/gui/progress_bar.h" +#include "riscos/gui/status_bar.h" + +#define ICON_WIDGET 0 +#define WIDGET_WIDTH 12 +#define PROGRESS_WIDTH 160 + +struct status_bar { + wimp_w w; /**< status bar window handle */ + wimp_w parent; /**< parent window handle */ + const char *text; /**< status bar text */ + struct progress_bar *pb; /**< progress bar */ + unsigned int scale; /**< current status bar scale */ + int width; /**< current status bar width */ + bool visible; /**< status bar is visible? */ +}; + +static char status_widget_text[] = ""; +static char status_widget_validation[] = "R5;Pptr_lr,8,6"; + +wimp_WINDOW(1) status_bar_definition = { + {0, 0, 1, 1}, + 0, + 0, + wimp_TOP, + wimp_WINDOW_NEW_FORMAT | wimp_WINDOW_MOVEABLE | + wimp_WINDOW_FURNITURE_WINDOW | + wimp_WINDOW_IGNORE_XEXTENT, + wimp_COLOUR_BLACK, + wimp_COLOUR_LIGHT_GREY, + wimp_COLOUR_LIGHT_GREY, + wimp_COLOUR_VERY_LIGHT_GREY, + wimp_COLOUR_DARK_GREY, + wimp_COLOUR_MID_LIGHT_GREY, + wimp_COLOUR_CREAM, + wimp_WINDOW_NEVER3D | 0x16u /* RISC OS 5.03+ */, + {0, 0, 65535, 65535}, + 0, + 0, + wimpspriteop_AREA, + 1, + 1, + {""}, + 1, + { + { + {0, 0, 1, 1}, + wimp_ICON_TEXT | wimp_ICON_INDIRECTED | + wimp_ICON_BORDER | wimp_ICON_FILLED | + (wimp_COLOUR_LIGHT_GREY << + wimp_ICON_BG_COLOUR_SHIFT) | + (wimp_BUTTON_CLICK_DRAG << + wimp_ICON_BUTTON_TYPE_SHIFT), + { + .indirected_text = { + status_widget_text, + status_widget_validation, + 1 + } + } + } + } +}; + +static void ro_gui_status_bar_open(wimp_open *open); +static bool ro_gui_status_bar_click(wimp_pointer *pointer); +static void ro_gui_status_bar_redraw(wimp_draw *redraw); +static void ro_gui_status_bar_redraw_callback(void *handle); +static void ro_gui_status_position_progress_bar(struct status_bar *sb); + + +/** + * Create a new status bar + * + * \param parent the window to contain the status bar + * \param width the proportional width to use (0...10,000) + */ +struct status_bar *ro_gui_status_bar_create(wimp_w parent, unsigned int width) +{ + struct status_bar *sb; + os_error *error; + + sb = calloc(1, sizeof(*sb)); + if (!sb) + return NULL; + + sb->pb = ro_gui_progress_bar_create(); + if (!sb->pb) + return NULL; + + error = xwimp_create_window((wimp_window *)&status_bar_definition, + &sb->w); + if (error) { + LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess); + free(sb); + return NULL; + } + sb->parent = parent; + sb->scale = width; + sb->visible = true; + + ro_gui_wimp_event_set_user_data(sb->w, sb); + ro_gui_wimp_event_register_open_window(sb->w, + ro_gui_status_bar_open); + ro_gui_wimp_event_register_mouse_click(sb->w, + ro_gui_status_bar_click); + ro_gui_wimp_event_register_redraw_window(sb->w, + ro_gui_status_bar_redraw); + ro_gui_wimp_event_set_help_prefix(sb->w, "HelpStatus"); + ro_gui_status_bar_resize(sb); + return sb; +} + + +/** + * Destroy a status bar and free all associated resources + * + * \param sb the status bar to destroy + */ +void ro_gui_status_bar_destroy(struct status_bar *sb) +{ + os_error *error; + assert(sb); + + ro_gui_wimp_event_finalise(sb->w); + error = xwimp_delete_window(sb->w); + if (error) { + LOG("xwimp_delete_window: 0x%x:%s", error->errnum, error->errmess); + } + + ro_gui_progress_bar_destroy(sb->pb); + + /* Remove any scheduled redraw callbacks */ + riscos_schedule(-1, ro_gui_status_bar_redraw_callback, (void *) sb); + + free(sb); +} + + +/** + * Get the handle of the window that represents a status bar + * + * \param sb the status bar to get the window handle of + * \return the status bar's window handle + */ +wimp_w ro_gui_status_bar_get_window(struct status_bar *sb) +{ + assert(sb); + + return sb->w; +} + + +/** + * Get the proportional width the status bar is currently using + * + * \param sb the status bar to get the width of + * \return the status bar's width (0...10,000) + */ +unsigned int ro_gui_status_bar_get_width(struct status_bar *sb) +{ + assert(sb); + + return sb->scale; +} + + +/** + * Set the visibility status of the status bar + * + * \param sb the status bar to check the visiblity of + * \param visible if the status bar should be shown or not. + * \return whether the status bar is visible + */ +void ro_gui_status_bar_set_visible(struct status_bar *sb, bool visible) +{ + assert(sb); + + sb->visible = visible; + if (visible) { + ro_gui_status_bar_resize(sb); + } else { + os_error *error = xwimp_close_window(sb->w); + if (error) { + LOG("xwimp_close_window: 0x%x:%s", error->errnum, error->errmess); + } + } +} + + +/** + * Get the visibility status of the status bar + * + * \param sb the status bar to check the visiblity of + * \return whether the status bar is visible + */ +bool ro_gui_status_bar_get_visible(struct status_bar *sb) +{ + assert(sb); + + return sb->visible; +} + + +/** + * Set the value of the progress bar + * + * \param sb the status bar to set the progress of + * \param value the value to use + */ +void ro_gui_status_bar_set_progress_value(struct status_bar *sb, + unsigned int value) +{ + assert(sb); + + ro_gui_status_bar_set_progress_range(sb, + max(value, ro_gui_progress_bar_get_range(sb->pb))); + ro_gui_progress_bar_set_value(sb->pb, value); +} + + +/** + * Set the range of the progress bar + * + * \param sb the status bar to set the range of + * \param range the range of the progress bar + */ +void ro_gui_status_bar_set_progress_range(struct status_bar *sb, + unsigned int range) +{ + unsigned int old_range; + + assert(sb); + + old_range = ro_gui_progress_bar_get_range(sb->pb); + ro_gui_progress_bar_set_range(sb->pb, range); + + LOG("Ranges are %i vs %i", old_range, range); + if ((old_range == 0) && (range != 0)) { + ro_gui_status_position_progress_bar(sb); + } else if ((old_range != 0) && (range == 0)) { + os_error *error = xwimp_close_window( + ro_gui_progress_bar_get_window(sb->pb)); + if (error) { + LOG("xwimp_close_window: 0x%x:%s", error->errnum, error->errmess); + } + } +} + + +/** + * Set the icon for the progress bar + * + * \param sb the status bar to set the icon for + * \param icon the icon to use, or NULL for no icon + */ +void ro_gui_status_bar_set_progress_icon(struct status_bar *sb, + const char *icon) +{ + assert(sb); + + ro_gui_progress_bar_set_icon(sb->pb, icon); +} + + +/** + * Set the text to display in the status bar + * + * \param sb the status bar to set the text for + * \param text the UTF8 text to display, or NULL for none + */ +void ro_gui_status_bar_set_text(struct status_bar *sb, const char *text) +{ + assert(sb); + + sb->text = text; + + /* Schedule a window redraw for 1cs' time. + * + * We do this to ensure that redraws as a result of text changes + * do not prevent other applications obtaining CPU time. + * + * The scheduled callback will be run when we receive the first + * null poll after 1cs has elapsed. It may then issue a redraw + * request to the Wimp. + * + * The scheduler ensures that only one instance of the + * { callback, handle } pair is registered at once. + */ + if (sb->visible && text != NULL) { + riscos_schedule(10, ro_gui_status_bar_redraw_callback, sb); + } +} + + +/** + * Resize a status bar following a change in the dimensions of the + * parent window. + * + * \param sb the status bar to resize + */ +void ro_gui_status_bar_resize(struct status_bar *sb) +{ + int window_width; + int status_width, status_height; + wimp_window_state state; + os_error *error; + os_box extent; + + if ((!sb) || (!sb->visible)) + return; + + /* get the window work area dimensions */ + state.w = sb->parent; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + return; + } + window_width = state.visible.x1 - state.visible.x0; + + + /* recalculate the scaled width */ + status_width = (window_width * sb->scale) / 10000; + if (status_width < WIDGET_WIDTH) + status_width = WIDGET_WIDTH; + status_height = ro_get_hscroll_height(sb->parent); + + /* resize the status/resize icons */ + if (status_width != sb->width) { + /* update the window extent */ + int redraw_left, redraw_right; + + extent.x0 = 0; + extent.y0 = 0; + extent.x1 = status_width; + extent.y1 = status_height - 4; + error = xwimp_set_extent(sb->w, &extent); + if (error) { + LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess); + return; + } + + /* re-open the nested window */ + state.w = sb->w; + state.xscroll = 0; + state.yscroll = 0; + state.next = wimp_TOP; + state.visible.x0 = state.visible.x0; + state.visible.y1 = state.visible.y0 - 2; + state.visible.x1 = state.visible.x0 + status_width; + state.visible.y0 = state.visible.y1 - status_height + 4; + error = xwimp_open_window_nested(PTR_WIMP_OPEN(&state), + sb->parent, + wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT + << wimp_CHILD_XORIGIN_SHIFT | + wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT + << wimp_CHILD_YORIGIN_SHIFT | + wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT + << wimp_CHILD_LS_EDGE_SHIFT | + wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT + << wimp_CHILD_BS_EDGE_SHIFT | + wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT + << wimp_CHILD_RS_EDGE_SHIFT | + wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT + << wimp_CHILD_TS_EDGE_SHIFT); + if (error) { + LOG("xwimp_open_window_nested: 0x%x: %s", error->errnum, error->errmess); + return; + } + ro_gui_status_position_progress_bar(sb); + error = xwimp_resize_icon(sb->w, ICON_WIDGET, + status_width - WIDGET_WIDTH, 0, + status_width, status_height - 4); + if (error) { + LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess); + return; + } + + redraw_left = min(status_width, sb->width) - WIDGET_WIDTH - 2; + redraw_right = max(status_width, sb->width); + xwimp_force_redraw(sb->w, redraw_left, 0, + redraw_right, status_height); + sb->width = status_width; + } +} + + +/** + * Process a WIMP redraw request + * + * \param redraw the redraw request to process + */ +void ro_gui_status_bar_redraw(wimp_draw *redraw) +{ + struct status_bar *sb; + os_error *error; + osbool more; + rufl_code code; + + sb = (struct status_bar *)ro_gui_wimp_event_get_user_data(redraw->w); + assert(sb); + + /* initialise the plotters */ + ro_plot_origin_x = 0; + ro_plot_origin_y = 0; + + /* redraw the window */ + error = xwimp_redraw_window(redraw, &more); + if (error) { + LOG("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess); + return; + } + while (more) { + /* redraw the status text */ + if (sb->text) { + error = xcolourtrans_set_font_colours(font_CURRENT, + 0xeeeeee00, 0x00000000, 14, 0, 0, 0); + if (error) { + LOG("xcolourtrans_set_font_colours: 0x%x: %s", error->errnum, error->errmess); + return; + } + code = rufl_paint(ro_gui_desktop_font_family, + ro_gui_desktop_font_style, + ro_gui_desktop_font_size, + sb->text, strlen(sb->text), + redraw->box.x0 + 6, redraw->box.y0 + 8, + rufl_BLEND_FONT); + if (code != rufl_OK) { + if (code == rufl_FONT_MANAGER_ERROR) + LOG("rufl_FONT_MANAGER_ERROR: 0x%x: %s", rufl_fm_error->errnum, rufl_fm_error->errmess); + else + LOG("rufl_paint: 0x%x", code); + } + } + + /* separate the widget from the text with a line */ + ro_plotters.rectangle((redraw->box.x0 + sb->width - WIDGET_WIDTH - 2) >> 1, + -redraw->box.y0 >> 1, + (redraw->box.x0 + sb->width - WIDGET_WIDTH) >> 1, + -redraw->box.y1 >> 1, + plot_style_fill_black); + + error = xwimp_get_rectangle(redraw, &more); + if (error) { + LOG("xwimp_get_rectangle: 0x%x: %s", error->errnum, error->errmess); + return; + } + } +} + +/** + * Callback for scheduled redraw + * + * \param handle Callback handle + */ +void ro_gui_status_bar_redraw_callback(void *handle) +{ + struct status_bar *sb = handle; + + wimp_force_redraw(sb->w, 0, 0, sb->width - WIDGET_WIDTH, 65536); +} + + +/** + * Process an mouse_click event for a status window. + * + * \param pointer details of the mouse click + */ +bool ro_gui_status_bar_click(wimp_pointer *pointer) +{ + wimp_drag drag; + os_error *error; + + switch (pointer->i) { + case ICON_WIDGET: + drag.w = pointer->w; + drag.type = wimp_DRAG_SYSTEM_SIZE; + drag.initial.x0 = pointer->pos.x; + drag.initial.x1 = pointer->pos.x; + drag.initial.y0 = pointer->pos.y; + drag.initial.y1 = pointer->pos.y; + error = xwimp_drag_box(&drag); + if (error) { + LOG("xwimp_drag_box: 0x%x: %s", error->errnum, error->errmess); + } + break; + } + return true; +} + + +/** + * Process an open_window request for a status window. + * + * \param open the request to process + */ +void ro_gui_status_bar_open(wimp_open *open) +{ + struct status_bar *sb; + int window_width, status_width; + wimp_window_state state; + os_error *error; + + /* get the parent width for scaling */ + sb = (struct status_bar *)ro_gui_wimp_event_get_user_data(open->w); + state.w = sb->parent; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + return; + } + window_width = state.visible.x1 - state.visible.x0; + if (window_width == 0) + window_width = 1; + status_width = open->visible.x1 - open->visible.x0; + if (status_width <= 12) + status_width = 0; + + /* store the new size */ + sb->scale = (10000 * status_width) / window_width; + if (sb->scale > 10000) + sb->scale = 10000; + ro_gui_status_bar_resize(sb); +} + + +/** + * Reposition the progress component following a change in the + * dimension of the status window. + * + * \param sb the status bar to update + */ +void ro_gui_status_position_progress_bar(struct status_bar *sb) +{ + wimp_window_state state; + os_error *error; + int left, right; + + if (!sb) + return; + if (ro_gui_progress_bar_get_range(sb->pb) == 0) + return; + + /* get the window work area dimensions */ + state.w = sb->w; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + return; + } + + /* calculate the dimensions */ + right = state.visible.x1 - WIDGET_WIDTH - 2; + left = max(state.visible.x0, right - PROGRESS_WIDTH); + + /* re-open the nested window */ + state.w = ro_gui_progress_bar_get_window(sb->pb); + state.xscroll = 0; + state.yscroll = 0; + state.next = wimp_TOP; + state.visible.x0 = left; + state.visible.x1 = right; + error = xwimp_open_window_nested(PTR_WIMP_OPEN(&state), + sb->w, + wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT + << wimp_CHILD_XORIGIN_SHIFT | + wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT + << wimp_CHILD_YORIGIN_SHIFT | + wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT + << wimp_CHILD_LS_EDGE_SHIFT | + wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT + << wimp_CHILD_BS_EDGE_SHIFT | + wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT + << wimp_CHILD_RS_EDGE_SHIFT | + wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT + << wimp_CHILD_TS_EDGE_SHIFT); + if (error) { + LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess); + } + + /* update the progress bar display on non-standard width */ + if ((right - left) != PROGRESS_WIDTH) + ro_gui_progress_bar_update(sb->pb, right - left, + state.visible.y1 - state.visible.y0); +} diff --git a/frontends/riscos/gui/status_bar.h b/frontends/riscos/gui/status_bar.h new file mode 100644 index 000000000..8b5bb35aa --- /dev/null +++ b/frontends/riscos/gui/status_bar.h @@ -0,0 +1,45 @@ +/* + * Copyright 2006 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * UTF8 status bar (interface). + */ + +#ifndef _NETSURF_RISCOS_STATUS_BAR_H_ +#define _NETSURF_RISCOS_STATUS_BAR_H_ + +#include <stdbool.h> + +struct status_bar; + +struct status_bar *ro_gui_status_bar_create(wimp_w parent, unsigned int width); +void ro_gui_status_bar_destroy(struct status_bar *sb); + +wimp_w ro_gui_status_bar_get_window(struct status_bar *sb); +unsigned int ro_gui_status_bar_get_width(struct status_bar *sb); +void ro_gui_status_bar_resize(struct status_bar *sb); +void ro_gui_status_bar_set_visible(struct status_bar *pb, bool visible); +bool ro_gui_status_bar_get_visible(struct status_bar *sb); +void ro_gui_status_bar_set_text(struct status_bar *sb, const char *text); +void ro_gui_status_bar_set_progress_value(struct status_bar *sb, + unsigned int value); +void ro_gui_status_bar_set_progress_range(struct status_bar *sb, + unsigned int range); +void ro_gui_status_bar_set_progress_icon(struct status_bar *sb, + const char *icon); +#endif diff --git a/frontends/riscos/gui/throbber.c b/frontends/riscos/gui/throbber.c new file mode 100644 index 000000000..a326f806c --- /dev/null +++ b/frontends/riscos/gui/throbber.c @@ -0,0 +1,418 @@ +/* + * Copyright 2004, 2005 Richard Wilson <info@tinct.net> + * Copyright 2011 Stephen Fryatt <stevef@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Throbber (implementation). + */ + +#include <alloca.h> +#include <assert.h> +#include <stdio.h> +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> +#include "oslib/os.h" +#include "oslib/osspriteop.h" +#include "oslib/wimp.h" + +#include "utils/log.h" +#include "riscos/gui.h" + +#include "riscos/gui/throbber.h" +#include "riscos/theme.h" +#include "riscos/wimp.h" + +#define THROBBER_SPRITE_NAME_LENGTH 12 +#define THROBBER_ANIMATE_INTERVAL 10 + +struct throbber { + /** The applied theme (or NULL to use the default) */ + struct theme_descriptor *theme; + + /** The widget dimensions. */ + int x_min, y_min; + + /** The window and icon details. */ + wimp_w window; + wimp_i icon; + os_box extent; + osspriteop_area *sprites; + bool hidden; + bool shaded; + + /** The animation details. */ + int max_frame; + int current_frame; + os_t last_update; + char sprite_name[THROBBER_SPRITE_NAME_LENGTH]; + bool force_redraw; +}; + +/* + * Private function prototypes. + */ + +static bool ro_gui_throbber_icon_update(struct throbber *throbber); +static bool ro_gui_throbber_icon_resize(struct throbber *throbber); + +/* This is an exported interface documented in throbber.h */ + +struct throbber *ro_gui_throbber_create(struct theme_descriptor *theme) +{ + struct throbber *throbber; + + /* Allocate memory. */ + + throbber = malloc(sizeof(struct throbber)); + if (throbber == NULL) { + LOG("No memory for malloc()"); + return NULL; + } + + /* Set up default parameters. If reading the throbber theme data + * fails, we give up and return a failure. + */ + + if (!ro_gui_theme_get_throbber_data(theme, &throbber->max_frame, + &throbber->x_min, &throbber->y_min, NULL, + &throbber->force_redraw)) { + free(throbber); + return NULL; + } + + throbber->sprites = ro_gui_theme_get_sprites(theme); + + throbber->theme = theme; + + throbber->extent.x0 = 0; + throbber->extent.y0 = 0; + throbber->extent.x1 = 0; + throbber->extent.y1 = 0; + + throbber->current_frame = 0; + throbber->last_update = 0; + + throbber->window = NULL; + throbber->icon = -1; + + throbber->hidden = false; + throbber->shaded = false; + + return throbber; +} + + +/* This is an exported interface documented in throbber.h */ + +bool ro_gui_throbber_rebuild(struct throbber *throbber, + struct theme_descriptor *theme, theme_style style, + wimp_w window, bool shaded) +{ + if (throbber == NULL) + return false; + + throbber->theme = theme; + throbber->window = window; + throbber->sprites = ro_gui_theme_get_sprites(theme); + + throbber->icon = -1; + + throbber->shaded = shaded; + + strcpy(throbber->sprite_name, "throbber0"); + + if (!ro_gui_theme_get_throbber_data(theme, &throbber->max_frame, + &throbber->x_min, &throbber->y_min, NULL, + &throbber->force_redraw)) { + free(throbber); + return false; + } + + return ro_gui_throbber_icon_update(throbber); +} + + +/* This is an exported interface documented in throbber.h */ + +void ro_gui_throbber_destroy(struct throbber *throbber) +{ + if (throbber == NULL) + return; + + free(throbber); +} + + +/* This is an exported interface documented in throbber.h */ + +bool ro_gui_throbber_get_dims(struct throbber *throbber, + int *width, int *height) +{ + if (throbber == NULL) + return false; + + if (throbber->x_min != -1 && throbber->y_min != -1) { + if (width != NULL) + *width = throbber->x_min; + if (height != NULL) + *height = throbber->y_min; + + return true; + } + + return false; +} + + +/* This is an exported interface documented in throbber.h */ + +bool ro_gui_throbber_set_extent(struct throbber *throbber, + int x0, int y0, int x1, int y1) +{ + if (throbber == NULL) + return false; + + if ((x1 - x0) < throbber->x_min || (y1 - y0) < throbber->y_min) + return false; + + if (throbber->extent.x0 == x0 && throbber->extent.y0 == y0 && + throbber->extent.x1 == x1 && + throbber->extent.y1 == y1) + return true; + + /* Redraw the relevant bits of the toolbar. */ + + if (throbber->window != NULL && throbber->icon != -1) { + xwimp_force_redraw(throbber->window, + throbber->extent.x0, throbber->extent.y0, + throbber->extent.x1, throbber->extent.y1); + xwimp_force_redraw(throbber->window, x0, y0, x1, y1); + } + + /* Update the throbber position */ + + throbber->extent.x0 = x0; + throbber->extent.y0 = y0; + throbber->extent.x1 = x1; + throbber->extent.y1 = y1; + + return ro_gui_throbber_icon_resize(throbber); +} + + +/** + * Create or delete a throbber's icon if required to bring it into sync with + * the current hidden setting. + * + * \param *throbber The throbber to update. + * \return true if successful; else false. + */ + +bool ro_gui_throbber_icon_update(struct throbber *throbber) +{ + wimp_icon_create icon; + os_error *error; + + if (throbber == NULL || throbber->window == NULL) + return false; + + if (!throbber->hidden && throbber->icon == -1) { + icon.w = throbber->window; + icon.icon.extent.x0 = throbber->extent.x0; + icon.icon.extent.y0 = throbber->extent.y0; + icon.icon.extent.x1 = throbber->extent.x1; + icon.icon.extent.y1 = throbber->extent.y1; + icon.icon.flags = wimp_ICON_SPRITE | wimp_ICON_INDIRECTED | + wimp_ICON_HCENTRED | wimp_ICON_VCENTRED; + icon.icon.data.indirected_sprite.id = + (osspriteop_id) throbber->sprite_name; + icon.icon.data.indirected_sprite.area = throbber->sprites; + icon.icon.data.indirected_sprite.size = + THROBBER_SPRITE_NAME_LENGTH; + + error = xwimp_create_icon(&icon, &throbber->icon); + if (error != NULL) { + LOG("xwimp_create_icon: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + throbber->icon = -1; + return false; + } + + if (!ro_gui_throbber_icon_resize(throbber)) + return false; + } else if (throbber->hidden && throbber->icon != -1) { + error = xwimp_delete_icon(throbber->window, throbber->icon); + if (error != NULL) { + LOG("xwimp_delete_icon: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + + throbber->icon = -1; + } + + if (throbber->icon != -1) + ro_gui_set_icon_shaded_state(throbber->window, + throbber->icon, throbber->shaded); + + return true; +} + + +/** + * Position the icons in the throbber to take account of the currently + * configured extent. + * + * \param *throbber The throbber to update. + * \return true if successful; else false. + */ + +bool ro_gui_throbber_icon_resize(struct throbber *throbber) +{ + + if (throbber->window == NULL) + return false; + + if (throbber->icon != -1) { + os_error *error; + error = xwimp_resize_icon(throbber->window, throbber->icon, + throbber->extent.x0, throbber->extent.y0, + throbber->extent.x1, throbber->extent.y1); + if (error != NULL) { + LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + throbber->icon = -1; + return false; + } + } + + return true; +} + + +/* This is an exported interface documented in throbber.h */ + +bool ro_gui_throbber_hide(struct throbber *throbber, bool hide) +{ + if (throbber == NULL || throbber->hidden == hide) + return (throbber == NULL) ? false : true; + + throbber->hidden = hide; + + return ro_gui_throbber_icon_update(throbber); +} + + +/* This is an exported interface documented in throbber.h */ + +bool ro_gui_throbber_help_suffix(struct throbber *throbber, wimp_i i, + os_coord *mouse, wimp_window_state *state, + wimp_mouse_state buttons, const char **suffix) +{ + os_coord pos; + + if (throbber == NULL || throbber->hidden) + return false; + + /* Check that the click was within our part of the window. */ + + pos.x = mouse->x - state->visible.x0 + state->xscroll; + pos.y = mouse->y - state->visible.y1 + state->yscroll; + + if (pos.x < throbber->extent.x0 || pos.x > throbber->extent.x1 || + pos.y < throbber->extent.y0 || + pos.y > throbber->extent.y1) + return false; + + /* Return a hard-coded icon number that matches the one that was + * always allocated to the throbber in a previous implementation. + * If Messages can be updated, this could be changed. + */ + + if (i == throbber->icon) + *suffix = "16"; + else + *suffix = ""; + + return true; +} + + +/* This is an exported interface documented in throbber.h */ + +bool ro_gui_throbber_animate(struct throbber *throbber) +{ + os_t t; + char sprite_name[THROBBER_SPRITE_NAME_LENGTH]; + + if (throbber == NULL || throbber->hidden) + return (throbber == NULL) ? false : true; + + xos_read_monotonic_time(&t); + + /* Drop out if we're not ready for the next frame, unless this + * call is to start animation from a stopped throbber (ie. if + * the current frame is 0). + */ + + if ((t < (throbber->last_update + THROBBER_ANIMATE_INTERVAL)) && + (throbber->current_frame > 0)) + return true; + + throbber->last_update = t; + throbber->current_frame++; + + if (throbber->current_frame > throbber->max_frame) + throbber->current_frame = 1; + + snprintf(sprite_name, THROBBER_SPRITE_NAME_LENGTH, + "throbber%i", throbber->current_frame); + ro_gui_set_icon_string(throbber->window, throbber->icon, + sprite_name, true); + + if (throbber->force_redraw) + ro_gui_force_redraw_icon(throbber->window, throbber->icon); + + return true; +} + + +/* This is an exported interface documented in throbber.h */ + +bool ro_gui_throbber_stop(struct throbber *throbber) +{ + char sprite_name[THROBBER_SPRITE_NAME_LENGTH]; + + if (throbber == NULL || throbber->hidden || + throbber->current_frame == 0) + return (throbber == FALSE) ? false : true; + + throbber->current_frame = 0; + throbber->last_update = 0; + + strcpy(sprite_name, "throbber0"); + ro_gui_set_icon_string(throbber->window, throbber->icon, + sprite_name, true); + + if (throbber->force_redraw) + ro_gui_force_redraw_icon(throbber->window, throbber->icon); + + return true; +} + diff --git a/frontends/riscos/gui/throbber.h b/frontends/riscos/gui/throbber.h new file mode 100644 index 000000000..6b2419b6e --- /dev/null +++ b/frontends/riscos/gui/throbber.h @@ -0,0 +1,147 @@ +/* + * Copyright 2005 Richard Wilson <info@tinct.net> + * Copyright 2011 Stephen Fryatt <stevef@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Throbber (interface). + */ + +#ifndef _NETSURF_RISCOS_THROBBER_H_ +#define _NETSURF_RISCOS_THROBBER_H_ + +#include <stdbool.h> +#include "riscos/theme.h" + +struct throbber; + + +/** + * Create a new throbber widget. + * + * \param *theme The theme to apply (or NULL for the default). + * \return A throbber handle, or NULL on failure. + */ + +struct throbber *ro_gui_throbber_create(struct theme_descriptor *theme); + +/** + * Place a throbber into a toolbar window and initialise any theme-specific + * settings. Any previous incarnation of the throbber will be forgotten: this + * is for use when a new toolbar is being created, or when a toolbar has been + * deleted and rebuilt following a theme change. + * + * \param *throbber The throbber to rebuild. + * \param *theme The theme to apply (or NULL for current). + * \param style The theme style to apply. + * \param window The window that the throbber is in. + * \param shaded true if the bar should be throbber; else false. + * \return true on success; else false. + */ + +bool ro_gui_throbber_rebuild(struct throbber *throbber, + struct theme_descriptor *theme, theme_style style, + wimp_w window, bool shaded); + + +/** + * Destroy a throbber widget. + * + * \param *throbber The throbber to destroy. + */ + +void ro_gui_throbber_destroy(struct throbber *throbber); + + +/** + * Return the MINIMUM dimensions required by the throbber, in RO units, + * allowing for the current theme. + * + * \param *throbber The throbber of interest. + * \param *width Return the required width. + * \param *height Return the required height. + * \return true if values are returned; else false. + */ + +bool ro_gui_throbber_get_dims(struct throbber *throbber, + int *width, int *height); + + +/** + * Set or update the dimensions to be used by the throbber in RO units + * + * If these are greater than the minimum required, the throbber will fill + * the extended space; if less, the call will fail. + * + * \param throbber The throbber to update. + * \param x0 top left of bounding box x coordinate + * \param y0 top left of bounding box y coordinate + * \param x1 bottom right of bounding box x coordinate + * \param y1 bottom right of bounding box y coordinate + * \return true if size updated; else false. + */ + +bool ro_gui_throbber_set_extent(struct throbber *throbber, + int x0, int y0, int x1, int y1); + + +/** + * Show or hide a throbber. + * + * \param *throbber The throbber to hide. + * \param hide true to hide the throbber; false to show it. + * \return true if successful; else false. + */ + +bool ro_gui_throbber_hide(struct throbber *throbber, bool hide); + + +/** + * Translate mouse data into an interactive help message for the throbber. + * + * \param throbber The throbber to process. + * \param i The wimp icon under the pointer. + * \param screenpos The screen position. + * \param state The toolbar window state. + * \param buttons The mouse button state. + * \param suffix Return a help token suffix, or "" for none. + * \return true if handled exclusively; else false. + */ + +bool ro_gui_throbber_help_suffix(struct throbber *throbber, wimp_i i, + os_coord *screenpos, wimp_window_state *state, + wimp_mouse_state buttons, const char **suffix); + +/** + * Start or update the amimation of a throbber. + * + * \param *throbber The throbber to amimate. + */ + +bool ro_gui_throbber_animate(struct throbber *throbber); + + +/** + * Stop the amimation of a throbber. + * + * \param *throbber The throbber to amimate. + */ + +bool ro_gui_throbber_stop(struct throbber *throbber); + +#endif + diff --git a/frontends/riscos/gui/url_bar.c b/frontends/riscos/gui/url_bar.c new file mode 100644 index 000000000..053014784 --- /dev/null +++ b/frontends/riscos/gui/url_bar.c @@ -0,0 +1,1344 @@ +/* + * Copyright 2004, 2005 Richard Wilson <info@tinct.net> + * Copyright 2011-2014 Stephen Fryatt <stevef@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * URL bars (implementation). + */ + +#include <alloca.h> +#include <assert.h> +#include <stdio.h> +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> +#include "oslib/os.h" +#include "oslib/osspriteop.h" +#include "oslib/wimp.h" + +#include "utils/log.h" +#include "utils/messages.h" +#include "utils/utf8.h" +#include "utils/utils.h" +#include "content/hlcache.h" +#include "content/content.h" +#include "desktop/browser.h" +#include "desktop/plotters.h" + +#include "riscos/gui.h" +#include "riscos/hotlist.h" +#include "riscos/gui/url_bar.h" +#include "riscos/theme.h" +#include "riscos/url_suggest.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" +#include "riscos/window.h" +#include "riscos/ucstables.h" +#include "riscos/filetype.h" + +#define URLBAR_HEIGHT 52 +#define URLBAR_FAVICON_SIZE 16 +#define URLBAR_HOTLIST_SIZE 17 +#define URLBAR_FAVICON_WIDTH ((5 + URLBAR_FAVICON_SIZE + 5) * 2) +#define URLBAR_HOTLIST_WIDTH ((5 + URLBAR_HOTLIST_SIZE + 5) * 2) +#define URLBAR_MIN_WIDTH 52 +#define URLBAR_GRIGHT_GUTTER 8 +#define URLBAR_FAVICON_NAME_LENGTH 12 + +struct url_bar { + /** The applied theme (or NULL to use the default) */ + struct theme_descriptor *theme; + + /** The widget dimensions. */ + int x_min, y_min; + + /** The window and icon details. */ + wimp_w window; + os_box extent; + + wimp_i container_icon; + + char favicon_sprite[URLBAR_FAVICON_NAME_LENGTH]; + int favicon_type; + struct hlcache_handle *favicon_content; + os_box favicon_extent; + os_coord favicon_offset; + int favicon_width, favicon_height; + + wimp_i text_icon; + char *text_buffer; + size_t text_size; + char *text_buffer_utf8; + + wimp_i suggest_icon; + int suggest_x, suggest_y; + + bool hidden; + bool display; + bool shaded; + + struct { + bool set; + os_box extent; + os_coord offset; + } hotlist; +}; + +static char text_validation[] = "Pptr_write;KN"; +static char suggest_icon[] = "gright"; +static char suggest_validation[] = "R5;Sgright,pgright"; +static char null_text_string[] = ""; + +struct url_bar_resource { + const char *url; + struct hlcache_handle *c; + int height; + bool ready; +}; /**< Treeview content resource data */ +enum url_bar_resource_id { + URLBAR_RES_HOTLIST_ADD = 0, + URLBAR_RES_HOTLIST_REMOVE, + URLBAR_RES_LAST +}; +static struct url_bar_resource url_bar_res[URLBAR_RES_LAST] = { + { "resource:icons/hotlist-add.png", NULL, 0, false }, + { "resource:icons/hotlist-rmv.png", NULL, 0, false } +}; /**< Treeview content resources */ + + +static void ro_gui_url_bar_set_hotlist(struct url_bar *url_bar, bool set); + + +/* This is an exported interface documented in url_bar.h */ + +struct url_bar *ro_gui_url_bar_create(struct theme_descriptor *theme) +{ + struct url_bar *url_bar; + + /* Allocate memory. */ + + url_bar = malloc(sizeof(struct url_bar)); + if (url_bar == NULL) { + LOG("No memory for malloc()"); + return NULL; + } + + /* Set up default parameters. */ + + url_bar->theme = theme; + + url_bar->display = false; + url_bar->shaded = false; + + url_bar->x_min = URLBAR_FAVICON_WIDTH + URLBAR_MIN_WIDTH + + URLBAR_HOTLIST_WIDTH; + url_bar->y_min = URLBAR_HEIGHT; + + url_bar->extent.x0 = 0; + url_bar->extent.y0 = 0; + url_bar->extent.x1 = 0; + url_bar->extent.y1 = 0; + + url_bar->window = NULL; + url_bar->container_icon = -1; + url_bar->text_icon = -1; + url_bar->suggest_icon = -1; + + url_bar->favicon_extent.x0 = 0; + url_bar->favicon_extent.y0 = 0; + url_bar->favicon_extent.x1 = 0; + url_bar->favicon_extent.y1 = 0; + url_bar->favicon_width = 0; + url_bar->favicon_height = 0; + url_bar->favicon_content = NULL; + url_bar->favicon_type = 0; + strncpy(url_bar->favicon_sprite, "Ssmall_xxx", + URLBAR_FAVICON_NAME_LENGTH); + + url_bar->hotlist.set = false; + url_bar->hotlist.extent.x0 = 0; + url_bar->hotlist.extent.y0 = 0; + url_bar->hotlist.extent.x1 = 0; + url_bar->hotlist.extent.y1 = 0; + + url_bar->text_size = RO_GUI_MAX_URL_SIZE; + url_bar->text_buffer = malloc(url_bar->text_size); + if (url_bar->text_buffer == NULL) { + free(url_bar); + return NULL; + } + url_bar->text_buffer[0] = 0; + url_bar->text_buffer_utf8 = NULL; + + url_bar->hidden = false; + + return url_bar; +} + + +/** + * Position the icons in the URL bar to take account of the currently + * configured extent. + * + * \param *url_bar The URL bar to update. + * \param full true to resize everything; false to move only + * the right-hand end of the bar. + * \return true if successful; else false. + */ + +static bool ro_gui_url_bar_icon_resize(struct url_bar *url_bar, bool full) +{ + int x0, y0, x1, y1; + int centre; + os_error *error; + os_coord eig = {1, 1}; + wimp_caret caret; + + if (url_bar == NULL || url_bar->window == NULL) + return false; + + /* calculate 1px in OS units */ + ro_convert_pixels_to_os_units(&eig, (os_mode) -1); + + /* The vertical centre line of the widget's extent. */ + + centre = url_bar->extent.y0 + + (url_bar->extent.y1 - url_bar->extent.y0) / 2; + + /* Position the container icon. */ + + if (url_bar->container_icon != -1) { + x0 = url_bar->extent.x0; + x1 = url_bar->extent.x1 - + url_bar->suggest_x - URLBAR_GRIGHT_GUTTER; + + y0 = centre - (URLBAR_HEIGHT / 2); + y1 = y0 + URLBAR_HEIGHT; + + error = xwimp_resize_icon(url_bar->window, + url_bar->container_icon, + x0, y0, x1, y1); + if (error != NULL) { + LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + url_bar->container_icon = -1; + return false; + } + } + + /* Position the URL Suggest icon. */ + + if (url_bar->suggest_icon != -1) { + x0 = url_bar->extent.x1 - url_bar->suggest_x; + x1 = url_bar->extent.x1; + + y0 = centre - (url_bar->suggest_y / 2); + y1 = y0 + url_bar->suggest_y; + + error = xwimp_resize_icon(url_bar->window, + url_bar->suggest_icon, + x0, y0, x1, y1); + if (error != NULL) { + LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + url_bar->suggest_icon = -1; + return false; + } + } + + /* Position the Text icon. */ + + if (url_bar->text_icon != -1) { + x0 = url_bar->extent.x0 + URLBAR_FAVICON_WIDTH; + x1 = url_bar->extent.x1 - eig.x - URLBAR_HOTLIST_WIDTH - + url_bar->suggest_x - URLBAR_GRIGHT_GUTTER; + + y0 = centre - (URLBAR_HEIGHT / 2) + eig.y; + y1 = y0 + URLBAR_HEIGHT - 2 * eig.y; + + error = xwimp_resize_icon(url_bar->window, + url_bar->text_icon, + x0, y0, x1, y1); + if (error != NULL) { + LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + url_bar->text_icon = -1; + return false; + } + + if (xwimp_get_caret_position(&caret) == NULL) { + if ((caret.w == url_bar->window) && + (caret.i == url_bar->text_icon)) { + xwimp_set_caret_position(url_bar->window, + url_bar->text_icon, caret.pos.x, + caret.pos.y, -1, caret.index); + } + } + } + + /* Position the Favicon icon. */ + + url_bar->favicon_extent.x0 = url_bar->extent.x0 + eig.x; + url_bar->favicon_extent.x1 = url_bar->extent.x0 + URLBAR_FAVICON_WIDTH; + url_bar->favicon_extent.y0 = centre - (URLBAR_HEIGHT / 2) + eig.y; + url_bar->favicon_extent.y1 = url_bar->favicon_extent.y0 + URLBAR_HEIGHT + - 2 * eig.y; + + /* Position the Hotlist icon. */ + + url_bar->hotlist.extent.x0 = url_bar->extent.x1 - eig.x - + URLBAR_HOTLIST_WIDTH - url_bar->suggest_x - + URLBAR_GRIGHT_GUTTER; + url_bar->hotlist.extent.x1 = url_bar->hotlist.extent.x0 + + URLBAR_HOTLIST_WIDTH; + url_bar->hotlist.extent.y0 = centre - (URLBAR_HEIGHT / 2) + eig.y; + url_bar->hotlist.extent.y1 = url_bar->hotlist.extent.y0 + URLBAR_HEIGHT + - 2 * eig.y; + + url_bar->hotlist.offset.x = ((url_bar->hotlist.extent.x1 - + url_bar->hotlist.extent.x0) - + (URLBAR_HOTLIST_SIZE * 2)) / 2; + url_bar->hotlist.offset.y = ((url_bar->hotlist.extent.y1 - + url_bar->hotlist.extent.y0) - + (URLBAR_HOTLIST_SIZE * 2)) / 2 - 1; + + return true; +} + + +/** + * Create or delete a URL bar's icons if required to bring it into sync with + * the current hidden setting. + * + * \param *url_bar The URL bar to update. + * \return true if successful; else false. + */ + +static bool ro_gui_url_bar_icon_update(struct url_bar *url_bar) +{ + wimp_icon_create icon; + os_error *error; + bool resize; + + if (url_bar == NULL || url_bar->window == NULL) + return false; + + icon.w = url_bar->window; + icon.icon.extent.x0 = 0; + icon.icon.extent.y0 = 0; + icon.icon.extent.x1 = 0; + icon.icon.extent.y1 = 0; + + resize = false; + + /* Create or delete the container icon. */ + + if (!url_bar->hidden && url_bar->container_icon == -1) { + icon.icon.flags = wimp_ICON_BORDER | + (wimp_COLOUR_BLACK << + wimp_ICON_FG_COLOUR_SHIFT) | + (wimp_BUTTON_DOUBLE_CLICK_DRAG << + wimp_ICON_BUTTON_TYPE_SHIFT); + error = xwimp_create_icon(&icon, &url_bar->container_icon); + if (error != NULL) { + LOG("xwimp_create_icon: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + url_bar->container_icon = -1; + return false; + } + + resize = true; + } else if (url_bar->hidden && url_bar->container_icon != -1){ + error = xwimp_delete_icon(url_bar->window, + url_bar->container_icon); + if (error != NULL) { + LOG("xwimp_delete_icon: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + + url_bar->container_icon = -1; + } + + /* Create or delete the text icon. */ + + if (!url_bar->hidden && url_bar->text_icon == -1) { + icon.icon.data.indirected_text.text = url_bar->text_buffer; + icon.icon.data.indirected_text.validation = text_validation; + icon.icon.data.indirected_text.size = url_bar->text_size; + icon.icon.flags = wimp_ICON_TEXT | wimp_ICON_INDIRECTED | + wimp_ICON_VCENTRED | wimp_ICON_FILLED | + (wimp_COLOUR_BLACK << + wimp_ICON_FG_COLOUR_SHIFT); + if (url_bar->display) + icon.icon.flags |= (wimp_BUTTON_NEVER << + wimp_ICON_BUTTON_TYPE_SHIFT); + else + icon.icon.flags |= (wimp_BUTTON_WRITE_CLICK_DRAG << + wimp_ICON_BUTTON_TYPE_SHIFT); + error = xwimp_create_icon(&icon, &url_bar->text_icon); + if (error) { + LOG("xwimp_create_icon: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + url_bar->text_icon = -1; + return false; + } + + resize = true; + } else if (url_bar->hidden && url_bar->text_icon != -1) { + error = xwimp_delete_icon(url_bar->window, + url_bar->text_icon); + if (error != NULL) { + LOG("xwimp_delete_icon: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + + url_bar->text_icon = -1; + } + + /* Create or delete the suggest icon. */ + + if (!url_bar->hidden && url_bar->suggest_icon == -1) { + icon.icon.data.indirected_text.text = null_text_string; + icon.icon.data.indirected_text.size = 1; + icon.icon.data.indirected_text.validation = suggest_validation; + icon.icon.flags = wimp_ICON_TEXT | wimp_ICON_SPRITE | + wimp_ICON_INDIRECTED | wimp_ICON_HCENTRED | + wimp_ICON_VCENTRED | (wimp_BUTTON_CLICK << + wimp_ICON_BUTTON_TYPE_SHIFT); + error = xwimp_create_icon(&icon, &url_bar->suggest_icon); + if (error) { + LOG("xwimp_create_icon: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + + if (!url_bar->display) + ro_gui_wimp_event_register_menu_gright(url_bar->window, + wimp_ICON_WINDOW, url_bar->suggest_icon, + ro_gui_url_suggest_menu); + + if (!ro_gui_url_bar_update_urlsuggest(url_bar)) + return false; + + resize = true; + } else if (url_bar->hidden && url_bar->suggest_icon != -1) { + ro_gui_wimp_event_deregister(url_bar->window, + url_bar->suggest_icon); + error = xwimp_delete_icon(url_bar->window, + url_bar->suggest_icon); + if (error != NULL) { + LOG("xwimp_delete_icon: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + + url_bar->suggest_icon = -1; + } + + /* If any icons were created, resize the bar. */ + + if (resize && !ro_gui_url_bar_icon_resize(url_bar, true)) + return false; + + /* If there are any icons, apply shading as necessary. */ + + if (url_bar->container_icon != -1) + ro_gui_set_icon_shaded_state(url_bar->window, + url_bar->container_icon, url_bar->shaded); + + if (url_bar->text_icon != -1) + ro_gui_set_icon_shaded_state(url_bar->window, + url_bar->text_icon, url_bar->shaded); + + if (url_bar->suggest_icon != -1) + ro_gui_set_icon_shaded_state(url_bar->window, + url_bar->suggest_icon, url_bar->shaded); + + return true; +} + + +/* This is an exported interface documented in url_bar.h */ + +bool ro_gui_url_bar_rebuild(struct url_bar *url_bar, + struct theme_descriptor *theme, theme_style style, + wimp_w window, bool display, bool shaded) +{ + if (url_bar == NULL) + return false; + + url_bar->theme = theme; + url_bar->window = window; + + url_bar->display = display; + url_bar->shaded = shaded; + + url_bar->container_icon = -1; + url_bar->text_icon = -1; + url_bar->suggest_icon = -1; + + ro_gui_wimp_get_sprite_dimensions((osspriteop_area *) -1, + suggest_icon, &url_bar->suggest_x, &url_bar->suggest_y); + + url_bar->x_min = URLBAR_FAVICON_WIDTH + URLBAR_MIN_WIDTH + + URLBAR_HOTLIST_WIDTH + URLBAR_GRIGHT_GUTTER + + url_bar->suggest_x; + url_bar->y_min = (url_bar->suggest_y > URLBAR_HEIGHT) ? + url_bar->suggest_y : URLBAR_HEIGHT; + + return ro_gui_url_bar_icon_update(url_bar); +} + + +/* This is an exported interface documented in url_bar.h */ + +void ro_gui_url_bar_destroy(struct url_bar *url_bar) +{ + if (url_bar == NULL) + return; + + if (url_bar->text_buffer_utf8 != NULL) + free(url_bar->text_buffer_utf8); + + if (url_bar->text_buffer != NULL) + free(url_bar->text_buffer); + + free(url_bar); +} + + +/* This is an exported interface documented in url_bar.h */ + +bool ro_gui_url_bar_get_dims(struct url_bar *url_bar, + int *width, int *height) +{ + if (url_bar == NULL) + return false; + + if (url_bar->x_min != -1 && url_bar->y_min != -1) { + if (width != NULL) + *width = url_bar->x_min; + if (height != NULL) + *height = url_bar->y_min; + + return true; + } + + return false; +} + + +/* This is an exported interface documented in url_bar.h */ + +bool ro_gui_url_bar_set_extent(struct url_bar *url_bar, + int x0, int y0, int x1, int y1) +{ + bool stretch; + + if (url_bar == NULL) + return false; + + if ((x1 - x0) < url_bar->x_min || (y1 - y0) < url_bar->y_min) + return false; + + if (url_bar->extent.x0 == x0 && url_bar->extent.y0 == y0 && + url_bar->extent.x1 == x1 && + url_bar->extent.y1 == y1) + return true; + + /* If it's only the length that changes, less needs to be updated. */ + + stretch = (url_bar->extent.x0 == x0 && url_bar->extent.y0 == y0 && + url_bar->extent.y1 == y1) ? true : false; + + /* Redraw the relevant bits of the toolbar. */ + + if (url_bar->window != NULL && !url_bar->hidden) { + if (stretch) { + xwimp_force_redraw(url_bar->window, + x0 + URLBAR_FAVICON_WIDTH, y0, + (x1 > url_bar->extent.x1) ? + x1 : url_bar->extent.x1, y1); + } else { + xwimp_force_redraw(url_bar->window, + url_bar->extent.x0, url_bar->extent.y0, + url_bar->extent.x1, url_bar->extent.y1); + xwimp_force_redraw(url_bar->window, x0, y0, x1, y1); + } + } + + /* Reposition the URL bar icons. */ + + url_bar->extent.x0 = x0; + url_bar->extent.y0 = y0; + url_bar->extent.x1 = x1; + url_bar->extent.y1 = y1; + + return ro_gui_url_bar_icon_resize(url_bar, !stretch); +} + + +/* This is an exported interface documented in url_bar.h */ + +bool ro_gui_url_bar_hide(struct url_bar *url_bar, bool hide) +{ + if (url_bar == NULL || url_bar->hidden == hide) + return (url_bar == NULL) ? false : true; + + url_bar->hidden = hide; + + return ro_gui_url_bar_icon_update(url_bar); +} + + +/* This is an exported interface documented in url_bar.h */ + +void ro_gui_url_bar_redraw(struct url_bar *url_bar, wimp_draw *redraw) +{ + wimp_icon icon; + struct rect clip; + bool draw_favicon = true; + bool draw_hotlist = true; + + /* Test for a valid URL bar */ + if (url_bar == NULL || url_bar->hidden) + return; + + if ((redraw->clip.x0 - (redraw->box.x0 - redraw->xscroll)) > + (url_bar->favicon_extent.x1) || + (redraw->clip.y0 - (redraw->box.y1 - redraw->yscroll)) > + (url_bar->favicon_extent.y1) || + (redraw->clip.x1 - (redraw->box.x0 - redraw->xscroll)) < + (url_bar->favicon_extent.x0) || + (redraw->clip.y1 - (redraw->box.y1 - redraw->yscroll)) < + (url_bar->favicon_extent.y0)) { + /* Favicon not in redraw area */ + draw_favicon = false; + } + + if ((redraw->clip.x0 - (redraw->box.x0 - redraw->xscroll)) > + (url_bar->hotlist.extent.x1) || + (redraw->clip.y0 - (redraw->box.y1 - redraw->yscroll)) > + (url_bar->hotlist.extent.y1) || + (redraw->clip.x1 - (redraw->box.x0 - redraw->xscroll)) < + (url_bar->hotlist.extent.x0) || + (redraw->clip.y1 - (redraw->box.y1 - redraw->yscroll)) < + (url_bar->hotlist.extent.y0)) { + /* Hotlist icon not in redraw area */ + draw_hotlist = false; + } + + if (draw_favicon) { + if (url_bar->favicon_content == NULL) { + icon.data.indirected_text.text = null_text_string; + icon.data.indirected_text.validation = + url_bar->favicon_sprite; + icon.data.indirected_text.size = 1; + icon.flags = wimp_ICON_TEXT | wimp_ICON_SPRITE | + wimp_ICON_INDIRECTED | + wimp_ICON_FILLED | + wimp_ICON_HCENTRED | + wimp_ICON_VCENTRED; + icon.extent.x0 = url_bar->favicon_extent.x0; + icon.extent.x1 = url_bar->favicon_extent.x1; + icon.extent.y0 = url_bar->favicon_extent.y0; + icon.extent.y1 = url_bar->favicon_extent.y1; + + xwimp_plot_icon(&icon); + } else { + struct content_redraw_data data; + struct redraw_context ctx = { + .interactive = true, + .background_images = true, + .plot = &ro_plotters + }; + + xwimp_set_colour(wimp_COLOUR_WHITE); + xos_plot(os_MOVE_TO, + (redraw->box.x0 - redraw->xscroll) + + url_bar->favicon_extent.x0, + (redraw->box.y1 - redraw->yscroll) + + url_bar->favicon_extent.y0); + xos_plot(os_PLOT_TO | os_PLOT_RECTANGLE, + (redraw->box.x0 - redraw->xscroll) + + url_bar->favicon_extent.x1, + (redraw->box.y1 - redraw->yscroll) + + url_bar->favicon_extent.y1); + + clip.x0 = (redraw->clip.x0 - ro_plot_origin_x) / 2; + clip.y0 = (ro_plot_origin_y - redraw->clip.y0) / 2; + clip.x1 = (redraw->clip.x1 - ro_plot_origin_x) / 2; + clip.y1 = (ro_plot_origin_y - redraw->clip.y1) / 2; + + data.x = (url_bar->favicon_extent.x0 + + url_bar->favicon_offset.x) / 2; + data.y = (url_bar->favicon_offset.y - + url_bar->favicon_extent.y1) / 2; + data.width = url_bar->favicon_width; + data.height = url_bar->favicon_height; + data.background_colour = 0xFFFFFF; + data.scale = 1; + data.repeat_x = false; + data.repeat_y = false; + + content_redraw(url_bar->favicon_content, + &data, &clip, &ctx); + } + } + + if (draw_hotlist) { + struct content_redraw_data data; + struct redraw_context ctx = { + .interactive = true, + .background_images = true, + .plot = &ro_plotters + }; + struct url_bar_resource *hotlist_icon = url_bar->hotlist.set ? + &(url_bar_res[URLBAR_RES_HOTLIST_REMOVE]) : + &(url_bar_res[URLBAR_RES_HOTLIST_ADD]); + + xwimp_set_colour(wimp_COLOUR_WHITE); + xos_plot(os_MOVE_TO, + (redraw->box.x0 - redraw->xscroll) + + url_bar->hotlist.extent.x0, + (redraw->box.y1 - redraw->yscroll) + + url_bar->hotlist.extent.y0); + xos_plot(os_PLOT_TO | os_PLOT_RECTANGLE, + (redraw->box.x0 - redraw->xscroll) + + url_bar->hotlist.extent.x1, + (redraw->box.y1 - redraw->yscroll) + + url_bar->hotlist.extent.y1); + + if (hotlist_icon->ready == false) { + return; + } + + clip.x0 = (redraw->clip.x0 - ro_plot_origin_x) / 2; + clip.y0 = (ro_plot_origin_y - redraw->clip.y0) / 2; + clip.x1 = (redraw->clip.x1 - ro_plot_origin_x) / 2; + clip.y1 = (ro_plot_origin_y - redraw->clip.y1) / 2; + + data.x = (url_bar->hotlist.extent.x0 + + url_bar->hotlist.offset.x) / 2; + data.y = (url_bar->hotlist.offset.y - + url_bar->hotlist.extent.y1) / 2; + data.width = URLBAR_HOTLIST_SIZE; + data.height = URLBAR_HOTLIST_SIZE; + data.background_colour = 0xFFFFFF; + data.scale = 1; + data.repeat_x = false; + data.repeat_y = false; + + content_redraw(hotlist_icon->c, &data, &clip, &ctx); + } +} + + +/* This is an exported interface documented in url_bar.h */ + +bool ro_gui_url_bar_click(struct url_bar *url_bar, + wimp_pointer *pointer, wimp_window_state *state, + url_bar_action *action) +{ + os_coord pos; + + if (url_bar == NULL || url_bar->hidden || + url_bar->display || url_bar->shaded) + return false; + + /* Check that the click was within our part of the window. */ + + pos.x = pointer->pos.x - state->visible.x0 + state->xscroll; + pos.y = pointer->pos.y - state->visible.y1 + state->yscroll; + + if (pos.x < url_bar->extent.x0 || pos.x > url_bar->extent.x1 || + pos.y < url_bar->extent.y0 || + pos.y > url_bar->extent.y1) + return false; + + /* If we have a Select or Adjust click, check if it originated on the + * hotlist icon; if it did, return an event. + */ + + if (pointer->buttons == wimp_SINGLE_SELECT || + pointer->buttons == wimp_SINGLE_ADJUST) { + if (pos.x >= url_bar->hotlist.extent.x0 && + pos.x <= url_bar->hotlist.extent.x1 && + pos.y >= url_bar->hotlist.extent.y0 && + pos.y <= url_bar->hotlist.extent.y1) { + if (pointer->buttons == wimp_SINGLE_SELECT && + action != NULL) + *action = TOOLBAR_URL_SELECT_HOTLIST; + else if (pointer->buttons == wimp_SINGLE_ADJUST && + action != NULL) + *action = TOOLBAR_URL_ADJUST_HOTLIST; + return true; + } + } + + /* If we find a Select or Adjust drag, check if it originated on the + * URL bar or over the favicon. If either, then return an event. + */ + + if (pointer->buttons == wimp_DRAG_SELECT || + pointer->buttons == wimp_DRAG_ADJUST) { + if (pointer->i == url_bar->text_icon) { + if (action != NULL) + *action = TOOLBAR_URL_DRAG_URL; + return true; + } + + if (pos.x >= url_bar->favicon_extent.x0 && + pos.x <= url_bar->favicon_extent.x1 && + pos.y >= url_bar->favicon_extent.y0 && + pos.y <= url_bar->favicon_extent.y1) { + if (action != NULL) + *action = TOOLBAR_URL_DRAG_FAVICON; + return true; + } + } + + return false; +} + + +/* This is an exported interface documented in url_bar.h */ + +bool ro_gui_url_bar_menu_prepare(struct url_bar *url_bar, wimp_i i, + wimp_menu *menu, wimp_pointer *pointer) +{ + if (url_bar == NULL || url_bar->suggest_icon != i || + menu != ro_gui_url_suggest_menu) + return false; + + if (pointer != NULL) + return ro_gui_url_suggest_prepare_menu(); + + return true; +} + + +/* This is an exported interface documented in url_bar.h */ + +bool ro_gui_url_bar_menu_select(struct url_bar *url_bar, wimp_i i, + wimp_menu *menu, wimp_selection *selection, menu_action action) +{ + const char *urltxt; + struct gui_window *g; + + if (url_bar == NULL || url_bar->suggest_icon != i || + menu != ro_gui_url_suggest_menu) + return false; + + urltxt = ro_gui_url_suggest_get_selection(selection); + g = ro_gui_toolbar_lookup(url_bar->window); + + if (urltxt != NULL && g != NULL && g->bw != NULL) { + nsurl *url; + nserror error; + + error = nsurl_create(urltxt, &url); + if (error != NSERROR_OK) { + ro_warn_user(messages_get_errorcode(error), 0); + } else { + ro_gui_window_set_url(g, url); + + browser_window_navigate(g->bw, + url, + NULL, + BW_NAVIGATE_HISTORY, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + } + + return true; +} + + +/* This is an exported interface documented in url_bar.h */ + +bool ro_gui_url_bar_help_suffix(struct url_bar *url_bar, wimp_i i, + os_coord *mouse, wimp_window_state *state, + wimp_mouse_state buttons, const char **suffix) +{ + os_coord pos; + + if (url_bar == NULL || url_bar->hidden) + return false; + + /* Check that the click was within our part of the window. */ + + pos.x = mouse->x - state->visible.x0 + state->xscroll; + pos.y = mouse->y - state->visible.y1 + state->yscroll; + + if (pos.x < url_bar->extent.x0 || pos.x > url_bar->extent.x1 || + pos.y < url_bar->extent.y0 || + pos.y > url_bar->extent.y1) + return false; + + /* Return hard-coded icon numbers that match the ones that were + * always allocated to the URL bar in a previous implementation. + * If Messages can be updated, this could be changed. + */ + + if (i == url_bar->text_icon) + *suffix = "14"; + else if (i == url_bar->suggest_icon) + *suffix = "15"; + else if (pos.x >= url_bar->hotlist.extent.x0 && + pos.x <= url_bar->hotlist.extent.x1 && + pos.y >= url_bar->hotlist.extent.y0 && + pos.y <= url_bar->hotlist.extent.y1) + *suffix = "Hot"; + else if (pos.x >= url_bar->favicon_extent.x0 && + pos.x <= url_bar->favicon_extent.x1 && + pos.y >= url_bar->favicon_extent.y0 && + pos.y <= url_bar->favicon_extent.y1) + *suffix = "Fav"; + else + *suffix = ""; + + return true; +} + + +/* This is an exported interface documented in url_bar.h */ + +bool ro_gui_url_bar_take_caret(struct url_bar *url_bar) +{ + os_error *error; + + if (url_bar == NULL || url_bar->hidden) + return false; + + error = xwimp_set_caret_position(url_bar->window, url_bar->text_icon, + -1, -1, -1, 0); + if (error) { + LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + + return false; + } + + return true; +} + + +/* This is an exported interface documented in url_bar.h */ + +void ro_gui_url_bar_set_url(struct url_bar *url_bar, const char *url, + bool is_utf8, bool set_caret) +{ + wimp_caret caret; + os_error *error; + char *local_text = NULL; + const char *local_url; + nsurl *n; + + if (url_bar == NULL || url_bar->text_buffer == NULL || url == NULL) + return; + + /* Before we do anything with the URL, get it into local encoding so + * that behaviour is consistant with the rest of the URL Bar module + * (which will act on the icon's text buffer, which is always in local + * encoding). + */ + + if (is_utf8) { + nserror err; + + err = utf8_to_local_encoding(url, 0, &local_text); + if (err != NSERROR_OK) { + /* A bad encoding should never happen, so assert this */ + assert(err != NSERROR_BAD_ENCODING); + LOG("utf8_to_enc failed"); + /* Paranoia */ + local_text = NULL; + } + local_url = (local_text != NULL) ? local_text : url; + } else { + local_url = url; + } + + /* Copy the text into the icon buffer. If the text is too long, blank + * the buffer and warn the user. + */ + + if (strlen(local_url) >= url_bar->text_size) { + url_bar->text_buffer[0] = '\0'; + ro_warn_user("LongURL", NULL); + LOG("Long URL (%zu chars): %s", strlen(url), url); + } else { + strncpy(url_bar->text_buffer, local_url, + url_bar->text_size - 1); + url_bar->text_buffer[url_bar->text_size - 1] = '\0'; + } + + if (local_text != NULL) + free(local_text); + + /* Set the hotlist flag. */ + + if (nsurl_create(url_bar->text_buffer, &n) == NSERROR_OK) { + ro_gui_url_bar_set_hotlist(url_bar, ro_gui_hotlist_has_page(n)); + nsurl_unref(n); + } + + /* If there's no icon, then there's nothing else to do... */ + + if (url_bar->text_icon == -1) + return; + + /* ...if there is, redraw the icon and fix the caret's position. */ + + ro_gui_redraw_icon(url_bar->window, url_bar->text_icon); + + error = xwimp_get_caret_position(&caret); + if (error) { + LOG("xwimp_get_caret_position: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + if (set_caret || (caret.w == url_bar->window && + caret.i == url_bar->text_icon)) { + const char *set_url = ro_gui_get_icon_string(url_bar->window, + url_bar->text_icon); + + error = xwimp_set_caret_position(url_bar->window, + url_bar->text_icon, 0, 0, -1, strlen(set_url)); + if (error) { + LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + } +} + + +/* This is an exported interface documented in url_bar.h */ + +void ro_gui_url_bar_update_hotlist(struct url_bar *url_bar) +{ + const char *url; + nsurl *n; + + if (url_bar == NULL) + return; + + url = (const char *) url_bar->text_buffer; + if (url != NULL && nsurl_create(url, &n) == NSERROR_OK) { + ro_gui_url_bar_set_hotlist(url_bar, ro_gui_hotlist_has_page(n)); + nsurl_unref(n); + } +} + + +/** + * Set the state of a URL Bar's hotlist icon. + * + * \param *url_bar The URL Bar to update. + * \param set TRUE to set the hotlist icon; FALSE to clear it. + */ + +static void ro_gui_url_bar_set_hotlist(struct url_bar *url_bar, bool set) +{ + if (url_bar == NULL || set == url_bar->hotlist.set) + return; + + url_bar->hotlist.set = set; + + if (!url_bar->hidden) { + xwimp_force_redraw(url_bar->window, + url_bar->hotlist.extent.x0, + url_bar->hotlist.extent.y0, + url_bar->hotlist.extent.x1, + url_bar->hotlist.extent.y1); + } +} + + +/* This is an exported interface documented in url_bar.h */ + +const char *ro_gui_url_bar_get_url(struct url_bar *url_bar) +{ + if ((url_bar == NULL) || (url_bar->text_buffer == NULL)) + return NULL; + + if (url_bar->text_buffer_utf8 != NULL) { + free(url_bar->text_buffer_utf8); + url_bar->text_buffer_utf8 = NULL; + } + + if (url_bar->text_buffer[0] == '\0') + return (const char *) url_bar->text_buffer; + + if (utf8_from_local_encoding(url_bar->text_buffer, 0, &url_bar->text_buffer_utf8) == NSERROR_OK) { + return (const char *) url_bar->text_buffer_utf8; + } + + return (const char *) url_bar->text_buffer; +} + + +/* This is an exported interface documented in url_bar.h */ + +bool ro_gui_url_bar_get_url_extent(struct url_bar *url_bar, os_box *extent) +{ + wimp_icon_state state; + os_error *error; + + if (url_bar == NULL || url_bar->hidden) + return false; + + if (extent == NULL) + return true; + + state.w = url_bar->window; + state.i = url_bar->container_icon; + error = xwimp_get_icon_state(&state); + if (error) { + LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + + extent->x0 = state.icon.extent.x0; + extent->y0 = state.icon.extent.y0; + extent->x1 = state.icon.extent.x1; + extent->y1 = state.icon.extent.y1; + + return true; +} + + +/* This is an exported interface documented in url_bar.h */ + +bool ro_gui_url_bar_test_for_text_field_click(struct url_bar *url_bar, + wimp_pointer *pointer) +{ + if (url_bar == NULL || url_bar->hidden || pointer == NULL) + return false; + + return (pointer->w == url_bar->window && + pointer->i == url_bar->text_icon) ? true : false; +} + + +/* This is an exported interface documented in url_bar.h */ + +bool ro_gui_url_bar_test_for_text_field_keypress(struct url_bar *url_bar, + wimp_key *key) +{ + const char *url; + nsurl *n; + + if (url_bar == NULL || url_bar->hidden || key == NULL) + return false; + + if (key->w != url_bar->window || key->i != url_bar->text_icon) + return false; + + /* Update hotlist indicator */ + + url = (const char *) url_bar->text_buffer; + if (url != NULL && nsurl_create(url, &n) == NSERROR_OK) { + ro_gui_url_bar_set_hotlist(url_bar, ro_gui_hotlist_has_page(n)); + nsurl_unref(n); + } else if (url_bar->hotlist.set) { + ro_gui_url_bar_set_hotlist(url_bar, false); + } + + return true; +} + + +/* This is an exported interface documented in url_bar.h */ + +bool ro_gui_url_bar_set_site_favicon(struct url_bar *url_bar, + struct hlcache_handle *h) +{ + content_type type = CONTENT_NONE; + + if (url_bar == NULL) + return false; + + if (h != NULL) + type = content_get_type(h); + + // \TODO -- Maybe test for CONTENT_ICO ??? + + if (type == CONTENT_IMAGE) { + url_bar->favicon_content = h; + url_bar->favicon_width = content_get_width(h); + url_bar->favicon_height = content_get_height(h); + + if (url_bar->favicon_width > URLBAR_FAVICON_SIZE) + url_bar->favicon_width = URLBAR_FAVICON_SIZE; + + if (url_bar->favicon_height > URLBAR_FAVICON_SIZE) + url_bar->favicon_height = URLBAR_FAVICON_SIZE; + + url_bar->favicon_offset.x = ((url_bar->favicon_extent.x1 - + url_bar->favicon_extent.x0) - + (url_bar->favicon_width * 2)) / 2; + url_bar->favicon_offset.y = ((url_bar->favicon_extent.y1 - + url_bar->favicon_extent.y0) - + (url_bar->favicon_height * 2)) / 2; + } else { + url_bar->favicon_content = NULL; + + if (url_bar->favicon_type != 0) + snprintf(url_bar->favicon_sprite, + URLBAR_FAVICON_NAME_LENGTH, + "Ssmall_%.3x", url_bar->favicon_type); + else + snprintf(url_bar->favicon_sprite, + URLBAR_FAVICON_NAME_LENGTH, + "Ssmall_xxx"); + } + + if (!url_bar->hidden) + xwimp_force_redraw(url_bar->window, + url_bar->favicon_extent.x0, + url_bar->favicon_extent.y0, + url_bar->favicon_extent.x1, + url_bar->favicon_extent.y1); + + return true; +} + + +/* This is an exported interface documented in url_bar.h */ + +bool ro_gui_url_bar_set_content_favicon(struct url_bar *url_bar, + struct gui_window *g) +{ + int type = 0; + char sprite[URLBAR_FAVICON_NAME_LENGTH]; + struct hlcache_handle *h; + + if (url_bar == NULL || g == NULL) + return false; + + h = browser_window_get_content(g->bw); + if (h != NULL) + type = ro_content_filetype(h); + + if (type != 0) { + snprintf(sprite, URLBAR_FAVICON_NAME_LENGTH, + "small_%.3x", type); + + if (!ro_gui_wimp_sprite_exists(sprite)) + type = 0; + } + + url_bar->favicon_type = type; + + if (url_bar->favicon_content == NULL) { + if (type == 0) + snprintf(url_bar->favicon_sprite, + URLBAR_FAVICON_NAME_LENGTH, "Ssmall_xxx"); + else + snprintf(url_bar->favicon_sprite, + URLBAR_FAVICON_NAME_LENGTH, "S%s", sprite); + + if (!url_bar->hidden) + xwimp_force_redraw(url_bar->window, + url_bar->favicon_extent.x0, + url_bar->favicon_extent.y0, + url_bar->favicon_extent.x1, + url_bar->favicon_extent.y1); + } + + return true; +} + + +/* This is an exported interface documented in url_bar.h */ + +bool ro_gui_url_bar_update_urlsuggest(struct url_bar *url_bar) +{ + if (url_bar == NULL || url_bar->hidden) + return (url_bar == NULL) ? false : true; + + if (url_bar->window != NULL && url_bar->suggest_icon != -1) + ro_gui_set_icon_shaded_state(url_bar->window, + url_bar->suggest_icon, + !ro_gui_url_suggest_get_menu_available()); + + return true; +} + + +/** + * Callback for hlcache. + */ +static nserror ro_gui_url_bar_res_cb(hlcache_handle *handle, + const hlcache_event *event, void *pw) +{ + struct url_bar_resource *r = pw; + + switch (event->type) { + case CONTENT_MSG_READY: + case CONTENT_MSG_DONE: + r->ready = true; + r->height = content_get_height(handle); + break; + + default: + break; + } + + return NSERROR_OK; +} + + +/* Exported interface, documented in url_bar.h */ +bool ro_gui_url_bar_init(void) +{ + int i; + + for (i = 0; i < URLBAR_RES_LAST; i++) { + nsurl *url; + if (nsurl_create(url_bar_res[i].url, &url) == NSERROR_OK) { + hlcache_handle_retrieve(url, 0, NULL, NULL, + ro_gui_url_bar_res_cb, + &(url_bar_res[i]), NULL, + CONTENT_IMAGE, &(url_bar_res[i].c)); + nsurl_unref(url); + } + } + + return true; +} + + +/* Exported interface, documented in url_bar.h */ +void ro_gui_url_bar_fini(void) +{ + int i; + + for (i = 0; i < URLBAR_RES_LAST; i++) { + hlcache_handle_release(url_bar_res[i].c); + } +} diff --git a/frontends/riscos/gui/url_bar.h b/frontends/riscos/gui/url_bar.h new file mode 100644 index 000000000..981afb35f --- /dev/null +++ b/frontends/riscos/gui/url_bar.h @@ -0,0 +1,329 @@ +/* + * Copyright 2005 Richard Wilson <info@tinct.net> + * Copyright 2011 Stephen Fryatt <stevef@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * URL bars (interface). + */ + +#ifndef _NETSURF_RISCOS_URLBAR_H_ +#define _NETSURF_RISCOS_URLBAR_H_ + +#include <stdbool.h> +#include "riscos/menus.h" +#include "riscos/theme.h" + +/* A list of possible URL bar actions. */ + +typedef enum { + TOOLBAR_URL_NONE = 0, /* Special case: no action */ + TOOLBAR_URL_DRAG_URL, + TOOLBAR_URL_DRAG_FAVICON, + TOOLBAR_URL_SELECT_HOTLIST, + TOOLBAR_URL_ADJUST_HOTLIST +} url_bar_action; + +struct url_bar; +struct hlcache_handle; + +/** + * Initialise the url bar module. + * + * \return True iff success, else false. + */ + +bool ro_gui_url_bar_init(void); + +/** + * Finalise the url bar module + */ + +void ro_gui_url_bar_fini(void); + +/** + * Create a new url bar widget. + * + * \param *theme The theme to apply (or NULL for the default). + * \return A url bar handle, or NULL on failure. + */ + +struct url_bar *ro_gui_url_bar_create(struct theme_descriptor *theme); + + +/** + * Place a URL bar into a toolbar window and initialise any theme-specific + * settings. Any previous incarnation of the bar will be forgotten: this + * is for use when a new toolbar is being created, or when a toolbar has been + * deleted and rebuilt following a theme change. + * + * \param *url_bar The URL bar to rebuild. + * \param *theme The theme to apply (or NULL for current). + * \param style The theme style to apply. + * \param window The window that the bar is in. + * \param display true if the bar should be for display only. + * \param shaded true if the bar should be shaded; else false. + * \return true on success; else false. + */ + +bool ro_gui_url_bar_rebuild(struct url_bar *url_bar, + struct theme_descriptor *theme, theme_style style, + wimp_w window, bool display, bool shaded); + + +/** + * Destroy a url bar widget. + * + * \param *url_bar The url bar to destroy. + */ + +void ro_gui_url_bar_destroy(struct url_bar *url_bar); + + +/** + * Return the MINIMUM dimensions required by the URL bar, in RO units, + * allowing for the current theme. + * + * \param *url_bar The URL bar of interest. + * \param *width Return the required width. + * \param *height Return the required height. + * \return true if values are returned; else false. + */ + +bool ro_gui_url_bar_get_dims(struct url_bar *url_bar, + int *width, int *height); + + +/** + * Set or update the dimensions to be used by the URL bar, in RO units. + * If these are greater than the minimum required, the URL bar will fill + * the extended space; if less, the call will fail. + * + * \param *url_bar The URL bar to update. + * \param x0 The minimum X window position. + * \param y0 The minimum Y window position. + * \param x1 The maximum X window position. + * \param y1 The maximum Y window position. + * \return true if size updated; else false. + */ + +bool ro_gui_url_bar_set_extent(struct url_bar *url_bar, + int x0, int y0, int x1, int y1); + + +/** + * Show or hide a URL bar. + * + * \param *url_bar The URL bar to hide. + * \param hide true to hide the bar; false to show it. + * \return true if successful; else false. + */ + +bool ro_gui_url_bar_hide(struct url_bar *url_bar, bool hide); + + +/** + * Handle redraw event rectangles in a URL bar. + * + * \param *url_bar The URL bar to use. + * \param *redraw The Wimp redraw rectangle to process. + */ + +void ro_gui_url_bar_redraw(struct url_bar *url_bar, wimp_draw *redraw); + + +/** + * Handle mouse clicks in a URL bar. + * + * \param *url_bar The URL bar to use. + * \param *pointer The Wimp mouse click event data. + * \param *state The toolbar window state. + * \param *action Returns the selected action, or + * TOOLBAR_URL_NONE. + * \return true if the event was handled exclusively; + * else false. + */ + +bool ro_gui_url_bar_click(struct url_bar *url_bar, + wimp_pointer *pointer, wimp_window_state *state, + url_bar_action *action); + + +/** + * Process offered menu prepare events from the parent window. + * + * \param *url_bar The URL bar in question. + * \param i The icon owning the menu. + * \param *menu The menu to be prepared. + * \param *pointer The Wimp Pointer data from the event. + * \return true if the event is claimed; else false. + */ + +bool ro_gui_url_bar_menu_prepare(struct url_bar *url_bar, wimp_i i, + wimp_menu *menu, wimp_pointer *pointer); + + +/** + * Process offered menu select events from the parent window. + * + * \param *url_bar The URL bar in question. + * \param i The icon owning the menu. + * \param *menu The menu to be prepared. + * \param *selection The wimp menu selection data. + * \param action The selected menu action. + * \return true if the event is claimed; else false. + */ + +bool ro_gui_url_bar_menu_select(struct url_bar *url_bar, wimp_i i, + wimp_menu *menu, wimp_selection *selection, menu_action action); + + +/** + * Translate mouse data into an interactive help message for the URL bar. + * + * \param *url_bar The URL bar to process. + * \param i The wimp icon under the pointer. + * \param *mouse The mouse position. + * \param *state The toolbar window state. + * \param buttons The mouse button state. + * \param **suffix Return a help token suffix, or "" for none. + * \return true if handled exclusively; else false. + */ + +bool ro_gui_url_bar_help_suffix(struct url_bar *url_bar, wimp_i i, + os_coord *mouse, wimp_window_state *state, + wimp_mouse_state buttons, const char **suffix); + + +/** + * Give a URL bar input focus. + * + * \param *url_bar The URL bar to give focus to. + * \return true if successful; else false. + */ + +bool ro_gui_url_bar_take_caret(struct url_bar *url_bar); + + +/** + * Set the content of a URL Bar field. + * + * \param *url_bar The URL Bar to update. + * \param *url The new url to insert. + * \param is_utf8 true if the string is in utf8 encoding; false + * if it is in local encoding. + * \param set_caret true if the caret should be placed in the field; + * else false. + */ + +void ro_gui_url_bar_set_url(struct url_bar *url_bar, const char *url, + bool is_utf8, bool set_caret); + + +/** + * Update the state of a URL Bar's hotlist icon to reflect any changes to the + * URL or the contents of the hotlist. + * + * \param *url_bar The URL Bar to update. + */ + +void ro_gui_url_bar_update_hotlist(struct url_bar *url_bar); + + +/** + * Return a pointer to the URL contained in a URL bar. + * + * \param *url_bar The URL Bar to look up the URL from. + * \return Pointer to the URL, or NULL. + */ + +const char *ro_gui_url_bar_get_url(struct url_bar *url_bar); + + +/** + * Return the current work area coordinates of the URL and favicon field's + * bounding box. + * + * \param *url_bar The URL bar to check. + * \param *extent Returns the field extent. + * \return true if successful; else false. + */ + +bool ro_gui_url_bar_get_url_extent(struct url_bar *url_bar, os_box *extent); + + +/** + * Test a pointer click to see if it was in the URL bar's text field. + * + * \param url_bar The URL Bar to test. + * \param pointer The pointer event data to test. + * \return true if the click was in the field; else false. + */ + +bool ro_gui_url_bar_test_for_text_field_click(struct url_bar *url_bar, + wimp_pointer *pointer); + + +/** + * Test a keypress to see if it was in the URL bar's text field. + * + * \param url_bar The URL Bar to test. + * \param key The key pressed + * \return true if the keypress was in the field; else false. + */ + +bool ro_gui_url_bar_test_for_text_field_keypress(struct url_bar *url_bar, + wimp_key *key); + + +/** + * Set the favicon to a site supplied favicon image, or remove the image + * and return to using filetype-based icons. + * + * \param *url_bar The URL Bar to update the favicon on. + * \param *h The content to use, or NULL to unset. + * \return true if successful; else false. + */ + +bool ro_gui_url_bar_set_site_favicon(struct url_bar *url_bar, + struct hlcache_handle *h); + + +/** + * Set the favicon to a RISC OS filetype sprite based on the type of the + * content within the supplied window. + * + * \param *url_bar The URL Bar to update the favicon on. + * \param *g The window with the content to use. + * \return true if successful; else false. + */ + +bool ro_gui_url_bar_set_content_favicon(struct url_bar *url_bar, + struct gui_window *g); + + +/** + * Update the state of the URL suggestion pop-up menu icon on a URL bar. + * + * \param *url_bar The URL bar to update. + * \return true if successful; else false. + */ + +bool ro_gui_url_bar_update_urlsuggest(struct url_bar *url_bar); + +#endif + diff --git a/frontends/riscos/help.c b/frontends/riscos/help.c new file mode 100644 index 000000000..73cb6957d --- /dev/null +++ b/frontends/riscos/help.c @@ -0,0 +1,361 @@ +/* + * Copyright 2004, 2005 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Interactive help (implementation). + */ + +#include <oslib/wimp.h> +#include <oslib/taskmanager.h> + +#include "utils/nsoption.h" +#include "utils/log.h" +#include "utils/messages.h" +#include "utils/utf8.h" +#include "desktop/mouse.h" +#include "desktop/gui_window.h" + +#include "riscos/treeview.h" +#include "riscos/help.h" +#include "riscos/wimp_event.h" +#include "riscos/hotlist.h" +#include "riscos/global_history.h" +#include "riscos/cookies.h" +#include "riscos/wimp.h" +#include "riscos/iconbar.h" +#include "riscos/window.h" +#include "riscos/ucstables.h" +#include "riscos/gui.h" + +/* Recognised help keys + ==================== + Help keys should be registered using the wimp_event system to be + recognised. The only special case help values are: + + HelpIconbar Iconbar (no icon suffix is used) + HelpBrowser Browser window [*] + HelpHotlist Hotlist window [*] + HelpGHistory Global history window [*] + HelpCookies Cookies window [*] + + HelpIconMenu Iconbar menu + HelpBrowserMenu Browser window menu + HelpHotlistMenu Hotlist window menu + HelpGHistoryMenu Global history window menu + HelpCookiesMenu Cookie window menu + + The prefixes are followed by either the icon number (eg 'HelpToolbar7'), + or a series of numbers representing the menu structure (eg + 'HelpBrowserMenu3-1-2'). + If '<key><identifier>' is not available, then simply '<key>' is then + used. For example if 'HelpToolbar7' is not available then 'HelpToolbar' + is then tried. + If an item is greyed out then a suffix of 'g' is added (eg + 'HelpToolbar7g'). For this to work, windows must have bit 4 of the + window flag byte set and the user must be running RISC OS 5.03 or + greater. + For items marked with an asterisk [*] a call must be made to determine + the required help text as the window does not contain any icons. An + example of this is the hotlist window where ro_gui_hotlist_help() is + called. +*/ + + +static void ro_gui_interactive_help_broadcast(wimp_message *message, + char *token); +static os_t help_time = 0; + + +/** + * Attempts to process an interactive help message request + * + * \param message the request message + */ +void ro_gui_interactive_help_request(wimp_message *message) +{ + char message_token[32]; + char menu_buffer[4]; + wimp_selection menu_tree; + help_full_message_request *message_data; + wimp_w window; + wimp_i icon; + unsigned int index; + bool greyed = false; + wimp_menu *test_menu; + os_error *error; + const char *auto_text; + int i; + + /* check we aren't turned off */ + if (!nsoption_bool(interactive_help)) + return; + + /* only accept help requests */ + if ((!message) || (message->action != message_HELP_REQUEST)) + return; + + /* remember the time of the request so we can track them */ + xos_read_monotonic_time(&help_time); + + /* set up our state */ + message_token[0] = 0x00; + message_data = (help_full_message_request *)message; + window = message_data->w; + icon = message_data->i; + + /* do the basic window checks */ + auto_text = ro_gui_wimp_event_get_help_prefix(window); + if (auto_text != NULL) { + const char *auto_suffix = ro_gui_wimp_event_get_help_suffix( + window, icon, &message_data->pos, + message_data->buttons); + + if (auto_suffix == NULL) + sprintf(message_token, "%s%i", auto_text, (int)icon); + else + sprintf(message_token, "%s%s", auto_text, auto_suffix); + } else if (window == wimp_ICON_BAR) + sprintf(message_token, "HelpIconbar"); + else if (ro_gui_hotlist_check_window(message->data.data_xfer.w)) { + i = ro_treeview_get_help(message_data); + sprintf(message_token, + (i >= 0) ? "HelpTree%i" :"HelpHotlist%i", i); + } else if (ro_gui_global_history_check_window( + message->data.data_xfer.w)) { + i = ro_treeview_get_help(message_data); + sprintf(message_token, + (i >= 0) ? "HelpTree%i" :"HelpGHistory%i", i); + } else if (ro_gui_cookies_check_window(message->data.data_xfer.w)) { + i = ro_treeview_get_help(message_data); + sprintf(message_token, + (i >= 0) ? "HelpTree%i" :"HelpCookies%i", i); + } else if (ro_gui_window_lookup(window) != NULL) + sprintf(message_token, "HelpBrowser%i", (int)icon); + + /* if we've managed to find something so far then we broadcast it */ + if (message_token[0]) { + if ((icon >= 0) && + (ro_gui_get_icon_shaded_state(window, icon))) + strcat(message_token, "g"); + ro_gui_interactive_help_broadcast(message, + (char *)message_token); + return; + } + + /* if we are not on an icon, we can't be in a menu (which stops + * separators giving help for their parent) so we abort */ + if (icon == wimp_ICON_WINDOW) + return; + + /* get the current menu tree */ + error = xwimp_get_menu_state(wimp_GIVEN_WINDOW_AND_ICON, + &menu_tree, window, icon); + if (error) { + LOG("xwimp_get_menu_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + if (menu_tree.items[0] == -1) + return; + + /* get the menu prefix */ + if (ro_gui_iconbar_check_menu(current_menu)) + sprintf(message_token, "HelpIconMenu"); + else if (ro_gui_window_check_menu(current_menu)) + sprintf(message_token, "HelpBrowserMenu"); + else if (ro_gui_hotlist_check_menu(current_menu)) + sprintf(message_token, "HelpHotlistMenu"); + else if (ro_gui_global_history_check_menu(current_menu)) + sprintf(message_token, "HelpGHistoryMenu"); + else if (ro_gui_cookies_check_menu(current_menu)) + sprintf(message_token, "HelpCookiesMenu"); + else + return; + + /* decode the menu */ + index = 0; + test_menu = current_menu; + while (menu_tree.items[index] != -1) { + greyed |= test_menu->entries[menu_tree.items[index]].icon_flags + & wimp_ICON_SHADED; + test_menu = test_menu->entries[menu_tree.items[index]].sub_menu; + if (index == 0) + sprintf(menu_buffer, "%i", menu_tree.items[index]); + else + sprintf(menu_buffer, "-%i", menu_tree.items[index]); + strcat(message_token, menu_buffer); + index++; + } + if (greyed) + strcat(message_token, "g"); + ro_gui_interactive_help_broadcast(message, (char *)message_token); +} + + +/** + * Broadcasts a help reply + * + * \param message the original request message + * \param token the token to look up + */ +static void ro_gui_interactive_help_broadcast(wimp_message *message, + char *token) +{ + const char *translated_token; + help_full_message_reply *reply; + char *local_token; + os_error *error; + + /* start off with an empty reply */ + reply = (help_full_message_reply *)message; + reply->reply[0] = '\0'; + + /* check if the message exists */ + translated_token = messages_get(token); + if (translated_token == token) { + /* no default help for 'g' suffix */ + if (token[strlen(token) - 1] != 'g') { + /* find the base key from the token */ + char *base_token = token; + while (base_token[0] != 0x00) { + if ((base_token[0] == '-') || + ((base_token[0] >= '0') && + (base_token[0] <= '9'))) + base_token[0] = 0x00; + else + ++base_token; + } + translated_token = messages_get(token); + } + } + + /* copy our message string */ + if (translated_token != token) { + /* convert to local encoding */ + nserror err = utf8_to_local_encoding(translated_token, 0, + &local_token); + if (err != NSERROR_OK) { + /* badenc should never happen */ + assert(err != NSERROR_BAD_ENCODING); + /* simply use UTF-8 string */ + strncpy(reply->reply, translated_token, 235); + } + else { + strncpy(reply->reply, local_token, 235); + free(local_token); + } + reply->reply[235] = '\0'; + } + + /* broadcast the help reply */ + reply->size = 256; + reply->action = message_HELP_REPLY; + reply->your_ref = reply->my_ref; + error = xwimp_send_message(wimp_USER_MESSAGE, (wimp_message *)reply, + reply->sender); + if (error) { + LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } +} + + +/** + * Checks if interactive help is running + * + * \return non-zero if interactive help is available, or 0 if not available + */ +bool ro_gui_interactive_help_available(void) +{ + taskmanager_task task; + int context = 0; + os_t time; + + /* generic test: any help request within the last 100cs */ + xos_read_monotonic_time(&time); + if ((help_time + 100) > time) + return true; + + /* special cases: check known application names */ + do { + os_error *error; + error = xtaskmanager_enumerate_tasks(context, &task, + sizeof(taskmanager_task), &context, 0); + if (error) { + LOG("xtaskmanager_enumerate_tasks: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MiscError", error->errmess); + } + + /* we can't just use strcmp due to string termination issues */ + if (!strncmp(task.name, "Help", 4) && + (task.name[4] < 32)) + return true; + else if (!strncmp(task.name, "Bubble Help", 11) && + (task.name[11] < 32)) + return true; + else if (!strncmp(task.name, "Floating Help", 13) && + (task.name[13] < 32)) + return true; + } while (context >= 0); + return false; +} + + +/** + * Launches interactive help. + */ +void ro_gui_interactive_help_start(void) +{ + char *help_start; + wimp_t task = 0; + os_error *error; + + /* don't launch a second copy of anything */ + if (ro_gui_interactive_help_available()) + return; + + /* launch <Help$Start> */ + help_start = getenv("Help$Start"); + if ((help_start) && (help_start[0])) { + error = xwimp_start_task("<Help$Start>", &task); + if (error) { + LOG("xwimp_start_tast: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + } + + /* first attempt failed, launch !Help */ + if (!task) { + error = xwimp_start_task("Resources:$.Apps.!Help", &task); + if (error) { + LOG("xwimp_start_tast: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + } + + /* pretend we got a help request straight away */ + if (task) { + error = xos_read_monotonic_time(&help_time); + if (error) { + LOG("xwimp_read_monotonic_time: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + } +} diff --git a/frontends/riscos/help.h b/frontends/riscos/help.h new file mode 100644 index 000000000..b09594ac8 --- /dev/null +++ b/frontends/riscos/help.h @@ -0,0 +1,33 @@ +/* + * Copyright 2004, 2005 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Interactive help (interface). + */ + +#ifndef _NETSURF_RISCOS_HELP_H_ +#define _NETSURF_RISCOS_HELP_H_ + +#include <stdbool.h> +#include "oslib/wimp.h" + +void ro_gui_interactive_help_request(wimp_message *message); +bool ro_gui_interactive_help_available(void); +void ro_gui_interactive_help_start(void); + +#endif diff --git a/frontends/riscos/history.c b/frontends/riscos/history.c new file mode 100644 index 000000000..9d78f6ded --- /dev/null +++ b/frontends/riscos/history.c @@ -0,0 +1,336 @@ +/* + * Copyright 2006 James Bursa <bursa@users.sourceforge.net> + * Copyright 2005 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Browser history window (RISC OS implementation). + * + * There is only one history window, not one per browser window. + */ + +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> +#include "oslib/wimp.h" + +#include "utils/nsoption.h" +#include "utils/log.h" +#include "desktop/browser_history.h" +#include "desktop/plotters.h" + +#include "riscos/dialog.h" +#include "riscos/gui.h" +#include "riscos/mouse.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" +#include "riscos/wimputils.h" + +static struct browser_window *history_bw; +/* Last position of mouse in window. */ +static int mouse_x = 0; +/* Last position of mouse in window. */ +static int mouse_y = 0; +wimp_w history_window; + +static void ro_gui_history_redraw(wimp_draw *redraw); +static bool ro_gui_history_click(wimp_pointer *pointer); +static void ro_gui_history_pointer_entering(wimp_entering *entering); +static void ro_gui_history_track_end(wimp_leaving *leaving, void *data); +static void ro_gui_history_mouse_at(wimp_pointer *pointer, void *data); + + +/** + * Create history window. + */ + +void ro_gui_history_init(void) +{ + history_window = ro_gui_dialog_create("history"); + ro_gui_wimp_event_register_redraw_window(history_window, + ro_gui_history_redraw); + ro_gui_wimp_event_register_mouse_click(history_window, + ro_gui_history_click); + ro_gui_wimp_event_register_pointer_entering_window(history_window, + ro_gui_history_pointer_entering); + ro_gui_wimp_event_set_help_prefix(history_window, "HelpHistory"); +} + + +/** + * Open history window. + * + * \param g The riscos window to open history for. + * \param at_pointer open the window at the pointer. + */ + +void ro_gui_history_open(struct gui_window *g, bool at_pointer) +{ + struct browser_window *bw; + int width, height; + os_box box = {0, 0, 0, 0}; + wimp_window_state state; + os_error *error; + + assert(g != NULL); + assert(g->bw != NULL); + bw = g->bw; + history_bw = bw; + + browser_window_history_size(bw, &width, &height); + width *= 2; + height *= 2; + + /* set extent */ + box.x1 = width; + box.y0 = -height; + error = xwimp_set_extent(history_window, &box); + if (error) { + LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + /* open full size */ + state.w = history_window; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + state.visible.x0 = 0; + state.visible.y0 = 0; + state.visible.x1 = width; + state.visible.y1 = height; + state.next = wimp_HIDDEN; + error = xwimp_open_window(PTR_WIMP_OPEN(&state)); + if (error) { + LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + ro_gui_dialog_open_persistent(g->window, history_window, at_pointer); +} + + +/** + * Redraw history window. + */ + +void ro_gui_history_redraw(wimp_draw *redraw) +{ + osbool more; + os_error *error; + struct redraw_context ctx = { + .interactive = true, + .background_images = true, + .plot = &ro_plotters + }; + + error = xwimp_redraw_window(redraw, &more); + if (error) { + LOG("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + while (more) { + ro_plot_origin_x = redraw->box.x0 - redraw->xscroll; + ro_plot_origin_y = redraw->box.y1 - redraw->yscroll; + browser_window_history_redraw(history_bw, &ctx); + error = xwimp_get_rectangle(redraw, &more); + if (error) { + LOG("xwimp_get_rectangle: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + } +} + + +/** + * Handle Pointer Entering Window events the history window. + * + * \param *entering The Wimp_PointerEnteringWindow block. + */ + +void ro_gui_history_pointer_entering(wimp_entering *entering) +{ + ro_mouse_track_start(ro_gui_history_track_end, + ro_gui_history_mouse_at, NULL); +} + + +/** + * Handle Pointer Leaving Window events the history window. These arrive as the + * termination callback handler from ro_mouse's mouse tracking. + * + * \param *leaving The Wimp_PointerLeavingWindow block. + * \param *data NULL data pointer. + */ + +void ro_gui_history_track_end(wimp_leaving *leaving, void *data) +{ + ro_gui_dialog_close(dialog_tooltip); +} + + +/** + * Handle mouse movements over the history window. + */ + +void ro_gui_history_mouse_at(wimp_pointer *pointer, void *data) +{ + int x, y; + int width; + const char *url; + wimp_window_state state; + wimp_icon_state ic; + os_box box = {0, 0, 0, 0}; + os_error *error; + + LOG("Mouse at..."); + + /* If the mouse hasn't moved, or if we don't want tooltips, exit */ + if ((mouse_x == pointer->pos.x && mouse_y == pointer->pos.y) || + !nsoption_bool(history_tooltip)) + return; + + /* Update mouse position */ + mouse_x = pointer->pos.x; + mouse_y = pointer->pos.y; + + /* Find history tree entry under mouse */ + state.w = history_window; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + x = (pointer->pos.x - (state.visible.x0 - state.xscroll)) / 2; + y = -(pointer->pos.y - (state.visible.y1 - state.yscroll)) / 2; + url = browser_window_history_position_url(history_bw, x, y); + if (!url) { + /* not over a tree entry => close tooltip window. */ + error = xwimp_close_window(dialog_tooltip); + if (error) { + LOG("xwimp_close_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + return; + } + + /* get width of string */ + error = xwimptextop_string_width(url, + strlen(url) > 256 ? 256 : strlen(url), + &width); + if (error) { + LOG("xwimptextop_string_width: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + ro_gui_set_icon_string(dialog_tooltip, 0, url, true); + + /* resize icon appropriately */ + ic.w = dialog_tooltip; + ic.i = 0; + error = xwimp_get_icon_state(&ic); + if (error) { + LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + error = xwimp_resize_icon(dialog_tooltip, 0, + ic.icon.extent.x0, ic.icon.extent.y0, + width + 16, ic.icon.extent.y1); + if (error) { + LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + state.w = dialog_tooltip; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + /* update window extent */ + box.x1 = width + 16; + box.y0 = -36; + error = xwimp_set_extent(dialog_tooltip, &box); + if (error) { + LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + /* set visible area */ + state.visible.x0 = pointer->pos.x + 24; + state.visible.y0 = pointer->pos.y - 22 - 36; + state.visible.x1 = pointer->pos.x + 24 + width + 16; + state.visible.y1 = pointer->pos.y - 22; + state.next = wimp_TOP; + /* open window */ + error = xwimp_open_window(PTR_WIMP_OPEN(&state)); + if (error) { + LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } +} + + +/** + * Handle mouse clicks in the history window. + * + * \return true if the event was handled, false to pass it on + */ + +bool ro_gui_history_click(wimp_pointer *pointer) +{ + int x, y; + wimp_window_state state; + os_error *error; + + if (pointer->buttons != wimp_CLICK_SELECT && + pointer->buttons != wimp_CLICK_ADJUST) + /* return if not select or adjust click */ + return true; + + state.w = history_window; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return true; + } + + x = (pointer->pos.x - (state.visible.x0 - state.xscroll)) / 2; + y = -(pointer->pos.y - (state.visible.y1 - state.yscroll)) / 2; + browser_window_history_click(history_bw, x, y, + pointer->buttons == wimp_CLICK_ADJUST); + + return true; +} diff --git a/frontends/riscos/hotlist.c b/frontends/riscos/hotlist.c new file mode 100644 index 000000000..381978faf --- /dev/null +++ b/frontends/riscos/hotlist.c @@ -0,0 +1,737 @@ +/* + * Copyright 2004, 2005 Richard Wilson <info@tinct.net> + * Copyright 2010, 2013 Stephen Fryatt <stevef@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Hotlist (implementation). + */ + +#include <ctype.h> +#include <string.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include "oslib/osfile.h" +#include "oslib/osmodule.h" +#include "oslib/wimp.h" + +#include "utils/log.h" +#include "utils/messages.h" +#include "utils/nsoption.h" +#include "content/content.h" +#include "content/hlcache.h" +#include "content/urldb.h" +#include "desktop/hotlist.h" +#include "desktop/tree.h" +#include "desktop/gui_window.h" + +#include "riscos/gui.h" +#include "riscos/dialog.h" +#include "riscos/hotlist.h" +#include "riscos/menus.h" +#include "riscos/message.h" +#include "riscos/save.h" +#include "riscos/toolbar.h" +#include "riscos/treeview.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" +#include "riscos/query.h" + +static void ro_gui_hotlist_toolbar_update_buttons(void); +static void ro_gui_hotlist_toolbar_save_buttons(char *config); +static bool ro_gui_hotlist_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_pointer *pointer); +static void ro_gui_hotlist_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_selection *selection, menu_action action); +static bool ro_gui_hotlist_menu_select(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_selection *selection, menu_action action); +static void ro_gui_hotlist_toolbar_click(button_bar_action action); +static void ro_gui_hotlist_addurl_bounce(wimp_message *message); +static void ro_gui_hotlist_scheduled_callback(void *p); +static void ro_gui_hotlist_remove_confirmed(query_id id, + enum query_response res, void *p); +static void ro_gui_hotlist_remove_cancelled(query_id id, + enum query_response res, void *p); + +static const query_callback remove_funcs = { + ro_gui_hotlist_remove_confirmed, + ro_gui_hotlist_remove_cancelled +}; + +struct ro_treeview_callbacks ro_hotlist_treeview_callbacks = { + ro_gui_hotlist_toolbar_click, + ro_gui_hotlist_toolbar_update_buttons, + ro_gui_hotlist_toolbar_save_buttons +}; + +/* Hotlist Protocol Message Blocks, which are currently not in OSLib. */ + +struct ro_hotlist_message_hotlist_addurl { + wimp_MESSAGE_HEADER_MEMBERS /**< The standard message header. */ + char *url; /**< Pointer to the URL in RMA. */ + char *title; /**< Pointer to the title in RMA. */ + char appname[32]; /**< The application name. */ +}; + +struct ro_hotlist_message_hotlist_changed { + wimp_MESSAGE_HEADER_MEMBERS /**< The standard message header. */ +}; + +static char *hotlist_url = NULL; /**< URL area claimed from RMA. */ +static char *hotlist_title = NULL; /**< Title area claimed from RMA. */ + +/** Hotlist Query Handler. */ + +static query_id hotlist_query = QUERY_INVALID; +static nsurl *hotlist_delete_url = NULL; + +/* The RISC OS hotlist window, toolbar and treeview data. */ + +static struct ro_hotlist { + wimp_w window; /**< The hotlist RO window handle. */ + struct toolbar *toolbar; /**< The hotlist toolbar handle. */ + ro_treeview *tv; /**< The hotlist treeview handle. */ + wimp_menu *menu; /**< The hotlist window menu. */ +} hotlist_window; + +/** + * Pre-Initialise the hotlist tree. This is called for things that need to + * be done at the gui_init() stage, such as loading templates. + */ + +void ro_gui_hotlist_preinitialise(void) +{ + /* Create our window. */ + + hotlist_window.window = ro_gui_dialog_create("tree"); + ro_gui_set_window_title(hotlist_window.window, + messages_get("Hotlist")); +} + +/** + * Initialise the hotlist tree, at the gui_init2() stage. + */ + +void ro_gui_hotlist_postinitialise(void) +{ + /* Create our toolbar. */ + + hotlist_window.toolbar = ro_toolbar_create(NULL, hotlist_window.window, + THEME_STYLE_HOTLIST_TOOLBAR, TOOLBAR_FLAGS_NONE, + ro_treeview_get_toolbar_callbacks(), NULL, + "HelpHotToolbar"); + if (hotlist_window.toolbar != NULL) { + ro_toolbar_add_buttons(hotlist_window.toolbar, + hotlist_toolbar_buttons, + nsoption_charp(toolbar_hotlist)); + ro_toolbar_rebuild(hotlist_window.toolbar); + } + + /* Create the treeview with the window and toolbar. */ + tree_hotlist_path = nsoption_charp(hotlist_path); + hotlist_window.tv = ro_treeview_create(hotlist_window.window, + hotlist_window.toolbar, &ro_hotlist_treeview_callbacks, + TREE_HOTLIST); + if (hotlist_window.tv == NULL) { + LOG("Failed to allocate treeview"); + return; + } + + ro_toolbar_update_client_data(hotlist_window.toolbar, + hotlist_window.tv); + + /* Build the hotlist window menu. */ + + static const struct ns_menu hotlist_definition = { + "Hotlist", { + { "Hotlist", NO_ACTION, 0 }, + { "Hotlist.New", NO_ACTION, 0 }, + { "Hotlist.New.Folder", TREE_NEW_FOLDER, 0 }, + { "Hotlist.New.Link", TREE_NEW_LINK, 0 }, + { "_Hotlist.Export", HOTLIST_EXPORT, &dialog_saveas }, + { "Hotlist.Expand", TREE_EXPAND_ALL, 0 }, + { "Hotlist.Expand.All", TREE_EXPAND_ALL, 0 }, + { "Hotlist.Expand.Folders", TREE_EXPAND_FOLDERS, 0 }, + { "Hotlist.Expand.Links", TREE_EXPAND_LINKS, 0 }, + { "Hotlist.Collapse", TREE_COLLAPSE_ALL, 0 }, + { "Hotlist.Collapse.All", TREE_COLLAPSE_ALL, 0 }, + { "Hotlist.Collapse.Folders", TREE_COLLAPSE_FOLDERS, 0 }, + { "Hotlist.Collapse.Links", TREE_COLLAPSE_LINKS, 0 }, + { "Hotlist.Toolbars", NO_ACTION, 0 }, + { "_Hotlist.Toolbars.ToolButtons", TOOLBAR_BUTTONS, 0 }, + { "Hotlist.Toolbars.EditToolbar", TOOLBAR_EDIT, 0 }, + { "Selection", TREE_SELECTION, 0 }, + { "Selection.Edit", TREE_SELECTION_EDIT, 0 }, + { "Selection.Launch", TREE_SELECTION_LAUNCH, 0 }, + { "Selection.Delete", TREE_SELECTION_DELETE, 0 }, + { "SelectAll", TREE_SELECT_ALL, 0 }, + { "Clear", TREE_CLEAR_SELECTION, 0 }, + {NULL, 0, 0} + } + }; + + hotlist_window.menu = ro_gui_menu_define_menu(&hotlist_definition); + + ro_gui_wimp_event_register_menu(hotlist_window.window, + hotlist_window.menu, false, false); + ro_gui_wimp_event_register_menu_prepare(hotlist_window.window, + ro_gui_hotlist_menu_prepare); + ro_gui_wimp_event_register_menu_selection(hotlist_window.window, + ro_gui_hotlist_menu_select); + ro_gui_wimp_event_register_menu_warning(hotlist_window.window, + ro_gui_hotlist_menu_warning); +} + +/** + * Destroy the hotlist window. + */ + +void ro_gui_hotlist_destroy(void) +{ + if (hotlist_window.tv == NULL) + return; + + tree_hotlist_path = nsoption_charp(hotlist_save); + ro_treeview_destroy(hotlist_window.tv); +} + + +/** + * Open the hotlist window. + * + */ + +void ro_gui_hotlist_open(void) +{ + if (nsoption_bool(external_hotlists) && + nsoption_charp(external_hotlist_app) != NULL && + *nsoption_charp(external_hotlist_app) != '\0') { + char command[2048]; + os_error *error; + + snprintf(command, sizeof(command), "Filer_Run %s", + nsoption_charp(external_hotlist_app)); + error = xos_cli(command); + + if (error == NULL) + return; + + LOG("xos_cli: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("Failed to launch external hotlist: %s", + error->errmess); + } + + ro_gui_hotlist_toolbar_update_buttons(); + + if (!ro_gui_dialog_open_top(hotlist_window.window, + hotlist_window.toolbar, 600, 800)) { + ro_treeview_set_origin(hotlist_window.tv, 0, + -(ro_toolbar_height(hotlist_window.toolbar))); + } +} + +/** + * Handle toolbar button clicks. + * + * \param action The action to handle + */ + +void ro_gui_hotlist_toolbar_click(button_bar_action action) +{ + switch (action) { + case TOOLBAR_BUTTON_DELETE: + hotlist_keypress(NS_KEY_DELETE_LEFT); + ro_toolbar_update_all_hotlists(); + break; + + case TOOLBAR_BUTTON_EXPAND: + hotlist_expand(false); + break; + + case TOOLBAR_BUTTON_COLLAPSE: + hotlist_contract(false); + break; + + case TOOLBAR_BUTTON_OPEN: + hotlist_expand(true); + break; + + case TOOLBAR_BUTTON_CLOSE: + hotlist_contract(true); + break; + + case TOOLBAR_BUTTON_LAUNCH: + hotlist_keypress(NS_KEY_CR); + break; + + case TOOLBAR_BUTTON_CREATE: + hotlist_add_folder(NULL, false, 0); + break; + + default: + break; + } +} + + +/** + * Update the button state in the hotlist toolbar. + */ + +void ro_gui_hotlist_toolbar_update_buttons(void) +{ + ro_toolbar_set_button_shaded_state(hotlist_window.toolbar, + TOOLBAR_BUTTON_DELETE, + !hotlist_has_selection()); + + ro_toolbar_set_button_shaded_state(hotlist_window.toolbar, + TOOLBAR_BUTTON_LAUNCH, + !hotlist_has_selection()); +} + + +/** + * Save a new button arrangement in the hotlist toolbar. + * + * \param *config The new button configuration string. + */ + +void ro_gui_hotlist_toolbar_save_buttons(char *config) +{ + nsoption_set_charp(toolbar_hotlist, config); + ro_gui_save_options(); +} + + +/** + * Prepare the hotlist menu for opening + * + * \param w The window owning the menu. + * \param i A wimp icon + * \param menu The menu about to be opened. + * \param pointer Pointer to the relevant wimp event block, or + * NULL for an Adjust click. + * \return true if the event was handled; else false. + */ + +bool ro_gui_hotlist_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_pointer *pointer) +{ + bool selection; + + if (menu != hotlist_window.menu) + return false; + + selection = hotlist_has_selection(); + + ro_gui_menu_set_entry_shaded(hotlist_window.menu, + TREE_SELECTION, !selection); + ro_gui_menu_set_entry_shaded(hotlist_window.menu, + TREE_CLEAR_SELECTION, !selection); + + ro_gui_save_prepare(GUI_SAVE_HOTLIST_EXPORT_HTML, + NULL, NULL, NULL, NULL); + + ro_gui_menu_set_entry_shaded(menu, TOOLBAR_BUTTONS, + ro_toolbar_menu_option_shade(hotlist_window.toolbar)); + ro_gui_menu_set_entry_ticked(menu, TOOLBAR_BUTTONS, + ro_toolbar_menu_buttons_tick(hotlist_window.toolbar)); + + ro_gui_menu_set_entry_shaded(menu, TOOLBAR_EDIT, + ro_toolbar_menu_edit_shade(hotlist_window.toolbar)); + ro_gui_menu_set_entry_ticked(menu, TOOLBAR_EDIT, + ro_toolbar_menu_edit_tick(hotlist_window.toolbar)); + + return true; +} + + +/** + * Handle submenu warnings for the hotlist menu + * + * \param w The window owning the menu. + * \param i The icon owning the menu. + * \param *menu The menu to which the warning applies. + * \param *selection The wimp menu selection data. + * \param action The selected menu action. + */ + +void ro_gui_hotlist_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_selection *selection, menu_action action) +{ + /* Do nothing */ +} + +/** + * Handle selections from the hotlist menu + * + * \param w The window owning the menu. + * \param i The icon owning the menu. + * \param *menu The menu from which the selection was made. + * \param *selection The wimp menu selection data. + * \param action The selected menu action. + * \return true if action accepted; else false. + */ + +bool ro_gui_hotlist_menu_select(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_selection *selection, menu_action action) +{ + switch (action) { + case HOTLIST_EXPORT: + ro_gui_dialog_open_persistent(w, dialog_saveas, true); + return true; + case TREE_NEW_FOLDER: + hotlist_add_folder(NULL, false, 0); + return true; + case TREE_NEW_LINK: + hotlist_add_entry(NULL, NULL, false, 0); + return true; + case TREE_EXPAND_ALL: + hotlist_expand(false); + return true; + case TREE_EXPAND_FOLDERS: + hotlist_expand(true); + return true; + case TREE_EXPAND_LINKS: + hotlist_expand(false); + return true; + case TREE_COLLAPSE_ALL: + hotlist_contract(true); + return true; + case TREE_COLLAPSE_FOLDERS: + hotlist_contract(true); + return true; + case TREE_COLLAPSE_LINKS: + hotlist_contract(false); + return true; + case TREE_SELECTION_EDIT: + hotlist_edit_selection(); + return true; + case TREE_SELECTION_LAUNCH: + hotlist_keypress(NS_KEY_CR); + return true; + case TREE_SELECTION_DELETE: + hotlist_keypress(NS_KEY_DELETE_LEFT); + ro_toolbar_update_all_hotlists(); + return true; + case TREE_SELECT_ALL: + hotlist_keypress(NS_KEY_SELECT_ALL); + return true; + case TREE_CLEAR_SELECTION: + hotlist_keypress(NS_KEY_CLEAR_SELECTION); + return true; + case TOOLBAR_BUTTONS: + ro_toolbar_set_display_buttons(hotlist_window.toolbar, + !ro_toolbar_get_display_buttons( + hotlist_window.toolbar)); + return true; + case TOOLBAR_EDIT: + ro_toolbar_toggle_edit(hotlist_window.toolbar); + return true; + default: + return false; + } + + return false; +} + +/** + * Check if a particular window handle is the hotlist window + * + * \param window The window in question + * \return true if this window is the hotlist + */ +bool ro_gui_hotlist_check_window(wimp_w window) +{ + if (hotlist_window.window == window) + return true; + else + return false; +} + +/** + * Check if a particular menu handle is the hotlist menu + * + * \param *menu The menu in question. + * \return true if this menu is the hotlist menu + */ + +bool ro_gui_hotlist_check_menu(wimp_menu *menu) +{ + if (hotlist_window.menu == menu) + return true; + else + return false; +} + + +/** + * Add a URL to the hotlist. This will be passed on to the core hotlist, then + * Message_HotlistAddURL will broadcast to any bookmark applications via the + * Hotlist Protocol. + * + * \param *url The URL to be added. + */ + +void ro_gui_hotlist_add_page(nsurl *url) +{ + const struct url_data *data; + wimp_message message; + struct ro_hotlist_message_hotlist_addurl *add_url = + (struct ro_hotlist_message_hotlist_addurl *) &message; + + if (url == NULL) + return; + + /* If we're not using external hotlists, add the page to NetSurf's + * own hotlist and return... + */ + + if (!nsoption_bool(external_hotlists)) { + hotlist_add_url(url); + return; + } + + /* ...otherwise try broadcasting the details to any other + * interested parties. If no-one answers, we'll fall back to + * NetSurf's hotlist anyway when the message bounces. + */ + + ro_gui_hotlist_add_cleanup(); + + data = urldb_get_url_data(url); + if (data == NULL) + return; + + hotlist_url = osmodule_alloc(nsurl_length(url) + 1); + hotlist_title = osmodule_alloc(strlen(data->title) + 1); + + if (hotlist_url == NULL || hotlist_title == NULL) { + ro_gui_hotlist_add_cleanup(); + return; + } + + strcpy(hotlist_url, nsurl_access(url)); + strcpy(hotlist_title, data->title); + + add_url->size = 60; + add_url->your_ref = 0; + add_url->action = message_HOTLIST_ADD_URL; + add_url->url = hotlist_url; + add_url->title = hotlist_title; + strcpy(add_url->appname, "NetSurf"); + + if (!ro_message_send_message(wimp_USER_MESSAGE_RECORDED, &message, 0, + ro_gui_hotlist_addurl_bounce)) + ro_gui_hotlist_add_cleanup(); + + /* Listen for the next Null poll, as an indication that the + * message didn't bounce. + */ + + riscos_schedule(0, ro_gui_hotlist_scheduled_callback, NULL); +} + + +/** + * Handle bounced Message_HotlistAddURL, so that RMA storage can be freed. + * + * \param *message The bounced message content. + */ + +static void ro_gui_hotlist_addurl_bounce(wimp_message *message) +{ + if (hotlist_url != NULL) { + nsurl *nsurl; + + if (nsurl_create(hotlist_url, &nsurl) != NSERROR_OK) + return; + + hotlist_add_url(nsurl); + nsurl_unref(nsurl); + } + + ro_gui_hotlist_add_cleanup(); + + /* There's no longer any need to listen for the next Null poll. */ + + riscos_schedule(-1, ro_gui_hotlist_scheduled_callback, NULL); +} + + +/** + * Callback to schedule for the next available Null poll, by which point + * a hotlist client will have claimed the Message_HotlistAddURL and any + * details in RMA can safely be discarded. + * + * \param *p Unused data pointer. + */ + +static void ro_gui_hotlist_scheduled_callback(void *p) +{ + ro_gui_hotlist_add_cleanup(); +} + + +/** + * Clean up RMA storage used by the Message_HotlistAddURL protocol. + */ + +void ro_gui_hotlist_add_cleanup(void) +{ + if (hotlist_url != NULL) { + osmodule_free(hotlist_url); + hotlist_url = NULL; + } + + if (hotlist_title != NULL) { + osmodule_free(hotlist_title); + hotlist_title = NULL; + } +} + + +/** + * Remove a URL from the hotlist. This will be passed on to the core hotlist, + * unless we're configured to use external hotlists in which case we ignore it. + * + * \param *url The URL to be removed. + */ + +void ro_gui_hotlist_remove_page(nsurl *url) +{ + if (url == NULL || nsoption_bool(external_hotlists) || + !hotlist_has_url(url)) + return; + + /* Clean up any existing delete attempts before continuing. */ + + if (hotlist_query != QUERY_INVALID) { + query_close(hotlist_query); + hotlist_query = QUERY_INVALID; + } + + if (hotlist_delete_url != NULL) { + nsurl_unref(hotlist_delete_url); + hotlist_delete_url = NULL; + } + + /* Check with the user before removing the URL, unless they don't + * want us to be careful in which case just do it. + */ + + if (nsoption_bool(confirm_hotlist_remove)) { + hotlist_query = query_user("RemoveHotlist", NULL, + &remove_funcs, NULL, + messages_get("Remove"), + messages_get("DontRemove")); + + hotlist_delete_url = nsurl_ref(url); + } else { + hotlist_remove_url(url); + ro_toolbar_update_all_hotlists(); + } +} + + +/** + * Callback confirming a URL delete query. + * + * \param id The ID of the query calling us. + * \param res The user's response to the query. + * \param *p Callback data (always NULL). + */ + +static void ro_gui_hotlist_remove_confirmed(query_id id, + enum query_response res, void *p) +{ + hotlist_remove_url(hotlist_delete_url); + ro_toolbar_update_all_hotlists(); + + nsurl_unref(hotlist_delete_url); + hotlist_delete_url = NULL; + hotlist_query = QUERY_INVALID; +} + + +/** + * Callback cancelling a URL delete query. + * + * \param id The ID of the query calling us. + * \param res The user's response to the query. + * \param *p Callback data (always NULL). + */ + +static void ro_gui_hotlist_remove_cancelled(query_id id, + enum query_response res, void *p) +{ + nsurl_unref(hotlist_delete_url); + hotlist_delete_url = NULL; + hotlist_query = QUERY_INVALID; +} + + +/** + * Report whether the hotlist contains a given URL. This will be passed on to + * the core hotlist, unless we're configured to use an external hotlist in which + * case we always report false. + * + * \param *url The URL to be tested. + * \return true if the hotlist contains the URL; else false. + */ + +bool ro_gui_hotlist_has_page(nsurl *url) +{ + if (url == NULL || nsoption_bool(external_hotlists)) + return false; + + return hotlist_has_url(url); +} + + +#if 0 +/** + * Handle URL dropped on hotlist + * + * \param message the wimp message we're acting on + * \param url the URL to add + */ +void ro_gui_hotlist_url_drop(wimp_message *message, const char *url) +{ + int x, y; + nsurl *nsurl; + + if (hotlist_window.window != message->data.data_xfer.w) + return; + + if (url == NULL) + return; + + if (nsurl_create(url, &nsurl) != NSERROR_OK) + return; + + ro_gui_tree_get_tree_coordinates(hotlist_window.tree, + message->data.data_xfer.pos.x, + message->data.data_xfer.pos.y, + &x, &y); + + hotlist_add_entry(nsurl, NULL, true, y); + nsurl_unref(nsurl); +} +#endif diff --git a/frontends/riscos/hotlist.h b/frontends/riscos/hotlist.h new file mode 100644 index 000000000..0b87a2e96 --- /dev/null +++ b/frontends/riscos/hotlist.h @@ -0,0 +1,53 @@ +/* + * Copyright 2006 Richard Wilson <info@tinct.net> + * Copyright 2010, 2013 Stephen Fryatt <stevef@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Hotlist (interface). + */ + +#ifndef _NETSURF_RISCOS_HOTLIST_H_ +#define _NETSURF_RISCOS_HOTLIST_H_ + +/* Hotlist Protocol Messages, which are currently not in OSLib. */ + +#ifndef message_HOTLIST_ADD_URL +#define message_HOTLIST_ADD_URL 0x4af81 +#endif + +#ifndef message_HOTLIST_CHANGED +#define message_HOTLIST_CHANGED 0x4af82 +#endif + +#include "riscos/menus.h" + +struct nsurl; + +void ro_gui_hotlist_preinitialise(void); +void ro_gui_hotlist_postinitialise(void); +void ro_gui_hotlist_destroy(void); +void ro_gui_hotlist_open(void); +void ro_gui_hotlist_save(void); +bool ro_gui_hotlist_check_window(wimp_w window); +bool ro_gui_hotlist_check_menu(wimp_menu *menu); +void ro_gui_hotlist_add_page(struct nsurl *url); +void ro_gui_hotlist_add_cleanup(void); +void ro_gui_hotlist_remove_page(struct nsurl *url); +bool ro_gui_hotlist_has_page(struct nsurl *url); + +#endif diff --git a/frontends/riscos/iconbar.c b/frontends/riscos/iconbar.c new file mode 100644 index 000000000..9cff116a1 --- /dev/null +++ b/frontends/riscos/iconbar.c @@ -0,0 +1,261 @@ +/* + * Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Iconbar icon and menus (implementation). + */ + +#include <assert.h> +#include <errno.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <features.h> +#include <oslib/os.h> +#include <oslib/osbyte.h> +#include <oslib/wimp.h> + +#include "utils/nsoption.h" +#include "utils/log.h" +#include "utils/messages.h" +#include "utils/nsurl.h" +#include "desktop/browser.h" + +#include "riscos/gui.h" +#include "riscos/configure.h" +#include "riscos/cookies.h" +#include "riscos/dialog.h" +#include "riscos/global_history.h" +#include "riscos/hotlist.h" +#include "riscos/iconbar.h" +#include "riscos/wimp_event.h" + +static bool ro_gui_iconbar_click(wimp_pointer *pointer); + +static bool ro_gui_iconbar_menu_select(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_selection *selection, menu_action action); +static void ro_gui_iconbar_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_selection *selection, menu_action action); + + +static wimp_menu *ro_gui_iconbar_menu = NULL; /**< Iconbar menu handle */ + +/** + * Initialise the iconbar menus, create an icon and register the necessary + * handlers to look after them all. + */ + +void ro_gui_iconbar_initialise(void) +{ + os_error *error; + + /* Build the iconbar menu */ + + static const struct ns_menu iconbar_definition = { + "NetSurf", { + { "Info", NO_ACTION, &dialog_info }, + { "AppHelpNoShortcut", HELP_OPEN_CONTENTS, 0 }, + { "Open", BROWSER_NAVIGATE_URL, 0 }, + { "Open.OpenURL", BROWSER_NAVIGATE_URL, &dialog_openurl }, + { "Open.HotlistShowNoShortcut", HOTLIST_SHOW, 0 }, + { "Open.HistGlobalNoShortcut", HISTORY_SHOW_GLOBAL, 0 }, + { "Open.ShowCookies", COOKIES_SHOW, 0 }, + { "Choices", CHOICES_SHOW, 0 }, + { "Quit", APPLICATION_QUIT, 0 }, + {NULL, 0, 0} + } + }; + ro_gui_iconbar_menu = ro_gui_menu_define_menu(&iconbar_definition); + + /* Create an iconbar icon. */ + + wimp_icon_create icon = { + wimp_ICON_BAR_RIGHT, + { { 0, 0, 68, 68 }, + wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | + (wimp_BUTTON_CLICK << wimp_ICON_BUTTON_TYPE_SHIFT), + { "!netsurf" } } }; + error = xwimp_create_icon(&icon, 0); + if (error) { + LOG("xwimp_create_icon: 0x%x: %s", error->errnum, error->errmess); + die(error->errmess); + } + + /* Register handlers to look after clicks and menu actions. */ + + ro_gui_wimp_event_register_mouse_click(wimp_ICON_BAR, + ro_gui_iconbar_click); + + ro_gui_wimp_event_register_menu(wimp_ICON_BAR, ro_gui_iconbar_menu, + true, true); + ro_gui_wimp_event_register_menu_selection(wimp_ICON_BAR, + ro_gui_iconbar_menu_select); + ro_gui_wimp_event_register_menu_warning(wimp_ICON_BAR, + ro_gui_iconbar_menu_warning); +} + + +/** + * Handle Mouse_Click events on the iconbar icon. + * + * \param *pointer The wimp event block to be processed. + * \return true if the event was handled; else false. + */ + +bool ro_gui_iconbar_click(wimp_pointer *pointer) +{ + int key_down = 0; + nsurl *url; + nserror error; + + switch (pointer->buttons) { + case wimp_CLICK_SELECT: + if (nsoption_charp(homepage_url) != NULL) { + error = nsurl_create(nsoption_charp(homepage_url), &url); + } else { + error = nsurl_create(NETSURF_HOMEPAGE, &url); + } + + /* create an initial browser window */ + if (error == NSERROR_OK) { + error = browser_window_create(BW_CREATE_HISTORY, + url, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + if (error != NSERROR_OK) { + ro_warn_user(messages_get_errorcode(error), 0); + } + break; + + case wimp_CLICK_ADJUST: + xosbyte1(osbyte_SCAN_KEYBOARD, 0 ^ 0x80, 0, &key_down); + if (key_down == 0) + ro_gui_hotlist_open(); + break; + } + + return true; +} + +/** + * Handle submenu warnings for the iconbar menu + * + * \param w The window owning the menu. + * \param i The icon owning the menu. + * \param *menu The menu to which the warning applies. + * \param *selection The wimp menu selection data. + * \param action The selected menu action. + */ + +void ro_gui_iconbar_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_selection *selection, menu_action action) +{ + if (w != wimp_ICON_BAR || i != wimp_ICON_WINDOW) + return; + + switch (action) { + case BROWSER_NAVIGATE_URL: + ro_gui_dialog_prepare_open_url(); + break; + default: + break; + } +} + +/** + * Handle selections from the iconbar menu + * + * \param w The window owning the menu. + * \param i The icon owning the menu. + * \param menu The wimp menu + * \param selection The wimp menu selection data. + * \param action The selected menu action. + * \return true if action accepted; else false. + */ + +bool ro_gui_iconbar_menu_select(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_selection *selection, menu_action action) +{ + nsurl *url; + nserror error; + + if (w != wimp_ICON_BAR || i != wimp_ICON_WINDOW) + return false; + + switch (action) { + case HELP_OPEN_CONTENTS: + error = nsurl_create("http://www.netsurf-browser.org/documentation/", &url); + if (error == NSERROR_OK) { + error = browser_window_create(BW_CREATE_HISTORY, + url, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + if (error != NSERROR_OK) { + ro_warn_user(messages_get_errorcode(error), 0); + } + return true; + + case BROWSER_NAVIGATE_URL: + ro_gui_dialog_prepare_open_url(); + ro_gui_dialog_open_persistent(NULL, dialog_openurl, true); + return true; + case HOTLIST_SHOW: + ro_gui_hotlist_open(); + return true; + case HISTORY_SHOW_GLOBAL: + ro_gui_global_history_open(); + return true; + case COOKIES_SHOW: + ro_gui_cookies_open(); + return true; + case CHOICES_SHOW: + ro_gui_configure_show(); + return true; + case APPLICATION_QUIT: + if (ro_gui_prequit()) { + LOG("QUIT in response to user request"); + riscos_done = true; + } + return true; + default: + return false; + } + + return false; +} + +/** + * Check if a particular menu handle is the iconbar menu + * + * \param *menu The menu in question. + * \return true if this menu is the iconbar menu + */ + +bool ro_gui_iconbar_check_menu(wimp_menu *menu) +{ + return (ro_gui_iconbar_menu == menu) ? true : false; +} + diff --git a/frontends/riscos/iconbar.h b/frontends/riscos/iconbar.h new file mode 100644 index 000000000..e40f9acd8 --- /dev/null +++ b/frontends/riscos/iconbar.h @@ -0,0 +1,32 @@ +/* + * Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Iconbar icon and menus (interface). + */ + +#include <stdbool.h> + +#ifndef _NETSURF_RISCOS_ICONBAR_H_ +#define _NETSURF_RISCOS_ICONBAR_H_ + +void ro_gui_iconbar_initialise(void); +bool ro_gui_iconbar_check_menu(wimp_menu *menu); + +#endif + diff --git a/frontends/riscos/image.c b/frontends/riscos/image.c new file mode 100644 index 000000000..acbe62d98 --- /dev/null +++ b/frontends/riscos/image.c @@ -0,0 +1,219 @@ +/* + * Copyright 2004 John M Bell <jmb202@ecs.soton.ac.uk> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdbool.h> +#include <swis.h> +#include <stdlib.h> +#include <oslib/colourtrans.h> +#include <oslib/osspriteop.h> + +#include "utils/nsoption.h" +#include "utils/log.h" + +#include "riscos/image.h" +#include "riscos/gui.h" +#include "riscos/tinct.h" + +static bool image_redraw_tinct(osspriteop_id header, int x, int y, + int req_width, int req_height, int width, int height, + colour background_colour, bool repeatx, bool repeaty, + bool alpha, unsigned int tinct_options); +static bool image_redraw_os(osspriteop_id header, int x, int y, + int req_width, int req_height, int width, int height); + +/** + * Plot an image at the given coordinates using the method specified + * + * \param area The sprite area containing the sprite + * \param x Left edge of sprite + * \param y Top edge of sprite + * \param req_width The requested width of the sprite + * \param req_height The requested height of the sprite + * \param width The actual width of the sprite + * \param height The actual height of the sprite + * \param background_colour The background colour to blend to + * \param repeatx Repeat the image in the x direction + * \param repeaty Repeat the image in the y direction + * \param background Use background image settings (otherwise foreground) + * \param type The plot method to use + * \return true on success, false otherwise + */ +bool image_redraw(osspriteop_area *area, int x, int y, int req_width, + int req_height, int width, int height, + colour background_colour, + bool repeatx, bool repeaty, bool background, image_type type) +{ + unsigned int tinct_options; + + /* failed decompression/loading can result in no image being present */ + if (!area) + return false; + + osspriteop_id header = (osspriteop_id) + ((char*) area + area->first); + req_width *= 2; + req_height *= 2; + width *= 2; + height *= 2; + tinct_options = background ? nsoption_int(plot_bg_quality) : + nsoption_int(plot_fg_quality); + switch (type) { + case IMAGE_PLOT_TINCT_ALPHA: + return image_redraw_tinct(header, x, y, + req_width, req_height, + width, height, + background_colour, + repeatx, repeaty, true, + tinct_options); + case IMAGE_PLOT_TINCT_OPAQUE: + return image_redraw_tinct(header, x, y, + req_width, req_height, + width, height, + background_colour, + repeatx, repeaty, false, + tinct_options); + case IMAGE_PLOT_OS: + return image_redraw_os(header, x, y, req_width, + req_height, width, height); + default: + break; + } + + return false; +} + +/** + * Plot an image at the given coordinates using tinct + * + * \param header The sprite header + * \param x Left edge of sprite + * \param y Top edge of sprite + * \param req_width The requested width of the sprite + * \param req_height The requested height of the sprite + * \param width The actual width of the sprite + * \param height The actual height of the sprite + * \param background_colour The background colour to blend to + * \param repeatx Repeat the image in the x direction + * \param repeaty Repeat the image in the y direction + * \param alpha Use the alpha channel + * \param tinct_options The base option set to use + * \return true on success, false otherwise + */ +bool image_redraw_tinct(osspriteop_id header, int x, int y, + int req_width, int req_height, int width, int height, + colour background_colour, bool repeatx, bool repeaty, + bool alpha, unsigned int tinct_options) +{ + _kernel_oserror *error; + + /* Set up our flagword + */ + tinct_options |= background_colour << tinct_BACKGROUND_SHIFT; + if (print_active) + tinct_options |= tinct_USE_OS_SPRITE_OP; + if (repeatx) + tinct_options |= tinct_FILL_HORIZONTALLY; + if (repeaty) + tinct_options |= tinct_FILL_VERTICALLY; + + if (alpha) { + error = _swix(Tinct_PlotScaledAlpha, _INR(2,7), + header, x, y - req_height, + req_width, req_height, tinct_options); + } else { + error = _swix(Tinct_PlotScaled, _INR(2,7), + header, x, y - req_height, + req_width, req_height, tinct_options); + } + + if (error) { + LOG("xtinct_plotscaled%s: 0x%x: %s", (alpha ? "alpha" : ""), error->errnum, error->errmess); + return false; + } + + return true; +} + + +/** + * Plot an image at the given coordinates using os_spriteop + * + * \param header The sprite header + * \param x Left edge of sprite + * \param y Top edge of sprite + * \param req_width The requested width of the sprite + * \param req_height The requested height of the sprite + * \param width The actual width of the sprite + * \param height The actual height of the sprite + * \return true on success, false otherwise + */ +bool image_redraw_os(osspriteop_id header, int x, int y, int req_width, + int req_height, int width, int height) +{ + int size; + os_factors f; + osspriteop_trans_tab *table; + os_error *error; + + error = xcolourtrans_generate_table_for_sprite( + (osspriteop_area *)0x100, header, + os_CURRENT_MODE, + colourtrans_CURRENT_PALETTE, + 0, colourtrans_GIVEN_SPRITE, 0, 0, &size); + if (error) { + LOG("xcolourtrans_generate_table_for_sprite: 0x%x: %s", error->errnum, error->errmess); + return false; + } + + table = calloc(size, sizeof(char)); + if (!table) { + LOG("malloc failed"); + ro_warn_user("NoMemory", 0); + return false; + } + + error = xcolourtrans_generate_table_for_sprite( + (osspriteop_area *)0x100, header, + os_CURRENT_MODE, + colourtrans_CURRENT_PALETTE, + table, colourtrans_GIVEN_SPRITE, 0, 0, 0); + if (error) { + LOG("xcolourtrans_generate_table_for_sprite: 0x%x: %s", error->errnum, error->errmess); + free(table); + return false; + } + + f.xmul = req_width; + f.ymul = req_height; + f.xdiv = width; + f.ydiv = height; + + error = xosspriteop_put_sprite_scaled(osspriteop_PTR, + (osspriteop_area *)0x100, header, + x, (int)(y - req_height), + 8, &f, table); + if (error) { + LOG("xosspriteop_put_sprite_scaled: 0x%x: %s", error->errnum, error->errmess); + free(table); + return false; + } + + free(table); + + return true; +} diff --git a/frontends/riscos/image.h b/frontends/riscos/image.h new file mode 100644 index 000000000..a11388c13 --- /dev/null +++ b/frontends/riscos/image.h @@ -0,0 +1,39 @@ +/* + * Copyright 2004 John M Bell <jmb202@ecs.soton.ac.uk> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _NETSURF_RISCOS_IMAGE_H_ +#define _NETSURF_RISCOS_IMAGE_H_ + +#include <stdbool.h> +#include "desktop/plot_style.h" +#include "oslib/osspriteop.h" + +struct osspriteop_area; + +typedef enum { + IMAGE_PLOT_TINCT_ALPHA, + IMAGE_PLOT_TINCT_OPAQUE, + IMAGE_PLOT_OS +} image_type; + +bool image_redraw(osspriteop_area *area, int x, int y, int req_width, + int req_height, int width, int height, + colour background_colour, + bool repeatx, bool repeaty, bool background, image_type type); + +#endif diff --git a/frontends/riscos/menus.c b/frontends/riscos/menus.c new file mode 100644 index 000000000..37285c9d1 --- /dev/null +++ b/frontends/riscos/menus.c @@ -0,0 +1,958 @@ +/* + * Copyright 2003 Phil Mellor <monkeyson@users.sourceforge.net> + * Copyright 2005 James Bursa <bursa@users.sourceforge.net> + * Copyright 2003 John M Bell <jmb202@ecs.soton.ac.uk> + * Copyright 2005 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * \file + * Menu creation and handling implementation. + */ + +#include <ctype.h> +#include <stdlib.h> +#include <string.h> +#include "oslib/os.h" +#include "oslib/osbyte.h" +#include "oslib/osgbpb.h" +#include "oslib/territory.h" +#include "oslib/wimp.h" + +#include "utils/log.h" +#include "utils/messages.h" +#include "utils/utf8.h" +#include "content/content.h" +#include "content/hlcache.h" +#include "content/urldb.h" +#include "desktop/cookie_manager.h" +#include "desktop/browser.h" +#include "desktop/textinput.h" + +#include "riscos/dialog.h" +#include "riscos/configure.h" +#include "riscos/cookies.h" +#include "riscos/gui.h" +#include "riscos/global_history.h" +#include "riscos/help.h" +#include "riscos/hotlist.h" +#include "riscos/menus.h" +#include "utils/nsoption.h" +#include "riscos/save.h" +#include "riscos/tinct.h" +#include "riscos/toolbar.h" +#include "riscos/treeview.h" +#include "riscos/url_suggest.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" +#include "riscos/ucstables.h" + +struct menu_definition_entry { + menu_action action; /**< menu action */ + wimp_menu_entry *menu_entry; /**< corresponding menu entry */ + const char *entry_key; /**< Messages key for entry text */ + struct menu_definition_entry *next; /**< next menu entry */ +}; + +struct menu_definition { + wimp_menu *menu; /**< corresponding menu */ + const char *title_key; /**< Messages key for title text */ + int current_encoding; /**< Identifier for current text encoding of menu text (as per OS_Byte,71,127) */ + struct menu_definition_entry *entries; /**< menu entries */ + struct menu_definition *next; /**< next menu */ +}; + +static void ro_gui_menu_closed(void); +static void ro_gui_menu_define_menu_add(struct menu_definition *definition, + const struct ns_menu *menu, int depth, + wimp_menu_entry *parent_entry, + int first, int last, const char *prefix, int prefix_length); +static struct menu_definition *ro_gui_menu_find_menu(wimp_menu *menu); +static struct menu_definition_entry *ro_gui_menu_find_entry(wimp_menu *menu, + menu_action action); +static menu_action ro_gui_menu_find_action(wimp_menu *menu, + wimp_menu_entry *menu_entry); +static int ro_gui_menu_get_checksum(void); +static bool ro_gui_menu_translate(struct menu_definition *menu); + + +/* default menu item flags */ +#define DEFAULT_FLAGS (wimp_ICON_TEXT | wimp_ICON_FILLED | \ + (wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT) | \ + (wimp_COLOUR_WHITE << wimp_ICON_BG_COLOUR_SHIFT)) + +/** The currently defined menus to perform actions for */ +static struct menu_definition *ro_gui_menu_definitions; +/** The current menu being worked with (may not be open) */ +wimp_menu *current_menu; +/** Whether a menu is currently open */ +bool current_menu_open = false; +/** Window that owns the current menu */ +wimp_w current_menu_window; +/** Icon that owns the current menu (only valid for popup menus) */ +static wimp_i current_menu_icon; +/** The available menus */ +wimp_menu *image_quality_menu, *proxy_type_menu, *languages_menu; + +/* the values given in PRM 3-157 for how to check menus/windows are + * incorrect so we use a hack of checking if the sub-menu has bit 0 + * set which is undocumented but true of window handles on + * all target OS versions */ +#define IS_MENU(menu) !((int)(menu) & 1) + +/** + * Create menu structures. + */ + +void ro_gui_menu_init(void) +{ + /* image quality menu */ + static const struct ns_menu images_definition = { + "Display", { + { "ImgStyle0", NO_ACTION, 0 }, + { "ImgStyle1", NO_ACTION, 0 }, + { "ImgStyle2", NO_ACTION, 0 }, + { "ImgStyle3", NO_ACTION, 0 }, + {NULL, 0, 0} + } + }; + image_quality_menu = ro_gui_menu_define_menu(&images_definition); + + /* proxy menu */ + static const struct ns_menu proxy_type_definition = { + "ProxyType", { + { "ProxyNone", NO_ACTION, 0 }, + { "ProxyNoAuth", NO_ACTION, 0 }, + { "ProxyBasic", NO_ACTION, 0 }, + { "ProxyNTLM", NO_ACTION, 0 }, + {NULL, 0, 0} + } + }; + proxy_type_menu = ro_gui_menu_define_menu(&proxy_type_definition); + + /* special case menus */ + ro_gui_url_suggest_init(); + + /* Note: This table *must* be kept in sync with the LangNames file */ + static const struct ns_menu lang_definition = { + "Languages", { + { "lang_af", NO_ACTION, 0 }, + { "lang_bm", NO_ACTION, 0 }, + { "lang_ca", NO_ACTION, 0 }, + { "lang_cs", NO_ACTION, 0 }, + { "lang_cy", NO_ACTION, 0 }, + { "lang_da", NO_ACTION, 0 }, + { "lang_de", NO_ACTION, 0 }, + { "lang_en", NO_ACTION, 0 }, + { "lang_es", NO_ACTION, 0 }, + { "lang_et", NO_ACTION, 0 }, + { "lang_eu", NO_ACTION, 0 }, + { "lang_ff", NO_ACTION, 0 }, + { "lang_fi", NO_ACTION, 0 }, + { "lang_fr", NO_ACTION, 0 }, + { "lang_ga", NO_ACTION, 0 }, + { "lang_gl", NO_ACTION, 0 }, + { "lang_ha", NO_ACTION, 0 }, + { "lang_hr", NO_ACTION, 0 }, + { "lang_hu", NO_ACTION, 0 }, + { "lang_id", NO_ACTION, 0 }, + { "lang_is", NO_ACTION, 0 }, + { "lang_it", NO_ACTION, 0 }, + { "lang_lt", NO_ACTION, 0 }, + { "lang_lv", NO_ACTION, 0 }, + { "lang_ms", NO_ACTION, 0 }, + { "lang_mt", NO_ACTION, 0 }, + { "lang_nl", NO_ACTION, 0 }, + { "lang_no", NO_ACTION, 0 }, + { "lang_pl", NO_ACTION, 0 }, + { "lang_pt", NO_ACTION, 0 }, + { "lang_rn", NO_ACTION, 0 }, + { "lang_ro", NO_ACTION, 0 }, + { "lang_rw", NO_ACTION, 0 }, + { "lang_sk", NO_ACTION, 0 }, + { "lang_sl", NO_ACTION, 0 }, + { "lang_so", NO_ACTION, 0 }, + { "lang_sq", NO_ACTION, 0 }, + { "lang_sr", NO_ACTION, 0 }, + { "lang_sv", NO_ACTION, 0 }, + { "lang_sw", NO_ACTION, 0 }, + { "lang_tr", NO_ACTION, 0 }, + { "lang_uz", NO_ACTION, 0 }, + { "lang_vi", NO_ACTION, 0 }, + { "lang_wo", NO_ACTION, 0 }, + { "lang_xs", NO_ACTION, 0 }, + { "lang_yo", NO_ACTION, 0 }, + { "lang_zu", NO_ACTION, 0 }, + { NULL, 0, 0 } + } + }; + languages_menu = ro_gui_menu_define_menu(&lang_definition); +} + + +/** + * Display a menu. + * + * \param *menu Pointer to the menu to be displayed. + * \param x The x position. + * \param y The y position. + * \param w The window that the menu belongs to. + */ + +void ro_gui_menu_create(wimp_menu *menu, int x, int y, wimp_w w) +{ + os_error *error; + struct menu_definition *definition; + + /* translate menu, if necessary (this returns quickly + * if there's nothing to be done) */ + definition = ro_gui_menu_find_menu(menu); + if (definition) { + if (!ro_gui_menu_translate(definition)) { + ro_warn_user("NoMemory", 0); + return; + } + } + + /* store the menu characteristics */ + current_menu = menu; + current_menu_window = w; + current_menu_icon = wimp_ICON_WINDOW; + + /* create the menu */ + current_menu_open = true; + error = xwimp_create_menu(menu, x - 64, y); + if (error) { + LOG("xwimp_create_menu: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MenuError", error->errmess); + ro_gui_menu_closed(); + } +} + + +/** + * Display a pop-up menu next to the specified icon. + * + * \param menu menu to open + * \param w window handle + * \param i icon handle + */ + +void ro_gui_popup_menu(wimp_menu *menu, wimp_w w, wimp_i i) +{ + wimp_window_state state; + wimp_icon_state icon_state; + os_error *error; + + state.w = w; + icon_state.w = w; + icon_state.i = i; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MenuError", error->errmess); + return; + } + + error = xwimp_get_icon_state(&icon_state); + if (error) { + LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MenuError", error->errmess); + return; + } + + ro_gui_menu_create(menu, + state.visible.x0 + icon_state.icon.extent.x1 + 64, + state.visible.y1 + icon_state.icon.extent.y1 - + state.yscroll, w); + current_menu_icon = i; +} + + +/** + * Forcibly close any menu or transient dialogue box that is currently open. + */ + +void ro_gui_menu_destroy(void) +{ + os_error *error; + + if (current_menu == NULL) + return; + + error = xwimp_create_menu(wimp_CLOSE_MENU, 0, 0); + if (error) { + LOG("xwimp_create_menu: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MenuError", error->errmess); + } + + ro_gui_menu_closed(); +} + + +/** + * Allow the current menu window to change, if the window is deleted and + * recreated while a menu is active on an Adjust-click. + * + * \param from The original window handle. + * \param to The new replacement window handle. + */ + +void ro_gui_menu_window_changed(wimp_w from, wimp_w to) +{ + + if (from == current_menu_window) + current_menu_window = to; +} + + +/** + * Handle menu selection. + */ + +void ro_gui_menu_selection(wimp_selection *selection) +{ + int i; //, j; + wimp_menu_entry *menu_entry; + menu_action action; + wimp_pointer pointer; + os_error *error; + int previous_menu_icon = current_menu_icon; + + /* if we are using gui_multitask then menu selection events + * may be delivered after the menu has been closed. As such, + * we simply ignore these events. */ + if (!current_menu) + return; + + assert(current_menu_window); + + /* get the menu entry and associated action and definition */ + menu_entry = ¤t_menu->entries[selection->items[0]]; + for (i = 1; selection->items[i] != -1; i++) + menu_entry = &menu_entry->sub_menu-> + entries[selection->items[i]]; + action = ro_gui_menu_find_action(current_menu, menu_entry); + + /* Deal with the menu action. If this manages to re-prepare the + * menu for re-opening, we test for and act on Adjust clicks. + */ + + if (!ro_gui_wimp_event_menu_selection(current_menu_window, + current_menu_icon, current_menu, selection, action)) + return; + + /* re-open the menu for Adjust clicks */ + error = xwimp_get_pointer_info(&pointer); + if (error) { + LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + ro_gui_menu_closed(); + return; + } + + if (pointer.buttons != wimp_CLICK_ADJUST) { + ro_gui_menu_closed(); + return; + } + + ro_gui_menu_create(current_menu, 0, 0, current_menu_window); + current_menu_icon = previous_menu_icon; +} + + +/** + * Handle Message_MenuWarning. + */ +void ro_gui_menu_warning(wimp_message_menu_warning *warning) +{ + int i; + menu_action action; + wimp_menu_entry *menu_entry; + os_error *error; + + assert(current_menu); + assert(current_menu_window); + + /* get the sub-menu of the warning */ + if (warning->selection.items[0] == -1) + return; + menu_entry = ¤t_menu->entries[warning->selection.items[0]]; + for (i = 1; warning->selection.items[i] != -1; i++) + menu_entry = &menu_entry->sub_menu-> + entries[warning->selection.items[i]]; + action = ro_gui_menu_find_action(current_menu, menu_entry); + + /* Process the warning via Wimp_Event, then register the resulting + * submenu with the module. + */ + + ro_gui_wimp_event_submenu_warning(current_menu_window, + current_menu_icon, current_menu, &(warning->selection), + action); + + if (IS_MENU(menu_entry->sub_menu)) { + ro_gui_wimp_event_register_submenu((wimp_w) 0); + } else { + ro_gui_wimp_event_register_submenu((wimp_w) + menu_entry->sub_menu); + + /* If this is a dialogue box, remove the close and back icons. + */ + + ro_gui_wimp_update_window_furniture((wimp_w) + menu_entry->sub_menu, + wimp_WINDOW_CLOSE_ICON | wimp_WINDOW_BACK_ICON, + 0); + } + + /* open the sub-menu */ + + error = xwimp_create_sub_menu(menu_entry->sub_menu, + warning->pos.x, warning->pos.y); + if (error) { + LOG("xwimp_create_sub_menu: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MenuError", error->errmess); + } +} + + +/** + * Handle Message_MenusDeleted, removing our current record of an open menu + * if it matches the deleted menu handle. + * + * \param *deleted The message block. + */ + +void ro_gui_menu_message_deleted(wimp_message_menus_deleted *deleted) +{ + if (deleted != NULL && deleted->menu == current_menu) + ro_gui_menu_closed(); +} + + +/** + * Clean up after a menu has been closed, or forcibly close an open menu. + */ + +static void ro_gui_menu_closed(void) +{ + if (current_menu != NULL) + ro_gui_wimp_event_menus_closed(current_menu_window, + current_menu_icon, current_menu); + + current_menu = NULL; + current_menu_window = NULL; + current_menu_icon = 0; + current_menu_open = false; +} + + +/** + * Update the current menu by sending it a Menu Prepare event through wimp_event + * and then reopening it if the contents has changed. + * + * \param *menu The menu to refresh: if 0, the current menu will be + * refreshed regardless, otherwise it will be refreshed + * only if it matches the supplied handle. + */ + +void ro_gui_menu_refresh(wimp_menu *menu) +{ + int checksum = 0; + + if (!current_menu_open) + return; + + checksum = ro_gui_menu_get_checksum(); + + if (!ro_gui_wimp_event_prepare_menu(current_menu_window, + current_menu_icon, current_menu)) + return; + + /* \TODO -- Call the menu's event handler here. */ + + if (checksum != ro_gui_menu_get_checksum()) { + os_error *error; + error = xwimp_create_menu(current_menu, 0, 0); + if (error) { + LOG("xwimp_create_menu: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MenuError", error->errmess); + } + } +} + + + + +/** + * Creates a wimp_menu and adds it to the list to handle actions for. + * + * \param menu The data to create the menu with + * \return The menu created, or NULL on failure + */ +wimp_menu *ro_gui_menu_define_menu(const struct ns_menu *menu) +{ + struct menu_definition *definition; + int entry; + + definition = calloc(sizeof(struct menu_definition), 1); + if (!definition) { + die("No memory to create menu definition."); + return NULL; /* For the benefit of scan-build */ + } + + /* link in the menu to our list */ + definition->next = ro_gui_menu_definitions; + ro_gui_menu_definitions = definition; + + /* count number of menu entries */ + for (entry = 0; menu->entries[entry].text; entry++) + /* do nothing */; + + /* create our definitions */ + ro_gui_menu_define_menu_add(definition, menu, 0, NULL, + 0, entry, NULL, 0); + + /* and translate menu into current encoding */ + if (!ro_gui_menu_translate(definition)) + die("No memory to translate menu."); + + return definition->menu; +} + +/** + * Create a wimp menu tree from ns_menu data. + * This function does *not* deal with the menu textual content - it simply + * creates and populates the appropriate structures. Textual content is + * generated by ro_gui_menu_translate_menu() + * + * \param definition Top level menu definition + * \param menu Menu declaration data + * \param depth Depth of menu we're currently building + * \param parent_entry Entry in parent menu, or NULL if root menu + * \param first First index in declaration data that is used by this menu + * \param last Last index in declaration data that is used by this menu + * \param prefix Prefix pf menu declaration string already seen + * \param prefix_length Length of prefix + */ +void ro_gui_menu_define_menu_add(struct menu_definition *definition, + const struct ns_menu *menu, int depth, + wimp_menu_entry *parent_entry, int first, int last, + const char *prefix, int prefix_length) +{ + int entry; + int entries = 0; + int matches[last - first + 1]; + const char *text, *menu_text; + wimp_menu *new_menu; + struct menu_definition_entry *definition_entry; + + /* step 1: store the matches for depth and subset string */ + for (entry = first; entry < last; entry++) { + const char *match; + int cur_depth = 0; + match = menu->entries[entry].text; + + /* skip specials at start of string */ + while (!isalnum(*match)) + match++; + + /* attempt prefix match */ + if ((prefix) && (strncmp(match, prefix, prefix_length))) + continue; + + /* Find depth of this entry */ + while (*match) + if (*match++ == '.') + cur_depth++; + + if (depth == cur_depth) + matches[entries++] = entry; + } + matches[entries] = last; + + /* no entries, so exit */ + if (entries == 0) + return; + + /* step 2: build and link the menu. we must use realloc to stop + * our memory fragmenting so we can test for sub-menus easily */ + new_menu = (wimp_menu *)malloc(wimp_SIZEOF_MENU(entries)); + if (!new_menu) + die("No memory to create menu."); + + if (parent_entry) { + /* Fix up sub menu pointer */ + parent_entry->sub_menu = new_menu; + } else { + /* Root menu => fill in definition struct */ + definition->title_key = menu->title; + definition->current_encoding = 0; + definition->menu = new_menu; + } + + /* this is fixed up in ro_gui_menu_translate() */ + new_menu->title_data.indirected_text.text = NULL; + + /* fill in menu flags */ + ro_gui_menu_init_structure(new_menu, entries); + + /* and then create the entries */ + for (entry = 0; entry < entries; entry++) { + /* add the entry */ + int id = matches[entry]; + + text = menu->entries[id].text; + + /* fill in menu flags from specials at start of string */ + new_menu->entries[entry].menu_flags = 0; + while (!isalnum(*text)) { + if (*text == '_') + new_menu->entries[entry].menu_flags |= + wimp_MENU_SEPARATE; + text++; + } + + /* get messages key for menu entry */ + menu_text = strrchr(text, '.'); + if (!menu_text) + /* no '.' => top-level entry */ + menu_text = text; + else + menu_text++; /* and move past the '.' */ + + /* fill in submenu data */ + if (menu->entries[id].sub_window) + new_menu->entries[entry].sub_menu = + (wimp_menu *) (*menu->entries[id].sub_window); + + /* this is fixed up in ro_gui_menu_translate() */ + new_menu->entries[entry].data.indirected_text.text = NULL; + + /* create definition entry */ + definition_entry = + malloc(sizeof(struct menu_definition_entry)); + if (!definition_entry) + die("Unable to create menu definition entry"); + definition_entry->action = menu->entries[id].action; + definition_entry->menu_entry = &new_menu->entries[entry]; + definition_entry->entry_key = menu_text; + definition_entry->next = definition->entries; + definition->entries = definition_entry; + + /* recurse */ + if (new_menu->entries[entry].sub_menu == wimp_NO_SUB_MENU) { + ro_gui_menu_define_menu_add(definition, menu, + depth + 1, &new_menu->entries[entry], + matches[entry], matches[entry + 1], + text, strlen(text)); + } + + /* give menu warnings */ + if (new_menu->entries[entry].sub_menu != wimp_NO_SUB_MENU) + new_menu->entries[entry].menu_flags |= + wimp_MENU_GIVE_WARNING; + } + new_menu->entries[0].menu_flags |= wimp_MENU_TITLE_INDIRECTED; + new_menu->entries[entries - 1].menu_flags |= wimp_MENU_LAST; +} + + +/** + * Initialise the basic state of a menu structure so all entries are + * indirected text with no flags, no submenu. + */ +void ro_gui_menu_init_structure(wimp_menu *menu, int entries) +{ + int i; + + menu->title_fg = wimp_COLOUR_BLACK; + menu->title_bg = wimp_COLOUR_LIGHT_GREY; + menu->work_fg = wimp_COLOUR_BLACK; + menu->work_bg = wimp_COLOUR_WHITE; + menu->width = 200; + menu->height = wimp_MENU_ITEM_HEIGHT; + menu->gap = wimp_MENU_ITEM_GAP; + + for (i = 0; i < entries; i++) { + menu->entries[i].menu_flags = 0; + menu->entries[i].sub_menu = wimp_NO_SUB_MENU; + menu->entries[i].icon_flags = + DEFAULT_FLAGS | wimp_ICON_INDIRECTED; + menu->entries[i].data.indirected_text.validation = + (char *)-1; + } + menu->entries[0].menu_flags |= wimp_MENU_TITLE_INDIRECTED; + menu->entries[i - 1].menu_flags |= wimp_MENU_LAST; +} + + +/** + * Finds the menu_definition corresponding to a wimp_menu. + * + * \param menu the menu to find the definition for + * \return the associated definition, or NULL if one could not be found + */ +struct menu_definition *ro_gui_menu_find_menu(wimp_menu *menu) +{ + struct menu_definition *definition; + + if (!menu) + return NULL; + + for (definition = ro_gui_menu_definitions; definition; + definition = definition->next) + if (definition->menu == menu) + return definition; + return NULL; +} + + +/** + * Finds the key associated with a menu entry translation. + * + * \param menu the menu to search + * \param translated the translated text + * \return the original message key, or NULL if one could not be found + */ +const char *ro_gui_menu_find_menu_entry_key(wimp_menu *menu, + const char *translated) +{ + struct menu_definition_entry *entry; + struct menu_definition *definition = ro_gui_menu_find_menu(menu); + + if (!definition) + return NULL; + + for (entry = definition->entries; entry; entry = entry->next) + if (!strcmp(entry->menu_entry->data.indirected_text.text, translated)) + return entry->entry_key; + return NULL; +} + + +/** + * Finds the menu_definition_entry corresponding to an action for a wimp_menu. + * + * \param menu the menu to search for an action within + * \param action the action to find + * \return the associated menu entry, or NULL if one could not be found + */ +struct menu_definition_entry *ro_gui_menu_find_entry(wimp_menu *menu, + menu_action action) +{ + struct menu_definition_entry *entry; + struct menu_definition *definition = ro_gui_menu_find_menu(menu); + + if (!definition) + return NULL; + + for (entry = definition->entries; entry; entry = entry->next) + if (entry->action == action) + return entry; + return NULL; +} + + +/** + * Finds the action corresponding to a wimp_menu_entry for a wimp_menu. + * + * \param menu the menu to search for an action within + * \param menu_entry the menu_entry to find + * \return the associated action, or 0 if one could not be found + */ +menu_action ro_gui_menu_find_action(wimp_menu *menu, wimp_menu_entry *menu_entry) +{ + struct menu_definition_entry *entry; + struct menu_definition *definition = ro_gui_menu_find_menu(menu); + + if (!definition) + return NO_ACTION; + + for (entry = definition->entries; entry; entry = entry->next) { + if (entry->menu_entry == menu_entry) + return entry->action; + } + return NO_ACTION; +} + + +/** + * Sets an action within a menu as having a specific ticked status. + * + * \param menu the menu containing the action + * \param action the action to tick/untick + * \param shaded whether to set the item as shaded + */ +void ro_gui_menu_set_entry_shaded(wimp_menu *menu, menu_action action, + bool shaded) +{ + struct menu_definition_entry *entry; + struct menu_definition *definition = ro_gui_menu_find_menu(menu); + + if (!definition) + return; + + /* we can't use find_entry as multiple actions may appear in one menu */ + for (entry = definition->entries; entry; entry = entry->next) + if (entry->action == action) { + if (shaded) + entry->menu_entry->icon_flags |= wimp_ICON_SHADED; + else + entry->menu_entry->icon_flags &= ~wimp_ICON_SHADED; + } +} + + +/** + * Sets an action within a menu as having a specific ticked status. + * + * \param menu the menu containing the action + * \param action the action to tick/untick + * \param ticked whether to set the item as ticked + */ +void ro_gui_menu_set_entry_ticked(wimp_menu *menu, menu_action action, + bool ticked) +{ + struct menu_definition_entry *entry = + ro_gui_menu_find_entry(menu, action); + if (entry) { + if (ticked) + entry->menu_entry->menu_flags |= wimp_MENU_TICKED; + else + entry->menu_entry->menu_flags &= ~wimp_MENU_TICKED; + } +} + + +/** + * Calculates a simple checksum for the current menu state + */ +int ro_gui_menu_get_checksum(void) +{ + wimp_selection menu_tree; + int i = 0, j, checksum = 0; + os_error *error; + wimp_menu *menu; + + if (!current_menu_open) + return 0; + + error = xwimp_get_menu_state((wimp_menu_state_flags)0, + &menu_tree, 0, 0); + if (error) { + LOG("xwimp_get_menu_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MenuError", error->errmess); + return 0; + } + + menu = current_menu; + do { + j = 0; + do { + if (menu->entries[j].icon_flags & wimp_ICON_SHADED) + checksum ^= (1 << (i + j * 2)); + if (menu->entries[j].menu_flags & wimp_MENU_TICKED) + checksum ^= (2 << (i + j * 2)); + } while (!(menu->entries[j++].menu_flags & wimp_MENU_LAST)); + + j = menu_tree.items[i++]; + if (j != -1) { + menu = menu->entries[j].sub_menu; + if ((!menu) || (menu == wimp_NO_SUB_MENU) || (!IS_MENU(menu))) + break; + } + } while (j != -1); + + return checksum; +} + +/** + * Translate a menu's textual content into the system local encoding + * + * \param menu The menu to translate + * \return false if out of memory, true otherwise + */ +bool ro_gui_menu_translate(struct menu_definition *menu) +{ + os_error *error; + int alphabet; + struct menu_definition_entry *entry; + char *translated; + nserror err; + + /* read current alphabet */ + error = xosbyte1(osbyte_ALPHABET_NUMBER, 127, 0, &alphabet); + if (error) { + LOG("failed reading alphabet: 0x%x: %s", error->errnum, error->errmess); + /* assume Latin1 */ + alphabet = territory_ALPHABET_LATIN1; + } + + if (menu->current_encoding == alphabet) + /* menu text is already in the correct encoding */ + return true; + + /* translate root menu title text */ + free(menu->menu->title_data.indirected_text.text); + err = utf8_to_local_encoding(messages_get(menu->title_key), + 0, &translated); + if (err != NSERROR_OK) { + assert(err != NSERROR_BAD_ENCODING); + LOG("utf8_to_enc failed"); + return false; + } + + /* and fill in WIMP menu field */ + menu->menu->title_data.indirected_text.text = translated; + + /* now the menu entries */ + for (entry = menu->entries; entry; entry = entry->next) { + wimp_menu *submenu = entry->menu_entry->sub_menu; + + /* tranlate menu entry text */ + free(entry->menu_entry->data.indirected_text.text); + err = utf8_to_local_encoding(messages_get(entry->entry_key), + 0, &translated); + if (err != NSERROR_OK) { + assert(err != NSERROR_BAD_ENCODING); + LOG("utf8_to_enc failed"); + return false; + } + + /* fill in WIMP menu fields */ + entry->menu_entry->data.indirected_text.text = translated; + entry->menu_entry->data.indirected_text.validation = + (char *) -1; + entry->menu_entry->data.indirected_text.size = + strlen(translated); + + /* child menu title - this is the same as the text of + * the parent menu entry, so just copy the pointer */ + if (submenu != wimp_NO_SUB_MENU && IS_MENU(submenu)) { + submenu->title_data.indirected_text.text = + translated; + } + } + + /* finally, set the current encoding of the menu */ + menu->current_encoding = alphabet; + + return true; +} + diff --git a/frontends/riscos/menus.h b/frontends/riscos/menus.h new file mode 100644 index 000000000..7faa87ed6 --- /dev/null +++ b/frontends/riscos/menus.h @@ -0,0 +1,183 @@ +/* + * Copyright 2005 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _NETSURF_RISCOS_MENUS_H_ +#define _NETSURF_RISCOS_MENUS_H_ + +extern wimp_menu *image_quality_menu, *proxy_type_menu, *languages_menu; + +extern wimp_menu *current_menu; + +typedef enum { + + /* no/unknown actions */ + NO_ACTION, + + /* help actions */ + HELP_OPEN_CONTENTS, + HELP_OPEN_GUIDE, + HELP_OPEN_INFORMATION, + HELP_OPEN_CREDITS, + HELP_OPEN_LICENCE, + HELP_LAUNCH_INTERACTIVE, + + /* history actions */ + HISTORY_SHOW_LOCAL, + HISTORY_SHOW_GLOBAL, + + /* hotlist actions */ + HOTLIST_ADD_URL, + HOTLIST_SHOW, + + /* cookie actions */ + COOKIES_SHOW, + COOKIES_DELETE, + + /* page actions */ + BROWSER_PAGE, + BROWSER_PAGE_INFO, + BROWSER_PRINT, + BROWSER_NEW_WINDOW, + BROWSER_VIEW_SOURCE, + + /* object actions */ + BROWSER_OBJECT, + BROWSER_OBJECT_OBJECT, + BROWSER_OBJECT_LINK, + BROWSER_OBJECT_INFO, + BROWSER_OBJECT_PRINT, + BROWSER_OBJECT_RELOAD, + BROWSER_LINK_SAVE, + BROWSER_LINK_DOWNLOAD, + BROWSER_LINK_NEW_WINDOW, + + /* save actions */ + BROWSER_OBJECT_SAVE, + BROWSER_OBJECT_EXPORT, + BROWSER_OBJECT_EXPORT_SPRITE, + BROWSER_OBJECT_EXPORT_DRAW, + BROWSER_OBJECT_SAVE_URL_URI, + BROWSER_OBJECT_SAVE_URL_URL, + BROWSER_OBJECT_SAVE_URL_TEXT, + BROWSER_SAVE, + BROWSER_SAVE_COMPLETE, + BROWSER_EXPORT_DRAW, + BROWSER_EXPORT_PDF, + BROWSER_EXPORT_TEXT, + BROWSER_SAVE_URL_URI, + BROWSER_SAVE_URL_URL, + BROWSER_SAVE_URL_TEXT, + BROWSER_LINK_SAVE_URI, + BROWSER_LINK_SAVE_URL, + BROWSER_LINK_SAVE_TEXT, + HOTLIST_EXPORT, + HISTORY_EXPORT, + + /* selection actions */ + BROWSER_SELECTION, + BROWSER_SELECTION_SAVE, + BROWSER_SELECTION_COPY, + BROWSER_SELECTION_CUT, + BROWSER_SELECTION_PASTE, + BROWSER_SELECTION_CLEAR, + BROWSER_SELECTION_ALL, + + /* navigation actions */ + BROWSER_NAVIGATE_HOME, + BROWSER_NAVIGATE_BACK, + BROWSER_NAVIGATE_FORWARD, + BROWSER_NAVIGATE_UP, + BROWSER_NAVIGATE_RELOAD, + BROWSER_NAVIGATE_RELOAD_ALL, + BROWSER_NAVIGATE_STOP, + BROWSER_NAVIGATE_URL, + + /* browser window/display actions */ + BROWSER_SCALE_VIEW, + BROWSER_FIND_TEXT, + BROWSER_IMAGES_FOREGROUND, + BROWSER_IMAGES_BACKGROUND, + BROWSER_BUFFER_ANIMS, + BROWSER_BUFFER_ALL, + BROWSER_SAVE_VIEW, + BROWSER_WINDOW_DEFAULT, + BROWSER_WINDOW_STAGGER, + BROWSER_WINDOW_COPY, + BROWSER_WINDOW_RESET, + + /* tree actions */ + TREE_NEW_FOLDER, + TREE_NEW_LINK, + TREE_EXPAND_ALL, + TREE_EXPAND_FOLDERS, + TREE_EXPAND_LINKS, + TREE_COLLAPSE_ALL, + TREE_COLLAPSE_FOLDERS, + TREE_COLLAPSE_LINKS, + TREE_SELECTION, + TREE_SELECTION_EDIT, + TREE_SELECTION_LAUNCH, + TREE_SELECTION_DELETE, + TREE_SELECT_ALL, + TREE_CLEAR_SELECTION, + + /* toolbar actions */ + TOOLBAR_BUTTONS, + TOOLBAR_ADDRESS_BAR, + TOOLBAR_THROBBER, + TOOLBAR_EDIT, + + /* misc actions */ + CHOICES_SHOW, + APPLICATION_QUIT, +} menu_action; + + +/* Menu entry structures for use when defining menus. */ + +struct ns_menu_entry { + const char *text; /**< menu text (from messages) */ + menu_action action; /**< associated action */ + wimp_w *sub_window; /**< sub-window if any */ +}; + +struct ns_menu { + const char *title; + struct ns_menu_entry entries[]; +}; + + +void ro_gui_menu_init(void); +void ro_gui_menu_create(wimp_menu* menu, int x, int y, wimp_w w); +void ro_gui_menu_destroy(void); +void ro_gui_popup_menu(wimp_menu *menu, wimp_w w, wimp_i i); +void ro_gui_menu_window_changed(wimp_w from, wimp_w to); +void ro_gui_menu_selection(wimp_selection* selection); +void ro_gui_menu_warning(wimp_message_menu_warning *warning); +void ro_gui_menu_message_deleted(wimp_message_menus_deleted *deleted); +void ro_gui_menu_refresh(wimp_menu *menu); +void ro_gui_menu_init_structure(wimp_menu *menu, int entries); +const char *ro_gui_menu_find_menu_entry_key(wimp_menu *menu, + const char *translated); +wimp_menu *ro_gui_menu_define_menu(const struct ns_menu *menu); +void ro_gui_menu_set_entry_shaded(wimp_menu *menu, menu_action action, + bool shaded); +void ro_gui_menu_set_entry_ticked(wimp_menu *menu, menu_action action, + bool ticked); + +#endif diff --git a/frontends/riscos/message.c b/frontends/riscos/message.c new file mode 100644 index 000000000..1c54ea0b7 --- /dev/null +++ b/frontends/riscos/message.c @@ -0,0 +1,247 @@ +/* + * Copyright 2006 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Automated RISC OS message routing (implementation). + */ + +#include <assert.h> +#include <stdbool.h> +#include <stdlib.h> +#include "oslib/os.h" +#include "oslib/wimp.h" + +#include "utils/log.h" + +#include "riscos/message.h" +#include "riscos/gui.h" + +struct active_message { + unsigned int message_code; + int id; + void (*callback)(wimp_message *message); + struct active_message *next; + struct active_message *previous; +}; +struct active_message *current_messages = NULL; + +static struct active_message *ro_message_add(unsigned int message_code, + void (*callback)(wimp_message *message)); +static void ro_message_free(int ref); + + +/** + * Sends a message and registers a return route for a bounce. + * + * \param event the message event type + * \param message the message to register a route back for + * \param task the task to send a message to, or 0 for broadcast + * \param callback the code to call on a bounce + * \return true on success, false otherwise + */ +bool ro_message_send_message(wimp_event_no event, wimp_message *message, + wimp_t task, void (*callback)(wimp_message *message)) +{ + os_error *error; + + assert(message); + + /* send a message */ + error = xwimp_send_message(event, message, task); + if (error) { + LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + + /* register the default bounce handler */ + if (callback) { + assert(event == wimp_USER_MESSAGE_RECORDED); + return ro_message_register_handler(message, message->action, + callback); + } + return true; +} + + +/** + * Sends a message and registers a return route for a bounce. + * + * \param event the message event type + * \param message the message to register a route back for + * \param to_w the window to send the message to + * \param to_i the icon + * \param callback the code to call on a bounce + * \param to_t receives the task handle of the window's creator + * \return true on success, false otherwise + */ +bool ro_message_send_message_to_window(wimp_event_no event, wimp_message *message, + wimp_w to_w, wimp_i to_i, void (*callback)(wimp_message *message), + wimp_t *to_t) +{ + os_error *error; + + assert(message); + + /* send a message */ + error = xwimp_send_message_to_window(event, message, to_w, to_i, to_t); + if (error) { + LOG("xwimp_send_message_to_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + + /* register the default bounce handler */ + if (callback) { + assert(event == wimp_USER_MESSAGE_RECORDED); + return ro_message_register_handler(message, message->action, + callback); + } + return true; +} + + +/** + * Registers a return route for a message. + * + * This function must be called after wimp_send_message so that a + * valid value is present in the my_ref field. + * + * \param message the message to register a route back for + * \param message_code the message action code to route + * \param callback the code to call for a matched action + * \return true on success, false on memory exhaustion + */ +bool ro_message_register_handler(wimp_message *message, + unsigned int message_code, + void (*callback)(wimp_message *message)) +{ + struct active_message *add; + + assert(message); + assert(callback); + + add = ro_message_add(message_code, callback); + if (add) + add->id = message->my_ref; + return (add != NULL); +} + + +/** + * Registers a route for a message code. + * + * \param message_code the message action code to route + * \param callback the code to call for a matched action + * \return true on success, false on memory exhaustion + */ +bool ro_message_register_route(unsigned int message_code, + void (*callback)(wimp_message *message)) +{ + assert(callback); + + return (ro_message_add(message_code, callback) != NULL); +} + +struct active_message *ro_message_add(unsigned int message_code, + void (*callback)(wimp_message *message)) +{ + struct active_message *add; + + assert(callback); + + add = (struct active_message *)malloc(sizeof(*add)); + if (!add) + return NULL; + add->message_code = message_code; + add->id = 0; + add->callback = callback; + add->next = current_messages; + add->previous = NULL; + current_messages = add; + return add; +} + + +/** + * Attempts to route a message. + * + * \param event wimp event + * \param message the message to attempt to route + * \return true if message was routed, false otherwise + */ +bool ro_message_handle_message(wimp_event_no event, wimp_message *message) +{ + struct active_message *test; + + assert(message); + + if (event == wimp_USER_MESSAGE_ACKNOWLEDGE) { + /* handle message acknowledgement */ + bool handled = false; + int ref = message->my_ref; + + if (ref == 0) + return false; + + /* handle the message */ + for (test = current_messages; test; test = test->next) { + if ((ref == test->id) && + (message->action == test->message_code)) { + handled = true; + if (test->callback) + test->callback(message); + break; + } + } + + /* remove all handlers for this id */ + ro_message_free(ref); + return handled; + } else { + /* handle simple routing */ + for (test = current_messages; test; test = test->next) { + if ((test->id == 0) && + (message->action == test->message_code)) { + test->callback(message); + return true; + } + } + } + return false; +} + + +void ro_message_free(int ref) +{ + struct active_message *test; + struct active_message *next = current_messages; + + while ((test = next)) { + next = test->next; + if (ref == test->id) { + if (test->previous) + test->previous->next = test->next; + if (test->next) + test->next->previous = test->previous; + if (current_messages == test) + current_messages = test->next; + free(test); + } + } +} diff --git a/frontends/riscos/message.h b/frontends/riscos/message.h new file mode 100644 index 000000000..8c1a515f2 --- /dev/null +++ b/frontends/riscos/message.h @@ -0,0 +1,42 @@ +/* + * Copyright 2006 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Automated RISC OS message routing (interface). + */ + + +#ifndef _NETSURF_RISCOS_MESSAGE_H_ +#define _NETSURF_RISCOS_MESSAGE_H_ + +#include <stdbool.h> +#include "oslib/wimp.h" + +bool ro_message_send_message(wimp_event_no event, wimp_message *message, + wimp_t task, void (*callback)(wimp_message *message)); +bool ro_message_send_message_to_window(wimp_event_no event, wimp_message *message, + wimp_w to_w, wimp_i to_i, void (*callback)(wimp_message *message), + wimp_t *to_t); +bool ro_message_register_handler(wimp_message *message, + unsigned int message_code, + void (*callback)(wimp_message *message)); +bool ro_message_register_route(unsigned int message_code, + void (*callback)(wimp_message *message)); +bool ro_message_handle_message(wimp_event_no event, wimp_message *message); + +#endif diff --git a/frontends/riscos/mouse.c b/frontends/riscos/mouse.c new file mode 100644 index 000000000..a0cc0e7ce --- /dev/null +++ b/frontends/riscos/mouse.c @@ -0,0 +1,282 @@ +/* + * Copyright 2013 Stephen Fryatt <stevef@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Mouse dragging and tracking support implementation. + * + * Two different functions are provided:- + * + * 1. Wimp_DragBox support, allowing clients to start a drag and specify + * callbacks to be used + * + * - on Null Polls while the drag is active, + * - when the drag terminates with Event_DragEnd, and + * - when the drag terminates with Escape being pressed. + * + * 2. Mouse tracking support, allowing clients to track the mouse while it + * remains in the current window and specify callbacks to be used + * + * - on Null Polls while the pointer is in the window, and + * - when the pointer leaves the window. + */ + +#include <assert.h> +#include <oslib/wimp.h> + +#include "utils/log.h" + +#include "riscos/mouse.h" +#include "riscos/gui.h" + +/* Data for the wimp drag handler. */ + +static void (*ro_mouse_drag_end_callback)(wimp_dragged *dragged, void *data) + = NULL; +static void (*ro_mouse_drag_track_callback)(wimp_pointer *pointer, void *data) + = NULL; +static void (*ro_mouse_drag_cancel_callback)(void *data) = NULL; +static void *ro_mouse_drag_data = NULL; + +static bool ro_mouse_ignore_leaving_event = false; + +/* Data for the wimp poll handler. */ + +static void (*ro_mouse_poll_end_callback)(wimp_leaving *leaving, void *data) + = NULL; +static void (*ro_mouse_poll_track_callback)(wimp_pointer *pointer, void *data) + = NULL; +static void *ro_mouse_poll_data = NULL; + + +/** + * Process Null polls for any drags and mouse trackers that are currently + * active. + */ + +void ro_mouse_poll(void) +{ + wimp_pointer pointer; + os_error *error; + + /* If no trackers are active, just exit. */ + + if (ro_mouse_drag_track_callback == NULL && + ro_mouse_poll_track_callback == NULL) + return; + + error = xwimp_get_pointer_info(&pointer); + if (error) { + LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + /* Process the drag tracker, if one is active. */ + + if (ro_mouse_drag_track_callback != NULL) + ro_mouse_drag_track_callback(&pointer, ro_mouse_drag_data); + + /* Process the window tracker, if one is active. */ + + if (ro_mouse_poll_track_callback != NULL) + ro_mouse_poll_track_callback(&pointer, ro_mouse_poll_data); +} + + +/** + * Start a drag, providing a function to be called when the Wimp_DragEnd event + * is received and optionally a tracking function to be called on null polls + * in between times. + * + * \param *drag_end Callback for when the drag terminates, or NULL for none. + * \param *drag_track Callback for mouse tracking during the drag, or NULL for + * none. + * \param *drag_cancel Callback for cancelling the drag, or NULL if the drag + * can't be cancelled. + * \param *data Data to be passed to the callback functions, or NULL. + */ + +void ro_mouse_drag_start(void (*drag_end)(wimp_dragged *dragged, void *data), + void (*drag_track)(wimp_pointer *pointer, void *data), + void (*drag_cancel)(void *data), void *data) +{ + /* A drag should never be started when one is already in progress. */ + + assert(ro_mouse_drag_end_callback == NULL && + ro_mouse_drag_track_callback == NULL && + ro_mouse_drag_cancel_callback == NULL && + ro_mouse_drag_data == NULL); + + ro_mouse_drag_end_callback = drag_end; + ro_mouse_drag_track_callback = drag_track; + ro_mouse_drag_cancel_callback = drag_cancel; + ro_mouse_drag_data = data; + + /* The Wimp sends a PointerLeaving event when Wimp_DragBox is called, + * so we mask out the next event that will come our way. + */ + + ro_mouse_ignore_leaving_event = true; +} + + +/** + * Process Wimp_DragEnd events by terminating an active drag track and passing + * the details on to any registered event handler. + * + * \param *dragged The Wimp_DragEnd data block. + */ + +void ro_mouse_drag_end(wimp_dragged *dragged) +{ + if (ro_mouse_drag_end_callback != NULL) + ro_mouse_drag_end_callback(dragged, ro_mouse_drag_data); + else + ro_warn_user("WimpError", "No callback"); + + /* Wimp_DragEnd is a one-shot event, so clear the data ready for + * another claimant. + */ + + ro_mouse_drag_end_callback = NULL; + ro_mouse_drag_track_callback = NULL; + ro_mouse_drag_cancel_callback = NULL; + ro_mouse_drag_data = NULL; +} + + +/** + * Start tracking the mouse in a window, providing a function to be called on + * null polls and optionally one to be called when it leaves the window. + * + * \param *poll_end Callback for when the pointer leaves the window, or + * NULL for none. Claimants can receive *leaving==NULL if + * a new tracker is started before a PointerLeaving event + * is received. + * \param *poll_track Callback for mouse tracking while the pointer remains + * in the window, or NULL for none. + * \param *data Data to be passed to the callback functions, or NULL. + */ + +void ro_mouse_track_start(void (*poll_end)(wimp_leaving *leaving, void *data), + void (*poll_track)(wimp_pointer *pointer, void *data), + void *data) +{ + /* It should never be possible for the mouse to be in two windows + * at the same time! However, some third-party extensions to RISC OS + * appear to make this possible (MouseAxess being one), so in the + * event that there's still a claimant we tidy them up first and then + * log the fact in case there are any unexpected consequences. + * + * NB: The Poll End callback will get called with *leaving == NULL in + * this situation, as there's no PointerLeaving event to pass on. + */ + + if (ro_mouse_poll_end_callback != NULL || + ro_mouse_poll_track_callback != NULL || + ro_mouse_poll_data != NULL) { + if (ro_mouse_poll_end_callback != NULL && + ro_mouse_ignore_leaving_event == false) + ro_mouse_poll_end_callback(NULL, ro_mouse_poll_data); + + LOG("Unexpected mouse track termination."); + + ro_mouse_ignore_leaving_event = false; + ro_mouse_poll_end_callback = NULL; + ro_mouse_poll_track_callback = NULL; + ro_mouse_poll_data = NULL; + } + + /* Now record details of the new claimant. */ + + ro_mouse_poll_end_callback = poll_end; + ro_mouse_poll_track_callback = poll_track; + ro_mouse_poll_data = data; +} + + +/** + * Process Wimp_PointerLeaving events by terminating an active mouse track and + * passing the details on to any registered event handler. + * + * If the ignore mask is set, we don't pass the event on to the client as it + * is assumed that it's a result of starting a Wimp_DragBox operation. + * + * \param *leaving The Wimp_PointerLeaving data block. + */ + +void ro_mouse_pointer_leaving_window(wimp_leaving *leaving) +{ + if (ro_mouse_poll_end_callback != NULL && + ro_mouse_ignore_leaving_event == false) + ro_mouse_poll_end_callback(leaving, ro_mouse_poll_data); + + ro_mouse_ignore_leaving_event = false; + + /* Poll tracking is a one-shot event, so clear the data ready for + * another claimant. + */ + + ro_mouse_poll_end_callback = NULL; + ro_mouse_poll_track_callback = NULL; + ro_mouse_poll_data = NULL; +} + + +/** + * Kill any tracking events if the data pointers match the supplied pointer. + * + * \param *data The data of the client to be killed. + */ + +void ro_mouse_kill(void *data) +{ + if (data == ro_mouse_drag_data) { + ro_mouse_drag_end_callback = NULL; + ro_mouse_drag_track_callback = NULL; + ro_mouse_drag_cancel_callback = NULL; + ro_mouse_drag_data = NULL; + } + + if (data == ro_mouse_poll_data) { + ro_mouse_poll_end_callback = NULL; + ro_mouse_poll_track_callback = NULL; + ro_mouse_poll_data = NULL; + } +} + + +/** + * Return the desired polling interval to allow the mouse tracking to be + * carried out. + * + * \return Desired poll interval (0 for none required). + */ + +os_t ro_mouse_poll_interval(void) +{ + if (ro_mouse_drag_track_callback != NULL) + return 4; + + if (ro_mouse_poll_track_callback != NULL) + return 10; + + return 0; + +} + diff --git a/frontends/riscos/mouse.h b/frontends/riscos/mouse.h new file mode 100644 index 000000000..6bc5c13e1 --- /dev/null +++ b/frontends/riscos/mouse.h @@ -0,0 +1,110 @@ +/* + * Copyright 2013 Stephen Fryatt <stevef@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +/** \file + * Mouse dragging and tracking support interface for RISC OS. + */ + +#ifndef _NETSURF_RISCOS_MOUSE_H_ +#define _NETSURF_RISCOS_MOUSE_H_ + + +/** + * Process Null polls for any drags and mouse trackers that are currently + * active. + */ + +void ro_mouse_poll(void); + + +/** + * Start a drag, providing a function to be called when the Wimp_DragEnd event + * is received and optionally a tracking function to be called on null polls + * in between times. + * + * \param *drag_end Callback for when the drag terminates, or NULL for none. + * \param *drag_track Callback for mouse tracking during the drag, or NULL for + * none. + * \param *drag_cancel Callback for cancelling the drag, or NULL if the drag + * can't be cancelled. + * \param *data Data to be passed to the callback functions, or NULL. + */ + +void ro_mouse_drag_start(void (*drag_end)(wimp_dragged *dragged, void *data), + void (*drag_track)(wimp_pointer *pointer, void *data), + void (*drag_cancel)(void *data), void *data); + + +/** + * Process Wimp_DragEnd events by passing the details on to any registered + * event handler. + * + * \param *dragged The Wimp_DragEnd data block. + */ + +void ro_mouse_drag_end(wimp_dragged *dragged); + + +/** + * Start tracking the mouse in a window, providing a function to be called on + * null polls and optionally one to be called when it leaves the window. + * + * \param *poll_end Callback for when the pointer leaves the window, or + * NULL for none. Claimants can receive *leaving==NULL if + * a new tracker is started before a PointerLeaving event + * is received. + * \param *poll_track Callback for mouse tracking while the pointer remains + * in the window, or NULL for none. + * \param *data Data to be passed to the callback functions, or NULL. + */ + +void ro_mouse_track_start(void (*poll_end)(wimp_leaving *leaving, void *data), + void (*poll_track)(wimp_pointer *pointer, void *data), + void *data); + +/** + * Process Wimp_PointerLeaving events by terminating an active mouse track and + * passing the details on to any registered event handler. + * + * \param *leaving The Wimp_PointerLeaving data block. + */ + +void ro_mouse_pointer_leaving_window(wimp_leaving *leaving); + + +/** + * Kill any tracking events if the data pointers match the supplied pointer. + * + * \param *data The data of the client to be killed. + */ + +void ro_mouse_kill(void *data); + + +/** + * Return the desired polling interval to allow the mouse tracking to be + * carried out. + * + * \return Desired poll interval (0 for none required). + */ + +os_t ro_mouse_poll_interval(void); + +#endif + diff --git a/frontends/riscos/options.h b/frontends/riscos/options.h new file mode 100644 index 000000000..cb2b78bd8 --- /dev/null +++ b/frontends/riscos/options.h @@ -0,0 +1,68 @@ +/* + * Copyright 2012 Vincent Sanders <vince@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * RISC OS specific options. + */ + +#ifndef _NETSURF_RISCOS_OPTIONS_H_ +#define _NETSURF_RISCOS_OPTIONS_H_ + +#include "riscos/tinct.h" + +/* setup longer default reflow time */ +#define DEFAULT_REFLOW_PERIOD 100 /* time in cs */ + +#define CHOICES_PREFIX "<Choices$Write>.WWW.NetSurf." + +#endif + +NSOPTION_STRING(theme, "Aletheia") +NSOPTION_STRING(language, NULL) +NSOPTION_INTEGER(plot_fg_quality, tinct_ERROR_DIFFUSE) +NSOPTION_INTEGER(plot_bg_quality, tinct_DITHER) +NSOPTION_BOOL(history_tooltip, true) +NSOPTION_BOOL(toolbar_show_buttons, true) +NSOPTION_BOOL(toolbar_show_address, true) +NSOPTION_BOOL(toolbar_show_throbber, true) +NSOPTION_STRING(toolbar_browser, "0123|58|9") +NSOPTION_STRING(toolbar_hotlist, "40|12|3") +NSOPTION_STRING(toolbar_history, "0|12|3") +NSOPTION_STRING(toolbar_cookies, "0|12") +NSOPTION_BOOL(window_stagger, true) +NSOPTION_BOOL(window_size_clone, true) +NSOPTION_BOOL(buffer_animations, true) +NSOPTION_BOOL(buffer_everything, true) +NSOPTION_BOOL(open_browser_at_startup, false) +NSOPTION_BOOL(no_plugins, false) +NSOPTION_BOOL(block_popups, false) +NSOPTION_BOOL(strip_extensions, false) +NSOPTION_BOOL(confirm_overwrite, true) +NSOPTION_BOOL(confirm_hotlist_remove, true) +NSOPTION_STRING(url_path, "NetSurf:URL") +NSOPTION_STRING(url_save, CHOICES_PREFIX "URL") +NSOPTION_STRING(hotlist_path, "NetSurf:Hotlist") +NSOPTION_STRING(hotlist_save, CHOICES_PREFIX "Hotlist") +NSOPTION_STRING(recent_path, "NetSurf:Recent") +NSOPTION_STRING(recent_save, CHOICES_PREFIX "Recent") +NSOPTION_STRING(theme_path, "NetSurf:Themes") +NSOPTION_STRING(theme_save, CHOICES_PREFIX "Themes") +NSOPTION_BOOL(thumbnail_iconise, true) +NSOPTION_BOOL(interactive_help, true) +NSOPTION_BOOL(external_hotlists, false) +NSOPTION_STRING(external_hotlist_app, NULL) diff --git a/frontends/riscos/oslib_pre7.h b/frontends/riscos/oslib_pre7.h new file mode 100644 index 000000000..a99bd0349 --- /dev/null +++ b/frontends/riscos/oslib_pre7.h @@ -0,0 +1,42 @@ +/* + * Copyright 2008 John Tytgat <joty@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Backward compatible defines to make NetSurf buildable with pre-OSLib 7 + * releases. + */ + +#ifndef _NETSURF_RISCOS_OSLIB_PRE7_H_ +#define _NETSURF_RISCOS_OSLIB_PRE7_H_ + +#include "oslib/colourtrans.h" + +/** + * After OSLib 6.90, there was a rename of colourtrans defines in order + * to avoid namespace clashes: + * svn diff -c 238 https://ro-oslib.svn.sourceforge.net/svnroot/ro-oslib/trunk/\!OSLib/Source/Core/oslib/ColourTrans.swi + * Foresee some backwards compatibility until we've switched to OSLib 7. +*/ +#ifndef colourtrans_SET_BG_GCOL +# define colourtrans_SET_BG_GCOL colourtrans_SET_BG +#endif +#ifndef colourtrans_USE_ECFS_GCOL +# define colourtrans_USE_ECFS_GCOL colourtrans_USE_ECFS +#endif + +#endif diff --git a/frontends/riscos/palettes.c b/frontends/riscos/palettes.c new file mode 100644 index 000000000..631d8802a --- /dev/null +++ b/frontends/riscos/palettes.c @@ -0,0 +1,321 @@ +/* + * Copyright 2006 Adrian Lees <adrianl@users.sourceforge.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Palette definitions for sprites + */ + +#include "riscos/palettes.h" + + +const os_colour default_palette1[] = +{ + 0xffffff00, 0xffffff00, + 0x00000000, 0x00000000 +}; + + +const os_colour default_palette2[] = +{ + 0xffffff00, 0xffffff00, + 0xbbbbbb00, 0xbbbbbb00, + 0x77777700, 0x77777700, + 0x00000000, 0x00000000 +}; + + +const os_colour wimp_palette[] = +{ + 0xffffff00, 0xffffff00, + 0xdddddd00, 0xdddddd00, + 0xbbbbbb00, 0xbbbbbb00, + 0x99999900, 0x99999900, + 0x77777700, 0x77777700, + 0x55555500, 0x55555500, + 0x33333300, 0x33333300, + 0x00000000, 0x00000000, + 0x99440000, 0x99440000, + 0x00eeee00, 0x00eeee00, + 0x00cc0000, 0x00cc0000, + 0x0000dd00, 0x0000dd00, + 0xbbeeee00, 0xbbeeee00, + 0x00885500, 0x00885500, + 0x00bbff00, 0x00bbff00, + 0xffbb0000, 0xffbb0000 +}; + + +const os_colour default_palette8[] = +{ + 0x00000010, 0x00000010, + 0x11111110, 0x11111110, + 0x22222210, 0x22222210, + 0x33333310, 0x33333310, + 0x00004410, 0x00004410, + 0x11115510, 0x11115510, + 0x22226610, 0x22226610, + 0x33337710, 0x33337710, + 0x44000010, 0x44000010, + 0x55111110, 0x55111110, + 0x66222210, 0x66222210, + 0x77333310, 0x77333310, + 0x44004410, 0x44004410, + 0x55115510, 0x55115510, + 0x66226610, 0x66226610, + 0x77337710, 0x77337710, + 0x00008810, 0x00008810, + 0x11119910, 0x11119910, + 0x2222AA10, 0x2222AA10, + 0x3333BB10, 0x3333BB10, + 0x0000CC10, 0x0000CC10, + 0x1111DD10, 0x1111DD10, + 0x2222EE10, 0x2222EE10, + 0x3333FF10, 0x3333FF10, + 0x44008810, 0x44008810, + 0x55119910, 0x55119910, + 0x6622AA10, 0x6622AA10, + 0x7733BB10, 0x7733BB10, + 0x4400CC10, 0x4400CC10, + 0x5511DD10, 0x5511DD10, + 0x6622EE10, 0x6622EE10, + 0x7733FF10, 0x7733FF10, + 0x00440010, 0x00440010, + 0x11551110, 0x11551110, + 0x22662210, 0x22662210, + 0x33773310, 0x33773310, + 0x00444410, 0x00444410, + 0x11555510, 0x11555510, + 0x22666610, 0x22666610, + 0x33777710, 0x33777710, + 0x44440010, 0x44440010, + 0x55551110, 0x55551110, + 0x66662210, 0x66662210, + 0x77773310, 0x77773310, + 0x44444410, 0x44444410, + 0x55555510, 0x55555510, + 0x66666610, 0x66666610, + 0x77777710, 0x77777710, + 0x00448810, 0x00448810, + 0x11559910, 0x11559910, + 0x2266AA10, 0x2266AA10, + 0x3377BB10, 0x3377BB10, + 0x0044CC10, 0x0044CC10, + 0x1155DD10, 0x1155DD10, + 0x2266EE10, 0x2266EE10, + 0x3377FF10, 0x3377FF10, + 0x44448810, 0x44448810, + 0x55559910, 0x55559910, + 0x6666AA10, 0x6666AA10, + 0x7777BB10, 0x7777BB10, + 0x4444CC10, 0x4444CC10, + 0x5555DD10, 0x5555DD10, + 0x6666EE10, 0x6666EE10, + 0x7777FF10, 0x7777FF10, + 0x00880010, 0x00880010, + 0x11991110, 0x11991110, + 0x22AA2210, 0x22AA2210, + 0x33BB3310, 0x33BB3310, + 0x00884410, 0x00884410, + 0x11995510, 0x11995510, + 0x22AA6610, 0x22AA6610, + 0x33BB7710, 0x33BB7710, + 0x44880010, 0x44880010, + 0x55991110, 0x55991110, + 0x66AA2210, 0x66AA2210, + 0x77BB3310, 0x77BB3310, + 0x44884410, 0x44884410, + 0x55995510, 0x55995510, + 0x66AA6610, 0x66AA6610, + 0x77BB7710, 0x77BB7710, + 0x00888810, 0x00888810, + 0x11999910, 0x11999910, + 0x22AAAA10, 0x22AAAA10, + 0x33BBBB10, 0x33BBBB10, + 0x0088CC10, 0x0088CC10, + 0x1199DD10, 0x1199DD10, + 0x22AAEE10, 0x22AAEE10, + 0x33BBFF10, 0x33BBFF10, + 0x44888810, 0x44888810, + 0x55999910, 0x55999910, + 0x66AAAA10, 0x66AAAA10, + 0x77BBBB10, 0x77BBBB10, + 0x4488CC10, 0x4488CC10, + 0x5599DD10, 0x5599DD10, + 0x66AAEE10, 0x66AAEE10, + 0x77BBFF10, 0x77BBFF10, + 0x00CC0010, 0x00CC0010, + 0x11DD1110, 0x11DD1110, + 0x22EE2210, 0x22EE2210, + 0x33FF3310, 0x33FF3310, + 0x00CC4410, 0x00CC4410, + 0x11DD5510, 0x11DD5510, + 0x22EE6610, 0x22EE6610, + 0x33FF7710, 0x33FF7710, + 0x44CC0010, 0x44CC0010, + 0x55DD1110, 0x55DD1110, + 0x66EE2210, 0x66EE2210, + 0x77FF3310, 0x77FF3310, + 0x44CC4410, 0x44CC4410, + 0x55DD5510, 0x55DD5510, + 0x66EE6610, 0x66EE6610, + 0x77FF7710, 0x77FF7710, + 0x00CC8810, 0x00CC8810, + 0x11DD9910, 0x11DD9910, + 0x22EEAA10, 0x22EEAA10, + 0x33FFBB10, 0x33FFBB10, + 0x00CCCC10, 0x00CCCC10, + 0x11DDDD10, 0x11DDDD10, + 0x22EEEE10, 0x22EEEE10, + 0x33FFFF10, 0x33FFFF10, + 0x44CC8810, 0x44CC8810, + 0x55DD9910, 0x55DD9910, + 0x66EEAA10, 0x66EEAA10, + 0x77FFBB10, 0x77FFBB10, + 0x44CCCC10, 0x44CCCC10, + 0x55DDDD10, 0x55DDDD10, + 0x66EEEE10, 0x66EEEE10, + 0x77FFFF10, 0x77FFFF10, + 0x88000010, 0x88000010, + 0x99111110, 0x99111110, + 0xAA222210, 0xAA222210, + 0xBB333310, 0xBB333310, + 0x88004410, 0x88004410, + 0x99115510, 0x99115510, + 0xAA226610, 0xAA226610, + 0xBB337710, 0xBB337710, + 0xCC000010, 0xCC000010, + 0xDD111110, 0xDD111110, + 0xEE222210, 0xEE222210, + 0xFF333310, 0xFF333310, + 0xCC004410, 0xCC004410, + 0xDD115510, 0xDD115510, + 0xEE226610, 0xEE226610, + 0xFF337710, 0xFF337710, + 0x88008810, 0x88008810, + 0x99119910, 0x99119910, + 0xAA22AA10, 0xAA22AA10, + 0xBB33BB10, 0xBB33BB10, + 0x8800CC10, 0x8800CC10, + 0x9911DD10, 0x9911DD10, + 0xAA22EE10, 0xAA22EE10, + 0xBB33FF10, 0xBB33FF10, + 0xCC008810, 0xCC008810, + 0xDD119910, 0xDD119910, + 0xEE22AA10, 0xEE22AA10, + 0xFF33BB10, 0xFF33BB10, + 0xCC00CC10, 0xCC00CC10, + 0xDD11DD10, 0xDD11DD10, + 0xEE22EE10, 0xEE22EE10, + 0xFF33FF10, 0xFF33FF10, + 0x88440010, 0x88440010, + 0x99551110, 0x99551110, + 0xAA662210, 0xAA662210, + 0xBB773310, 0xBB773310, + 0x88444410, 0x88444410, + 0x99555510, 0x99555510, + 0xAA666610, 0xAA666610, + 0xBB777710, 0xBB777710, + 0xCC440010, 0xCC440010, + 0xDD551110, 0xDD551110, + 0xEE662210, 0xEE662210, + 0xFF773310, 0xFF773310, + 0xCC444410, 0xCC444410, + 0xDD555510, 0xDD555510, + 0xEE666610, 0xEE666610, + 0xFF777710, 0xFF777710, + 0x88448810, 0x88448810, + 0x99559910, 0x99559910, + 0xAA66AA10, 0xAA66AA10, + 0xBB77BB10, 0xBB77BB10, + 0x8844CC10, 0x8844CC10, + 0x9955DD10, 0x9955DD10, + 0xAA66EE10, 0xAA66EE10, + 0xBB77FF10, 0xBB77FF10, + 0xCC448810, 0xCC448810, + 0xDD559910, 0xDD559910, + 0xEE66AA10, 0xEE66AA10, + 0xFF77BB10, 0xFF77BB10, + 0xCC44CC10, 0xCC44CC10, + 0xDD55DD10, 0xDD55DD10, + 0xEE66EE10, 0xEE66EE10, + 0xFF77FF10, 0xFF77FF10, + 0x88880010, 0x88880010, + 0x99991110, 0x99991110, + 0xAAAA2210, 0xAAAA2210, + 0xBBBB3310, 0xBBBB3310, + 0x88884410, 0x88884410, + 0x99995510, 0x99995510, + 0xAAAA6610, 0xAAAA6610, + 0xBBBB7710, 0xBBBB7710, + 0xCC880010, 0xCC880010, + 0xDD991110, 0xDD991110, + 0xEEAA2210, 0xEEAA2210, + 0xFFBB3310, 0xFFBB3310, + 0xCC884410, 0xCC884410, + 0xDD995510, 0xDD995510, + 0xEEAA6610, 0xEEAA6610, + 0xFFBB7710, 0xFFBB7710, + 0x88888810, 0x88888810, + 0x99999910, 0x99999910, + 0xAAAAAA10, 0xAAAAAA10, + 0xBBBBBB10, 0xBBBBBB10, + 0x8888CC10, 0x8888CC10, + 0x9999DD10, 0x9999DD10, + 0xAAAAEE10, 0xAAAAEE10, + 0xBBBBFF10, 0xBBBBFF10, + 0xCC888810, 0xCC888810, + 0xDD999910, 0xDD999910, + 0xEEAAAA10, 0xEEAAAA10, + 0xFFBBBB10, 0xFFBBBB10, + 0xCC88CC10, 0xCC88CC10, + 0xDD99DD10, 0xDD99DD10, + 0xEEAAEE10, 0xEEAAEE10, + 0xFFBBFF10, 0xFFBBFF10, + 0x88CC0010, 0x88CC0010, + 0x99DD1110, 0x99DD1110, + 0xAAEE2210, 0xAAEE2210, + 0xBBFF3310, 0xBBFF3310, + 0x88CC4410, 0x88CC4410, + 0x99DD5510, 0x99DD5510, + 0xAAEE6610, 0xAAEE6610, + 0xBBFF7710, 0xBBFF7710, + 0xCCCC0010, 0xCCCC0010, + 0xDDDD1110, 0xDDDD1110, + 0xEEEE2210, 0xEEEE2210, + 0xFFFF3310, 0xFFFF3310, + 0xCCCC4410, 0xCCCC4410, + 0xDDDD5510, 0xDDDD5510, + 0xEEEE6610, 0xEEEE6610, + 0xFFFF7710, 0xFFFF7710, + 0x88CC8810, 0x88CC8810, + 0x99DD9910, 0x99DD9910, + 0xAAEEAA10, 0xAAEEAA10, + 0xBBFFBB10, 0xBBFFBB10, + 0x88CCCC10, 0x88CCCC10, + 0x99DDDD10, 0x99DDDD10, + 0xAAEEEE10, 0xAAEEEE10, + 0xBBFFFF10, 0xBBFFFF10, + 0xCCCC8810, 0xCCCC8810, + 0xDDDD9910, 0xDDDD9910, + 0xEEEEAA10, 0xEEEEAA10, + 0xFFFFBB10, 0xFFFFBB10, + 0xCCCCCC10, 0xCCCCCC10, + 0xDDDDDD10, 0xDDDDDD10, + 0xEEEEEE10, 0xEEEEEE10, + 0xFFFFFF10, 0xFFFFFF10 +}; diff --git a/frontends/riscos/palettes.h b/frontends/riscos/palettes.h new file mode 100644 index 000000000..82fccb467 --- /dev/null +++ b/frontends/riscos/palettes.h @@ -0,0 +1,33 @@ +/* + * Copyright 2006 Adrian Lees <adrianl@users.sourceforge.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Palette definitions for sprites + */ + +#ifndef __NETSURF_RISCOS_PALETTES_H_ +#define __NETSURF_RISCOS_PALETTES_H_ +#include "oslib/os.h" + +extern const os_colour default_palette1[]; +extern const os_colour default_palette2[]; +extern const os_colour wimp_palette[]; +extern const os_colour default_palette8[]; +extern const os_colour captured_palette8[]; + +#endif diff --git a/frontends/riscos/plotters.c b/frontends/riscos/plotters.c new file mode 100644 index 000000000..38fd9d74a --- /dev/null +++ b/frontends/riscos/plotters.c @@ -0,0 +1,525 @@ +/* + * Copyright 2004 James Bursa <bursa@users.sourceforge.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Target independent plotting (RISC OS screen implementation). + */ + +#include <stdbool.h> +#include <math.h> +#include "oslib/colourtrans.h" +#include "oslib/draw.h" +#include "oslib/os.h" + +#include "utils/log.h" +#include "utils/utils.h" +#include "desktop/plotters.h" + +#include "riscos/bitmap.h" +#include "riscos/image.h" +#include "riscos/gui.h" +#include "riscos/font.h" +#include "riscos/oslib_pre7.h" + +static bool ro_plot_rectangle(int x0, int y0, int x1, int y1, const plot_style_t *style); +static bool ro_plot_line(int x0, int y0, int x1, int y1, const plot_style_t *style); +static bool ro_plot_draw_path(const draw_path * const path, int width, + colour c, bool dotted, bool dashed); +static bool ro_plot_polygon(const int *p, unsigned int n, const plot_style_t *style); +static bool ro_plot_path(const float *p, unsigned int n, colour fill, float width, + colour c, const float transform[6]); +static bool ro_plot_clip(const struct rect *clip); +static bool ro_plot_text(int x, int y, const char *text, size_t length, + const plot_font_style_t *fstyle); +static bool ro_plot_disc(int x, int y, int radius, const plot_style_t *style); +static bool ro_plot_arc(int x, int y, int radius, int angle1, int angle2, + const plot_style_t *style); +static bool ro_plot_bitmap(int x, int y, int width, int height, + struct bitmap *bitmap, colour bg, + bitmap_flags_t flags); + + +struct plotter_table plot; + +const struct plotter_table ro_plotters = { + .rectangle = ro_plot_rectangle, + .line = ro_plot_line, + .polygon = ro_plot_polygon, + .clip = ro_plot_clip, + .text = ro_plot_text, + .disc = ro_plot_disc, + .arc = ro_plot_arc, + .bitmap = ro_plot_bitmap, + .path = ro_plot_path, + .option_knockout = true, +}; + +int ro_plot_origin_x = 0; +int ro_plot_origin_y = 0; + +/** One version of the A9home OS is incapable of drawing patterned lines */ +bool ro_plot_patterned_lines = true; + + + +bool ro_plot_rectangle(int x0, int y0, int x1, int y1, const plot_style_t *style) +{ + if (style->fill_type != PLOT_OP_TYPE_NONE) { + os_error *error; + error = xcolourtrans_set_gcol(style->fill_colour << 8, + colourtrans_USE_ECFS_GCOL, + os_ACTION_OVERWRITE, 0, 0); + if (error) { + LOG("xcolourtrans_set_gcol: 0x%x: %s", error->errnum, error->errmess); + return false; + } + + error = xos_plot(os_MOVE_TO, + ro_plot_origin_x + x0 * 2, + ro_plot_origin_y - y0 * 2 - 1); + if (error) { + LOG("xos_plot: 0x%x: %s", error->errnum, error->errmess); + return false; + } + + error = xos_plot(os_PLOT_RECTANGLE | os_PLOT_TO, + ro_plot_origin_x + x1 * 2 - 1, + ro_plot_origin_y - y1 * 2); + if (error) { + LOG("xos_plot: 0x%x: %s", error->errnum, error->errmess); + return false; + } + } + + if (style->stroke_type != PLOT_OP_TYPE_NONE) { + bool dotted = false; + bool dashed = false; + + const int path[] = { draw_MOVE_TO, + (ro_plot_origin_x + x0 * 2) * 256, + (ro_plot_origin_y - y0 * 2 - 1) * 256, + draw_LINE_TO, + (ro_plot_origin_x + (x1) * 2) * 256, + (ro_plot_origin_y - y0 * 2 - 1) * 256, + draw_LINE_TO, + (ro_plot_origin_x + (x1) * 2) * 256, + (ro_plot_origin_y - (y1) * 2 - 1) * 256, + draw_LINE_TO, + (ro_plot_origin_x + x0 * 2) * 256, + (ro_plot_origin_y - (y1) * 2 - 1) * 256, + draw_CLOSE_LINE, + (ro_plot_origin_x + x0 * 2) * 256, + (ro_plot_origin_y - y0 * 2 - 1) * 256, + draw_END_PATH }; + + if (style->stroke_type == PLOT_OP_TYPE_DOT) + dotted = true; + + if (style->stroke_type == PLOT_OP_TYPE_DASH) + dashed = true; + + ro_plot_draw_path((const draw_path *)path, + style->stroke_width, + style->stroke_colour, + dotted, dashed); + } + + return true; +} + + +bool ro_plot_line(int x0, int y0, int x1, int y1, const plot_style_t *style) +{ + if (style->stroke_type != PLOT_OP_TYPE_NONE) { + const int path[] = { draw_MOVE_TO, + (ro_plot_origin_x + x0 * 2) * 256, + (ro_plot_origin_y - y0 * 2 - 1) * 256, + draw_LINE_TO, + (ro_plot_origin_x + x1 * 2) * 256, + (ro_plot_origin_y - y1 * 2 - 1) * 256, + draw_END_PATH }; + bool dotted = false; + bool dashed = false; + + if (style->stroke_type == PLOT_OP_TYPE_DOT) + dotted = true; + + if (style->stroke_type == PLOT_OP_TYPE_DASH) + dashed = true; + + return ro_plot_draw_path((const draw_path *)path, + style->stroke_width, + style->stroke_colour, + dotted, dashed); + } + return true; +} + + +bool ro_plot_draw_path(const draw_path * const path, int width, + colour c, bool dotted, bool dashed) +{ + static const draw_line_style line_style = { draw_JOIN_MITRED, + draw_CAP_BUTT, draw_CAP_BUTT, 0, 0x7fffffff, + 0, 0, 0, 0 }; + draw_dash_pattern dash = { 0, 1, { 512 } }; + const draw_dash_pattern *dash_pattern = 0; + os_error *error; + + if (width < 1) + width = 1; + + if (ro_plot_patterned_lines) { + if (dotted) { + dash.elements[0] = 512 * width; + dash_pattern = ‐ + } else if (dashed) { + dash.elements[0] = 1536 * width; + dash_pattern = ‐ + } + } + + error = xcolourtrans_set_gcol(c << 8, 0, os_ACTION_OVERWRITE, 0, 0); + if (error) { + LOG("xcolourtrans_set_gcol: 0x%x: %s", error->errnum, error->errmess); + return false; + } + + error = xdraw_stroke(path, 0, 0, 0, width * 2 * 256, + &line_style, dash_pattern); + if (error) { + LOG("xdraw_stroke: 0x%x: %s", error->errnum, error->errmess); + return false; + } + + return true; +} + + +bool ro_plot_polygon(const int *p, unsigned int n, const plot_style_t *style) +{ + int path[n * 3 + 2]; + unsigned int i; + os_error *error; + + for (i = 0; i != n; i++) { + path[i * 3 + 0] = draw_LINE_TO; + path[i * 3 + 1] = (ro_plot_origin_x + p[i * 2 + 0] * 2) * 256; + path[i * 3 + 2] = (ro_plot_origin_y - p[i * 2 + 1] * 2) * 256; + } + path[0] = draw_MOVE_TO; + path[n * 3] = draw_END_PATH; + path[n * 3 + 1] = 0; + + error = xcolourtrans_set_gcol(style->fill_colour << 8, 0, os_ACTION_OVERWRITE, 0, 0); + if (error) { + LOG("xcolourtrans_set_gcol: 0x%x: %s", error->errnum, error->errmess); + return false; + } + error = xdraw_fill((draw_path *) path, 0, 0, 0); + if (error) { + LOG("xdraw_fill: 0x%x: %s", error->errnum, error->errmess); + return false; + } + + return true; +} + + +bool ro_plot_path(const float *p, unsigned int n, colour fill, float width, + colour c, const float transform[6]) +{ + static const draw_line_style line_style = { draw_JOIN_MITRED, + draw_CAP_BUTT, draw_CAP_BUTT, 0, 0x7fffffff, + 0, 0, 0, 0 }; + int *path = 0; + unsigned int i; + os_trfm trfm; + os_error *error; + + if (n == 0) + return true; + + if (p[0] != PLOTTER_PATH_MOVE) { + LOG("path doesn't start with a move"); + goto error; + } + + path = malloc(sizeof *path * (n + 10)); + if (!path) { + LOG("out of memory"); + goto error; + } + + for (i = 0; i < n; ) { + if (p[i] == PLOTTER_PATH_MOVE) { + path[i] = draw_MOVE_TO; + path[i + 1] = p[i + 1] * 2 * 256; + path[i + 2] = -p[i + 2] * 2 * 256; + i += 3; + } else if (p[i] == PLOTTER_PATH_CLOSE) { + path[i] = draw_CLOSE_LINE; + i++; + } else if (p[i] == PLOTTER_PATH_LINE) { + path[i] = draw_LINE_TO; + path[i + 1] = p[i + 1] * 2 * 256; + path[i + 2] = -p[i + 2] * 2 * 256; + i += 3; + } else if (p[i] == PLOTTER_PATH_BEZIER) { + path[i] = draw_BEZIER_TO; + path[i + 1] = p[i + 1] * 2 * 256; + path[i + 2] = -p[i + 2] * 2 * 256; + path[i + 3] = p[i + 3] * 2 * 256; + path[i + 4] = -p[i + 4] * 2 * 256; + path[i + 5] = p[i + 5] * 2 * 256; + path[i + 6] = -p[i + 6] * 2 * 256; + i += 7; + } else { + LOG("bad path command %f", p[i]); + goto error; + } + } + path[i] = draw_END_PATH; + path[i + 1] = 0; + + trfm.entries[0][0] = transform[0] * 0x10000; + trfm.entries[0][1] = transform[1] * 0x10000; + trfm.entries[1][0] = transform[2] * 0x10000; + trfm.entries[1][1] = transform[3] * 0x10000; + trfm.entries[2][0] = (ro_plot_origin_x + transform[4] * 2) * 256; + trfm.entries[2][1] = (ro_plot_origin_y - transform[5] * 2) * 256; + + if (fill != NS_TRANSPARENT) { + error = xcolourtrans_set_gcol(fill << 8, 0, + os_ACTION_OVERWRITE, 0, 0); + if (error) { + LOG("xcolourtrans_set_gcol: 0x%x: %s", error->errnum, error->errmess); + goto error; + } + + error = xdraw_fill((draw_path *) path, 0, &trfm, 0); + if (error) { + LOG("xdraw_stroke: 0x%x: %s", error->errnum, error->errmess); + goto error; + } + } + + if (c != NS_TRANSPARENT) { + error = xcolourtrans_set_gcol(c << 8, 0, + os_ACTION_OVERWRITE, 0, 0); + if (error) { + LOG("xcolourtrans_set_gcol: 0x%x: %s", error->errnum, error->errmess); + goto error; + } + + error = xdraw_stroke((draw_path *) path, 0, &trfm, 0, + width * 2 * 256, &line_style, 0); + if (error) { + LOG("xdraw_stroke: 0x%x: %s", error->errnum, error->errmess); + goto error; + } + } + + free(path); + return true; + +error: + free(path); + return false; +} + + + + +bool ro_plot_clip(const struct rect *clip) +{ + os_error *error; + char buf[12]; + + int clip_x0 = ro_plot_origin_x + clip->x0 * 2; + int clip_y0 = ro_plot_origin_y - clip->y0 * 2 - 1; + int clip_x1 = ro_plot_origin_x + clip->x1 * 2 - 1; + int clip_y1 = ro_plot_origin_y - clip->y1 * 2; + + if (clip_x1 < clip_x0 || clip_y0 < clip_y1) { + LOG("bad clip rectangle %i %i %i %i", clip_x0, clip_y0, clip_x1, clip_y1); + return false; + } + + buf[0] = os_VDU_SET_GRAPHICS_WINDOW; + buf[1] = clip_x0; + buf[2] = clip_x0 >> 8; + buf[3] = clip_y1; + buf[4] = clip_y1 >> 8; + buf[5] = clip_x1; + buf[6] = clip_x1 >> 8; + buf[7] = clip_y0; + buf[8] = clip_y0 >> 8; + + error = xos_writen(buf, 9); + if (error) { + LOG("xos_writen: 0x%x: %s", error->errnum, error->errmess); + return false; + } + + return true; +} + + +bool ro_plot_text(int x, int y, const char *text, size_t length, + const plot_font_style_t *fstyle) +{ + os_error *error; + + error = xcolourtrans_set_font_colours(font_CURRENT, + fstyle->background << 8, fstyle->foreground << 8, + 14, 0, 0, 0); + if (error) { + LOG("xcolourtrans_set_font_colours: 0x%x: %s", error->errnum, error->errmess); + return false; + } + + return nsfont_paint(fstyle, text, length, + ro_plot_origin_x + x * 2, + ro_plot_origin_y - y * 2); +} + + +bool ro_plot_disc(int x, int y, int radius, const plot_style_t *style) +{ + os_error *error; + if (style->fill_type != PLOT_OP_TYPE_NONE) { + error = xcolourtrans_set_gcol(style->fill_colour << 8, 0, + os_ACTION_OVERWRITE, 0, 0); + if (error) { + LOG("xcolourtrans_set_gcol: 0x%x: %s", error->errnum, error->errmess); + return false; + } + error = xos_plot(os_MOVE_TO, + ro_plot_origin_x + x * 2, + ro_plot_origin_y - y * 2); + if (error) { + LOG("xos_plot: 0x%x: %s", error->errnum, error->errmess); + return false; + } + error = xos_plot(os_PLOT_CIRCLE | os_PLOT_BY, radius * 2, 0); + if (error) { + LOG("xos_plot: 0x%x: %s", error->errnum, error->errmess); + return false; + } + } + + if (style->stroke_type != PLOT_OP_TYPE_NONE) { + + error = xcolourtrans_set_gcol(style->stroke_colour << 8, 0, + os_ACTION_OVERWRITE, 0, 0); + if (error) { + LOG("xcolourtrans_set_gcol: 0x%x: %s", error->errnum, error->errmess); + return false; + } + error = xos_plot(os_MOVE_TO, + ro_plot_origin_x + x * 2, + ro_plot_origin_y - y * 2); + if (error) { + LOG("xos_plot: 0x%x: %s", error->errnum, error->errmess); + return false; + } + error = xos_plot(os_PLOT_CIRCLE_OUTLINE | os_PLOT_BY, + radius * 2, 0); + + if (error) { + LOG("xos_plot: 0x%x: %s", error->errnum, error->errmess); + return false; + } + } + return true; +} + +bool ro_plot_arc(int x, int y, int radius, int angle1, int angle2, const plot_style_t *style) +{ + os_error *error; + int sx, sy, ex, ey; + double t; + + x = ro_plot_origin_x + x * 2; + y = ro_plot_origin_y - y * 2; + radius <<= 1; + + error = xcolourtrans_set_gcol(style->fill_colour << 8, 0, + os_ACTION_OVERWRITE, 0, 0); + + if (error) { + LOG("xcolourtrans_set_gcol: 0x%x: %s", error->errnum, error->errmess); + return false; + } + + t = ((double)angle1 * M_PI) / 180.0; + sx = (x + (int)(radius * cos(t))); + sy = (y + (int)(radius * sin(t))); + + t = ((double)angle2 * M_PI) / 180.0; + ex = (x + (int)(radius * cos(t))); + ey = (y + (int)(radius * sin(t))); + + error = xos_plot(os_MOVE_TO, x, y); /* move to centre */ + if (error) { + LOG("xos_plot: 0x%x: %s", error->errnum, error->errmess); + return false; + } + + error = xos_plot(os_MOVE_TO, sx, sy); /* move to start */ + if (error) { + LOG("xos_plot: 0x%x: %s", error->errnum, error->errmess); + return false; + } + + error = xos_plot(os_PLOT_ARC | os_PLOT_TO, ex, ey); /* arc to end */ + if (error) { + LOG("xos_plot: 0x%x: %s", error->errnum, error->errmess); + return false; + } + + return true; +} + + + +bool ro_plot_bitmap(int x, int y, int width, int height, + struct bitmap *bitmap, colour bg, + bitmap_flags_t flags) +{ + const uint8_t *buffer; + + buffer = riscos_bitmap_get_buffer(bitmap); + if (!buffer) { + LOG("bitmap_get_buffer failed"); + return false; + } + + return image_redraw(bitmap->sprite_area, + ro_plot_origin_x + x * 2, + ro_plot_origin_y - y * 2, + width, height, + bitmap->width, + bitmap->height, + bg, + flags & BITMAPF_REPEAT_X, flags & BITMAPF_REPEAT_Y, + flags & BITMAPF_REPEAT_X || flags & BITMAPF_REPEAT_Y, + riscos_bitmap_get_opaque(bitmap) ? IMAGE_PLOT_TINCT_OPAQUE : + IMAGE_PLOT_TINCT_ALPHA); +} diff --git a/frontends/riscos/print.c b/frontends/riscos/print.c new file mode 100644 index 000000000..95730d6be --- /dev/null +++ b/frontends/riscos/print.c @@ -0,0 +1,976 @@ +/* + * Copyright 2004 John M Bell <jmb202@ecs.soton.ac.uk> + * Copyright 2006 James Bursa <bursa@users.sourceforge.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "utils/config.h" + +#include <assert.h> +#include <string.h> +#include <swis.h> +#include <oslib/font.h> +#include <oslib/hourglass.h> +#include <oslib/osfile.h> +#include <oslib/osfind.h> +#include <oslib/pdriver.h> +#include <oslib/wimp.h> +#include <rufl.h> +#include <limits.h> + +#include "utils/config.h" +#include "utils/log.h" +#include "utils/messages.h" +#include "utils/utils.h" +#include "utils/nsoption.h" +#include "content/content.h" +#include "content/hlcache.h" +#include "desktop/browser.h" +#include "desktop/plotters.h" + +#include "riscos/gui.h" +#include "riscos/dialog.h" +#include "riscos/menus.h" +#include "riscos/print.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" +#include "riscos/filetype.h" +#include "riscos/font.h" + + +#define ICON_PRINT_TO_BOTTOM 1 +#define ICON_PRINT_SHEETS 2 +#define ICON_PRINT_SHEETS_VALUE 3 +#define ICON_PRINT_SHEETS_DOWN 4 +#define ICON_PRINT_SHEETS_UP 5 +#define ICON_PRINT_SHEETS_TEXT 6 +#define ICON_PRINT_FG_IMAGES 7 +#define ICON_PRINT_BG_IMAGES 8 +#define ICON_PRINT_IN_BACKGROUND 9 +#define ICON_PRINT_UPRIGHT 10 +#define ICON_PRINT_SIDEWAYS 11 +#define ICON_PRINT_COPIES 12 +#define ICON_PRINT_COPIES_DOWN 13 +#define ICON_PRINT_COPIES_UP 14 +#define ICON_PRINT_CANCEL 15 +#define ICON_PRINT_PRINT 16 +#define ICON_PRINT_TEXT_BLACK 20 + + +/** \todo landscape format pages + * \todo be somewhat more intelligent and try not to crop pages + * half way up a line of text + * \todo make use of print stylesheets + */ + +struct gui_window *ro_print_current_window = NULL; +bool print_text_black = false; +bool print_active = false; + +/* 1 millipoint == 1/400 OS unit == 1/800 browser units */ + +static int print_prev_message = 0; +static bool print_in_background = false; +static float print_scale = 1.0; +static int print_num_copies = 1; +static bool print_bg_images = false; +static int print_max_sheets = -1; +static bool print_sideways = false; +/** List of fonts in current print. */ +static char **print_fonts_list = 0; +/** Number of entries in print_fonts_list. */ +static unsigned int print_fonts_count; +/** Error in print_fonts_plot_text() or print_fonts_callback(). */ +static const char *print_fonts_error; + +void gui_window_redraw_window(struct gui_window *g); + +static bool ro_gui_print_click(wimp_pointer *pointer); +static bool ro_gui_print_apply(wimp_w w); +static void print_update_sheets_shaded_state(bool on); +static void print_send_printsave(hlcache_handle *h); +static bool print_send_printtypeknown(wimp_message *m); +static bool print_document(struct gui_window *g, const char *filename); +static const char *print_declare_fonts(hlcache_handle *h); +static bool print_fonts_plot_rectangle(int x0, int y0, int x1, int y1, const plot_style_t *style); +static bool print_fonts_plot_line(int x0, int y0, int x1, int y1, const plot_style_t *style); +static bool print_fonts_plot_polygon(const int *p, unsigned int n, const plot_style_t *style); +static bool print_fonts_plot_clip(const struct rect *clip); +static bool print_fonts_plot_text(int x, int y, const char *text, size_t length, + const plot_font_style_t *fstyle); +static bool print_fonts_plot_disc(int x, int y, int radius, const plot_style_t *style); +static bool print_fonts_plot_arc(int x, int y, int radius, int angle1, int angle2, const plot_style_t *style); +static bool print_fonts_plot_bitmap(int x, int y, int width, int height, + struct bitmap *bitmap, colour bg, + bitmap_flags_t flags); +static bool print_fonts_plot_path(const float *p, unsigned int n, colour fill, float width, + colour c, const float transform[6]); +static void print_fonts_callback(void *context, + const char *font_name, unsigned int font_size, + const char *s8, unsigned short *s16, unsigned int n, + int x, int y); + + +/** Plotter for print_declare_fonts(). All the functions do nothing except for + * print_fonts_plot_text, which records the fonts used. */ +static const struct plotter_table print_fonts_plotters = { + .rectangle = print_fonts_plot_rectangle, + .line = print_fonts_plot_line, + .polygon = print_fonts_plot_polygon, + .clip = print_fonts_plot_clip, + .text = print_fonts_plot_text, + .disc = print_fonts_plot_disc, + .arc = print_fonts_plot_arc, + .bitmap = print_fonts_plot_bitmap, + .path = print_fonts_plot_path, + .option_knockout = false, +}; + + +/** + * Initialise the print dialog. + */ + +void ro_gui_print_init(void) +{ + wimp_i radio_print_type[] = {ICON_PRINT_TO_BOTTOM, ICON_PRINT_SHEETS, + -1}; + wimp_i radio_print_orientation[] = {ICON_PRINT_UPRIGHT, + ICON_PRINT_SIDEWAYS, -1}; + + dialog_print = ro_gui_dialog_create("print"); + ro_gui_wimp_event_register_radio(dialog_print, radio_print_type); + ro_gui_wimp_event_register_radio(dialog_print, radio_print_orientation); + ro_gui_wimp_event_register_checkbox(dialog_print, ICON_PRINT_FG_IMAGES); + ro_gui_wimp_event_register_checkbox(dialog_print, ICON_PRINT_BG_IMAGES); + ro_gui_wimp_event_register_checkbox(dialog_print, + ICON_PRINT_IN_BACKGROUND); + ro_gui_wimp_event_register_checkbox(dialog_print, + ICON_PRINT_TEXT_BLACK); + ro_gui_wimp_event_register_text_field(dialog_print, + ICON_PRINT_SHEETS_TEXT); + ro_gui_wimp_event_register_numeric_field(dialog_print, + ICON_PRINT_COPIES, ICON_PRINT_COPIES_UP, + ICON_PRINT_COPIES_DOWN, 1, 99, 1, 0); + ro_gui_wimp_event_register_numeric_field(dialog_print, + ICON_PRINT_SHEETS_VALUE, ICON_PRINT_SHEETS_UP, + ICON_PRINT_SHEETS_DOWN, 1, 99, 1, 0); + ro_gui_wimp_event_register_cancel(dialog_print, ICON_PRINT_CANCEL); + ro_gui_wimp_event_register_mouse_click(dialog_print, + ro_gui_print_click); + ro_gui_wimp_event_register_ok(dialog_print, ICON_PRINT_PRINT, + ro_gui_print_apply); + ro_gui_wimp_event_set_help_prefix(dialog_print, "HelpPrint"); +} + + +/** + * Prepares all aspects of the print dialog prior to opening. + * + * \param g parent window + */ + +void ro_gui_print_prepare(struct gui_window *g) +{ + char *desc; + bool printers_exists = true; + os_error *error; + + assert(g); + + ro_print_current_window = g; + print_prev_message = 0; + + /* Read Printer Driver name */ + error = xpdriver_info(0, 0, 0, 0, &desc, 0, 0, 0); + if (error) { + LOG("xpdriver_info: 0x%x: %s", error->errnum, error->errmess); + printers_exists = false; + } + + ro_gui_set_icon_selected_state(dialog_print, ICON_PRINT_TO_BOTTOM, + true); + + ro_gui_set_icon_selected_state(dialog_print, ICON_PRINT_SHEETS, false); + ro_gui_set_icon_integer(dialog_print, ICON_PRINT_SHEETS_VALUE, 1); + print_update_sheets_shaded_state(true); + + ro_gui_set_icon_selected_state(dialog_print, ICON_PRINT_FG_IMAGES, + true); + ro_gui_set_icon_shaded_state(dialog_print, ICON_PRINT_FG_IMAGES, true); + + ro_gui_set_icon_selected_state(dialog_print, ICON_PRINT_BG_IMAGES, + print_bg_images); + + ro_gui_set_icon_selected_state(dialog_print, ICON_PRINT_IN_BACKGROUND, + false); + + ro_gui_set_icon_selected_state(dialog_print, ICON_PRINT_UPRIGHT, true); + ro_gui_set_icon_selected_state(dialog_print, ICON_PRINT_SIDEWAYS, + false); + + ro_gui_set_icon_selected_state(dialog_print, ICON_PRINT_TEXT_BLACK, + false); + + ro_gui_set_icon_integer(dialog_print, ICON_PRINT_COPIES, 1); + + ro_gui_set_icon_shaded_state(dialog_print, ICON_PRINT_PRINT, + !printers_exists); + if (printers_exists) + ro_gui_set_window_title(dialog_print, desc); + + ro_gui_wimp_event_memorise(dialog_print); +} + + +/** + * Handle mouse clicks in print dialog + * + * \param pointer wimp_pointer block + */ + +bool ro_gui_print_click(wimp_pointer *pointer) +{ + if (pointer->buttons == wimp_CLICK_MENU) + return true; + + switch (pointer->i) { + case ICON_PRINT_TO_BOTTOM: + case ICON_PRINT_SHEETS: + print_update_sheets_shaded_state(pointer->i != + ICON_PRINT_SHEETS); + break; + } + return false; +} + + +/** + * Handle click on the Print button in the print dialog. + */ + +bool ro_gui_print_apply(wimp_w w) +{ + int copies = atoi(ro_gui_get_icon_string(dialog_print, + ICON_PRINT_COPIES)); + int sheets = atoi(ro_gui_get_icon_string(dialog_print, + ICON_PRINT_SHEETS_VALUE)); + + print_in_background = ro_gui_get_icon_selected_state(dialog_print, + ICON_PRINT_IN_BACKGROUND); + print_text_black = ro_gui_get_icon_selected_state(dialog_print, + ICON_PRINT_TEXT_BLACK); + print_sideways = ro_gui_get_icon_selected_state(dialog_print, + ICON_PRINT_SIDEWAYS); + print_num_copies = copies; + if (ro_gui_get_icon_selected_state(dialog_print, ICON_PRINT_SHEETS)) + print_max_sheets = sheets; + else + print_max_sheets = -1; + print_bg_images = ro_gui_get_icon_selected_state(dialog_print, + ICON_PRINT_BG_IMAGES); + + print_send_printsave(browser_window_get_content( + ro_print_current_window->bw)); + + return true; +} + + +/** + * Set shaded state of sheets + * + * \param on whether to turn shading on or off + */ + +void print_update_sheets_shaded_state(bool on) +{ + ro_gui_set_icon_shaded_state(dialog_print, ICON_PRINT_SHEETS_VALUE, on); + ro_gui_set_icon_shaded_state(dialog_print, ICON_PRINT_SHEETS_DOWN, on); + ro_gui_set_icon_shaded_state(dialog_print, ICON_PRINT_SHEETS_UP, on); + ro_gui_set_icon_shaded_state(dialog_print, ICON_PRINT_SHEETS_TEXT, on); + ro_gui_set_caret_first(dialog_print); +} + + +/** + * Send a message_PRINT_SAVE + * + * \param h handle to content to print. + */ + +void print_send_printsave(hlcache_handle *h) +{ + wimp_full_message_data_xfer m; + os_error *e; + int len; + + len = strlen(content_get_title(h)) + 1; + if (212 < len) + len = 212; + + m.size = ((44+len+3) & ~3); + m.your_ref = 0; + m.action = message_PRINT_SAVE; + m.w = (wimp_w)0; + m.i = m.pos.x = m.pos.y = 0; + m.est_size = 1024; /* arbitrary value - it really doesn't matter */ + m.file_type = ro_content_filetype(h); + strncpy(m.file_name, content_get_title(h), 211); + m.file_name[211] = 0; + e = xwimp_send_message(wimp_USER_MESSAGE_RECORDED, + (wimp_message *)&m, 0); + if (e) { + LOG("xwimp_send_message: 0x%x: %s", e->errnum, e->errmess); + ro_warn_user("WimpError", e->errmess); + ro_print_cleanup(); + } + print_prev_message = m.my_ref; +} + + +/** + * Send a message_PRINT_TYPE_KNOWN + * + * \param m message to reply to + * \return true on success, false otherwise + */ + +bool print_send_printtypeknown(wimp_message *m) +{ + os_error *e; + + m->size = 20; + m->your_ref = m->my_ref; + m->action = message_PRINT_TYPE_KNOWN; + e = xwimp_send_message(wimp_USER_MESSAGE, m, m->sender); + if (e) { + LOG("xwimp_send_message: 0x%x: %s", e->errnum, e->errmess); + ro_warn_user("WimpError", e->errmess); + return false; + } + + return true; +} + + +/** + * Handle a bounced message_PRINT_SAVE + * + * \param m the bounced message + */ + +void ro_print_save_bounce(wimp_message *m) +{ + if (m->my_ref == 0 || m->my_ref != print_prev_message) + return; + + /* try to print anyway (we're graphics printing) */ + if (ro_print_current_window) { + print_document(ro_print_current_window, "printer:"); + } + ro_print_cleanup(); +} + + +/** + * Handle message_PRINT_ERROR + * + * \param m the message containing the error + */ + +void ro_print_error(wimp_message *m) +{ + pdriver_message_print_error *p = (pdriver_message_print_error*)&m->data; + if (m->your_ref == 0 || m->your_ref != print_prev_message) + return; + + if (m->size == 20) + ro_warn_user("PrintErrorRO2", 0); + else + ro_warn_user("PrintError", p->errmess); + + ro_print_cleanup(); +} + + +/** + * Handle message_PRINT_TYPE_ODD + * + * \param m the message to handle + */ + +void ro_print_type_odd(wimp_message *m) +{ + if ((m->your_ref == 0 || m->your_ref == print_prev_message) && + !print_in_background) { + /* reply to a previous message (ie printsave) */ + if (ro_print_current_window && print_send_printtypeknown(m)) { + print_document(ro_print_current_window, "printer:"); + } + ro_print_cleanup(); + } + else { + /* broadcast message */ + /* no need to do anything */ + } + +} + + +/** + * Handle message_DATASAVE_ACK for the printing protocol. + * + * \param m the message to handle + * \return true if message successfully handled, false otherwise + * + * We cheat here and, instead of giving Printers what it asked for (a copy of + * the file so it can poke us later via a broadcast of PrintTypeOdd), we give + * it a file that it can print itself without having to bother us further. For + * PostScript printers (type 0) we give it a PostScript file. Otherwise, we give + * it a PrintOut file. + * + * This method has a couple of advantages: + * - we can reuse this code for background printing (we simply ignore the + * PrintTypeOdd reply) + * - there's no need to ensure all components of a page queued to be printed + * still exist when it reaches the top of the queue. (which reduces complexity + * a fair bit) + */ + +bool ro_print_ack(wimp_message *m) +{ + pdriver_info_type info_type; + pdriver_type type; + os_error *error; + + if (m->your_ref == 0 || m->your_ref != print_prev_message || + !ro_print_current_window) + return false; + + /* read printer driver type */ + error = xpdriver_info(&info_type, 0, 0, 0, 0, 0, 0, 0); + if (error) { + LOG("xpdriver_info: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("PrintError", error->errmess); + ro_print_cleanup(); + return true; + } + type = info_type >> 16; + + /* print to file */ + if (!print_document(ro_print_current_window, + m->data.data_xfer.file_name)) { + ro_print_cleanup(); + return true; + } + + /* send dataload */ + m->your_ref = m->my_ref; + m->action = message_DATA_LOAD; + + if (type == pdriver_TYPE_PS) + m->data.data_xfer.file_type = osfile_TYPE_POSTSCRIPT; + else + m->data.data_xfer.file_type = osfile_TYPE_PRINTOUT; + + error = xwimp_send_message(wimp_USER_MESSAGE_RECORDED, m, m->sender); + if (error) { + LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + /* and delete temporary file */ + xosfile_delete(m->data.data_xfer.file_name, + 0, 0, 0, 0, 0); + } + print_prev_message = m->my_ref; + + ro_print_cleanup(); + return true; +} + + +/** + * Handle a bounced dataload message + * + * \param m the message to handle + */ + +void ro_print_dataload_bounce(wimp_message *m) +{ + if (m->your_ref == 0 || m->your_ref != print_prev_message) + return; + + xosfile_delete(m->data.data_xfer.file_name, 0, 0, 0, 0, 0); + ro_print_cleanup(); +} + + +/** + * Cleanup after printing + */ + +void ro_print_cleanup(void) +{ + ro_print_current_window = NULL; + print_text_black = false; + print_prev_message = 0; + print_max_sheets = -1; + ro_gui_menu_destroy(); + ro_gui_dialog_close(dialog_print); +} + + +/** + * Print a document. + * + * \param g gui_window containing the document to print + * \param filename name of file to print to + * \return true on success, false on error and error reported + */ + +bool print_document(struct gui_window *g, const char *filename) +{ + int left, right, top, bottom, width, height; + int saved_width, saved_height; + int yscroll = 0, sheets = print_max_sheets; + hlcache_handle *h = browser_window_get_content(g->bw); + const char *error_message; + pdriver_features features; + os_fw fhandle, old_job = 0; + os_error *error; + + /* no point printing a blank page */ + if (!h) { + ro_warn_user("PrintError", "nothing to print"); + return false; + } + + /* read printer driver features */ + error = xpdriver_info(0, 0, 0, &features, 0, 0, 0, 0); + if (error) { + LOG("xpdriver_info: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("PrintError", error->errmess); + return false; + } + + /* read page size */ + error = xpdriver_page_size(0, 0, &left, &bottom, &right, &top); + if (error) { + LOG("xpdriver_page_size: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("PrintError", error->errmess); + return false; + } + + if (print_sideways) { + width = (top - bottom) / 800; + height = (right - left) / 800; + } else { + width = (right - left) / 800; + height = (top - bottom) / 800; + } + + /* layout the document to the correct width */ + saved_width = content_get_width(h); + saved_height = content_get_height(h); + if (content_get_type(h) == CONTENT_HTML) + content_reformat(h, false, width, height); + + /* open printer file */ + error = xosfind_openoutw(osfind_NO_PATH | osfind_ERROR_IF_DIR | + osfind_ERROR_IF_ABSENT, filename, 0, &fhandle); + if (error) { + LOG("xosfind_openoutw: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("PrintError", error->errmess); + return false; + } + + /* select print job */ + error = xpdriver_select_jobw(fhandle, "NetSurf", &old_job); + if (error) { + LOG("xpdriver_select_jobw: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("PrintError", error->errmess); + xosfind_closew(fhandle); + return false; + } + + rufl_invalidate_cache(); + + /* declare fonts, if necessary */ + if (features & pdriver_FEATURE_DECLARE_FONT) { + if ((error_message = print_declare_fonts(h))) + goto error; + } + + ro_gui_current_redraw_gui = g; + + /* print is now active */ + print_active = true; + + do { + struct rect clip; + os_box b; + os_hom_trfm t; + os_coord p; + osbool more; + + if (print_sideways) { + b.x0 = bottom / 400 -2; + b.y0 = left / 400 - 2; + b.x1 = top / 400 + 2; + b.y1 = right / 400 + 2; + t.entries[0][0] = 0; + t.entries[0][1] = 65536; + t.entries[1][0] = -65536; + t.entries[1][1] = 0; + p.x = right; + p.y = bottom; + ro_plot_origin_x = bottom / 400; + ro_plot_origin_y = right / 400 + yscroll * 2; + } else { + b.x0 = left / 400 -2; + b.y0 = bottom / 400 - 2; + b.x1 = right / 400 + 2; + b.y1 = top / 400 + 2; + t.entries[0][0] = 65536; + t.entries[0][1] = 0; + t.entries[1][0] = 0; + t.entries[1][1] = 65536; + p.x = left; + p.y = bottom; + ro_plot_origin_x = left / 400; + ro_plot_origin_y = top / 400 + yscroll * 2; + } + + xhourglass_percentage((int) (yscroll * 100 / + content_get_height(h))); + + /* give page rectangle */ + error = xpdriver_give_rectangle(0, &b, &t, &p, os_COLOUR_WHITE); + if (error) { + LOG("xpdriver_give_rectangle: 0x%x: %s", error->errnum, error->errmess); + error_message = error->errmess; + goto error; + } + + LOG("given rectangle: [(%d, %d), (%d, %d)]", b.x0, b.y0, b.x1, b.y1); + + /* and redraw the document */ + error = xpdriver_draw_page(print_num_copies, &b, 0, 0, + &more, 0); + if (error) { + LOG("xpdriver_draw_page: 0x%x: %s", error->errnum, error->errmess); + error_message = error->errmess; + goto error; + } + + while (more) { + struct content_redraw_data data; + /* TODO: turn knockout off for print */ + struct redraw_context ctx = { + .interactive = false, + .background_images = print_bg_images, + .plot = &ro_plotters + }; + + LOG("redrawing area: [(%d, %d), (%d, %d)]", b.x0, b.y0, b.x1, b.y1); + clip.x0 = (b.x0 - ro_plot_origin_x) / 2; + clip.y0 = (ro_plot_origin_y - b.y1) / 2; + clip.x1 = (b.x1 - ro_plot_origin_x) / 2; + clip.y1 = (ro_plot_origin_y - b.y0) / 2; + + data.x = 0; + data.y = 0; + data.width = content_get_width(h); + data.height = content_get_height(h); + data.background_colour = 0xFFFFFF; + data.scale = print_scale; + data.repeat_x = false; + data.repeat_y = false; + + if (!content_redraw(h, &data, &clip, &ctx)) { + error_message = "redraw error"; + goto error; + } + + error = xpdriver_get_rectangle(&b, &more, 0); + if (error) { + LOG("xpdriver_get_rectangle: 0x%x: %s", error->errnum, error->errmess); + error_message = error->errmess; + goto error; + } + } + + yscroll += height; + } while (yscroll <= content_get_height(h) && --sheets != 0); + + /* make print inactive */ + print_active = false; + ro_gui_current_redraw_gui = 0; + + /* clean up + * + * Call PDriver_EndJob via _swix() so that r9 is preserved. This + * prevents a crash if the SWI corrupts it on exit (as seems to + * happen on some versions of RISC OS 6). + */ + + error = (os_error *) _swix(PDriver_EndJob, _IN(0), (int) fhandle); + if (error) { + LOG("xpdriver_end_jobw: 0x%x: %s", error->errnum, error->errmess); + error_message = error->errmess; + goto error; + } + + error = xosfind_closew(fhandle); + if (error) { + LOG("xosfind_closew: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("PrintError", error->errmess); + return false; + } + + if (old_job) { + error = xpdriver_select_jobw(old_job, 0, 0); + if (error) { + LOG("xpdriver_select_jobw: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("PrintError", error->errmess); + /* the printing succeeded anyway */ + return true; + } + } + + rufl_invalidate_cache(); + + /* restore document layout and redraw browser window */ + if (content_get_type(h) == CONTENT_HTML) + content_reformat(h, false, saved_width, saved_height); + + gui_window_redraw_window(g); + + return true; + +error: + xpdriver_abort_job(fhandle); + xosfind_closew(fhandle); + if (old_job) + xpdriver_select_jobw(old_job, 0, 0); + print_active = false; + ro_gui_current_redraw_gui = 0; + + ro_warn_user("PrintError", error_message); + + rufl_invalidate_cache(); + + /* restore document layout */ + if (content_get_type(h) == CONTENT_HTML) + content_reformat(h, false, saved_width, saved_height); + + return false; +} + + +/** + * Declare fonts to the printer driver. + * + * \param h handle to content being printed + * \return 0 on success, error message on error + */ + +const char *print_declare_fonts(hlcache_handle *h) +{ + unsigned int i; + struct rect clip; + struct content_redraw_data data; + const char *error_message = 0; + os_error *error; + struct redraw_context ctx = { + .interactive = false, + .background_images = false, + .plot = &print_fonts_plotters + }; + + free(print_fonts_list); + print_fonts_list = 0; + print_fonts_count = 0; + print_fonts_error = 0; + + clip.x0 = clip.y0 = INT_MIN; + clip.x1 = clip.y1 = INT_MAX; + + data.x = 0; + data.y = 0; + data.width = content_get_width(h); + data.height = content_get_height(h); + data.background_colour = 0xFFFFFF; + data.scale = 1; + data.repeat_x = false; + data.repeat_y = false; + + if (!content_redraw(h, &data, &clip, &ctx)) { + if (print_fonts_error) + return print_fonts_error; + return "Declaring fonts failed."; + } + + for (i = 0; i != print_fonts_count; ++i) { + LOG("%u %s", i, print_fonts_list[i]); + error = xpdriver_declare_font(0, print_fonts_list[i], + pdriver_KERNED); + if (error) { + LOG("xpdriver_declare_font: 0x%x: %s", error->errnum, error->errmess); + error_message = error->errmess; + goto end; + } + } + error = xpdriver_declare_font(0, 0, 0); + if (error) { + LOG("xpdriver_declare_font: 0x%x: %s", error->errnum, error->errmess); + error_message = error->errmess; + goto end; + } + +end: + for (i = 0; i != print_fonts_count; i++) + free(print_fonts_list[i]); + free(print_fonts_list); + print_fonts_list = 0; + + return error_message; +} + + +bool print_fonts_plot_rectangle(int x0, int y0, int x1, int y1, const plot_style_t *style) +{ + return true; +} + + +bool print_fonts_plot_line(int x0, int y0, int x1, int y1, const plot_style_t *style) +{ + return true; +} + +bool print_fonts_plot_polygon(const int *p, unsigned int n, const plot_style_t *style) +{ + return true; +} + + +bool print_fonts_plot_clip(const struct rect *clip) +{ + return true; +} + +bool print_fonts_plot_disc(int x, int y, int radius, const plot_style_t *style) +{ + return true; +} + +bool print_fonts_plot_arc(int x, int y, int radius, int angle1, int angle2, + const plot_style_t *style) +{ + return true; +} + +bool print_fonts_plot_bitmap(int x, int y, int width, int height, + struct bitmap *bitmap, colour bg, bitmap_flags_t flags) +{ + return true; +} + +bool print_fonts_plot_path(const float *p, unsigned int n, colour fill, float width, + colour c, const float transform[6]) +{ + return true; +} + + +/** + * Plotter for text plotting during font listing. + */ + +bool print_fonts_plot_text(int x, int y, const char *text, size_t length, + const plot_font_style_t *fstyle) +{ + const char *font_family; + unsigned int font_size; + rufl_style font_style; + rufl_code code; + + nsfont_read_style(fstyle, &font_family, &font_size, &font_style); + + code = rufl_paint_callback(font_family, font_style, font_size, + text, length, 0, 0, print_fonts_callback, 0); + if (code != rufl_OK) { + if (code == rufl_FONT_MANAGER_ERROR) { + LOG("rufl_paint_callback: rufl_FONT_MANAGER_ERROR: ""0x%x: %s", rufl_fm_error->errnum, rufl_fm_error->errmess); + print_fonts_error = rufl_fm_error->errmess; + } else { + LOG("rufl_paint_callback: 0x%x", code); + } + return false; + } + if (print_fonts_error) + return false; + + return true; +} + + +/** + * Callback for print_fonts_plot_text(). + * + * The font name is added to print_fonts_list. + */ + +void print_fonts_callback(void *context, + const char *font_name, unsigned int font_size, + const char *s8, unsigned short *s16, unsigned int n, + int x, int y) +{ + unsigned int i; + char **fonts_list; + + (void) context; /* unused */ + (void) font_size; /* unused */ + (void) x; /* unused */ + (void) y; /* unused */ + + assert(s8 || s16); + + /* check if the font name is new */ + for (i = 0; i != print_fonts_count && + strcmp(print_fonts_list[i], font_name) != 0; i++) + ; + if (i != print_fonts_count) + return; + + /* add to list of fonts */ + fonts_list = realloc(print_fonts_list, + sizeof print_fonts_list[0] * + (print_fonts_count + 1)); + if (!fonts_list) { + print_fonts_error = messages_get("NoMemory"); + return; + } + fonts_list[print_fonts_count] = strdup(font_name); + if (!fonts_list[print_fonts_count]) { + print_fonts_error = messages_get("NoMemory"); + return; + } + print_fonts_list = fonts_list; + print_fonts_count++; +} + diff --git a/frontends/riscos/print.h b/frontends/riscos/print.h new file mode 100644 index 000000000..d997dce99 --- /dev/null +++ b/frontends/riscos/print.h @@ -0,0 +1,33 @@ +/* + * Copyright 2004 John M Bell <jmb202@ecs.soton.ac.uk> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _NETSURF_RISCOS_PRINT_H_ +#define _NETSURF_RISCOS_PRINT_H_ + +struct gui_window; + +extern struct gui_window *ro_print_current_window; + +void ro_print_save_bounce(wimp_message *m); +void ro_print_error(wimp_message *m); +void ro_print_type_odd(wimp_message *m); +bool ro_print_ack(wimp_message *m); +void ro_print_dataload_bounce(wimp_message *m); +void ro_print_cleanup(void); + +#endif diff --git a/frontends/riscos/query.c b/frontends/riscos/query.c new file mode 100644 index 000000000..1d7cf5120 --- /dev/null +++ b/frontends/riscos/query.c @@ -0,0 +1,381 @@ +/* + * Copyright 2005 Adrian Lees <adrianl@users.sourceforge.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <string.h> +#include <stdbool.h> + +#include "utils/log.h" +#include "utils/messages.h" +#include "utils/utf8.h" +#include "utils/utils.h" + +#include "riscos/gui.h" +#include "riscos/query.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" +#include "riscos/ucstables.h" +#include "riscos/dialog.h" + +#define ICON_QUERY_MESSAGE 0 +#define ICON_QUERY_YES 1 +#define ICON_QUERY_NO 2 +#define ICON_QUERY_HELP 3 + +/** Data for a query window */ +struct gui_query_window +{ + struct gui_query_window *prev; /** Previous query in list */ + struct gui_query_window *next; /** Next query in list */ + + query_id id; /** unique ID number for this query */ + wimp_w window; /** RISC OS window handle */ + + const query_callback *cb; /** Table of callback functions */ + void *pw; /** Handle passed to callback functions */ + + bool default_confirm; /** Default action is to confirm */ +}; + + +/** Next unallocated query id */ +static query_id next_id = (query_id)1; + +/** List of all query windows. */ +static struct gui_query_window *gui_query_window_list = 0; + +/** Template for a query window. */ +static struct wimp_window *query_template; + +/** Widths of Yes and No buttons */ +static int query_yes_width = 0; +static int query_no_width = 0; + +static struct gui_query_window *ro_gui_query_window_lookup_id(query_id id); + +static bool ro_gui_query_click(wimp_pointer *pointer); +static void ro_gui_query_close(wimp_w w); +static bool ro_gui_query_apply(wimp_w w); + + +void ro_gui_query_init(void) +{ + query_template = ro_gui_dialog_load_template("query"); +} + + +/** + * Lookup a query window using its ID number + * + * \param id id to search for + * \return pointer to query window or NULL + */ + +struct gui_query_window *ro_gui_query_window_lookup_id(query_id id) +{ + struct gui_query_window *qw = gui_query_window_list; + while (qw && qw->id != id) + qw = qw->next; + return qw; +} + + +/** + * Display a query to the user, requesting a response, near the current + * pointer position to keep the required mouse travel small, but also + * protecting against spurious mouse clicks. + * + * \param query message token of query + * \param detail parameter used in expanding tokenised message + * \param cb table of callback functions to be called when user responds + * \param pw handle to be passed to callback functions + * \param yes text to use for 'Yes' button' (or NULL for default) + * \param no text to use for 'No' button (or NULL for default) + * \return id number of the query (or QUERY_INVALID if it failed) + */ + +query_id query_user(const char *query, const char *detail, + const query_callback *cb, void *pw, + const char *yes, const char *no) +{ + wimp_pointer pointer; + if (xwimp_get_pointer_info(&pointer)) + pointer.pos.y = pointer.pos.x = -1; + + return query_user_xy(query, detail, cb, pw, yes, no, + pointer.pos.x, pointer.pos.y); +} + + +/** + * Display a query to the user, requesting a response, at a specified + * screen position (x,y). The window is positioned relative to the given + * location such that the required mouse travel is small, but non-zero + * for protection spurious double-clicks. + * + * \param query message token of query + * \param detail parameter used in expanding tokenised message + * \param cb table of callback functions to be called when user responds + * \param pw handle to be passed to callback functions + * \param yes text to use for 'Yes' button' (or NULL for default) + * \param no text to use for 'No' button (or NULL for default) + * \param x x position in screen coordinates (-1 = centred on screen) + * \param y y position in screen coordinates (-1 = centred on screen) + * \return id number of the query (or QUERY_INVALID if it failed) + */ + +query_id query_user_xy(const char *query, const char *detail, + const query_callback *cb, void *pw, + const char *yes, const char *no, + int x, int y) +{ + struct gui_query_window *qw; + char query_buffer[300]; + os_error *error; + wimp_icon *icn; + int width; + int len; + int tx; + char *local_text = NULL; + nserror err; + + qw = malloc(sizeof(struct gui_query_window)); + if (!qw) { + ro_warn_user("NoMemory", NULL); + return QUERY_INVALID; + } + + qw->cb = cb; + qw->pw = pw; + qw->id = next_id++; + qw->default_confirm = false; + + if (next_id == QUERY_INVALID) + next_id++; + + if (!yes) yes = messages_get("Yes"); + if (!no) no = messages_get("No"); + + /* set the text of the 'Yes' button and size accordingly */ + err = utf8_to_local_encoding(yes, 0, &local_text); + if (err != NSERROR_OK) { + assert(err != NSERROR_BAD_ENCODING); + LOG("utf8_to_local_encoding_failed"); + local_text = NULL; + } + + icn = &query_template->icons[ICON_QUERY_YES]; + len = strlen(local_text ? local_text : yes); + len = max(len, icn->data.indirected_text.size - 1); + memcpy(icn->data.indirected_text.text, + local_text ? local_text: yes, len); + icn->data.indirected_text.text[len] = '\0'; + + free(local_text); + local_text = NULL; + + error = xwimptextop_string_width(icn->data.indirected_text.text, len, &width); + if (error) { + LOG("xwimptextop_string_width: 0x%x:%s", error->errnum, error->errmess); + width = len * 16; + } + if (!query_yes_width) query_yes_width = icn->extent.x1 - icn->extent.x0; + width += 44; + if (width < query_yes_width) + width = query_yes_width; + icn->extent.x0 = tx = icn->extent.x1 - width; + + /* set the text of the 'No' button and size accordingly */ + err = utf8_to_local_encoding(no, 0, &local_text); + if (err != NSERROR_OK) { + assert(err != NSERROR_BAD_ENCODING); + LOG("utf8_to_local_encoding_failed"); + local_text = NULL; + } + + icn = &query_template->icons[ICON_QUERY_NO]; + len = strlen(local_text ? local_text : no); + len = max(len, icn->data.indirected_text.size - 1); + memcpy(icn->data.indirected_text.text, + local_text ? local_text : no, len); + icn->data.indirected_text.text[len] = '\0'; + + free(local_text); + local_text = NULL; + + if (!query_no_width) query_no_width = icn->extent.x1 - icn->extent.x0; + icn->extent.x1 = tx - 16; + error = xwimptextop_string_width(icn->data.indirected_text.text, len, &width); + if (error) { + LOG("xwimptextop_string_width: 0x%x:%s", error->errnum, error->errmess); + width = len * 16; + } + width += 28; + if (width < query_no_width) + width = query_no_width; + icn->extent.x0 = icn->extent.x1 - width; + + error = xwimp_create_window(query_template, &qw->window); + if (error) { + ro_warn_user("WimpError", error->errmess); + free(qw); + return QUERY_INVALID; + } + + snprintf(query_buffer, sizeof query_buffer, "%s %s", + messages_get(query), detail ? detail : ""); + query_buffer[sizeof query_buffer - 1] = 0; + + ro_gui_set_icon_string(qw->window, ICON_QUERY_MESSAGE, + query_buffer, true); + + xwimp_set_icon_state(qw->window, ICON_QUERY_HELP, + wimp_ICON_DELETED, wimp_ICON_DELETED); + + if (x >= 0 && y >= 0) { + x -= tx - 8; + y += (query_template->visible.y1 - query_template->visible.y0) / 2; + ro_gui_dialog_open_xy(qw->window, x, y); + } + else + ro_gui_dialog_open(qw->window); + + ro_gui_wimp_event_set_user_data(qw->window, qw); + ro_gui_wimp_event_register_mouse_click(qw->window, ro_gui_query_click); + ro_gui_wimp_event_register_cancel(qw->window, ICON_QUERY_NO); + ro_gui_wimp_event_register_ok(qw->window, ICON_QUERY_YES, ro_gui_query_apply); + ro_gui_wimp_event_register_close_window(qw->window, ro_gui_query_close); + + error = xwimp_set_caret_position(qw->window, (wimp_i)-1, 0, 0, 1 << 25, -1); + if (error) { + LOG("xwimp_get_caret_position: 0x%x : %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + + /* put this query window at the head of our list */ + if (gui_query_window_list) + gui_query_window_list->prev = qw; + + qw->prev = NULL; + qw->next = gui_query_window_list; + gui_query_window_list = qw; + + return qw->id; +} + + +/** + * Close a query window without waiting for a response from the user. + * (should normally only be called if the user has responded in some other + * way of which the query window in unaware.) + * + * \param id id of query window to close + */ + +void query_close(query_id id) +{ + struct gui_query_window *qw = ro_gui_query_window_lookup_id(id); + if (!qw) + return; + ro_gui_query_close(qw->window); + +} + + +void ro_gui_query_window_bring_to_front(query_id id) +{ + struct gui_query_window *qw = ro_gui_query_window_lookup_id(id); + if (qw) { + os_error *error; + + ro_gui_dialog_open(qw->window); + + error = xwimp_set_caret_position(qw->window, (wimp_i)-1, 0, 0, 1 << 25, -1); + if (error) { + LOG("xwimp_get_caret_position: 0x%x : %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + } +} + + +/** + * Handle closing of query dialog + */ +void ro_gui_query_close(wimp_w w) +{ + struct gui_query_window *qw; + os_error *error; + + qw = (struct gui_query_window *)ro_gui_wimp_event_get_user_data(w); + + ro_gui_dialog_close(w); + error = xwimp_delete_window(qw->window); + if (error) { + LOG("xwimp_delete_window: 0x%x:%s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + ro_gui_wimp_event_finalise(w); + + /* remove from linked-list of query windows and release memory */ + if (qw->prev) + qw->prev->next = qw->next; + else + gui_query_window_list = qw->next; + + if (qw->next) + qw->next->prev = qw->prev; + free(qw); +} + + +/** + * Handle acceptance of query dialog + */ +bool ro_gui_query_apply(wimp_w w) +{ + struct gui_query_window *qw; + const query_callback *cb; + + qw = (struct gui_query_window *)ro_gui_wimp_event_get_user_data(w); + cb = qw->cb; + cb->confirm(qw->id, QUERY_YES, qw->pw); + return true; +} + + +/** + * Handle clicks in query dialog + */ +bool ro_gui_query_click(wimp_pointer *pointer) +{ + struct gui_query_window *qw; + const query_callback *cb; + + qw = (struct gui_query_window *)ro_gui_wimp_event_get_user_data(pointer->w); + cb = qw->cb; + + switch (pointer->i) { + case ICON_QUERY_NO: + cb->cancel(qw->id, QUERY_NO, qw->pw); + break; + default: + return false; + } + return false; +} diff --git a/frontends/riscos/query.h b/frontends/riscos/query.h new file mode 100644 index 000000000..c60a8bbbb --- /dev/null +++ b/frontends/riscos/query.h @@ -0,0 +1,53 @@ +/* + * Copyright 2005 Adrian Lees <adrianl@users.sourceforge.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _NETSURF_RISCOS_QUERY_H +#define _NETSURF_RISCOS_QUERY_H + +#include <stdbool.h> +#include "oslib/wimp.h" + +enum query_response { + QUERY_CONTINUE, + QUERY_YES, + QUERY_NO, + QUERY_ESCAPE +}; + +typedef int query_id; + +#define QUERY_INVALID ((query_id)-1) + +typedef struct +{ + void (*confirm)(query_id id, enum query_response res, void *pw); + void (*cancel)(query_id, enum query_response res, void *pw); +} query_callback; + + +query_id query_user_xy(const char *query, const char *detail, + const query_callback *cb, void *pw, const char *yes, const char *no, + int x, int y); +void ro_gui_query_init(void); +void ro_gui_query_window_bring_to_front(query_id id); + +query_id query_user(const char *query, const char *detail, + const query_callback *cb, void *pw, const char *yes, const char *no); +void query_close(query_id); + +#endif diff --git a/frontends/riscos/save.c b/frontends/riscos/save.c new file mode 100644 index 000000000..27330700c --- /dev/null +++ b/frontends/riscos/save.c @@ -0,0 +1,1401 @@ +/* + * Copyright 2004-2007 James Bursa <bursa@users.sourceforge.net> + * Copyright 2005 Adrian Lees <adrianl@users.sourceforge.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Save dialog and drag and drop saving (implementation). + */ + +#include <assert.h> +#include <ctype.h> +#include <errno.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "oslib/dragasprite.h" +#include "oslib/osbyte.h" +#include "oslib/osfile.h" +#include "oslib/osmodule.h" +#include "oslib/osspriteop.h" +#include "oslib/wimp.h" +#include "oslib/wimpspriteop.h" + +#include "utils/config.h" +#include "utils/log.h" +#include "utils/messages.h" +#include "utils/utf8.h" +#include "content/content.h" +#include "content/hlcache.h" +#include "desktop/browser.h" +#include "desktop/hotlist.h" +#include "desktop/global_history.h" +#include "desktop/version.h" +#include "desktop/save_complete.h" +#include "desktop/save_text.h" +#include "desktop/gui_window.h" +#include "image/bitmap.h" +#include "render/form.h" + +#include "riscos/bitmap.h" +#include "riscos/dialog.h" +#include "riscos/gui.h" +#include "riscos/menus.h" +#include "riscos/message.h" +#include "riscos/mouse.h" +#include "utils/nsoption.h" +#include "riscos/query.h" +#include "riscos/save.h" +#include "riscos/save_draw.h" +#include "riscos/save_pdf.h" +#include "riscos/textselection.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" +#include "riscos/ucstables.h" +#include "riscos/filetype.h" + +//typedef enum +//{ +// QueryRsn_Quit, +// QueryRsn_Abort, +// QueryRsn_Overwrite +//} query_reason; + + +/**todo - much of the state information for a save should probably be moved into a structure + now since we could have multiple saves outstanding */ + +static gui_save_type gui_save_current_type; +static hlcache_handle *gui_save_content = NULL; +static char *gui_save_selection = NULL; +static const char *gui_save_url = NULL; +static const char *gui_save_title = NULL; +static int gui_save_filetype; +static query_id gui_save_query; +static bool gui_save_send_dataload; +static wimp_message gui_save_message; +static bool gui_save_close_after = true; + +static bool dragbox_active = false; /** in-progress Wimp_DragBox/DragASprite op */ +static bool using_dragasprite = true; +static bool saving_from_dialog = true; +static osspriteop_area *saveas_area = NULL; +static wimp_w gui_save_sourcew = (wimp_w)-1; +#define LEAFNAME_MAX 200 +static char save_leafname[LEAFNAME_MAX]; + +/** Current save directory (updated by and used for dialog-based saving) */ +static char *save_dir = NULL; +static size_t save_dir_len; + +typedef enum { LINK_ACORN, LINK_ANT, LINK_TEXT } link_format; + +static bool ro_gui_save_complete(hlcache_handle *h, char *path); +static bool ro_gui_save_content(hlcache_handle *h, char *path, bool force_overwrite); +static void ro_gui_save_done(void); +static void ro_gui_save_bounced(wimp_message *message); +static bool ro_gui_save_object_native(hlcache_handle *h, char *path); +static bool ro_gui_save_link(const char *url, const char *title, link_format format, char *path); +static void ro_gui_save_set_state(hlcache_handle *h, gui_save_type save_type, + const nsurl *url, char *leaf_buf, size_t leaf_len, + char *icon_buf, size_t icon_len); +static void ro_gui_save_drag_end(wimp_dragged *drag, void *data); +static bool ro_gui_save_create_thumbnail(hlcache_handle *h, const char *name); +static void ro_gui_save_overwrite_confirmed(query_id, enum query_response res, void *p); +static void ro_gui_save_overwrite_cancelled(query_id, enum query_response res, void *p); + +static const query_callback overwrite_funcs = +{ + ro_gui_save_overwrite_confirmed, + ro_gui_save_overwrite_cancelled +}; + + +/** An entry in gui_save_table. */ +struct gui_save_table_entry { + int filetype; + const char *name; +}; + +/** Table of filetypes and default filenames. Must be in sync with + * gui_save_type (riscos/gui.h). A filetype of 0 indicates the content should + * be used. + */ +static const struct gui_save_table_entry gui_save_table[] = { + /* GUI_SAVE_SOURCE, */ { 0, "SaveSource" }, + /* GUI_SAVE_DRAW, */ { 0xaff, "SaveDraw" }, + /* GUI_SAVE_PDF, */ { 0xadf, "SavePDF" }, + /* GUI_SAVE_TEXT, */ { 0xfff, "SaveText" }, + /* GUI_SAVE_COMPLETE, */ { 0xfaf, "SaveComplete" }, + /* GUI_SAVE_OBJECT_ORIG, */ { 0, "SaveObject" }, + /* GUI_SAVE_OBJECT_NATIVE, */ { 0, "SaveObject" }, + /* GUI_SAVE_LINK_URI, */ { 0xf91, "SaveLink" }, + /* GUI_SAVE_LINK_URL, */ { 0xb28, "SaveLink" }, + /* GUI_SAVE_LINK_TEXT, */ { 0xfff, "SaveLink" }, + /* GUI_SAVE_HOTLIST_EXPORT_HTML, */ { 0xfaf, "Hotlist" }, + /* GUI_SAVE_HISTORY_EXPORT_HTML, */ { 0xfaf, "History" }, + /* GUI_SAVE_TEXT_SELECTION, */ { 0xfff, "SaveSelection" }, +}; + + +/** + * Create the saveas dialogue from the given template, and the sprite area + * necessary for our thumbnail (full page save) + * + * \param template_name name of template to be used + * \return window handle of created dialogue + */ + +wimp_w ro_gui_saveas_create(const char *template_name) +{ + const int sprite_size = (68 * 68 * 4) + ((68 * 68) / 8); /* 32bpp with mask */ + int area_size = sizeof(osspriteop_area) + sizeof(osspriteop_header) + + 256 * 8 + sprite_size; + void *area = NULL; + wimp_window *window; + os_error *error; + wimp_icon *icons; + wimp_w w; + + window = ro_gui_dialog_load_template(template_name); + assert(window); + + icons = window->icons; + + error = xosmodule_alloc(area_size, (void **) &area); + if (error) { + LOG("xosmodule_alloc: 0x%x: %s", error->errnum, error->errmess); + xwimp_close_template(); + die(error->errmess); + } else { + saveas_area = area; + saveas_area->size = area_size; + saveas_area->first = 16; + + error = xosspriteop_clear_sprites(osspriteop_USER_AREA, saveas_area); + if (error) { + LOG("xosspriteop_clear_sprites: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MiscError", error->errmess); + + xosmodule_free(saveas_area); + saveas_area = NULL; + } + } + + assert((icons[ICON_SAVE_ICON].flags & + (wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_INDIRECTED)) == + (wimp_ICON_SPRITE | wimp_ICON_INDIRECTED)); + icons[ICON_SAVE_ICON].data.indirected_sprite.area = saveas_area; + + /* create window */ + error = xwimp_create_window(window, &w); + if (error) { + LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess); + xwimp_close_template(); + die(error->errmess); + } + + /* the window definition is copied by the wimp and may be freed */ + free(window); + + return w; +} + + +/** + * Clean-up function that releases our sprite area and memory. + */ + +void ro_gui_saveas_quit(void) +{ + if (saveas_area) { + os_error *error = xosmodule_free(saveas_area); + if (error) { + LOG("xosmodule_free: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MiscError", error->errmess); + } + saveas_area = NULL; + } + + free(save_dir); + save_dir = NULL; +} + +/** + * Prepares the save box to reflect gui_save_type and a content, and + * opens it. + * + * \param save_type type of save + * \param h content to save + * \param s selection to save + * \param url url to be saved (link types) + * \param title title (if any), when saving links + */ + +void ro_gui_save_prepare(gui_save_type save_type, hlcache_handle *h, + char *s, const nsurl *url, const char *title) +{ + char name_buf[FILENAME_MAX]; + size_t leaf_offset = 0; + char icon_buf[20]; + + assert( (save_type == GUI_SAVE_LINK_URI) || + (save_type == GUI_SAVE_LINK_URL) || + (save_type == GUI_SAVE_LINK_TEXT) || + (save_type == GUI_SAVE_HOTLIST_EXPORT_HTML) || + (save_type == GUI_SAVE_HISTORY_EXPORT_HTML) || + (save_type == GUI_SAVE_TEXT_SELECTION) || h); + + if (gui_save_selection == NULL) + free(gui_save_selection); + + gui_save_selection = s; + if (url != NULL) { + gui_save_url = nsurl_access(url); + } else { + gui_save_url = NULL; + } + gui_save_title = title; + + if (save_dir) { + leaf_offset = save_dir_len; + memcpy(name_buf, save_dir, leaf_offset); + name_buf[leaf_offset++] = '.'; + } + + if (h != NULL) { + url = hlcache_handle_get_url(h); + } + + ro_gui_save_set_state(h, save_type, url, + name_buf + leaf_offset, FILENAME_MAX - leaf_offset, + icon_buf, sizeof(icon_buf)); + + ro_gui_set_icon_sprite(dialog_saveas, ICON_SAVE_ICON, saveas_area, + icon_buf); + + ro_gui_set_icon_string(dialog_saveas, ICON_SAVE_PATH, name_buf, true); + ro_gui_wimp_event_memorise(dialog_saveas); +} + +/** + * Starts a drag for the save dialog + * + * \param pointer mouse position info from Wimp + */ +void ro_gui_save_start_drag(wimp_pointer *pointer) +{ + if (pointer->buttons & (wimp_DRAG_SELECT | wimp_DRAG_ADJUST)) { + const char *sprite = ro_gui_get_icon_string(pointer->w, pointer->i); + int x = pointer->pos.x, y = pointer->pos.y; + wimp_window_state wstate; + wimp_icon_state istate; + /* start the drag from the icon's exact location, rather than the pointer */ + istate.w = wstate.w = pointer->w; + istate.i = pointer->i; + if (!xwimp_get_window_state(&wstate) && !xwimp_get_icon_state(&istate)) { + x = (istate.icon.extent.x1 + istate.icon.extent.x0)/2 + + wstate.visible.x0 - wstate.xscroll; + y = (istate.icon.extent.y1 + istate.icon.extent.y0)/2 + + wstate.visible.y1 - wstate.yscroll; + } + ro_mouse_drag_start(ro_gui_save_drag_end, NULL, NULL, NULL); + gui_save_sourcew = pointer->w; + saving_from_dialog = true; + gui_save_close_after = !(pointer->buttons & wimp_DRAG_ADJUST); + ro_gui_drag_icon(x, y, sprite); + } +} + + +/** + * Handle OK click/keypress in the save dialog. + * + * \param w window handle of save dialog + * \return true on success, false on failure + */ +bool ro_gui_save_ok(wimp_w w) +{ + const char *name = ro_gui_get_icon_string(w, ICON_SAVE_PATH); + wimp_pointer pointer; + char path[256]; + + if (!strrchr(name, '.')) { + ro_warn_user("NoPathError", NULL); + return false; + } + + ro_gui_convert_save_path(path, sizeof path, name); + gui_save_sourcew = w; + saving_from_dialog = true; + gui_save_send_dataload = false; + gui_save_close_after = xwimp_get_pointer_info(&pointer) + || !(pointer.buttons & wimp_CLICK_ADJUST); + memcpy(&gui_save_message.data.data_xfer.file_name, path, 1 + strlen(path)); + + if (ro_gui_save_content(gui_save_content, path, !nsoption_bool(confirm_overwrite))) { + ro_gui_save_done(); + return true; + } + return false; +} + + +/** + * Initiates drag saving of an object directly from a browser window + * + * \param save_type type of save + * \param c content to save + * \param g gui window + */ + +void gui_drag_save_object(struct gui_window *g, hlcache_handle *c, + gui_save_type save_type) +{ + wimp_pointer pointer; + char icon_buf[20]; + os_error *error; + + /* Close the save window because otherwise we need two contexts + */ + xwimp_create_menu(wimp_CLOSE_MENU, 0, 0); + ro_gui_dialog_close(dialog_saveas); + + gui_save_sourcew = g->window; + saving_from_dialog = false; + + error = xwimp_get_pointer_info(&pointer); + if (error) { + LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + ro_gui_save_set_state(c, save_type, hlcache_handle_get_url(c), + save_leafname, LEAFNAME_MAX, + icon_buf, sizeof(icon_buf)); + + ro_mouse_drag_start(ro_gui_save_drag_end, NULL, NULL, NULL); + + ro_gui_drag_icon(pointer.pos.x, pointer.pos.y, icon_buf); +} + + +/** + * Initiates drag saving of a selection from a browser window + * + * \param g gui window + * \param selection selection object + */ + +void gui_drag_save_selection(struct gui_window *g, const char *selection) +{ + wimp_pointer pointer; + char icon_buf[20]; + os_error *error; + + /* Close the save window because otherwise we need two contexts + */ + xwimp_create_menu(wimp_CLOSE_MENU, 0, 0); + ro_gui_dialog_close(dialog_saveas); + + gui_save_sourcew = g->window; + saving_from_dialog = false; + + error = xwimp_get_pointer_info(&pointer); + if (error) { + LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + + if (gui_save_selection == NULL) + free(gui_save_selection); + + if (selection == NULL) + gui_save_selection = strdup(""); + else + gui_save_selection = strdup(selection); + + ro_gui_save_set_state(NULL, GUI_SAVE_TEXT_SELECTION, NULL, + save_leafname, LEAFNAME_MAX, + icon_buf, sizeof(icon_buf)); + + ro_mouse_drag_start(ro_gui_save_drag_end, NULL, NULL, NULL); + + ro_gui_drag_icon(pointer.pos.x, pointer.pos.y, icon_buf); +} + + +/** + * Initiates drag saving of a link/URL file + * + * \param save_type format in which URL should be saved + * \param url url to be saved + * \param title title to be included in URI format, if any + * \param g gui window to save from + * \ + */ + +void ro_gui_drag_save_link(gui_save_type save_type, const nsurl *url, + const char *title, struct gui_window *g) +{ + wimp_pointer pointer; + char icon_buf[20]; + os_error *error; + + /* Close the save window because otherwise we need two contexts + */ + xwimp_create_menu(wimp_CLOSE_MENU, 0, 0); + ro_gui_dialog_close(dialog_saveas); + + gui_save_url = nsurl_access(url); + gui_save_title = title; + gui_save_sourcew = g->window; + saving_from_dialog = false; + + error = xwimp_get_pointer_info(&pointer); + if (error) { + LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + ro_gui_save_set_state(NULL, save_type, url, save_leafname, + LEAFNAME_MAX, icon_buf, sizeof(icon_buf)); + + ro_mouse_drag_start(ro_gui_save_drag_end, NULL, NULL, NULL); + + ro_gui_drag_icon(pointer.pos.x, pointer.pos.y, icon_buf); +} + + +/** + * Start drag of icon under the pointer. + */ + +void ro_gui_drag_icon(int x, int y, const char *sprite) +{ + os_error *error; + wimp_drag drag; + int r2; + + drag.initial.x0 = x - 34; + drag.initial.y0 = y - 34; + drag.initial.x1 = x + 34; + drag.initial.y1 = y + 34; + + if (sprite && (xosbyte2(osbyte_READ_CMOS, 28, 0, &r2) || (r2 & 2))) { + osspriteop_area *area = (osspriteop_area*)1; + + /* first try our local sprite area in case it's a thumbnail sprite */ + if (saveas_area) { + error = xosspriteop_select_sprite(osspriteop_USER_AREA, + saveas_area, (osspriteop_id)sprite, NULL); + if (error) { + if (error->errnum != error_SPRITE_OP_DOESNT_EXIST) { + LOG("xosspriteop_select_sprite: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MiscError", error->errmess); + } + } + else + area = saveas_area; + } + + error = xdragasprite_start(dragasprite_HPOS_CENTRE | + dragasprite_VPOS_CENTRE | + dragasprite_BOUND_POINTER | + dragasprite_DROP_SHADOW, + area, sprite, &drag.initial, 0); + + if (!error) { + using_dragasprite = true; + dragbox_active = true; + return; + } + + LOG("xdragasprite_start: 0x%x: %s", error->errnum, error->errmess); + } + + drag.type = wimp_DRAG_USER_FIXED; + drag.bbox.x0 = -0x8000; + drag.bbox.y0 = -0x8000; + drag.bbox.x1 = 0x7fff; + drag.bbox.y1 = 0x7fff; + + using_dragasprite = false; + error = xwimp_drag_box(&drag); + + if (error) { + LOG("xwimp_drag_box: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("DragError", error->errmess); + } + else + dragbox_active = true; +} + + +/** + * Convert a ctrl-char terminated pathname possibly containing spaces + * to a NUL-terminated one containing only hard spaces. + * + * \param dp destination buffer to receive pathname + * \param len size of destination buffer + * \param p source pathname, ctrl-char terminated + */ + +void ro_gui_convert_save_path(char *dp, size_t len, const char *p) +{ + char *ep = dp + len - 1; /* leave room for NUL */ + + assert(p <= dp || p > ep); /* in-situ conversion /is/ allowed */ + + while (dp < ep && *p >= ' ') /* ctrl-char terminated */ + { + *dp++ = (*p == ' ') ? 160 : *p; + p++; + } + *dp = '\0'; +} + + +void ro_gui_drag_box_cancel(void) +{ + if (dragbox_active) { + os_error *error; + if (using_dragasprite) { + error = xdragasprite_stop(); + if (error) { + LOG("xdragasprite_stop: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + } + else { + error = xwimp_drag_box(NULL); + if (error) { + LOG("xwimp_drag_box: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + } + dragbox_active = false; + } +} + + +/** + * Handle User_Drag_Box event for a drag from the save dialog or browser window. + * + * \param *drag The Wimp_DragEnd data block. + * \param *data NULL, as function is used as a callback from ro_mouse. + */ + +static void ro_gui_save_drag_end(wimp_dragged *drag, void *data) +{ + const char *name; + wimp_pointer pointer; + wimp_message message; + os_error *error; + char *dp, *ep; + char *local_name = NULL; + + if (dragbox_active) + ro_gui_drag_box_cancel(); + + error = xwimp_get_pointer_info(&pointer); + if (error) { + LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + /* perform hit-test if the destination is the same as the source window; + we want to allow drag-saving from a page into the input fields within + the page, but avoid accidental replacements of the current page */ + if (gui_save_sourcew != (wimp_w)-1 && pointer.w == gui_save_sourcew) { + int dx = (drag->final.x1 + drag->final.x0)/2; + int dy = (drag->final.y1 + drag->final.y0)/2; + struct gui_window *g; + bool dest_ok = false; + os_coord pos; + + g = ro_gui_window_lookup(gui_save_sourcew); + + if (g && ro_gui_window_to_window_pos(g, dx, dy, &pos)) { + dest_ok = browser_window_drop_file_at_point(g->bw, + pos.x, pos.y, NULL); + } + if (!dest_ok) + return; + } + + if (!saving_from_dialog) { + /* saving directly from browser window, choose a + * name based upon the URL */ + nserror err; + err = utf8_to_local_encoding(save_leafname, 0, &local_name); + if (err != NSERROR_OK) { + /* badenc should never happen */ + assert(err != NSERROR_BAD_ENCODING); + local_name = NULL; + } + name = local_name ? local_name : save_leafname; + } + else { + char *dot; + + /* saving from dialog, grab leafname from icon */ + name = ro_gui_get_icon_string(gui_save_sourcew, ICON_SAVE_PATH); + dot = strrchr(name, '.'); + if (dot) + name = dot + 1; + } + + dp = message.data.data_xfer.file_name; + ep = dp + sizeof message.data.data_xfer.file_name; + + if (gui_save_current_type == GUI_SAVE_COMPLETE) { + message.data.data_xfer.file_type = 0x2000; + if (*name != '!') *dp++ = '!'; + } else + message.data.data_xfer.file_type = gui_save_filetype; + + ro_gui_convert_save_path(dp, ep - dp, name); + +/* \todo - we're supposed to set this if drag-n-drop used */ + message.your_ref = 0; + + message.action = message_DATA_SAVE; + message.data.data_xfer.w = pointer.w; + message.data.data_xfer.i = pointer.i; + message.data.data_xfer.pos.x = pointer.pos.x; + message.data.data_xfer.pos.y = pointer.pos.y; + message.data.data_xfer.est_size = 1000; + message.size = 44 + ((strlen(message.data.data_xfer.file_name) + 4) & + (~3u)); + + ro_message_send_message_to_window(wimp_USER_MESSAGE_RECORDED, &message, + pointer.w, pointer.i, ro_gui_save_bounced, NULL); + + gui_current_drag_type = GUI_DRAG_SAVE; + + free(local_name); +} + + + +/** + * Send DataSave message on behalf of clipboard code and remember that it's the + * clipboard contents we're being asked for when the DataSaveAck reply arrives + */ + +void ro_gui_send_datasave(gui_save_type save_type, + wimp_full_message_data_xfer *message, wimp_t to) +{ + /* Close the save window because otherwise we need two contexts + */ + + ro_gui_dialog_close(dialog_saveas); + + if (ro_message_send_message(wimp_USER_MESSAGE_RECORDED, (wimp_message*)message, + to, ro_gui_save_bounced)) { + gui_save_current_type = save_type; + gui_save_sourcew = (wimp_w)-1; + saving_from_dialog = false; + + gui_current_drag_type = GUI_DRAG_SAVE; + } +} + + +/** + * Handle lack of Message_DataSaveAck for drags, saveas dialogs and clipboard code + */ + +void ro_gui_save_bounced(wimp_message *message) +{ + gui_current_drag_type = GUI_DRAG_NONE; +} + + +/** + * Handle Message_DataSaveAck for a drag from the save dialog or browser window, + * or Clipboard protocol. + */ + +void ro_gui_save_datasave_ack(wimp_message *message) +{ + char *path = message->data.data_xfer.file_name; + hlcache_handle *h = gui_save_content; + bool force_overwrite; + + switch (gui_save_current_type) { + case GUI_SAVE_LINK_URI: + case GUI_SAVE_LINK_URL: + case GUI_SAVE_LINK_TEXT: + case GUI_SAVE_HOTLIST_EXPORT_HTML: + case GUI_SAVE_HISTORY_EXPORT_HTML: + case GUI_SAVE_TEXT_SELECTION: + case GUI_SAVE_CLIPBOARD_CONTENTS: + break; + + default: + if (!gui_save_content) { + LOG("unexpected DataSaveAck: gui_save_content not set"); + return; + } + break; + } + + if (saving_from_dialog) + ro_gui_set_icon_string(gui_save_sourcew, ICON_SAVE_PATH, + path, true); + + gui_save_send_dataload = true; + memcpy(&gui_save_message, message, sizeof(gui_save_message)); + + /* if saving/pasting to another application, don't request user + confirmation; a ScrapFile almost certainly exists already */ + if (message->data.data_xfer.est_size == -1) + force_overwrite = true; + else + force_overwrite = !nsoption_bool(confirm_overwrite); + + if (ro_gui_save_content(h, path, force_overwrite)) + ro_gui_save_done(); +} + + + +/** + * Does the actual saving + * + * \param h handle to content to save (or NULL for other) + * \param path path to save as + * \param force_overwrite true iff required to overwrite without prompting + * \return true on success, + * false on (i) error and error reported + * or (ii) deferred awaiting user confirmation + */ + +bool ro_gui_save_content(hlcache_handle *h, char *path, bool force_overwrite) +{ + os_error *error; + const char *source_data; + unsigned long source_size; + + /* does the user want to check for collisions when saving? */ + if (!force_overwrite) { + fileswitch_object_type obj_type; + /* check whether the destination file/dir already exists */ + error = xosfile_read_stamped(path, &obj_type, + NULL, NULL, NULL, NULL, NULL); + if (error) { + LOG("xosfile_read_stamped: 0x%x:%s", error->errnum, error->errmess); + ro_warn_user("SaveError", error->errmess); + return false; + } + + switch (obj_type) { + case osfile_NOT_FOUND: + break; + + case osfile_IS_FILE: + gui_save_query = query_user("OverwriteFile", NULL, &overwrite_funcs, NULL, + messages_get("Replace"), messages_get("DontReplace")); +// gui_save_query_rsn = QueryRsn_Overwrite; + return false; + + default: + error = xosfile_make_error(path, obj_type); + assert(error); + ro_warn_user("SaveError", error->errmess); + return false; + } + } + + switch (gui_save_current_type) { +#ifdef WITH_DRAW_EXPORT + case GUI_SAVE_DRAW: + return save_as_draw(h, path); +#endif +#ifdef WITH_PDF_EXPORT + case GUI_SAVE_PDF: + return save_as_pdf(h, path); +#endif + case GUI_SAVE_TEXT: + save_as_text(h, path); + xosfile_set_type(path, 0xfff); + break; + case GUI_SAVE_COMPLETE: + assert(h); + if (content_get_type(h) == CONTENT_HTML) { + if (strcmp(path, "<Wimp$Scrap>")) + return ro_gui_save_complete(h, path); + + /* we can't send a whole directory to another + * application, so just send the HTML source */ + gui_save_current_type = GUI_SAVE_SOURCE; + } + else + gui_save_current_type = GUI_SAVE_OBJECT_ORIG; /* \todo do this earlier? */ + /* no break */ + case GUI_SAVE_SOURCE: + case GUI_SAVE_OBJECT_ORIG: + source_data = content_get_source_data(h, &source_size); + error = xosfile_save_stamped(path, + ro_content_filetype(h), + (byte *) source_data, + (byte *) source_data + source_size); + if (error) { + LOG("xosfile_save_stamped: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("SaveError", error->errmess); + return false; + } + break; + + case GUI_SAVE_OBJECT_NATIVE: + return ro_gui_save_object_native(h, path); + + case GUI_SAVE_LINK_URI: + return ro_gui_save_link(gui_save_url, gui_save_title, + LINK_ACORN, path); + + case GUI_SAVE_LINK_URL: + return ro_gui_save_link(gui_save_url, gui_save_title, + LINK_ANT, path); + + case GUI_SAVE_LINK_TEXT: + return ro_gui_save_link(gui_save_url, gui_save_title, + LINK_TEXT, path); + + case GUI_SAVE_HOTLIST_EXPORT_HTML: + if (hotlist_export(path, NULL) != NSERROR_OK) + return false; + error = xosfile_set_type(path, 0xfaf); + if (error) + LOG("xosfile_set_type: 0x%x: %s", error->errnum, error->errmess); + break; + case GUI_SAVE_HISTORY_EXPORT_HTML: + if (global_history_export(path, NULL) != NSERROR_OK) + return false; + error = xosfile_set_type(path, 0xfaf); + if (error) + LOG("xosfile_set_type: 0x%x: %s", error->errnum, error->errmess); + break; + + case GUI_SAVE_TEXT_SELECTION: + if (gui_save_selection == NULL) + return false; + if (!utf8_save_text(gui_save_selection, path)) { + free(gui_save_selection); + gui_save_selection = NULL; + return false; + } + free(gui_save_selection); + gui_save_selection = NULL; + xosfile_set_type(path, 0xfff); + break; + + case GUI_SAVE_CLIPBOARD_CONTENTS: + return ro_gui_save_clipboard(path); + + default: + LOG("Unexpected content type: %d, path %s", gui_save_current_type, path); + return false; + } + return true; +} + + +/** + * Save completed, inform recipient and close our 'save as' dialog. + */ + +void ro_gui_save_done(void) +{ + os_error *error; + + if (gui_save_send_dataload) { + /* Ack successful save with message_DATA_LOAD */ + wimp_message *message = &gui_save_message; + message->action = message_DATA_LOAD; + message->your_ref = message->my_ref; + error = xwimp_send_message(wimp_USER_MESSAGE, message, + message->sender); + if (error) { + LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("SaveError", error->errmess); + } + } + + if (saving_from_dialog) { + /* remember the save directory if saving to the Filer */ + if (!gui_save_send_dataload || + gui_save_message.data.data_xfer.est_size != -1) { + char *sp = gui_save_message.data.data_xfer.file_name; + char *ep = sp + sizeof(gui_save_message.data.data_xfer.file_name); + char *lastdot = NULL; + char *p = sp; + + while (p < ep && *p >= 0x20) { + if (*p == '.') { + /* don't remember the directory if it's a temporary file */ + if (!lastdot && p == sp + 12 && + !memcmp(sp, "<Wimp$Scrap>", 12)) break; + lastdot = p; + } + p++; + } + if (lastdot) { + /* remember the directory */ + char *new_dir = realloc(save_dir, (lastdot+1)-sp); + if (new_dir) { + save_dir_len = lastdot - sp; + memcpy(new_dir, sp, save_dir_len); + new_dir[save_dir_len] = '\0'; + save_dir = new_dir; + } + } + } + + if (gui_save_close_after) { + /* Close the save window */ + ro_gui_dialog_close(dialog_saveas); + error = xwimp_create_menu(wimp_CLOSE_MENU, 0, 0); + if (error) { + LOG("xwimp_create_menu: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MenuError", error->errmess); + } + } + } + + if (!saving_from_dialog || gui_save_close_after) + gui_save_content = 0; +} + +static void ro_gui_save_set_file_type(const char *path, lwc_string *mime_type) +{ + int rotype = ro_content_filetype_from_mime_type(mime_type); + os_error *error; + + error = xosfile_set_type(path, rotype); + if (error != NULL) { + LOG("xosfile_set_type: 0x%x: %s", error->errnum, error->errmess); + } +} + +/** + * Prepare an application directory and save_complete() to it. + * + * \param h content of type CONTENT_HTML to save + * \param path path to save as + * \return true on success, false on error and error reported + */ + +bool ro_gui_save_complete(hlcache_handle *h, char *path) +{ + void *spr = ((byte *) saveas_area) + saveas_area->first; + osspriteop_header *sprite = (osspriteop_header *) spr; + char name[12]; + char buf[256]; + FILE *fp; + os_error *error; + size_t len; + char *dot; + int i; + + /* Create dir */ + error = xosfile_create_dir(path, 0); + if (error) { + LOG("xosfile_create_dir: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("SaveError", error->errmess); + return false; + } + + /* Save !Run file */ + snprintf(buf, sizeof buf, "%s.!Run", path); + fp = fopen(buf, "w"); + if (!fp) { + LOG("fopen(): errno = %i", errno); + ro_warn_user("SaveError", strerror(errno)); + return false; + } + fprintf(fp, "IconSprites <Obey$Dir>.!Sprites\n"); + fprintf(fp, "Filer_Run <Obey$Dir>.index\n"); + fclose(fp); + error = xosfile_set_type(buf, 0xfeb); + if (error) { + LOG("xosfile_set_type: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("SaveError", error->errmess); + return false; + } + + /* create an empty !Runimage so the date gets correctly set */ + snprintf(buf, sizeof buf, "%s.!RunImage", path); + fp = fopen(buf, "w"); + if (!fp) { + LOG("Creating !RunImage failed: errno = %i", errno); + } else { + fclose(fp); + } + + /* Make sure the sprite name matches the directory name, because + the user may have renamed the directory since we created the + thumbnail sprite */ + + dot = strrchr(path, '.'); + if (dot) dot++; else dot = path; + len = strlen(dot); + if (len >= 12) len = 12; + + memcpy(name, sprite->name, 12); /* remember original name */ + memcpy(sprite->name, dot, len); + memset(sprite->name + len, 0, 12 - len); + for (i = 0; i < 12; i++) /* convert to lower case */ + if (sprite->name[i] != '\0') + sprite->name[i] = tolower(sprite->name[i]); + + /* Create !Sprites */ + snprintf(buf, sizeof buf, "%s.!Sprites", path); + + error = xosspriteop_save_sprite_file(osspriteop_NAME, saveas_area, buf); + if (error) { + LOG("xosspriteop_save_sprite_file: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("SaveError", error->errmess); + return false; + } + + /* restore sprite name in case the save fails and we need to try again */ + memcpy(sprite->name, name, 12); + + /* save URL file with original URL */ + snprintf(buf, sizeof buf, "%s.URL", path); + if (!ro_gui_save_link(nsurl_access(hlcache_handle_get_url(h)), + content_get_title(h), LINK_ANT, buf)) + return false; + + return save_complete(h, path, ro_gui_save_set_file_type); +} + +bool ro_gui_save_object_native(hlcache_handle *h, char *path) +{ + int file_type = ro_content_filetype(h); + + if (file_type == osfile_TYPE_SPRITE || file_type == osfile_TYPE_DRAW) { + /* Native sprite or drawfile */ + const char *source_data; + unsigned long source_size; + os_error *error; + + source_data = content_get_source_data(h, &source_size); + error = xosfile_save_stamped(path, file_type, + (byte *) source_data, + (byte *) source_data + source_size); + if (error != NULL) { + LOG("xosfile_save_stamped: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("SaveError", error->errmess); + return false; + } + } else { + /* Non-native type: export */ + switch (ro_content_native_type(h)) { + case osfile_TYPE_SPRITE: + { + unsigned flags = (os_version == 0xA9) ? + BITMAP_SAVE_FULL_ALPHA : 0; + riscos_bitmap_save(content_get_bitmap(h), path, flags); + } + break; + case osfile_TYPE_DRAW: + /* Must be SVG */ + return save_as_draw(h, path); + default: + return false; + } + } + + return true; +} + + +/** + * Save a link file. + * + * \param url url to be saved + * \param title corresponding title, if any + * \param format format of link file + * \param path pathname for link file + * \return true on success, false on failure and reports the error + */ + +bool ro_gui_save_link(const char *url, const char *title, link_format format, + char *path) +{ + FILE *fp = fopen(path, "w"); + + if (!fp) { + ro_warn_user("SaveError", strerror(errno)); + return false; + } + + switch (format) { + case LINK_ACORN: /* URI */ + fprintf(fp, "%s\t%s\n", "URI", "100"); + fprintf(fp, "\t# NetSurf %s\n\n", netsurf_version); + fprintf(fp, "\t%s\n", url); + if (title) + fprintf(fp, "\t%s\n", title); + else + fprintf(fp, "\t*\n"); + break; + case LINK_ANT: /* URL */ + case LINK_TEXT: /* Text */ + fprintf(fp, "%s\n", url); + break; + } + + fclose(fp); + + switch (format) { + case LINK_ACORN: /* URI */ + xosfile_set_type(path, 0xf91); + break; + case LINK_ANT: /* URL */ + xosfile_set_type(path, 0xb28); + break; + case LINK_TEXT: /* Text */ + xosfile_set_type(path, 0xfff); + break; + } + + return true; +} + + +/** + * Suggest a leafname and sprite name for the given content. + * + * \param h content being saved + * \param save_type type of save operation being performed + * \param url used to determine leafname + * \param leaf_buf buffer to receive suggested leafname. + * \param leaf_len size of buffer to receive suggested leafname. + * \param icon_buf buffer to receive sprite name. + * \param icon_len size of buffer to receive icon name. + */ + +void ro_gui_save_set_state(hlcache_handle *h, gui_save_type save_type, + const nsurl *url, char *leaf_buf, size_t leaf_len, + char *icon_buf, size_t icon_len) +{ + /* filename */ + const char *name = gui_save_table[save_type].name; + bool done = false; + char *nice = NULL; + nserror err; + char *local_name; + + assert(icon_len >= 13); + + /* parameters that we need to remember */ + gui_save_current_type = save_type; + gui_save_content = h; + + /* suggest a filetype based upon the content */ + gui_save_filetype = gui_save_table[save_type].filetype; + if (!gui_save_filetype && h) { + if (save_type == GUI_SAVE_OBJECT_NATIVE) { + switch (ro_content_native_type(h)) { + case osfile_TYPE_SPRITE: + gui_save_filetype = osfile_TYPE_SPRITE; + break; + case osfile_TYPE_DRAW: + gui_save_filetype = osfile_TYPE_DRAW; + break; + default: + break; + } + } + if (!gui_save_filetype) + gui_save_filetype = ro_content_filetype(h); + } + + /* leafname */ + if ((url != NULL) && + (nsurl_nice(url, &nice, nsoption_bool(strip_extensions)) == + NSERROR_OK)) { + size_t i; + for (i = 0; nice[i]; i++) { + if (nice[i] == '.') + nice[i] = '/'; + else if (nice[i] <= ' ' || + strchr(":*#$&@^%\\", nice[i])) + nice[i] = '_'; + } + name = nice; + } else { + name = messages_get(name); + } + + /* filename is utf8 */ + if (save_type == GUI_SAVE_COMPLETE && leaf_len > 0) { + leaf_buf[0] = '!'; + leaf_buf++; + leaf_len--; + } + strncpy(leaf_buf, name, leaf_len); + leaf_buf[leaf_len - 1] = 0; + + err = utf8_to_local_encoding(name, 0, &local_name); + if (err != NSERROR_OK) { + /* badenc should never happen */ + assert(err != NSERROR_BAD_ENCODING); + local_name = NULL; + } + + if (local_name != NULL) + name = local_name; + + /* sprite name used for icon and dragging */ + if (save_type == GUI_SAVE_COMPLETE) { + int index; + + /* Paint gets confused with uppercase characters and we need to + convert spaces to hard spaces */ + icon_buf[0] = '!'; + for (index = 0; index < 11 && name[index]; ) { + char ch = name[index]; + if (ch == ' ') + icon_buf[++index] = 0xa0; + else + icon_buf[++index] = tolower(ch); + } + memset(&icon_buf[index + 1], 0, 11 - index); + icon_buf[12] = '\0'; + + if (ro_gui_save_create_thumbnail(h, icon_buf)) + done = true; + } + + if (!done) { + osspriteop_header *sprite; + os_error *error; + + sprintf(icon_buf, "file_%.3x", gui_save_filetype); + + error = ro_gui_wimp_get_sprite(icon_buf, &sprite); + if (error && error->errnum == error_SPRITE_OP_DOESNT_EXIST) { + /* try the 'unknown' filetype sprite as a fallback */ + memcpy(icon_buf, "file_xxx", 9); + error = ro_gui_wimp_get_sprite(icon_buf, &sprite); + } + + if (error) { + LOG("ro_gui_wimp_get_sprite: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MiscError", error->errmess); + } else { + /* the sprite area should always be large enough for + * file_xxx sprites */ + assert(sprite->size <= saveas_area->size - + saveas_area->first); + + memcpy((byte*)saveas_area + saveas_area->first, + sprite, + sprite->size); + + saveas_area->sprite_count = 1; + saveas_area->used = saveas_area->first + sprite->size; + } + } + + free(local_name); + free(nice); +} + + + +/** + * Create a thumbnail sprite for the page being saved. + * + * \param h content to be converted + * \param name sprite name to use + * \return true iff successful + */ + +bool ro_gui_save_create_thumbnail(hlcache_handle *h, const char *name) +{ + osspriteop_header *sprite_header; + struct bitmap *bitmap; + osspriteop_area *area; + + bitmap = riscos_bitmap_create(34, 34, BITMAP_NEW | BITMAP_OPAQUE | BITMAP_CLEAR_MEMORY); + if (!bitmap) { + LOG("Thumbnail initialisation failed."); + return false; + } + riscos_bitmap_render(bitmap, h); + area = riscos_bitmap_convert_8bpp(bitmap); + riscos_bitmap_destroy(bitmap); + if (!area) { + LOG("Thumbnail conversion failed."); + return false; + } + + sprite_header = (osspriteop_header *)(area + 1); + strncpy(sprite_header->name, name, 12); + + + /* we can't resize the saveas sprite area because it may move and we have + no elegant way to update the window definition on all OS versions */ + assert(sprite_header->size <= saveas_area->size - saveas_area->first); + + memcpy((byte*)saveas_area + saveas_area->first, + sprite_header, sprite_header->size); + + saveas_area->sprite_count = 1; + saveas_area->used = saveas_area->first + sprite_header->size; + + free(area); + + return true; +} + + +/** + * User has opted not to overwrite the existing file. + */ + +void ro_gui_save_overwrite_cancelled(query_id id, enum query_response res, void *p) +{ + if (!saving_from_dialog) { +// ro_gui_save_prepare(gui_save_current_type, gui_save_content); +// ro_gui_dialog_open_persistent(g->window, dialog_saveas, true); + } +} + + +/** + * Overwrite of existing file confirmed, proceed with the save. + */ + +void ro_gui_save_overwrite_confirmed(query_id id, enum query_response res, void *p) +{ + if (ro_gui_save_content(gui_save_content, gui_save_message.data.data_xfer.file_name, true)) + ro_gui_save_done(); +} diff --git a/frontends/riscos/save.h b/frontends/riscos/save.h new file mode 100644 index 000000000..dba09a984 --- /dev/null +++ b/frontends/riscos/save.h @@ -0,0 +1,50 @@ +/* + * Copyright 2006 Adrian Lees <adrianl@users.sourceforge.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * File/object/selection saving (Interface). + */ + +#ifndef _NETSURF_RISCOS_SAVE_H_ +#define _NETSURF_RISCOS_SAVE_H_ + +#include <stdbool.h> +#include "oslib/wimp.h" + +enum gui_save_type; +struct nsurl; + +void gui_drag_save_object(struct gui_window *g, struct hlcache_handle *c, enum gui_save_type save_type); +void gui_drag_save_selection(struct gui_window *g, const char *selection); + +wimp_w ro_gui_saveas_create(const char *template_name); +void ro_gui_saveas_quit(void); +void ro_gui_save_prepare(enum gui_save_type save_type, struct hlcache_handle *h, + char *s, const struct nsurl *url, + const char *title); +void ro_gui_save_start_drag(wimp_pointer *pointer); +void ro_gui_drag_save_link(enum gui_save_type save_type, const struct nsurl *url, + const char *title, struct gui_window *g); +void ro_gui_drag_icon(int x, int y, const char *sprite); +void ro_gui_drag_box_cancel(void); +void ro_gui_send_datasave(enum gui_save_type save_type, wimp_full_message_data_xfer *message, wimp_t to); +void ro_gui_save_datasave_ack(wimp_message *message); +bool ro_gui_save_ok(wimp_w w); +void ro_gui_convert_save_path(char *dp, size_t len, const char *p); + +#endif diff --git a/frontends/riscos/save_draw.c b/frontends/riscos/save_draw.c new file mode 100644 index 000000000..50febf3b2 --- /dev/null +++ b/frontends/riscos/save_draw.c @@ -0,0 +1,474 @@ +/* + * Copyright 2004 John M Bell <jmb202@ecs.soton.ac.uk> + * Copyright 2004-2008 John Tytgat <joty@netsurf-browser.org> + * Copyright 2007 James Bursa <bursa@users.sourceforge.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Export a content as a DrawFile (implementation). + */ + +#ifdef WITH_DRAW_EXPORT + +#include <assert.h> +#include <limits.h> +#include <oslib/draw.h> +#include <oslib/osfile.h> +#include <pencil.h> + +#include "utils/log.h" +#include "utils/utils.h" +#include "content/content.h" +#include "content/hlcache.h" +#include "desktop/plotters.h" + +#include "riscos/bitmap.h" +#include "riscos/gui.h" +#include "riscos/save_draw.h" +#include "riscos/font.h" + +static bool ro_save_draw_rectangle(int x0, int y0, int x1, int y1, const plot_style_t *style); +static bool ro_save_draw_line(int x0, int y0, int x1, int y1, const plot_style_t *style); +static bool ro_save_draw_polygon(const int *p, unsigned int n, const plot_style_t *style); +static bool ro_save_draw_path(const float *p, unsigned int n, colour fill, + float width, colour c, const float transform[6]); +static bool ro_save_draw_clip(const struct rect *clip); +static bool ro_save_draw_text(int x, int y, const char *text, size_t length, + const plot_font_style_t *fstyle); +static bool ro_save_draw_disc(int x, int y, int radius, const plot_style_t *style); +static bool ro_save_draw_arc(int x, int y, int radius, int angle1, int angle2, + const plot_style_t *style); +static bool ro_save_draw_bitmap(int x, int y, int width, int height, + struct bitmap *bitmap, colour bg, bitmap_flags_t flags); +static bool ro_save_draw_group_start(const char *name); +static bool ro_save_draw_group_end(void); +static bool ro_save_draw_error(pencil_code code); + + +static const struct plotter_table ro_save_draw_plotters = { + .rectangle = ro_save_draw_rectangle, + .line = ro_save_draw_line, + .polygon = ro_save_draw_polygon, + .clip = ro_save_draw_clip, + .text = ro_save_draw_text, + .disc = ro_save_draw_disc, + .arc = ro_save_draw_arc, + .bitmap = ro_save_draw_bitmap, + .group_start = ro_save_draw_group_start, + .group_end = ro_save_draw_group_end, + .path = ro_save_draw_path, + .option_knockout = false, +}; + +static struct pencil_diagram *ro_save_draw_diagram; +static int ro_save_draw_width; +static int ro_save_draw_height; + + +/** + * Export a content as a DrawFile. + * + * \param h content to export + * \param path path to save DrawFile as + * \return true on success, false on error and error reported + */ + +bool save_as_draw(hlcache_handle *h, const char *path) +{ + pencil_code code; + char *drawfile_buffer; + struct rect clip; + struct content_redraw_data data; + size_t drawfile_size; + os_error *error; + struct redraw_context ctx = { + .interactive = false, + .background_images = true, + .plot = &ro_save_draw_plotters + }; + + ro_save_draw_diagram = pencil_create(); + if (!ro_save_draw_diagram) { + ro_warn_user("NoMemory", 0); + return false; + } + + ro_save_draw_width = content_get_width(h); + ro_save_draw_height = content_get_height(h); + + clip.x0 = clip.y0 = INT_MIN; + clip.x1 = clip.y1 = INT_MAX; + + data.x = 0; + data.y = -ro_save_draw_height; + data.width = ro_save_draw_width; + data.height = ro_save_draw_height; + data.background_colour = 0xFFFFFF; + data.scale = 1; + data.repeat_x = false; + data.repeat_y = false; + + if (!content_redraw(h, &data, &clip, &ctx)) { + pencil_free(ro_save_draw_diagram); + return false; + } + + /*pencil_dump(ro_save_draw_diagram);*/ + + code = pencil_save_drawfile(ro_save_draw_diagram, "NetSurf", + &drawfile_buffer, &drawfile_size); + if (code != pencil_OK) { + ro_warn_user("SaveError", 0); + pencil_free(ro_save_draw_diagram); + return false; + } + assert(drawfile_buffer); + + error = xosfile_save_stamped(path, osfile_TYPE_DRAW, + (byte *) drawfile_buffer, + (byte *) drawfile_buffer + drawfile_size); + if (error) { + LOG("xosfile_save_stamped failed: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("SaveError", error->errmess); + pencil_free(ro_save_draw_diagram); + return false; + } + + pencil_free(ro_save_draw_diagram); + + return true; +} + +bool ro_save_draw_rectangle(int x0, int y0, int x1, int y1, const plot_style_t *style) +{ + pencil_code code; + const int path[] = { draw_MOVE_TO, x0 * 2, -y0 * 2 - 1, + draw_LINE_TO, x1 * 2, -y0 * 2 - 1, + draw_LINE_TO, x1 * 2, -y1 * 2 - 1, + draw_LINE_TO, x0 * 2, -y1 * 2 - 1, + draw_CLOSE_LINE, + draw_END_PATH }; + + if (style->fill_type != PLOT_OP_TYPE_NONE) { + + code = pencil_path(ro_save_draw_diagram, + path, + sizeof path / sizeof path[0], + style->fill_colour << 8, + pencil_TRANSPARENT, + 0, + pencil_JOIN_MITRED, + pencil_CAP_BUTT, + pencil_CAP_BUTT, + 0, + 0, + false, + pencil_SOLID); + if (code != pencil_OK) + return ro_save_draw_error(code); + } + + if (style->stroke_type != PLOT_OP_TYPE_NONE) { + + code = pencil_path(ro_save_draw_diagram, + path, + sizeof path / sizeof path[0], + pencil_TRANSPARENT, + style->stroke_colour << 8, + style->stroke_width, + pencil_JOIN_MITRED, + pencil_CAP_BUTT, + pencil_CAP_BUTT, + 0, + 0, + false, + pencil_SOLID); + + if (code != pencil_OK) + return ro_save_draw_error(code); + } + return true; +} + + +bool ro_save_draw_line(int x0, int y0, int x1, int y1, const plot_style_t *style) +{ + pencil_code code; + const int path[] = { draw_MOVE_TO, x0 * 2, -y0 * 2 - 1, + draw_LINE_TO, x1 * 2, -y1 * 2 - 1, + draw_END_PATH }; + + code = pencil_path(ro_save_draw_diagram, + path, + sizeof path / sizeof path[0], + pencil_TRANSPARENT, + style->stroke_colour << 8, + style->stroke_width, + pencil_JOIN_MITRED, + pencil_CAP_BUTT, + pencil_CAP_BUTT, + 0, 0, false, + pencil_SOLID); + if (code != pencil_OK) + return ro_save_draw_error(code); + + return true; +} + + +bool ro_save_draw_polygon(const int *p, unsigned int n, const plot_style_t *style) +{ + pencil_code code; + int path[n * 3 + 1]; + unsigned int i; + + for (i = 0; i != n; i++) { + path[i * 3 + 0] = draw_LINE_TO; + path[i * 3 + 1] = p[i * 2 + 0] * 2; + path[i * 3 + 2] = -p[i * 2 + 1] * 2; + } + path[0] = draw_MOVE_TO; + path[n * 3] = draw_END_PATH; + + code = pencil_path(ro_save_draw_diagram, + path, n * 3 + 1, + style->fill_colour << 8, + pencil_TRANSPARENT, + 0, + pencil_JOIN_MITRED, + pencil_CAP_BUTT, + pencil_CAP_BUTT, + 0, + 0, + false, + pencil_SOLID); + if (code != pencil_OK) + return ro_save_draw_error(code); + + return true; +} + + +bool ro_save_draw_path(const float *p, unsigned int n, colour fill, + float width, colour c, const float transform[6]) +{ + if (n == 0) + return true; + + if (p[0] != PLOTTER_PATH_MOVE) { + LOG("path doesn't start with a move"); + return false; + } + + int *path = malloc(sizeof *path * (n + 10)); + if (!path) { + LOG("out of memory"); + return false; + } + + unsigned int i; + bool empty_path = true; + for (i = 0; i < n; ) { + if (p[i] == PLOTTER_PATH_MOVE) { + path[i] = draw_MOVE_TO; + path[i + 1] = (transform[0] * p[i + 1] + + transform[2] * -p[i + 2] + + transform[4]) * 2; + path[i + 2] = (transform[1] * p[i + 1] + + transform[3] * -p[i + 2] + + -transform[5]) * 2; + i += 3; + } else if (p[i] == PLOTTER_PATH_CLOSE) { + path[i] = draw_CLOSE_LINE; + i++; + } else if (p[i] == PLOTTER_PATH_LINE) { + path[i] = draw_LINE_TO; + path[i + 1] = (transform[0] * p[i + 1] + + transform[2] * -p[i + 2] + + transform[4]) * 2; + path[i + 2] = (transform[1] * p[i + 1] + + transform[3] * -p[i + 2] + + -transform[5]) * 2; + i += 3; + empty_path = false; + } else if (p[i] == PLOTTER_PATH_BEZIER) { + path[i] = draw_BEZIER_TO; + path[i + 1] = (transform[0] * p[i + 1] + + transform[2] * -p[i + 2] + + transform[4]) * 2; + path[i + 2] = (transform[1] * p[i + 1] + + transform[3] * -p[i + 2] + + -transform[5]) * 2; + path[i + 3] = (transform[0] * p[i + 3] + + transform[2] * -p[i + 4] + + transform[4]) * 2; + path[i + 4] = (transform[1] * p[i + 3] + + transform[3] * -p[i + 4] + + -transform[5]) * 2; + path[i + 5] = (transform[0] * p[i + 5] + + transform[2] * -p[i + 6] + + transform[4]) * 2; + path[i + 6] = (transform[1] * p[i + 5] + + transform[3] * -p[i + 6] + + -transform[5]) * 2; + i += 7; + empty_path = false; + } else { + LOG("bad path command %f", p[i]); + free(path); + return false; + } + } + path[i] = draw_END_PATH; + + if (empty_path) { + free(path); + return true; + } + + pencil_code code = pencil_path(ro_save_draw_diagram, path, i + 1, + fill == NS_TRANSPARENT ? pencil_TRANSPARENT : fill << 8, + c == NS_TRANSPARENT ? pencil_TRANSPARENT : c << 8, + width, pencil_JOIN_MITRED, + pencil_CAP_BUTT, pencil_CAP_BUTT, 0, 0, false, + pencil_SOLID); + free(path); + if (code != pencil_OK) + return ro_save_draw_error(code); + + return true; +} + + + + +bool ro_save_draw_clip(const struct rect *clip) +{ + return true; +} + + +bool ro_save_draw_text(int x, int y, const char *text, size_t length, + const plot_font_style_t *fstyle) +{ + pencil_code code; + const char *font_family; + unsigned int font_size; + rufl_style font_style; + + nsfont_read_style(fstyle, &font_family, &font_size, &font_style); + + code = pencil_text(ro_save_draw_diagram, x * 2, -y * 2, font_family, + font_style, font_size, text, length, + fstyle->foreground << 8); + if (code != pencil_OK) + return ro_save_draw_error(code); + + return true; +} + + +bool ro_save_draw_disc(int x, int y, int radius, const plot_style_t *style) +{ + return true; +} + +bool ro_save_draw_arc(int x, int y, int radius, int angle1, int angle2, + const plot_style_t *style) +{ + return true; +} + +bool ro_save_draw_bitmap(int x, int y, int width, int height, + struct bitmap *bitmap, colour bg, bitmap_flags_t flags) +{ + pencil_code code; + const uint8_t *buffer; + + buffer = riscos_bitmap_get_buffer(bitmap); + if (!buffer) { + ro_warn_user("NoMemory", 0); + return false; + } + + code = pencil_sprite(ro_save_draw_diagram, x * 2, (-y - height) * 2, + width * 2, height * 2, + ((char *) bitmap->sprite_area) + + bitmap->sprite_area->first); + if (code != pencil_OK) + return ro_save_draw_error(code); + + return true; +} + + +bool ro_save_draw_group_start(const char *name) +{ + pencil_code code; + + code = pencil_group_start(ro_save_draw_diagram, name); + if (code != pencil_OK) + return ro_save_draw_error(code); + + return true; +} + + +bool ro_save_draw_group_end(void) +{ + pencil_code code; + + code = pencil_group_end(ro_save_draw_diagram); + if (code != pencil_OK) + return ro_save_draw_error(code); + + return true; +} + + +/** + * Report an error from pencil. + * + * \param code error code + * \return false + */ + +bool ro_save_draw_error(pencil_code code) +{ + LOG("code %i", code); + + switch (code) { + case pencil_OK: + assert(0); + break; + case pencil_OUT_OF_MEMORY: + ro_warn_user("NoMemory", 0); + break; + case pencil_FONT_MANAGER_ERROR: + ro_warn_user("SaveError", rufl_fm_error->errmess); + break; + case pencil_FONT_NOT_FOUND: + case pencil_IO_ERROR: + case pencil_IO_EOF: + ro_warn_user("SaveError", "generating the DrawFile failed"); + break; + } + + return false; +} + +#endif diff --git a/frontends/riscos/save_draw.h b/frontends/riscos/save_draw.h new file mode 100644 index 000000000..7ae447790 --- /dev/null +++ b/frontends/riscos/save_draw.h @@ -0,0 +1,31 @@ +/* + * Copyright 2004 John M Bell <jmb202@ecs.soton.ac.uk> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _NETSURF_RISCOS_SAVE_DRAW_H_ +#define _NETSURF_RISCOS_SAVE_DRAW_H_ + +#ifdef WITH_DRAW_EXPORT + +#include <stdbool.h> +struct hlcache_handle; + +bool save_as_draw(struct hlcache_handle *h, const char *path); + +#endif + +#endif diff --git a/frontends/riscos/save_pdf.c b/frontends/riscos/save_pdf.c new file mode 100644 index 000000000..3d6395629 --- /dev/null +++ b/frontends/riscos/save_pdf.c @@ -0,0 +1,60 @@ +/* + * Copyright 2008 John Tytgat <joty@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Export a content as a PDF file (implementation). + */ + +#include "utils/config.h" +#ifdef WITH_PDF_EXPORT + +#include <stdbool.h> +#include "oslib/osfile.h" +#include "content/content.h" +#include "content/hlcache.h" +#include "desktop/print.h" +#include "desktop/save_pdf/font_haru.h" +#include "desktop/save_pdf/pdf_plotters.h" +#include "riscos/save_pdf.h" +#include "utils/log.h" +#include "utils/config.h" + +/** + * Export a content as a PDF file. + * + * \param h content to export + * \param path path to save PDF as + * \return true on success, false on error and error reported + */ +bool save_as_pdf(hlcache_handle *h, const char *path) +{ + struct print_settings *psettings; + + psettings = print_make_settings(PRINT_DEFAULT, path, &haru_nsfont); + if (psettings == NULL) + return false; + + if (!print_basic_run(h, &pdf_printer, psettings)) + return false; + + xosfile_set_type(path, 0xadf); + + return true; +} + +#endif diff --git a/frontends/riscos/save_pdf.h b/frontends/riscos/save_pdf.h new file mode 100644 index 000000000..ad4599dea --- /dev/null +++ b/frontends/riscos/save_pdf.h @@ -0,0 +1,31 @@ +/* + * Copyright 2008 John Tytgat <joty@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _NETSURF_RISCOS_SAVE_PDF_H_ +#define _NETSURF_RISCOS_SAVE_PDF_H_ + +#include "utils/config.h" +#ifdef WITH_PDF_EXPORT + +struct hlcache_handle; + +bool save_as_pdf(struct hlcache_handle *h, const char *path); + +#endif /* WITH_PDF_EXPORT */ + +#endif diff --git a/frontends/riscos/schedule.c b/frontends/riscos/schedule.c new file mode 100644 index 000000000..54308b7a9 --- /dev/null +++ b/frontends/riscos/schedule.c @@ -0,0 +1,163 @@ +/* + * Copyright 2004 James Bursa <bursa@users.sourceforge.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Scheduled callback queue (implementation). + * + * The queue is simply implemented as a linked list. + */ + +#include <stdbool.h> +#include <stdlib.h> + +#include "oslib/os.h" +#include "utils/log.h" + +#include "riscos/gui.h" + + +/** Entry in the queue of scheduled callbacks. */ +struct sched_entry { + /** Preferred time for callback. */ + os_t time; + /** Function to call at the specified time. */ + void (*callback)(void *p); + /** User parameter for callback. */ + void *p; + /** Next (later) entry in queue. */ + struct sched_entry *next; +}; + +/** Queue of scheduled callbacks (sentinel at head). */ +static struct sched_entry sched_queue = { 0, 0, 0, 0 }; + +/** Items have been scheduled. */ +bool sched_active = false; +/** Time of soonest scheduled event (valid only if sched_active is true). */ +os_t sched_time; + +/** + * Unschedule a callback. + * + * \param callback callback function + * \param p user parameter, passed to callback function + * + * All scheduled callbacks matching both callback and p are removed. + */ + +static nserror schedule_remove(void (*callback)(void *p), void *p) +{ + struct sched_entry *entry, *prev; + + prev = &sched_queue; + + for (entry = prev->next; entry; entry = prev->next) { + if (entry->callback != callback || entry->p != p) { + prev = entry; + continue; + } + + prev->next = entry->next; + free(entry); + + /* There can only ever be one match, and we've found it */ + break; + } + + if (sched_queue.next) { + sched_active = true; + sched_time = sched_queue.next->time; + } else { + sched_active = false; + } + + return NSERROR_OK; +} + +/* exported function documented in riscos/gui.h */ +nserror riscos_schedule(int t, void (*callback)(void *p), void *p) +{ + struct sched_entry *entry; + struct sched_entry *queue; + os_t time; + nserror ret; + + ret = schedule_remove(callback, p); + if ((t < 0) || (ret != NSERROR_OK)) { + return ret; + } + + t = t / 10; /* convert to centiseconds */ + + time = os_read_monotonic_time() + t; + + entry = malloc(sizeof *entry); + if (!entry) { + LOG("malloc failed"); + return NSERROR_NOMEM; + } + + entry->time = time; + entry->callback = callback; + entry->p = p; + + for (queue = &sched_queue; + queue->next && queue->next->time <= time; + queue = queue->next) + ; + entry->next = queue->next; + queue->next = entry; + + sched_active = true; + sched_time = sched_queue.next->time; + + return NSERROR_OK; +} + + +/* exported function documented in riscos/gui.h */ +bool schedule_run(void) +{ + struct sched_entry *entry; + os_t now; + + now = os_read_monotonic_time(); + + while (sched_queue.next && sched_queue.next->time <= now) { + void (*callback)(void *p); + void *p; + + entry = sched_queue.next; + callback = entry->callback; + p = entry->p; + sched_queue.next = entry->next; + free(entry); + /* The callback may call riscos_schedule(), so leave + * the queue in a safe state. + */ + callback(p); + } + + if (sched_queue.next) { + sched_active = true; + sched_time = sched_queue.next->time; + } else + sched_active = false; + + return sched_active; +} diff --git a/frontends/riscos/scripts/Help b/frontends/riscos/scripts/Help new file mode 100644 index 000000000..9116926a3 --- /dev/null +++ b/frontends/riscos/scripts/Help @@ -0,0 +1,12 @@ +| Help file for NetSurf. ( $Revision$ ) + +| Set system variables and application sprites +Set NetSurf$ForceVars 1 +/<Obey$Dir>.!Boot +UnSet NetSurf$ForceVars + +| Resource Locations +SetMacro NetSurf$Path Choices:WWW.NetSurf.,<NetSurf$Dir>. + +WimpSlot -min 8k -max 8k +Run <NetSurf$Dir>.OpenHelp diff --git a/frontends/riscos/scripts/Run b/frontends/riscos/scripts/Run new file mode 100644 index 000000000..4a51d7838 --- /dev/null +++ b/frontends/riscos/scripts/Run @@ -0,0 +1,109 @@ +| Run file for NetSurf. +| +| This file ensures that the system resources required by NetSurf are +| present. Additionally, it forces setting of system variables related +| to NetSurf. + +| Set system variables and application sprites +Set NetSurf$ForceVars 1 +/<Obey$Dir>.!Boot +UnSet NetSurf$ForceVars + +| Configure logging. Set 1 to enable, or 0 to suppress. +Set NetSurf$Logging 1 + +| Detect if NetSurf is already running and, if so, force the +| current instance to open a new window. Then stop this script. +Set Alias$NetSurfRunning UnSet Alias$NetSurfRunning|mUnSet NetSurf$Running|mObey +Set NetSurf$Running 0 +WimpSlot -min 64k -max 64k +/<NetSurf$Dir>.KickNS +| If not running, then unset system variables and continue +If "<NetSurf$Running>" = "0" Then Set Alias$NetSurfRunning UnSet Alias$NetSurfRunning|mUnSet NetSurf$Running +| Invoke our alias to clean up +NetSurfRunning + +| Resource Locations +| The following are read-only locations +SetMacro NetSurf$Path Choices:WWW.NetSurf.,<NetSurf$Dir>. +| The following are write-only locations +SetMacro NetSurf$ChoicesSave <Choices$Write>.WWW.NetSurf.Choices + +| We need RISC OS 3 +RMEnsure UtilityModule 3.00 Error NetSurf needs RISC OS 3 or later + +| Ensure Nested WIMP is installed +| http://acorn.riscos.com/ (in the universal boot archive) +RMEnsure WindowManager 3.80 Error NetSurf requires the Nested Window Manager. This can be obtained by downloading the Universal Boot sequence from http://acorn.riscos.com/ + +| Check for various key resources - can't do much if they don't exist +If "<System$Path>" = "" Then Set System$Path_Message System resources not found. +If "<Wimp$ScrapDir>" = "" Then Error Scrap resource not found. +If "<InetDBase$Path>" = "" Then Error Internet resources can not be found +If "<Unicode$Path>" = "" Then Error NetSurf requires the !Unicode resource. This can be found, along with the Iconv module, at http://www.netsurf-browser.org/projects/iconv/ +If "<Inet$MimeMappings>" = "" Then Set Inet$MimeMappings InetDBase:MimeMap + +| Define this alias for clarity +| Syntax: NetSurfRMLoad <Path to module> +Set Alias$NetSurfRMLoad IfThere %%*0 Then RMLoad %%*0 + +| Ensure a 32bit SharedCLibrary is installed +| (5.17 == first 32bit SCL, 5.43 == C99 features) +RMEnsure SharedCLibrary 5.17 NetSurfRMLoad System:Modules.CLib +RMEnsure SharedCLibrary 5.43 Error NetSurf requires SharedCLibrary 5.43 or later. This can be downloaded from https://www.riscosopen.org/content/downloads/common + +| Ensure CallASWI is installed +RMEnsure UtilityModule 3.70 RMEnsure CallASWI 0.02 NetSurfRMLoad System:Modules.CallASWI +RMEnsure UtilityModule 3.70 RMEnsure CallASWI 0.02 Error NetSurf requires the CallASWI module. This can be downloaded from https://www.riscosopen.org/content/downloads/common + +| Ensure DrawFile module is installed +| Should be installed in !System.310.Modules +RMEnsure DrawFile 1.30 NetSurfRMLoad System:Modules.DrawFile +RMEnsure DrawFile 1.30 Error NetSurf requires the DrawFile module. This can be downloaded from https://www.riscosopen.org/content/downloads/common + +| Ensure SharedUnixLibrary is installed +RMEnsure SharedUnixLibrary 1.07 NetSurfRMLoad System:Modules.SharedULib +RMEnsure SharedUnixLibrary 1.07 Error NetSurf requires SharedUnixLibrary 1.07 or later. Please use the RISC OS Configure app to update the computer's !System directory from the NetSurf archive. + +| Load AcornURI if it isn't already +Unset NetSurf$Start_URI_Handler +RMEnsure AcornURI 0.12 Set NetSurf$Start_URI_Handler 1 +RMEnsure AcornURI 0.12 NetSurfRMLoad System:Modules.Network.URI +RMEnsure AcornURI 0.12 Error NetSurf requires AcornURI 0.12 or later. Please use the RISC OS Configure app to update the computer's !System directory from the NetSurf archive. +RMEnsure AcornURI 0.12 Unset NetSurf$Start_URI_Handler + +| Check for mime map module +RMEnsure MimeMap 0.10 NetSurfRMLoad System:Modules.Network.MimeMap +RMEnsure MimeMap 0.10 Error NetSurf requires MimeMap 0.10 or later + +| Ensure Tinct is loaded +RMEnsure Tinct 0.13 NetSurfRMLoad System:Modules.Tinct +RMEnsure Tinct 0.13 Error NetSurf requires Tinct 0.13 or later. Please use the RISC OS Configure app to update the computer's !System directory from the NetSurf archive. + +| Ensure Iconv +RMEnsure Iconv 0.12 NetSurfRMLoad System:Modules.Iconv +RMEnsure Iconv 0.12 Error NetSurf requires Iconv 0.12 or later. Please use the RISC OS Configure app to update the computer's !System directory from the NetSurf archive. + +| Ensure CryptRandom +RMEnsure CryptRandom 0.13 NetSurfRMLoad System:Modules.CryptRand +RMEnsure CryptRandom 0.13 Error NetSurf requires CryptRandom 0.13 or later. Please use the RISC OS Configure app to update the computer's !System directory from the NetSurf archive. + +| Disable SpecialFX, if present +Set NetSurf$SpecialFX 1 +RMEnsure SpecialFX 1.00 Set NetSurf$SpecialFX 0 +If <NetSurf$SpecialFX> Then SpecialFX ~B~G~L NetSurf +Unset NetSurf$SpecialFX + +| No longer need this alias +Unset Alias$NetSurfRMLoad + +| Now attempt to create Scrap directories +CDir <Wimp$ScrapDir>.WWW +CDir <Wimp$ScrapDir>.WWW.NetSurf + +| Install NetSurf-specific fonts +| NB: trailing dot is required +FontInstall NetSurf:Resources.Fonts. + +WIMPSLOT +Run <NetSurf$Dir>.!RunImage %*0 2><Wimp$ScrapDir>.WWW.NetSurf.Log diff --git a/frontends/riscos/search.c b/frontends/riscos/search.c new file mode 100644 index 000000000..989c9aa9e --- /dev/null +++ b/frontends/riscos/search.c @@ -0,0 +1,475 @@ +/* + * Copyright 2004 John M Bell <jmb202@ecs.soton.ac.uk> + * Copyright 2005 Adrian Lees <adrianl@users.sourceforge.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * \file + * Free text search implementation + */ + +#include "utils/config.h" + +#include <ctype.h> +#include <string.h> +#include "oslib/hourglass.h" +#include "oslib/wimp.h" + +#include "utils/log.h" +#include "utils/messages.h" +#include "content/content.h" +#include "content/hlcache.h" +#include "desktop/browser.h" +#include "desktop/gui_search.h" +#include "desktop/browser.h" +#include "desktop/search.h" + +#include "riscos/gui.h" +#include "riscos/dialog.h" +#include "riscos/menus.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" + +#define RECENT_SEARCHES 8 + +struct search_static_data { + char *recent_searches[RECENT_SEARCHES]; + bool search_insert; + struct browser_window *search_window; +}; + +static struct search_static_data search_data = + { { NULL }, false, NULL }; + +static wimp_MENU(RECENT_SEARCHES) menu_recent; +wimp_menu *recent_search_menu = (wimp_menu *)&menu_recent; +#define DEFAULT_FLAGS (wimp_ICON_TEXT | wimp_ICON_FILLED | \ + (wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT) | \ + (wimp_COLOUR_WHITE << wimp_ICON_BG_COLOUR_SHIFT)) + + +static void ro_gui_search_end(wimp_w w); +static bool ro_gui_search_next(wimp_w w); +static bool ro_gui_search_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_pointer *pointer); +static bool ro_gui_search_prepare_menu(void); +static bool ro_gui_search_click(wimp_pointer *pointer); +static bool ro_gui_search_keypress(wimp_key *key); +static search_flags_t ro_gui_search_update_flags(void); +static void ro_gui_search_set_forward_state(bool active, void *p); +static void ro_gui_search_set_back_state(bool active, void *p); +static void ro_gui_search_set_status(bool found, void *p); +static void ro_gui_search_set_hourglass(bool active, void *p); +static void ro_gui_search_add_recent(const char *string, void *p); + +static struct gui_search_table search_table = { + ro_gui_search_set_status, + ro_gui_search_set_hourglass, + ro_gui_search_add_recent, + ro_gui_search_set_forward_state, + ro_gui_search_set_back_state, +}; + +struct gui_search_table *riscos_search_table = &search_table; + +void ro_gui_search_init(void) +{ + dialog_search = ro_gui_dialog_create("search"); + ro_gui_wimp_event_register_keypress(dialog_search, + ro_gui_search_keypress); + ro_gui_wimp_event_register_close_window(dialog_search, + ro_gui_search_end); + ro_gui_wimp_event_register_menu_prepare(dialog_search, + ro_gui_search_menu_prepare); + ro_gui_wimp_event_register_menu_gright(dialog_search, + ICON_SEARCH_TEXT, ICON_SEARCH_MENU, + recent_search_menu); + ro_gui_wimp_event_register_text_field(dialog_search, + ICON_SEARCH_STATUS); + ro_gui_wimp_event_register_checkbox(dialog_search, + ICON_SEARCH_CASE_SENSITIVE); + ro_gui_wimp_event_register_mouse_click(dialog_search, + ro_gui_search_click); + ro_gui_wimp_event_register_ok(dialog_search, ICON_SEARCH_FIND_NEXT, + ro_gui_search_next); + ro_gui_wimp_event_register_cancel(dialog_search, ICON_SEARCH_CANCEL); + ro_gui_wimp_event_set_help_prefix(dialog_search, "HelpSearch"); + + recent_search_menu->title_data.indirected_text.text = + (char*)messages_get("Search"); + ro_gui_menu_init_structure(recent_search_menu, RECENT_SEARCHES); +} + +/** + * Wrapper for the pressing of an OK button for wimp_event. + * + * \return false, to indicate the window should not be closed + */ +bool ro_gui_search_next(wimp_w w) +{ + search_data.search_insert = true; + search_flags_t flags = SEARCH_FLAG_FORWARDS | + ro_gui_search_update_flags(); + browser_window_search(search_data.search_window, NULL, flags, + ro_gui_get_icon_string(dialog_search, + ICON_SEARCH_TEXT)); + return false; +} + + +/** + * Callback to prepare menus in the Search dialog. At present, this + * only has to handle the previous search pop-up. + * + * \param w The window handle owning the menu. + * \param i The icon handle owning the menu. + * \param *menu The menu to be prepared. + * \param *pointer The associated mouse click event block, or NULL + * on an Adjust-click re-opening. + * \return true if the event was handled; false if not. + */ + +bool ro_gui_search_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_pointer *pointer) +{ + if (menu != recent_search_menu || i != ICON_SEARCH_MENU) + return false; + + if (pointer != NULL) + return ro_gui_search_prepare_menu(); + + return true; +} + + +bool ro_gui_search_click(wimp_pointer *pointer) +{ + search_flags_t flags; + switch (pointer->i) { + case ICON_SEARCH_FIND_PREV: + search_data.search_insert = true; + flags = ~SEARCH_FLAG_FORWARDS & + ro_gui_search_update_flags(); + browser_window_search(search_data.search_window, NULL, + flags, + ro_gui_get_icon_string(dialog_search, + ICON_SEARCH_TEXT)); + return true; + case ICON_SEARCH_CASE_SENSITIVE: + flags = SEARCH_FLAG_FORWARDS | + ro_gui_search_update_flags(); + browser_window_search_clear( + search_data.search_window); + browser_window_search(search_data.search_window, NULL, + flags, + ro_gui_get_icon_string(dialog_search, + ICON_SEARCH_TEXT)); + return true; + case ICON_SEARCH_SHOW_ALL: + flags = ro_gui_get_icon_selected_state( + pointer->w, pointer->i) ? + SEARCH_FLAG_SHOWALL : SEARCH_FLAG_NONE; + browser_window_search(search_data.search_window, NULL, + flags, + ro_gui_get_icon_string(dialog_search, + ICON_SEARCH_TEXT)); + return true; + } + return false; +} + +/** + * add search string to recent searches list + * + * front is at liberty how to implement the bare notification + * should normally store a strdup() of the string in + * search_global_data.recent[]; + * core gives no guarantee of the integrity of the const char * + * + * \param search string search pattern + * \param p the pointer sent to search_verify_new() + */ + +void ro_gui_search_add_recent(const char *search, void *p) +{ + char *tmp; + int i; + + if ((search == NULL) || (search[0] == '\0')) + return; + + if (!search_data.search_insert) { + free(search_data.recent_searches[0]); + search_data.recent_searches[0] = strdup(search); + ro_gui_search_prepare_menu(); + return; + } + + if ((search_data.recent_searches[0] != NULL) && + (!strcmp(search_data.recent_searches[0], search))) + return; + + tmp = strdup(search); + if (!tmp) { + ro_warn_user("NoMemory", 0); + return; + } + free(search_data.recent_searches[RECENT_SEARCHES - 1]); + for (i = RECENT_SEARCHES - 1; i > 0; i--) + search_data.recent_searches[i] = search_data.recent_searches[i - 1]; + search_data.recent_searches[0] = tmp; + search_data.search_insert = false; + + ro_gui_set_icon_shaded_state(dialog_search, ICON_SEARCH_MENU, false); + ro_gui_search_prepare_menu(); +} + +bool ro_gui_search_prepare_menu(void) +{ + int i; + int suggestions = 0; + + for (i = 0; i < RECENT_SEARCHES; i++) + if (search_data.recent_searches[i] != NULL) + suggestions++; + + if (suggestions == 0) + return false; + + for (i = 0; i < suggestions; i++) { + recent_search_menu->entries[i].menu_flags &= ~wimp_MENU_LAST; + recent_search_menu->entries[i].data.indirected_text.text = + search_data.recent_searches[i]; + recent_search_menu->entries[i].data.indirected_text.size = + strlen(search_data.recent_searches[i]) + 1; + } + recent_search_menu->entries[suggestions - 1].menu_flags |= + wimp_MENU_LAST; + + return true; +} + +/** + * Determine of the browser window is searchable. + * + * \param bw The browser window to check. + */ +static bool ro_gui_search_bw_searchable(struct browser_window *bw) +{ + hlcache_handle *h; + + assert(bw != NULL); + + h = browser_window_get_content(bw); + + /* only handle html/textplain contents */ + /** \todo Should have content_is_searchable() api */ + if ((!h) || (content_get_type(h) != CONTENT_HTML && + content_get_type(h) != CONTENT_TEXTPLAIN)) + return false; + + return true; +} + + +/** + * Open the search dialog + * + * \param bw the browser window to search + */ +void ro_gui_search_prepare(struct browser_window *bw) +{ + /* only handle searchable contents */ + if (!ro_gui_search_bw_searchable(bw)) + return; + + /* if the search dialogue is reopened over a new window, we may + need to cancel the previous search */ + ro_gui_search_set_forward_state(true, bw); + ro_gui_search_set_back_state(true, bw); + + search_data.search_window = bw; + + ro_gui_set_icon_string(dialog_search, ICON_SEARCH_TEXT, "", true); + ro_gui_set_icon_selected_state(dialog_search, + ICON_SEARCH_CASE_SENSITIVE, false); + ro_gui_set_icon_selected_state(dialog_search, + ICON_SEARCH_SHOW_ALL, false); + + ro_gui_search_set_status(true, NULL); + + ro_gui_wimp_event_memorise(dialog_search); + search_data.search_insert = true; +} + +/** + * Handle keypresses in the search dialog + * + * \param key wimp_key block + * \return true if keypress handled, false otherwise + */ +bool ro_gui_search_keypress(wimp_key *key) +{ + bool state; + search_flags_t flags; + + switch (key->c) { + case 1: { + flags = ro_gui_search_update_flags() + ^ SEARCH_FLAG_SHOWALL; + browser_window_search(search_data.search_window, NULL, + flags, + ro_gui_get_icon_string(dialog_search, + ICON_SEARCH_TEXT)); + } + break; + case 9: /* ctrl i */ + state = ro_gui_get_icon_selected_state(dialog_search, + ICON_SEARCH_CASE_SENSITIVE); + ro_gui_set_icon_selected_state(dialog_search, + ICON_SEARCH_CASE_SENSITIVE, !state); + flags = SEARCH_FLAG_FORWARDS | + ro_gui_search_update_flags(); + browser_window_search(search_data.search_window, NULL, + flags, + ro_gui_get_icon_string(dialog_search, + ICON_SEARCH_TEXT)); + return true; + case IS_WIMP_KEY | wimp_KEY_UP: + search_data.search_insert = true; + flags = ~SEARCH_FLAG_FORWARDS & + ro_gui_search_update_flags(); + browser_window_search(search_data.search_window, NULL, + flags, + ro_gui_get_icon_string(dialog_search, + ICON_SEARCH_TEXT)); + return true; + case IS_WIMP_KEY | wimp_KEY_DOWN: + search_data.search_insert = true; + flags = SEARCH_FLAG_FORWARDS | + ro_gui_search_update_flags(); + browser_window_search(search_data.search_window, NULL, + flags, + ro_gui_get_icon_string(dialog_search, + ICON_SEARCH_TEXT)); + return true; + + default: + if (key->c == 21) { + /* ctrl+u means the user's starting + * a new search */ + browser_window_search_clear( + search_data.search_window); + search_data.search_insert = true; + } + if (key->c == 8 || /* backspace */ + key->c == 21 || /* ctrl u */ + (key->c >= 0x20 && key->c <= 0x7f)) { + flags = SEARCH_FLAG_FORWARDS | + ro_gui_search_update_flags(); + ro_gui_search_set_forward_state(true, + search_data.search_window); + ro_gui_search_set_back_state(true, + search_data.search_window); + browser_window_search(search_data.search_window, + NULL, + flags, + ro_gui_get_icon_string( + dialog_search, + ICON_SEARCH_TEXT)); + return true; + } + break; + } + + return false; +} + +/** + * Ends the search + * \param w the search window handle (not used) + */ +void ro_gui_search_end(wimp_w w) +{ + browser_window_search_clear(search_data.search_window); +} + +/** +* Change the displayed search status. +* \param found search pattern matched in text +* \param p the pointer sent to search_verify_new() / search_create_context() +*/ + +void ro_gui_search_set_status(bool found, void *p) +{ + ro_gui_set_icon_string(dialog_search, ICON_SEARCH_STATUS, found ? "" : + messages_get("NotFound"), true); +} + +/** +* display hourglass while searching +* \param active start/stop indicator +* \param p the pointer sent to search_verify_new() / search_create_context() +*/ + +void ro_gui_search_set_hourglass(bool active, void *p) +{ + if (active) + xhourglass_on(); + + else + xhourglass_off(); +} + +/** +* activate search forwards button in gui +* \param active activate/inactivate +* \param p the pointer sent to search_verify_new() / search_create_context() +*/ + +void ro_gui_search_set_forward_state(bool active, void *p) +{ + ro_gui_set_icon_shaded_state(dialog_search, ICON_SEARCH_FIND_NEXT, + !active); +} + +/** +* activate search forwards button in gui +* \param active activate/inactivate +* \param p the pointer sent to search_verify_new() / search_create_context() +*/ + +void ro_gui_search_set_back_state(bool active, void *p) +{ + ro_gui_set_icon_shaded_state(dialog_search, ICON_SEARCH_FIND_PREV, + !active); +} + +/** +* retrieve state of 'case sensitive', 'show all' checks in gui +*/ +search_flags_t ro_gui_search_update_flags(void) +{ + search_flags_t flags; + flags = 0 | (ro_gui_get_icon_selected_state(dialog_search, + ICON_SEARCH_CASE_SENSITIVE) ? + SEARCH_FLAG_CASE_SENSITIVE : 0) | + (ro_gui_get_icon_selected_state(dialog_search, + ICON_SEARCH_SHOW_ALL) ? SEARCH_FLAG_SHOWALL : 0); + return flags; +} + diff --git a/frontends/riscos/searchweb.c b/frontends/riscos/searchweb.c new file mode 100644 index 000000000..14246d228 --- /dev/null +++ b/frontends/riscos/searchweb.c @@ -0,0 +1,18 @@ +/* + * Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + diff --git a/frontends/riscos/sslcert.c b/frontends/riscos/sslcert.c new file mode 100644 index 000000000..9e43f2db1 --- /dev/null +++ b/frontends/riscos/sslcert.c @@ -0,0 +1,348 @@ +/* + * Copyright 2006 John M Bell <jmb202@ecs.soton.ac.uk> + * Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * SSL Certificate verification UI (implementation) + */ + +#include "utils/config.h" + +#include <assert.h> +#include <stdbool.h> +#include <stdio.h> +#include <string.h> +#include "oslib/wimp.h" + +#include "utils/log.h" +#include "content/content.h" +#include "content/hlcache.h" +#include "content/fetch.h" +#include "content/urldb.h" +#include "desktop/browser.h" +#include "desktop/sslcert_viewer.h" +#include "desktop/tree.h" + +#include "riscos/dialog.h" +#include "riscos/sslcert.h" +#include "riscos/textarea.h" +#include "riscos/treeview.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" +#include "riscos/wimputils.h" +#include "riscos/gui.h" + +#define ICON_SSL_PANE 1 +#define ICON_SSL_REJECT 3 +#define ICON_SSL_ACCEPT 4 + +static wimp_window *ro_gui_cert_dialog_template; +static wimp_window *ro_gui_cert_tree_template; + +struct ro_sslcert +{ + wimp_w window; + wimp_w pane; + ro_treeview *tv; + struct sslcert_session_data *data; +}; + +static void ro_gui_cert_accept(wimp_pointer *pointer); +static void ro_gui_cert_reject(wimp_pointer *pointer); +static void ro_gui_cert_close_window(wimp_w w); +static void ro_gui_cert_release_window(struct ro_sslcert *s); + +/** + * Load and initialise the certificate window template + */ + +void ro_gui_cert_preinitialise(void) +{ + /* Load templates for the SSL windows and adjust the tree window + * flags to suit. + */ + + ro_gui_cert_dialog_template = ro_gui_dialog_load_template("sslcert"); + ro_gui_cert_tree_template = ro_gui_dialog_load_template("tree"); + + ro_gui_cert_tree_template->flags &= ~(wimp_WINDOW_MOVEABLE | + wimp_WINDOW_BACK_ICON | + wimp_WINDOW_CLOSE_ICON | + wimp_WINDOW_TITLE_ICON | + wimp_WINDOW_SIZE_ICON | + wimp_WINDOW_TOGGLE_ICON); +} + +/** + * Load and initialise the certificate window template + */ + +void ro_gui_cert_postinitialise(void) +{ + /* Initialise the SSL module. */ +} + +/** + * Prompt the user to verify a certificate with issuse. + * + * \param url The URL being verified. + * \param certs The certificate to be verified + * \param num The number of certificates to be verified. + * \param cb Callback upon user decision. + * \param cbpw Context pointer passed to cb + */ +void gui_cert_verify(nsurl *url, + const struct ssl_cert_info *certs, unsigned long num, + nserror (*cb)(bool proceed, void *pw), void *cbpw) +{ + struct ro_sslcert *sslcert_window; + wimp_window_state state; + wimp_icon_state istate; + wimp_window_info info; + os_error *error; + bool set_extent; + + assert(certs); + + sslcert_window = malloc(sizeof(struct ro_sslcert)); + if (sslcert_window == NULL) { + LOG("Failed to allocate memory for SSL Cert Dialog"); + return; + } + + /* Create the SSL window and its pane. */ + + error = xwimp_create_window(ro_gui_cert_dialog_template, + &(sslcert_window->window)); + if (error) { + LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess); + free(sslcert_window); + return; + } + + error = xwimp_create_window(ro_gui_cert_tree_template, + &(sslcert_window->pane)); + if (error) { + LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess); + free(sslcert_window); + return; + } + + /* Create the SSL data and build a tree from it. */ + sslcert_viewer_create_session_data(num, url, + cb, cbpw, certs, &sslcert_window->data); + ssl_current_session = sslcert_window->data; + + sslcert_window->tv = ro_treeview_create(sslcert_window->pane, + NULL, NULL, TREE_SSLCERT); + if (sslcert_window->tv == NULL) { + LOG("Failed to allocate treeview"); + free(sslcert_window); + return; + } + + /* Set up the certificate window event handling. + * + * (The action buttons are registered as button events, not OK and + * Cancel, as both need to carry out actions.) + */ + + ro_gui_wimp_event_set_user_data(sslcert_window->window, sslcert_window); + ro_gui_wimp_event_register_close_window(sslcert_window->window, + ro_gui_cert_close_window); + ro_gui_wimp_event_register_button(sslcert_window->window, + ICON_SSL_REJECT, ro_gui_cert_reject); + ro_gui_wimp_event_register_button(sslcert_window->window, + ICON_SSL_ACCEPT, ro_gui_cert_accept); + + ro_gui_dialog_open_persistent(NULL, sslcert_window->window, false); + + /* Nest the tree window inside the pane window. To do this, we: + * - Get the current pane extent, + * - Get the parent window position and the location of the pane- + * locating icon inside it, + * - Set the visible area of the pane to suit, + * - Check that the pane extents are OK for this visible area, and + * increase them if necessary, + * - Before finally opening the pane as a nested part of the parent. + */ + + info.w = sslcert_window->pane; + error = xwimp_get_window_info_header_only(&info); + if (error) { + ro_gui_cert_release_window(sslcert_window); + LOG("xwimp_get_window_info: 0x%x: %s", error->errnum, error->errmess); + return; + } + + state.w = sslcert_window->window; + error = xwimp_get_window_state(&state); + if (error) { + ro_gui_cert_release_window(sslcert_window); + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + return; + } + + istate.w = sslcert_window->window; + istate.i = ICON_SSL_PANE; + error = xwimp_get_icon_state(&istate); + if (error) { + ro_gui_cert_release_window(sslcert_window); + LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess); + return; + } + + state.w = sslcert_window->pane; + state.visible.x1 = state.visible.x0 + istate.icon.extent.x1 - 20 - + ro_get_vscroll_width(sslcert_window->pane); + state.visible.x0 += istate.icon.extent.x0 + 20; + state.visible.y0 = state.visible.y1 + istate.icon.extent.y0 + 20 + + ro_get_hscroll_height(sslcert_window->pane); + state.visible.y1 += istate.icon.extent.y1 - 32; + + set_extent = false; + + if ((info.extent.x1 - info.extent.x0) < + (state.visible.x1 - state.visible.x0)) { + info.extent.x0 = 0; + info.extent.x1 = state.visible.x1 - state.visible.x0; + set_extent = true; + } + if ((info.extent.y1 - info.extent.y0) < + (state.visible.y1 - state.visible.y0)) { + info.extent.y1 = 0; + info.extent.x1 = state.visible.y0 - state.visible.y1; + set_extent = true; + } + + if (set_extent) { + error = xwimp_set_extent(sslcert_window->pane, &(info.extent)); + if (error) { + ro_gui_cert_release_window(sslcert_window); + LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess); + return; + } + } + + error = xwimp_open_window_nested(PTR_WIMP_OPEN(&state), + sslcert_window->window, + wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT + << wimp_CHILD_XORIGIN_SHIFT | + wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT + << wimp_CHILD_YORIGIN_SHIFT | + wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT + << wimp_CHILD_LS_EDGE_SHIFT | + wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT + << wimp_CHILD_RS_EDGE_SHIFT); + if (error) { + ro_gui_cert_release_window(sslcert_window); + LOG("xwimp_open_window_nested: 0x%x: %s", error->errnum, error->errmess); + ro_gui_cert_release_window(sslcert_window); + return; + } + + ro_treeview_set_origin(sslcert_window->tv, 0, 0); +} + +/** + * Handle acceptance of certificate via event callback. + * + * \param *pointer The wimp pointer block. + */ + +void ro_gui_cert_accept(wimp_pointer *pointer) +{ + struct ro_sslcert *s; + + s = (struct ro_sslcert *) ro_gui_wimp_event_get_user_data(pointer->w); + + if (s != NULL) { + sslcert_viewer_accept(s->data); + ro_gui_dialog_close(s->window); + ro_gui_cert_release_window(s); + } +} + +/** + * Handle rejection of certificate via event callback. + * + * \param pointer The wimp pointer block. + */ + +void ro_gui_cert_reject(wimp_pointer *pointer) +{ + struct ro_sslcert *s; + + s = (struct ro_sslcert *) ro_gui_wimp_event_get_user_data(pointer->w); + + if (s != NULL) { + sslcert_viewer_reject(s->data); + ro_gui_dialog_close(s->window); + ro_gui_cert_release_window(s); + } +} + +/** + * Callback to handle the closure of the SSL dialogue by other means. + * + * \param w The window being closed. + */ + +static void ro_gui_cert_close_window(wimp_w w) +{ + struct ro_sslcert *s; + + s = (struct ro_sslcert *) ro_gui_wimp_event_get_user_data(w); + + if (s != NULL) + ro_gui_cert_release_window(s); +} + +/** + * Handle closing of the RISC OS certificate verification dialog, deleting + * the windows and freeing up the treeview and data block. + * + * \param *s The data block associated with the dialogue. + */ + +void ro_gui_cert_release_window(struct ro_sslcert *s) +{ + os_error *error; + + if (s == NULL) + return; + + LOG("Releasing SSL data: 0x%x", (unsigned)s); + + ro_gui_wimp_event_finalise(s->window); + ro_treeview_destroy(s->tv); + + error = xwimp_delete_window(s->window); + if (error) { + LOG("xwimp_delete_window: 0x%x:%s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + error = xwimp_delete_window(s->pane); + if (error) { + LOG("xwimp_delete_window: 0x%x:%s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + + free(s); +} + diff --git a/frontends/riscos/sslcert.h b/frontends/riscos/sslcert.h new file mode 100644 index 000000000..17fce5552 --- /dev/null +++ b/frontends/riscos/sslcert.h @@ -0,0 +1,34 @@ +/* + * Copyright 2006 Richard Wilson <info@tinct.net> + * Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * SSL certificate viewer (interface). + */ + +#ifndef _NETSURF_RISCOS_SSLCERT_H_ +#define _NETSURF_RISCOS_SSLCERT_H_ + +struct node; + +void ro_gui_cert_preinitialise(void); +void ro_gui_cert_postinitialise(void); +void ro_gui_cert_open(struct tree *tree, struct node *node); + +#endif + diff --git a/frontends/riscos/templates/de b/frontends/riscos/templates/de new file mode 100644 index 000000000..0fb4a9de7 --- /dev/null +++ b/frontends/riscos/templates/de @@ -0,0 +1,3845 @@ +Template: + +wimp_window { + template_name:"configure" + visible:378,820,1046,1126 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BACK_ICON | wimp_WINDOW_CLOSE_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_TOGGLE_ICON | wimp_WINDOW_VSCROLL | wimp_WINDOW_SIZE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_LIGHT_GREY + extra_flags: + extent:0,-880,1236,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:4 + ymin:156 + text.text:"NetSurf Konfiguration" + text.size:* + text.validation:"" +} + +wimp_window { + template_name:"con_cache" + visible:500,672,1088,1100 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-428,588,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + work_flags: + sprite_area:&1 + xmin:588 + ymin:240 + text_only:"Cache" + wimp_icon { + extent:16,-124,568,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-52,268,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Memory cache " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:44,-100,164,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Größe" + text.size:13 + text.validation:"" + } + wimp_icon { + extent:168,-104,336,-52 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"512.0" + text.size:10 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:352,-96,384,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:384,-96,416,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:424,-100,480,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"MB" + } + wimp_icon { + extent:16,-312,568,-152 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-180,268,-136 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Disc cache " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:44,-232,164,-188 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Größe" + text.size:13 + text.validation:"" + } + wimp_icon { + extent:168,-236,336,-184 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"512" + text.size:10 + text.validation:"Pptr_write;Kta;A0-9" + } + wimp_icon { + extent:352,-228,384,-196 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:384,-228,416,-196 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:424,-232,480,-192 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"MB" + } + wimp_icon { + extent:44,-292,164,-248 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Expiry" + text.size:13 + text.validation:"" + } + wimp_icon { + extent:168,-296,336,-244 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"512" + text.size:10 + text.validation:"Pptr_write;Kta;A0-9" + } + wimp_icon { + extent:352,-288,384,-256 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:384,-288,416,-256 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:424,-292,500,-252 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"days" + } + wimp_icon { + extent:24,-396,188,-344 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Standard" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:204,-396,368,-344 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Abbruch" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:384,-404,568,-336 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"OK" + text.size:4 + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"con_fonts" + visible:744,374,1456,1098 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-724,712,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:712 + ymin:724 + text.text:"Schriftarten" + text.size:* + text.validation:"" + wimp_icon { + extent:16,-424,696,-28 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-52,236,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Font faces " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:26,-104,198,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Sans-serif" + } + wimp_icon { + extent:200,-108,624,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:632,-104,676,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:106,-164,198,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Serif" + } + wimp_icon { + extent:200,-168,624,-116 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:632,-164,676,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:34,-224,198,-180 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Monospace" + } + wimp_icon { + extent:200,-228,624,-176 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:632,-224,676,-180 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:74,-284,198,-240 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Cursive" + } + wimp_icon { + extent:200,-288,624,-236 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:632,-284,676,-240 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:74,-344,198,-300 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Fantasy" + } + wimp_icon { + extent:200,-348,624,-296 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:632,-344,676,-300 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:42,-404,198,-360 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Standard" + } + wimp_icon { + extent:200,-408,624,-356 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:632,-404,676,-360 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:16,-616,696,-456 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-480,220,-436 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Font size " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:64,-532,192,-488 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Normal" + } + wimp_icon { + extent:200,-536,368,-484 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"12.3" + text.size:10 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:380,-528,412,-496 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:412,-528,444,-496 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:452,-532,492,-488 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"pt" + } + wimp_icon { + extent:60,-592,192,-548 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Minimum" + } + wimp_icon { + extent:200,-596,368,-544 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"12.3" + text.size:10 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:380,-588,412,-556 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:412,-588,444,-556 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:452,-592,492,-548 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"pt" + } + wimp_icon { + extent:24,-696,188,-644 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Standard" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:332,-696,496,-644 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Abbruch" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:512,-704,696,-636 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"OK" + text.size:4 + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"con_home" + visible:400,304,1200,600 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-296,800,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:800 + ymin:296 + text_only:"Homepage" + wimp_icon { + extent:16,-184,784,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-52,284,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Home page " + text_and_sprite.size:16 + text_and_sprite.validation:"" + } + wimp_icon { + extent:48,-108,120,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"URL" + } + wimp_icon { + extent:124,-112,712,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:128 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:720,-108,764,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:124,-164,676,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Fenster beim Start öffnen" + text_and_sprite.size:32 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:24,-264,188,-212 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Standard" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:416,-264,580,-212 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Abbruch" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:596,-272,780,-204 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"OK" + text.size:4 + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"con_image" + visible:828,926,1504,1514 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-588,676,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:676 + ymin:588 + text_only:"Bilder" + wimp_icon { + extent:16,-292,660,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-52,284,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Image quality " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-108,224,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Vordergrund" + } + wimp_icon { + extent:232,-112,592,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Error diffused" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:600,-108,644,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:32,-168,224,-124 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Hintergrund" + } + wimp_icon { + extent:232,-172,592,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Error diffused" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:600,-168,644,-124 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:32,-276,644,-180 + icon_flags:wimp_ICON_BORDER + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + } + wimp_icon { + extent:16,-476,660,-320 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-348,284,-304 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Animations " + text_and_sprite.size:16 + text_and_sprite.validation:"" + } + wimp_icon { + extent:20,-404,208,-360 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Speedlimit" + text.size:12 + text.validation:"" + } + wimp_icon { + extent:212,-408,380,-356 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"12.34" + text.size:* + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:396,-400,428,-368 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:428,-400,460,-368 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:468,-404,612,-360 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Sekunden" + text.size:* + text.validation:"" + } + wimp_icon { + extent:212,-460,640,-416 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Animationen abschalten" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:24,-560,188,-508 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Standard" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:296,-560,460,-508 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Abbruch" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:476,-568,660,-500 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"OK" + text.size:4 + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"con_lang" + visible:770,1102,1514,1402 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-300,744,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:744 + ymin:300 + text.text:"Spracheinstellungen" + text.size:* + text.validation:"" + wimp_icon { + extent:16,-188,728,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-52,284,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Language " + text_and_sprite.size:16 + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-108,204,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Oberfläche" + } + wimp_icon { + extent:208,-112,660,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"1337" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:668,-108,712,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:40,-168,204,-124 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Webseiten" + } + wimp_icon { + extent:208,-172,660,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"8008135" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:668,-168,712,-124 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:24,-268,188,-216 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Standard" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:360,-268,524,-216 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Abbruch" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:540,-276,724,-208 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"OK" + text.size:4 + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"con_theme" + visible:408,370,1316,974 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-604,908,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:640 + ymin:604 + text_only:"Themen" + wimp_icon { + extent:16,-492,892,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-52,332,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Available themes " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:24,-576,188,-524 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Standard" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:524,-576,688,-524 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Abbruch" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:704,-584,888,-516 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"OK" + text.size:4 + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"download" + visible:486,610,1394,890 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_BACK_ICON | wimp_WINDOW_CLOSE_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-280,908,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:796 + ymin:280 + text.text:"NetSurf Download" + text.size:* + text.validation:"" + wimp_icon { + extent:420,-84,488,-16 + icon_flags:wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK_DRAG + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + sprite.id:"file_ddc" + sprite.size:* + sprite.area:&1 + } + wimp_icon { + extent:204,-152,900,-100 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"http://netsurf.sourceforge.net/netsurf.zip" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:204,-212,900,-160 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"netsurf" + text.size:* + text.validation:"Pptr_write" + } + wimp_icon { + extent:204,-212,900,-160 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"ADFS::A7000+.$.netsurf" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:8,-272,900,-220 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:12,-268,296,-224 + icon_flags:wimp_ICON_FILLED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_CREAM + } + wimp_icon { + extent:12,-268,896,-224 + icon_flags:wimp_ICON_TEXT | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"84.4KB of 1.1MB 26.6KB/s 0:39 remaining" + text.size:* + text.validation:"" + } + wimp_icon { + extent:92,-148,200,-104 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Quelle" + } + wimp_icon { + extent:12,-208,200,-164 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Zielort" + } +} + +wimp_window { + template_name:"history" + visible:252,388,1152,808 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_SCROLL_REPEAT | wimp_WINDOW_BACK_ICON | wimp_WINDOW_CLOSE_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_TOGGLE_ICON | wimp_WINDOW_VSCROLL | wimp_WINDOW_SIZE_ICON | wimp_WINDOW_HSCROLL | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_WHITE + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-880,1236,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags:wimp_BUTTON_CLICK + sprite_area:&1 + xmin:0 + ymin:0 + text.text:"History" + text.size:* + text.validation:"" +} + +wimp_window { + template_name:"info" + visible:268,838,888,1086 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_CREAM + scroll_inner:wimp_COLOUR_ORANGE + highlight_bg:wimp_COLOUR_LIGHT_GREY + extra_flags: + extent:0,-248,620,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags:wimp_BUTTON_CLICK + sprite_area:&1 + xmin:0 + ymin:0 + text.text:"Über dieses Programm" + text.size:* + text.validation:"" + wimp_icon { + extent:676,-204,852,-156 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_RED + text_only:"OK" + } + wimp_icon { + extent:152,-60,612,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK_DRAG + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"NetSurf" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:152,-120,612,-68 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK_DRAG + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Open source web browser" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:152,-180,612,-128 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK_DRAG + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"© NetSurf developers" + text.size:40 + text.validation:"R2" + } + wimp_icon { + extent:152,-240,612,-188 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK_DRAG + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"CVS test build" + text.size:40 + text.validation:"R2" + } + wimp_icon { + extent:60,-56,148,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Name" + } + wimp_icon { + extent:48,-116,148,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Zweck" + } + wimp_icon { + extent:56,-176,148,-132 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Autor" + } + wimp_icon { + extent:24,-236,148,-192 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Version" + } +} + +wimp_window { + template_name:"login" + visible:710,422,1386,758 + xscroll:0 + yscroll:-8 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-344,676,-8 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:676 + ymin:336 + text.text:"Authentifizierung" + text.size:20 + text.validation:"" + wimp_icon { + extent:532,-332,664,-264 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Login" + text.size:8 + text.validation:"R6,3;Nok" + } + wimp_icon { + extent:376,-324,508,-272 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Abbruch" + text.size:* + text.validation:"R5,3;Ncancel" + } + wimp_icon { + extent:168,-68,668,-16 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"moo.yoo.com" + text.size:255 + text.validation:"R2" + } + wimp_icon { + extent:168,-128,668,-76 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"my sekr3t area" + text.size:255 + text.validation:"R2" + } + wimp_icon { + extent:168,-188,668,-136 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:255 + text.validation:"Pptr_write;Kta;N401username" + } + wimp_icon { + extent:168,-248,668,-196 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:255 + text.validation:"Pptr_write;Kta;D*" + } + wimp_icon { + extent:88,-64,164,-20 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Host" + } + wimp_icon { + extent:16,-184,164,-140 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Username" + } + wimp_icon { + extent:24,-244,164,-200 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Passwort" + } + wimp_icon { + extent:68,-124,164,-80 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Realm" + } +} + +wimp_window { + template_name:"new_entry" + visible:1120,590,1720,810 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-220,600,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:600 + ymin:220 + text.text:"" + text.size:32 + text.validation:"" + wimp_icon { + extent:12,-56,108,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Name" + } + wimp_icon { + extent:112,-60,588,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:128 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:12,-116,108,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"URL" + } + wimp_icon { + extent:112,-120,532,-68 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:1024 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:304,-200,436,-148 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Abbruch" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:456,-208,588,-140 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"OK" + text.size:8 + text.validation:"R6,3" + } + wimp_icon { + extent:540,-116,584,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } +} + +wimp_window { + template_name:"new_folder" + visible:480,954,1080,1114 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-160,600,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:600 + ymin:160 + text.text:"" + text.size:21 + text.validation:"" + wimp_icon { + extent:12,-56,108,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Name" + } + wimp_icon { + extent:112,-60,588,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:128 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:304,-140,436,-88 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Abbruch" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:456,-148,588,-80 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"OK" + text.size:8 + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"objectinfo" + visible:272,900,1060,1088 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-188,788,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags:wimp_BUTTON_CLICK + sprite_area:&1 + xmin:788 + ymin:188 + text.text:"Über das Objekt" + text.size:20 + text.validation:"" + wimp_icon { + extent:204,-60,780,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:64 + text.validation:"R2" + } + wimp_icon { + extent:204,-120,780,-68 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:64 + text.validation:"R2" + } + wimp_icon { + extent:204,-180,780,-128 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:64 + text.validation:"R2" + } + wimp_icon { + extent:12,-80,84,-12 + icon_flags:wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + sprite.id:"file_faf" + sprite.size:* + sprite.area:&1 + } + wimp_icon { + extent:124,-116,200,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Ziel" + } + wimp_icon { + extent:136,-176,200,-132 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Typ" + } + wimp_icon { + extent:128,-56,200,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"URL" + } +} + +wimp_window { + template_name:"open_url" + visible:438,126,1238,282 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-156,800,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:0 + ymin:0 + text.text:"Webseite öffnen" + text.size:25 + text.validation:"" + wimp_icon { + extent:20,-56,92,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"URL" + } + wimp_icon { + extent:96,-60,736,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:1 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:504,-136,632,-84 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Abbruch" + text.size:21 + text.validation:"R5,3" + } + wimp_icon { + extent:656,-144,788,-76 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Öffnen" + text.size:8 + text.validation:"R6,3" + } + wimp_icon { + extent:744,-56,788,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } +} + +wimp_window { + template_name:"pageinfo" + visible:576,224,1368,472 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-248,792,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags:wimp_BUTTON_CLICK + sprite_area:&1 + xmin:792 + ymin:248 + text.text:"Über das Dokument" + text.size:20 + text.validation:"" + wimp_icon { + extent:208,-60,784,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:64 + text.validation:"R2" + } + wimp_icon { + extent:208,-120,784,-68 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:64 + text.validation:"R2" + } + wimp_icon { + extent:208,-180,784,-128 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:64 + text.validation:"R2" + } + wimp_icon { + extent:208,-240,784,-188 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:64 + text.validation:"R2" + } + wimp_icon { + extent:12,-80,84,-12 + icon_flags:wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + sprite.id:"file_faf" + sprite.size:* + sprite.area:&1 + } + wimp_icon { + extent:132,-116,204,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"URL" + } + wimp_icon { + extent:48,-176,204,-132 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Kodierung" + } + wimp_icon { + extent:140,-236,204,-192 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Typ" + } + wimp_icon { + extent:112,-56,204,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Titel" + } +} + +wimp_window { + template_name:"print" + visible:1204,134,1804,706 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-572,600,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:600 + ymin:572 + text.text:"kein Drucker" + text.size:20 + text.validation:"" + wimp_icon { + extent:12,-176,588,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-100,504,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:1 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Ende der Web-Seite" + text_and_sprite.size:27 + text_and_sprite.validation:"Sradiooff,radioon" + } + wimp_icon { + extent:32,-152,492,-108 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:1 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:6 + text_and_sprite.validation:"Sradiooff,radioon" + } + wimp_icon { + extent:84,-156,164,-104 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"1" + text.size:3 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:176,-148,208,-116 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:212,-148,244,-116 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:248,-152,476,-108 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Seiten" + text.size:18 + text.validation:"" + } + wimp_icon { + extent:12,-236,452,-192 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Vordergrundbilder zeigen" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:12,-288,452,-244 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Hintergrundbilder zeigen" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:12,-340,420,-296 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"im Hintergrund drucken" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:12,-404,196,-360 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Portrait" + text_and_sprite.size:* + text_and_sprite.validation:"Sradiooff,radioon" + } + wimp_icon { + extent:12,-452,228,-408 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Landschaft" + text_and_sprite.size:* + text_and_sprite.validation:"Sradiooff,radioon" + } + wimp_icon { + extent:432,-456,512,-404 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"1" + text.size:3 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:524,-448,556,-416 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:556,-448,588,-416 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:284,-552,416,-500 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Abbruch" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:440,-560,588,-492 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Drucken" + text.size:* + text.validation:"R6,3" + } + wimp_icon { + extent:320,-452,428,-408 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Kopien" + } + wimp_icon { + extent:-4,-480,608,-472 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:32,-52,364,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Druck beenden nach " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:252,-400,596,-356 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Text immer schwarz" + text_and_sprite.size:24 + text_and_sprite.validation:"Soptoff,opton" + } +} + +wimp_window { + template_name:"query" + visible:426,1082,1226,1326 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_LIGHT_GREY + extra_flags: + extent:0,-244,800,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:0 + ymin:0 + text.text:"Sicherheitsabfrage von NetSurf" + text.size:* + text.validation:"" + wimp_icon { + extent:92,-148,792,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Message" + text.size:300 + text.validation:"R2;L" + } + wimp_icon { + extent:636,-232,788,-164 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"012345678901234567" + text.size:* + text.validation:"R6,3" + } + wimp_icon { + extent:504,-224,620,-172 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"012345678901234567" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:16,-224,132,-172 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Hilfe" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:12,-80,80,-12 + icon_flags:wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + sprite_only:"!netsurf" + } +} + +wimp_window { + template_name:"saveas" + visible:618,322,950,570 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-248,332,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:0 + ymin:0 + text_only:"Abspeichern" + wimp_icon { + extent:132,-84,200,-16 + icon_flags:wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK_DRAG + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + sprite.id:"file_faf" + sprite.size:13 + sprite.area:&1 + } + wimp_icon { + extent:8,-152,324,-96 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:256 + text.validation:"Pptr_write" + } + wimp_icon { + extent:172,-236,320,-168 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Sichern" + text.size:* + text.validation:"R6,3" + } + wimp_icon { + extent:20,-228,148,-176 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Abbruch" + text.size:* + text.validation:"R5,3" + } +} + +wimp_window { + template_name:"search" + visible:384,780,1028,1024 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-244,644,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:644 + ymin:244 + text.text:"Text suchen" + text.size:* + text.validation:"" + wimp_icon { + extent:96,-60,580,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:32 + text.validation:"KN;Pptr_write" + } + wimp_icon { + extent:96,-116,352,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Groß/klein" + text_and_sprite.size:15 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:500,-228,632,-160 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"vor" + text.size:10 + text.validation:"R6,3" + } + wimp_icon { + extent:348,-220,484,-168 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"zurück" + text.size:9 + text.validation:"R5,3" + } + wimp_icon { + extent:204,-220,332,-168 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Abbruch" + text.size:12 + text.validation:"R5,3" + } + wimp_icon { + extent:16,-216,196,-172 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Not found" + text.size:* + text.validation:"" + } + wimp_icon { + extent:-8,-148,652,-140 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:16,-56,92,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Text" + } + wimp_icon { + extent:588,-56,632,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_ICON_SHADED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:352,-116,580,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Alle zeigen" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } +} + +wimp_window { + template_name:"theme_inst" + visible:384,134,1184,378 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-244,800,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:0 + ymin:0 + text.text:"NetSurf Themen-Installation" + text.size:* + text.validation:"" + wimp_icon { + extent:92,-148,792,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Message" + text.size:300 + text.validation:"R2;L" + } + wimp_icon { + extent:540,-232,788,-164 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Installieren" + text.size:* + text.validation:"R6,3" + } + wimp_icon { + extent:394,-224,522,-172 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Abbruch" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:12,-80,80,-12 + icon_flags:wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + sprite_only:"!netsurf" + } +} + +wimp_window { + template_name:"tooltip" + visible:884,620,1148,656 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-36,2000,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + work_flags: + sprite_area:&1 + xmin:0 + ymin:0 + text_only:"<Untitled>" + wimp_icon { + extent:0,-40,300,4 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_ICON_SELECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Kommentar" + text.size:256 + text.validation:"" + } +} + +wimp_window { + template_name:"tree" + visible:530,654,1042,954 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_SCROLL_REPEAT | wimp_WINDOW_IGNORE_XEXTENT | wimp_WINDOW_IGNORE_YEXTENT | wimp_WINDOW_BACK_ICON | wimp_WINDOW_CLOSE_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_TOGGLE_ICON | wimp_WINDOW_VSCROLL | wimp_WINDOW_SIZE_ICON | wimp_WINDOW_HSCROLL | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_TRANSPARENT + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-880,1236,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags:wimp_BUTTON_DOUBLE_CLICK_DRAG + sprite_area:&1 + xmin:0 + ymin:0 + text.text:"" + text.size:64 + text.validation:"" +} + +wimp_window { + template_name:"url_suggest" + visible:320,390,1102,684 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_NO_BOUNDS | wimp_WINDOW_IGNORE_XEXTENT | wimp_WINDOW_IGNORE_YEXTENT | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_TRANSPARENT + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-65536,65536,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + work_flags:wimp_BUTTON_CLICK + sprite_area:&1 + xmin:0 + ymin:0 + text_only:"<Untitled>" +} + +wimp_window { + template_name:"warning" + visible:320,524,1120,768 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-244,800,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:0 + ymin:0 + text.text:"Warnung von NetSurf" + text.size:21 + text.validation:"" + wimp_icon { + extent:92,-148,792,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Message" + text.size:300 + text.validation:"R2;L" + } + wimp_icon { + extent:624,-232,788,-164 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Weiter" + text.size:9 + text.validation:"R6,3" + } + wimp_icon { + extent:480,-224,600,-172 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Hilfe" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:12,-80,80,-12 + icon_flags:wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + sprite_only:"!netsurf" + } +} + +wimp_window { + template_name:"zoom" + visible:694,830,1142,1054 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-224,448,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:448 + ymin:224 + text.text:"Ansicht skalieren" + text.size:* + text.validation:"" + wimp_icon { + extent:8,-56,104,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Größe" + } + wimp_icon { + extent:108,-60,208,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"100" + text.size:5 + text.validation:"Pptr_write;KTA;A0-9." + } + wimp_icon { + extent:220,-52,252,-20 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"R5;sdown,pdown" + } + wimp_icon { + extent:252,-52,284,-20 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"R5;sup,pup" + } + wimp_icon { + extent:288,-56,328,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_HCENTRED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"%" + } + wimp_icon { + extent:108,-112,420,-68 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Frames skalieren" + text_and_sprite.size:20 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:-4,-132,548,-124 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:84,-204,216,-152 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Abbruch" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:240,-212,436,-144 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Skalieren" + text.size:* + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"con_inter" + visible:1094,146,1838,918 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-772,744,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:744 + ymin:584 + text_only:"Nützliches" + wimp_icon { + extent:16,-168,728,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-52,492,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Downloading / saving files " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-92,696,-48 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Erweiterungen beim Speichern entfernen" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:32,-152,676,-108 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"vor Überschreiben von Dateien fragen" + text_and_sprite.size:46 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:16,-344,728,-200 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:36,-224,496,-180 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Interactive features " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-268,744,-224 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"aktuellste URLs beim Tippen anzeigen" + text_and_sprite.size:42 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:32,-328,872,-284 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"URLs in lokaler History einblenden" + text_and_sprite.size:44 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:16,-468,728,-372 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:36,-400,240,-356 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Thumbnails " + text_and_sprite.size:23 + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-452,648,-408 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Thumbnails zeigen beim Iconisieren" + text_and_sprite.size:42 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:24,-740,188,-688 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Standard" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:360,-740,524,-688 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Abbruch" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:540,-748,724,-680 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"OK" + text.size:4 + text.validation:"R6,3" + } + wimp_icon { + extent:16,-660,728,-492 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:36,-520,240,-476 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Hotlist" + text_and_sprite.size:23 + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-572,728,-528 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Use external hotlist apps when available" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:28,-640,232,-588 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Hotlist path" + text.size:* + text.validation:"" + } + wimp_icon { + extent:232,-640,708,-588 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"Writable icon" + text.size:256 + text.validation:"Pptr_write;Kta" + } +} + +wimp_window { + template_name:"con_secure" + visible:440,540,1032,904 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-364,592,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:592 + ymin:364 + text_only:"Sicherheit" + wimp_icon { + extent:16,-120,576,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-52,364,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Cross-site privacy " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-96,568,-52 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Seitenreferenzen senden" + text_and_sprite.size:31 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:16,-252,576,-148 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-176,316,-132 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Site history " + text_and_sprite.size:18 + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-224,172,-180 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"behalten" + } + wimp_icon { + extent:184,-228,344,-176 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"12" + text.size:4 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:358,-216,390,-184 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:390,-220,422,-188 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:434,-224,510,-180 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Tage" + } + wimp_icon { + extent:24,-336,188,-284 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Standard" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:208,-336,372,-284 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Abbruch" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:388,-344,572,-276 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"OK" + text.size:4 + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"con_connect" + visible:902,402,1562,1070 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-668,660,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:660 + ymin:668 + text_only:"Verbindung" + wimp_icon { + extent:16,-304,644,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:28,-52,264,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" HTTP Proxy " + text_and_sprite.size:15 + text_and_sprite.validation:"" + } + wimp_icon { + extent:12,-104,184,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Proxytyp" + } + wimp_icon { + extent:188,-108,572,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:32 + text.validation:"R2" + } + wimp_icon { + extent:580,-104,624,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:108,-164,184,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Host" + text.size:* + text.validation:"" + } + wimp_icon { + extent:188,-168,504,-116 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"myhost.proxy" + text.size:255 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:500,-164,528,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_HCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:":" + text.size:* + text.validation:"" + } + wimp_icon { + extent:524,-168,628,-116 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"8080" + text.size:8 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:36,-224,184,-180 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Username" + text.size:* + text.validation:"" + } + wimp_icon { + extent:188,-228,628,-176 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"k1dd13" + text.size:64 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:36,-284,184,-240 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Passwort" + text.size:* + text.validation:"" + } + wimp_icon { + extent:188,-288,628,-236 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"1337" + text.size:64 + text.validation:"Pptr_write;Kta;D*" + } + wimp_icon { + extent:16,-552,644,-332 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-360,268,-316 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Fetching " + text_and_sprite.size:15 + text_and_sprite.validation:"" + } + wimp_icon { + extent:52,-412,340,-368 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Fetches maximal" + text.size:18 + text.validation:"" + } + wimp_icon { + extent:344,-416,552,-364 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"99" + text.size:* + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:560,-408,592,-376 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:592,-408,624,-376 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:56,-472,340,-428 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Fetches pro Host" + text.size:18 + text.validation:"" + } + wimp_icon { + extent:344,-476,552,-424 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"99" + text.size:4 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:560,-468,596,-436 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:592,-468,624,-436 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:32,-532,340,-488 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Verbindungen cachen" + text.size:22 + text.validation:"" + } + wimp_icon { + extent:344,-536,552,-484 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"99" + text.size:4 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:560,-528,596,-496 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:592,-528,624,-496 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:24,-640,188,-588 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Standard" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:276,-640,440,-588 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Abbruch" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:456,-648,640,-580 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"OK" + text.size:4 + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"ssldisplay" + visible:212,142,1172,682 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_CLOSE_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-540,960,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:960 + ymin:76 + text.text:"SSL Zertifikat" + text.size:16 + text.validation:"" + wimp_icon { + extent:432,-168,928,-116 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:16,-520,944,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:24,-108,148,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Version" + } + wimp_icon { + extent:152,-108,264,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:260,-104,432,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"gültig von" + } + wimp_icon { + extent:432,-108,928,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:68,-168,148,-124 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Typ" + } + wimp_icon { + extent:152,-168,264,-116 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:244,-164,432,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"gültig bis" + } + wimp_icon { + extent:32,-52,380,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Certificate details " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:40,-228,148,-184 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Serial" + } + wimp_icon { + extent:152,-228,928,-176 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:40,-288,148,-244 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Issuer" + } + wimp_icon { + extent:152,-376,928,-236 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2;L" + } + wimp_icon { + extent:24,-432,148,-388 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Subject" + } + wimp_icon { + extent:152,-504,928,-384 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2;L" + } +} + +wimp_window { + template_name:"sslcert" + visible:348,306,1136,898 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-592,788,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:788 + ymin:592 + text.text:"SSL Zertifizierungsproblem" + text.size:* + text.validation:"" + wimp_icon { + extent:16,-108,772,-16 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"NetSurf konnte ein SSL Zertifikat nicht prüfen. Bitte die Details unten beachten." + text.size:150 + text.validation:"R2;L" + } + wimp_icon { + extent:16,-484,772,-136 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-164,380,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Certificate chain " + text_and_sprite.size:22 + text_and_sprite.validation:"" + } + wimp_icon { + extent:404,-564,568,-512 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Ablehnen" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:588,-572,772,-504 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annehmen" + text.size:12 + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"con_content" + visible:1404,424,2044,924 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-500,640,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:640 + ymin:452 + text_only:"Content" + wimp_icon { + extent:16,-272,624,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-52,492,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Content blocking " + text_and_sprite.size:29 + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-100,436,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Werbung unterdrücken" + text_and_sprite.size:39 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:32,-152,528,-108 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Pop-Up Fenster abschalten" + text_and_sprite.size:46 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:32,-256,496,-212 +#ifdef WITH_PLUGIN + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO +#else + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_DELETED | wimp_BUTTON_RADIO +#endif + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Plugins nicht benutzen" + text_and_sprite.size:42 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:16,-384,624,-292 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-320,492,-276 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Link targets " + text_and_sprite.size:29 + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-368,612,-324 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Links dürfen neue Fenster öffnen" + text_and_sprite.size:35 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:24,-468,188,-416 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Standard" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:256,-468,420,-416 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Abbruch" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:436,-476,620,-408 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"OK" + text.size:4 + text.validation:"R6,3" + } + wimp_icon { + extent:32,-204,376,-160 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Disable JavaScript" + text_and_sprite.size:19 + text_and_sprite.validation:"Soptoff,opton" + } +} diff --git a/frontends/riscos/templates/en b/frontends/riscos/templates/en new file mode 100644 index 000000000..7746b86cc --- /dev/null +++ b/frontends/riscos/templates/en @@ -0,0 +1,3837 @@ +Template: + +wimp_window { + template_name:"configure" + visible:378,966,1050,1126 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BACK_ICON | wimp_WINDOW_CLOSE_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_TOGGLE_ICON | wimp_WINDOW_VSCROLL | wimp_WINDOW_SIZE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_LIGHT_GREY + extra_flags: + extent:0,-880,1236,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:4 + ymin:160 + text.text:"NetSurf configuration" + text.size:* + text.validation:"" +} + +wimp_window { + template_name:"con_cache" + visible:184,682,772,1110 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-428,588,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + work_flags: + sprite_area:&1 + xmin:588 + ymin:240 + text_only:"Cache" + wimp_icon { + extent:16,-124,568,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-52,268,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Memory cache " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:44,-104,164,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Size" + text.size:13 + text.validation:"" + } + wimp_icon { + extent:168,-108,336,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"512.0" + text.size:10 + text.validation:"Pptr_write;Kta;A0-9." + } + wimp_icon { + extent:352,-100,384,-68 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:384,-100,416,-68 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:424,-104,480,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"MB" + } + wimp_icon { + extent:16,-312,568,-152 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-180,268,-136 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Disc cache " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:44,-232,164,-188 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Size" + text.size:13 + text.validation:"" + } + wimp_icon { + extent:168,-236,336,-184 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"512" + text.size:10 + text.validation:"Pptr_write;Kta;A0-9" + } + wimp_icon { + extent:352,-228,384,-196 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:384,-228,416,-196 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:424,-232,480,-192 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"MB" + } + wimp_icon { + extent:44,-292,164,-248 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Expiry" + text.size:13 + text.validation:"" + } + wimp_icon { + extent:168,-296,336,-244 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"512" + text.size:10 + text.validation:"Pptr_write;Kta;A0-9" + } + wimp_icon { + extent:352,-288,384,-256 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:384,-288,416,-256 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:424,-292,500,-252 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"days" + } + wimp_icon { + extent:24,-396,188,-344 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Default" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:204,-396,368,-344 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Cancel" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:384,-404,568,-336 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Set" + text.size:* + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"con_fonts" + visible:558,802,1282,1526 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-724,724,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + work_flags: + sprite_area:&1 + xmin:712 + ymin:724 + text_only:"Fonts" + wimp_icon { + extent:16,-424,704,-28 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-52,236,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Font faces " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:28,-104,200,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Sans-serif" + } + wimp_icon { + extent:204,-108,628,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:640,-104,684,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:108,-164,200,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Serif" + } + wimp_icon { + extent:204,-168,628,-116 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:640,-164,684,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:36,-224,200,-180 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Monospace" + } + wimp_icon { + extent:204,-228,628,-176 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:640,-224,684,-180 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:76,-284,200,-240 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Cursive" + } + wimp_icon { + extent:204,-288,628,-236 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:640,-284,684,-240 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:72,-344,200,-300 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Fantasy" + } + wimp_icon { + extent:204,-348,628,-296 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:640,-344,684,-300 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:76,-404,200,-360 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Default" + } + wimp_icon { + extent:204,-408,628,-356 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:640,-404,684,-360 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:16,-612,704,-452 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-480,220,-436 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Font size " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:76,-532,200,-488 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Default" + } + wimp_icon { + extent:204,-536,372,-484 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"12.3" + text.size:10 + text.validation:"Pptr_write;Kta;A0-9." + } + wimp_icon { + extent:388,-528,420,-496 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:420,-528,452,-496 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:460,-532,500,-488 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"pt" + } + wimp_icon { + extent:52,-592,200,-548 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Minimum" + } + wimp_icon { + extent:204,-596,372,-544 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"12.3" + text.size:10 + text.validation:"Pptr_write;Kta;A0-9." + } + wimp_icon { + extent:388,-588,420,-556 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:420,-588,452,-556 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:460,-592,500,-548 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"pt" + } + wimp_icon { + extent:24,-696,188,-644 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Default" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:340,-696,504,-644 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Cancel" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:520,-704,704,-636 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Set" + text.size:* + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"con_home" + visible:808,592,1608,888 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-296,800,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + work_flags: + sprite_area:&1 + xmin:800 + ymin:296 + text_only:"Home page" + wimp_icon { + extent:16,-184,784,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-52,284,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Home page " + text_and_sprite.size:16 + text_and_sprite.validation:"" + } + wimp_icon { + extent:40,-108,120,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"URL" + } + wimp_icon { + extent:124,-112,712,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:128 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:720,-108,764,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:124,-164,676,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_SELECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Open browser window on start-up" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:24,-264,188,-212 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Default" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:420,-264,584,-212 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Cancel" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:600,-272,784,-204 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Set" + text.size:* + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"con_image" + visible:1488,822,2164,1410 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-588,676,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + work_flags: + sprite_area:&1 + xmin:676 + ymin:588 + text_only:"Images" + wimp_icon { + extent:16,-292,660,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-52,284,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Image quality " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:28,-108,204,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Foreground" + } + wimp_icon { + extent:208,-112,592,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Error diffused" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:600,-108,644,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:24,-168,204,-124 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Background" + } + wimp_icon { + extent:208,-172,592,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Error diffused" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:600,-168,644,-124 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:32,-276,644,-180 + icon_flags:wimp_ICON_BORDER + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + } + wimp_icon { + extent:16,-476,660,-320 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-348,236,-304 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Animations " + text_and_sprite.size:16 + text_and_sprite.validation:"" + } + wimp_icon { + extent:20,-404,208,-360 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Speed limit" + text.size:* + text.validation:"" + } + wimp_icon { + extent:212,-408,380,-356 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"12.34" + text.size:* + text.validation:"Pptr_write;Kta;A0-9." + } + wimp_icon { + extent:396,-400,428,-368 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:428,-400,460,-368 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:468,-404,592,-360 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"seconds" + text.size:* + text.validation:"" + } + wimp_icon { + extent:212,-460,556,-416 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Disable animations" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:24,-560,188,-508 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Default" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:292,-560,456,-508 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Cancel" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:472,-568,656,-500 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Set" + text.size:* + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"con_inter" + visible:2320,436,3164,1220 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-784,844,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:744 + ymin:584 + text_only:"Interface" + wimp_icon { + extent:16,-168,820,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-52,492,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Downloading / saving files " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-100,680,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Strip filename extensions when saving" + text_and_sprite.size:39 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:32,-152,808,-108 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Request confirmation before overwriting files" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:16,-344,820,-200 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:36,-224,496,-180 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Interactive features " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-276,744,-232 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Display recently visited URLs as you type" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:32,-328,776,-284 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Hover URLs by the pointer for local history" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:16,-468,820,-372 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:36,-400,240,-356 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Thumbnails " + text_and_sprite.size:23 + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-452,648,-408 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Use thumbnails for iconised windows" + text_and_sprite.size:42 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:24,-748,188,-696 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Default" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:456,-748,620,-696 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Cancel" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:636,-756,820,-688 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Set" + text.size:* + text.validation:"R6,3" + } + wimp_icon { + extent:16,-664,820,-496 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:36,-524,240,-480 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Hotlist" + text_and_sprite.size:23 + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-576,728,-532 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Use external hotlist apps when available" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:28,-644,232,-592 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Hotlist path" + text.size:* + text.validation:"" + } + wimp_icon { + extent:232,-644,800,-592 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"Writable icon" + text.size:256 + text.validation:"Pptr_write;Kta" + } +} + +wimp_window { + template_name:"con_lang" + visible:1574,956,2318,1256 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-300,744,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + work_flags: + sprite_area:&1 + xmin:744 + ymin:300 + text_only:"Language" + wimp_icon { + extent:16,-188,728,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-52,284,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Language " + text_and_sprite.size:16 + text_and_sprite.validation:"" + } + wimp_icon { + extent:48,-108,204,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Interface" + } + wimp_icon { + extent:208,-112,660,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"1337" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:668,-108,712,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:44,-168,204,-124 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Web pages" + } + wimp_icon { + extent:208,-172,660,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"8008135" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:668,-168,712,-124 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:24,-272,188,-220 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Default" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:360,-272,524,-220 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Cancel" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:540,-280,724,-212 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Set" + text.size:* + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"con_theme" + visible:410,38,1318,642 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-604,908,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + work_flags: + sprite_area:&1 + xmin:640 + ymin:604 + text_only:"Themes" + wimp_icon { + extent:16,-492,892,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-52,332,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Available themes " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:24,-576,188,-524 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Default" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:524,-576,688,-524 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Cancel" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:704,-584,888,-516 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Set" + text.size:* + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"download" + visible:486,610,1394,890 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BACK_ICON | wimp_WINDOW_CLOSE_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-280,908,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:80 + ymin:28 + text.text:"NetSurf Download" + text.size:* + text.validation:"" + wimp_icon { + extent:420,-84,488,-16 + icon_flags:wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK_DRAG + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + sprite.id:"file_ddc" + sprite.size:* + sprite.area:&1 + } + wimp_icon { + extent:204,-152,900,-100 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"http://netsurf.sourceforge.net/netsurf.zip" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:204,-212,900,-160 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"netsurf" + text.size:* + text.validation:"Pptr_write" + } + wimp_icon { + extent:204,-212,900,-160 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"ADFS::A7000+.$.netsurf" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:8,-272,900,-220 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:12,-268,296,-224 + icon_flags:wimp_ICON_FILLED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_CREAM + } + wimp_icon { + extent:12,-268,896,-224 + icon_flags:wimp_ICON_TEXT | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"84.4KB of 1.1MB 26.6KB/s 0:39 remaining" + text.size:* + text.validation:"" + } + wimp_icon { + extent:92,-148,200,-104 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Source" + } + wimp_icon { + extent:12,-208,200,-164 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Destination" + } +} + +wimp_window { + template_name:"history" + visible:252,388,1152,808 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_SCROLL_REPEAT | wimp_WINDOW_BACK_ICON | wimp_WINDOW_CLOSE_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_TOGGLE_ICON | wimp_WINDOW_VSCROLL | wimp_WINDOW_SIZE_ICON | wimp_WINDOW_HSCROLL | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_WHITE + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-880,1236,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags:wimp_BUTTON_CLICK + sprite_area:&1 + xmin:0 + ymin:0 + text.text:"History" + text.size:* + text.validation:"" +} + +wimp_window { + template_name:"info" + visible:752,452,1372,700 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_CREAM + scroll_inner:wimp_COLOUR_ORANGE + highlight_bg:wimp_COLOUR_LIGHT_GREY + extra_flags: + extent:0,-248,620,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + work_flags:wimp_BUTTON_CLICK + sprite_area:&1 + xmin:620 + ymin:248 + text.text:"About this program" + text.size:* + text.validation:"" + wimp_icon { + extent:672,-200,848,-152 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_RED + text_only:"OK" + } + wimp_icon { + extent:152,-60,612,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK_DRAG + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"NetSurf" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:152,-120,612,-68 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK_DRAG + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Open source web browser" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:152,-180,612,-128 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK_DRAG + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"© NetSurf developers" + text.size:40 + text.validation:"R2" + } + wimp_icon { + extent:152,-240,612,-188 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK_DRAG + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"CVS test build" + text.size:40 + text.validation:"R2" + } + wimp_icon { + extent:52,-56,148,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Name" + } + wimp_icon { + extent:24,-116,148,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Purpose" + } + wimp_icon { + extent:24,-176,148,-132 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Authors" + } + wimp_icon { + extent:24,-236,148,-192 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Version" + } +} + +wimp_window { + template_name:"login" + visible:582,400,1258,736 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-336,676,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:676 + ymin:336 + text.text:"Site Authentication" + text.size:* + text.validation:"" + wimp_icon { + extent:532,-324,664,-256 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Login" + text.size:8 + text.validation:"R6,3;Nok" + } + wimp_icon { + extent:380,-316,508,-264 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Cancel" + text.size:* + text.validation:"R5,3;Ncancel" + } + wimp_icon { + extent:168,-60,668,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"moo.yoo.com" + text.size:255 + text.validation:"R2" + } + wimp_icon { + extent:168,-120,668,-68 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"my sekr3t area" + text.size:255 + text.validation:"R2" + } + wimp_icon { + extent:168,-180,668,-128 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:255 + text.validation:"Pptr_write;Kta;N401username" + } + wimp_icon { + extent:168,-240,668,-188 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:255 + text.validation:"Pptr_write;Kta;D*" + } + wimp_icon { + extent:84,-56,164,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Host" + } + wimp_icon { + extent:8,-176,164,-132 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Username" + } + wimp_icon { + extent:20,-236,164,-192 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Password" + } + wimp_icon { + extent:64,-116,164,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Realm" + } +} + +wimp_window { + template_name:"new_entry" + visible:480,660,1080,880 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-220,600,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:600 + ymin:220 + text.text:"" + text.size:32 + text.validation:"" + wimp_icon { + extent:12,-56,108,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Name" + } + wimp_icon { + extent:112,-60,588,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:128 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:12,-116,108,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"URL" + } + wimp_icon { + extent:112,-120,532,-68 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:1024 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:304,-200,432,-148 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Cancel" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:456,-208,588,-140 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"OK" + text.size:8 + text.validation:"R6,3" + } + wimp_icon { + extent:540,-116,584,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } +} + +wimp_window { + template_name:"new_folder" + visible:480,954,1080,1114 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-160,600,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:600 + ymin:160 + text.text:"" + text.size:21 + text.validation:"" + wimp_icon { + extent:12,-56,108,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Name" + } + wimp_icon { + extent:112,-60,588,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:128 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:304,-140,432,-88 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Cancel" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:456,-148,588,-80 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"OK" + text.size:8 + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"objectinfo" + visible:428,292,1216,480 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-188,788,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags:wimp_BUTTON_CLICK + sprite_area:&1 + xmin:788 + ymin:188 + text.text:"About this object" + text.size:20 + text.validation:"" + wimp_icon { + extent:204,-60,780,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:64 + text.validation:"R2" + } + wimp_icon { + extent:204,-120,780,-68 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:64 + text.validation:"R2" + } + wimp_icon { + extent:204,-180,780,-128 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:64 + text.validation:"R2" + } + wimp_icon { + extent:12,-80,84,-12 + icon_flags:wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + sprite.id:"file_faf" + sprite.size:* + sprite.area:&1 + } + wimp_icon { + extent:92,-116,200,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Target" + } + wimp_icon { + extent:120,-176,200,-132 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Type" + } + wimp_icon { + extent:120,-56,200,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"URL" + } +} + +wimp_window { + template_name:"open_url" + visible:248,266,1048,422 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-156,800,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:0 + ymin:0 + text_only:"Open URL" + wimp_icon { + extent:12,-56,92,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"URL" + } + wimp_icon { + extent:96,-60,736,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:1 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:504,-136,632,-84 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Cancel" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:656,-144,788,-76 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Open" + text.size:8 + text.validation:"R6,3" + } + wimp_icon { + extent:744,-56,788,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } +} + +wimp_window { + template_name:"pageinfo" + visible:310,528,1102,776 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-248,792,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:792 + ymin:248 + text.text:"About this document" + text.size:* + text.validation:"" + wimp_icon { + extent:208,-60,784,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:64 + text.validation:"R2" + } + wimp_icon { + extent:208,-120,784,-68 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:64 + text.validation:"R2" + } + wimp_icon { + extent:208,-180,784,-128 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:64 + text.validation:"R2" + } + wimp_icon { + extent:208,-240,784,-188 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:64 + text.validation:"R2" + } + wimp_icon { + extent:12,-80,84,-12 + icon_flags:wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + sprite.id:"file_faf" + sprite.size:* + sprite.area:&1 + } + wimp_icon { + extent:124,-116,204,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"URL" + } + wimp_icon { + extent:60,-176,204,-132 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Encoding" + } + wimp_icon { + extent:124,-236,204,-192 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Type" + } + wimp_icon { + extent:112,-56,204,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Title" + } +} + +wimp_window { + template_name:"print" + visible:472,136,1132,708 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-572,700,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:600 + ymin:572 + text.text:"No Printer" + text.size:20 + text.validation:"" + wimp_icon { + extent:12,-176,652,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-100,504,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:1 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"the bottom of the web page" + text_and_sprite.size:* + text_and_sprite.validation:"Sradiooff,radioon" + } + wimp_icon { + extent:32,-152,492,-108 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:1 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:6 + text_and_sprite.validation:"Sradiooff,radioon" + } + wimp_icon { + extent:84,-156,164,-104 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"1" + text.size:3 + text.validation:"Pptr_write;Kta;A0-9" + } + wimp_icon { + extent:176,-148,208,-116 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:208,-148,240,-116 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:244,-152,528,-108 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"sheets are filled" + text.size:* + text.validation:"" + } + wimp_icon { + extent:12,-236,420,-192 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Show foreground images" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:12,-288,420,-244 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Show background images" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:12,-340,372,-296 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Print in background" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:12,-404,180,-360 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_SELECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Upright" + text_and_sprite.size:* + text_and_sprite.validation:"Sradiooff,radioon" + } + wimp_icon { + extent:12,-452,196,-408 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Sideways" + text_and_sprite.size:* + text_and_sprite.validation:"Sradiooff,radioon" + } + wimp_icon { + extent:480,-456,560,-404 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"1" + text.size:3 + text.validation:"Pptr_write;Kta;A0-9" + } + wimp_icon { + extent:572,-448,604,-416 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:604,-448,636,-416 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:364,-552,492,-500 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Cancel" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:516,-560,648,-492 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Print" + text.size:8 + text.validation:"R6,3" + } + wimp_icon { + extent:368,-452,476,-408 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Copies" + } + wimp_icon { + extent:-16,-480,676,-472 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:32,-48,364,-4 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" End printing after " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:232,-400,656,-356 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Print all text in black" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } +} + +wimp_window { + template_name:"query" + visible:142,562,942,806 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_LIGHT_GREY + extra_flags: + extent:0,-244,800,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:0 + ymin:0 + text.text:"Query from NetSurf" + text.size:21 + text.validation:"" + wimp_icon { + extent:92,-148,792,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Message" + text.size:300 + text.validation:"R2;L" + } + wimp_icon { + extent:604,-232,788,-164 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"012345678901234567" + text.size:* + text.validation:"R6,3" + } + wimp_icon { + extent:424,-224,588,-172 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"012345678901234567" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:16,-224,132,-172 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Help" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:12,-80,80,-12 + icon_flags:wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + sprite_only:"!netsurf" + } +} + +wimp_window { + template_name:"saveas" + visible:824,676,1140,924 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BOUNDED_ONCE | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-248,316,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:308 + ymin:244 + text_only:"Save as" + wimp_icon { + extent:124,-84,192,-16 + icon_flags:wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK_DRAG + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + sprite.id:"file_faf" + sprite.size:13 + sprite.area:&1 + } + wimp_icon { + extent:8,-152,308,-100 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:256 + text.validation:"Pptr_write" + } + wimp_icon { + extent:172,-236,304,-168 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Save" + text.size:* + text.validation:"R6,3" + } + wimp_icon { + extent:20,-228,148,-176 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Cancel" + text.size:* + text.validation:"R5,3" + } +} + +wimp_window { + template_name:"search" + visible:1036,684,1680,928 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-244,644,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:644 + ymin:244 + text.text:"Find text" + text.size:* + text.validation:"" + wimp_icon { + extent:96,-60,580,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:32 + text.validation:"KN;Pptr_write" + } + wimp_icon { + extent:96,-116,376,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Case sensitive" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:500,-228,632,-160 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Next" + text.size:10 + text.validation:"R6,3" + } + wimp_icon { + extent:348,-220,484,-168 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Previous" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:204,-220,332,-168 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Cancel" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:16,-216,196,-172 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Not found" + text.size:* + text.validation:"" + } + wimp_icon { + extent:-8,-148,652,-140 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:16,-56,92,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Find" + } + wimp_icon { + extent:588,-56,632,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_ICON_SHADED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:408,-116,592,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Show all" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } +} + +wimp_window { + template_name:"theme_inst" + visible:374,590,1174,834 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-244,800,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:800 + ymin:244 + text.text:"NetSurf theme installer" + text.size:* + text.validation:"" + wimp_icon { + extent:92,-148,792,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Message" + text.size:300 + text.validation:"R2;L" + } + wimp_icon { + extent:640,-232,788,-164 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Install" + text.size:* + text.validation:"R6,3" + } + wimp_icon { + extent:488,-224,616,-172 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Cancel" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:12,-80,80,-12 + icon_flags:wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + sprite_only:"!netsurf" + } +} + +wimp_window { + template_name:"tooltip" + visible:884,620,1148,656 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BOUNDED_ONCE | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-36,2000,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + work_flags: + sprite_area:&1 + xmin:0 + ymin:0 + text_only:"<Untitled>" + wimp_icon { + extent:0,-40,300,4 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Comment" + text.size:256 + text.validation:"" + } +} + +wimp_window { + template_name:"tree" + visible:530,654,1042,954 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_SCROLL_REPEAT | wimp_WINDOW_IGNORE_XEXTENT | wimp_WINDOW_IGNORE_YEXTENT | wimp_WINDOW_BOUNDED_ONCE | wimp_WINDOW_BACK_ICON | wimp_WINDOW_CLOSE_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_TOGGLE_ICON | wimp_WINDOW_VSCROLL | wimp_WINDOW_SIZE_ICON | wimp_WINDOW_HSCROLL | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_TRANSPARENT + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-880,1236,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags:wimp_BUTTON_DOUBLE_CLICK_DRAG + sprite_area:&1 + xmin:0 + ymin:0 + text.text:"" + text.size:64 + text.validation:"" +} + +wimp_window { + template_name:"url_suggest" + visible:320,390,1102,684 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_NO_BOUNDS | wimp_WINDOW_IGNORE_XEXTENT | wimp_WINDOW_IGNORE_YEXTENT | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_TRANSPARENT + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-65536,65536,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + work_flags:wimp_BUTTON_CLICK + sprite_area:&1 + xmin:0 + ymin:0 + text_only:"<Untitled>" +} + +wimp_window { + template_name:"warning" + visible:320,850,1120,1094 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BOUNDED_ONCE | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-244,800,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:0 + ymin:0 + text.text:"Warning from NetSurf" + text.size:* + text.validation:"" + wimp_icon { + extent:92,-148,792,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Message" + text.size:300 + text.validation:"R2;L" + } + wimp_icon { + extent:608,-232,788,-164 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Continue" + text.size:* + text.validation:"R6,3" + } + wimp_icon { + extent:484,-224,584,-172 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Help" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:12,-80,80,-12 + icon_flags:wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + sprite_only:"!netsurf" + } +} + +wimp_window { + template_name:"zoom" + visible:182,356,630,578 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BOUNDED_ONCE | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-224,448,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + work_flags: + sprite_area:&1 + xmin:448 + ymin:220 + text_only:"Scale view" + wimp_icon { + extent:8,-56,100,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Scale" + } + wimp_icon { + extent:104,-60,204,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"100" + text.size:5 + text.validation:"Pptr_write;KTA;A0-9." + } + wimp_icon { + extent:216,-52,248,-20 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"R5;sdown,pdown" + } + wimp_icon { + extent:248,-52,280,-20 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"R5;sup,pup" + } + wimp_icon { + extent:284,-56,324,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_HCENTRED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"%" + } + wimp_icon { + extent:104,-112,416,-68 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Scale all frames" + text_and_sprite.size:20 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:-4,-132,716,-124 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:164,-204,292,-152 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Cancel" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:308,-212,440,-144 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Scale" + text.size:* + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"ssldisplay" + visible:862,768,1822,1308 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BOUNDED_ONCE | wimp_WINDOW_CLOSE_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-540,960,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:960 + ymin:76 + text.text:"SSL certificate" + text.size:* + text.validation:"" + wimp_icon { + extent:16,-520,944,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-52,380,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Certificate details " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:24,-108,148,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Version" + } + wimp_icon { + extent:152,-108,264,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:284,-104,456,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Valid from" + } + wimp_icon { + extent:460,-108,928,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:68,-168,148,-124 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Type" + } + wimp_icon { + extent:152,-168,264,-116 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:268,-164,456,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Valid until" + } + wimp_icon { + extent:460,-168,928,-116 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:40,-228,148,-184 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Serial" + } + wimp_icon { + extent:152,-228,928,-176 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:40,-288,148,-244 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Issuer" + } + wimp_icon { + extent:152,-376,928,-236 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2;L" + } + wimp_icon { + extent:24,-432,148,-388 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Subject" + } + wimp_icon { + extent:152,-504,928,-384 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2;L" + } +} + +wimp_window { + template_name:"con_secure" + visible:1590,788,2182,1152 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-364,592,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + work_flags: + sprite_area:&1 + xmin:592 + ymin:364 + text_only:"Security" + wimp_icon { + extent:16,-120,576,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-52,364,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Cross-site privacy " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-104,568,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Send site referral information" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:16,-252,576,-148 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-176,316,-132 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Site history " + text_and_sprite.size:18 + text_and_sprite.validation:"" + } + wimp_icon { + extent:24,-228,164,-184 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Duration" + } + wimp_icon { + extent:168,-232,336,-180 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"12" + text.size:4 + text.validation:"Pptr_write;Kta;A0-9" + } + wimp_icon { + extent:352,-224,384,-192 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:384,-224,416,-192 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:424,-228,500,-184 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"days" + } + wimp_icon { + extent:24,-336,188,-284 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Default" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:208,-336,372,-284 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Cancel" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:388,-344,572,-276 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Set" + text.size:* + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"con_content" + visible:1248,854,1912,1354 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-500,664,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:640 + ymin:452 + text_only:"Content" + wimp_icon { + extent:16,-272,644,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-52,492,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Content blocking " + text_and_sprite.size:29 + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-100,392,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Hide advertisements" + text_and_sprite.size:39 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:32,-152,440,-108 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Disable pop-up windows" + text_and_sprite.size:46 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:32,-256,344,-212 +#ifdef WITH_PLUGIN + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO +#else + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_DELETED | wimp_BUTTON_RADIO +#endif + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Disable plug-ins" + text_and_sprite.size:42 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:16,-384,644,-292 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-320,492,-276 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Link targets " + text_and_sprite.size:29 + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-368,632,-324 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Allow links to open in new windows" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:24,-468,188,-416 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Default" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:280,-468,444,-416 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Cancel" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:460,-476,644,-408 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Set" + text.size:* + text.validation:"R6,3" + } + wimp_icon { + extent:32,-204,376,-160 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Disable JavaScript" + text_and_sprite.size:19 + text_and_sprite.validation:"Soptoff,opton" + } +} + +wimp_window { + template_name:"con_connect" + visible:1328,566,2008,1234 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-668,680,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + work_flags: + sprite_area:&1 + xmin:660 + ymin:668 + text_only:"Connection" + wimp_icon { + extent:16,-304,664,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:28,-52,232,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" HTTP Proxy " + text_and_sprite.size:15 + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-104,204,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Proxy type" + } + wimp_icon { + extent:208,-108,592,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:32 + text.validation:"R2" + } + wimp_icon { + extent:600,-104,644,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:124,-164,204,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Host" + text.size:* + text.validation:"" + } + wimp_icon { + extent:208,-168,524,-116 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"myhost.proxy" + text.size:255 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:520,-164,548,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_HCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:":" + text.size:* + text.validation:"" + } + wimp_icon { + extent:544,-168,648,-116 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"8080" + text.size:8 + text.validation:"Pptr_write;Kta;A0-9" + } + wimp_icon { + extent:48,-224,204,-180 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Username" + text.size:* + text.validation:"" + } + wimp_icon { + extent:208,-228,648,-176 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"k1dd13" + text.size:64 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:60,-284,204,-240 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Password" + text.size:* + text.validation:"" + } + wimp_icon { + extent:208,-288,648,-236 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"1337" + text.size:64 + text.validation:"Pptr_write;Kta;D*" + } + wimp_icon { + extent:16,-552,664,-332 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-360,204,-316 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Fetching " + text_and_sprite.size:15 + text_and_sprite.validation:"" + } + wimp_icon { + extent:80,-412,340,-368 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Maximum fetches" + text.size:* + text.validation:"" + } + wimp_icon { + extent:344,-416,552,-364 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"99" + text.size:* + text.validation:"Pptr_write;Kta;A0-9" + } + wimp_icon { + extent:568,-408,600,-376 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:600,-408,632,-376 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:72,-472,340,-428 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Fetches per host" + text.size:18 + text.validation:"" + } + wimp_icon { + extent:344,-476,552,-424 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"99" + text.size:4 + text.validation:"Pptr_write;Kta;A0-9" + } + wimp_icon { + extent:568,-468,604,-436 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:600,-468,632,-436 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:40,-532,340,-488 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Cached connections" + text.size:* + text.validation:"" + } + wimp_icon { + extent:344,-536,552,-484 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"99" + text.size:4 + text.validation:"Pptr_write;Kta;A0-9" + } + wimp_icon { + extent:568,-528,604,-496 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:600,-528,632,-496 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:24,-640,188,-588 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Default" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:296,-640,460,-588 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Cancel" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:476,-648,660,-580 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Set" + text.size:* + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"sslcert" + visible:348,306,1136,898 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BOUNDED_ONCE | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-592,788,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:788 + ymin:592 + text.text:"SSL certificate problem" + text.size:* + text.validation:"" + wimp_icon { + extent:16,-108,772,-16 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"NetSurf failed to verify the authenticity of an SSL certificate. Please verify the details presented below." + text.size:150 + text.validation:"R2;L" + } + wimp_icon { + extent:16,-484,772,-136 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-164,380,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Certificate chain " + text_and_sprite.size:22 + text_and_sprite.validation:"" + } + wimp_icon { + extent:404,-564,568,-512 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Reject" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:588,-572,772,-504 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Accept" + text.size:8 + text.validation:"R6,3" + } +} diff --git a/frontends/riscos/templates/fr b/frontends/riscos/templates/fr new file mode 100644 index 000000000..67792642c --- /dev/null +++ b/frontends/riscos/templates/fr @@ -0,0 +1,3862 @@ +Template: + +wimp_window { + template_name:"configure" + visible:378,820,1046,1126 + xscroll:0 + yscroll:-574 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BACK_ICON | wimp_WINDOW_CLOSE_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_TOGGLE_ICON | wimp_WINDOW_VSCROLL | wimp_WINDOW_SIZE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_LIGHT_GREY + extra_flags: + extent:0,-880,1236,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:4 + ymin:156 + text.text:"NetSurf configuration" + text.size:* + text.validation:"" +} + +wimp_window { + template_name:"con_cache" + visible:564,536,1152,964 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-428,588,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + work_flags: + sprite_area:&1 + xmin:588 + ymin:240 + text_only:"Cache" + wimp_icon { + extent:16,-124,568,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-52,284,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Cache mémoire " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:44,-104,164,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Taille" + text.size:13 + text.validation:"" + } + wimp_icon { + extent:168,-108,336,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"512.0" + text.size:10 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:352,-100,384,-68 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:384,-100,416,-68 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:424,-104,480,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"MB" + } + wimp_icon { + extent:16,-312,568,-152 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-180,268,-136 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Disc cache " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:44,-232,164,-188 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Taille" + text.size:13 + text.validation:"" + } + wimp_icon { + extent:168,-236,336,-184 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"512" + text.size:10 + text.validation:"Pptr_write;Kta;A0-9" + } + wimp_icon { + extent:352,-228,384,-196 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:384,-228,416,-196 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:424,-232,480,-192 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"MB" + } + wimp_icon { + extent:44,-292,164,-248 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Expiry" + text.size:13 + text.validation:"" + } + wimp_icon { + extent:168,-296,336,-244 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"512" + text.size:10 + text.validation:"Pptr_write;Kta;A0-9" + } + wimp_icon { + extent:352,-288,384,-256 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:384,-288,416,-256 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:424,-292,500,-252 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"days" + } + wimp_icon { + extent:24,-396,188,-344 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Par défaut" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:204,-396,368,-344 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuler" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:384,-404,568,-336 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Valider" + text.size:* + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"con_fonts" + visible:316,250,1028,974 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-724,712,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:712 + ymin:724 + text_only:"Fontes" + wimp_icon { + extent:16,-424,696,-28 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-52,236,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Polices " + text_and_sprite.size:13 + text_and_sprite.validation:"" + } + wimp_icon { + extent:20,-104,192,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Sans-serif" + } + wimp_icon { + extent:196,-108,620,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:632,-104,676,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:100,-164,192,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Serif" + } + wimp_icon { + extent:196,-168,620,-116 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:632,-164,676,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:28,-224,192,-180 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Monospace" + } + wimp_icon { + extent:196,-228,620,-176 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:632,-224,676,-180 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:68,-284,192,-240 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Cursive" + } + wimp_icon { + extent:196,-288,620,-236 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:632,-284,676,-240 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:28,-344,192,-300 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Fantaisiste" + } + wimp_icon { + extent:196,-348,620,-296 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:632,-344,676,-300 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:48,-404,192,-360 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Par défaut" + } + wimp_icon { + extent:196,-408,620,-356 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:632,-404,676,-360 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:16,-612,696,-452 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-480,316,-436 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Taille de fonte " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:28,-532,192,-488 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Par défaut" + } + wimp_icon { + extent:196,-536,364,-484 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"12.3" + text.size:10 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:380,-528,412,-496 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:412,-528,444,-496 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:452,-532,492,-488 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"pt" + } + wimp_icon { + extent:60,-592,192,-548 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Minimum" + } + wimp_icon { + extent:196,-596,364,-544 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"12.3" + text.size:10 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:380,-588,412,-556 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:412,-588,444,-556 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:452,-592,492,-548 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"pt" + } + wimp_icon { + extent:24,-696,188,-644 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Par défaut" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:332,-696,496,-644 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuler" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:512,-704,696,-636 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Valider" + text.size:* + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"con_home" + visible:288,150,1088,446 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BOUNDED_ONCE | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-296,800,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:800 + ymin:296 + text.text:"Page d'accueil" + text.size:* + text.validation:"" + wimp_icon { + extent:16,-184,784,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-52,300,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Page d'accueil " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:48,-108,120,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"URL" + } + wimp_icon { + extent:124,-112,712,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:128 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:720,-108,764,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:124,-164,676,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Ouvrir une fenêtre au démarrage" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:24,-264,188,-212 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Par défaut" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:416,-264,580,-212 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuler" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:596,-272,780,-204 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Valider" + text.size:* + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"con_image" + visible:828,908,1504,1496 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-588,676,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + work_flags: + sprite_area:&1 + xmin:676 + ymin:588 + text_only:"Images" + wimp_icon { + extent:16,-292,660,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-52,332,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Qualité d'images " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:24,-108,204,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Premier plan" + text.size:* + text.validation:"" + } + wimp_icon { + extent:208,-112,592,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Error diffused" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:600,-108,644,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:32,-168,204,-124 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Fond" + } + wimp_icon { + extent:208,-172,592,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Error diffused" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:600,-168,644,-124 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:32,-276,644,-180 + icon_flags:wimp_ICON_BORDER + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + } + wimp_icon { + extent:16,-476,660,-320 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-348,284,-304 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Animations " + text_and_sprite.size:16 + text_and_sprite.validation:"" + } + wimp_icon { + extent:20,-404,208,-360 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Vitesse limite" + text.size:* + text.validation:"" + } + wimp_icon { + extent:212,-408,380,-356 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"12.34" + text.size:* + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:396,-400,428,-368 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:428,-400,460,-368 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:468,-404,592,-360 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"secondes" + text.size:* + text.validation:"" + } + wimp_icon { + extent:212,-460,628,-416 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Désactiver les animations" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:24,-560,188,-508 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Par défaut" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:296,-560,460,-508 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuler" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:476,-568,660,-500 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Valider" + text.size:* + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"con_lang" + visible:770,1102,1514,1402 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BOUNDED_ONCE | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-300,744,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:744 + ymin:300 + text_only:"Langue" + wimp_icon { + extent:16,-188,728,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-52,284,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Langue " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:48,-108,204,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Interface" + } + wimp_icon { + extent:208,-112,660,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"1337" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:668,-108,712,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:40,-168,204,-124 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Pages web" + } + wimp_icon { + extent:208,-172,660,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"8008135" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:668,-168,712,-124 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:24,-268,188,-216 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Par défaut" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:360,-268,524,-216 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuler" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:540,-276,724,-208 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Valider" + text.size:* + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"con_theme" + visible:408,370,1316,974 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-604,908,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:640 + ymin:604 + text_only:"Thèmes" + wimp_icon { + extent:16,-492,892,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-52,364,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Thèmes disponibles " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:24,-576,188,-524 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Par défaut" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:524,-576,688,-524 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuler" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:704,-584,888,-516 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Valider" + text.size:* + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"download" + visible:486,610,1394,890 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BOUNDED_ONCE | wimp_WINDOW_BACK_ICON | wimp_WINDOW_CLOSE_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-280,908,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:80 + ymin:28 + text.text:"Téléchargement de Netsurf" + text.size:* + text.validation:"" + wimp_icon { + extent:420,-84,488,-16 + icon_flags:wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK_DRAG + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + sprite.id:"file_ddc" + sprite.size:* + sprite.area:&1 + } + wimp_icon { + extent:204,-152,900,-100 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"http://netsurf.sourceforge.net/netsurf.zip" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:204,-212,900,-160 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"netsurf" + text.size:* + text.validation:"Pptr_write" + } + wimp_icon { + extent:204,-212,900,-160 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"ADFS::A7000+.$.netsurf" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:8,-272,900,-220 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:12,-268,296,-224 + icon_flags:wimp_ICON_FILLED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_CREAM + } + wimp_icon { + extent:12,-268,896,-224 + icon_flags:wimp_ICON_TEXT | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"84.4KB of 1.1MB 26.6KB/s 0:39 remaining" + text.size:* + text.validation:"" + } + wimp_icon { + extent:92,-148,200,-104 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Source" + } + wimp_icon { + extent:12,-208,200,-164 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Destination" + } +} + +wimp_window { + template_name:"history" + visible:252,388,1152,808 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_SCROLL_REPEAT | wimp_WINDOW_BOUNDED_ONCE | wimp_WINDOW_BACK_ICON | wimp_WINDOW_CLOSE_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_TOGGLE_ICON | wimp_WINDOW_VSCROLL | wimp_WINDOW_SIZE_ICON | wimp_WINDOW_HSCROLL | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_WHITE + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-880,1236,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags:wimp_BUTTON_CLICK + sprite_area:&1 + xmin:0 + ymin:0 + text.text:"Historique" + text.size:* + text.validation:"" +} + +wimp_window { + template_name:"info" + visible:506,58,1126,306 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BOUNDED_ONCE | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_CREAM + scroll_inner:wimp_COLOUR_ORANGE + highlight_bg:wimp_COLOUR_LIGHT_GREY + extra_flags: + extent:0,-248,620,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + work_flags:wimp_BUTTON_CLICK + sprite_area:&1 + xmin:0 + ymin:0 + text.text:"A propos de ce programme" + text.size:* + text.validation:"" + wimp_icon { + extent:676,-204,852,-156 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_RED + text_only:"OK" + } + wimp_icon { + extent:152,-60,612,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK_DRAG + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"NetSurf" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:152,-120,612,-68 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK_DRAG + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Navigateur web libre" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:152,-180,612,-128 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK_DRAG + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"© Développeurs NetSurf" + text.size:40 + text.validation:"R2" + } + wimp_icon { + extent:152,-240,612,-188 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK_DRAG + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"CVS test build" + text.size:40 + text.validation:"R2" + } + wimp_icon { + extent:76,-56,148,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Nom" + } + wimp_icon { + extent:20,-116,148,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Fonction" + } + wimp_icon { + extent:24,-176,148,-132 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Auteurs" + } + wimp_icon { + extent:24,-236,148,-192 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Version" + } + wimp_icon { + extent:4,-8,4,262328 + icon_flags:wimp_ICON_TEXT | wimp_ICON_DELETED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text_only:"<Deleted>" + } +} + +wimp_window { + template_name:"login" + visible:566,258,1242,594 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BOUNDED_ONCE | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-336,676,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:676 + ymin:336 + text.text:"Authentification du Site" + text.size:* + text.validation:"" + wimp_icon { + extent:532,-324,664,-256 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Entrer" + text.size:8 + text.validation:"R6,3;Nok" + } + wimp_icon { + extent:376,-316,508,-264 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuler" + text.size:* + text.validation:"R5,3;Ncancel" + } + wimp_icon { + extent:200,-60,668,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"moo.yoo.com" + text.size:255 + text.validation:"R2" + } + wimp_icon { + extent:200,-120,668,-68 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"my sekr3t area" + text.size:255 + text.validation:"R2" + } + wimp_icon { + extent:200,-180,668,-128 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:255 + text.validation:"Pptr_write;Kta;N401username" + } + wimp_icon { + extent:200,-240,668,-188 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:255 + text.validation:"Pptr_write;Kta;D*" + } + wimp_icon { + extent:120,-56,196,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Hôte" + } + wimp_icon { + extent:8,-176,196,-132 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Identifiant" + text.size:* + text.validation:"" + } + wimp_icon { + extent:8,-236,196,-192 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Code secret" + text.size:* + text.validation:"" + } + wimp_icon { + extent:68,-116,196,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Domaine" + } +} + +wimp_window { + template_name:"new_entry" + visible:1120,590,1720,810 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-220,600,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:600 + ymin:220 + text.text:"" + text.size:32 + text.validation:"" + wimp_icon { + extent:12,-56,108,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Nom" + } + wimp_icon { + extent:112,-60,588,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:128 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:12,-116,108,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"URL" + } + wimp_icon { + extent:112,-120,532,-68 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:1024 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:304,-200,436,-148 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuler" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:456,-208,588,-140 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"OK" + text.size:8 + text.validation:"R6,3" + } + wimp_icon { + extent:540,-116,584,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } +} + +wimp_window { + template_name:"new_folder" + visible:596,278,1196,438 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-160,600,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:600 + ymin:160 + text.text:"" + text.size:25 + text.validation:"" + wimp_icon { + extent:12,-56,108,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Nom" + } + wimp_icon { + extent:112,-60,588,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:128 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:304,-140,436,-88 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuler" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:456,-148,588,-80 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"OK" + text.size:8 + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"objectinfo" + visible:276,892,1064,1084 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-192,788,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags:wimp_BUTTON_CLICK + sprite_area:&1 + xmin:0 + ymin:0 + text.text:"À propos de cet objet" + text.size:* + text.validation:"" + wimp_icon { + extent:208,-60,784,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:64 + text.validation:"R2" + } + wimp_icon { + extent:208,-120,784,-68 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:64 + text.validation:"R2" + } + wimp_icon { + extent:208,-180,784,-128 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:64 + text.validation:"R2" + } + wimp_icon { + extent:12,-80,84,-12 + icon_flags:wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + sprite.id:"file_faf" + sprite.size:* + sprite.area:&1 + } + wimp_icon { + extent:112,-116,204,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Cible" + } + wimp_icon { + extent:124,-176,204,-132 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Type" + } + wimp_icon { + extent:132,-56,204,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"URL" + } +} + +wimp_window { + template_name:"open_url" + visible:440,134,1240,290 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-156,800,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:0 + ymin:0 + text.text:"Ouvrir l'URL" + text.size:* + text.validation:"" + wimp_icon { + extent:20,-56,92,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"URL" + } + wimp_icon { + extent:96,-60,736,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:1 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:504,-136,632,-84 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuler" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:656,-144,788,-76 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Ouvrir" + text.size:8 + text.validation:"R6,3" + } + wimp_icon { + extent:744,-56,788,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } +} + +wimp_window { + template_name:"pageinfo" + visible:348,298,1140,546 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-248,792,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags:wimp_BUTTON_CLICK + sprite_area:&1 + xmin:792 + ymin:248 + text.text:"À propos de ce document" + text.size:* + text.validation:"" + wimp_icon { + extent:208,-60,784,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:64 + text.validation:"R2" + } + wimp_icon { + extent:208,-120,784,-68 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:64 + text.validation:"R2" + } + wimp_icon { + extent:208,-180,784,-128 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:64 + text.validation:"R2" + } + wimp_icon { + extent:208,-240,784,-188 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:64 + text.validation:"R2" + } + wimp_icon { + extent:12,-80,84,-12 + icon_flags:wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + sprite.id:"file_faf" + sprite.size:* + sprite.area:&1 + } + wimp_icon { + extent:132,-116,204,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"URL" + } + wimp_icon { + extent:60,-176,204,-132 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Encodage" + } + wimp_icon { + extent:124,-236,204,-192 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Type" + } + wimp_icon { + extent:112,-56,204,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Titre" + } +} + +wimp_window { + template_name:"print" + visible:464,144,1064,716 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-572,600,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:0 + ymin:0 + text.text:"Pas d'imprimante" + text.size:20 + text.validation:"" + wimp_icon { + extent:12,-176,588,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:1 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-100,504,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:1 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"le bas de la page web" + text_and_sprite.size:27 + text_and_sprite.validation:"Sradiooff,radioon" + } + wimp_icon { + extent:32,-152,492,-108 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:1 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:6 + text_and_sprite.validation:"Sradiooff,radioon" + } + wimp_icon { + extent:84,-156,164,-104 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"1" + text.size:3 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:176,-148,208,-116 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:208,-148,240,-116 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:244,-152,528,-108 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"feuilles remplies" + text.size:* + text.validation:"" + } + wimp_icon { + extent:12,-236,580,-192 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Imprimer les images d'avant-plan" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:12,-288,500,-244 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Imprimer les images de fond" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:12,-340,468,-296 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Imprimer en tâche de fond" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:12,-404,180,-360 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Portrait" + text_and_sprite.size:* + text_and_sprite.validation:"Sradiooff,radioon" + } + wimp_icon { + extent:12,-452,196,-408 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Paysage" + text_and_sprite.size:9 + text_and_sprite.validation:"Sradiooff,radioon" + } + wimp_icon { + extent:428,-456,508,-404 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"1" + text.size:3 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:524,-448,556,-416 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:556,-448,588,-416 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:268,-552,400,-500 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuler" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:424,-560,588,-492 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Imprimer" + text.size:* + text.validation:"R6,3" + } + wimp_icon { + extent:284,-452,424,-408 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Copies" + } + wimp_icon { + extent:-12,-480,604,-472 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:32,-52,460,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Finir l'impression après " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:252,-400,676,-356 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Tout le texte en noir" + text_and_sprite.size:24 + text_and_sprite.validation:"Soptoff,opton" + } +} + +wimp_window { + template_name:"query" + visible:426,1082,1226,1326 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_LIGHT_GREY + extra_flags: + extent:0,-244,800,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:0 + ymin:0 + text.text:"Question de NetSurf" + text.size:21 + text.validation:"" + wimp_icon { + extent:92,-148,792,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Message" + text.size:300 + text.validation:"R2;L" + } + wimp_icon { + extent:636,-232,788,-164 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"012345678901234567" + text.size:* + text.validation:"R6,3" + } + wimp_icon { + extent:504,-224,620,-172 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"012345678901234567" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:8,-224,124,-172 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Aide" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:12,-80,80,-12 + icon_flags:wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + sprite_only:"!netsurf" + } +} + +wimp_window { + template_name:"saveas" + visible:682,168,998,416 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-248,316,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:0 + ymin:0 + text_only:"Sauver sous" + wimp_icon { + extent:124,-84,192,-16 + icon_flags:wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK_DRAG + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + sprite.id:"file_faf" + sprite.size:13 + sprite.area:&1 + } + wimp_icon { + extent:8,-152,308,-100 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:256 + text.validation:"Pptr_write" + } + wimp_icon { + extent:172,-236,304,-168 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Sauver" + text.size:* + text.validation:"R6,3" + } + wimp_icon { + extent:20,-228,148,-176 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuler" + text.size:* + text.validation:"R5,3" + } +} + +wimp_window { + template_name:"search" + visible:170,720,814,964 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BOUNDED_ONCE | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-244,644,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:644 + ymin:244 + text.text:"Recherche de texte" + text.size:* + text.validation:"" + wimp_icon { + extent:192,-60,580,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:32 + text.validation:"KN;Pptr_write" + } + wimp_icon { + extent:32,-116,364,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Sensible à la casse" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:500,-228,632,-160 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Suivant" + text.size:10 + text.validation:"R6,3" + } + wimp_icon { + extent:340,-220,492,-168 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Précédent" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:204,-220,332,-168 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuler" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:16,-216,196,-172 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Non trouvé" + text.size:* + text.validation:"" + } + wimp_icon { + extent:-8,-148,652,-140 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:16,-56,184,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Chercher" + } + wimp_icon { + extent:588,-56,632,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_ICON_SHADED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:400,-116,628,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Tout montrer" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } +} + +wimp_window { + template_name:"theme_inst" + visible:458,234,1258,478 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BOUNDED_ONCE | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-244,800,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:0 + ymin:0 + text.text:"Installateur de Thèmes de NetSurf" + text.size:* + text.validation:"" + wimp_icon { + extent:92,-148,792,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Message" + text.size:300 + text.validation:"R2;L" + } + wimp_icon { + extent:608,-232,788,-164 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Installer" + text.size:* + text.validation:"R6,3" + } + wimp_icon { + extent:452,-224,584,-172 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuler" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:12,-80,80,-12 + icon_flags:wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + sprite_only:"!netsurf" + } +} + +wimp_window { + template_name:"tooltip" + visible:884,620,1148,656 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BOUNDED_ONCE | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-36,2000,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + work_flags: + sprite_area:&1 + xmin:0 + ymin:0 + text_only:"<Untitled>" + wimp_icon { + extent:0,-40,300,4 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Comment" + text.size:256 + text.validation:"" + } +} + +wimp_window { + template_name:"tree" + visible:530,654,1042,954 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_SCROLL_REPEAT | wimp_WINDOW_IGNORE_XEXTENT | wimp_WINDOW_IGNORE_YEXTENT | wimp_WINDOW_BOUNDED_ONCE | wimp_WINDOW_BACK_ICON | wimp_WINDOW_CLOSE_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_TOGGLE_ICON | wimp_WINDOW_VSCROLL | wimp_WINDOW_SIZE_ICON | wimp_WINDOW_HSCROLL | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_TRANSPARENT + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-880,1236,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags:wimp_BUTTON_DOUBLE_CLICK_DRAG + sprite_area:&1 + xmin:0 + ymin:0 + text.text:"" + text.size:64 + text.validation:"" +} + +wimp_window { + template_name:"url_suggest" + visible:320,390,1102,684 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_NO_BOUNDS | wimp_WINDOW_IGNORE_XEXTENT | wimp_WINDOW_IGNORE_YEXTENT | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_TRANSPARENT + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-65536,65536,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + work_flags:wimp_BUTTON_CLICK + sprite_area:&1 + xmin:0 + ymin:0 + text_only:"<Untitled>" +} + +wimp_window { + template_name:"warning" + visible:320,524,1120,768 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-244,800,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:0 + ymin:0 + text.text:"Alerte de NetSurf" + text.size:21 + text.validation:"" + wimp_icon { + extent:92,-148,792,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Message" + text.size:300 + text.validation:"R2;L" + } + wimp_icon { + extent:624,-232,788,-164 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Continuer" + text.size:* + text.validation:"R6,3" + } + wimp_icon { + extent:480,-224,600,-172 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Aide" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:12,-80,80,-12 + icon_flags:wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + sprite_only:"!netsurf" + } +} + +wimp_window { + template_name:"zoom" + visible:828,402,1276,626 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-224,448,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + work_flags: + sprite_area:&1 + xmin:448 + ymin:224 + text.text:"Ajuster la vue" + text.size:* + text.validation:"" + wimp_icon { + extent:8,-56,132,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Echelle" + } + wimp_icon { + extent:136,-60,236,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"100" + text.size:5 + text.validation:"Pptr_write;KTA;A0-9." + } + wimp_icon { + extent:248,-52,280,-20 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"R5;sdown,pdown" + } + wimp_icon { + extent:280,-52,312,-20 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"R5;sup,pup" + } + wimp_icon { + extent:316,-56,356,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_HCENTRED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"%" + } + wimp_icon { + extent:136,-112,448,-68 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Scale all frames" + text_and_sprite.size:20 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:-12,-132,564,-124 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:20,-204,152,-152 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuler" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:176,-212,436,-144 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Redimensionner" + text.size:* + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"con_secure" + visible:872,490,1464,854 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-364,592,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:592 + ymin:364 + text_only:"Sécurité" + wimp_icon { + extent:16,-120,576,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-52,492,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Confidentialité inter-site " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-104,568,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Envoyer l'info de renvoi de site" + text_and_sprite.size:40 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:16,-252,576,-148 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-176,380,-132 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Historique de sites " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:24,-228,164,-184 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Durée" + } + wimp_icon { + extent:168,-232,336,-180 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"12" + text.size:4 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:352,-224,384,-192 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:384,-224,416,-192 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:424,-228,500,-184 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"jours" + } + wimp_icon { + extent:24,-336,188,-284 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Par défaut" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:208,-336,372,-284 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuler" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:388,-344,572,-276 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Valider" + text.size:* + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"con_content" + visible:598,836,1350,1336 + xscroll:0 + yscroll:0 + next: + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_OPEN | wimp_WINDOW_HAS_FOCUS | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-500,752,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:640 + ymin:448 + text_only:"Contenu" + wimp_icon { + extent:16,-272,732,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-52,492,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Blocage de contenu " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-100,392,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Cacher les pubs" + text_and_sprite.size:39 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:32,-152,516,-108 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Désactiver les fenêtres pop-up" + text_and_sprite.size:46 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:32,-256,404,-212 +#ifdef WITH_PLUGIN + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO +#else + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_DELETED | wimp_BUTTON_RADIO +#endif + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Désactiver les plug-ins" + text_and_sprite.size:42 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:16,-384,732,-292 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-320,492,-276 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Cibles de liens " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-372,716,-324 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Autoriser les liens à ouvrir une nouvelle fenêtre" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:24,-468,188,-416 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Par défaut" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:372,-468,536,-416 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuler" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:544,-476,728,-408 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Valider" + text.size:* + text.validation:"R6,3" + } + wimp_icon { + extent:32,-204,376,-160 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Disable JavaScript" + text_and_sprite.size:19 + text_and_sprite.validation:"Soptoff,opton" + } +} + +wimp_window { + template_name:"con_connect" + visible:446,482,1106,1150 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-668,660,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + work_flags: + sprite_area:&1 + xmin:660 + ymin:668 + text_only:"Connection" + wimp_icon { + extent:16,-304,644,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:28,-52,264,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Proxy HTTP " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-104,240,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Type de proxy" + text.size:* + text.validation:"" + } + wimp_icon { + extent:244,-108,572,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Display field" + text.size:32 + text.validation:"R2" + } + wimp_icon { + extent:580,-104,624,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:164,-164,240,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Hôte" + text.size:* + text.validation:"" + } + wimp_icon { + extent:244,-168,504,-116 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"myhost.proxy" + text.size:255 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:500,-164,528,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_HCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:":" + text.size:* + text.validation:"" + } + wimp_icon { + extent:524,-168,628,-116 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"8080" + text.size:8 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:92,-224,240,-180 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Identifiant" + text.size:* + text.validation:"" + } + wimp_icon { + extent:244,-228,628,-176 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"k1dd13" + text.size:64 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:52,-284,240,-240 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Mot de passe" + text.size:* + text.validation:"" + } + wimp_icon { + extent:244,-288,628,-236 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"1337" + text.size:64 + text.validation:"Pptr_write;Kta;D*" + } + wimp_icon { + extent:16,-552,644,-332 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-360,316,-316 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Téléchargements " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:68,-412,320,-368 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Nombre maximum" + text.size:16 + text.validation:"" + } + wimp_icon { + extent:324,-416,532,-364 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"99" + text.size:* + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:548,-408,580,-376 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:580,-408,612,-376 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:36,-472,320,-428 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Nombre par hôte" + text.size:18 + text.validation:"" + } + wimp_icon { + extent:324,-476,532,-424 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"99" + text.size:4 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:548,-468,584,-436 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:580,-468,612,-436 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:20,-532,320,-488 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Connexions en cache" + text.size:* + text.validation:"" + } + wimp_icon { + extent:324,-536,532,-484 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"99" + text.size:4 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:548,-528,584,-496 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:580,-528,612,-496 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:* + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:24,-640,188,-588 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Par défaut" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:276,-640,440,-588 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuler" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:456,-648,640,-580 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Valider" + text.size:* + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"con_inter" + visible:264,290,1008,1066 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-844,744,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:744 + ymin:704 + text_only:"Interface" + wimp_icon { + extent:16,-168,728,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-52,732,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Téléchargements / sauvegardes de fichiers " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-100,676,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Supprimer l'extension lors des sauvegardes" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:32,-152,676,-108 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Demander confirmation avant écrasement" + text_and_sprite.size:46 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:16,-344,728,-200 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:36,-224,496,-180 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Fonctions interactives " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-276,744,-232 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Afficher les URLs visitées récemment" + text_and_sprite.size:42 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:32,-328,872,-284 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"URLs flottantes dans l'historique local" + text_and_sprite.size:44 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:16,-468,728,-372 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:36,-400,240,-356 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Vignettes " + text_and_sprite.size:23 + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-452,716,-408 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Utiliser les vignettes pour les fenêtres iconisées" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:24,-744,188,-692 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Par défaut" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:360,-744,524,-692 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuler" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:540,-752,724,-684 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Valider" + text.size:* + text.validation:"R6,3" + } + wimp_icon { + extent:16,-660,728,-492 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:36,-520,240,-476 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Hotlist" + text_and_sprite.size:23 + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-572,728,-528 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Use external hotlist apps when available" + text_and_sprite.size:* + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:28,-640,232,-588 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Hotlist path" + text.size:* + text.validation:"" + } + wimp_icon { + extent:232,-640,708,-588 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"Writable icon" + text.size:256 + text.validation:"Pptr_write;Kta" + } + +} + +wimp_window { + template_name:"ssldisplay" + visible:282,178,1242,718 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_CLOSE_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-540,960,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:960 + ymin:76 + text.text:"Certificat SSL" + text.size:16 + text.validation:"" + wimp_icon { + extent:16,-520,944,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-52,412,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Détails de certificat " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:68,-108,192,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Version" + } + wimp_icon { + extent:200,-108,312,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:384,-104,524,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Valide de" + } + wimp_icon { + extent:524,-108,928,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:112,-168,192,-124 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Type" + } + wimp_icon { + extent:200,-168,312,-116 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:328,-164,524,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Valide jusqu'à" + text.size:* + text.validation:"" + } + wimp_icon { + extent:524,-168,928,-116 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:84,-228,192,-184 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Série" + } + wimp_icon { + extent:200,-228,928,-176 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2" + } + wimp_icon { + extent:32,-288,200,-244 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Fournisseur" + } + wimp_icon { + extent:200,-376,928,-236 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2;L" + } + wimp_icon { + extent:68,-432,192,-388 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Sujet" + } + wimp_icon { + extent:200,-504,928,-384 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R2;L" + } +} + +wimp_window { + template_name:"sslcert" + visible:348,306,1136,898 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-592,788,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:788 + ymin:592 + text.text:"Problème de certificat SSL" + text.size:* + text.validation:"" + wimp_icon { + extent:16,-108,772,-16 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"NetSurf n'a pas pu vérifier l'authenticité d'un certificat SSL. Vérifiez SVP les détails présentés ci-dessous." + text.size:150 + text.validation:"R2;L" + } + wimp_icon { + extent:16,-484,772,-136 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:* + text.validation:"R4" + } + wimp_icon { + extent:32,-164,380,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Chaîne de certificat " + text_and_sprite.size:* + text_and_sprite.validation:"" + } + wimp_icon { + extent:404,-564,568,-512 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Rejeter" + text.size:* + text.validation:"R5,3" + } + wimp_icon { + extent:588,-572,772,-504 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Accepter" + text.size:* + text.validation:"R6,3" + } +} diff --git a/frontends/riscos/templates/nl b/frontends/riscos/templates/nl new file mode 100644 index 000000000..704206fbd --- /dev/null +++ b/frontends/riscos/templates/nl @@ -0,0 +1,3887 @@ +Template: + +wimp_window { + template_name:"configure" + visible:378,966,1050,1126 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BACK_ICON | wimp_WINDOW_CLOSE_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_TOGGLE_ICON | wimp_WINDOW_VSCROLL | wimp_WINDOW_SIZE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_LIGHT_GREY + extra_flags: + extent:0,-880,1236,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:4 + ymin:160 + text.text:"NetSurf-instellingen" + text.size:22 + text.validation:"" +} + +wimp_window { + template_name:"con_cache" + visible:184,682,772,1110 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-428,588,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + work_flags: + sprite_area:&1 + xmin:588 + ymin:240 + text_only:"Buffer" + wimp_icon { + extent:16,-124,568,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R4" + } + wimp_icon { + extent:32,-52,300,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Geheugenbuffer " + text_and_sprite.size:17 + text_and_sprite.validation:"" + } + wimp_icon { + extent:60,-104,212,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Grootte" + text.size:13 + text.validation:"" + } + wimp_icon { + extent:216,-108,380,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"512.0" + text.size:10 + text.validation:"Pptr_write;Kta;A0-9." + } + wimp_icon { + extent:392,-100,424,-68 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:424,-100,456,-68 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:464,-104,528,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"MB" + } + wimp_icon { + extent:16,-312,568,-152 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R4" + } + wimp_icon { + extent:32,-180,268,-136 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Schijfbuffer " + text_and_sprite.size:15 + text_and_sprite.validation:"" + } + wimp_icon { + extent:60,-232,212,-188 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Grootte" + text.size:13 + text.validation:"" + } + wimp_icon { + extent:216,-236,380,-184 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"512" + text.size:10 + text.validation:"Pptr_write;Kta;A0-9" + } + wimp_icon { + extent:392,-228,424,-196 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:424,-228,456,-196 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:464,-232,528,-192 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"MB" + } + wimp_icon { + extent:12,-292,212,-248 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Bewaar max." + text.size:12 + text.validation:"" + } + wimp_icon { + extent:216,-296,380,-244 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"512" + text.size:10 + text.validation:"Pptr_write;Kta;A0-9" + } + wimp_icon { + extent:392,-288,424,-256 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:424,-288,456,-256 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:464,-292,560,-252 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"dagen" + } + wimp_icon { + extent:24,-396,200,-344 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Standaard" + text.size:10 + text.validation:"R5,3" + } + wimp_icon { + extent:216,-396,376,-344 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuleer" + text.size:9 + text.validation:"R5,3" + } + wimp_icon { + extent:392,-404,568,-336 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Stel in" + text.size:8 + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"con_fonts" + visible:558,802,1282,1526 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-724,724,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + work_flags: + sprite_area:&1 + xmin:712 + ymin:724 + text_only:"Lettertypen" + wimp_icon { + extent:16,-424,704,-28 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R4" + } + wimp_icon { + extent:32,-52,256,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Lettertypen " + text_and_sprite.size:14 + text_and_sprite.validation:"" + } + wimp_icon { + extent:24,-104,216,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Schreefloos" + } + wimp_icon { + extent:220,-108,628,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Weergaveveld" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:640,-104,684,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:24,-164,216,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Met schreef" + } + wimp_icon { + extent:220,-168,628,-116 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Weergaveveld" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:640,-164,684,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:36,-224,216,-180 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Monospace" + } + wimp_icon { + extent:220,-228,628,-176 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Weergaveveld" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:640,-224,684,-180 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:88,-284,216,-240 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Cursief" + } + wimp_icon { + extent:220,-288,628,-236 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Weergaveveld" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:640,-284,684,-240 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:72,-344,216,-300 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Fantasie" + } + wimp_icon { + extent:220,-348,628,-296 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Weergaveveld" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:640,-344,684,-300 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:56,-404,216,-360 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Standaard" + } + wimp_icon { + extent:220,-408,628,-356 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Weergaveveld" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:640,-404,684,-360 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:16,-612,704,-452 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R4" + } + wimp_icon { + extent:32,-480,296,-436 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Lettergrootte " + text_and_sprite.size:16 + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-532,200,-488 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Standaard" + } + wimp_icon { + extent:204,-536,372,-484 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"12.3" + text.size:10 + text.validation:"Pptr_write;Kta;A0-9." + } + wimp_icon { + extent:388,-528,420,-496 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:420,-528,452,-496 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:460,-532,500,-488 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"pt" + } + wimp_icon { + extent:52,-592,200,-548 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Minimum" + } + wimp_icon { + extent:204,-596,372,-544 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"12.3" + text.size:10 + text.validation:"Pptr_write;Kta;A0-9." + } + wimp_icon { + extent:388,-588,420,-556 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:420,-588,452,-556 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:460,-592,500,-548 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"pt" + } + wimp_icon { + extent:24,-696,200,-644 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Standaard" + text.size:10 + text.validation:"R5,3" + } + wimp_icon { + extent:340,-696,504,-644 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuleer" + text.size:9 + text.validation:"R5,3" + } + wimp_icon { + extent:520,-704,704,-636 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Stel in" + text.size:8 + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"con_home" + visible:808,592,1608,888 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-296,800,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + work_flags: + sprite_area:&1 + xmin:800 + ymin:296 + text_only:"Startpagina" + wimp_icon { + extent:16,-184,784,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R4" + } + wimp_icon { + extent:32,-52,284,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Startpagina " + text_and_sprite.size:16 + text_and_sprite.validation:"" + } + wimp_icon { + extent:24,-108,120,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Adres" + } + wimp_icon { + extent:124,-112,712,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:128 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:720,-108,764,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:124,-164,732,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_SELECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Browservenster openen na opstarten" + text_and_sprite.size:35 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:24,-264,200,-212 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Standaard" + text.size:10 + text.validation:"R5,3" + } + wimp_icon { + extent:420,-264,584,-212 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuleer" + text.size:9 + text.validation:"R5,3" + } + wimp_icon { + extent:600,-272,784,-204 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Stel in" + text.size:8 + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"con_image" + visible:1488,822,2164,1410 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-588,676,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + work_flags: + sprite_area:&1 + xmin:676 + ymin:588 + text.text:"Afbeeldingen" + text.size:13 + text.validation:"" + wimp_icon { + extent:16,-292,660,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R4" + } + wimp_icon { + extent:32,-52,396,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Afbeeldingskwaliteit " + text_and_sprite.size:23 + text_and_sprite.validation:"" + } + wimp_icon { + extent:40,-108,216,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Voorgrond" + } + wimp_icon { + extent:220,-112,592,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"RISC OS-routines" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:600,-108,644,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:24,-168,216,-124 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Achtergrond" + } + wimp_icon { + extent:220,-172,592,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"RISC OS-routines" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:600,-168,644,-124 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:32,-276,644,-180 + icon_flags:wimp_ICON_BORDER + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + } + wimp_icon { + extent:16,-476,660,-320 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R4" + } + wimp_icon { + extent:32,-348,236,-304 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Animaties " + text_and_sprite.size:16 + text_and_sprite.validation:"" + } + wimp_icon { + extent:20,-404,232,-360 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Animatietijd" + text.size:15 + text.validation:"" + } + wimp_icon { + extent:236,-408,404,-356 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"12.34" + text.size:6 + text.validation:"Pptr_write;Kta;A0-9." + } + wimp_icon { + extent:420,-400,452,-368 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:452,-400,484,-368 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:492,-404,644,-360 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"seconden" + text.size:9 + text.validation:"" + } + wimp_icon { + extent:236,-460,616,-416 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Animaties uitzetten" + text_and_sprite.size:20 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:24,-560,200,-508 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Standaard" + text.size:10 + text.validation:"R5,3" + } + wimp_icon { + extent:292,-560,456,-508 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuleer" + text.size:9 + text.validation:"R5,3" + } + wimp_icon { + extent:472,-568,656,-500 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Stel in" + text.size:8 + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"con_inter" + visible:2320,436,3164,1220 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-784,844,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:744 + ymin:584 + text.text:"Gebruikersinterface" + text.size:20 + text.validation:"" + wimp_icon { + extent:16,-168,820,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R4" + } + wimp_icon { + extent:32,-52,576,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Ophalen / opslaan van bestanden " + text_and_sprite.size:34 + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-100,748,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Bestand opslaan zonder bestandsextensie" + text_and_sprite.size:40 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:32,-152,808,-108 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Toestemming vragen bij overschrijven" + text_and_sprite.size:37 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:16,-344,820,-200 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R4" + } + wimp_icon { + extent:36,-224,496,-180 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Interactieve kenmerken " + text_and_sprite.size:25 + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-276,804,-232 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Recent bezochte adressen tonen tijdens typen" + text_and_sprite.size:45 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:32,-328,776,-284 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Adressen tonen bij de venstergeschiedenis" + text_and_sprite.size:42 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:16,-468,820,-372 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R4" + } + wimp_icon { + extent:36,-400,240,-356 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Miniaturen " + text_and_sprite.size:23 + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-452,708,-408 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Miniaturen gebruiken bij symboliseren" + text_and_sprite.size:42 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:24,-748,200,-696 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Standaard" + text.size:10 + text.validation:"R5,3" + } + wimp_icon { + extent:456,-748,620,-696 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuleer" + text.size:9 + text.validation:"R5,3" + } + wimp_icon { + extent:636,-756,820,-688 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Stel in" + text.size:8 + text.validation:"R6,3" + } + wimp_icon { + extent:16,-664,820,-496 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R4" + } + wimp_icon { + extent:36,-524,240,-480 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Favorieten" + text_and_sprite.size:23 + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-576,728,-532 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Extern programma voor favorietenlijst" + text_and_sprite.size:38 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:24,-644,256,-592 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Programmapad" + text.size:13 + text.validation:"" + } + wimp_icon { + extent:260,-644,800,-592 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"Schrijfbaar veld" + text.size:256 + text.validation:"Pptr_write;Kta" + } +} + +wimp_window { + template_name:"con_lang" + visible:1574,956,2318,1256 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-300,744,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + work_flags: + sprite_area:&1 + xmin:744 + ymin:300 + text_only:"Taal" + wimp_icon { + extent:16,-188,728,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R4" + } + wimp_icon { + extent:32,-52,284,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Taal " + text_and_sprite.size:16 + text_and_sprite.validation:"" + } + wimp_icon { + extent:64,-108,224,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Interface" + } + wimp_icon { + extent:228,-112,660,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"1337" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:668,-108,712,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:32,-168,224,-124 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Webpagina's" + } + wimp_icon { + extent:228,-172,660,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"8008135" + text.size:256 + text.validation:"R2" + } + wimp_icon { + extent:668,-168,712,-124 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:24,-272,200,-220 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Standaard" + text.size:10 + text.validation:"R5,3" + } + wimp_icon { + extent:360,-272,524,-220 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuleer" + text.size:9 + text.validation:"R5,3" + } + wimp_icon { + extent:540,-280,724,-212 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Stel in" + text.size:8 + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"con_theme" + visible:410,38,1318,642 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-604,908,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + work_flags: + sprite_area:&1 + xmin:640 + ymin:604 + text_only:"Thema's" + wimp_icon { + extent:16,-492,892,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R4" + } + wimp_icon { + extent:32,-52,392,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Beschikbare thema's " + text_and_sprite.size:22 + text_and_sprite.validation:"" + } + wimp_icon { + extent:24,-576,200,-524 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Standaard" + text.size:10 + text.validation:"R5,3" + } + wimp_icon { + extent:524,-576,688,-524 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuleer" + text.size:9 + text.validation:"R5,3" + } + wimp_icon { + extent:704,-584,888,-516 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Stel in" + text.size:8 + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"download" + visible:486,610,1394,890 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BACK_ICON | wimp_WINDOW_CLOSE_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-280,908,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:88 + ymin:28 + text.text:"NetSurf-ophaalproces" + text.size:21 + text.validation:"" + wimp_icon { + extent:420,-84,488,-16 + icon_flags:wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK_DRAG + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + sprite.id:"file_ddc" + sprite.size:9 + sprite.area:&1 + } + wimp_icon { + extent:204,-152,900,-100 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"http://netsurf.sourceforge.net/netsurf.zip" + text.size:43 + text.validation:"R2" + } + wimp_icon { + extent:204,-212,900,-160 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"netsurf" + text.size:8 + text.validation:"Pptr_write" + } + wimp_icon { + extent:204,-212,900,-160 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"ADFS::A7000+.$.netsurf" + text.size:23 + text.validation:"R2" + } + wimp_icon { + extent:8,-272,900,-220 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R2" + } + wimp_icon { + extent:12,-268,296,-224 + icon_flags:wimp_ICON_FILLED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_CREAM + } + wimp_icon { + extent:12,-268,896,-224 + icon_flags:wimp_ICON_TEXT | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"999 KB compleet gemiddeld 926.6 KB/s 0:39 resterend" + text.size:72 + text.validation:"" + } + wimp_icon { + extent:92,-148,200,-104 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Bron" + } + wimp_icon { + extent:12,-208,200,-164 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Bestemming" + } +} + +wimp_window { + template_name:"history" + visible:252,388,1152,808 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_SCROLL_REPEAT | wimp_WINDOW_BACK_ICON | wimp_WINDOW_CLOSE_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_TOGGLE_ICON | wimp_WINDOW_VSCROLL | wimp_WINDOW_SIZE_ICON | wimp_WINDOW_HSCROLL | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_WHITE + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-880,1236,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags:wimp_BUTTON_CLICK + sprite_area:&1 + xmin:0 + ymin:0 + text.text:" Venstergeschiedenis " + text.size:22 + text.validation:"" +} + +wimp_window { + template_name:"info" + visible:752,332,1412,700 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_CREAM + scroll_inner:wimp_COLOUR_ORANGE + highlight_bg:wimp_COLOUR_LIGHT_GREY + extra_flags: + extent:0,-368,660,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + work_flags:wimp_BUTTON_CLICK + sprite_area:&1 + xmin:660 + ymin:248 + text.text:"Programma-informatie" + text.size:21 + text.validation:"" + wimp_icon { + extent:672,-200,848,-152 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_RED + text_only:"OK" + } + wimp_icon { + extent:168,-60,652,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK_DRAG + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"NetSurf" + text.size:8 + text.validation:"R2" + } + wimp_icon { + extent:168,-120,652,-68 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK_DRAG + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Webbrowser met open broncode" + text.size:29 + text.validation:"R2" + } + wimp_icon { + extent:168,-180,652,-128 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK_DRAG + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"© NetSurf-ontwikkelaars" + text.size:40 + text.validation:"R2" + } + wimp_icon { + extent:168,-360,652,-308 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK_DRAG + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"CVS-testuitgave" + text.size:40 + text.validation:"R2" + } + wimp_icon { + extent:72,-56,164,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Naam" + } + wimp_icon { + extent:40,-116,164,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Functie" + } + wimp_icon { + extent:40,-176,164,-132 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Auteurs" + } + wimp_icon { + extent:40,-356,164,-312 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Versie" + } + wimp_icon { + extent:168,-300,652,-248 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK_DRAG + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"g.vankatwijk@freeler.nl" + text.size:50 + text.validation:"R2" + } + wimp_icon { + extent:8,-296,164,-252 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Contact" + text.size:20 + text.validation:"" + } + wimp_icon { + extent:168,-240,652,-188 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK_DRAG + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"NetSurf-vertalers" + text.size:40 + text.validation:"R2" + } + wimp_icon { + extent:4,-236,164,-192 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Vertaling" + } +} + +wimp_window { + template_name:"login" + visible:582,400,1322,736 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-336,740,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:740 + ymin:336 + text.text:"Website-authenticatie" + text.size:22 + text.validation:"" + wimp_icon { + extent:596,-324,728,-256 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Login" + text.size:8 + text.validation:"R6,3;Nok" + } + wimp_icon { + extent:408,-316,572,-264 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuleer" + text.size:9 + text.validation:"R5,3;Ncancel" + } + wimp_icon { + extent:252,-60,732,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"moo.yoo.com" + text.size:255 + text.validation:"R2" + } + wimp_icon { + extent:252,-120,732,-68 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"my sekr3t area" + text.size:255 + text.validation:"R2" + } + wimp_icon { + extent:252,-180,732,-128 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:255 + text.validation:"Pptr_write;Kta;N401username" + } + wimp_icon { + extent:252,-240,732,-188 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:255 + text.validation:"Pptr_write;Kta;D*" + } + wimp_icon { + extent:100,-56,248,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Website" + } + wimp_icon { + extent:4,-176,248,-132 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Gebruikersnaam" + text.size:15 + text.validation:"" + } + wimp_icon { + extent:16,-236,248,-192 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Wachtwoord" + } + wimp_icon { + extent:108,-116,248,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Gebied" + } +} + +wimp_window { + template_name:"new_entry" + visible:480,660,1080,880 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-220,600,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:600 + ymin:220 + text.text:"" + text.size:32 + text.validation:"" + wimp_icon { + extent:12,-56,108,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Naam" + } + wimp_icon { + extent:112,-60,588,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:128 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:12,-116,108,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Adres" + } + wimp_icon { + extent:112,-120,532,-68 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:1024 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:268,-200,432,-148 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuleer" + text.size:9 + text.validation:"R5,3" + } + wimp_icon { + extent:456,-208,588,-140 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"OK" + text.size:8 + text.validation:"R6,3" + } + wimp_icon { + extent:540,-116,584,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } +} + +wimp_window { + template_name:"new_folder" + visible:480,954,1080,1114 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-160,600,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:600 + ymin:160 + text.text:"" + text.size:21 + text.validation:"" + wimp_icon { + extent:12,-56,108,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Naam" + } + wimp_icon { + extent:112,-60,588,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:128 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:268,-140,432,-88 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuleer" + text.size:9 + text.validation:"R5,3" + } + wimp_icon { + extent:456,-148,588,-80 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"OK" + text.size:8 + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"objectinfo" + visible:428,292,1216,480 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-188,788,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags:wimp_BUTTON_CLICK + sprite_area:&1 + xmin:788 + ymin:188 + text.text:"Objectinformatie" + text.size:20 + text.validation:"" + wimp_icon { + extent:204,-60,780,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Weergaveveld" + text.size:64 + text.validation:"R2" + } + wimp_icon { + extent:204,-120,780,-68 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Weergaveveld" + text.size:64 + text.validation:"R2" + } + wimp_icon { + extent:204,-180,780,-128 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Weergaveveld" + text.size:64 + text.validation:"R2" + } + wimp_icon { + extent:12,-80,84,-12 + icon_flags:wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + sprite.id:"file_faf" + sprite.size:9 + sprite.area:&1 + } + wimp_icon { + extent:92,-116,200,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Doel" + } + wimp_icon { + extent:120,-176,200,-132 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Type" + } + wimp_icon { + extent:104,-56,200,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Adres" + } +} + +wimp_window { + template_name:"open_url" + visible:248,266,1048,422 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-156,800,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:0 + ymin:0 + text.text:"Weblocatie openen" + text.size:18 + text.validation:"" + wimp_icon { + extent:8,-56,104,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Adres" + } + wimp_icon { + extent:108,-60,736,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:1 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:468,-136,632,-84 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuleer" + text.size:9 + text.validation:"R5,3" + } + wimp_icon { + extent:656,-144,788,-76 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Open" + text.size:8 + text.validation:"R6,3" + } + wimp_icon { + extent:744,-56,788,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } +} + +wimp_window { + template_name:"pageinfo" + visible:310,528,1102,776 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-248,792,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:792 + ymin:248 + text.text:"Documentinformatie" + text.size:19 + text.validation:"" + wimp_icon { + extent:208,-60,784,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Weergaveveld" + text.size:64 + text.validation:"R2" + } + wimp_icon { + extent:208,-120,784,-68 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Weergaveveld" + text.size:64 + text.validation:"R2" + } + wimp_icon { + extent:208,-180,784,-128 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Weergaveveld" + text.size:64 + text.validation:"R2" + } + wimp_icon { + extent:208,-240,784,-188 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Weergaveveld" + text.size:64 + text.validation:"R2" + } + wimp_icon { + extent:12,-80,84,-12 + icon_flags:wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + sprite.id:"file_faf" + sprite.size:9 + sprite.area:&1 + } + wimp_icon { + extent:108,-116,204,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Adres" + } + wimp_icon { + extent:60,-176,204,-132 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Codering" + } + wimp_icon { + extent:116,-236,204,-192 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Type" + } + wimp_icon { + extent:112,-56,204,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Titel" + } +} + +wimp_window { + template_name:"print" + visible:472,136,1132,708 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-572,700,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:600 + ymin:572 + text.text:"Geen stuurprogramma aanwezig" + text.size:29 + text.validation:"" + wimp_icon { + extent:12,-176,652,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R4" + } + wimp_icon { + extent:32,-100,504,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:1 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"einde van de webpagina" + text_and_sprite.size:23 + text_and_sprite.validation:"Sradiooff,radioon" + } + wimp_icon { + extent:32,-152,492,-108 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:1 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:6 + text_and_sprite.validation:"Sradiooff,radioon" + } + wimp_icon { + extent:84,-156,164,-104 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"1" + text.size:3 + text.validation:"Pptr_write;Kta;A0-9" + } + wimp_icon { + extent:176,-148,208,-116 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:208,-148,240,-116 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:244,-152,528,-108 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"pagina('s)" + text.size:11 + text.validation:"" + } + wimp_icon { + extent:12,-236,512,-192 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Voorgrondafbeeldingen" + text_and_sprite.size:22 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:12,-288,528,-244 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Achtergrondafbeeldingen" + text_and_sprite.size:24 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:12,-340,492,-296 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Afdrukken in achtergrond" + text_and_sprite.size:25 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:12,-404,180,-360 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_SELECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Staand" + text_and_sprite.size:7 + text_and_sprite.validation:"Sradiooff,radioon" + } + wimp_icon { + extent:12,-452,196,-408 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Liggend" + text_and_sprite.size:8 + text_and_sprite.validation:"Sradiooff,radioon" + } + wimp_icon { + extent:480,-456,560,-404 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"1" + text.size:3 + text.validation:"Pptr_write;Kta;A0-9" + } + wimp_icon { + extent:572,-448,604,-416 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:604,-448,636,-416 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:292,-552,456,-500 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuleer" + text.size:9 + text.validation:"R5,3" + } + wimp_icon { + extent:480,-560,648,-492 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Druk af" + text.size:8 + text.validation:"R6,3" + } + wimp_icon { + extent:344,-452,476,-408 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Kopieën" + } + wimp_icon { + extent:-16,-480,676,-472 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R2" + } + wimp_icon { + extent:32,-48,448,-4 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Afdrukken stoppen na " + text_and_sprite.size:23 + text_and_sprite.validation:"" + } + wimp_icon { + extent:232,-400,656,-356 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Alle tekst in zwart" + text_and_sprite.size:20 + text_and_sprite.validation:"Soptoff,opton" + } +} + +wimp_window { + template_name:"query" + visible:142,526,942,806 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_LIGHT_GREY + extra_flags: + extent:0,-280,800,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:0 + ymin:0 + text.text:"Vraag van NetSurf" + text.size:21 + text.validation:"" + wimp_icon { + extent:92,-184,792,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Bericht" + text.size:300 + text.validation:"R2;L" + } + wimp_icon { + extent:604,-268,788,-200 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"012345678901234567" + text.size:19 + text.validation:"R6,3" + } + wimp_icon { + extent:424,-260,588,-208 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"0123456789012345678901" + text.size:23 + text.validation:"R5,3" + } + wimp_icon { + extent:16,-260,132,-208 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Hulp" + text.size:5 + text.validation:"R5,3" + } + wimp_icon { + extent:12,-80,80,-12 + icon_flags:wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + sprite_only:"!netsurf" + } +} + +wimp_window { + template_name:"saveas" + visible:824,676,1164,924 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BOUNDED_ONCE | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-248,340,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:308 + ymin:244 + text_only:"Bewaar als" + wimp_icon { + extent:144,-84,212,-16 + icon_flags:wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK_DRAG + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + sprite.id:"file_faf" + sprite.size:13 + sprite.area:&1 + } + wimp_icon { + extent:8,-152,332,-100 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:256 + text.validation:"Pptr_write" + } + wimp_icon { + extent:184,-236,332,-168 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Bewaar" + text.size:7 + text.validation:"R6,3" + } + wimp_icon { + extent:8,-228,168,-176 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuleer" + text.size:9 + text.validation:"R5,3" + } +} + +wimp_window { + template_name:"search" + visible:1036,684,1792,928 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-244,756,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:756 + ymin:244 + text.text:"Tekst zoeken" + text.size:13 + text.validation:"" + wimp_icon { + extent:96,-60,692,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"" + text.size:32 + text.validation:"KN;Pptr_write" + } + wimp_icon { + extent:96,-116,476,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Hoofdlettergevoelig" + text_and_sprite.size:20 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:568,-228,744,-160 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Volgende" + text.size:10 + text.validation:"R6,3" + } + wimp_icon { + extent:424,-220,552,-168 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Vorige" + text.size:7 + text.validation:"R5,3" + } + wimp_icon { + extent:248,-220,408,-168 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuleer" + text.size:9 + text.validation:"R5,3" + } + wimp_icon { + extent:12,-216,232,-172 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Niet gevonden" + text.size:14 + text.validation:"" + } + wimp_icon { + extent:-8,-148,772,-140 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R2" + } + wimp_icon { + extent:16,-56,92,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Zoek" + } + wimp_icon { + extent:700,-56,744,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_ICON_SHADED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:13 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:472,-116,748,-72 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Alles markeren" + text_and_sprite.size:15 + text_and_sprite.validation:"Soptoff,opton" + } +} + +wimp_window { + template_name:"theme_inst" + visible:374,554,1174,834 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-280,800,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:800 + ymin:280 + text.text:"NetSurf-thema-intallatie" + text.size:25 + text.validation:"" + wimp_icon { + extent:92,-184,792,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Bericht" + text.size:300 + text.validation:"R2;L" + } + wimp_icon { + extent:588,-268,788,-200 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Installeer" + text.size:11 + text.validation:"R6,3" + } + wimp_icon { + extent:404,-260,564,-208 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuleer" + text.size:9 + text.validation:"R5,3" + } + wimp_icon { + extent:12,-80,80,-12 + icon_flags:wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + sprite_only:"!netsurf" + } +} + +wimp_window { + template_name:"tooltip" + visible:884,620,1148,656 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BOUNDED_ONCE | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-36,2000,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + work_flags: + sprite_area:&1 + xmin:0 + ymin:0 + text_only:"<Naamloos>" + wimp_icon { + extent:0,-40,300,4 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Commentaar" + text.size:256 + text.validation:"" + } +} + +wimp_window { + template_name:"tree" + visible:530,654,1042,954 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_SCROLL_REPEAT | wimp_WINDOW_IGNORE_XEXTENT | wimp_WINDOW_IGNORE_YEXTENT | wimp_WINDOW_BOUNDED_ONCE | wimp_WINDOW_BACK_ICON | wimp_WINDOW_CLOSE_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_TOGGLE_ICON | wimp_WINDOW_VSCROLL | wimp_WINDOW_SIZE_ICON | wimp_WINDOW_HSCROLL | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_TRANSPARENT + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-880,1236,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags:wimp_BUTTON_DOUBLE_CLICK_DRAG + sprite_area:&1 + xmin:0 + ymin:0 + text.text:"" + text.size:64 + text.validation:"" +} + +wimp_window { + template_name:"url_suggest" + visible:320,390,1102,684 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_NO_BOUNDS | wimp_WINDOW_IGNORE_XEXTENT | wimp_WINDOW_IGNORE_YEXTENT | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_TRANSPARENT + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-65536,65536,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + work_flags:wimp_BUTTON_CLICK + sprite_area:&1 + xmin:0 + ymin:0 + text_only:"<Naamloos>" +} + +wimp_window { + template_name:"warning" + visible:320,814,1120,1094 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BOUNDED_ONCE | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-280,800,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:0 + ymin:0 + text.text:"Waarschuwing van NetSurf" + text.size:25 + text.validation:"" + wimp_icon { + extent:92,-184,792,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Bericht" + text.size:300 + text.validation:"R2;L" + } + wimp_icon { + extent:608,-268,788,-200 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Verder" + text.size:7 + text.validation:"R6,3" + } + wimp_icon { + extent:484,-260,584,-208 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Hulp" + text.size:5 + text.validation:"R5,3" + } + wimp_icon { + extent:12,-80,80,-12 + icon_flags:wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + sprite_only:"!netsurf" + } +} + +wimp_window { + template_name:"zoom" + visible:182,356,650,578 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BOUNDED_ONCE | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-224,468,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + work_flags: + sprite_area:&1 + xmin:468 + ymin:220 + text.text:"Pagina schalen" + text.size:15 + text.validation:"" + wimp_icon { + extent:0,-56,112,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Schaal" + } + wimp_icon { + extent:116,-60,212,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"100" + text.size:5 + text.validation:"Pptr_write;KTA;A0-9." + } + wimp_icon { + extent:224,-52,256,-20 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"R5;sdown,pdown" + } + wimp_icon { + extent:256,-52,288,-20 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"R5;sup,pup" + } + wimp_icon { + extent:292,-56,332,-12 + icon_flags:wimp_ICON_TEXT | wimp_ICON_HCENTRED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"%" + } + wimp_icon { + extent:116,-112,460,-68 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Frames meeschalen" + text_and_sprite.size:20 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:-4,-132,716,-124 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R2" + } + wimp_icon { + extent:148,-204,308,-152 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuleer" + text.size:9 + text.validation:"R5,3" + } + wimp_icon { + extent:324,-212,460,-144 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Schaal" + text.size:7 + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"ssldisplay" + visible:862,768,1870,1308 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BOUNDED_ONCE | wimp_WINDOW_CLOSE_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-540,1008,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:1008 + ymin:76 + text.text:"SSL-certificaat" + text.size:16 + text.validation:"" + wimp_icon { + extent:16,-520,992,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R4" + } + wimp_icon { + extent:32,-52,380,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Certificaatedetails " + text_and_sprite.size:22 + text_and_sprite.validation:"" + } + wimp_icon { + extent:72,-108,196,-64 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Versie" + } + wimp_icon { + extent:200,-108,312,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R2" + } + wimp_icon { + extent:320,-104,528,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Geldig vanaf" + text.size:13 + text.validation:"" + } + wimp_icon { + extent:532,-108,976,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R2" + } + wimp_icon { + extent:116,-168,196,-124 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Type" + } + wimp_icon { + extent:200,-168,312,-116 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R2" + } + wimp_icon { + extent:340,-164,528,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Geldig tot" + } + wimp_icon { + extent:532,-168,976,-116 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R2" + } + wimp_icon { + extent:68,-228,196,-184 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Serienr" + } + wimp_icon { + extent:200,-228,976,-176 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R2" + } + wimp_icon { + extent:56,-288,196,-244 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Uitgever" + } + wimp_icon { + extent:200,-376,976,-236 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R2;L" + } + wimp_icon { + extent:24,-432,196,-388 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Onderwerp" + } + wimp_icon { + extent:200,-504,976,-384 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R2;L" + } +} + +wimp_window { + template_name:"con_secure" + visible:1590,788,2206,1152 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-364,616,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + work_flags: + sprite_area:&1 + xmin:616 + ymin:364 + text.text:"Privacy & veiligheid" + text.size:21 + text.validation:"" + wimp_icon { + extent:16,-120,600,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R4" + } + wimp_icon { + extent:32,-52,364,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Cross-site privacy " + text_and_sprite.size:21 + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-104,592,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Sitegerelateerde info verzenden" + text_and_sprite.size:32 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:16,-252,600,-148 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R4" + } + wimp_icon { + extent:32,-176,316,-132 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Sitegeschiedenis " + text_and_sprite.size:18 + text_and_sprite.validation:"" + } + wimp_icon { + extent:28,-228,112,-184 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Max." + } + wimp_icon { + extent:116,-232,240,-180 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"12" + text.size:4 + text.validation:"Pptr_write;Kta;A0-9" + } + wimp_icon { + extent:252,-224,284,-192 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:284,-224,316,-192 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:324,-228,596,-184 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"dagen onthouden" + text.size:16 + text.validation:"" + } + wimp_icon { + extent:24,-336,200,-284 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Standaard" + text.size:10 + text.validation:"R5,3" + } + wimp_icon { + extent:232,-336,396,-284 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuleer" + text.size:9 + text.validation:"R5,3" + } + wimp_icon { + extent:412,-344,596,-276 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Stel in" + text.size:8 + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"con_content" + visible:1248,854,1928,1354 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_FULL_SIZE | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-500,680,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:656 + ymin:452 + text_only:"Browsen" + wimp_icon { + extent:16,-272,660,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R4" + } + wimp_icon { + extent:32,-52,492,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Paginaverwerking " + text_and_sprite.size:29 + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-100,460,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Advertenties verbergen" + text_and_sprite.size:39 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:32,-152,592,-108 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Pop-up vensters verhinderen" + text_and_sprite.size:46 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:32,-256,540,-212 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_DELETED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"Plug-ins uitschakelen" + text_and_sprite.size:42 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:16,-384,660,-292 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R4" + } + wimp_icon { + extent:32,-320,492,-276 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Koppelingen " + text_and_sprite.size:29 + text_and_sprite.validation:"" + } + wimp_icon { + extent:32,-368,644,-324 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"In nieuw venster openen toestaan" + text_and_sprite.size:36 + text_and_sprite.validation:"Soptoff,opton" + } + wimp_icon { + extent:24,-468,200,-416 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Standaard" + text.size:10 + text.validation:"R5,3" + } + wimp_icon { + extent:296,-468,460,-416 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuleer" + text.size:9 + text.validation:"R5,3" + } + wimp_icon { + extent:476,-476,660,-408 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Stel in" + text.size:8 + text.validation:"R6,3" + } + wimp_icon { + extent:32,-204,532,-160 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_RADIO + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"JavaScript uitschakelen" + text_and_sprite.size:24 + text_and_sprite.validation:"Soptoff,opton" + } +} + +wimp_window { + template_name:"con_connect" + visible:1328,566,2068,1234 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BACK_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-668,740,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED + work_flags: + sprite_area:&1 + xmin:740 + ymin:668 + text_only:"Verbinding" + wimp_icon { + extent:16,-304,724,-24 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R4" + } + wimp_icon { + extent:28,-52,232,-8 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" HTTP-proxy " + text_and_sprite.size:15 + text_and_sprite.validation:"" + } + wimp_icon { + extent:96,-104,268,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_only:"Proxy-type" + } + wimp_icon { + extent:272,-108,652,-56 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Weergaveveld" + text.size:32 + text.validation:"R2" + } + wimp_icon { + extent:660,-104,704,-60 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"R5;sgright,pgright" + } + wimp_icon { + extent:156,-164,268,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Server" + text.size:7 + text.validation:"" + } + wimp_icon { + extent:272,-168,584,-116 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"myhost.proxy" + text.size:255 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:580,-164,608,-120 + icon_flags:wimp_ICON_TEXT | wimp_ICON_HCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:":" + text.size:2 + text.validation:"" + } + wimp_icon { + extent:604,-168,708,-116 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"8080" + text.size:8 + text.validation:"Pptr_write;Kta;A0-9" + } + wimp_icon { + extent:12,-224,268,-180 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Gebruikersnaam" + text.size:15 + text.validation:"" + } + wimp_icon { + extent:272,-228,708,-176 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"k1dd13" + text.size:64 + text.validation:"Pptr_write;Kta" + } + wimp_icon { + extent:44,-284,268,-240 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Wachtwoord" + text.size:11 + text.validation:"" + } + wimp_icon { + extent:272,-288,708,-236 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"1337" + text.size:64 + text.validation:"Pptr_write;Kta;D*" + } + wimp_icon { + extent:16,-552,724,-332 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R4" + } + wimp_icon { + extent:32,-360,332,-316 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Ophaalopdrachten " + text_and_sprite.size:19 + text_and_sprite.validation:"" + } + wimp_icon { + extent:148,-412,408,-368 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Maximum aantal" + text.size:15 + text.validation:"" + } + wimp_icon { + extent:412,-416,620,-364 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"99" + text.size:3 + text.validation:"Pptr_write;Kta;A0-9" + } + wimp_icon { + extent:636,-408,668,-376 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:668,-408,700,-376 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:116,-472,408,-428 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Aantal per server" + text.size:18 + text.validation:"" + } + wimp_icon { + extent:412,-476,620,-424 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"99" + text.size:4 + text.validation:"Pptr_write;Kta;A0-9" + } + wimp_icon { + extent:636,-468,672,-436 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:668,-468,700,-436 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:24,-532,408,-488 + icon_flags:wimp_ICON_TEXT | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_ICON_RJUSTIFIED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Gebufferde verbindingen" + text.size:24 + text.validation:"" + } + wimp_icon { + extent:412,-536,620,-484 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_WRITABLE + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_WHITE + text.text:"99" + text.size:4 + text.validation:"Pptr_write;Kta;A0-9" + } + wimp_icon { + extent:636,-528,672,-496 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"r5;sdown,pdown" + } + wimp_icon { + extent:668,-528,700,-496 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED | wimp_BUTTON_REPEAT + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:"" + text_and_sprite.size:1 + text_and_sprite.validation:"r5;sup,pup" + } + wimp_icon { + extent:24,-640,200,-588 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Standaard" + text.size:10 + text.validation:"R5,3" + } + wimp_icon { + extent:360,-640,524,-588 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Annuleer" + text.size:9 + text.validation:"R5,3" + } + wimp_icon { + extent:540,-648,724,-580 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Stel in" + text.size:8 + text.validation:"R6,3" + } +} + +wimp_window { + template_name:"sslcert" + visible:348,250,1136,898 + xscroll:0 + yscroll:0 + next:wimp_TOP + window_flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BOUNDED_ONCE | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_NEW_FORMAT + title_fg:wimp_COLOUR_BLACK + title_bg:wimp_COLOUR_LIGHT_GREY + work_fg:wimp_COLOUR_BLACK + work_bg:wimp_COLOUR_VERY_LIGHT_GREY + scroll_outer:wimp_COLOUR_MID_LIGHT_GREY + scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY + highlight_bg:wimp_COLOUR_CREAM + extra_flags: + extent:0,-648,788,0 + title_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | 0x27000000 + work_flags: + sprite_area:&1 + xmin:788 + ymin:648 + text.text:"SSL-certificaatprobleem" + text.size:24 + text.validation:"" + wimp_icon { + extent:16,-148,772,-16 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"NetSurf kan de rechtmatigheid van een SSL-certificaat niet verifiëren. Verifieer de details hieronder." + text.size:150 + text.validation:"R2;L" + } + wimp_icon { + extent:16,-548,772,-176 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"" + text.size:1 + text.validation:"R4" + } + wimp_icon { + extent:32,-204,380,-160 + icon_flags:wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text_and_sprite.text:" Certificaatketen " + text_and_sprite.size:22 + text_and_sprite.validation:"" + } + wimp_icon { + extent:404,-624,568,-572 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Verwerp" + text.size:8 + text.validation:"R5,3" + } + wimp_icon { + extent:588,-632,772,-564 + icon_flags:wimp_ICON_TEXT | wimp_ICON_BORDER | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | wimp_BUTTON_CLICK + icon_esg:0 + icon_fg:wimp_COLOUR_BLACK + icon_bg:wimp_COLOUR_VERY_LIGHT_GREY + text.text:"Accepteer" + text.size:10 + text.validation:"R6,3" + } +} diff --git a/frontends/riscos/textarea.c b/frontends/riscos/textarea.c new file mode 100644 index 000000000..ecf3e0c3d --- /dev/null +++ b/frontends/riscos/textarea.c @@ -0,0 +1,1160 @@ +/* + * Copyright 2006 John-Mark Bell <jmb202@ecs.soton.ac.uk> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Single/Multi-line UTF-8 text area (implementation) + */ + +#include <inttypes.h> +#include <stdbool.h> +#include <stdint.h> +#include <string.h> +#include <swis.h> +#include <oslib/colourtrans.h> +#include <oslib/osbyte.h> +#include <oslib/serviceinternational.h> +#include <oslib/wimp.h> +#include <oslib/wimpspriteop.h> + +#include "utils/log.h" +#include "utils/utf8.h" +#include "desktop/browser.h" + +#include "riscos/gui.h" +#include "riscos/oslib_pre7.h" +#include "riscos/textarea.h" +#include "riscos/ucstables.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" +#include "riscos/wimputils.h" + +#define MARGIN_LEFT 8 +#define MARGIN_RIGHT 8 + +struct line_info { + unsigned int b_start; /**< Byte offset of line start */ + unsigned int b_length; /**< Byte length of line */ +}; + +struct text_area { +#define MAGIC (('T'<<24) | ('E'<<16) | ('X'<<8) | 'T') + unsigned int magic; /**< Magic word, for sanity */ + + unsigned int flags; /**< Textarea flags */ + unsigned int vis_width; /**< Visible width, in pixels */ + unsigned int vis_height; /**< Visible height, in pixels */ + wimp_w window; /**< Window handle */ + + char *text; /**< UTF-8 text */ + unsigned int text_alloc; /**< Size of allocated text */ + unsigned int text_len; /**< Length of text, in bytes */ + struct { + unsigned int line; /**< Line caret is on */ + unsigned int char_off; /**< Character index of caret */ + } caret_pos; +// unsigned int selection_start; /**< Character index of sel start */ +// unsigned int selection_end; /**< Character index of sel end */ + + wimp_w parent; /**< Parent window handle */ + wimp_i icon; /**< Parent icon handle */ + + char *font_family; /**< Font family of text */ + unsigned int font_size; /**< Font size (16ths/pt) */ + rufl_style font_style; /**< Font style (rufl) */ + int line_height; /**< Total height of a line, given font size */ + int line_spacing; /**< Height of line spacing, given font size */ + + unsigned int line_count; /**< Count of lines */ +#define LINE_CHUNK_SIZE 256 + struct line_info *lines; /**< Line info array */ + + struct text_area *next; /**< Next text area in list */ + struct text_area *prev; /**< Prev text area in list */ +}; + +static wimp_window text_area_definition = { + {0, 0, 16, 16}, + 0, + 0, + wimp_TOP, + wimp_WINDOW_NEW_FORMAT | wimp_WINDOW_NO_BOUNDS, + wimp_COLOUR_BLACK, + wimp_COLOUR_LIGHT_GREY, + wimp_COLOUR_LIGHT_GREY, + wimp_COLOUR_VERY_LIGHT_GREY, + wimp_COLOUR_DARK_GREY, + wimp_COLOUR_MID_LIGHT_GREY, + wimp_COLOUR_CREAM, + 0, + {0, -16384, 16384, 0}, + wimp_ICON_TEXT | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED, + wimp_BUTTON_CLICK << wimp_ICON_BUTTON_TYPE_SHIFT, + wimpspriteop_AREA, + 1, + 1, + {""}, + 0, + {} +}; + +static void ro_textarea_reflow(struct text_area *ta, unsigned int line); +static bool ro_textarea_mouse_click(wimp_pointer *pointer); +static bool ro_textarea_key_press(wimp_key *key); +static void ro_textarea_redraw(wimp_draw *redraw); +static void ro_textarea_redraw_internal(wimp_draw *redraw, bool update); +static void ro_textarea_open(wimp_open *open); + +/** + * Create a text area + * + * \param parent Parent window + * \param icon Icon in parent window to replace + * \param flags Text area flags + * \param font_family RUfl font family to use, or NULL for default + * \param font_size Font size to use (pt * 16), or 0 for default + * \param font_style Font style to use, or 0 for default + * \return Opaque handle for textarea or 0 on error + */ +uintptr_t ro_textarea_create(wimp_w parent, wimp_i icon, unsigned int flags, + const char *font_family, unsigned int font_size, + rufl_style font_style) +{ + struct text_area *ret; + os_error *error; + + ret = malloc(sizeof(struct text_area)); + if (!ret) { + LOG("malloc failed"); + return 0; + } + + ret->parent = parent; + ret->icon = icon; + ret->magic = MAGIC; + ret->flags = flags; + ret->text = malloc(64); + if (!ret->text) { + LOG("malloc failed"); + free(ret); + return 0; + } + ret->text[0] = '\0'; + ret->text_alloc = 64; + ret->text_len = 1; + ret->caret_pos.line = ret->caret_pos.char_off = (unsigned int)-1; +// ret->selection_start = (unsigned int)-1; +// ret->selection_end = (unsigned int)-1; + ret->font_family = strdup(font_family ? font_family : "Corpus"); + if (!ret->font_family) { + LOG("strdup failed"); + free(ret->text); + free(ret); + return 0; + } + ret->font_size = font_size ? font_size : 192 /* 12pt */; + ret->font_style = font_style ? font_style : rufl_WEIGHT_400; + + /** \todo Better line height calculation */ + ret->line_height = (int)(((ret->font_size * 1.3) / 16) * 2.0) + 1; + ret->line_spacing = ret->line_height / 8; + + ret->line_count = 0; + ret->lines = 0; + + if (flags & TEXTAREA_READONLY) + text_area_definition.title_fg = 0xff; + else + text_area_definition.title_fg = wimp_COLOUR_BLACK; + error = xwimp_create_window(&text_area_definition, &ret->window); + if (error) { + LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess); + free(ret->font_family); + free(ret->text); + free(ret); + return 0; + } + + /* set the window dimensions */ + if (!ro_textarea_update((uintptr_t)ret)) { + ro_textarea_destroy((uintptr_t)ret); + return 0; + } + + /* and register our event handlers */ + ro_gui_wimp_event_set_user_data(ret->window, ret); + ro_gui_wimp_event_register_mouse_click(ret->window, + ro_textarea_mouse_click); + ro_gui_wimp_event_register_keypress(ret->window, + ro_textarea_key_press); + ro_gui_wimp_event_register_redraw_window(ret->window, + ro_textarea_redraw); + ro_gui_wimp_event_register_open_window(ret->window, + ro_textarea_open); + + return (uintptr_t)ret; +} + +/** + * Update the a text area following a change in the parent icon + * + * \param self Text area to update + */ +bool ro_textarea_update(uintptr_t self) +{ + struct text_area *ta; + wimp_window_state state; + wimp_icon_state istate; + os_box extent; + os_error *error; + + ta = (struct text_area *)self; + if (!ta || ta->magic != MAGIC) + return false; + + state.w = ta->parent; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + return false; + } + + istate.w = ta->parent; + istate.i = ta->icon; + error = xwimp_get_icon_state(&istate); + if (error) { + LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess); + return false; + } + + state.w = ta->window; + state.visible.x1 = state.visible.x0 + istate.icon.extent.x1 - + ro_get_vscroll_width(ta->window) - state.xscroll; + state.visible.x0 += istate.icon.extent.x0 + 2 - state.xscroll; + state.visible.y0 = state.visible.y1 + istate.icon.extent.y0 + + ro_get_hscroll_height(ta->window) - state.yscroll; + state.visible.y1 += istate.icon.extent.y1 - 2 - state.yscroll; + + if (ta->flags & TEXTAREA_READONLY) { + state.visible.x0 += 2; + state.visible.x1 -= 4; + state.visible.y0 += 2; + state.visible.y1 -= 4; + } + + /* set our width/height */ + ta->vis_width = state.visible.x1 - state.visible.x0; + ta->vis_height = state.visible.y1 - state.visible.y0; + + /* Set window extent to visible area */ + extent.x0 = 0; + extent.y0 = -ta->vis_height; + extent.x1 = ta->vis_width; + extent.y1 = 0; + + error = xwimp_set_extent(ta->window, &extent); + if (error) { + LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess); + return false; + } + + /* and open the window */ + error = xwimp_open_window_nested(PTR_WIMP_OPEN(&state), ta->parent, + wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT + << wimp_CHILD_XORIGIN_SHIFT | + wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT + << wimp_CHILD_YORIGIN_SHIFT | + wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT + << wimp_CHILD_LS_EDGE_SHIFT | + wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT + << wimp_CHILD_RS_EDGE_SHIFT); + if (error) { + LOG("xwimp_open_window_nested: 0x%x: %s", error->errnum, error->errmess); + return false; + } + + /* reflow the text */ + ro_textarea_reflow(ta, 0); + return true; +} + +/** + * Destroy a text area + * + * \param self Text area to destroy + */ +void ro_textarea_destroy(uintptr_t self) +{ + struct text_area *ta; + os_error *error; + + ta = (struct text_area *)self; + if (!ta || ta->magic != MAGIC) + return; + + error = xwimp_delete_window(ta->window); + if (error) { + LOG("xwimp_delete_window: 0x%x: %s", error->errnum, error->errmess); + } + + ro_gui_wimp_event_finalise(ta->window); + + free(ta->font_family); + free(ta->text); + free(ta); +} + +/** + * Set the text in a text area, discarding any current text + * + * \param self Text area + * \param text UTF-8 text to set text area's contents to + * \return true on success, false on memory exhaustion + */ +bool ro_textarea_set_text(uintptr_t self, const char *text) +{ + struct text_area *ta; + unsigned int len = strlen(text) + 1; + + ta = (struct text_area *)self; + if (!ta || ta->magic != MAGIC) { + LOG("magic doesn't match"); + return true; + } + + if (len >= ta->text_alloc) { + char *temp = realloc(ta->text, len + 64); + if (!temp) { + LOG("realloc failed"); + return false; + } + ta->text = temp; + ta->text_alloc = len+64; + } + + memcpy(ta->text, text, len); + ta->text_len = len; + + ro_textarea_reflow(ta, 0); + + return true; +} + +/** + * Extract the text from a text area + * + * \param self Text area + * \param buf Pointer to buffer to receive data, or NULL + * to read length required + * \param len Length (bytes) of buffer pointed to by buf, or 0 to read length + * \return Length (bytes) written/required or -1 on error + */ +int ro_textarea_get_text(uintptr_t self, char *buf, unsigned int len) +{ + struct text_area *ta; + + ta = (struct text_area *)self; + if (!ta || ta->magic != MAGIC) { + LOG("magic doesn't match"); + return -1; + } + + if (buf == NULL && len == 0) { + /* want length */ + return ta->text_len; + } + + if (len < ta->text_len) { + LOG("buffer too small"); + return -1; + } + + memcpy(buf, ta->text, ta->text_len); + + return ta->text_len; +} + +/** + * Insert text into the text area + * + * \param self Text area + * \param index 0-based character index to insert at + * \param text UTF-8 text to insert + */ +void ro_textarea_insert_text(uintptr_t self, unsigned int index, + const char *text) +{ + struct text_area *ta; + unsigned int b_len = strlen(text); + size_t b_off, c_len; + + ta = (struct text_area *)self; + if (!ta || ta->magic != MAGIC) { + LOG("magic doesn't match"); + return; + } + + c_len = utf8_length(ta->text); + + /* Find insertion point */ + if (index > c_len) + index = c_len; + + for (b_off = 0; index-- > 0; + b_off = utf8_next(ta->text, ta->text_len, b_off)) + ; /* do nothing */ + + if (b_len + ta->text_len >= ta->text_alloc) { + char *temp = realloc(ta->text, b_len + ta->text_len + 64); + if (!temp) { + LOG("realloc failed"); + return; + } + + ta->text = temp; + ta->text_alloc = b_len + ta->text_len + 64; + } + + /* Shift text following up */ + memmove(ta->text + b_off + b_len, ta->text + b_off, + ta->text_len - b_off); + /* Insert new text */ + memcpy(ta->text + b_off, text, b_len); + + ta->text_len += b_len; + + /** \todo calculate line to reflow from */ + ro_textarea_reflow(ta, 0); +} + +/** + * Replace text in a text area + * + * \param self Text area + * \param start Start character index of replaced section (inclusive) + * \param end End character index of replaced section (exclusive) + * \param text UTF-8 text to insert + */ +void ro_textarea_replace_text(uintptr_t self, unsigned int start, + unsigned int end, const char *text) +{ + struct text_area *ta; + int b_len = strlen(text); + size_t b_start, b_end, c_len, diff; + + ta = (struct text_area *)self; + if (!ta || ta->magic != MAGIC) { + LOG("magic doesn't match"); + return; + } + + c_len = utf8_length(ta->text); + + if (start > c_len) + start = c_len; + if (end > c_len) + end = c_len; + + if (start == end) + return ro_textarea_insert_text(self, start, text); + + if (start > end) { + int temp = end; + end = start; + start = temp; + } + + diff = end - start; + + for (b_start = 0; start-- > 0; + b_start = utf8_next(ta->text, ta->text_len, b_start)) + ; /* do nothing */ + + for (b_end = b_start; diff-- > 0; + b_end = utf8_next(ta->text, ta->text_len, b_end)) + ; /* do nothing */ + + if (b_len + ta->text_len - (b_end - b_start) >= ta->text_alloc) { + char *temp = realloc(ta->text, + b_len + ta->text_len - (b_end - b_start) + 64); + if (!temp) { + LOG("realloc failed"); + return; + } + + ta->text = temp; + ta->text_alloc = + b_len + ta->text_len - (b_end - b_start) + 64; + } + + /* Shift text following to new position */ + memmove(ta->text + b_start + b_len, ta->text + b_end, + ta->text_len - b_end); + + /* Insert new text */ + memcpy(ta->text + b_start, text, b_len); + + ta->text_len += b_len - (b_end - b_start); + + /** \todo calculate line to reflow from */ + ro_textarea_reflow(ta, 0); +} + +/** + * Set the caret's position + * + * \param self Text area + * \param caret 0-based character index to place caret at + */ +void ro_textarea_set_caret(uintptr_t self, unsigned int caret) +{ + struct text_area *ta; + size_t c_len, b_off; + unsigned int i; + size_t index; + int x; + os_coord os_line_height; + rufl_code code; + os_error *error; + + ta = (struct text_area *)self; + if (!ta || ta->magic != MAGIC) { + LOG("magic doesn't match"); + return; + } + + c_len = utf8_length(ta->text); + + if (caret > c_len) + caret = c_len; + + /* Find byte offset of caret position */ + for (b_off = 0; caret > 0; caret--) + b_off = utf8_next(ta->text, ta->text_len, b_off); + + /* Now find line in which byte offset appears */ + for (i = 0; i < ta->line_count - 1; i++) + if (ta->lines[i + 1].b_start > b_off) + break; + + ta->caret_pos.line = i; + + /* Now calculate the char. offset of the caret in this line */ + for (c_len = 0, ta->caret_pos.char_off = 0; + c_len < b_off - ta->lines[i].b_start; + c_len = utf8_next(ta->text + ta->lines[i].b_start, + ta->lines[i].b_length, c_len)) + ta->caret_pos.char_off++; + + + /* Finally, redraw the WIMP caret */ + index = ro_textarea_get_caret(self); + os_line_height.x = 0; + os_line_height.y = (int)((float)(ta->line_height - ta->line_spacing) * 0.62) + 1; + ro_convert_pixels_to_os_units(&os_line_height, (os_mode)-1); + + for (b_off = 0; index-- > 0; b_off = utf8_next(ta->text, ta->text_len, b_off)) + ; /* do nothing */ + + code = rufl_width(ta->font_family, ta->font_style, ta->font_size, + ta->text + ta->lines[ta->caret_pos.line].b_start, + b_off - ta->lines[ta->caret_pos.line].b_start, &x); + if (code != rufl_OK) { + if (code == rufl_FONT_MANAGER_ERROR) + LOG("rufl_width: 0x%x: %s", rufl_fm_error->errnum, rufl_fm_error->errmess); + else + LOG("rufl_width: 0x%x", code); + return; + } + + error = xwimp_set_caret_position(ta->window, -1, x + MARGIN_LEFT, + -((ta->caret_pos.line + 1) * ta->line_height) - + ta->line_height / 4 + ta->line_spacing, + os_line_height.y, -1); + if (error) { + LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess); + return; + } +} + +/** + * Set the caret's position + * + * \param self Text area + * \param x X position of caret on the screen + * \param y Y position of caret on the screen + */ +void ro_textarea_set_caret_xy(uintptr_t self, int x, int y) +{ + struct text_area *ta; + wimp_window_state state; + size_t b_off, c_off, temp; + int line; + os_coord os_line_height; + rufl_code code; + os_error *error; + + ta = (struct text_area *)self; + if (!ta || ta->magic != MAGIC) { + LOG("magic doesn't match"); + return; + } + + if (ta->flags & TEXTAREA_READONLY) + return; + + os_line_height.x = 0; + os_line_height.y = (int)((float)(ta->line_height - ta->line_spacing) * 0.62) + 1; + ro_convert_pixels_to_os_units(&os_line_height, (os_mode)-1); + + state.w = ta->window; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + return; + } + + x = x - (state.visible.x0 - state.xscroll) - MARGIN_LEFT; + y = (state.visible.y1 - state.yscroll) - y; + + line = y / ta->line_height; + + if (line < 0) + line = 0; + if (ta->line_count - 1 < (unsigned)line) + line = ta->line_count - 1; + + code = rufl_x_to_offset(ta->font_family, ta->font_style, + ta->font_size, + ta->text + ta->lines[line].b_start, + ta->lines[line].b_length, + x, &b_off, &x); + if (code != rufl_OK) { + if (code == rufl_FONT_MANAGER_ERROR) + LOG("rufl_x_to_offset: 0x%x: %s", rufl_fm_error->errnum, rufl_fm_error->errmess); + else + LOG("rufl_x_to_offset: 0x%x", code); + return; + } + + for (temp = 0, c_off = 0; temp < b_off + ta->lines[line].b_start; + temp = utf8_next(ta->text, ta->text_len, temp)) + c_off++; + + ro_textarea_set_caret((uintptr_t)ta, c_off); +} + +/** + * Get the caret's position + * + * \param self Text area + * \return 0-based character index of caret location, or -1 on error + */ +unsigned int ro_textarea_get_caret(uintptr_t self) +{ + struct text_area *ta; + size_t c_off = 0, b_off; + + ta = (struct text_area *)self; + if (!ta || ta->magic != MAGIC) { + LOG("magic doesn't match"); + return -1; + } + + /* Calculate character offset of this line's start */ + for (b_off = 0; b_off < ta->lines[ta->caret_pos.line].b_start; + b_off = utf8_next(ta->text, ta->text_len, b_off)) + c_off++; + + return c_off + ta->caret_pos.char_off; +} + +/** \todo Selection handling */ + +/** + * Reflow a text area from the given line onwards + * + * \param ta Text area to reflow + * \param line Line number to begin reflow on + */ +void ro_textarea_reflow(struct text_area *ta, unsigned int line) +{ + rufl_code code; + char *text; + unsigned int len; + size_t b_off; + int x; + char *space; + unsigned int line_count = 0; + os_box extent; + os_error *error; + + /** \todo pay attention to line parameter */ + /** \todo create horizontal scrollbar if needed */ + + ta->line_count = 0; + + if (!ta->lines) { + ta->lines = + malloc(LINE_CHUNK_SIZE * sizeof(struct line_info)); + if (!ta->lines) { + LOG("malloc failed"); + return; + } + } + + if (!(ta->flags & TEXTAREA_MULTILINE)) { + /* Single line */ + ta->lines[line_count].b_start = 0; + ta->lines[line_count++].b_length = ta->text_len - 1; + + ta->line_count = line_count; + + return; + } + + for (len = ta->text_len - 1, text = ta->text; len > 0; + len -= b_off, text += b_off) { + code = rufl_split(ta->font_family, ta->font_style, + ta->font_size, text, len, + ta->vis_width - MARGIN_LEFT - MARGIN_RIGHT, + &b_off, &x); + if (code != rufl_OK) { + if (code == rufl_FONT_MANAGER_ERROR) + LOG("rufl_x_to_offset: 0x%x: %s", rufl_fm_error->errnum, rufl_fm_error->errmess); + else + LOG("rufl_x_to_offset: 0x%x", code); + return; + } + + if (line_count > 0 && line_count % LINE_CHUNK_SIZE == 0) { + struct line_info *temp = realloc(ta->lines, + (line_count + LINE_CHUNK_SIZE) * + sizeof(struct line_info)); + if (!temp) { + LOG("realloc failed"); + return; + } + + ta->lines = temp; + } + + /* handle CR/LF */ + for (space = text; space < text + b_off; space++) { + if (*space == '\r' || *space == '\n') + break; + } + + if (space != text + b_off) { + /* Found newline; use it */ + ta->lines[line_count].b_start = text - ta->text; + ta->lines[line_count++].b_length = space - text; + + /* CRLF / LFCR pair */ + if (*space == '\r' && *(space + 1) == '\n') + space++; + else if (*space == '\n' && *(space + 1) == '\r') + space++; + + b_off = space + 1 - text; + + if (len - b_off == 0) { + /* reached end of input => add last line */ + ta->lines[line_count].b_start = + text + b_off - ta->text; + ta->lines[line_count++].b_length = 0; + } + + continue; + } + + if (len - b_off > 0) { + /* find last space (if any) */ + for (space = text + b_off; space > text; space--) + if (*space == ' ') + break; + + if (space != text) + b_off = space + 1 - text; + } + + ta->lines[line_count].b_start = text - ta->text; + ta->lines[line_count++].b_length = b_off; + } + + ta->line_count = line_count; + + /* and now update extent */ + extent.x0 = 0; + extent.y1 = 0; + extent.x1 = ta->vis_width; + extent.y0 = -ta->line_height * line_count - ta->line_spacing; + + if (extent.y0 > (int)-ta->vis_height) + /* haven't filled window yet */ + return; + + error = xwimp_set_extent(ta->window, &extent); + if (error) { + LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess); + return; + } + + /* Create vertical scrollbar if we don't already have one */ + if (!ro_gui_wimp_check_window_furniture(ta->window, + wimp_WINDOW_VSCROLL)) { + wimp_window_state state; + wimp_w parent; + bits linkage; + unsigned int vscroll_width; + + /* Save window parent & linkage flags */ + state.w = ta->window; + error = xwimp_get_window_state_and_nesting(&state, + &parent, &linkage); + if (error) { + LOG("xwimp_get_window_state_and_nesting: 0x%x: %s", error->errnum, error->errmess); + return; + } + + /* Now, attempt to create vertical scrollbar */ + ro_gui_wimp_update_window_furniture(ta->window, + wimp_WINDOW_VSCROLL, + wimp_WINDOW_VSCROLL); + + /* Get new window state */ + state.w = ta->window; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + return; + } + + /* Get scroll width */ + vscroll_width = ro_get_vscroll_width(NULL); + + /* Shrink width by difference */ + state.visible.x1 -= vscroll_width; + + /* and reopen window */ + error = xwimp_open_window_nested(PTR_WIMP_OPEN(&state), + parent, linkage); + if (error) { + LOG("xwimp_open_window_nested: 0x%x: %s", error->errnum, error->errmess); + return; + } + + /* finally, update visible width */ + ta->vis_width -= vscroll_width; + + /* Now we've done that, we have to reflow the text area */ + ro_textarea_reflow(ta, 0); + } +} + +/** + * Handle mouse clicks in a text area + * + * \param pointer Mouse click state block + * \return true if click handled, false otherwise + */ +bool ro_textarea_mouse_click(wimp_pointer *pointer) +{ + struct text_area *ta; + + ta = (struct text_area *)ro_gui_wimp_event_get_user_data(pointer->w); + + ro_textarea_set_caret_xy((uintptr_t)ta, pointer->pos.x, pointer->pos.y); + return true; +} + +/** + * Handle key presses in a text area + * + * \param key Key pressed state block + * \return true if press handled, false otherwise + */ +bool ro_textarea_key_press(wimp_key *key) +{ + uint32_t c = (uint32_t) key->c; + wimp_key keypress; + struct text_area *ta; + bool redraw = false; + unsigned int c_pos; + + ta = (struct text_area *)ro_gui_wimp_event_get_user_data(key->w); + + if (ta->flags & TEXTAREA_READONLY) + return true; + + if (!(c & IS_WIMP_KEY || + (c <= 0x001f || (0x007f <= c && c <= 0x009f)))) { + /* normal character - insert */ + char utf8[7]; + size_t utf8_len; + + utf8_len = utf8_from_ucs4(c, utf8); + utf8[utf8_len] = '\0'; + + c_pos = ro_textarea_get_caret((uintptr_t)ta); + ro_textarea_insert_text((uintptr_t)ta, c_pos, utf8); + ro_textarea_set_caret((uintptr_t)ta, ++c_pos); + + redraw = true; + } else { + os_error *error; + /** \todo handle command keys */ + switch (c & ~IS_WIMP_KEY) { + case 8: /* Backspace */ + c_pos = ro_textarea_get_caret((uintptr_t)ta); + if (c_pos > 0) { + ro_textarea_replace_text((uintptr_t)ta, + c_pos - 1, c_pos, ""); + ro_textarea_set_caret((uintptr_t)ta, c_pos - 1); + redraw = true; + } + break; + case 21: /* Ctrl + U */ + ro_textarea_set_text((uintptr_t)ta, ""); + ro_textarea_set_caret((uintptr_t)ta, 0); + redraw = true; + break; + case wimp_KEY_DELETE: + c_pos = ro_textarea_get_caret((uintptr_t)ta); + if (os_version < RISCOS5 && c_pos > 0) { + ro_textarea_replace_text((uintptr_t)ta, + c_pos - 1, c_pos, ""); + ro_textarea_set_caret((uintptr_t)ta, c_pos - 1); + } else { + ro_textarea_replace_text((uintptr_t)ta, c_pos, + c_pos + 1, ""); + } + redraw = true; + break; + + case wimp_KEY_LEFT: + c_pos = ro_textarea_get_caret((uintptr_t)ta); + if (c_pos > 0) + ro_textarea_set_caret((uintptr_t)ta, c_pos - 1); + break; + case wimp_KEY_RIGHT: + c_pos = ro_textarea_get_caret((uintptr_t)ta); + ro_textarea_set_caret((uintptr_t)ta, c_pos + 1); + break; + case wimp_KEY_UP: + /** \todo Move caret up a line */ + break; + case wimp_KEY_DOWN: + /** \todo Move caret down a line */ + break; + + case wimp_KEY_HOME: + case wimp_KEY_CONTROL | wimp_KEY_LEFT: + /** \todo line start */ + break; + case wimp_KEY_CONTROL | wimp_KEY_RIGHT: + /** \todo line end */ + break; + case wimp_KEY_CONTROL | wimp_KEY_UP: + ro_textarea_set_caret((uintptr_t)ta, 0); + break; + case wimp_KEY_CONTROL | wimp_KEY_DOWN: + ro_textarea_set_caret((uintptr_t)ta, + utf8_length(ta->text)); + break; + + case wimp_KEY_COPY: + if (os_version < RISCOS5) { + c_pos = ro_textarea_get_caret((uintptr_t)ta); + ro_textarea_replace_text((uintptr_t)ta, c_pos, + c_pos + 1, ""); + } else { + /** \todo line end */ + } + break; + + /** pass on RETURN and ESCAPE to the parent icon */ + case wimp_KEY_RETURN: + if (ta->flags & TEXTAREA_MULTILINE) { + /* Insert newline */ + c_pos = ro_textarea_get_caret((uintptr_t)ta); + ro_textarea_insert_text((uintptr_t)ta, c_pos, + "\n"); + ro_textarea_set_caret((uintptr_t)ta, ++c_pos); + + redraw = true; + + break; + } + /* fall through */ + case wimp_KEY_ESCAPE: + keypress = *key; + keypress.w = ta->parent; + keypress.i = ta->icon; + keypress.index = 0; /* undefined if not in an icon */ + error = xwimp_send_message_to_window(wimp_KEY_PRESSED, + (wimp_message*)&keypress, ta->parent, + ta->icon, 0); + if (error) { + LOG("xwimp_send_message: 0x%x:%s", error->errnum, error->errmess); + } + break; + } + } + + if (redraw) { + wimp_draw update; + + update.w = ta->window; + update.box.x0 = 0; + update.box.y1 = 0; + update.box.x1 = ta->vis_width; + update.box.y0 = -ta->line_height * (ta->line_count + 1); + ro_textarea_redraw_internal(&update, true); + } + + return true; +} + +/** + * Handle WIMP redraw requests for text areas + * + * \param redraw Redraw request block + */ +void ro_textarea_redraw(wimp_draw *redraw) +{ + ro_textarea_redraw_internal(redraw, false); +} + +/** + * Internal textarea redraw routine + * + * \param redraw Redraw/update request block + * \param update True if update, false if full redraw + */ +void ro_textarea_redraw_internal(wimp_draw *redraw, bool update) +{ + struct text_area *ta; + int line; + osbool more; + rufl_code code; + os_error *error; + + ta = (struct text_area *)ro_gui_wimp_event_get_user_data(redraw->w); + + if (update) + error = xwimp_update_window(redraw, &more); + else + error = xwimp_redraw_window(redraw, &more); + if (error) { + LOG("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess); + return; + } + + while (more) { + int line0, line1; + int clip_y0, clip_y1; + clip_y0 = (redraw->box.y1-redraw->yscroll) - redraw->clip.y1; + clip_y1 = (redraw->box.y1-redraw->yscroll) - redraw->clip.y0; + + error = xcolourtrans_set_gcol( + (ta->flags & TEXTAREA_READONLY) ? 0xD9D9D900 + : 0xFFFFFF00, + colourtrans_SET_BG_GCOL | colourtrans_USE_ECFS_GCOL, + os_ACTION_OVERWRITE, 0, 0); + if (error) { + LOG("xcolourtrans_set_gcol: 0x%x: %s", error->errnum, error->errmess); + return; + } + + error = xos_clg(); + if (error) { + LOG("xos_clg: 0x%x: %s", error->errnum, error->errmess); + return; + } + + if (!ta->lines) + /* Nothing to redraw */ + return; + + line0 = clip_y0 / ta->line_height - 1; + line1 = clip_y1 / ta->line_height + 1; + + if (line0 < 0) + line0 = 0; + if (line1 < 0) + line1 = 0; + if (ta->line_count - 1 < (unsigned)line0) + line0 = ta->line_count - 1; + if (ta->line_count - 1 < (unsigned)line1) + line1 = ta->line_count - 1; + if (line1 < line0) + line1 = line0; + + for (line = line0; line <= line1; line++) { + if (ta->lines[line].b_length == 0) + continue; + + error = xcolourtrans_set_font_colours(font_CURRENT, + (ta->flags & TEXTAREA_READONLY) ? + 0xD9D9D900 : 0xFFFFFF00, + 0x00000000, 14, 0, 0, 0); + if (error) { + LOG("xcolourtrans_set_font_colours: 0x%x: %s", error->errnum, error->errmess); + return; + } + + code = rufl_paint(ta->font_family, ta->font_style, + ta->font_size, + ta->text + ta->lines[line].b_start, + ta->lines[line].b_length, + redraw->box.x0 - redraw->xscroll + MARGIN_LEFT, + redraw->box.y1 - redraw->yscroll - + ((line + 1) * + ta->line_height - ta->line_spacing), + rufl_BLEND_FONT); + if (code != rufl_OK) { + if (code == rufl_FONT_MANAGER_ERROR) + LOG("rufl_paint: rufl_FONT_MANAGER_ERROR: 0x%x: %s", rufl_fm_error->errnum, rufl_fm_error->errmess); + else + LOG("rufl_paint: 0x%x", code); + } + } + + error = xwimp_get_rectangle(redraw, &more); + if (error) { + LOG("xwimp_get_rectangle: 0x%x: %s", error->errnum, error->errmess); + return; + } + } +} + +/** + * Handle a WIMP open window request + * + * \param open OpenWindow block + */ +void ro_textarea_open(wimp_open *open) +{ + os_error *error; + + error = xwimp_open_window(open); + if (error) { + LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess); + return; + } +} diff --git a/frontends/riscos/textarea.h b/frontends/riscos/textarea.h new file mode 100644 index 000000000..c726a0e78 --- /dev/null +++ b/frontends/riscos/textarea.h @@ -0,0 +1,50 @@ +/* + * Copyright 2006 John-Mark Bell <jmb202@ecs.soton.ac.uk> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Single/Multi-line UTF-8 text area (interface) + */ + +#ifndef _NETSURF_RISCOS_TEXTAREA_H_ +#define _NETSURF_RISCOS_TEXTAREA_H_ +#include <stdbool.h> +#include <stdint.h> +#include "rufl.h" +#include "oslib/wimp.h" + +/* Text area flags */ +#define TEXTAREA_MULTILINE 0x01 /**< Text area is multiline */ +#define TEXTAREA_READONLY 0x02 /**< Text area is read only */ + +uintptr_t ro_textarea_create(wimp_w parent, wimp_i icon, unsigned int flags, + const char *font_family, unsigned int font_size, + rufl_style font_style); +bool ro_textarea_update(uintptr_t self); +void ro_textarea_destroy(uintptr_t self); +bool ro_textarea_set_text(uintptr_t self, const char *text); +int ro_textarea_get_text(uintptr_t self, char *buf, unsigned int len); +void ro_textarea_insert_text(uintptr_t self, unsigned int index, + const char *text); +void ro_textarea_replace_text(uintptr_t self, unsigned int start, + unsigned int end, const char *text); +void ro_textarea_set_caret(uintptr_t self, unsigned int caret); +void ro_textarea_set_caret_xy(uintptr_t self, int x, int y); +unsigned int ro_textarea_get_caret(uintptr_t self); + + +#endif diff --git a/frontends/riscos/textselection.c b/frontends/riscos/textselection.c new file mode 100644 index 000000000..718171db0 --- /dev/null +++ b/frontends/riscos/textselection.c @@ -0,0 +1,657 @@ +/* + * Copyright 2005 Adrian Lees <adrianl@users.sourceforge.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Text selection code (platform-dependent implementation) + */ + +#include <assert.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <oslib/osfile.h> +#include <oslib/wimp.h> + +#include "utils/log.h" +#include "utils/utf8.h" +#include "utils/utils.h" +#include "content/hlcache.h" +#include "desktop/gui_clipboard.h" +#include "desktop/gui_window.h" +#include "desktop/textinput.h" +#include "desktop/browser.h" + +#include "riscos/gui.h" +#include "riscos/menus.h" +#include "riscos/message.h" +#include "riscos/mouse.h" +#include "riscos/save.h" +#include "riscos/textselection.h" +#include "riscos/ucstables.h" + + +#ifndef wimp_DRAG_CLAIM_SUPPRESS_DRAGBOX +#define wimp_DRAG_CLAIM_SUPPRESS_DRAGBOX ((wimp_drag_claim_flags) 0x2u) +#endif + + +/** Receive of Dragging message has claimed it */ +static bool dragging_claimed = false; +static wimp_t dragging_claimant; +static os_box dragging_box = { -34, -34, 34, 34 }; /* \todo - size properly */ +static wimp_drag_claim_flags last_claim_flags = 0; +static struct gui_window *last_start_window; + +static bool drag_claimed = false; + +static bool owns_clipboard = false; +static bool owns_caret_and_selection = false; + +/* Current clipboard contents if we own the clipboard + * Current paste buffer if we don't + */ +static char *clipboard = NULL; +static size_t clip_length = 0; + +/* Paste context */ +static ro_gui_selection_prepare_paste_cb paste_cb = NULL; +static void *paste_cb_pw = NULL; +static int paste_prev_message = 0; + +static void ro_gui_selection_drag_end(wimp_dragged *drag, void *g); +static void ro_gui_discard_clipboard_contents(void); +static void ro_gui_dragging_bounced(wimp_message *message); + + +/** + * Start drag-selecting text within a browser window (RO-dependent part) + * + * \param g gui window + */ + +void gui_start_selection(struct gui_window *g) +{ + wimp_full_message_claim_entity msg; + wimp_auto_scroll_info scroll; + wimp_window_state state; + wimp_drag drag; + os_error *error; + + LOG("starting text_selection drag"); + + state.w = g->window; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + /* claim caret and selection */ + msg.size = sizeof(msg); + msg.your_ref = 0; + msg.action = message_CLAIM_ENTITY; + msg.flags = wimp_CLAIM_CARET_OR_SELECTION; + + error = xwimp_send_message(wimp_USER_MESSAGE, + (wimp_message*)&msg, wimp_BROADCAST); + if (error) { + LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + owns_caret_and_selection = true; + + scroll.w = g->window; + scroll.pause_zone_sizes.x0 = 80; + scroll.pause_zone_sizes.y0 = 80; + scroll.pause_zone_sizes.x1 = 80; + scroll.pause_zone_sizes.y1 = 80; + scroll.pause_duration = 0; + scroll.state_change = (void *)0; + error = xwimp_auto_scroll(wimp_AUTO_SCROLL_ENABLE_VERTICAL | + wimp_AUTO_SCROLL_ENABLE_HORIZONTAL, + &scroll, 0); + if (error) + LOG("xwimp_auto_scroll: 0x%x: %s", error->errnum, error->errmess); + + ro_mouse_drag_start(ro_gui_selection_drag_end, ro_gui_window_mouse_at, + NULL, g); + + drag.type = wimp_DRAG_USER_POINT; + /* Don't constrain mouse pointer during drags */ + drag.bbox.x0 = -16384; + drag.bbox.y0 = -16384; + drag.bbox.x1 = 16384; + drag.bbox.y1 = 16384; + + error = xwimp_drag_box(&drag); + if (error) { + LOG("xwimp_drag_box: 0x%x : %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + last_start_window = g; +} + + +/** + * End of text selection drag operation + * + * \param *drag position of pointer at conclusion of drag + * \param *data gui window pointer. + */ + +static void ro_gui_selection_drag_end(wimp_dragged *drag, void *data) +{ + wimp_auto_scroll_info scroll; + wimp_pointer pointer; + os_error *error; + os_coord pos; + struct gui_window *g = (struct gui_window *) data; + + scroll.w = g->window; + error = xwimp_auto_scroll(0, &scroll, 0); + if (error) + LOG("xwimp_auto_scroll: 0x%x: %s", error->errnum, error->errmess); + + error = xwimp_drag_box((wimp_drag*)-1); + if (error) { + LOG("xwimp_drag_box: 0x%x : %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + + error = xwimp_get_pointer_info(&pointer); + if (error) { + LOG("xwimp_get_pointer_info 0x%x : %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + if (ro_gui_window_to_window_pos(g, drag->final.x0, drag->final.y0, &pos)) + browser_window_mouse_track(g->bw, 0, pos.x, pos.y); +} + +/** + * Core tells front end to put given text in clipboard + * + * \param buffer UTF-8 text, owned by core + * \param length Byte length of UTF-8 text in buffer + * \param styles Array of styles given to text runs, owned by core, or NULL + * \param n_styles Number of text run styles in array + */ +static void gui_set_clipboard(const char *buffer, size_t length, + nsclipboard_styles styles[], int n_styles) +{ + char *new_cb; + + if (length == 0) + return; + + new_cb = malloc(length); + if (new_cb == NULL) + return; + + memcpy(new_cb, buffer, length); + + /* Replace existing clipboard contents */ + free(clipboard); + clipboard = new_cb; + clip_length = length; + + if (!owns_clipboard) { + /* Tell RO we now own clipboard */ + wimp_full_message_claim_entity msg; + os_error *error; + + LOG("claiming clipboard"); + + msg.size = sizeof(msg); + msg.your_ref = 0; + msg.action = message_CLAIM_ENTITY; + msg.flags = wimp_CLAIM_CLIPBOARD; + + error = xwimp_send_message(wimp_USER_MESSAGE, + (wimp_message*)&msg, wimp_BROADCAST); + if (error) { + LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + owns_clipboard = true; + } + + LOG("clipboard now holds %zd bytes", clip_length); +} + + +/** + * Core asks front end for clipboard contents. + * + * \param buffer UTF-8 text, allocated by front end, ownership yielded to core + * \param length Byte length of UTF-8 text in buffer + */ +static void gui_get_clipboard(char **buffer, size_t *length) +{ + *buffer = NULL; + *length = 0; + + if (clip_length > 0) { + char *cb = malloc(clip_length); + if (cb != NULL) { + memcpy(cb, clipboard, clip_length); + *buffer = cb; + *length = clip_length; + } + } +} + + +/** + * Discard the current contents of the clipboard, if any, releasing the + * memory it uses. + */ + +void ro_gui_discard_clipboard_contents(void) +{ + free(clipboard); + clipboard = NULL; + clip_length = 0; +} + + +static void ro_gui_selection_prepare_paste_complete(void) +{ + ro_gui_selection_prepare_paste_cb cb = paste_cb; + void *pw = paste_cb_pw; + + paste_cb = NULL; + paste_cb_pw = NULL; + paste_prev_message = 0; + + cb(pw); +} + +static void ro_gui_selection_prepare_paste_bounced(wimp_message *message) +{ + ro_gui_selection_prepare_paste_complete(); +} + +/** + * Prepare to paste data from another application + * + * \param w Window being pasted into + * \param cb Callback to call once preparation is complete + * \param pw Private data for callback + */ + +void ro_gui_selection_prepare_paste(wimp_w w, + ro_gui_selection_prepare_paste_cb cb, void *pw) +{ + if (owns_clipboard) { + /* We own the clipboard: we're already prepared */ + cb(pw); + } else { + /* Someone else owns the clipboard: request its contents */ + wimp_full_message_data_request msg; + bool success; + + ro_gui_discard_clipboard_contents(); + + msg.size = 48; /* There's only one filetype listed. */ + msg.your_ref = 0; + msg.action = message_DATA_REQUEST; + msg.w = w; + msg.i = -1; + msg.pos.x = 0; + msg.pos.y = 0; + msg.flags = wimp_DATA_REQUEST_CLIPBOARD; + msg.file_types[0] = osfile_TYPE_TEXT; + msg.file_types[1] = ~0; + + success = ro_message_send_message(wimp_USER_MESSAGE_RECORDED, + (wimp_message *) &msg, wimp_BROADCAST, + ro_gui_selection_prepare_paste_bounced); + if (success == false) { + /* Ensure key is handled, anyway */ + cb(pw); + } else { + /* Set up paste context */ + paste_cb = cb; + paste_cb_pw = pw; + paste_prev_message = msg.my_ref; + } + } +} + +/** + * Prepare to paste data from another application (step 2) + * + * \param dataxfer DataSave message + * \return True if message was handled, false otherwise + */ +bool ro_gui_selection_prepare_paste_datasave( + wimp_full_message_data_xfer *dataxfer) +{ + bool success; + + /* Ignore messages that aren't for us */ + if (dataxfer->your_ref == 0 || dataxfer->your_ref != paste_prev_message) + return false; + + /* We're done if the paste data isn't text */ + if (dataxfer->file_type != osfile_TYPE_TEXT) { + ro_gui_selection_prepare_paste_complete(); + return true; + } + + /* Generate and send DataSaveAck */ + dataxfer->your_ref = dataxfer->my_ref; + dataxfer->size = offsetof(wimp_full_message_data_xfer, file_name) + 16; + dataxfer->action = message_DATA_SAVE_ACK; + dataxfer->est_size = -1; + memcpy(dataxfer->file_name, "<Wimp$Scrap>", SLEN("<Wimp$Scrap>") + 1); + + success = ro_message_send_message(wimp_USER_MESSAGE_RECORDED, + (wimp_message *) dataxfer, dataxfer->sender, + ro_gui_selection_prepare_paste_bounced); + if (success == false) { + ro_gui_selection_prepare_paste_complete(); + } else { + paste_prev_message = dataxfer->my_ref; + } + + return true; +} + + +/** + * Prepare to paste data from another application (step 3) + * + * \param dataxfer DataLoad message + * \return True if message was handled, false otherwise + */ +bool ro_gui_selection_prepare_paste_dataload( + wimp_full_message_data_xfer *dataxfer) +{ + FILE *fp; + + /* Ignore messages that aren't for us */ + if (dataxfer->your_ref == 0 || dataxfer->your_ref != paste_prev_message) + return false; + + fp = fopen(dataxfer->file_name, "r"); + if (fp != NULL) { + long size; + fseek(fp, 0, SEEK_END); + size = ftell(fp); + fseek(fp, 0, SEEK_SET); + + if (size > 0) { + char *local_cb = malloc(size); + if (local_cb != NULL) { + nserror ret; + fread(local_cb, 1, size, fp); + + ret = utf8_from_local_encoding(local_cb, size, + &clipboard); + if (ret == NSERROR_OK) { + clip_length = strlen(clipboard); + } + + free(local_cb); + } + } + + fclose(fp); + } + + /* Send DataLoadAck */ + dataxfer->action = message_DATA_LOAD_ACK; + dataxfer->your_ref = dataxfer->my_ref; + ro_message_send_message(wimp_USER_MESSAGE, + (wimp_message *) dataxfer, dataxfer->sender, NULL); + + ro_gui_selection_prepare_paste_complete(); + return true; +} + + +/** + * Responds to CLAIM_ENTITY message notifying us that the caret + * and selection or clipboard have been claimed by another application. + * + * \param claim CLAIM_ENTITY message + */ + +void ro_gui_selection_claim_entity(wimp_full_message_claim_entity *claim) +{ + /* ignore our own broadcasts! */ + if (claim->sender != task_handle) { + + LOG("%x", claim->flags); + + if (claim->flags & wimp_CLAIM_CARET_OR_SELECTION) { + owns_caret_and_selection = false; + } + + if (claim->flags & wimp_CLAIM_CLIPBOARD) { + ro_gui_discard_clipboard_contents(); + owns_clipboard = false; + } + } +} + + +/** + * Responds to DATA_REQUEST message, returning information about the + * clipboard contents if we own the clipboard. + * + * \param req DATA_REQUEST message + */ + +void ro_gui_selection_data_request(wimp_full_message_data_request *req) +{ + if (owns_clipboard && clip_length > 0 && + (req->flags & wimp_DATA_REQUEST_CLIPBOARD)) { + wimp_full_message_data_xfer message; + int size; +// int i; + +// for(i = 0; i < NOF_ELEMENTS(req->file_types); i++) { +// bits ftype = req->file_types[i]; +// if (ftype == ~0U) break; /* list terminator */ +// +// LOG("type %x", ftype); +// i++; +// } + + /* we can only supply text at the moment, so that's what you're getting! */ + size = offsetof(wimp_full_message_data_xfer, file_name) + 9; + message.size = (size + 3) & ~3; + message.your_ref = req->my_ref; + message.action = message_DATA_SAVE; + message.w = req->w; + message.i = req->i; + message.pos = req->pos; + message.file_type = osfile_TYPE_TEXT; + message.est_size = clip_length; + memcpy(message.file_name, "TextFile", 9); + + ro_gui_send_datasave(GUI_SAVE_CLIPBOARD_CONTENTS, + &message, req->sender); + } +} + + +/** + * Save the clipboard contents to a file. + * + * \param path the pathname of the file + * \return true iff success, otherwise reporting the error before returning false + */ + +bool ro_gui_save_clipboard(const char *path) +{ + char *local_cb; + nserror ret; + os_error *error; + + assert(clip_length > 0 && clipboard); + + ret = utf8_to_local_encoding(clipboard, clip_length, &local_cb); + if (ret != NSERROR_OK) { + ro_warn_user("SaveError", "Could not convert"); + return false; + } + + error = xosfile_save_stamped(path, osfile_TYPE_TEXT, + (byte*) local_cb, + (byte*) local_cb + strlen(local_cb)); + + free(local_cb); + + if (error) { + LOG("xosfile_save_stamped: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("SaveError", error->errmess); + return false; + } + + return true; +} + + +/** + * Handler for Message_Dragging, used to implement auto-scrolling and + * ghost caret when a drag is in progress. + */ + +void ro_gui_selection_dragging(wimp_message *message) +{ + wimp_full_message_dragging *drag = (wimp_full_message_dragging*)message; + struct gui_window *g; + os_coord pos; + + /* with autoscrolling, we will probably need to remember the + * gui_window and override the drag->w window handle which + * could be any window on the desktop */ + g = ro_gui_window_lookup(drag->w); + + if ((drag->flags & wimp_DRAGGING_TERMINATE_DRAG) || !g) { + + drag_claimed = false; + return; + } + + if (!ro_gui_window_to_window_pos(g, drag->pos.x, drag->pos.y, &pos)) + return; + + drag_claimed = false; +} + + + +/** + * Reset drag-and-drop state when drag completes (DataSave received) + */ + +void ro_gui_selection_drag_reset(void) +{ + drag_claimed = false; +} + + +/** + * + */ + +void ro_gui_selection_drag_claim(wimp_message *message) +{ + wimp_full_message_drag_claim *claim = (wimp_full_message_drag_claim*)message; + + dragging_claimant = message->sender; + dragging_claimed = true; + + /* have we been asked to remove the drag box/sprite? */ + if (claim->flags & wimp_DRAG_CLAIM_SUPPRESS_DRAGBOX) { + ro_gui_drag_box_cancel(); + } + else { + /* \todo - restore it here? */ + } + + /* do we need to restore the default pointer shape? */ + if ((last_claim_flags & wimp_DRAG_CLAIM_POINTER_CHANGED) && + !(claim->flags & wimp_DRAG_CLAIM_POINTER_CHANGED)) { + gui_window_set_pointer(last_start_window, GUI_POINTER_DEFAULT); + } + + last_claim_flags = claim->flags; +} + + +void ro_gui_selection_send_dragging(wimp_pointer *pointer) +{ + wimp_full_message_dragging dragmsg; + + LOG("sending DRAGGING to %p, %d", pointer->w, pointer->i); + + dragmsg.size = offsetof(wimp_full_message_dragging, file_types) + 8; + dragmsg.your_ref = 0; + dragmsg.action = message_DRAGGING; + dragmsg.w = pointer->w; + dragmsg.i = pointer->i; + dragmsg.pos = pointer->pos; +/* \todo - this is interesting because it depends upon not just the state of the + shift key, but also whether it /can/ be deleted, ie. from text area/input + rather than page contents */ + dragmsg.flags = wimp_DRAGGING_FROM_SELECTION; + dragmsg.box = dragging_box; + dragmsg.file_types[0] = osfile_TYPE_TEXT; + dragmsg.file_types[1] = ~0; + + /* if the message_dragmsg messages have been claimed we must address them + to the claimant task, which is not necessarily the task that owns whatever + window happens to be under the pointer */ + + if (dragging_claimed) { + ro_message_send_message(wimp_USER_MESSAGE_RECORDED, + (wimp_message*)&dragmsg, dragging_claimant, ro_gui_dragging_bounced); + } + else { + ro_message_send_message_to_window(wimp_USER_MESSAGE_RECORDED, + (wimp_message*)&dragmsg, pointer->w, pointer->i, + ro_gui_dragging_bounced, &dragging_claimant); + } +} + + +/** + * Our message_DRAGGING message was bounced, ie. the intended recipient does not + * support the drag-and-drop protocol or cannot receive the data at the pointer + * position. + */ + +void ro_gui_dragging_bounced(wimp_message *message) +{ + dragging_claimed = false; +} + +static struct gui_clipboard_table clipboard_table = { + .get = gui_get_clipboard, + .set = gui_set_clipboard, +}; + +struct gui_clipboard_table *riscos_clipboard_table = &clipboard_table; diff --git a/frontends/riscos/textselection.h b/frontends/riscos/textselection.h new file mode 100644 index 000000000..400e3dd26 --- /dev/null +++ b/frontends/riscos/textselection.h @@ -0,0 +1,53 @@ +/* + * Copyright 2006 Adrian Lees <adrianl@users.sourceforge.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Text selection import/export (interface). + */ + +#ifndef _NETSURF_RISCOS_TEXTSELECTION_H_ +#define _NETSURF_RISCOS_TEXTSELECTION_H_ + +#include "oslib/wimp.h" + +struct gui_clipboard_table *riscos_clipboard_table; + +void gui_start_selection(struct gui_window *g); + +typedef void (*ro_gui_selection_prepare_paste_cb)(void *pw); + +void ro_gui_selection_prepare_paste(wimp_w w, + ro_gui_selection_prepare_paste_cb cb, void *pw); +bool ro_gui_selection_prepare_paste_datasave( + wimp_full_message_data_xfer *dataxfer); +bool ro_gui_selection_prepare_paste_dataload( + wimp_full_message_data_xfer *dataxfer); + +void ro_gui_selection_claim_entity(wimp_full_message_claim_entity *claim); +void ro_gui_selection_data_request(wimp_full_message_data_request *req); +bool ro_gui_save_clipboard(const char *path); + +/* drag-and-drop, receiving */ +void ro_gui_selection_dragging(wimp_message *message); +void ro_gui_selection_drag_reset(void); + +/* drag-and-drop, sending */ +void ro_gui_selection_send_dragging(wimp_pointer *pointer); +void ro_gui_selection_drag_claim(wimp_message *message); + +#endif diff --git a/frontends/riscos/theme.c b/frontends/riscos/theme.c new file mode 100644 index 000000000..714b9e5a1 --- /dev/null +++ b/frontends/riscos/theme.c @@ -0,0 +1,741 @@ +/* + * Copyright 2004, 2005 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Window themes (implementation). + */ + +#include <alloca.h> +#include <assert.h> +#include <stdio.h> +#include <stdbool.h> +#include <string.h> +#include "oslib/dragasprite.h" +#include "oslib/os.h" +#include "oslib/osgbpb.h" +#include "oslib/osfile.h" +#include "oslib/osfind.h" +#include "oslib/osspriteop.h" +#include "oslib/wimpspriteop.h" +#include "oslib/squash.h" +#include "oslib/wimp.h" +#include "oslib/wimpextend.h" +#include "oslib/wimpspriteop.h" + +#include "utils/nsoption.h" +#include "utils/log.h" +#include "content/content.h" + +#include "riscos/cookies.h" +#include "riscos/dialog.h" +#include "riscos/global_history.h" +#include "riscos/gui.h" +#include "riscos/hotlist.h" +#include "riscos/menus.h" +#include "riscos/theme.h" +#include "riscos/treeview.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" +#include "riscos/wimputils.h" + +/** @todo provide a proper interface for these and make them static again! */ + +static struct theme_descriptor *theme_current = NULL; +static struct theme_descriptor *theme_descriptors = NULL; + +static bool ro_gui_theme_add_descriptor(const char *folder, const char *leafname); +static void ro_gui_theme_get_available_in_dir(const char *directory); +static void ro_gui_theme_free(struct theme_descriptor *descriptor); + +/** + * Initialise the theme handler + */ +void ro_gui_theme_initialise(void) +{ + struct theme_descriptor *descriptor; + + theme_descriptors = ro_gui_theme_get_available(); + descriptor = ro_gui_theme_find(nsoption_charp(theme)); + if (!descriptor) + descriptor = ro_gui_theme_find("Aletheia"); + ro_gui_theme_apply(descriptor); +} + + +/** + * Finalise the theme handler + */ +void ro_gui_theme_finalise(void) +{ + ro_gui_theme_close(theme_current, false); + ro_gui_theme_free(theme_descriptors); +} + + +/** + * Finds a theme from the cached values. + * + * The returned theme is only guaranteed to be valid until the next call + * to ro_gui_theme_get_available() unless it has been opened using + * ro_gui_theme_open(). + * + * \param leafname the filename of the theme_descriptor to return + * \return the requested theme_descriptor, or NULL if not found + */ +struct theme_descriptor *ro_gui_theme_find(const char *leafname) +{ + struct theme_descriptor *descriptor; + + if (!leafname) + return NULL; + + for (descriptor = theme_descriptors; descriptor; + descriptor = descriptor->next) + if (!strcmp(leafname, descriptor->leafname)) + return descriptor; + /* fallback for 10 chars on old filesystems */ + for (descriptor = theme_descriptors; descriptor; + descriptor = descriptor->next) + if (!strncmp(leafname, descriptor->leafname, 10)) + return descriptor; + return NULL; +} + + +/** + * Reads and caches the currently available themes. + * + * \return the requested theme_descriptor, or NULL if not found + */ +struct theme_descriptor *ro_gui_theme_get_available(void) +{ + struct theme_descriptor *current; + struct theme_descriptor *test; + + /* close any unused descriptors */ + ro_gui_theme_free(theme_descriptors); + + /* add our default 'Aletheia' theme */ + ro_gui_theme_add_descriptor("NetSurf:Resources", "Aletheia"); + + /* scan our choices directory */ + ro_gui_theme_get_available_in_dir(nsoption_charp(theme_path)); + + /* sort alphabetically in a very rubbish way */ + if ((theme_descriptors) && (theme_descriptors->next)) { + current = theme_descriptors; + while ((test = current->next)) { + if (strcmp(current->name, test->name) > 0) { + current->next->previous = current->previous; + if (current->previous) + current->previous->next = current->next; + current->next = test->next; + test->next = current; + current->previous = test; + if (current->next) + current->next->previous = current; + + current = test->previous; + if (!current) current = test; + } else { + current = current->next; + } + } + while (theme_descriptors->previous) + theme_descriptors = theme_descriptors->previous; + } + + return theme_descriptors; +} + + +/** + * Adds the themes in a directory to the global cache. + * + * \param directory the directory to scan + */ +static void ro_gui_theme_get_available_in_dir(const char *directory) +{ + int context = 0; + int read_count; + osgbpb_INFO(100) info; + + while (context != -1) { + /* read some directory info */ + os_error *error = xosgbpb_dir_entries_info(directory, + (osgbpb_info_list *) &info, 1, context, + sizeof(info), 0, &read_count, &context); + if (error) { + LOG("xosgbpb_dir_entries_info: 0x%x: %s", + error->errnum, error->errmess); + if (error->errnum == 0xd6) /* no such dir */ + return; + ro_warn_user("MiscError", error->errmess); + break; + } + + /* only process files */ + if ((read_count != 0) && (info.obj_type == fileswitch_IS_FILE)) + ro_gui_theme_add_descriptor(directory, info.name); + } +} + + +/** + * Returns the current theme handle, or NULL if none is set. + * + * \return The theme descriptor handle, or NULL. + */ + +struct theme_descriptor *ro_gui_theme_get_current(void) +{ + return theme_current; +} + + +/** + * Returns a sprite area for use with the given theme. This may return a + * pointer to the wimp sprite pool if a theme area isn't available. + * + * \param *descriptor The theme to use, or NULL for the current. + * \return A pointer to the theme sprite area. + */ + +osspriteop_area *ro_gui_theme_get_sprites(struct theme_descriptor *descriptor) +{ + osspriteop_area *area; + + if (descriptor == NULL) + descriptor = theme_current; + + if (descriptor != NULL && descriptor->theme != NULL) + area = descriptor->theme->sprite_area; + else + area = (osspriteop_area *) 1; + + return area; +} + + +/** + * Returns an interger element from the specified theme, or the current theme + * if the descriptor is NULL. + * + * This is an attempt to abstract the theme data from its clients: it should + * simplify the task of expanding the theme system in the future should this + * be necessary to include other parts of the RISC OS GUI in the theme system. + * + * \param *descriptor The theme to use, or NULL for the current. + * \param style The style to use. + * \param element The style element to return. + * \return The requested value, or 0. + */ + +int ro_gui_theme_get_style_element(struct theme_descriptor *descriptor, + theme_style style, theme_element element) +{ + if (descriptor == NULL) + descriptor = theme_current; + + if (descriptor == NULL) + return 0; + + switch (style) { + case THEME_STYLE_NONE: + switch(element) { + case THEME_ELEMENT_FOREGROUND: + return wimp_COLOUR_BLACK; + case THEME_ELEMENT_BACKGROUND: + return wimp_COLOUR_VERY_LIGHT_GREY; + default: + return 0; + } + break; + + case THEME_STYLE_BROWSER_TOOLBAR: + switch (element) { + case THEME_ELEMENT_FOREGROUND: + return wimp_COLOUR_BLACK; + case THEME_ELEMENT_BACKGROUND: + return descriptor->browser_background; + default: + return 0; + } + break; + + case THEME_STYLE_HOTLIST_TOOLBAR: + case THEME_STYLE_COOKIES_TOOLBAR: + case THEME_STYLE_GLOBAL_HISTORY_TOOLBAR: + switch (element) { + case THEME_ELEMENT_FOREGROUND: + return wimp_COLOUR_BLACK; + case THEME_ELEMENT_BACKGROUND: + return descriptor->hotlist_background; + default: + return 0; + } + break; + + case THEME_STYLE_STATUS_BAR: + switch (element) { + case THEME_ELEMENT_FOREGROUND: + return descriptor->status_foreground; + case THEME_ELEMENT_BACKGROUND: + return descriptor->status_background; + default: + return 0; + } + break; + + default: + return 0; + } +} + +/** + * Returns details of the throbber as defined in a theme. + * + * \param *descriptor The theme of interest (NULL for current). + * \param *frames Return the number of animation frames. + * \param *width Return the throbber width. + * \param *height Return the throbber height. + * \param *right Return the 'locate on right' flag. + * \param *redraw Return the 'forcible redraw' flag. + * \return true if meaningful data has been returned; + * else false. + */ + +bool ro_gui_theme_get_throbber_data(struct theme_descriptor *descriptor, + int *frames, int *width, int *height, + bool *right, bool *redraw) +{ + if (descriptor == NULL) + descriptor = theme_current; + + if (descriptor == NULL || descriptor->theme == NULL) + return false; + + if (frames != NULL) + *frames = descriptor->theme->throbber_frames; + if (width != NULL) + *width = descriptor->theme->throbber_width; + if (height != NULL) + *height = descriptor->theme->throbber_height; + if (right != NULL) + *right = descriptor->throbber_right; + if (redraw != NULL) + *redraw = descriptor->throbber_redraw; + + return true; +} + + +/** + * Checks a theme is valid and adds it to the current list + * + * \param folder the theme folder + * \param leafname the theme leafname + * \return whether the theme was added + */ +bool ro_gui_theme_add_descriptor(const char *folder, const char *leafname) +{ + struct theme_file_header file_header; + struct theme_descriptor *current; + struct theme_descriptor *test; + int output_left; + os_fw file_handle; + os_error *error; + char *filename; + + /* create a full filename */ + filename = malloc(strlen(folder) + strlen(leafname) + 2); + if (!filename) { + LOG("No memory for malloc"); + ro_warn_user("NoMemory", 0); + return false; + } + sprintf(filename, "%s.%s", folder, leafname); + + /* get the header */ + error = xosfind_openinw(osfind_NO_PATH, filename, 0, + &file_handle); + if (error) { + LOG("xosfind_openinw: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("FileError", error->errmess); + free(filename); + return false; + } + if (file_handle == 0) { + free(filename); + return false; + } + error = xosgbpb_read_atw(file_handle, + (byte *) &file_header, + sizeof (struct theme_file_header), + 0, &output_left); + xosfind_closew(file_handle); + if (error) { + LOG("xosbgpb_read_atw: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("FileError", error->errmess); + free(filename); + return false; + } + if (output_left > 0) { /* should try to read more? */ + free(filename); + return false; + } + + /* create a new theme descriptor */ + current = (struct theme_descriptor *)calloc(1, + sizeof(struct theme_descriptor)); + if (!current) { + LOG("calloc failed"); + ro_warn_user("NoMemory", 0); + free(filename); + return false; + } + if (!ro_gui_theme_read_file_header(current, &file_header)) { + free(filename); + free(current); + return false; + } + current->filename = filename; + current->leafname = current->filename + strlen(folder) + 1; + + /* don't add duplicates */ + for (test = theme_descriptors; test; test = test->next) { + if (!strcmp(current->name, test->name)) { + free(current->filename); + free(current); + return false; + } + } + + /* link in our new descriptor at the head*/ + if (theme_descriptors) { + current->next = theme_descriptors; + theme_descriptors->previous = current; + } + theme_descriptors = current; + return true; + +} + + +/** + * Fills in the basic details for a descriptor from a file header. + * The filename string is not set. + * + * \param descriptor the descriptor to set up + * \param file_header the header to read from + * \return false for a badly formed theme, true otherwise + */ +bool ro_gui_theme_read_file_header(struct theme_descriptor *descriptor, + struct theme_file_header *file_header) +{ + if ((file_header->magic_value != 0x4d54534e) || + (file_header->parser_version > 2)) + return false; + + strcpy(descriptor->name, file_header->name); + strcpy(descriptor->author, file_header->author); + descriptor->browser_background = file_header->browser_bg; + descriptor->hotlist_background = file_header->hotlist_bg; + descriptor->status_background = file_header->status_bg; + descriptor->status_foreground = file_header->status_fg; + descriptor->decompressed_size = file_header->decompressed_sprite_size; + descriptor->compressed_size = file_header->compressed_sprite_size; + if (file_header->parser_version >= 2) { + descriptor->throbber_right = + !(file_header->theme_flags & (1 << 0)); + descriptor->throbber_redraw = + file_header->theme_flags & (1 << 1); + } else { + descriptor->throbber_right = + (file_header->theme_flags == 0x00); + descriptor->throbber_redraw = true; + } + return true; +} + + +/** + * Opens a theme ready for use. + * + * \param descriptor the theme_descriptor to open + * \param list whether to open all themes in the list + * \return whether the operation was successful + */ +bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list) +{ + fileswitch_object_type obj_type; + squash_output_status status; + os_coord dimensions; + os_mode mode; + os_error *error; + struct theme_descriptor *next_descriptor; + char sprite_name[16]; + const char *name = sprite_name; + bool result = true; + int i, n; + int workspace_size, file_size; + char *raw_data, *workspace; + osspriteop_area *decompressed; + + /* If we are freeing the whole of the list then we need to + start at the first descriptor. + */ + if (list && descriptor) + while (descriptor->previous) descriptor = descriptor->previous; + + /* Open the themes + */ + for (; descriptor; descriptor = next_descriptor) { + /* see if we should iterate through the entire list */ + if (list) + next_descriptor = descriptor->next; + else + next_descriptor = NULL; + + /* if we are already loaded, increase the usage count */ + if (descriptor->theme) { + descriptor->theme->users = descriptor->theme->users + 1; + continue; + } + + /* create a new theme */ + descriptor->theme = (struct theme *)calloc(1, + sizeof(struct theme)); + if (!descriptor->theme) { + LOG("calloc() failed"); + ro_warn_user("NoMemory", 0); + continue; + } + descriptor->theme->users = 1; + + /* try to load the associated file */ + error = xosfile_read_stamped_no_path(descriptor->filename, + &obj_type, 0, 0, &file_size, 0, 0); + if (error) { + LOG("xosfile_read_stamped_no_path: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("FileError", error->errmess); + continue; + } + if (obj_type != fileswitch_IS_FILE) + continue; + raw_data = malloc(file_size); + if (!raw_data) { + LOG("malloc() failed"); + ro_warn_user("NoMemory", 0); + continue; + } + error = xosfile_load_stamped_no_path(descriptor->filename, + (byte *)raw_data, 0, 0, 0, 0, 0); + if (error) { + free(raw_data); + LOG("xosfile_load_stamped_no_path: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("FileError", error->errmess); + continue; + } + + /* decompress the new data */ + error = xsquash_decompress_return_sizes(-1, &workspace_size, 0); + if (error) { + free(raw_data); + LOG("xsquash_decompress_return_sizes: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MiscError", error->errmess); + continue; + } + decompressed = (osspriteop_area *)malloc( + descriptor->decompressed_size); + workspace = malloc(workspace_size); + if ((!decompressed) || (!workspace)) { + free(decompressed); + free(raw_data); + LOG("malloc() failed"); + ro_warn_user("NoMemory", 0); + continue; + } + error = xsquash_decompress(squash_INPUT_ALL_PRESENT, workspace, + (byte *)(raw_data + sizeof( + struct theme_file_header)), + descriptor->compressed_size, + (byte *)decompressed, + descriptor->decompressed_size, + &status, 0, 0, 0, 0); + free(workspace); + free(raw_data); + if (error) { + free(decompressed); + LOG("xsquash_decompress: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MiscError", error->errmess); + continue; + } + if (status != 0) { + free(decompressed); + continue; + } + descriptor->theme->sprite_area = decompressed; + + /* find the highest sprite called 'throbber%i', and get the + * maximum dimensions for all 'thobber%i' icons. */ + for (i = 1; i <= descriptor->theme->sprite_area->sprite_count; + i++) { + error = xosspriteop_return_name(osspriteop_USER_AREA, + descriptor->theme->sprite_area, + sprite_name, 16, i, 0); + if (error) { + LOG("xosspriteop_return_name: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MiscError", error->errmess); + continue; + } + if (strncmp(sprite_name, "throbber", 8)) + continue; + + /* get the max sprite width/height */ + error = xosspriteop_read_sprite_info( + osspriteop_USER_AREA, + descriptor->theme->sprite_area, + (osspriteop_id) name, + &dimensions.x, &dimensions.y, + (osbool *) 0, &mode); + if (error) { + LOG("xosspriteop_read_sprite_info: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MiscError", error->errmess); + continue; + } + ro_convert_pixels_to_os_units(&dimensions, mode); + if (descriptor->theme->throbber_width < dimensions.x) + descriptor->theme->throbber_width = + dimensions.x; + if (descriptor->theme->throbber_height < dimensions.y) + descriptor->theme->throbber_height = + dimensions.y; + + /* get the throbber number */ + n = atoi(sprite_name + 8); + if (descriptor->theme->throbber_frames < n) + descriptor->theme->throbber_frames = n; + } + } + return result; +} + + +/** + * Applies the theme to all current windows and subsequent ones. + * + * \param descriptor the theme_descriptor to open + * \return whether the operation was successful + */ +bool ro_gui_theme_apply(struct theme_descriptor *descriptor) +{ + struct theme_descriptor *theme_previous; + + /* check if the theme is already applied */ + if (descriptor == theme_current) + return true; + + /* re-open the new-theme and release the current theme */ + if (!ro_gui_theme_open(descriptor, false)) + return false; + theme_previous = theme_current; + theme_current = descriptor; + + /* apply the theme to all the current toolbar-ed windows */ + ro_toolbar_theme_update(); + + ro_gui_theme_close(theme_previous, false); + return true; +} + + +/** + * Closes a theme after use. + * + * \param descriptor the theme_descriptor to close + * \param list whether to open all themes in the list + * \return whether the operation was successful + */ +void ro_gui_theme_close(struct theme_descriptor *descriptor, bool list) +{ + + if (!descriptor) + return; + + /* move to the start of the list */ + while (list && descriptor->previous) + descriptor = descriptor->previous; + + /* close the themes */ + while (descriptor) { + if (descriptor->theme) { + descriptor->theme->users = descriptor->theme->users - 1; + if (descriptor->theme->users <= 0) { + free(descriptor->theme->sprite_area); + free(descriptor->theme); + descriptor->theme = NULL; + } + } + if (!list) + return; + descriptor = descriptor->next; + } +} + + +/** + * Frees any unused theme descriptors. + * + * \param descriptor the theme_descriptor to free + */ +void ro_gui_theme_free(struct theme_descriptor *descriptor) +{ + struct theme_descriptor *next_descriptor; + + if (!descriptor) + return; + + /* move to the start of the list */ + while (descriptor->previous) + descriptor = descriptor->previous; + + /* free closed themes */ + for (; descriptor; descriptor = next_descriptor) { + next_descriptor = descriptor->next; + + /* no theme? no descriptor */ + if (!descriptor->theme) { + if (descriptor->previous) + descriptor->previous->next = descriptor->next; + if (descriptor->next) + descriptor->next->previous = + descriptor->previous; + + /* keep the cached list in sync */ + if (theme_descriptors == descriptor) + theme_descriptors = next_descriptor; + + /* release any memory */ + free(descriptor->filename); + free(descriptor); + } + } +} + + diff --git a/frontends/riscos/theme.h b/frontends/riscos/theme.h new file mode 100644 index 000000000..4a4ba1cb2 --- /dev/null +++ b/frontends/riscos/theme.h @@ -0,0 +1,109 @@ +/* + * Copyright 2005 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Window themes(interface). + */ + +#include <stdbool.h> +#include "oslib/osspriteop.h" + +#ifndef _NETSURF_RISCOS_THEME_H_ +#define _NETSURF_RISCOS_THEME_H_ + +/** Theme styles, collecting groups of attributes for different locations. */ + +typedef enum { + THEME_STYLE_NONE = 0, + THEME_STYLE_BROWSER_TOOLBAR, + THEME_STYLE_HOTLIST_TOOLBAR, + THEME_STYLE_COOKIES_TOOLBAR, + THEME_STYLE_GLOBAL_HISTORY_TOOLBAR, + THEME_STYLE_STATUS_BAR +} theme_style; + +/** Theme elements, which belong to styles. */ + +typedef enum { + THEME_ELEMENT_FOREGROUND, + THEME_ELEMENT_BACKGROUND +} theme_element; + +struct theme_file_header { + unsigned int magic_value; + unsigned int parser_version; + char name[32]; + char author[64]; + char browser_bg; + char hotlist_bg; + char status_bg; + char status_fg; + char theme_flags; + char future_expansion_1; + char future_expansion_2; + char future_expansion_3; + unsigned int compressed_sprite_size; + unsigned int decompressed_sprite_size; +}; + +struct theme { + osspriteop_area *sprite_area; /**< sprite area for theme */ + int throbber_width; /**< width of the throbber */ + int throbber_height; /**< height of the throbber */ + int throbber_frames; /**< frames of animation for the throbber */ + int users; /**< number of users for the theme */ +}; + +struct theme_descriptor { + char *leafname; /**< theme leafname */ + char *filename; /**< theme filename */ + char name[32]; /**< theme name */ + char author[64]; /**< theme author */ + int browser_background; /**< background colour of browser toolbar */ + int hotlist_background; /**< background colour of hotlist toolbar */ + int status_background; /**< background colour of status window */ + int status_foreground; /**< colour of status window text */ + bool throbber_right; /**< throbber is on the right (left otherwise) */ + bool throbber_redraw; /**< throbber requires forcible updating */ + unsigned int decompressed_size; /**< decompressed sprite size */ + unsigned int compressed_size; /**< compressed sprite size */ + struct theme *theme; /**< corresponding theme (must be opened) */ + struct theme_descriptor *previous; /**< previous descriptor in the list */ + struct theme_descriptor *next; /**< next descriptor in the list */ +}; + +void ro_gui_theme_initialise(void); +void ro_gui_theme_finalise(void); +struct theme_descriptor *ro_gui_theme_find(const char *leafname); +struct theme_descriptor *ro_gui_theme_get_available(void); +struct theme_descriptor *ro_gui_theme_get_current(void); +osspriteop_area *ro_gui_theme_get_sprites(struct theme_descriptor *descriptor); +int ro_gui_theme_get_style_element(struct theme_descriptor *descriptor, + theme_style style, theme_element element); +bool ro_gui_theme_get_throbber_data(struct theme_descriptor *descriptor, + int *frames, int *width, int *height, + bool *right, bool *redraw); + +bool ro_gui_theme_read_file_header(struct theme_descriptor *descriptor, + struct theme_file_header *file_header); + +bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list); +bool ro_gui_theme_apply(struct theme_descriptor *descriptor); +void ro_gui_theme_close(struct theme_descriptor *descriptor, bool list); +#endif + diff --git a/frontends/riscos/theme_install.c b/frontends/riscos/theme_install.c new file mode 100644 index 000000000..5c11ffb83 --- /dev/null +++ b/frontends/riscos/theme_install.c @@ -0,0 +1,237 @@ +/* + * Copyright 2005 James Bursa <bursa@users.sourceforge.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Theme auto-installing. + */ + +#include <assert.h> +#include <stdbool.h> +#include <oslib/osfile.h> +#include <oslib/wimp.h> + +#include "utils/nsoption.h" +#include "utils/log.h" +#include "utils/messages.h" +#include "content/content.h" +#include "content/hlcache.h" +#include "desktop/browser.h" +#include "desktop/theme.h" + +#include "riscos/dialog.h" +#include "riscos/gui.h" +#include "riscos/theme.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" + + +static hlcache_handle *theme_install_content = NULL; +static struct theme_descriptor theme_install_descriptor; +wimp_w dialog_theme_install; + + +static void theme_install_close(wimp_w w); +static nserror theme_install_callback(hlcache_handle *handle, + const hlcache_event *event, void *pw); +static bool theme_install_read(const char *source_data, + unsigned long source_size); + + +/** + * Handle a CONTENT_THEME that has started loading. + */ + +void theme_install_start(hlcache_handle *c) +{ + assert(c != NULL); + assert(content_get_type(c) == CONTENT_THEME); + + if (ro_gui_dialog_open_top(dialog_theme_install, NULL, 0, 0)) { + ro_warn_user("ThemeInstActive", 0); + return; + } + + /* stop theme sitting in memory cache */ + content_invalidate_reuse_data(c); + + hlcache_handle_replace_callback(c, theme_install_callback, NULL); + + ro_gui_set_icon_string(dialog_theme_install, ICON_THEME_INSTALL_MESSAGE, + messages_get("ThemeInstDown"), true); + ro_gui_set_icon_shaded_state(dialog_theme_install, + ICON_THEME_INSTALL_INSTALL, true); + ro_gui_wimp_event_register_close_window(dialog_theme_install, + theme_install_close); +} + + +/** + * Callback for fetchcache() for theme install fetches. + */ + +nserror theme_install_callback(hlcache_handle *handle, + const hlcache_event *event, void *pw) +{ + switch (event->type) { + + case CONTENT_MSG_DONE: + { + const char *source_data; + unsigned long source_size; + int author_indent = 0; + char buffer[256]; + + theme_install_content = handle; + + source_data = content_get_source_data(handle, &source_size); + + if (!theme_install_read(source_data, source_size)) { + ro_warn_user("ThemeInvalid", 0); + theme_install_close(dialog_theme_install); + break; + } + + /* remove '© ' from the start of the data */ + if (theme_install_descriptor.author[0] == '©') + author_indent++; + while (theme_install_descriptor.author[author_indent] == ' ') + author_indent++; + snprintf(buffer, sizeof buffer, messages_get("ThemeInstall"), + theme_install_descriptor.name, + &theme_install_descriptor.author[author_indent]); + buffer[sizeof buffer - 1] = '\0'; + ro_gui_set_icon_string(dialog_theme_install, + ICON_THEME_INSTALL_MESSAGE, + buffer, true); + ro_gui_set_icon_shaded_state(dialog_theme_install, + ICON_THEME_INSTALL_INSTALL, false); + } + break; + + case CONTENT_MSG_ERROR: + theme_install_close(dialog_theme_install); + ro_warn_user(event->data.error, 0); + break; + + default: + break; + } + + return NSERROR_OK; +} + + +/** + * Fill in theme_install_descriptor from received theme data. + * + * \param source_data received data + * \param source_size size of data + * \return true if data is a correct theme, false on error + * + * If the data is a correct theme, theme_install_descriptor is filled in. + */ + +bool theme_install_read(const char *source_data, unsigned long source_size) +{ + const void *data = source_data; + + if (source_size < sizeof(struct theme_file_header)) + return false; + if (!ro_gui_theme_read_file_header(&theme_install_descriptor, + (struct theme_file_header *) data)) + return false; + if (source_size - sizeof(struct theme_file_header) != + theme_install_descriptor.compressed_size) + return false; + return true; +} + + +/** + * Install the downloaded theme. + * + * \param w the theme install window handle + */ + +bool ro_gui_theme_install_apply(wimp_w w) +{ + char theme_save[256]; + char *theme_file; + struct theme_descriptor *theme_install; + os_error *error; + char *fix; + const char *source_data; + unsigned long source_size; + + assert(theme_install_content); + + /* convert spaces to hard spaces */ + theme_file = strdup(theme_install_descriptor.name); + if (!theme_file) { + LOG("malloc failed"); + ro_warn_user("NoMemory", 0); + return false; + } + for (fix = theme_file; *fix != '\0'; fix++) + if (*fix == ' ') + *fix = 160; /* hard space */ + + /* simply overwrite previous theme versions */ + snprintf(theme_save, sizeof theme_save, "%s.%s", + nsoption_charp(theme_save), theme_file); + + theme_save[sizeof theme_save - 1] = '\0'; + + source_data = content_get_source_data(theme_install_content, + &source_size); + + error = xosfile_save_stamped(theme_save, 0xffd, + (byte *) source_data, + (byte *) source_data + source_size); + if (error) { + LOG("xosfile_save_stamped: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("ThemeInstallErr", 0); + free(theme_file); + return false; + } + + /* apply the new theme */ + ro_gui_theme_get_available(); + theme_install = ro_gui_theme_find(theme_file); + if (!theme_install || !ro_gui_theme_apply(theme_install)) { + ro_warn_user("ThemeApplyErr", 0); + } else { + nsoption_set_charp(theme, strdup(theme_install->leafname)); + } + free(theme_file); + ro_gui_save_options(); + return true; +} + + +/** + * Close the theme installer and free resources. + */ + +void theme_install_close(wimp_w w) +{ + if (theme_install_content) + hlcache_handle_release(theme_install_content); + + theme_install_content = NULL; +} diff --git a/frontends/riscos/tinct.h b/frontends/riscos/tinct.h new file mode 100644 index 000000000..e02dcdece --- /dev/null +++ b/frontends/riscos/tinct.h @@ -0,0 +1,154 @@ +/* + * Copyright 2005 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Complete details on using Tinct are available from http://www.tinct.net. + */ + +/** \file + * Tinct SWI numbers and flags for version 0.11 + */ + +#ifndef _NETSURF_RISCOS_TINCT_H_ +#define _NETSURF_RISCOS_TINCT_H_ + + +/** + * Plots an alpha-blended sprite at the specified coordinates. + * + * -> R2 Sprite pointer + * R3 X coordinate + * R4 Y coordinate + * R7 Flag word +*/ +#define Tinct_PlotAlpha 0x57240 + + +/** + * Plots a scaled alpha-blended sprite at the specified coordinates. + * + * -> R2 Sprite pointer + * R3 X coordinate + * R4 Y coordinate + * R5 Scaled sprite width + * R6 Scaled sprite height + * R7 Flag word + */ +#define Tinct_PlotScaledAlpha 0x57241 + + +/** + * Plots a sprite at the specified coordinates with a constant 0xff value for + * the alpha channel, ie without a mask. + * + * -> R2 Sprite pointer + * R3 X coordinate + * R4 Y coordinate + * R7 Flag word + */ +#define Tinct_Plot 0x57242 + +/** + * Plots a scaled sprite at the specified coordinates with a constant 0xff value + * for the alpha channel, ie without a mask. + * + * -> R2 Sprite pointer + * R3 X coordinate + * R4 Y coordinate + * R5 Scaled sprite width + * R6 Scaled sprite height + * R7 Flag word + */ +#define Tinct_PlotScaled 0x57243 + + +/** + * Converts a paletted sprite into its 32bpp equivalent. Sufficient memory must + * have previously been allocated for the sprite (44 + width * height * 4). + * As sprites with 16bpp or 32bpp do not have palettes, conversion cannot be + * performed on these variants. All sprites must be supplied with a full palette, + * eg 8bpp must have 256 palette entries. + * + * -> R2 Source sprite pointer + * R3 Destination sprite pointer + */ +#define Tinct_ConvertSprite 0x57244 + + +/** + * Returns the features available to the caller by specifying bits in the flag + * word. The features available are unique for each mode, although the current + * version of Tinct supports the same subset of features for all modes. + * + * -> R0 Feature to test for, or 0 for all features + * <- R0 Features available + */ +#define Tinct_AvailableFeatures 0x57245 + + +/** + * Compresses an image using a fast algorithm. Sufficient memory must have been + * previously allocated for the maximum possible compressed size. This value is + * equal to 28 + (width * height * 4) * 33 / 32. + * + * -> R0 Source sprite pointer + * R2 Output data buffer + * R3 Output bytes available + * R7 Flag word (currently 0) + * <- R0 Size of compressed data + */ +#define Tinct_Compress 0x57246 + + +/** + * Decompresses an image previously compressed. Sufficient memory must have been + * previously allocated for the decompressed data (44 + width * height * 4) where + * width and height are available at +0 and +4 of the compressed data respectively. + * + * -> R0 Input data buffer + * R2 Output data buffer + * R7 Flag word (currently 0) + * <- R0 Size of decompressed data + */ +#define Tinct_Decompress 0x57247 + + +/* Plotting flags +*/ +#define tinct_READ_SCREEN_BASE 0x01 /** <-- Use when hardware scrolling */ +#define tinct_BILINEAR_FILTER 0x02 /** <-- Perform bi-linear filtering */ +#define tinct_DITHER 0x04 /** <-- Perform dithering */ +#define tinct_ERROR_DIFFUSE 0x08 /** <-- Perform error diffusion */ +#define tinct_DITHER_INVERTED 0x0C /** <-- Perform dithering with inverted pattern */ +#define tinct_FILL_HORIZONTALLY 0x10 /** <-- Horizontally fill clipping region with image */ +#define tinct_FILL_VERTICALLY 0x20 /** <-- Vertically fill clipping region with image */ +#define tinct_FORCE_PALETTE_READ 0x40 /** <-- Use after a palette change when out of the desktop */ +#define tinct_USE_OS_SPRITE_OP 0x80 /** <-- Use when printing */ + +/* Compression flags +*/ +#define tinct_OPAQUE_IMAGE 0x01 /** <-- Image is opaque, compress further */ + +/* Shifts +*/ +#define tinct_BACKGROUND_SHIFT 0x08 + +/* Sprite mode +*/ +#define tinct_SPRITE_MODE (os_mode)0x301680b5 +#endif diff --git a/frontends/riscos/toolbar.c b/frontends/riscos/toolbar.c new file mode 100644 index 000000000..83751a7b4 --- /dev/null +++ b/frontends/riscos/toolbar.c @@ -0,0 +1,1788 @@ +/* + * Copyright 2004, 2005 Richard Wilson <info@tinct.net> + * Copyright 2010, 2011 Stephen Fryatt <stevef@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Window toolbars (implementation). + */ + +#include <alloca.h> +#include <assert.h> +#include <stdio.h> +#include <stdbool.h> +#include <string.h> +#include "oslib/dragasprite.h" +#include "oslib/os.h" +#include "oslib/osgbpb.h" +#include "oslib/osfile.h" +#include "oslib/osfind.h" +#include "oslib/osspriteop.h" +#include "oslib/wimpspriteop.h" +#include "oslib/squash.h" +#include "oslib/wimp.h" +#include "oslib/wimpextend.h" +#include "oslib/wimpspriteop.h" + +#include "utils/log.h" +#include "utils/nsoption.h" +#include "content/content.h" +#include "desktop/plotters.h" + +#include "riscos/cookies.h" +#include "riscos/dialog.h" +#include "riscos/global_history.h" +#include "riscos/gui.h" +#include "riscos/gui/button_bar.h" +#include "riscos/gui/throbber.h" +#include "riscos/gui/url_bar.h" +#include "riscos/hotlist.h" +#include "riscos/menus.h" +#include "riscos/save.h" +#include "riscos/theme.h" +#include "riscos/toolbar.h" +#include "riscos/treeview.h" +#include "riscos/url_complete.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" +#include "riscos/wimputils.h" +#include "riscos/window.h" + + +#define TOOLBAR_WIDGET_GUTTER 8 +#define TOOLBAR_DEFAULT_WIDTH 16384 + +/* Toolbar rows used to index into the arrays of row-specific data. + */ + +#define TOOLBAR_ROW_TOP 0 +#define TOOLBAR_ROW_DIV1 1 +#define TOOLBAR_ROW_EDIT 2 +#define TOOLBAR_MAX_ROWS 3 + +/* The toolbar data structure. + */ + +struct toolbar { + /** Bar details. */ + struct theme_descriptor *theme; + theme_style style; + toolbar_flags flags; + + int current_width, current_height; + int full_width, full_height; + int clip_width, clip_height; + + /** Toolbar and parent window handles. */ + wimp_w toolbar_handle; + wimp_w parent_handle; + + /** Row locations and sizes. */ + int row_y0[TOOLBAR_MAX_ROWS]; + int row_y1[TOOLBAR_MAX_ROWS]; + + /** Details for the button bar. */ + struct button_bar *buttons; + bool buttons_display; + os_coord buttons_size; + + /** Details for the URL bar. */ + struct url_bar *url; + bool url_display; + os_coord url_size; + + /** Details for the throbber. */ + struct throbber *throbber; + bool throbber_display; + bool throbber_right; + os_coord throbber_size; + + /** Client callback data. */ + const struct toolbar_callbacks *callbacks; + void *client_data; + + /** Details for the toolbar editor. */ + wimp_i editor_div1; + struct button_bar *editor; + os_coord editor_size; + + bool editing; + + /** Interactive help data. */ + + const char *help_prefix; + + /** The next bar in the toolbar list. */ + struct toolbar *next; +}; + + +/* Global variables for the toolbar module. + */ + +/** The list of defined toolbars. */ +static struct toolbar *ro_toolbar_bars = NULL; + +/** The Toolber Menu */ +wimp_menu *toolbar_menu; + + +/* A basic window definition for the toolbar and status bar. + */ + +static wimp_window ro_toolbar_window = { + {0, 0, 1, 1}, + 0, + 0, + wimp_TOP, + wimp_WINDOW_NEW_FORMAT | wimp_WINDOW_MOVEABLE | wimp_WINDOW_NO_BOUNDS | + wimp_WINDOW_FURNITURE_WINDOW | + wimp_WINDOW_IGNORE_XEXTENT | wimp_WINDOW_IGNORE_YEXTENT, + wimp_COLOUR_BLACK, + wimp_COLOUR_LIGHT_GREY, + wimp_COLOUR_LIGHT_GREY, + wimp_COLOUR_VERY_LIGHT_GREY, + wimp_COLOUR_DARK_GREY, + wimp_COLOUR_MID_LIGHT_GREY, + wimp_COLOUR_CREAM, + wimp_WINDOW_NEVER3D | 0x16u /* RISC OS 5.03+ */, + {0, 0, TOOLBAR_DEFAULT_WIDTH, 16384}, + 0, + wimp_BUTTON_DOUBLE_CLICK_DRAG << wimp_ICON_BUTTON_TYPE_SHIFT, + wimpspriteop_AREA, + 1, + 1, + {""}, + 0, + { } +}; + +static char ro_toolbar_null_string[] = ""; +static char ro_toolbar_line_validation[] = "R2"; + +/* + * Private function prototypes. + */ + +static void ro_toolbar_update_current_widgets(struct toolbar *toolbar); +static void ro_toolbar_refresh_widget_dimensions(struct toolbar *toolbar); +static void ro_toolbar_reformat_widgets(struct toolbar *toolbar); + +static void ro_toolbar_redraw(wimp_draw *redraw); +static bool ro_toolbar_click(wimp_pointer *pointer); +static bool ro_toolbar_keypress(wimp_key *key); +static bool ro_toolbar_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_pointer *pointer); +static void ro_toolbar_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_selection *selection, menu_action action); +static bool ro_toolbar_menu_select(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_selection *selection, menu_action action); +static const char *ro_toolbar_get_help_suffix(wimp_w w, wimp_i i, os_coord *pos, + wimp_mouse_state buttons); + +static void ro_toolbar_update_buttons(struct toolbar *toolbar); + + +/* This is an exported interface documented in toolbar.h */ + +void ro_toolbar_init(void) +{ + /* browser toolbar menu */ + static const struct ns_menu toolbar_definition = { + "Toolbar", { + { "Toolbars", NO_ACTION, 0 }, + { "Toolbars.ToolButtons", TOOLBAR_BUTTONS, 0 }, + { "Toolbars.ToolAddress", TOOLBAR_ADDRESS_BAR, 0 }, + { "Toolbars.ToolThrob", TOOLBAR_THROBBER, 0 }, + { "EditToolbar", TOOLBAR_EDIT, 0 }, + {NULL, 0, 0} + } + }; + toolbar_menu = ro_gui_menu_define_menu( + &toolbar_definition); +} + + +/* This is an exported interface documented in toolbar.h */ + +struct toolbar *ro_toolbar_create(struct theme_descriptor *descriptor, + wimp_w parent, theme_style style, toolbar_flags bar_flags, + const struct toolbar_callbacks *callbacks, void *client_data, + const char *help) +{ + struct toolbar *toolbar; + + /* Allocate memory for the bar and link it into the list of bars. */ + + toolbar = calloc(sizeof(struct toolbar), 1); + if (toolbar == NULL) { + LOG("No memory for malloc()"); + ro_warn_user("NoMemory", 0); + return NULL; + } + + toolbar->next = ro_toolbar_bars; + ro_toolbar_bars = toolbar; + + /* Store the supplied settings. */ + + toolbar->flags = bar_flags; + toolbar->theme = descriptor; + toolbar->style = style; + toolbar->parent_handle = parent; + toolbar->callbacks = callbacks; + toolbar->client_data = client_data; + + /* Set up the internal widgets: initially, there are none. */ + + toolbar->buttons = NULL; + toolbar->buttons_display = false; + + toolbar->url = NULL; + toolbar->url_display = false; + + toolbar->throbber = NULL; + toolbar->throbber_display = false; + + /* Set up the bar editor. */ + + toolbar->editor = NULL; + toolbar->editor_div1 = -1; + + toolbar->editing = false; + + toolbar->help_prefix = help; + + return toolbar; +} + + +/* This is an exported interface documented in toolbar.h */ + +bool ro_toolbar_add_buttons(struct toolbar *toolbar, + const struct button_bar_buttons buttons[], char *button_order) +{ + if (toolbar == NULL) + return false; + + if (toolbar->buttons != NULL) + return false; + + toolbar->buttons = ro_gui_button_bar_create(toolbar->theme, buttons); + if (toolbar->buttons != NULL) { + toolbar->buttons_display = true; + ro_gui_button_bar_arrange_buttons(toolbar->buttons, + button_order); + } + + toolbar->editor = ro_gui_button_bar_create(toolbar->theme, buttons); + if (toolbar->editor != NULL) + ro_gui_button_bar_hide(toolbar->editor, !toolbar->editing); + + if (toolbar->buttons != NULL && toolbar->editor != NULL) + if (!ro_gui_button_bar_link_editor(toolbar->buttons, + toolbar->editor, + (void (*)(void *)) + ro_toolbar_update_current_widgets, + toolbar)) + return false; + + return (toolbar->buttons == NULL || toolbar->editor == NULL) ? + false : true; +} + + +/* This is an exported interface documented in toolbar.h */ + +bool ro_toolbar_add_throbber(struct toolbar *toolbar) +{ + if (toolbar == NULL) + return false; + + if (toolbar->throbber != NULL) + return false; + + toolbar->throbber = ro_gui_throbber_create(toolbar->theme); + + if (toolbar->throbber != NULL) + toolbar->throbber_display = true; + + return (toolbar->throbber == NULL) ? false : true; +} + + +/* This is an exported interface documented in toolbar.h */ + +bool ro_toolbar_add_url(struct toolbar *toolbar) +{ + if (toolbar == NULL) + return false; + + if (toolbar->url != NULL) + return false; + + toolbar->url = ro_gui_url_bar_create(toolbar->theme); + + if (toolbar->url != NULL) + toolbar->url_display = true; + + return (toolbar->url == NULL) ? false : true; +} + + +/* This is an exported interface documented in toolbar.h */ + +bool ro_toolbar_rebuild(struct toolbar *toolbar) +{ + os_error *error; + wimp_icon_create icon; + wimp_w old_window = NULL; + + if (toolbar == NULL) + return false; + + /* Start to set up the toolbar window. */ + + ro_toolbar_window.sprite_area = + ro_gui_theme_get_sprites(toolbar->theme); + ro_toolbar_window.work_bg = + ro_gui_theme_get_style_element(toolbar->theme, + toolbar->style, THEME_ELEMENT_BACKGROUND); + + /* Delete any existing toolbar window... */ + + if (toolbar->toolbar_handle != NULL) { + old_window = toolbar->toolbar_handle; + error = xwimp_delete_window(toolbar->toolbar_handle); + if (error) + LOG("xwimp_delete_window: 0x%x: %s", error->errnum, error->errmess); + toolbar->toolbar_handle = NULL; + } + + /* ...and create a new window. */ + + error = xwimp_create_window(&ro_toolbar_window, + &toolbar->toolbar_handle); + if (error) { + LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + + /* Set up the toolbar's event handlers. Only set the user activity- + * related callbacks if the bar isn't for display purposes. If the + * toolbar is being recreated, simply transfer the handlers across + * from the old, now-deleted window. + */ + + if (old_window == NULL) { + ro_gui_wimp_event_register_redraw_window( + toolbar->toolbar_handle, ro_toolbar_redraw); + ro_gui_wimp_event_set_user_data(toolbar->toolbar_handle, + toolbar); + + if (!(toolbar->flags & TOOLBAR_FLAGS_DISPLAY)) { + ro_gui_wimp_event_register_mouse_click( + toolbar->toolbar_handle, + ro_toolbar_click); + ro_gui_wimp_event_register_keypress( + toolbar->toolbar_handle, + ro_toolbar_keypress); + ro_gui_wimp_event_register_menu_prepare( + toolbar->toolbar_handle, + ro_toolbar_menu_prepare); + ro_gui_wimp_event_register_menu_warning( + toolbar->toolbar_handle, + ro_toolbar_menu_warning); + ro_gui_wimp_event_register_menu_selection( + toolbar->toolbar_handle, + ro_toolbar_menu_select); + ro_gui_wimp_event_register_menu(toolbar->toolbar_handle, + toolbar_menu, true, false); + ro_gui_wimp_event_register_help_suffix( + toolbar->toolbar_handle, + ro_toolbar_get_help_suffix); + } + } else { + ro_gui_wimp_event_transfer(old_window, toolbar->toolbar_handle); + } + + /* The help prefix changes from edit to non-edit more. */ + + ro_gui_wimp_event_set_help_prefix(toolbar->toolbar_handle, + (toolbar->editing) ? + "HelpEditToolbar" : toolbar->help_prefix); + + /* Place the widgets into the new bar, using the new theme. + * + * \TODO -- If any widgets fail to rebuild, then we currently just + * carry on without them. Not sure if the whole bar + * rebuild should fail here? + */ + + if (toolbar->throbber != NULL) { + if (!ro_gui_throbber_rebuild(toolbar->throbber, toolbar->theme, + toolbar->style, toolbar->toolbar_handle, + toolbar->editing)) { + ro_gui_throbber_destroy(toolbar->throbber); + toolbar->throbber = NULL; + } + + ro_gui_theme_get_throbber_data(toolbar->theme, NULL, NULL, NULL, + &toolbar->throbber_right, NULL); + } + + if (toolbar->buttons != NULL) { + if (!ro_gui_button_bar_rebuild(toolbar->buttons, toolbar->theme, + toolbar->style, toolbar->toolbar_handle, + toolbar->editing)) { + ro_gui_button_bar_destroy(toolbar->buttons); + toolbar->buttons = NULL; + } + } + + if (toolbar->editor != NULL) { + if (!ro_gui_button_bar_rebuild(toolbar->editor, toolbar->theme, + toolbar->style, toolbar->toolbar_handle, + toolbar->editing)) { + ro_gui_button_bar_destroy(toolbar->editor); + toolbar->editor = NULL; + } + } + + if (toolbar->url != NULL) { + if (!ro_gui_url_bar_rebuild(toolbar->url, toolbar->theme, + toolbar->style, toolbar->toolbar_handle, + toolbar->flags & TOOLBAR_FLAGS_DISPLAY, + toolbar->editing)) { + ro_gui_url_bar_destroy(toolbar->url); + toolbar->url = NULL; + } + } + + /* If this is an editor, add in a divider icon and the editor + * button bar. + */ + + if (toolbar->editing) { + icon.w = toolbar->toolbar_handle; + icon.icon.flags = wimp_ICON_TEXT | wimp_ICON_INDIRECTED | + wimp_ICON_VCENTRED | wimp_ICON_BORDER | + (wimp_COLOUR_BLACK << + wimp_ICON_FG_COLOUR_SHIFT) | + (wimp_COLOUR_VERY_LIGHT_GREY << + wimp_ICON_BG_COLOUR_SHIFT); + icon.icon.extent.x0 = 0; + icon.icon.extent.x1 = 0; + icon.icon.extent.y1 = 0; + icon.icon.extent.y0 = 0; + icon.icon.data.indirected_text.text = ro_toolbar_null_string; + icon.icon.data.indirected_text.validation = + ro_toolbar_line_validation; + icon.icon.data.indirected_text.size = 1; + error = xwimp_create_icon(&icon, &toolbar->editor_div1); + if (error) { + LOG("xwimp_create_icon: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + toolbar->editor_div1 = -1; + } + } + + /* Establish the required dimensions to fit the widgets, then + * reflow the bar contents. + */ + + ro_toolbar_refresh_widget_dimensions(toolbar); + + ro_toolbar_process(toolbar, -1, true); + + if (toolbar->parent_handle != NULL) + ro_toolbar_attach(toolbar, toolbar->parent_handle); + + ro_toolbar_update_buttons(toolbar); + + return true; +} + + +/* This is an exported interface documented in toolbar.h */ + +bool ro_toolbar_attach(struct toolbar *toolbar, wimp_w parent) +{ + wimp_outline outline; + wimp_window_state state; + os_error *error; + + if (toolbar == NULL || toolbar->toolbar_handle == NULL) + return false; + + toolbar->parent_handle = parent; + + /* Only try to attach the toolbar if there's any of it visible to + * matter. + */ + + if (toolbar->current_height > 0) { + outline.w = parent; + xwimp_get_window_outline(&outline); + state.w = parent; + xwimp_get_window_state(&state); + state.w = toolbar->toolbar_handle; + state.visible.x1 = outline.outline.x1 - 2; + state.visible.y0 = state.visible.y1 + 2 - + toolbar->current_height; + state.xscroll = 0; + state.yscroll = 0; + error = xwimp_open_window_nested(PTR_WIMP_OPEN(&state), parent, + wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT + << wimp_CHILD_XORIGIN_SHIFT | + wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT + << wimp_CHILD_YORIGIN_SHIFT | + wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT + << wimp_CHILD_LS_EDGE_SHIFT | + wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT + << wimp_CHILD_BS_EDGE_SHIFT | + wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT + << wimp_CHILD_RS_EDGE_SHIFT | + wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT + << wimp_CHILD_TS_EDGE_SHIFT); + if (error) { + LOG("xwimp_open_window_nested: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + + return true; + } + + error = xwimp_close_window(toolbar->toolbar_handle); + if (error) { + LOG("xwimp_close_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + return true; +} + + +/* This is an exported interface documented in toolbar.h */ + +bool ro_toolbar_process(struct toolbar *toolbar, int width, bool reformat) +{ + os_error *error; + wimp_outline outline; + wimp_window_state state; + os_box extent; + int old_height, old_width; + + if (!toolbar) + return false; + + old_height = toolbar->current_height; + old_width = toolbar->current_width; + + /* Measure the parent window width if the caller has asked us to + * calculate the clip width ourselves. Otherwise, if a clip width + * has been specified, set the clip to that. + */ + + if ((toolbar->parent_handle != NULL) && (width == -1)) { + outline.w = toolbar->parent_handle; + error = xwimp_get_window_outline(&outline); + if (error) { + LOG("xwimp_get_window_outline: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + + toolbar->clip_width = outline.outline.x1 - + outline.outline.x0 - 2; + toolbar->current_width = toolbar->clip_width; + } else if (width != -1) { + toolbar->clip_width = width; + toolbar->current_width = toolbar->clip_width; + } + + /* Find the parent visible height to clip our toolbar height to + */ + + if (toolbar->parent_handle != NULL) { + state.w = toolbar->parent_handle; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + + toolbar->clip_height = state.visible.y1 - state.visible.y0 + 2; + + /* We can't obscure the height of the scroll bar as we + * lose the resize icon if we do. + */ + + if (toolbar->clip_height >= toolbar->full_height) + toolbar->current_height = toolbar->full_height; + else + toolbar->current_height = toolbar->clip_height; + + /* Resize the work area extent and update our position. */ + + if (old_height != toolbar->current_height) { + extent.x0 = 0; + extent.y0 = 0; + extent.x1 = TOOLBAR_DEFAULT_WIDTH; + extent.y1 = toolbar->current_height - 2; + error = xwimp_set_extent(toolbar->toolbar_handle, + &extent); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + + ro_toolbar_attach(toolbar, toolbar->parent_handle); + } + } else { + toolbar->clip_height = toolbar->full_height; + toolbar->current_height = toolbar->full_height; + } + + /* Reflow the widgets into the toolbar if the dimensions have + * changed or we have been asked to anyway. */ + + if (toolbar->current_width != old_width || reformat) + ro_toolbar_reformat_widgets(toolbar); + + return true; +} + + +/** + * Update the widgets currently on view in a toolbar. This can be used + * generally, but is primarily offered to widgets as a way for them + * to force an update. + * + * \param *toolbar The toolbar to update. + */ + +void ro_toolbar_update_current_widgets(struct toolbar *toolbar) +{ + int old_height; + + if (toolbar == NULL) + return; + + old_height = toolbar->full_height; + + ro_toolbar_refresh_widget_dimensions(toolbar); + ro_toolbar_reformat_widgets(toolbar); + + /* If the toolbar height has changed, we need to tell the client. */ + + if (toolbar->full_height != old_height) + ro_toolbar_refresh(toolbar); +} + + +/** + * Get the minimum dimenstions required by the toolbar widgets after + * these have changed. The minimum dimensions are assumed not to change + * unless we change theme (ie. we rebuild the bar) or we knowingly + * alter a widget (eg. we add or remove button-bar buttons). + * + * + * \param *toolbar The toolbar to refresh. + */ + +void ro_toolbar_refresh_widget_dimensions(struct toolbar *toolbar) +{ + int width, height; + int row_width, row_height; + + if (toolbar == NULL) + return; + + /* Process the toolbar editor and any associated divider rows. + */ + + if (toolbar->editor != NULL && toolbar->editing) { + width = 0; + height = 0; + ro_gui_button_bar_get_dims(toolbar->editor, &width, &height); + + toolbar->editor_size.x = width; + toolbar->editor_size.y = height; + + toolbar->row_y0[TOOLBAR_ROW_EDIT] = TOOLBAR_WIDGET_GUTTER; + toolbar->row_y1[TOOLBAR_ROW_EDIT] = TOOLBAR_WIDGET_GUTTER + + height; + + toolbar->row_y0[TOOLBAR_ROW_DIV1] = TOOLBAR_WIDGET_GUTTER + + toolbar->row_y1[TOOLBAR_ROW_EDIT]; + toolbar->row_y1[TOOLBAR_ROW_DIV1] = 8 + + toolbar->row_y0[TOOLBAR_ROW_DIV1]; + } else { + toolbar->editor_size.x = 0; + toolbar->editor_size.y = 0; + + toolbar->row_y0[TOOLBAR_ROW_EDIT] = 0; + toolbar->row_y1[TOOLBAR_ROW_EDIT] = 0; + toolbar->row_y0[TOOLBAR_ROW_DIV1] = 0; + toolbar->row_y1[TOOLBAR_ROW_DIV1] = 0; + } + + /* Process the top row icons. */ + + row_width = 0; + row_height = 0; + + /* If the editor is active, any button bar if forced into view. */ + + if (toolbar->buttons != NULL && + (toolbar->buttons_display || toolbar->editing)) { + width = 0; + height = 0; + ro_gui_button_bar_get_dims(toolbar->buttons, &width, &height); + + row_width += width; + toolbar->buttons_size.x = width; + toolbar->buttons_size.y = height; + + if (height > row_height) + row_height = height; + } else { + toolbar->buttons_size.x = 0; + toolbar->buttons_size.y = 0; + } + + if (toolbar->url != NULL && toolbar->url_display) { + width = 0; + height = 0; + ro_gui_url_bar_get_dims(toolbar->url, &width, &height); + + if (row_width > 0) + row_width += TOOLBAR_WIDGET_GUTTER; + row_width += width; + + toolbar->url_size.x = width; + toolbar->url_size.y = height; + + if (height > row_height) + row_height = height; + } else { + toolbar->url_size.x = 0; + toolbar->url_size.y = 0; + } + + if (toolbar->throbber != NULL && toolbar->throbber_display) { + width = 0; + height = 0; + ro_gui_throbber_get_dims(toolbar->throbber, &width, &height); + + if (row_width > 0) + row_width += TOOLBAR_WIDGET_GUTTER; + row_width += width; + + toolbar->throbber_size.x = width; + toolbar->throbber_size.y = height; + + if (height > row_height) + row_height = height; + } else { + toolbar->throbber_size.x = 0; + toolbar->throbber_size.y = 0; + } + + if (row_height > 0) { + toolbar->row_y0[TOOLBAR_ROW_TOP] = TOOLBAR_WIDGET_GUTTER + + toolbar->row_y1[TOOLBAR_ROW_DIV1]; + toolbar->row_y1[TOOLBAR_ROW_TOP] = row_height + + toolbar->row_y0[TOOLBAR_ROW_TOP]; + } else { + toolbar->row_y0[TOOLBAR_ROW_TOP] = 0; + toolbar->row_y1[TOOLBAR_ROW_TOP] = 0; + } + + /* Establish the full dimensions of the bar. + * + * \TODO -- This currently assumes an "all or nothing" approach to + * the editor bar, and will need reworking once we have to + * worry about tab bars. + */ + + if (toolbar->row_y1[TOOLBAR_ROW_TOP] > 0) { + toolbar->full_height = toolbar->row_y1[TOOLBAR_ROW_TOP] + + TOOLBAR_WIDGET_GUTTER; + } else { + toolbar->full_height = 0; + } + toolbar->full_width = 2 * TOOLBAR_WIDGET_GUTTER + + ((row_width > toolbar->editor_size.x) ? + row_width : toolbar->editor_size.x); +} + + +/** + * Reformat (reflow) the widgets into the toolbar, based on the toolbar size + * and the previously calculated widget dimensions. + * + * \param *toolbar The toolbar to reformat. + */ + +void ro_toolbar_reformat_widgets(struct toolbar *toolbar) +{ + int left_margin, right_margin; + + left_margin = TOOLBAR_WIDGET_GUTTER; + right_margin = toolbar->clip_width - TOOLBAR_WIDGET_GUTTER; + + /* Flow the toolbar editor row, which will be a fixed with and + * may alter the right margin. + */ + + if (toolbar->editor != NULL && toolbar->editing) { + if (right_margin < left_margin + toolbar->editor_size.x) + right_margin = left_margin + toolbar->editor_size.x; + + ro_gui_button_bar_set_extent(toolbar->editor, + left_margin, + toolbar->row_y0[TOOLBAR_ROW_EDIT], + left_margin + toolbar->editor_size.x, + toolbar->row_y1[TOOLBAR_ROW_EDIT]); + + if (toolbar->editor_div1 != -1) + xwimp_resize_icon(toolbar->toolbar_handle, + toolbar->editor_div1, -8, + toolbar->row_y0[TOOLBAR_ROW_DIV1], + toolbar->clip_width + 8, + toolbar->row_y1[TOOLBAR_ROW_DIV1]); + } + + /* Flow the top row. */ + + if (toolbar->throbber != NULL && toolbar->throbber_display) { + if (toolbar->throbber_right) { + right_margin -= (toolbar->throbber_size.x + + TOOLBAR_WIDGET_GUTTER); + } else { + ro_gui_throbber_set_extent(toolbar->throbber, + left_margin, + toolbar->row_y0[TOOLBAR_ROW_TOP], + left_margin + toolbar->throbber_size.x, + toolbar->row_y1[TOOLBAR_ROW_TOP]); + left_margin += (toolbar->throbber_size.x + + TOOLBAR_WIDGET_GUTTER); + } + } + + if (toolbar->buttons != NULL && + (toolbar->buttons_display || toolbar->editing)) { + if (right_margin < left_margin + toolbar->buttons_size.x) + right_margin = left_margin + toolbar->buttons_size.x; + + ro_gui_button_bar_set_extent(toolbar->buttons, + left_margin, + toolbar->row_y0[TOOLBAR_ROW_TOP], + left_margin + toolbar->buttons_size.x, + toolbar->row_y1[TOOLBAR_ROW_TOP]); + left_margin += (toolbar->buttons_size.x + + TOOLBAR_WIDGET_GUTTER); + } + + if (toolbar->url != NULL && toolbar->url_display) { + if (right_margin < left_margin + toolbar->url_size.x) + right_margin = left_margin + toolbar->url_size.x; + + ro_gui_url_bar_set_extent(toolbar->url, + left_margin, + toolbar->row_y0[TOOLBAR_ROW_TOP], + right_margin, + toolbar->row_y1[TOOLBAR_ROW_TOP]); + + left_margin = right_margin + TOOLBAR_WIDGET_GUTTER; + } + + if (toolbar->throbber != NULL && toolbar->throbber_display && + toolbar->throbber_right) { + left_margin = right_margin + TOOLBAR_WIDGET_GUTTER; + ro_gui_throbber_set_extent(toolbar->throbber, + left_margin, + toolbar->row_y0[TOOLBAR_ROW_TOP], + left_margin + toolbar->throbber_size.x, + toolbar->row_y1[TOOLBAR_ROW_TOP]); + } + +} + + +/* This is an exported interface documented in toolbar.h */ + +void ro_toolbar_destroy(struct toolbar *toolbar) +{ + struct toolbar *bar; + + if (toolbar == NULL) + return; + + LOG("Destroying toolbar 0x%x", (unsigned int)toolbar); + + /* Destroy the widgets. */ + + if (toolbar->buttons != NULL) + ro_gui_button_bar_destroy(toolbar->buttons); + + if (toolbar->editor != NULL) + ro_gui_button_bar_destroy(toolbar->editor); + + if (toolbar->url != NULL) + ro_gui_url_bar_destroy(toolbar->url); + + if (toolbar->throbber != NULL) + ro_gui_throbber_destroy(toolbar->throbber); + + /* Delete the toolbar window. */ + + if (toolbar->toolbar_handle != NULL) { + xwimp_delete_window(toolbar->toolbar_handle); + ro_gui_wimp_event_finalise(toolbar->toolbar_handle); + } + + /* Remove the bar from the list and free the memory. + */ + + if (ro_toolbar_bars == toolbar) { + ro_toolbar_bars = toolbar->next; + } else { + for (bar = ro_toolbar_bars; bar != NULL && bar->next != toolbar; + bar = bar->next); + + if (bar->next == toolbar) + bar->next = toolbar->next; + } + + free(toolbar); + +} + + +/** + * Handle redraw request events for a toolbar workarea. + * + * \param *redraw The redraw block for the event. + */ + +void ro_toolbar_redraw(wimp_draw *redraw) +{ + struct toolbar *toolbar; + osbool more; + os_error *error; + + toolbar = (struct toolbar *)ro_gui_wimp_event_get_user_data(redraw->w); + + assert(toolbar != NULL); + + error = xwimp_redraw_window(redraw, &more); + if (error) { + LOG("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + while (more) { + ro_plot_origin_x = redraw->box.x0 - redraw->xscroll; + ro_plot_origin_y = redraw->box.y1 - redraw->yscroll; + + if (toolbar->buttons != NULL && toolbar->buttons_display) + ro_gui_button_bar_redraw(toolbar->buttons, redraw); + + if (toolbar->editor != NULL && toolbar->editing) + ro_gui_button_bar_redraw(toolbar->editor, redraw); + + if (toolbar->url != NULL && toolbar->url_display) + ro_gui_url_bar_redraw(toolbar->url, redraw); + + error = xwimp_get_rectangle(redraw, &more); + if (error) { + LOG("xwimp_get_rectangle: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + } +} + + +/** + * Process clicks on a toolbar, passing details on to clients where necessary. + * + * \param *pointer The wimp mouse click event. + * \return True if the event was handled; else false. + */ + +bool ro_toolbar_click(wimp_pointer *pointer) +{ + struct toolbar *toolbar; + union toolbar_action action; + wimp_window_state state; + os_error *error; + + toolbar = (struct toolbar *) + ro_gui_wimp_event_get_user_data(pointer->w); + + if (toolbar == NULL) + return false; + + assert(pointer->w == toolbar->toolbar_handle); + + state.w = toolbar->toolbar_handle; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + + /* If the click wasn't in the URL Bar's text field, then it will + * need to close any URL Complete window that is open. + * + * \TODO -- This should really move into the URL Bar module, as + * URL Complete is really an extension to that. + */ + + if (toolbar->url != NULL && toolbar->url_display && + !ro_gui_url_bar_test_for_text_field_click(toolbar->url, + pointer)) + ro_gui_url_complete_close(); + + /* Pass the click around the toolbar widgets. */ + + if (toolbar->buttons != NULL && + (toolbar->buttons_display || toolbar->editing) && + ro_gui_button_bar_click(toolbar->buttons, pointer, + &state, &action.button)) { + if (action.button != TOOLBAR_BUTTON_NONE && + !toolbar->editing && + toolbar->callbacks != NULL && + toolbar->callbacks->user_action != NULL) + toolbar->callbacks->user_action(toolbar->client_data, + TOOLBAR_ACTION_BUTTON, action); + return true; + } + + if (toolbar->url != NULL && toolbar->url_display && + ro_gui_url_bar_click(toolbar->url, pointer, + &state, &action.url)) { + if (action.url != TOOLBAR_URL_NONE && + !toolbar->editing && + toolbar->callbacks != NULL && + toolbar->callbacks->user_action != NULL) + toolbar->callbacks->user_action(toolbar->client_data, + TOOLBAR_ACTION_URL, action); + return true; + } + + if (toolbar->editor != NULL && toolbar->editing && + ro_gui_button_bar_click(toolbar->editor, pointer, + &state, &action.button)) { + return true; + } + + /* Nothing else has handled this, so try passing it to the + * URL Complete module. + * + * \TODO -- This should really move into the URL Bar module, as + * URL Complete is really an extension to that. + */ + + if (toolbar->url != NULL && toolbar->url_display && + ro_gui_url_bar_test_for_text_field_click(toolbar->url, + pointer)) { + ro_gui_url_complete_start(toolbar); + return true; + } + + return false; +} + + +/** + * Process keypresses in a toolbar, passing details on to clients where + * necessary. + * + * \param *key The wimp key press event. + * \return True if the event was handled; else false. + */ + +bool ro_toolbar_keypress(wimp_key *key) +{ + struct toolbar *toolbar; + + toolbar = (struct toolbar *) ro_gui_wimp_event_get_user_data(key->w); + + if (toolbar == NULL) + return false; + + /* Pass the keypress on to the client and stop if they handle it. */ + + if (toolbar->callbacks->key_press != NULL && + toolbar->callbacks->key_press(toolbar->client_data, key)) + return true; + + /* If the caret is in the URL bar, ask the URL Complete module if it + * wants to handle the keypress. + * + * \TODO -- This should really move into the URL Bar module, as + * URL Complete is really an extension to that. + */ + + if (toolbar->url != NULL && toolbar->url_display && + ro_gui_url_bar_test_for_text_field_keypress( + toolbar->url, key) && + ro_gui_url_complete_keypress(toolbar, key->c)) + return true; + + return false; +} + + +/** + * Prepare the toolbar menu for (re-)opening + * + * \param w The window owning the menu. + * \param i The icon owning the menu. + * \param *menu The menu about to be opened. + * \param *pointer Pointer to the relevant wimp event block, or + * NULL for an Adjust click. + * \return true if the event was handled; else false. + */ + +bool ro_toolbar_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_pointer *pointer) +{ + struct toolbar *toolbar; + + toolbar = (struct toolbar *) ro_gui_wimp_event_get_user_data(w); + + if (toolbar == NULL) + return false; + + /* Pass the event on to potentially interested widgets. */ + + if (toolbar->url != NULL && ro_gui_url_bar_menu_prepare(toolbar->url, + i, menu, pointer)) + return true; + + /* Try to process the event as a toolbar menu. */ + + if (menu != toolbar_menu) + return false; + + /* Shade menu entries according to the state of the window and object + * under the pointer. + */ + + /* Toolbar (Sub)Menu */ + + ro_gui_menu_set_entry_shaded(menu, TOOLBAR_EDIT, + ro_toolbar_menu_edit_shade(toolbar)); + ro_gui_menu_set_entry_ticked(menu, TOOLBAR_EDIT, + ro_toolbar_menu_edit_tick(toolbar)); + + ro_gui_menu_set_entry_shaded(menu, TOOLBAR_BUTTONS, + ro_toolbar_menu_option_shade(toolbar) || + toolbar->buttons == NULL); + ro_gui_menu_set_entry_ticked(menu, TOOLBAR_BUTTONS, + ro_toolbar_menu_buttons_tick(toolbar) && + toolbar->buttons != NULL); + + ro_gui_menu_set_entry_shaded(menu, TOOLBAR_ADDRESS_BAR, + ro_toolbar_menu_edit_shade(toolbar) || + toolbar->url == NULL); + ro_gui_menu_set_entry_ticked(menu, TOOLBAR_ADDRESS_BAR, + ro_toolbar_menu_url_tick(toolbar) && + toolbar->url != NULL); + + ro_gui_menu_set_entry_shaded(menu, TOOLBAR_THROBBER, + ro_toolbar_menu_edit_shade(toolbar) || + toolbar->throbber == NULL); + ro_gui_menu_set_entry_ticked(menu, TOOLBAR_THROBBER, + ro_toolbar_menu_throbber_tick(toolbar) && + toolbar->throbber != NULL); + + return true; +} + + +/** + * Handle submenu warnings for the toolbar menu + * + * \param w The window owning the menu. + * \param i The icon owning the menu. + * \param *menu The menu to which the warning applies. + * \param *selection The wimp menu selection data. + * \param action The selected menu action. + */ + +void ro_toolbar_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_selection *selection, menu_action action) +{ + /* Do nothing */ +} + + +/** + * Handle selections from the toolbar menu + * + * \param w The window owning the menu. + * \param i The icon owning the menu. + * \param *menu The menu from which the selection was made. + * \param *selection The wimp menu selection data. + * \param action The selected menu action. + * \return true if action accepted; else false. + */ + +bool ro_toolbar_menu_select(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_selection *selection, menu_action action) +{ + struct toolbar *toolbar; + + toolbar = (struct toolbar *) ro_gui_wimp_event_get_user_data(w); + + if (toolbar == NULL) + return false; + + /* Pass the event on to potentially interested widgets. */ + + if (toolbar->url != NULL && ro_gui_url_bar_menu_select(toolbar->url, + i, menu, selection, action)) + return true; + + /* Try to process the event as a toolbar menu. */ + + if (menu != toolbar_menu) + return false; + + switch (action) { + case TOOLBAR_BUTTONS: + ro_toolbar_set_display_buttons(toolbar, + !ro_toolbar_get_display_buttons(toolbar)); + break; + case TOOLBAR_ADDRESS_BAR: + ro_toolbar_set_display_url(toolbar, + !ro_toolbar_get_display_url(toolbar)); + if (ro_toolbar_get_display_url(toolbar)) + ro_toolbar_take_caret(toolbar); + break; + case TOOLBAR_THROBBER: + ro_toolbar_set_display_throbber(toolbar, + !ro_toolbar_get_display_throbber(toolbar)); + break; + case TOOLBAR_EDIT: + ro_toolbar_toggle_edit(toolbar); + break; + default: + return false; + } + + return true; +} + + +/** + * Translate the contents of a message_HELP_REQUEST into a suffix for a + * NetSurf message token. The help system will then add this to whatever + * prefix the current toolbar has registered with WimpEvent. + * + * \param w The window handle under the mouse. + * \param i The icon handle under the mouse. + * \param *pos The mouse position. + * \param buttons The mouse button state. + * \return The required help token suffix. + */ + +const char *ro_toolbar_get_help_suffix(wimp_w w, wimp_i i, os_coord *pos, + wimp_mouse_state buttons) +{ + struct toolbar *toolbar; + wimp_window_state state; + os_error *error; + const char *suffix; + + toolbar = (struct toolbar *) ro_gui_wimp_event_get_user_data(w); + + if (toolbar == NULL || toolbar->toolbar_handle != w) + return NULL; + + state.w = toolbar->toolbar_handle; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return NULL; + } + + /* Pass the help request around the toolbar widgets. */ + + if (toolbar->throbber != NULL && toolbar->throbber_display && + ro_gui_throbber_help_suffix(toolbar->throbber, i, + pos, &state, buttons, &suffix)) + return suffix; + + if (toolbar->url != NULL && toolbar->url_display && + ro_gui_url_bar_help_suffix(toolbar->url, i, + pos, &state, buttons, &suffix)) + return suffix; + + if (toolbar->buttons != NULL && toolbar->buttons_display && + ro_gui_button_bar_help_suffix(toolbar->buttons, i, + pos, &state, buttons, &suffix)) + return suffix; + + return ""; +} + + +/* This is an exported interface documented in toolbar.h */ + +void ro_toolbar_update_client_data(struct toolbar *toolbar, void *client_data) +{ + if (toolbar != NULL) + toolbar->client_data = client_data; +} + + +/* This is an exported interface documented in toolbar.h */ + +void ro_toolbar_update_all_buttons(void) +{ + struct toolbar *bar; + + bar = ro_toolbar_bars; + while (bar != NULL) { + ro_toolbar_update_buttons(bar); + + bar = bar->next; + } +} + + +/** + * Update the state of a toolbar's buttons. + * + * \param toolbar the toolbar to update + */ + +void ro_toolbar_update_buttons(struct toolbar *toolbar) +{ + assert(toolbar != NULL); + + if (toolbar->callbacks != NULL && + toolbar->callbacks->update_buttons != NULL) + toolbar->callbacks->update_buttons(toolbar->client_data); +} + +/* This is an exported interface documented in toolbar.h */ + +void ro_toolbar_refresh(struct toolbar *toolbar) +{ + assert(toolbar != NULL); + + ro_toolbar_process(toolbar, -1, true); + if (toolbar->callbacks != NULL && + toolbar->callbacks->change_size != NULL) + toolbar->callbacks->change_size(toolbar->client_data); + + if (toolbar->toolbar_handle != NULL) + xwimp_force_redraw(toolbar->toolbar_handle, 0, 0, + toolbar->current_width, + toolbar->current_height); +} + + +/* This is an exported interface documented in toolbar.h */ + +void ro_toolbar_theme_update(void) +{ + struct toolbar *bar, *next; + bool ok; + + bar = ro_toolbar_bars; + while (bar != NULL) { + /* Take the next bar address now, as *bar may become invalid + * during the update process (if an update fails and + * ro_toolbar_destroy() is called) and we don't want to lose + * the link to the rest of the chain. + */ + + next = bar->next; + + /* Only process the bar if the theme is set to the default. + * Otherwise, it's up to the owner to do whatever they need + * to do for themselves. + */ + + if (bar->theme == NULL) { + ok = ro_toolbar_rebuild(bar); + + if (!ok) + ro_toolbar_destroy(bar); + } else { + ok = true; + } + + if (bar->callbacks != NULL && + bar->callbacks->theme_update != NULL) + bar->callbacks->theme_update(bar->client_data, ok); + + bar = next; + } +} + + +/* This is an exported interface documented in toolbar.h */ + +struct toolbar *ro_toolbar_parent_window_lookup(wimp_w w) +{ + struct toolbar *toolbar; + + toolbar = ro_toolbar_bars; + while (toolbar != NULL && toolbar->parent_handle != w) + toolbar = toolbar->next; + + return toolbar; +} + + +/* This is an exported interface documented in toolbar.h */ + +struct toolbar *ro_toolbar_window_lookup(wimp_w w) +{ + struct toolbar *toolbar; + + toolbar = ro_toolbar_bars; + while (toolbar != NULL && toolbar->toolbar_handle != w) + toolbar = toolbar->next; + + return toolbar; +} + + +/* This is an exported interface documented in toolbar.h */ + +wimp_w ro_toolbar_get_parent_window(struct toolbar *toolbar) +{ + return (toolbar != NULL) ? toolbar->parent_handle : 0; +} + + +/* This is an exported interface documented in toolbar.h */ + +wimp_w ro_toolbar_get_window(struct toolbar *toolbar) +{ + return (toolbar != NULL) ? toolbar->toolbar_handle : 0; +} + + +/* This is an exported interface documented in toolbar.h */ + +int ro_toolbar_height(struct toolbar *toolbar) +{ + return (toolbar == NULL) ? 0 : toolbar->current_height; +} + + +/* This is an exported interface documented in toolbar.h */ + +int ro_toolbar_full_height(struct toolbar *toolbar) +{ + return (toolbar == NULL) ? 0 : toolbar->full_height; +} + + +/* This is an exported interface documented in toolbar.h */ + +void ro_toolbar_start_throbbing(struct toolbar *toolbar) +{ + if (toolbar != NULL && toolbar->throbber != NULL) + ro_gui_throbber_animate(toolbar->throbber); +} + + +/* This is an exported interface documented in toolbar.h */ + +void ro_toolbar_stop_throbbing(struct toolbar *toolbar) +{ + if (toolbar != NULL && toolbar->throbber != NULL) + ro_gui_throbber_stop(toolbar->throbber); +} + + +/* This is an exported interface documented in toolbar.h */ + +void ro_toolbar_throb(struct toolbar *toolbar) +{ + if (toolbar != NULL && toolbar->throbber != NULL) + ro_gui_throbber_animate(toolbar->throbber); +} + + +/* This is an exported interface documented in toolbar.h */ + +bool ro_toolbar_set_button_order(struct toolbar *toolbar, char order[]) +{ + if (toolbar == NULL || toolbar->buttons == NULL) + return false; + + if (!ro_gui_button_bar_arrange_buttons(toolbar->buttons, order)) + return false; + + ro_toolbar_refresh_widget_dimensions(toolbar); + + return ro_toolbar_process(toolbar, -1, true); +} + + +/* This is an exported interface documented in toolbar.h */ + +void ro_toolbar_set_button_shaded_state(struct toolbar *toolbar, + button_bar_action action, bool shaded) +{ + if (toolbar == NULL || toolbar->buttons == NULL) + return; + + ro_gui_button_bar_shade_button(toolbar->buttons, action, shaded); +} + + +/* This is an exported interface documented in toolbar.h */ + +bool ro_toolbar_take_caret(struct toolbar *toolbar) +{ + if (toolbar == NULL || toolbar->url == NULL || !toolbar->url_display) + return false; + + return ro_gui_url_bar_take_caret(toolbar->url); +} + + +/* This is an exported interface documented in toolbar.h */ + +void ro_toolbar_set_url(struct toolbar *toolbar, const char *url, + bool is_utf8, bool set_caret) +{ + if (toolbar != NULL && toolbar->url != NULL) + ro_gui_url_bar_set_url(toolbar->url, url, is_utf8, set_caret); +} + + +/* This is an exported interface documented in toolbar.h */ + +const char *ro_toolbar_get_url(struct toolbar *toolbar) +{ + if (toolbar == NULL || toolbar->url == NULL) + return NULL; + + return ro_gui_url_bar_get_url(toolbar->url); +} + + +/* This is an exported interface documented in toolbar.h */ + +void ro_toolbar_update_all_hotlists(void) +{ + struct toolbar *bar; + + bar = ro_toolbar_bars; + while (bar != NULL) { + ro_toolbar_update_hotlist(bar); + + bar = bar->next; + } +} + + +/* This is an exported interface documented in toolbar.h */ + +void ro_toolbar_update_hotlist(struct toolbar *toolbar) +{ + if (toolbar == NULL || toolbar->url == NULL) + return; + + ro_gui_url_bar_update_hotlist(toolbar->url); +} + + +/* This is an exported interface documented in toolbar.h */ + +bool ro_toolbar_get_url_field_extent(struct toolbar *toolbar, os_box *extent) +{ + if (toolbar == NULL || toolbar->url == NULL) + return false; + + if (extent == NULL) + return true; + + return ro_gui_url_bar_get_url_extent(toolbar->url, extent); +} + + +/* This is an exported interface documented in toolbar.h */ + +void ro_toolbar_set_site_favicon(struct toolbar *toolbar, + struct hlcache_handle *h) +{ + if (toolbar == NULL || toolbar->url == NULL) + return; + + ro_gui_url_bar_set_site_favicon(toolbar->url, h); +} + + +/* This is an exported interface documented in toolbar.h */ + +void ro_toolbar_set_content_favicon(struct toolbar *toolbar, + struct gui_window *g) +{ + if (toolbar == NULL || toolbar->url == NULL) + return; + + ro_gui_url_bar_set_content_favicon(toolbar->url, g); +} + + +/* This is an exported interface documented in toolbar.h */ + +void ro_toolbar_update_urlsuggest(struct toolbar *toolbar) +{ + if (toolbar == NULL || toolbar->url == NULL) + return; + + ro_gui_url_bar_update_urlsuggest(toolbar->url); +} + + +/* This is an exported interface documented in toolbar.h */ + +void ro_toolbar_set_display_buttons(struct toolbar *toolbar, bool display) +{ + if (toolbar == NULL || toolbar->buttons == NULL) + return; + + toolbar->buttons_display = display; + ro_gui_button_bar_hide(toolbar->buttons, !display); + ro_toolbar_refresh_widget_dimensions(toolbar); + ro_toolbar_refresh(toolbar); +} + + +/* This is an exported interface documented in toolbar.h */ + +void ro_toolbar_set_display_url(struct toolbar *toolbar, bool display) +{ + if (toolbar == NULL || toolbar->url == NULL) + return; + + toolbar->url_display = display; + ro_gui_url_bar_hide(toolbar->url, !display); + ro_toolbar_refresh_widget_dimensions(toolbar); + ro_toolbar_refresh(toolbar); +} + + +/* This is an exported interface documented in toolbar.h */ + +void ro_toolbar_set_display_throbber(struct toolbar *toolbar, bool display) +{ + if (toolbar == NULL || toolbar->throbber == NULL) + return; + + toolbar->throbber_display = display; + ro_gui_throbber_hide(toolbar->throbber, !display); + ro_toolbar_refresh_widget_dimensions(toolbar); + ro_toolbar_refresh(toolbar); +} + + +/* This is an exported interface documented in toolbar.h */ + +bool ro_toolbar_get_display_buttons(struct toolbar *toolbar) +{ + return (toolbar == NULL || toolbar->buttons == NULL) ? + false : toolbar->buttons_display; +} + + +/* This is an exported interface documented in toolbar.h */ + +bool ro_toolbar_get_display_url(struct toolbar *toolbar) +{ + return (toolbar == NULL || toolbar->url == NULL) ? + false : toolbar->url_display; +} + + +/* This is an exported interface documented in toolbar.h */ + +bool ro_toolbar_get_display_throbber(struct toolbar *toolbar) +{ + return (toolbar == NULL || toolbar->throbber == NULL) ? + false : toolbar->throbber_display; +} + + +/* This is an exported interface documented in toolbar.h */ + +bool ro_toolbar_get_editing(struct toolbar *toolbar) +{ + return (toolbar == NULL || !toolbar->editing) ? false : true; +} + + +/* This is an exported interface documented in toolbar.h */ + +bool ro_toolbar_toggle_edit(struct toolbar *toolbar) +{ + if (toolbar == NULL || toolbar->editor == NULL) + return false; + + toolbar->editing = !toolbar->editing; + + ro_gui_button_bar_hide(toolbar->editor, !toolbar->editing); + ro_gui_button_bar_hide(toolbar->buttons, + !toolbar->buttons_display && !toolbar->editing); + + if (!ro_toolbar_rebuild(toolbar)) { + ro_toolbar_destroy(toolbar); + return false; + } + + ro_toolbar_refresh(toolbar); + + /* If there's a callback registered and an edit has finished, + * tell out client what the new button state is. + */ + + if (!toolbar->editing && toolbar->buttons != NULL && + toolbar->callbacks != NULL && + toolbar->callbacks->save_buttons != NULL) { + char *new_buttons; + new_buttons = ro_gui_button_bar_get_config(toolbar->buttons); + toolbar->callbacks->save_buttons(toolbar->client_data, + new_buttons); + } + + return true; +} + diff --git a/frontends/riscos/toolbar.h b/frontends/riscos/toolbar.h new file mode 100644 index 000000000..41f1af728 --- /dev/null +++ b/frontends/riscos/toolbar.h @@ -0,0 +1,542 @@ +/* + * Copyright 2005 Richard Wilson <info@tinct.net> + * Copyright 2010, 2011 Stephen Fryatt <stevef@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Window toolbars (interface). + */ + +#include <stdbool.h> +#include "riscos/theme.h" +#include "riscos/gui/button_bar.h" +#include "riscos/gui/throbber.h" +#include "riscos/gui/url_bar.h" + +#ifndef _NETSURF_RISCOS_TOOLBAR_H_ +#define _NETSURF_RISCOS_TOOLBAR_H_ + +typedef enum { + TOOLBAR_FLAGS_NONE = 0x00, + TOOLBAR_FLAGS_DISPLAY = 0x01, + TOOLBAR_FLAGS_EDIT = 0x02, +} toolbar_flags; + +/** + * Widget action types that the toolbar can pass on to clients. + */ + +typedef enum { + TOOLBAR_ACTION_NONE = 0, + TOOLBAR_ACTION_BUTTON, + TOOLBAR_ACTION_URL +} toolbar_action_type; + +/** + * Union to hold the different widget action data that can be passed + * from widget via toolbar to client. + */ + +union toolbar_action { + button_bar_action button; + url_bar_action url; +}; + +struct toolbar; + +struct toolbar_callbacks { + /** Call on theme update */ + void (*theme_update)(void *, bool); + + /** Call on bar size change */ + void (*change_size)(void *); + + /** Call to update button states */ + void (*update_buttons)(void *); + + /** Call to handle user actions */ + void (*user_action)(void *, toolbar_action_type, union toolbar_action); + + /** Call to handle keypresses. */ + bool (*key_press)(void *, wimp_key *); + + /** Call on change to button order. */ + void (*save_buttons)(void *, char *); +}; + + +#define ro_toolbar_menu_option_shade(toolbar) \ + (((toolbar) == NULL) || ro_toolbar_get_editing(toolbar)) + +#define ro_toolbar_menu_buttons_tick(toolbar) \ + (ro_toolbar_get_display_buttons(toolbar) || \ + ro_toolbar_get_editing(toolbar)) + +#define ro_toolbar_menu_url_tick(toolbar) \ + (ro_toolbar_get_display_url(toolbar)) + +#define ro_toolbar_menu_throbber_tick(toolbar) \ + (ro_toolbar_get_display_throbber(toolbar)) + +#define ro_toolbar_menu_edit_shade(toolbar) ((toolbar) == NULL) + +#define ro_toolbar_menu_edit_tick(toolbar) (ro_toolbar_get_editing(toolbar)) + + +/* The new toolbar API */ + + +/** + * Initialise the RISC OS toolbar widget. + */ + +void ro_toolbar_init(void); + + +/** + * Create a new toolbar, ready to have widgets added and to be attached to + * a window. If a parent window is supplied, then the toolbar module will + * handle the window attachments; if NULL, it is up to the client to sort this + * out for itself. + * + * \param *descriptor The theme to apply, or NULL for the default. + * \param parent The window to attach the toolbar to, or NULL. + * \param style The theme style to apply. + * \param bar_flags Toolbar flags for the new bar. + * \param *callbacks A client callback block, or NULL for none. + * \param *client_data A data pointer to pass to callbacks, or NULL. + * \param *help The Help token prefix for interactive help. + * \return The handle of the new bar, or NULL on failure. + */ + +struct toolbar *ro_toolbar_create(struct theme_descriptor *descriptor, + wimp_w parent, theme_style style, toolbar_flags bar_flags, + const struct toolbar_callbacks *callbacks, void *client_data, + const char *help); + + +/** + * Add a button bar to a toolbar, and configure the buttons. + * + * \param *toolbar The toolbar to take the button bar. + * \param buttons[] The button definitions. + * \param *button_order The initial button order to use. + * \return true if the action completed; else false. + */ + +bool ro_toolbar_add_buttons(struct toolbar *toolbar, + const struct button_bar_buttons buttons[], char *button_order); + + +/** + * Add a throbber to a toolbar. + * + * \param *toolbar The toolbar to take the throbber. + * \return true if the action completed; else false. + */ + +bool ro_toolbar_add_throbber(struct toolbar *toolbar); + + +/** + * Add a URL bar to a toolbar. + * + * \param *toolbar The toolbar to take the URL bar. + * \return true if the action completed; else false. + */ + +bool ro_toolbar_add_url(struct toolbar *toolbar); + + +/** + * (Re-)build a toolbar to use the specified (or current) theme. If false + * is returned, the toolbar may not be complete and should be deleted. + * + * \param *toolbar The toolbar to rebuild. + * \return true if the action was successful; else false. + */ + +bool ro_toolbar_rebuild(struct toolbar *toolbar); + + +/** + * Attach or re-attach a toolbar to its parent window. + * + * \param *toolbar The toolbar to attach. + * \param parent The window to attach the toolbar to. + * \return true if the operation succeeded; else false. + */ + +bool ro_toolbar_attach(struct toolbar *toolbar, wimp_w parent); + + +/** + * Process a toolbar, updating its contents for a size or content change. + * + * \param *toolbar The toolbar to update. + * \param width The width to reformat to, or -1 to use parent. + * \param reformat true to force a widget reflow; else false. + * \return true if the operation succeeded; else false. + */ + +bool ro_toolbar_process(struct toolbar *toolbar, int width, bool reformat); + + +/** + * Destroy a toolbar after use. + * + * \param *toolbar The toolbar to destroy. + */ + +void ro_toolbar_destroy(struct toolbar *toolbar); + + +/** + * Change the client data associated with a toolbar's callbacks. + * + * \param *toolbar the toolbar whose data is to be updated. + * \param *client_data the new client data, or NULL for none. + */ + +void ro_toolbar_update_client_data(struct toolbar *toolbar, void *client_data); + + +/** + * Force the update of all toolbars buttons to reflect the current state. + */ + +void ro_toolbar_update_all_buttons(void); + + +/** + * Refresh a toolbar after it has been updated + * + * \param toolbar the toolbar to update + */ + +void ro_toolbar_refresh(struct toolbar *toolbar); + + +/** + * Force the update of all toolbars to reflect the application of a new theme. + */ + +void ro_toolbar_theme_update(void); + + +/** + * Find the toolbar associated with a given RO window handle. + * + * \param w the window handle to look up. + * \return the toolbar handle, or NULL if a match wasn't found. + */ + +struct toolbar *ro_toolbar_parent_window_lookup(wimp_w w); + + +/** + * Find the toolbar using a given RO window handle for its pane. + * + * \param w the window (pane) handle to look up. + * \return the toolbar handle, or NULL if a match wasn't found. + */ + +struct toolbar *ro_toolbar_window_lookup(wimp_w w); + + +/** + * Return the RO window handle of the parent window for a toolbar. + * + * \param *toolbar the toolbar to look up. + * \return the RO window handle of the parent. + */ + +wimp_w ro_toolbar_get_parent_window(struct toolbar *toolbar); + + +/** + * Return the RO window handle of a toolbar. + * + * \param *toolbar the toolbar to look up. + * \return the RO window handle of the bar. + */ + +wimp_w ro_toolbar_get_window(struct toolbar *toolbar); + + +/** + * Return the current height of a toolbar, allowing for available window + * space. + * + * \param *toolbar The toolbar of interest. + * \return The current toolbar height in OS units. + */ + +int ro_toolbar_height(struct toolbar *toolbar); + + +/** + * Return the full height that a toolbar could grow to, if space is available. + * + * \param *toolbar The toolbar of interest. + * \return The full toolbar height in OS units. + */ + +int ro_toolbar_full_height(struct toolbar *toolbar); + + +/** + * Starts a toolbar throbber, if there is one active. + * + * \param *toolbar the toolbar to start throbbing. + */ + +void ro_toolbar_start_throbbing(struct toolbar *toolbar); + + +/** + * Stops a toolbar throbber, if there is one active. + * + * \param *toolbar the toolbar to stop throbbing. + */ + +void ro_toolbar_stop_throbbing(struct toolbar *toolbar); + + +/** + * Animate a toolbar throbber, if there is one active. + * + * \param *toolbar the toolbar to throb. + */ + +void ro_toolbar_throb(struct toolbar *toolbar); + +/** + * Change the arrangement of buttons and spacers on a button bar within a + * toolbar. + * + * \param *toolbar The toolbar to change. + * \param order[] The new button configuration. + * \return true of the order was updated; else false. + */ + +bool ro_toolbar_set_button_order(struct toolbar *toolbar, char order[]); + + +/** + * Set the shaded state of a toolbar button. + * + * \param *toolbar the toolbar to update. + * \param action the button action to update. + * \param shaded true if the button should be shaded; else false. + */ + +void ro_toolbar_set_button_shaded_state(struct toolbar *toolbar, + button_bar_action action, bool shaded); + +/** + * Give a toolbar input focus, placing the caret into the URL bar if one is + * present. Currently a toolbar can only accept focus if it has a URL bar. + * + * \param *toolbar The toolbar to take the caret. + * \return true if the caret was taken; else false. + */ + +bool ro_toolbar_take_caret(struct toolbar *toolbar); + + +/** + * Set the content of a toolbar's URL field. + * + * \param *toolbar the toolbar to update. + * \param *url the new url to insert. + * \param is_utf8 true if the string is in utf8 encoding; false + * if it is in local encoding. + * \param set_caret true if the caret should be placed in the field; + * else false. + */ + +void ro_toolbar_set_url(struct toolbar *toolbar, const char *url, + bool is_utf8, bool set_caret); + + +/** + * Return a pointer to the URL contained in a browser toolbar. If the toolbar + * doesn't have a URL field, then NULL is returned instead. + * + * \param *toolbar The toolbar to look up the URL from. + * \return pointer to the URL, or NULL. + */ + +const char *ro_toolbar_get_url(struct toolbar *toolbar); + + +/** + * Update the state of the URL Bar hotlist icons in all open toolbars. + */ + +void ro_toolbar_update_all_hotlists(void); + + +/** + * Update the state of a toolbar's URL Bar hotlist icon to reflect any changes + * to the URL or the hotlist contents. + * + * \param *toolbar The toolbar to update. + */ + +void ro_toolbar_update_hotlist(struct toolbar *toolbar); + + +/** + * Return the current work area coordinates of the URL and favicon field's + * bounding box. + * + * \param *toolbar The toolbar to look up. + * \param *extent Return the coordinates. + * \return true if successful; else false. + */ + +bool ro_toolbar_get_url_field_extent(struct toolbar *toolbar, os_box *extent); + + +/** + * Update the favicon in a browser window toolbar to the supplied content, or + * revert to using filetype-based icons. + * + * \param *toolbar The toolbar to refresh. + * \param *h The new favicon to use, or NULL for none. + */ + +void ro_toolbar_set_site_favicon(struct toolbar *toolbar, + struct hlcache_handle *h); + + +/** + * Update the favicon in a browser window toolbar to reflect the RISC OS + * filetype of the content within the supplied window. If the toolbar + * currently has a site favicon set, then this call will be ignored. + * + * \param *toolbar The toolbar to refresh. + * \param *g The gui window to set content favicon for. + */ + +void ro_toolbar_set_content_favicon(struct toolbar *toolbar, + struct gui_window *g); + + +/** + * Update the state of the URL suggestion pop-up menu icon on a toolbar. + * + * \param *toolbar The toolbar to update. + */ + +void ro_toolbar_update_urlsuggest(struct toolbar *toolbar); + + +/** + * Set the display button bar state for a toolbar. + * + * \param *toolbar the toolbar to update. + * \param display true to display the button bar; else false. + */ + +void ro_toolbar_set_display_buttons(struct toolbar *toolbar, bool display); + + +/** + * Set the display URL bar state for a toolbar. + * + * \param *toolbar the toolbar to update. + * \param display true to display the URL bar; else false. + */ + +void ro_toolbar_set_display_url(struct toolbar *toolbar, bool display); + + +/** + * Set the display throbber state for a toolbar. + * + * \param *toolbar the toolbar to update. + * \param display true to display the throbber; else false. + */ + +void ro_toolbar_set_display_throbber(struct toolbar *toolbar, bool display); + + +/** + * Return true or false depending on whether the given toolbar is set to + * display the button bar. + * + * \param *toolbar the toolbar of interest. + * \return true if the toolbar exists and the button bar is + * shown; else false. + */ + +bool ro_toolbar_get_display_buttons(struct toolbar *toolbar); + + +/** + * Return true or false depending on whether the given toolbar is set to + * display the URL bar. + * + * \param *toolbar the toolbar of interest. + * \return true if the toolbar exists and the URL bar is + * shown; else false. + */ + +bool ro_toolbar_get_display_url(struct toolbar *toolbar); + + +/** + * Return true or false depending on whether the given toolbar is set to + * display the throbber. + * + * \param *toolbar the toolbar of interest. + * \return true if the toolbar exists and the throbber is + * shown; else false. + */ + +bool ro_toolbar_get_display_throbber(struct toolbar *toolbar); + + +/** + * Return true or false depending on whether the given toolbar is currently + * being edited. + * + * \param *toolbar the toolbar of interest. + * \return true if the toolbar exists and is beng edited; + * else false. + */ + +bool ro_toolbar_get_editing(struct toolbar *toolbar); + + +/** + * Toggle toolbar edit mode on the given toolbar. Only a button bar can be + * edited, so edit mode can only be toggled if there's an editor button + * bar defined. + * + * \param *toolbar The toolbar to be toggled. + * \return true if the action was successful; false if + * the action failed and the toolbar was destroyed. + */ + +bool ro_toolbar_toggle_edit(struct toolbar *toolbar); + +#endif + diff --git a/frontends/riscos/treeview.c b/frontends/riscos/treeview.c new file mode 100644 index 000000000..3428ad3d4 --- /dev/null +++ b/frontends/riscos/treeview.c @@ -0,0 +1,1279 @@ +/* + * Copyright 2005 Richard Wilson <info@tinct.net> + * Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Generic tree handling (implementation). + */ + +#include <oslib/os.h> + +#include <assert.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <swis.h> +#include <time.h> +#include "oslib/colourtrans.h" +#include "oslib/dragasprite.h" +#include "oslib/osbyte.h" +#include "oslib/osspriteop.h" +#include "oslib/wimp.h" + +#include "utils/log.h" +#include "utils/messages.h" +#include "utils/utils.h" +#include "content/urldb.h" +#include "desktop/browser.h" +#include "desktop/plotters.h" +#include "desktop/textinput.h" +#include "desktop/tree.h" + +#include "riscos/bitmap.h" +#include "riscos/dialog.h" +#include "riscos/gui.h" +#include "riscos/image.h" +#include "riscos/menus.h" +#include "riscos/mouse.h" +#include "riscos/toolbar.h" +#include "riscos/tinct.h" +#include "riscos/textarea.h" +#include "riscos/treeview.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" +#include "riscos/wimputils.h" + +#ifndef wimp_KEY_END +#define wimp_KEY_END wimp_KEY_COPY +#endif + +struct ro_treeview +{ + struct tree *tree; /*< Pointer to treeview tree block. */ + wimp_w w; /*< RO Window Handle for tree window. */ + struct toolbar *tb; /*< Pointer to toolbar block. */ + struct { + int x; /*< X origin of tree, to RO work area. */ + int y; /*< Y origin of tree, to RO work area. */ + } origin; + struct { + int x; /*< X dimension of the tree, in RO units. */ + int y; /*< Y dimension of the tree, in RO units. */ + } size; /* (Dimensions are 0 until set correctly). */ + struct { + int x; /*< X extent of the window, in RO units. */ + int y; /*< Y extent of the window, in RO units. */ + } extent; /* (Extents are 0 until set correctly). */ + struct { + int x; /*< X coordinate of drag start */ + int y; /*< Y coordinate of drag start */ + } drag_start; + tree_drag_type drag; /*< The current drag type for the tree */ + struct ro_treeview_callbacks *callbacks; /*< Callback handlers */ +}; + +static void ro_treeview_redraw_request(int x, int y, int width, int height, + void *pw); +static void ro_treeview_resized(struct tree *tree, int width, int height, + void *pw); +static void ro_treeview_scroll_visible(int y, int height, void *pw); +static void ro_treeview_get_window_dimensions(int *width, int *height, + void *pw); + +static void ro_treeview_redraw(wimp_draw *redraw); +static void ro_treeview_scroll(wimp_scroll *scroll); +static void ro_treeview_redraw_loop(wimp_draw *redraw, ro_treeview *tv, + osbool more); +static void ro_treeview_open(wimp_open *open); +static bool ro_treeview_mouse_click(wimp_pointer *pointer); +static void ro_treeview_pointer_entering(wimp_entering *entering); +static void ro_treeview_drag_start(ro_treeview *tv, wimp_pointer *pointer, + wimp_window_state *state); +static void ro_treeview_drag_end(wimp_dragged *drag, void *data); +static bool ro_treeview_keypress(wimp_key *key); + +static void ro_treeview_set_window_extent(ro_treeview *tv, + int width, int height); + +static void ro_treeview_update_theme(void *data, bool ok); +static void ro_treeview_update_toolbar(void *data); +static void ro_treeview_button_update(void *data); +static void ro_treeview_save_toolbar_buttons(void *data, char *config); +static void ro_treeview_button_click(void *data, + toolbar_action_type action_type, union toolbar_action action); + +static const struct treeview_table ro_tree_callbacks = { + ro_treeview_redraw_request, + ro_treeview_resized, + ro_treeview_scroll_visible, + ro_treeview_get_window_dimensions +}; + +static const struct toolbar_callbacks ro_treeview_toolbar_callbacks = { + ro_treeview_update_theme, + ro_treeview_update_toolbar, + ro_treeview_button_update, + ro_treeview_button_click, + NULL, /* No toolbar keypress handler */ + ro_treeview_save_toolbar_buttons +}; + + +/** + * Create a RISC OS GUI implementation of a treeview tree. + * + * \param window The window to create the tree in. + * \param *toolbar A toolbar to attach to the window. + * \param *callbacks Callbacks to service the treeview. + * \param flags The treeview flags. + * + * \return The RISC OS treeview pointer. + */ + +ro_treeview *ro_treeview_create(wimp_w window, struct toolbar *toolbar, + struct ro_treeview_callbacks *callbacks, unsigned int flags) +{ + ro_treeview *tv; + + /* Claim memory for the treeview block, and create a tree. */ + + tv = malloc(sizeof(ro_treeview)); + if (tv == NULL) + return NULL; + + tv->w = window; + tv->tb = toolbar; + + /* Set the tree redraw origin at a default 0,0 RO units. */ + + tv->origin.x = 0; + tv->origin.y = 0; + + /* Set the tree size as 0,0 to indicate that we don't know. */ + + tv->size.x = 0; + tv->size.y = 0; + + /* Set the tree window extent to 0,0, to indicate that we + * don't know. */ + + tv->extent.x = 0; + tv->extent.y = 0; + + /* Set that there is no drag opperation at the moment */ + + tv->drag = TREE_NO_DRAG; + + tv->tree = tree_create(flags, &ro_tree_callbacks, tv); + if (tv->tree == NULL) { + free(tv); + return NULL; + } + + /* Record the callback info. */ + + tv->callbacks = callbacks; + + /* Register wimp events to handle the supplied window. */ + + ro_gui_wimp_event_register_redraw_window(tv->w, ro_treeview_redraw); + ro_gui_wimp_event_register_scroll_window(tv->w, ro_treeview_scroll); + ro_gui_wimp_event_register_pointer_entering_window(tv->w, + ro_treeview_pointer_entering); + ro_gui_wimp_event_register_open_window(tv->w, ro_treeview_open); + ro_gui_wimp_event_register_mouse_click(tv->w, ro_treeview_mouse_click); + ro_gui_wimp_event_register_keypress(tv->w, ro_treeview_keypress); + ro_gui_wimp_event_set_user_data(tv->w, tv); + + return tv; +} + +/** + * Delete a RISC OS GUI implementation of a treeview tree. The window is + * *not* destroyed -- this must be done by the caller. + * + * \param tv The RISC OS treeview to delete. + */ + +void ro_treeview_destroy(ro_treeview *tv) +{ + ro_gui_wimp_event_finalise(tv->w); + + tree_delete(tv->tree); + + free(tv); +} + +/** + * Return a pointer to a toolbar callbacks structure with the handlers to be + * used by any treeview window toolbars. + * + * \return A pointer to the callback structure. + */ + +const struct toolbar_callbacks *ro_treeview_get_toolbar_callbacks(void) +{ + return &ro_treeview_toolbar_callbacks; +} + +/** + * Change the redraw origin of a treeview tree in RISC OS graphics units. + * + * \param *tv The ro_treeview object to update. + * \param x The X position, in terms of the RO window work area. + * \param y The Y position, in terms of the RO window work area. + * + * \todo -- this probably needs a rework. + */ + +void ro_treeview_set_origin(ro_treeview *tv, int x, int y) +{ + if (tv != NULL) { + tv->origin.x = x; + tv->origin.y = y; + + /* Assuming that we know how big the tree currently is, then + * adjust the window work area extent to match. If we don't, + * then presumably the tree isn't in an open window yet and + * a subsequent Open Window Event should pick it up. + */ + + if (tv->size.x != 0 && tv->size.y != 0) + ro_treeview_set_window_extent(tv, + tv->origin.x + tv->size.x, + tv->origin.y + tv->size.y); + } +} + +/** + * Return details of the tree block associated with an ro_treeview object. + * + * \param *tv The ro_treeview object of interest. + * \return A pointer to the associated tree block. + */ + +struct tree *ro_treeview_get_tree(ro_treeview *tv) +{ + return (tv != NULL) ? (tv->tree) : (NULL); +} + +/** + * Return details of the RISC OS window handle associated with an + * ro_treeview object. + * + * \param *tv The ro_treeview object of interest. + * \return The associated RISC OS window handle. + */ + +wimp_w ro_treeview_get_window(ro_treeview *tv) +{ + return (tv != NULL) ? (tv->w) : (NULL); +} + +/** + * Callback to force a redraw of part of the treeview window. + * + * \param x Min X Coordinate of area to be redrawn. + * \param y Min Y Coordinate of area to be redrawn. + * \param width Width of area to be redrawn. + * \param height Height of area to be redrawn. + * \param pw The treeview object to be redrawn. + */ + +void ro_treeview_redraw_request(int x, int y, int width, int height, + void *pw) +{ + if (pw != NULL) { + ro_treeview *tv = (ro_treeview *) pw; + os_error *error; + wimp_draw update; + osbool more; + + update.w = tv->w; + update.box.x0 = (2 * x) + tv->origin.x; + update.box.y0 = (-2 * (y + height)) + tv->origin.y; + update.box.x1 = (2 * (x + width)) + tv->origin.x; + update.box.y1 = (-2 * y) + tv->origin.y; + + error = xwimp_update_window(&update, &more); + if (error) { + LOG("xwimp_update_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + ro_treeview_redraw_loop(&update, tv, more); + } +} + +/** + * Pass RISC OS redraw events on to the treeview widget. + * + * \param *redraw Pointer to Redraw Event block. + */ + +void ro_treeview_redraw(wimp_draw *redraw) +{ + osbool more; + os_error *error; + ro_treeview *tv; + + tv = (ro_treeview *) ro_gui_wimp_event_get_user_data(redraw->w); + if (tv == NULL) { + LOG("NULL treeview block for window: 0x%x", (unsigned int)redraw->w); + /* Don't return, as not servicing redraw events isn't a good + * idea. The following code must handle (tv == NULL) + * gracefully while clearing the redraw queue. + */ + } + + error = xwimp_redraw_window(redraw, &more); + if (error) { + LOG("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + ro_treeview_redraw_loop(redraw, tv, more); +} + +/** + * Handle scroll events in treeview windows. + * + * \param *scroll Pointer to Scroll Event block. + */ + +void ro_treeview_scroll(wimp_scroll *scroll) +{ + os_error *error; + int x = scroll->visible.x1 - scroll->visible.x0 - 32; + int y = scroll->visible.y1 - scroll->visible.y0 - 32; + ro_treeview *tv; + + tv = (ro_treeview *) ro_gui_wimp_event_get_user_data(scroll->w); + if (tv == NULL) + return; + + if (tv->tb != NULL) + y -= ro_toolbar_full_height(tv->tb); + + switch (scroll->xmin) { + case wimp_SCROLL_PAGE_LEFT: + scroll->xscroll -= x; + break; + case wimp_SCROLL_COLUMN_LEFT: + scroll->xscroll -= 32; + break; + case wimp_SCROLL_COLUMN_RIGHT: + scroll->xscroll += 32; + break; + case wimp_SCROLL_PAGE_RIGHT: + scroll->xscroll += x; + break; + default: + scroll->xscroll += (x * (scroll->xmin>>2)) >> 2; + break; + } + + switch (scroll->ymin) { + case wimp_SCROLL_PAGE_UP: + scroll->yscroll += y; + break; + case wimp_SCROLL_LINE_UP: + scroll->yscroll += 32; + break; + case wimp_SCROLL_LINE_DOWN: + scroll->yscroll -= 32; + break; + case wimp_SCROLL_PAGE_DOWN: + scroll->yscroll -= y; + break; + default: + scroll->yscroll += (y * (scroll->ymin>>2)) >> 2; + break; + } + + error = xwimp_open_window((wimp_open *) scroll); + if (error) { + LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess); + } +} + + +/** + * Redraw a treeview window, once the initial readraw block has been collected. + * + * /param *redraw Pointer to redraw block. + * /param *tv The treeview object being redrawn. + * /param more Flag to show if more actions are required. + */ + +void ro_treeview_redraw_loop(wimp_draw *redraw, ro_treeview *tv, osbool more) +{ + struct redraw_context ctx = { + .interactive = true, + .background_images = true, + .plot = &ro_plotters + }; + + while (more) { + os_error *error; + + if (tv != NULL && tv->tree != NULL) { + struct rect clip; + + ro_plot_origin_x = redraw->box.x0 + tv->origin.x - + redraw->xscroll; + ro_plot_origin_y = redraw->box.y1 + tv->origin.y - + redraw->yscroll; + + clip.x0 = (redraw->clip.x0 - ro_plot_origin_x) / 2; + clip.y0 = (ro_plot_origin_y - redraw->clip.y1) / 2; + + /* Treeview text alwyas has flat background colour, + * so disable unnecessary background blending */ + no_font_blending = true; + tree_draw(tv->tree, 0, 0, + clip.x0, clip.y0, + (redraw->clip.x1 - redraw->clip.x0)/2, + (redraw->clip.y1 - redraw->clip.y0)/2, + &ctx); + no_font_blending = false; + } + + error = xwimp_get_rectangle(redraw, &more); + if (error) { + LOG("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + } +} + +/** + * Callback to notify us of a new overall tree size. + * + * \param tree The tree being resized. + * \param width The new width of the window. + * \param height The new height of the window. + * \param *pw The treeview object to be resized. + */ + +void ro_treeview_resized(struct tree *tree, int width, int height, + void *pw) +{ + if (pw != NULL) { + ro_treeview *tv = (ro_treeview *) pw; + + /* Store the width and height in terms of RISC OS work area. */ + + tv->size.x = width * 2; + tv->size.y = -(height * 2); + + /* Resize the window. */ + + ro_treeview_set_window_extent(tv, tv->size.x, tv->size.y); + } +} + +/** + * Callback to request that a section of the tree is scrolled into view. + * + * \param y The Y coordinate of top of the area in NS units. + * \param height The height of the area in NS units. + * \param *pw The treeview object affected. + */ + +void ro_treeview_scroll_visible(int y, int height, void *pw) +{ + if (pw != NULL) { + ro_treeview *tv = (ro_treeview *) pw; + os_error *error; + wimp_window_state state; + int visible_t, visible_b; + int request_t, request_b; + + state.w = tv->w; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + /* Work out top and bottom of both the currently visible and + * the required areas, in terms of the RO work area. + */ + + visible_t = state.yscroll; + visible_b = state.yscroll + - (state.visible.y1 - state.visible.y0); + + request_t = -(2 * y);// - tv->origin.y; + request_b = -(2 * (y + height));// - tv->origin.y; + + /* If the area is outside the visible window, then scroll it + * in to view. + */ + + if (request_t > visible_t || request_b < visible_b) { + if (request_t > visible_t) { + state.yscroll = request_t; + } else if (request_b < visible_b) { + state.yscroll = request_b + tv->origin.y + + (state.visible.y1 - state.visible.y0); + + /* If the required area is bigger than the + * visible extent, then align to the top and + * let the bottom disappear out of view. + */ + + if (state.yscroll < request_t) + state.yscroll = request_t; + } + + error = xwimp_open_window((wimp_open *) &state); + if (error) { + LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + } + } +} + +/** + * Callback to return the tree window dimensions to the treeview system. + * + * \param *width Return the window width. + * \param *height Return the window height. + * \param *pw The treeview object to use. + */ + +void ro_treeview_get_window_dimensions(int *width, int *height, + void *pw) +{ + if (pw != NULL && (width != NULL || height != NULL)) { + ro_treeview *tv = (ro_treeview *) pw; + os_error *error; + wimp_window_state state; + + state.w = tv->w; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + if (width != NULL) + *width = (state.visible.x1 - state.visible.x0) / 2; + + if (height != NULL) + *height = (state.visible.y1 - state.visible.y0) / 2; + } +} + +/** + * Resize the RISC OS window extent of a treeview. + * + * \param *tv The RISC OS treeview object to resize. + * \param width The new width of the work area, in RO units. + * \param height The new height of the work area, in RO units. + */ + +void ro_treeview_set_window_extent(ro_treeview *tv, int width, int height) +{ + if (tv != NULL) { + os_error *error; + os_box extent; + wimp_window_state state; + int new_x, new_y; + int visible_x, visible_y; + + /* Calculate the new window extents, in RISC OS units. */ + + new_x = width + tv->origin.x; + new_y = height + tv->origin.y; + + /* Get details of the existing window, and start to sanity + * check the new extents. + */ + + state.w = tv->w; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + /* If the extent is smaller than the current visible area, + * then extend it so that it matches the visible area. + */ + + if (new_x < (state.visible.x1 - state.visible.x0)) + new_x = state.visible.x1 - state.visible.x0; + + if (new_y > (state.visible.y0 - state.visible.y1)) + new_y = state.visible.y0 - state.visible.y1; + + /* Calculate the maximum visible coordinates of the existing + * window. + */ + + visible_x = state.xscroll + + (state.visible.x1 - state.visible.x0); + visible_y = state.yscroll + + (state.visible.y0 - state.visible.y1); + + /* If the window is currently open, and the exising visible + * area is bigger than the new extent, then we need to reopen + * the window in an appropriare position before setting the + * new extent. + */ + + if ((state.flags & wimp_WINDOW_OPEN) && + (visible_x > new_x || visible_y < new_y)) { + int new_x_scroll = state.xscroll; + int new_y_scroll = state.yscroll; + + if (visible_x > new_x) + new_x_scroll = new_x - (state.visible.x1 + - state.visible.x0); + + if (visible_y < new_y) + new_y_scroll = new_y - (state.visible.y0 + - state.visible.y1); + + if (new_x_scroll < 0) { + state.visible.x1 -= new_x_scroll; + state.xscroll = 0; + } else { + state.xscroll = new_x_scroll; + } + + if (new_y_scroll > 0) { + state.visible.y0 += new_y_scroll; + state.yscroll = 0; + } else { + state.yscroll = new_y_scroll; + } + + error = xwimp_open_window((wimp_open *) &state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + /* \todo -- Not sure if we need to reattach the + * toolbar here: the nested wimp seems to take care + * of it for us? + */ + } + + /* Now that the new extent fits into the visible window, we + * can resize the work area. If we succeed, the values are + * recorded to save having to ask the Wimp for them + * each time. + */ + + extent.x0 = 0; + extent.y0 = new_y; + extent.x1 = new_x; + extent.y1 = 0; + + error = xwimp_set_extent(tv->w, &extent); + if (error) { + LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + tv->extent.x = new_x; + tv->extent.y = new_y; + } +} + +/** + * Handle RISC OS Window Open events for a treeview window. + * + * \param *open Pointer to the Window Open Event block. + */ + +static void ro_treeview_open(wimp_open *open) +{ + ro_treeview *tv; + os_error *error; + os_box extent; + int width, height; + + tv = (ro_treeview *) ro_gui_wimp_event_get_user_data(open->w); + if (tv == NULL) { + LOG("NULL treeview block for window: ox%x", (unsigned int)open->w); + return; + } + + /* Calculate the window work area. It must be at least the same as + * the current visible area of the window, and needs to contain the + * tree as defined by size.x + offset.x and size.y + offset.y (note + * that the offset.y should be set to cover any toolbar, so we can + * ignore the size of that). + */ + + width = open->visible.x1 - open->visible.x0; + height = open->visible.y0 - open->visible.y1; + + if (tv->size.x != 0 && width < (tv->origin.x + tv->size.x)) + width = (tv->origin.x + tv->size.x); + + if (tv->size.y != 0 && height > (tv->size.y + tv->origin.y)) + height = (tv->size.y + tv->origin.y); + + if (width != tv->extent.x || height != tv->extent.y) { + extent.x0 = 0; + extent.y0 = height; + extent.x1 = width; + extent.y1 = 0; + + error = xwimp_set_extent(tv->w, &extent); + if (error) { + LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + tv->extent.x = width; + tv->extent.y = height; + } + + /* \todo -- Might need to add vertical scrollbar hiding back in here? */ + + error = xwimp_open_window(open); + if (error) { + LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + + if (tv->tb) + ro_toolbar_process(tv->tb, -1, false); +} + + +/** + * Pass RISC OS Mouse Click events on to the treeview widget. + * + * \param *pointer Pointer to the Mouse Click Event block. + * \return Return true if click handled; else false. + */ + +static bool ro_treeview_mouse_click(wimp_pointer *pointer) +{ + os_error *error; + ro_treeview *tv; + wimp_window_state state; + int xpos, ypos; + browser_mouse_state mouse; + bool handled = false; + + tv = (ro_treeview *) ro_gui_wimp_event_get_user_data(pointer->w); + if (tv == NULL) { + LOG("NULL treeview block for window: 0x%x", (unsigned int)pointer->w); + return false; + } + + state.w = tv->w; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + + /* Convert the returned mouse coordinates into NetSurf's internal + * units. + */ + + xpos = ((pointer->pos.x - state.visible.x0) + + state.xscroll - tv->origin.x) / 2; + ypos = ((state.visible.y1 - pointer->pos.y) - + state.yscroll + tv->origin.y) / 2; + + /* Start to process the mouse click. + * + * Select and Adjust are processed normally. To get filer-like operation + * with selections, Menu clicks are passed to the treeview first as + * Select if there are no selected nodes in the tree. + */ + + mouse = 0; + + if (pointer->buttons == wimp_CLICK_MENU) { + /* TODO: test for no selection, and pass click to select node */ + /* mouse |= BROWSER_MOUSE_CLICK_1; */ + } else { + mouse = ro_gui_mouse_click_state(pointer->buttons, + wimp_BUTTON_DOUBLE_CLICK_DRAG); + + /* Give the window input focus on Select-clicks. This wouldn't + * be necessary if the core used the RISC OS caret. + */ + + if (mouse & BROWSER_MOUSE_CLICK_1) + xwimp_set_caret_position(tv->w, -1, -100, -100, 32, -1); + } + + if (mouse != 0) { + handled = tree_mouse_action(tv->tree, mouse, xpos, ypos); + + tv->drag = tree_drag_status(tv->tree); + if (tv->drag != TREE_NO_DRAG) { + tv->drag_start.x = xpos; + tv->drag_start.y = ypos; + } + + /* If it's a visible drag, start the RO side of the visible + * effects. + */ + + if (tv->drag == TREE_SELECT_DRAG || + tv->drag == TREE_MOVE_DRAG) + ro_treeview_drag_start(tv, pointer, &state); + + + if (tv->callbacks != NULL && + tv->callbacks->toolbar_button_update != NULL) + tv->callbacks->toolbar_button_update(); + } + + /* Special actions for some mouse buttons. Adjust closes the dialog; + * Menu opens a menu. For the latter, we assume that the owning module + * will have attached a window menu to our parent window with the auto + * flag unset (so that we can fudge the selection above). If it hasn't, + * the call will quietly fail. + * + * \TODO -- Adjust-click close isn't a perfect copy of what the RO + * version did: adjust clicks anywhere close the tree, and + * selections persist. + */ + + switch(pointer->buttons) { + case wimp_CLICK_ADJUST: + if (handled) + ro_gui_dialog_close(tv->w); + break; + + case wimp_CLICK_MENU: + ro_gui_wimp_event_process_window_menu_click(pointer); + break; + } + + return true; +} + + +/** + * Handle Pointer Entering Window events for treeview windows. + * + * \param *entering The Wimp_PointerEnteringWindow block. + */ + +void ro_treeview_pointer_entering(wimp_entering *entering) +{ + ro_treeview *tv; + + tv = (ro_treeview *) ro_gui_wimp_event_get_user_data(entering->w); + if (tv == NULL) + return; + + ro_mouse_track_start(NULL, ro_treeview_mouse_at, NULL); +} + +/** + * Track the mouse under Null Polls from the wimp, to support dragging. + * + * \param *pointer Pointer to a Wimp Pointer block. + * \param *data NULL to allow use as a ro_mouse callback. + */ + +void ro_treeview_mouse_at(wimp_pointer *pointer, void *data) +{ + os_error *error; + ro_treeview *tv; + wimp_window_state state; + int xpos, ypos; + browser_mouse_state mouse; + + if (pointer->buttons & (wimp_CLICK_MENU)) + return; + + tv = (ro_treeview *) ro_gui_wimp_event_get_user_data(pointer->w); + if (tv == NULL) { + LOG("NULL treeview block for window: 0x%x", (unsigned int)pointer->w); + return; + } + + if (tv->drag == TREE_NO_DRAG) + return; + + /* We know now that it's not a Menu click and the treeview thinks + * that a drag is in progress. + */ + + state.w = tv->w; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + /* Convert the returned mouse coordinates into NetSurf's internal + * units. + */ + + xpos = ((pointer->pos.x - state.visible.x0) + + state.xscroll - tv->origin.x) / 2; + ypos = ((state.visible.y1 - pointer->pos.y) - + state.yscroll + tv->origin.y) / 2; + + /* Start to process the mouse click. */ + + mouse = ro_gui_mouse_drag_state(pointer->buttons, + wimp_BUTTON_DOUBLE_CLICK_DRAG); + + tree_mouse_action(tv->tree, mouse, xpos, ypos); + + if (!(mouse & BROWSER_MOUSE_DRAG_ON)) { + tree_drag_end(tv->tree, mouse, tv->drag_start.x, + tv->drag_start.y, xpos, ypos); + tv->drag = TREE_NO_DRAG; + } + + if (tv->callbacks != NULL && + tv->callbacks->toolbar_button_update != NULL) + tv->callbacks->toolbar_button_update(); +} + + +/** + * Start a RISC OS drag event to reflect on screen what is happening + * during the core tree drag. + * + * \param *tv The RO treeview to which the drag is attached. + * \param *pointer The RO pointer event data block starting the drag. + * \param *state The RO window state block for the treeview window. + */ + +static void ro_treeview_drag_start(ro_treeview *tv, wimp_pointer *pointer, + wimp_window_state *state) +{ + os_error *error; + wimp_drag drag; + wimp_auto_scroll_info auto_scroll; + + drag.w = tv->w; + drag.bbox.x0 = state->visible.x0; + drag.bbox.y0 = state->visible.y0; + drag.bbox.x1 = state->visible.x1; + drag.bbox.y1 = state->visible.y1 - ro_toolbar_height(tv->tb) - 2; + + switch (tv->drag) { + case TREE_SELECT_DRAG: + drag.type = wimp_DRAG_USER_RUBBER; + + drag.initial.x0 = pointer->pos.x; + drag.initial.y0 = pointer->pos.y; + drag.initial.x1 = pointer->pos.x; + drag.initial.y1 = pointer->pos.y; + break; + + case TREE_MOVE_DRAG: + drag.type = wimp_DRAG_USER_POINT; + + drag.initial.x0 = pointer->pos.x - 4; + drag.initial.y0 = pointer->pos.y - 48; + drag.initial.x1 = pointer->pos.x + 48; + drag.initial.y1 = pointer->pos.y + 4; + break; + + default: + /* No other drag types are supported. */ + break; + } + + LOG("Drag start..."); + + error = xwimp_drag_box_with_flags(&drag, + wimp_DRAG_BOX_KEEP_IN_LINE | wimp_DRAG_BOX_CLIP); + if (error) { + LOG("xwimp_drag_box: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } else { + auto_scroll.w = tv->w; + auto_scroll.pause_zone_sizes.x0 = 80; + auto_scroll.pause_zone_sizes.y0 = 80; + auto_scroll.pause_zone_sizes.x1 = 80; + auto_scroll.pause_zone_sizes.y1 = 80 + + ro_toolbar_height(tv->tb); + auto_scroll.pause_duration = 0; + auto_scroll.state_change = (void *) 1; + + error = xwimp_auto_scroll(wimp_AUTO_SCROLL_ENABLE_VERTICAL, + &auto_scroll, NULL); + if (error) { + LOG("xwimp_auto_scroll: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + + ro_mouse_drag_start(ro_treeview_drag_end, ro_treeview_mouse_at, + NULL, NULL); + } +} + + +/** + * Process RISC OS User Drag Box events which relate to us: in effect, drags + * started by ro_treeview_drag_start(). + * + * \param *drag Pointer to the User Drag Box Event block. + * \param *data NULL to allow use as a ro_mouse callback. + */ + +static void ro_treeview_drag_end(wimp_dragged *drag, void *data) +{ + os_error *error; + + error = xwimp_drag_box((wimp_drag *) -1); + if (error) { + LOG("xwimp_drag_box: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + + error = xwimp_auto_scroll(0, NULL, NULL); + if (error) { + LOG("xwimp_auto_scroll: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } +} + + +/** + * Pass RISC OS keypress events on to the treeview widget. + * + * \param *key Pointer to the Key Pressed Event block. + * \return Return true if keypress handled; else false. + */ + +static bool ro_treeview_keypress(wimp_key *key) +{ + ro_treeview *tv; + uint32_t c; + + tv = (ro_treeview *) ro_gui_wimp_event_get_user_data(key->w); + if (tv == NULL) { + LOG("NULL treeview block for window: 0x%x", (unsigned int)key->w); + return false; + } + + c = (uint32_t) key->c; + + if ((unsigned)c < 0x20 || (0x7f <= c && c <= 0x9f) || + (c & IS_WIMP_KEY)) { + /* Munge control keys into unused control chars */ + /* We can't map onto 1->26 (reserved for ctrl+<qwerty> + That leaves 27->31 and 128->159 */ + switch (c & ~IS_WIMP_KEY) { + case wimp_KEY_TAB: c = 9; break; + case wimp_KEY_SHIFT | wimp_KEY_TAB: c = 11; break; + + /* cursor movement keys */ + case wimp_KEY_HOME: + case wimp_KEY_CONTROL | wimp_KEY_LEFT: + c = NS_KEY_LINE_START; + break; + case wimp_KEY_END: + if (os_version >= RISCOS5) + c = NS_KEY_LINE_END; + else + c = NS_KEY_DELETE_RIGHT; + break; + case wimp_KEY_CONTROL | wimp_KEY_RIGHT: c = NS_KEY_LINE_END; break; + case wimp_KEY_CONTROL | wimp_KEY_UP: c = NS_KEY_TEXT_START; break; + case wimp_KEY_CONTROL | wimp_KEY_DOWN: c = NS_KEY_TEXT_END; break; + case wimp_KEY_SHIFT | wimp_KEY_LEFT: c = NS_KEY_WORD_LEFT ; break; + case wimp_KEY_SHIFT | wimp_KEY_RIGHT: c = NS_KEY_WORD_RIGHT; break; + case wimp_KEY_SHIFT | wimp_KEY_UP: c = NS_KEY_PAGE_UP; break; + case wimp_KEY_SHIFT | wimp_KEY_DOWN: c = NS_KEY_PAGE_DOWN; break; + case wimp_KEY_LEFT: c = NS_KEY_LEFT; break; + case wimp_KEY_RIGHT: c = NS_KEY_RIGHT; break; + case wimp_KEY_UP: c = NS_KEY_UP; break; + case wimp_KEY_DOWN: c = NS_KEY_DOWN; break; + + /* editing */ + case wimp_KEY_CONTROL | wimp_KEY_END: + c = NS_KEY_DELETE_LINE_END; + break; + case wimp_KEY_DELETE: + if (ro_gui_ctrl_pressed()) + c = NS_KEY_DELETE_LINE_START; + else if (os_version < RISCOS5) + c = NS_KEY_DELETE_LEFT; + break; + + default: + break; + } + } + + if (!(c & IS_WIMP_KEY)) { + if (tree_keypress(tv->tree, c)) { + if (tv->callbacks && + tv->callbacks->toolbar_button_update + != NULL) + tv->callbacks->toolbar_button_update(); + + return true; + } + } + + return false; +} + + +/** + * Update a treeview to use a new theme. + * + * \param *data Pointer to the treeview to update. + * \param ok true if the bar still exists; else false. + */ + +void ro_treeview_update_theme(void *data, bool ok) +{ + ro_treeview *tv = (ro_treeview *) data; + + if (tv != NULL && tv->tb != NULL){ + if (ok) { + ro_treeview_update_toolbar(tv); + } else { + tv->tb = NULL; + } + } +} + + +/** + * Change the size of a treeview's toolbar and redraw the window. + * + * \param *data The treeview to update. + */ + +void ro_treeview_update_toolbar(void *data) +{ + ro_treeview *tv = (ro_treeview *) data; + + if (tv != NULL && tv->tb != NULL) { + ro_treeview_set_origin(tv, 0, + -(ro_toolbar_height(tv->tb))); + + xwimp_force_redraw(tv->w, 0, tv->extent.y, tv->extent.x, 0); + } +} + + +/** + * Update the toolbar icons in a treeview window's toolbar. As we're just + * an intermediate widget, we pass the details on down the chain. + * + * \param *data The treeview owning the toolbar. + */ + +void ro_treeview_button_update(void *data) +{ + ro_treeview *tv = (ro_treeview *) data; + + if (tv == NULL || tv->callbacks == NULL) + return; + + if (tv->callbacks->toolbar_button_update != NULL) + tv->callbacks->toolbar_button_update(); +} + + +/** + * Save a new button configuration from a treeview window's toolbar. As + * we're just an intermediate widget, we pass the details on. + * + * \param *data The treeview owning the toolbar. + * \param *config The new button config string. + */ + +void ro_treeview_save_toolbar_buttons(void *data, char *config) +{ + ro_treeview *tv = (ro_treeview *) data; + + if (tv == NULL || tv->callbacks == NULL) + return; + + if (tv->callbacks->toolbar_button_save != NULL) + tv->callbacks->toolbar_button_save(config); +} + + +/** + * Process clicks on buttons in a treeview window's toolbar. As we're just + * an intermediate widget, we just pass the details on down the chain. + * + * \param *data The treeview owning the click. + * \param action_type The action type to be handled. + * \param action The action to handle. + */ + +void ro_treeview_button_click(void *data, + toolbar_action_type action_type, union toolbar_action action) +{ + ro_treeview *tv = (ro_treeview *) data; + + if (tv == NULL || tv->callbacks == NULL || + action_type != TOOLBAR_ACTION_BUTTON) + return; + + if (tv->callbacks->toolbar_button_click != NULL) + tv->callbacks->toolbar_button_click(action.button); + + if (tv->callbacks->toolbar_button_update != NULL) + tv->callbacks->toolbar_button_update(); +} + + +/** + * Return a token identifying the interactive help message for a given cursor + * position. + * + * Currently this is inimplemented. + * + * \param *message_data Pointer to the Wimp's help message block. + * \return Token value (-1 indicates no help available). + */ + +int ro_treeview_get_help(help_full_message_request *message_data) +{ + return -1; +} + diff --git a/frontends/riscos/treeview.h b/frontends/riscos/treeview.h new file mode 100644 index 000000000..80ff7660f --- /dev/null +++ b/frontends/riscos/treeview.h @@ -0,0 +1,55 @@ +/* + * Copyright 2004 Richard Wilson <not_ginger_matt@users.sourceforge.net> + * Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Generic tree handling (interface). + */ + +#ifndef _NETSURF_RISCOS_TREEVIEW_H_ +#define _NETSURF_RISCOS_TREEVIEW_H_ + +#include <stdbool.h> +#include <oslib/help.h> +#include <oslib/wimp.h> + +#include "desktop/tree.h" +#include "riscos/toolbar.h" + +typedef struct ro_treeview ro_treeview; + +struct ro_treeview_callbacks { + void (*toolbar_button_click)(button_bar_action action); + void (*toolbar_button_update)(void); + void (*toolbar_button_save)(char *); +}; + +ro_treeview *ro_treeview_create(wimp_w window, struct toolbar *toolbar, + struct ro_treeview_callbacks *callbacks, unsigned int flags); +void ro_treeview_destroy(ro_treeview *tv); +const struct toolbar_callbacks *ro_treeview_get_toolbar_callbacks(void); + +struct tree *ro_treeview_get_tree(ro_treeview *tv); +wimp_w ro_treeview_get_window(ro_treeview *tv); + +void ro_treeview_set_origin(ro_treeview *tv, int x, int y); +void ro_treeview_mouse_at(wimp_pointer *pointer, void *data); +int ro_treeview_get_help(help_full_message_request *message_data); + +#endif + diff --git a/frontends/riscos/ucstables.c b/frontends/riscos/ucstables.c new file mode 100644 index 000000000..7ac685df2 --- /dev/null +++ b/frontends/riscos/ucstables.c @@ -0,0 +1,697 @@ +/* + * Copyright 2005 John M Bell <jmb202@ecs.soton.ac.uk> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * UCS conversion tables and RISC OS-specific UTF-8 text handling + */ + +#include <assert.h> +#include <limits.h> +#include <string.h> +#include <stdlib.h> +#include <oslib/osbyte.h> +#include <oslib/territory.h> + +#include "utils/config.h" +#include "utils/errors.h" +#include "utils/log.h" +#include "utils/utf8.h" +#include "utils/utils.h" +#include "desktop/gui_utf8.h" + +#include "riscos/ucstables.h" + +/* Common values (ASCII) */ +#define common \ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, \ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, \ + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, \ + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, \ + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, \ + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, \ + 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, \ + 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127 \ + +/* 0x8c->0x9F, used by many of the encodings */ +#define common2 \ + 0x2026, 0x2122, 0x2030, 0x2022, 0x2018, 0x2019, 0x2039, 0x203a, \ + 0x201c, 0x201d, 0x201e, 0x2013, 0x2014, 0x2212, 0x0152, 0x0153, \ + 0x2020, 0x2021, 0xfb01, 0xfb02 + +static const int latin1_table[256] = +{ + common, + 0x20ac, 0x0174, 0x0175, -1, -1, 0x0176, 0x0177, -1, -1, -1, -1, -1, + common2, + 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, + 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, + 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, + 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, + 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, + 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 +}; + +static const int latin2_table[256] = +{ + common, + 0x20ac, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + common2, + 0x00A0, 0x0104, 0x02D8, 0x0141, 0x00A4, 0x013D, 0x015A, 0x00A7, + 0x00A8, 0x0160, 0x015E, 0x0164, 0x0179, 0x00AD, 0x017D, 0x017B, + 0x00B0, 0x0105, 0x02DB, 0x0142, 0x00B4, 0x013E, 0x015B, 0x02C7, + 0x00B8, 0x0161, 0x015F, 0x0165, 0x017A, 0x02DD, 0x017E, 0x017C, + 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7, + 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E, + 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7, + 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF, + 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7, + 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F, + 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7, + 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9 +}; + +static const int latin3_table[256] = +{ + common, + 0x20ac, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + common2, + 0x00A0, 0x0126, 0x02D8, 0x00A3, 0x00A4, -1, 0x0124, 0x00A7, + 0x00A8, 0x0130, 0x015E, 0x011E, 0x0134, 0x00AD, -1, 0x017B, + 0x00B0, 0x0127, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x0125, 0x00B7, + 0x00B8, 0x0131, 0x015F, 0x011F, 0x0135, 0x00BD, -1, 0x017C, + 0x00C0, 0x00C1, 0x00C2, -1, 0x00C4, 0x010A, 0x0108, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + -1, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x0120, 0x00D6, 0x00D7, + 0x011C, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x016C, 0x015C, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, -1, 0x00E4, 0x010B, 0x0109, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + -1, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x0121, 0x00F6, 0x00F7, + 0x011D, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x016D, 0x015D, 0x02D9 +}; + +static const int latin4_table[256] = +{ + common, + 0x20ac, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + common2, + 0x00A0, 0x0104, 0x0138, 0x0156, 0x00A4, 0x0128, 0x013B, 0x00A7, + 0x00A8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00AD, 0x017D, 0x00AF, + 0x00B0, 0x0105, 0x02DB, 0x0157, 0x00B4, 0x0129, 0x013C, 0x02C7, + 0x00B8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014A, 0x017E, 0x014B, + 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E, + 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x012A, + 0x0110, 0x0145, 0x014C, 0x0136, 0x00D4, 0x00D5, 0x00D6, 0x00D7, + 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x0168, 0x016A, 0x00DF, + 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F, + 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x012B, + 0x0111, 0x0146, 0x014D, 0x0137, 0x00F4, 0x00F5, 0x00F6, 0x00F7, + 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x0169, 0x016B, 0x02D9 +}; + +static const int latin5_table[256] = +{ + common, + 0x20ac, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + common2, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015E, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, + 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF +}; + +static const int latin6_table[256] = +{ + common, + 0x20ac, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + common2, + 0x00A0, 0x0104, 0x0112, 0x0122, 0x012A, 0x0128, 0x0136, 0x00A7, + 0x013B, 0x0110, 0x0160, 0x0166, 0x017D, 0x00AD, 0x016A, 0x014A, + 0x00B0, 0x0105, 0x0113, 0x0123, 0x012B, 0x0129, 0x0137, 0x00B7, + 0x013C, 0x0111, 0x0161, 0x0167, 0x017E, 0x2015, 0x016B, 0x014B, + 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E, + 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x00CF, + 0x00D0, 0x0145, 0x014C, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x0168, + 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, + 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F, + 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x00EF, + 0x00F0, 0x0146, 0x014D, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x0169, + 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x0138 +}; + +static const int latin7_table[256] = +{ + common, + 0x20ac, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0x2026, 0x2122, 0x2030, 0x2022, 0x2018, -1, 0x2039, 0x203a, + -1, -1, -1, 0x2013, 0x2014, 0x2212, 0x0152, 0x0153, + 0x2020, 0x2021, 0xfb01, 0xfb02, + 0x00A0, 0x201D, 0x00A2, 0x00A3, 0x00A4, 0x201E, 0x00A6, 0x00A7, + 0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00C6, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x201C, 0x00B5, 0x00B6, 0x00B7, + 0x00F8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6, + 0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112, + 0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B, + 0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7, + 0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF, + 0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113, + 0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C, + 0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7, + 0x0173, 0x0142, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x2019 +}; + +static const int latin8_table[256] = +{ + common, + 0x20ac, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + common2, + 0x00A0, 0x1E02, 0x1E03, 0x00A3, 0x010A, 0x010B, 0x1E0A, 0x00A7, + 0x1E80, 0x00A9, 0x1E82, 0x1E0B, 0x1EF2, 0x00AD, 0x00AE, 0x0178, + 0x1E1E, 0x1E1F, 0x0120, 0x0121, 0x1E40, 0x1E41, 0x00B6, 0x1E56, + 0x1E81, 0x1E57, 0x1E83, 0x1E60, 0x1EF3, 0x1E84, 0x1E85, 0x1E61, + 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x0174, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x1E6A, + 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x0176, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x0175, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x1E6B, + 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x0177, 0x00FF +}; + +static const int latin9_table[256] = +{ + common, + -1, 0x0174, 0x0175, -1, -1, 0x0176, 0x0177, -1, -1, -1, -1, -1, + 0x2026, 0x2122, 0x2030, 0x2022, 0x2018, 0x2019, 0x2039, 0x203a, + 0x201c, 0x201d, 0x201e, 0x2013, 0x2014, 0x2212, -1, -1, + 0x2020, 0x2021, 0xfb01, 0xfb02, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x20AC, 0x00A5, 0x0160, 0x00A7, + 0x0161, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x017D, 0x00B5, 0x00B6, 0x00B7, + 0x017E, 0x00B9, 0x00BA, 0x00BB, 0x0152, 0x0153, 0x0178, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, + 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF +}; + +static const int latin10_table[256] = +{ + common, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0x2026, 0x2122, 0x2030, 0x2022, 0x2018, 0x2019, 0x2039, 0x203a, + 0x201c, -1, -1, 0x2013, 0x2014, 0x2212, -1, -1, + 0x2020, 0x2021, 0xfb01, 0xfb02, + 0x00A0, 0x0104, 0x0105, 0x0141, 0x20AC, 0x201E, 0x0160, 0x00a7, + 0x0161, 0x00A9, 0x0218, 0x00AB, 0x0179, 0x00AD, 0x017A, 0x017B, + 0x00B0, 0x00B1, 0x010C, 0x0142, 0x017D, 0x201D, 0x00B6, 0x00B7, + 0x017E, 0x010D, 0x0219, 0x00BB, 0x0152, 0x0153, 0x0178, 0x017C, + 0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0106, 0x00C6, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x0110, 0x0143, 0x00D2, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x015A, + 0x0170, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0118, 0x021A, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x0107, 0x00E6, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x0111, 0x0144, 0x00F2, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x015B, + 0x0171, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0119, 0x021B, 0x00FF +}; + +static const int welsh_table[256] = +{ + common, + 0x20ac, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + common2, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x1E80, 0x00A9, 0x1E82, 0x00AB, 0x1EF2, 0x00AD, 0x00AE, 0x0178, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x1E81, 0x00B9, 0x1E83, 0x00BB, 0x1EF3, 0x1E84, 0x1E85, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x0174, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x0176, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x0175, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, + 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x0177, 0x00FF +}; + +static const int greek_table[256] = +{ + common, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0x00A0, 0x2018, 0x2019, 0x00A3, 0x20AC, 0x20AF, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x037A, 0x00AB, 0x00AC, 0x00AD, 0x037E, 0x2015, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x0385, 0x0386, 0x0387, + 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F, + 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, + 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, + 0x03A0, 0x03A1, -1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, + 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF, + 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, + 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, + 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, + 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, -1 +}; + +static const int cyrillic_table[256] = +{ + common, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0x00A0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, + 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x00AD, 0x040E, 0x040F, + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, + 0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, + 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x00A7, 0x045E, 0x045F +}; + +static const int hebrew_table[256] = +{ + common, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0x00A0, -1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x203E, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 0x2017, + 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, + 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, + 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, + 0x05E8, 0x05E9, 0x05EA, -1, -1, 0x200E, 0x200F, -1 +}; + +/** + * Retrieve UCS table (above), given alphabet number + * + * \param alphabet The RISC OS alphabet number + * \return pointer to table, or NULL if not found + */ +const int *ucstable_from_alphabet(int alphabet) +{ + const int *ucstable = NULL; + + switch (alphabet) { + case territory_ALPHABET_LATIN1: + ucstable = latin1_table; + break; + case territory_ALPHABET_LATIN2: + ucstable = latin2_table; + break; + case territory_ALPHABET_LATIN3: + ucstable = latin3_table; + break; + case territory_ALPHABET_LATIN4: + ucstable = latin4_table; + break; + case territory_ALPHABET_LATIN5: + ucstable = latin5_table; + break; + case territory_ALPHABET_LATIN6: + ucstable = latin6_table; + break; + case 114: /* Latin7 */ + ucstable = latin7_table; + break; + case 115: /* Latin8 */ + ucstable = latin8_table; + break; + case 116: /* Latin10 */ + ucstable = latin10_table; + break; + case territory_ALPHABET_LATIN9: + ucstable = latin9_table; + break; + case territory_ALPHABET_WELSH: + ucstable = welsh_table; + break; + case territory_ALPHABET_GREEK: + ucstable = greek_table; + break; + case territory_ALPHABET_CYRILLIC: + ucstable = cyrillic_table; + break; + case territory_ALPHABET_HEBREW: + ucstable = hebrew_table; + break; + default: + ucstable = NULL; + break; + } + + return ucstable; +} + + +static const char *localencodings[] = { + "ISO-8859-1//TRANSLIT", /* BFont - 100 - just use Latin1, instead */ + "ISO-8859-1//TRANSLIT", + "ISO-8859-2//TRANSLIT", + "ISO-8859-3//TRANSLIT", + "ISO-8859-4//TRANSLIT", + "ISO-8859-5//TRANSLIT", + "ISO-8859-6//TRANSLIT", + "ISO-8859-7//TRANSLIT", + "ISO-8859-8//TRANSLIT", + "ISO-8859-9//TRANSLIT", + "ISO-IR-182//TRANSLIT", + "UTF-8", + "ISO-8859-15//TRANSLIT", + "ISO-8859-10//TRANSLIT", + "ISO-8859-13//TRANSLIT", + "ISO-8859-14//TRANSLIT", + "ISO-8859-16//TRANSLIT", +#define CONT_ENC_END 116 /* RISC OS alphabet numbers lie in a + * contiguous range [100,CONT_ENC_END] + * _except_ for Cyrillic2, which doesn't. + */ + "CP866//TRANSLIT" /* Cyrillic2 - 120 */ +}; + +static const struct special { + char local; /**< Local 8bit representation */ + char len; /**< Length (in bytes) of UTF-8 character */ + const char *utf; /**< UTF-8 representation */ +} special_chars[] = { + { 0x80, 3, "\xE2\x82\xAC" }, /* EURO SIGN */ + { 0x81, 2, "\xC5\xB4" }, /* LATIN CAPITAL LETTER W WITH CIRCUMFLEX */ + { 0x82, 2, "\xC5\xB5" }, /* LATIN SMALL LETTER W WITH CIRCUMFLEX */ + { 0x84, 3, "\xE2\x9C\x98" }, /* HEAVY BALLOT X */ + { 0x85, 2, "\xC5\xB6" }, /* LATIN CAPITAL LETTER Y WITH CIRCUMFLEX */ + { 0x86, 2, "\xC5\xB7" }, /* LATIN SMALL LETTER Y WITH CIRCUMFLEX */ + { 0x88, 3, "\xE2\x87\x90" }, /* LEFTWARDS DOUBLE ARROW */ + { 0x89, 3, "\xE2\x87\x92" }, /* RIGHTWARDS DOUBLE ARROW */ + { 0x8a, 3, "\xE2\x87\x93" }, /* DOWNWARDS DOUBLE ARROW */ + { 0x8b, 3, "\xE2\x87\x91" }, /* UPWARDS DOUBLE ARROW */ + { 0x8c, 3, "\xE2\x80\xA6" }, /* HORIZONTAL ELLIPSIS */ + { 0x8d, 3, "\xE2\x84\xA2" }, /* TRADE MARK SIGN */ + { 0x8e, 3, "\xE2\x80\xB0" }, /* PER MILLE SIGN */ + { 0x8f, 3, "\xE2\x80\xA2" }, /* BULLET */ + { 0x90, 3, "\xE2\x80\x98" }, /* LEFT SINGLE QUOTATION MARK */ + { 0x91, 3, "\xE2\x80\x99" }, /* RIGHT SINGLE QUOTATION MARK */ + { 0x92, 3, "\xE2\x80\xB9" }, /* SINGLE LEFT-POINTING ANGLE QUOTATION MARK */ + { 0x93, 3, "\xE2\x80\xBA" }, /* SINGLE RIGHT-POINTING ANGLE QUOTATION MARK */ + { 0x94, 3, "\xE2\x80\x9C" }, /* LEFT DOUBLE QUOTATION MARK */ + { 0x95, 3, "\xE2\x80\x9D" }, /* RIGHT DOUBLE QUOTATION MARK */ + { 0x96, 3, "\xE2\x80\x9E" }, /* DOUBLE LOW-9 QUOTATION MARK */ + { 0x97, 3, "\xE2\x80\x93" }, /* EN DASH */ + { 0x98, 3, "\xE2\x80\x94" }, /* EM DASH */ + { 0x99, 3, "\xE2\x88\x92" }, /* MINUS SIGN */ + { 0x9a, 2, "\xC5\x92" }, /* LATIN CAPITAL LIGATURE OE */ + { 0x9b, 2, "\xC5\x93" }, /* LATIN SMALL LIGATURE OE */ + { 0x9c, 3, "\xE2\x80\xA0" }, /* DAGGER */ + { 0x9d, 3, "\xE2\x80\xA1" }, /* DOUBLE DAGGER */ + { 0x9e, 3, "\xEF\xAC\x81" }, /* LATIN SMALL LIGATURE FI */ + { 0x9f, 3, "\xEF\xAC\x82" } /* LATIN SMALL LIGATURE FL */ +}; + + +/** + * Convert a UTF-8 encoded string into the system local encoding + * + * \param string The string to convert + * \param len The length (in bytes) of the string, or 0 + * \param result Pointer to location in which to store result + * \return An nserror code + */ +nserror utf8_to_local_encoding(const char *string, size_t len, char **result) +{ + os_error *error; + int alphabet, i; + size_t off, prev_off; + char *temp, *cur_pos; + const char *enc; + nserror err; + + assert(string); + assert(result); + + /* get length, if necessary */ + if (len == 0) + len = strlen(string); + + /* read system alphabet */ + error = xosbyte1(osbyte_ALPHABET_NUMBER, 127, 0, &alphabet); + if (error) + alphabet = territory_ALPHABET_LATIN1; + + /* UTF-8 -> simply copy string */ + if (alphabet == 111 /* UTF-8 */) { + *result = strndup(string, len); + return NSERROR_OK; + } + + /* get encoding name */ + enc = (alphabet <= CONT_ENC_END ? localencodings[alphabet - 100] + : (alphabet == 120 ? + localencodings[CONT_ENC_END - 100 + 1] + : localencodings[0])); + + /* create output buffer */ + *(result) = malloc(len + 1); + if (!(*result)) + return NSERROR_NOMEM; + *(*result) = '\0'; + + prev_off = 0; + cur_pos = (*result); + + /* Iterate over string, converting input between unconvertable + * characters and inserting appropriate output for characters + * that iconv can't handle. */ + for (off = 0; off < len; off = utf8_next(string, len, off)) { + if (string[off] != 0xE2 && + string[off] != 0xC5 && string[off] != 0xEF) + continue; + + for (i = 0; i != NOF_ELEMENTS(special_chars); i++) { + if (strncmp(string + off, special_chars[i].utf, + special_chars[i].len) != 0) + continue; + + /* 0 length has a special meaning to utf8_to_enc */ + if (off - prev_off > 0) { + err = utf8_to_enc(string + prev_off, enc, + off - prev_off, &temp); + if (err != NSERROR_OK) { + assert(err != NSERROR_BAD_ENCODING); + free(*result); + return NSERROR_NOMEM; + } + + strcat(cur_pos, temp); + + cur_pos += strlen(temp); + + free(temp); + } + + *cur_pos = special_chars[i].local; + *(++cur_pos) = '\0'; + prev_off = off + special_chars[i].len; + } + } + + /* handle last chunk + * NB. 0 length has a special meaning to utf8_to_enc */ + + if (prev_off < len) { + err = utf8_to_enc(string + prev_off, enc, len - prev_off, + &temp); + if (err != NSERROR_OK) { + assert(err != NSERROR_BAD_ENCODING); + free(*result); + return NSERROR_NOMEM; + } + + strcat(cur_pos, temp); + + free(temp); + } + + return NSERROR_OK; +} + +/** + * Convert a string encoded in the system local encoding to UTF-8 + * + * \param string The string to convert + * \param len The length (in bytes) of the string, or 0 + * \param result Pointer to location in which to store result + * \return An nserror code + */ +nserror utf8_from_local_encoding(const char *string, size_t len, char **result) +{ + os_error *error; + int alphabet, i, num_specials = 0, result_alloc; +#define SPECIAL_CHUNK_SIZE 255 + size_t off, prev_off, cur_off; + char *temp; + const char *enc; + nserror err; + + assert(string && result); + + /* get length, if necessary */ + if (len == 0) + len = strlen(string); + + /* read system alphabet */ + error = xosbyte1(osbyte_ALPHABET_NUMBER, 127, 0, &alphabet); + if (error) + alphabet = territory_ALPHABET_LATIN1; + + /* UTF-8 -> simply copy string */ + if (alphabet == 111 /* UTF-8 */) { + temp = strndup(string, len); + if (!temp) + return NSERROR_NOMEM; + + *result = temp; + return NSERROR_OK; + } + + /* get encoding name */ + enc = (alphabet <= CONT_ENC_END ? localencodings[alphabet - 100] + : (alphabet == 120 ? + localencodings[CONT_ENC_END - 100 + 1] + : localencodings[0])); + + /* create output buffer (oversized) */ + result_alloc = (len * 4) + (3 * SPECIAL_CHUNK_SIZE) + 1; + + *(result) = malloc(result_alloc); + if (!(*result)) + return NSERROR_NOMEM; + *(*result) = '\0'; + + prev_off = 0; + cur_off = 0; + + /* Iterate over string, converting input between unconvertable + * characters and inserting appropriate output for characters + * that iconv can't handle. */ + for (off = 0; off < len; off++) { + if (string[off] < 0x80 || string[off] > 0x9f) + continue; + + for (i = 0; i != NOF_ELEMENTS(special_chars); i++) { + if (string[off] != special_chars[i].local) + continue; + + /* 0 length has a special meaning to utf8_from_enc */ + if (off - prev_off > 0) { + err = utf8_from_enc(string + prev_off, enc, + off - prev_off, &temp, NULL); + if (err != NSERROR_OK) { + assert(err != NSERROR_BAD_ENCODING); + LOG("utf8_from_enc failed"); + free(*result); + return NSERROR_NOMEM; + } + + strcat((*result) + cur_off, temp); + + cur_off += strlen(temp); + + free(temp); + } + + strcat((*result) + cur_off, special_chars[i].utf); + + cur_off += special_chars[i].len; + + prev_off = off + 1; + + num_specials++; + if (num_specials % SPECIAL_CHUNK_SIZE == + SPECIAL_CHUNK_SIZE - 1) { + char *temp = realloc((*result), + result_alloc + + (3 * SPECIAL_CHUNK_SIZE)); + if (!temp) { + free(*result); + return NSERROR_NOMEM; + } + + *result = temp; + result_alloc += (3 * SPECIAL_CHUNK_SIZE); + } + } + } + + /* handle last chunk + * NB. 0 length has a special meaning to utf8_from_enc */ + if (prev_off < len) { + err = utf8_from_enc(string + prev_off, enc, len - prev_off, + &temp, NULL); + if (err != NSERROR_OK) { + assert(err != NSERROR_BAD_ENCODING); + LOG("utf8_from_enc failed"); + free(*result); + return NSERROR_NOMEM; + } + + strcat((*result) + cur_off, temp); + + cur_off += strlen(temp); + + free(temp); + } + + /* and copy into more reasonably-sized buffer */ + temp = realloc((*result), cur_off + 1); + if (!temp) { + LOG("realloc failed"); + free(*result); + return NSERROR_NOMEM; + } + *result = temp; + + return NSERROR_OK; +} + +static struct gui_utf8_table utf8_table = { + .utf8_to_local = utf8_to_local_encoding, + .local_to_utf8 = utf8_from_local_encoding, +}; + +struct gui_utf8_table *riscos_utf8_table = &utf8_table; diff --git a/frontends/riscos/ucstables.h b/frontends/riscos/ucstables.h new file mode 100644 index 000000000..e5d838249 --- /dev/null +++ b/frontends/riscos/ucstables.h @@ -0,0 +1,29 @@ +/* + * Copyright 2005 John M Bell <jmb202@ecs.soton.ac.uk> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * UCS conversion tables (interface) + * This is only used if nothing claims Service_International,8 + */ + +struct gui_utf8_table *riscos_utf8_table; + +nserror utf8_to_local_encoding(const char *string, size_t len, char **result); +nserror utf8_from_local_encoding(const char *string, size_t len, char **result); + +const int *ucstable_from_alphabet(int alphabet); diff --git a/frontends/riscos/uri.c b/frontends/riscos/uri.c new file mode 100644 index 000000000..9c384c9c0 --- /dev/null +++ b/frontends/riscos/uri.c @@ -0,0 +1,139 @@ +/* + * Copyright 2003 Rob Jackson <jacko@xms.ms> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "utils/config.h" + +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "oslib/uri.h" +#include "oslib/wimp.h" + +#include "utils/log.h" +#include "utils/messages.h" +#include "utils/nsurl.h" +#include "content/fetch.h" +#include "desktop/browser.h" + +#include "riscos/gui.h" +#include "riscos/uri.h" +#include "riscos/url_protocol.h" + +void ro_uri_message_received(wimp_message *msg) +{ + uri_full_message_process *uri_message = (uri_full_message_process *)msg; + uri_h uri_handle; + char* uri_requested; + int uri_length; + nsurl *url; + nserror error; + + uri_handle = uri_message->handle; + + if (nsurl_create(uri_message->uri, &url) != NSERROR_OK) { + return; + } + + if (!fetch_can_fetch(url)) { + nsurl_unref(url); + return; + } + + nsurl_unref(url); + + uri_message->your_ref = uri_message->my_ref; + uri_message->action = message_URI_PROCESS_ACK; + + xwimp_send_message(wimp_USER_MESSAGE, (wimp_message*)uri_message, + uri_message->sender); + + xuri_request_uri(0, 0, 0, uri_handle, &uri_length); + uri_requested = calloc((unsigned int)uri_length, sizeof(char)); + if (uri_requested == NULL) + return; + + xuri_request_uri(0, uri_requested, uri_length, uri_handle, NULL); + + error = nsurl_create(uri_requested, &url); + free(uri_requested); + if (error == NSERROR_OK) { + error = browser_window_create(BW_CREATE_HISTORY, + url, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + if (error != NSERROR_OK) { + ro_warn_user(messages_get_errorcode(error), 0); + } +} + +bool ro_uri_launch(const char *uri) +{ + uri_h uri_handle; + wimp_t handle_task; + uri_dispatch_flags returned; + os_error *e; + + e = xuri_dispatch(uri_DISPATCH_INFORM_CALLER, uri, task_handle, + &returned, &handle_task, &uri_handle); + + if (e || returned & 1) { + return false; + } + + return true; +} + +void ro_uri_bounce(wimp_message *msg) +{ + uri_full_message_process *message = (uri_full_message_process *)msg; + int size; + char *uri_buf; + os_error *e; + + if ((message->flags & 1) == 0) + return; + + /* Get required buffer size */ + e = xuri_request_uri(0, NULL, 0, message->handle, &size); + if (e) { + LOG("xuri_request_uri: %d: %s", e->errnum, e->errmess); + return; + } + + uri_buf = malloc(size); + if (uri_buf == NULL) + return; + + /* Get URI */ + e = xuri_request_uri(0, uri_buf, size, message->handle, 0); + if (e) { + LOG("xuri_request_uri: %d: %s", e->errnum, e->errmess); + free(uri_buf); + return; + } + + ro_url_load(uri_buf); + + free(uri_buf); + + return; +} diff --git a/frontends/riscos/uri.h b/frontends/riscos/uri.h new file mode 100644 index 000000000..d538ea914 --- /dev/null +++ b/frontends/riscos/uri.h @@ -0,0 +1,30 @@ +/* + * Copyright 2003 Rob Jackson <jacko@xms.ms> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _NETSURF_RISCOS_URI_H_ +#define _NETSURF_RISCOS_URI_H_ + +#include "utils/config.h" + +#include "oslib/wimp.h" + +void ro_uri_message_received(wimp_message *message); +bool ro_uri_launch(const char *uri); +void ro_uri_bounce(wimp_message *message); + +#endif diff --git a/frontends/riscos/url_complete.c b/frontends/riscos/url_complete.c new file mode 100644 index 000000000..3cf7f9228 --- /dev/null +++ b/frontends/riscos/url_complete.c @@ -0,0 +1,740 @@ +/* + * Copyright 2005 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * GUI URL auto-completion (implementation). + */ + +#include <assert.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <oslib/wimp.h> + +#include "utils/log.h" +#include "utils/nsoption.h" +#include "content/urldb.h" +#include "desktop/browser.h" + +#include "riscos/global_history.h" +#include "riscos/gui.h" +#include "riscos/mouse.h" +#include "riscos/toolbar.h" +#include "riscos/url_complete.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" +#include "riscos/wimputils.h" +#include "riscos/filetype.h" + +#define MAXIMUM_VISIBLE_LINES 7 + +static nsurl **url_complete_matches = NULL; +static int url_complete_matches_allocated = 0; +static int url_complete_matches_available = 0; +static char *url_complete_matched_string = NULL; +static int url_complete_matches_selection = -1; +static int url_complete_keypress_selection = -1; +static wimp_w url_complete_parent = 0; +static bool url_complete_matches_reset = false; +static char *url_complete_original_url = NULL; +static bool url_complete_memory_exhausted = false; + +static nsurl *url_complete_redraw[MAXIMUM_VISIBLE_LINES]; +static char url_complete_icon_null[] = ""; +static char url_complete_icon_sprite[12]; +static wimp_icon url_complete_icon; +static wimp_icon url_complete_sprite; +static int mouse_x; +static int mouse_y; + +static bool url_complete_callback(nsurl *url, + const struct url_data *data); +static void ro_gui_url_complete_mouse_at(wimp_pointer *pointer, void *data); + + +/* This is an exported interface documented in url_complete.h */ + +void ro_gui_url_complete_start(struct toolbar *toolbar) +{ + const char *url; + wimp_w parent; + + assert(toolbar != NULL); + parent = ro_toolbar_get_parent_window(toolbar); + + if (!ro_toolbar_get_display_url(toolbar) || + (parent == url_complete_parent)) + return; + + ro_gui_url_complete_close(); + url = ro_toolbar_get_url(toolbar); + if (url != NULL) { + url_complete_matched_string = strdup(url); + if (url_complete_matched_string) + url_complete_parent = parent; + } +} + + +/* This is an exported interface documented in url_complete.h */ + +bool ro_gui_url_complete_keypress(struct toolbar *toolbar, uint32_t key) +{ + wimp_w parent; + wimp_window_state state; + char *match_url; + const char *url; + int old_selection; + int height; + os_error *error; + bool currently_open; + + assert(toolbar != NULL); + parent = ro_toolbar_get_parent_window(toolbar); + + /* we must have a toolbar/url bar */ + if (!ro_toolbar_get_display_url(toolbar) || + (!nsoption_bool(url_suggestion))) { + ro_gui_url_complete_close(); + return false; + } + + /* if we are currently active elsewhere, remove the previous window */ + currently_open = ((parent == url_complete_parent) && + (url_complete_matches_available > 0)); + if (parent != url_complete_parent) + ro_gui_url_complete_close(); + + /* forcibly open on down keys */ + if ((!currently_open) && (url_complete_matched_string)) { + switch (key) { + case IS_WIMP_KEY | wimp_KEY_DOWN: + case IS_WIMP_KEY | wimp_KEY_PAGE_DOWN: + case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_DOWN: + free(url_complete_matched_string); + url_complete_matched_string = NULL; + } + } + + + /* get the text to match */ + url_complete_parent = parent; + url = ro_toolbar_get_url(toolbar); + match_url = (url != NULL) ? strdup(url) : NULL; + if (match_url == NULL) { + ro_gui_url_complete_close(); + return false; + } + + /* if the text to match has changed then update it */ + if ((!url_complete_matched_string) || + (strcmp(match_url, url_complete_matched_string))) { + + /* memorize the current matches */ + int i; + int lines = MAXIMUM_VISIBLE_LINES; + if (lines > url_complete_matches_available) + lines = url_complete_matches_available; + if (url_complete_matches) { + for (i = 0; i < MAXIMUM_VISIBLE_LINES; i++) { + if (i < lines) { + url_complete_redraw[i] = + url_complete_matches[i]; + } else { + url_complete_redraw[i] = NULL; + } + } + } + + /* our selection gets wiped */ + error = xwimp_force_redraw(dialog_url_complete, + 0, + -(url_complete_matches_selection + 1) * 44, + 65536, -url_complete_matches_selection * 44); + if (error) { + LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + + /* clear our state */ + free(url_complete_original_url); + free(url_complete_matched_string); + url_complete_matched_string = match_url; + url_complete_original_url = NULL; + url_complete_matches_available = 0; + url_complete_matches_selection = -1; + url_complete_keypress_selection = -1; + + /* get some initial memory */ + if (!url_complete_matches) { + url_complete_matches = malloc(64 * sizeof(char *)); + if (!url_complete_matches) { + ro_gui_url_complete_close(); + return false; + } + url_complete_matches_allocated = 64; + } + + /* find matches */ + url_complete_memory_exhausted = false; + if (strlen(match_url) == 0) + urldb_iterate_entries(url_complete_callback); + else + urldb_iterate_partial(match_url, url_complete_callback); + if ((url_complete_memory_exhausted) || + (url_complete_matches_available == 0)) { + ro_gui_url_complete_close(); + return false; + } + + /* update the window */ + state.w = parent; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + url_complete_matches_reset = true; + ro_gui_url_complete_resize(toolbar, PTR_WIMP_OPEN(&state)); + url_complete_matches_reset = false; + + /* redraw the relevant bits of the window */ + lines = MAXIMUM_VISIBLE_LINES; + if (lines > url_complete_matches_available) + lines = url_complete_matches_available; + for (i = 0; i < lines; i++) { + if (url_complete_redraw[i] != + url_complete_matches[i]) { + error = xwimp_force_redraw(dialog_url_complete, + 0, -(i + 1) * 44, 65536, -i * 44); + if (error) { + LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", + error->errmess); + } + } + } + } else { + free(match_url); + } + + /* handle keypresses */ + if (!currently_open) + return false; + + old_selection = url_complete_matches_selection; + + switch (key) { + case IS_WIMP_KEY | wimp_KEY_UP: + url_complete_matches_selection--; + break; + case IS_WIMP_KEY | wimp_KEY_DOWN: + url_complete_matches_selection++; + break; + case IS_WIMP_KEY | wimp_KEY_PAGE_UP: + url_complete_matches_selection -= + MAXIMUM_VISIBLE_LINES; + break; + case IS_WIMP_KEY | wimp_KEY_PAGE_DOWN: + url_complete_matches_selection += + MAXIMUM_VISIBLE_LINES; + break; + case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_UP: + url_complete_matches_selection = 0; + break; + case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_DOWN: + url_complete_matches_selection = 65536; + break; + } + + if (url_complete_matches_selection > + url_complete_matches_available - 1) + url_complete_matches_selection = + url_complete_matches_available - 1; + else if (url_complete_matches_selection < -1) + url_complete_matches_selection = -1; + + if (old_selection == url_complete_matches_selection) + return false; + + error = xwimp_force_redraw(dialog_url_complete, + 0, -(old_selection + 1) * 44, + 65536, -old_selection * 44); + if (error) { + LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + + error = xwimp_force_redraw(dialog_url_complete, + 0, -(url_complete_matches_selection + 1) * 44, + 65536, -url_complete_matches_selection * 44); + if (error) { + LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + + if (old_selection == -1) { + free(url_complete_original_url); + url_complete_original_url = malloc(strlen(url) + 1); + if (!url_complete_original_url) + return false; + strcpy(url_complete_original_url, url); + } + + if (url_complete_matches_selection == -1) { + ro_toolbar_set_url(toolbar, + url_complete_original_url, true, false); + } else { + ro_toolbar_set_url(toolbar, + nsurl_access(url_complete_matches[ + url_complete_matches_selection]), + true, false); + free(url_complete_matched_string); + url_complete_matched_string = strdup(nsurl_access( + url_complete_matches[ + url_complete_matches_selection])); + } + url_complete_keypress_selection = url_complete_matches_selection; + + /* auto-scroll */ + state.w = dialog_url_complete; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return true; + } + + if (state.yscroll < -(url_complete_matches_selection * 44)) + state.yscroll = -(url_complete_matches_selection * 44); + height = state.visible.y1 - state.visible.y0; + if (state.yscroll - height > + -((url_complete_matches_selection + 1) * 44)) + state.yscroll = + -((url_complete_matches_selection + 1) * 44) + height; + + error = xwimp_open_window(PTR_WIMP_OPEN(&state)); + if (error) { + LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return true; + } + + return true; +} + + +/** + * Callback function for urldb_iterate_partial + * + * \param url URL which matches + * \param data Data associated with URL + * \return true to continue iteration, false otherwise + */ + +bool url_complete_callback(nsurl *url, const struct url_data *data) +{ + nsurl **array_extend; + + /* Ignore unvisited URLs */ + if (data->visits == 0) + return true; + + url_complete_matches_available++; + + if (url_complete_matches_available > + url_complete_matches_allocated) { + + array_extend = (nsurl **)realloc(url_complete_matches, + (url_complete_matches_allocated + 64) * + sizeof(nsurl *)); + if (!array_extend) { + url_complete_memory_exhausted = true; + return false; + } + url_complete_matches = array_extend; + url_complete_matches_allocated += 64; + } + + url_complete_matches[url_complete_matches_available - 1] = url; + + return true; +} + + +/* This is an exported interface documented in url_complete.h */ + +void ro_gui_url_complete_resize(struct toolbar *toolbar, wimp_open *open) +{ + os_box extent = { 0, 0, 0, 0 }; + os_box url_extent; + wimp_window_state toolbar_state; + wimp_window_state state; + os_error *error; + int lines; + int scroll_v = 0; + + /* only react to our window */ + if (open->w != url_complete_parent) + return; + + /* if there is no toolbar, or there is no URL bar shown, + * or there are no URL matches, close it */ + if (!ro_toolbar_get_display_url(toolbar) || + (!url_complete_matches) || + (url_complete_matches_available == 0)) { + ro_gui_url_complete_close(); + return; + } + + /* get our current auto-complete window state for the scroll values */ + state.w = dialog_url_complete; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + if (url_complete_matches_reset) + state.yscroll = 0; + + /* move the window to the correct position */ + toolbar_state.w = ro_toolbar_get_window(toolbar); + error = xwimp_get_window_state(&toolbar_state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + if (!ro_toolbar_get_url_field_extent(toolbar, &url_extent)) { + LOG("Failed to read URL field extent."); + return; + } + + lines = url_complete_matches_available; + extent.y0 = -(lines * 44); + extent.x1 = 65536; + error = xwimp_set_extent(dialog_url_complete, &extent); + if (error) { + LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + state.next = open->next; + state.flags &= ~wimp_WINDOW_VSCROLL; + state.flags &= ~(4095 << 16); /* clear bits 16-27 */ + if (lines > MAXIMUM_VISIBLE_LINES) { + lines = MAXIMUM_VISIBLE_LINES; + scroll_v = ro_get_vscroll_width(NULL) - 2; + state.flags |= wimp_WINDOW_VSCROLL; + } + state.visible.x0 = open->visible.x0 + 2 + url_extent.x0; + state.visible.x1 = open->visible.x0 - 2 + url_extent.x1 - scroll_v; + state.visible.y1 = open->visible.y1 - url_extent.y1 + 2; + state.visible.y0 = state.visible.y1 - (lines * 44); + if (state.visible.x1 + scroll_v > toolbar_state.visible.x1) + state.visible.x1 = toolbar_state.visible.x1 - scroll_v; + if (state.visible.x1 - state.visible.x0 < 0) { + error = xwimp_close_window(dialog_url_complete); + if (error) { + LOG("xwimp_close_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + } else { + error = xwimp_open_window_nested_with_flags(&state, + (wimp_w)-1, 0); + if (error) { + LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + open->next = dialog_url_complete; + } +} + + +/* This is an exported interface documented in url_complete.h */ + +bool ro_gui_url_complete_close(void) +{ + os_error *error; + bool currently_open; + + /* There used to be a check here to see if the icon clicked was the + * URL text field in the toolbar. Since this only applied to clicks + * originating from the toolbar module following the restructuring, + * and this check was better done within the toolbar, it has been + * removed from this function and the associated parameters removed. + */ + + currently_open = ((url_complete_parent != NULL) && + (url_complete_matches_available > 0)); + + free(url_complete_matches); + free(url_complete_matched_string); + free(url_complete_original_url); + url_complete_matches = NULL; + url_complete_matched_string = NULL; + url_complete_original_url = NULL; + url_complete_matches_allocated = 0; + url_complete_matches_available = 0; + url_complete_keypress_selection = -1; + url_complete_matches_selection = -1; + url_complete_parent = 0; + + error = xwimp_close_window(dialog_url_complete); + if (error) { + LOG("xwimp_close_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + + return currently_open; +} + + +/* This is an exported interface documented in url_complete.h */ + +void ro_gui_url_complete_redraw(wimp_draw *redraw) +{ + osbool more; + os_error *error; + int line; + const struct url_data *data; + int type; + + /* initialise our icon */ + url_complete_icon.flags = wimp_ICON_INDIRECTED | wimp_ICON_VCENTRED | + wimp_ICON_TEXT | wimp_ICON_FILLED | + (wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT) | + (wimp_COLOUR_WHITE << wimp_ICON_BG_COLOUR_SHIFT); + url_complete_icon.extent.x0 = 50; + url_complete_icon.extent.x1 = 16384; + url_complete_icon.data.indirected_text.validation = + url_complete_icon_null; + url_complete_sprite.flags = wimp_ICON_TEXT | wimp_ICON_SPRITE | + wimp_ICON_INDIRECTED | wimp_ICON_FILLED | + wimp_ICON_HCENTRED | wimp_ICON_VCENTRED; + url_complete_sprite.extent.x0 = 0; + url_complete_sprite.extent.x1 = 50; + url_complete_sprite.data.indirected_text.text = + url_complete_icon_null; + url_complete_sprite.data.indirected_text.validation = + url_complete_icon_sprite; + url_complete_sprite.data.indirected_text.size = 1; + + /* no matches? no redraw */ + if (!url_complete_matches) { + LOG("Attempt to redraw with no matches made"); + /* Fill is never used, so make it something obvious */ + ro_gui_user_redraw(redraw, false, os_COLOUR_BLACK); + return; + } + + /* redraw */ + more = wimp_redraw_window(redraw); + while (more) { + int first_line, last_line; + int origin_y = redraw->box.y1 - redraw->yscroll; + int clip_y0 = redraw->clip.y0 - origin_y; + int clip_y1 = redraw->clip.y1 - origin_y; + + first_line = (-clip_y1) / 44; + last_line = (-clip_y0 + 43) / 44; + + for (line = first_line; line < last_line; line++) { + if (line == url_complete_matches_selection) + url_complete_icon.flags |= + wimp_ICON_SELECTED; + else + url_complete_icon.flags &= + ~wimp_ICON_SELECTED; + url_complete_icon.extent.y1 = -line * 44; + url_complete_icon.extent.y0 = -(line + 1) * 44; + url_complete_icon.data.indirected_text.text = + (char *)nsurl_access( + url_complete_matches[line]); + url_complete_icon.data.indirected_text.size = + nsurl_length( + url_complete_matches[line]); + + error = xwimp_plot_icon(&url_complete_icon); + if (error) { + LOG("xwimp_plot_icon: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + + data = urldb_get_url_data(url_complete_matches[line]); + if (data) + type = ro_content_filetype_from_type( + data->type); + else + type = 0; + + sprintf(url_complete_icon_sprite, "Ssmall_%.3x", + type); + + if (!ro_gui_wimp_sprite_exists( + url_complete_icon_sprite + 1)) + sprintf(url_complete_icon_sprite, + "Ssmall_xxx"); + url_complete_sprite.extent.y1 = -line * 44; + url_complete_sprite.extent.y0 = -(line + 1) * 44; + error = xwimp_plot_icon(&url_complete_sprite); + if (error) { + LOG("xwimp_plot_icon: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + } + more = wimp_get_rectangle(redraw); + } +} + + +/* This is an exported interface documented in url_complete.h */ + +void ro_gui_url_complete_entering(wimp_entering *entering) +{ + ro_mouse_track_start(NULL, ro_gui_url_complete_mouse_at, NULL); +} + + +/** + * Handle mouse movement over the URL completion window. + * + * \param *pointer The pointer state + * \param *data NULL data pointer expected by mouse tracker + */ + +void ro_gui_url_complete_mouse_at(wimp_pointer *pointer, void *data) +{ + wimp_mouse_state current; + + current = pointer->buttons; + pointer->buttons = 0; + ro_gui_url_complete_click(pointer); + pointer->buttons = current; +} + + +/* This is an exported interface documented in url_complete.h */ + +bool ro_gui_url_complete_click(wimp_pointer *pointer) +{ + wimp_window_state state; + os_error *error; + int selection; + struct gui_window *g; + + if ((mouse_x == pointer->pos.x) && (mouse_y == pointer->pos.y) && + (!pointer->buttons)) + return false; + + mouse_x = pointer->pos.x; + mouse_y = pointer->pos.y; + + state.w = dialog_url_complete; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + + selection = (state.visible.y1 - pointer->pos.y - state.yscroll) / 44; + if (selection != url_complete_matches_selection) { + int old_selection; + + if (url_complete_matches_selection == -1) { + const char *url; + + g = ro_gui_window_lookup(url_complete_parent); + if (!g) + return false; + url = ro_toolbar_get_url(g->toolbar); + free(url_complete_original_url); + url_complete_original_url = strdup(url); + if (!url_complete_original_url) + return false; + } + old_selection = url_complete_matches_selection; + url_complete_matches_selection = selection; + error = xwimp_force_redraw(dialog_url_complete, + 0, -(old_selection + 1) * 44, + 65536, -old_selection * 44); + if (error) { + LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + error = xwimp_force_redraw(dialog_url_complete, + 0, -(url_complete_matches_selection + 1) * 44, + 65536, -url_complete_matches_selection * 44); + if (error) { + LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + } + if (!pointer->buttons) + return true; + + /* find owning window */ + g = ro_gui_window_lookup(url_complete_parent); + if (!g) + return false; + + /* Select sets the text and launches */ + if (pointer->buttons == wimp_CLICK_SELECT) { + ro_toolbar_set_url(g->toolbar, + nsurl_access(url_complete_matches[ + url_complete_matches_selection]), + true, false); + + /** \todo The interaction of components here is hideous */ + /* Do NOT make any attempt to use any of the global url + * completion variables after this call to browser_window_navigate. + * They will be invalidated by (at least): + * + ro_gui_window_set_url + * + destruction of (i)frames within the current page + * Any attempt to use them will probably result in a crash. + */ + + browser_window_navigate(g->bw, + url_complete_matches[url_complete_matches_selection], + NULL, + BW_NAVIGATE_HISTORY, + NULL, + NULL, + NULL); + + ro_gui_url_complete_close(); + + /* Adjust just sets the text */ + } else if (pointer->buttons == wimp_CLICK_ADJUST) { + ro_toolbar_set_url(g->toolbar, + nsurl_access(url_complete_matches[ + url_complete_matches_selection]), + true, false); + ro_gui_url_complete_keypress(g->toolbar, 0); + } + return true; +} + diff --git a/frontends/riscos/url_complete.h b/frontends/riscos/url_complete.h new file mode 100644 index 000000000..6a4660e4a --- /dev/null +++ b/frontends/riscos/url_complete.h @@ -0,0 +1,100 @@ +/* + * Copyright 2005 Richard Wilson <info@tinct.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Central repository for URL data (interface). + */ + +#ifndef _NETSURF_RISCOS_URLCOMPLETE_H_ +#define _NETSURF_RISCOS_URLCOMPLETE_H_ + +#include <inttypes.h> +#include <stdbool.h> +#include "oslib/wimp.h" + +struct gui_window; + +/** + * Should be called when the caret is placed into a URL completion icon. + * + * \param *toolbar The toolbar to initialise URL completion for. + */ + +void ro_gui_url_complete_start(struct toolbar *toolbar); + + +/** + * Handles a keypress for URL completion + * + * \param *toolbar The toolbar to be updated. + * \param key the key pressed (as UTF32 code or + * wimp key + bit31 set) + * \return true to indicate keypress handled; else false. + */ + +bool ro_gui_url_complete_keypress(struct toolbar *toolbar, uint32_t key); + + +/** + * Move and resize the url completion window to match the toolbar. + * + * \param *toolbar The toolbar to update + * \param *open the wimp_open request (updated on exit) + */ + +void ro_gui_url_complete_resize(struct toolbar *toolbar, wimp_open *open); + + +/** + * Try to close the current url completion window + * + * \return whether the window was closed + */ + +bool ro_gui_url_complete_close(void); + + +/** + * Redraws a section of the URL completion window + * + * \param redraw the area to redraw + */ + +void ro_gui_url_complete_redraw(wimp_draw *redraw); + + +/** + * Handle the pointer entering the URL completion window. + * + * \param *entering The pointer entering data block. + */ + +void ro_gui_url_complete_entering(wimp_entering *entering); + + +/** + * Handle mouse clicks in the URL completion window. + * + * \param pointer the pointer state + * \return whether the click was handled + */ + +bool ro_gui_url_complete_click(wimp_pointer *pointer); + +#endif + diff --git a/frontends/riscos/url_protocol.c b/frontends/riscos/url_protocol.c new file mode 100644 index 000000000..2b9ef3556 --- /dev/null +++ b/frontends/riscos/url_protocol.c @@ -0,0 +1,226 @@ +/* + * Copyright 2003 John M Bell <jmb202@ecs.soton.ac.uk> + * Copyright 2003 Rob Jackson <jacko@xms.ms> + * Copyright 2004 James Bursa <bursa@users.sourceforge.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * ANT URL launching protocol (implementation). + * + * See http://www.vigay.com/inet/inet_url.html + */ + +#include "utils/config.h" + +#include <ctype.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <oslib/inetsuite.h> +#include <oslib/wimp.h> + +#include "utils/log.h" +#include "utils/messages.h" +#include "utils/nsurl.h" +#include "utils/config.h" +#include "content/fetch.h" +#include "desktop/browser.h" + +#include "riscos/gui.h" +#include "riscos/uri.h" +#include "riscos/url_protocol.h" + +/** + * Handle a Message_InetSuiteOpenURL. + */ + +void ro_url_message_received(wimp_message *message) +{ + char *url; + int i; + inetsuite_message_open_url *url_message = + (inetsuite_message_open_url*) &message->data; + os_error *error; + nsurl *nsurl; + nserror errorns; + + /* If the url_message->indirect.tag is non-zero, + * then the message data is contained within the message block. + */ + if (url_message->indirect.tag != 0) { + url = strndup(url_message->url, 236); + if (!url) { + ro_warn_user("NoMemory", 0); + return; + } + /* terminate at first control character */ + for (i = 0; !iscntrl(url[i]); i++) + ; + url[i] = 0; + + } else { + if (!url_message->indirect.url.offset) { + LOG("no URL in message"); + return; + } + if (28 < message->size && + url_message->indirect.body_file.offset) { + LOG("POST for URL message not implemented"); + return; + } + if (url_message->indirect.url.offset < 28 || + 236 <= url_message->indirect.url.offset) { + LOG("external pointers in URL message unimplemented"); + /* these messages have never been seen in the wild, + * and there is the problem of invalid addresses which + * would cause an abort */ + return; + } + + url = strndup((char *) url_message + + url_message->indirect.url.offset, + 236 - url_message->indirect.url.offset); + if (!url) { + ro_warn_user("NoMemory", 0); + return; + } + for (i = 0; !iscntrl(url[i]); i++) + ; + url[i] = 0; + } + + if (nsurl_create(url, &nsurl) != NSERROR_OK) { + free(url); + return; + } + + if (!fetch_can_fetch(nsurl)) { + nsurl_unref(nsurl); + free(url); + return; + } + + free(url); + + /* send ack */ + message->your_ref = message->my_ref; + error = xwimp_send_message(wimp_USER_MESSAGE_ACKNOWLEDGE, message, + message->sender); + if (error) { + LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + + /* create new browser window */ + errorns = browser_window_create(BW_CREATE_HISTORY, + nsurl, + NULL, + NULL, + NULL); + + + nsurl_unref(nsurl); + if (errorns != NSERROR_OK) { + ro_warn_user(messages_get_errorcode(errorns), 0); + } +} + + +/** + * Broadcast an ANT URL message. + */ + +void ro_url_broadcast(const char *url) +{ + inetsuite_full_message_open_url_direct message; + os_error *error; + int len = strlen(url) + 1; + + /* If URL is too long, then forget ANT and try URI, instead */ + if (236 < len) { + ro_uri_launch(url); + return; + } + + message.size = ((20+len+3) & ~3); + message.your_ref = 0; + message.action = message_INET_SUITE_OPEN_URL; + strncpy(message.url, url, 235); + message.url[235] = 0; + error = xwimp_send_message(wimp_USER_MESSAGE_RECORDED, + (wimp_message *) &message, 0); + if (error) { + LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } +} + + +/** + * Launch a program to handle an URL, using the ANT protocol + * Alias$URLOpen_ system. + */ + +void ro_url_load(const char *url) +{ + char *command; + char *colon; + os_error *error; + + colon = strchr(url, ':'); + if (!colon) { + LOG("invalid url '%s'", url); + return; + } + + command = malloc(40 + (colon - url) + strlen(url)); + if (!command) { + ro_warn_user("NoMemory", 0); + return; + } + + sprintf(command, "Alias$URLOpen_%.*s", (int) (colon - url), url); + if (!getenv(command)) { + free(command); + return; + } + + sprintf(command, "URLOpen_%.*s %s", (int) (colon - url), url, url); + + error = xwimp_start_task(command, 0); + if (error) { + LOG("xwimp_start_task: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + + free(command); +} + + +/** + * Handle a bounced Message_InetSuiteOpenURL. + */ + +void ro_url_bounce(wimp_message *message) +{ + inetsuite_message_open_url *url_message = + (inetsuite_message_open_url*) &message->data; + + /* ant broadcast bounced -> try uri broadcast / load */ + ro_uri_launch(url_message->url); +} + diff --git a/frontends/riscos/url_protocol.h b/frontends/riscos/url_protocol.h new file mode 100644 index 000000000..c066981f7 --- /dev/null +++ b/frontends/riscos/url_protocol.h @@ -0,0 +1,35 @@ +/* + * Copyright 2003 John M Bell <jmb202@ecs.soton.ac.uk> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * ANT URL launching protocol (interface). + */ + +#ifndef _NETSURF_RISCOS_URL_H_ +#define _NETSURF_RISCOS_URL_H_ + +#include "utils/config.h" + +#include "oslib/wimp.h" + +void ro_url_message_received(wimp_message *message); +void ro_url_broadcast(const char *url); +void ro_url_load(const char *url); +void ro_url_bounce(wimp_message *message); + +#endif diff --git a/frontends/riscos/url_suggest.c b/frontends/riscos/url_suggest.c new file mode 100644 index 000000000..3f6b6b54d --- /dev/null +++ b/frontends/riscos/url_suggest.c @@ -0,0 +1,239 @@ +/* + * Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * URL Suggestion Menu (implementation). + */ + +#include <assert.h> +#include <string.h> +#include <stdlib.h> + +#include "oslib/wimp.h" +#include "content/content_type.h" +#include "content/urldb.h" + +#include "riscos/menus.h" +#include "riscos/url_suggest.h" +#include "utils/messages.h" + +struct url_suggest_item { + const char *url; /*< The URL being stored. */ + unsigned int weight; /*< A weight assigned to the URL. */ + struct url_suggest_item *next; /*< The next URL in the list. */ +}; + +static bool ro_gui_url_suggest_callback(nsurl *url, + const struct url_data *data); + +static int suggest_entries; +static time_t suggest_time; +static struct url_suggest_item *suggest_list; + +static wimp_MENU(URL_SUGGEST_MAX_URLS) url_suggest_menu_block; +wimp_menu *ro_gui_url_suggest_menu = (wimp_menu *) &url_suggest_menu_block; + + +/** + * Initialise the URL suggestion menu. This MUST be called before anything + * tries to use the URL menu. + * + * \return true if initialisation was OK; else false. + */ + +bool ro_gui_url_suggest_init(void) +{ + ro_gui_url_suggest_menu->title_data.indirected_text.text = + (char *) messages_get("URLSuggest"); + ro_gui_menu_init_structure((wimp_menu *) ro_gui_url_suggest_menu, + URL_SUGGEST_MAX_URLS); + + suggest_entries = 0; + + return true; +} + + +/** + * Check if there is a URL suggestion menu available for use. + * + * \todo Ideally this should be able to decide if there's a menu + * available without actually having to build it all. + * + * \return true if the menu has entries; else false. + */ + +bool ro_gui_url_suggest_get_menu_available(void) +{ + return ro_gui_url_suggest_prepare_menu(); +} + + +/** + * Builds the URL suggestion menu. This is called by ro_gui_menu_create() when + * it is asked to display the url_suggest_menu. + * + * /return true if the menu has entries; else false. + */ + +bool ro_gui_url_suggest_prepare_menu(void) +{ + struct url_suggest_item *list, *next; + + /* Fetch the URLs we want to include from URLdb. */ + + suggest_entries = 0; + suggest_list = NULL; + suggest_time = time(NULL); + + urldb_iterate_entries(ro_gui_url_suggest_callback); + + /* If any menu entries were found, put them into the menu. The list + * is in reverse order, last to first, so the menu is filled backwards. + * Entries from the list are freed as we go. + */ + + assert(suggest_entries <= URL_SUGGEST_MAX_URLS); + + if (suggest_entries > 0) { + int i = suggest_entries; + + list = suggest_list; + suggest_list = NULL; + + while (list != NULL && i > 0) { + i--; + + ro_gui_url_suggest_menu->entries[i].menu_flags = 0; + ro_gui_url_suggest_menu-> + entries[i].data.indirected_text.text = + (char *) list->url; + ro_gui_url_suggest_menu-> + entries[i].data.indirected_text.size = + strlen(list->url) + 1; + + next = list->next; + free(list); + list = next; + } + + assert(i == 0); + + ro_gui_url_suggest_menu->entries[0].menu_flags |= + wimp_MENU_TITLE_INDIRECTED; + ro_gui_url_suggest_menu-> + entries[suggest_entries - 1].menu_flags |= + wimp_MENU_LAST; + + return true; + } + + return false; +} + + +/** + * Callback function for urldb_iterate_entries + * + * \param url URL which matches + * \param data Data associated with URL + * \return true to continue iteration, false otherwise + */ + +bool ro_gui_url_suggest_callback(nsurl *url, const struct url_data *data) +{ + int count; + unsigned int weight; + struct url_suggest_item **list, *new; + + /* Ignore unvisited URLs, and those that don't apply to HTML or Text. */ + + if (data->visits == 0 || (data->type != CONTENT_HTML && + data->type != CONTENT_TEXTPLAIN)) + return true; + + /* Calculate a weight for the URL. */ + + weight = (suggest_time - data->last_visit) / data->visits; + + /* Hunt through those URLs already found to see if we want to add + * this one. Smaller weights carry higher priority. + * + * The list is sorted into reverse order, so that lowest weight + * items are nearest the head. Therefore, items are dropped from + * the head, making things simpler. + */ + + list = &suggest_list; + count = 0; + + while (*list != NULL && weight < (*list)->weight) { + list = &((*list)->next); + count++; + } + + if (count > 0 || suggest_entries < URL_SUGGEST_MAX_URLS) { + new = (struct url_suggest_item *) + malloc(sizeof(struct url_suggest_item)); + + if (new != NULL) { + suggest_entries++; + /* TODO: keeping pointers to URLdb data is bad. + * should be nsurl_ref(url) or + * take a copy of the string. */ + new->url = nsurl_access(url); + new->weight = weight; + new->next = *list; + + *list = new; + } + } + + /* If adding the URL gave us too many menu items, drop the lowest + * priority ones until the list is the right length again. + */ + + while (suggest_list != NULL && suggest_entries > URL_SUGGEST_MAX_URLS) { + struct url_suggest_item *old = suggest_list; + suggest_list = suggest_list->next; + + free(old); + suggest_entries--; + } + + return true; +} + + +/** + * Process a selection from the URL Suggest menu. + * + * \param *selection The menu selection. + * \return Pointer to the URL that was selected, or NULL for none. + */ + +const char *ro_gui_url_suggest_get_selection(wimp_selection *selection) +{ + const char *url = NULL; + + if (selection->items[0] >= 0) + url = ro_gui_url_suggest_menu->entries[selection->items[0]]. + data.indirected_text.text; + + return url; +} diff --git a/frontends/riscos/url_suggest.h b/frontends/riscos/url_suggest.h new file mode 100644 index 000000000..738cb9bf7 --- /dev/null +++ b/frontends/riscos/url_suggest.h @@ -0,0 +1,38 @@ +/* + * Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * URL Suggestion Menu (interface). + */ + +#ifndef _NETSURF_RISCOS_URL_SUGGEST_H_ +#define _NETSURF_RISCOS_URL_SUGGEST_H_ + +#include "oslib/wimp.h" + +#define URL_SUGGEST_MAX_URLS 16 + +extern wimp_menu *ro_gui_url_suggest_menu; + +bool ro_gui_url_suggest_init(void); +bool ro_gui_url_suggest_get_menu_available(void); +bool ro_gui_url_suggest_prepare_menu(void); +const char *ro_gui_url_suggest_get_selection(wimp_selection *selection); + +#endif + diff --git a/frontends/riscos/wimp.c b/frontends/riscos/wimp.c new file mode 100644 index 000000000..2579c672e --- /dev/null +++ b/frontends/riscos/wimp.c @@ -0,0 +1,1134 @@ +/* + * Copyright 2004, 2005 Richard Wilson <info@tinct.net> + * Copyright 2008 John Tytgat <joty@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * General RISC OS WIMP/OS library functions (implementation). + */ + +#include <assert.h> +#include <locale.h> +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include "oslib/colourtrans.h" +#include "oslib/os.h" +#include "oslib/osfile.h" +#include "oslib/wimp.h" +#include "oslib/wimpextend.h" +#include "oslib/wimpspriteop.h" + +#include "utils/log.h" +#include "utils/utf8.h" + +#include "riscos/gui.h" +#include "riscos/oslib_pre7.h" +#include "riscos/wimp.h" +#include "riscos/ucstables.h" + + +static void ro_gui_wimp_cache_furniture_sizes(wimp_w w); +static size_t ro_gui_strlen(const char *str); +static int ro_gui_strncmp(const char *s1, const char *s2, size_t len); + +static wimpextend_furniture_sizes furniture_sizes; +static wimp_w furniture_window = NULL; + +/** + * Gets the horizontal scrollbar height + * + * \param w the window to read (or NULL to read a cached value) + */ +int ro_get_hscroll_height(wimp_w w) +{ + ro_gui_wimp_cache_furniture_sizes(w); + return furniture_sizes.border_widths.y0; +} + + +/** + * Gets the vertical scrollbar width + * + * \param w the window to read (or NULL to read a cached value) + */ +int ro_get_vscroll_width(wimp_w w) +{ + ro_gui_wimp_cache_furniture_sizes(w); + return furniture_sizes.border_widths.x1; +} + + +/** + * Gets the title bar height + * + * \param w the window to read (or NULL to read a cached value) + */ +int ro_get_title_height(wimp_w w) +{ + ro_gui_wimp_cache_furniture_sizes(w); + return furniture_sizes.border_widths.y1; +} + +/** + * Caches window furniture information + * + * \param w the window to cache information from + * \return true on success, false on error (default values cached) + */ +void ro_gui_wimp_cache_furniture_sizes(wimp_w w) +{ + os_error *error; + + if (furniture_window == w) + return; + furniture_window = w; + furniture_sizes.w = w; + furniture_sizes.border_widths.y0 = 40; + furniture_sizes.border_widths.x1 = 40; + error = xwimpextend_get_furniture_sizes(&furniture_sizes); + if (error) { + LOG("xwimpextend_get_furniture_sizes: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } +} + + +/** + * Reads a modes EIG factors. + * + * \param[in] mode mode to read EIG factors for, or -1 for current + * \param[out] xeig The x eig value + * \param[out] yeig The y eig value + * \return true on success else false. + */ +bool ro_gui_wimp_read_eig_factors(os_mode mode, int *xeig, int *yeig) +{ + os_error *error; + + error = xos_read_mode_variable(mode, os_MODEVAR_XEIG_FACTOR, xeig, 0); + if (error) { + LOG("xos_read_mode_variable: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MiscError", error->errmess); + return false; + } + error = xos_read_mode_variable(mode, os_MODEVAR_YEIG_FACTOR, yeig, 0); + if (error) { + LOG("xos_read_mode_variable: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MiscError", error->errmess); + return false; + } + return true; +} + + +/** + * Converts the supplied os_coord from OS units to pixels. + * + * \param os_units values to convert + * \param mode mode to use EIG factors for, or -1 for current + */ +void ro_convert_os_units_to_pixels(os_coord *os_units, os_mode mode) +{ + int xeig = 1, yeig = 1; + + ro_gui_wimp_read_eig_factors(mode, &xeig, &yeig); + os_units->x = ((os_units->x + (1 << xeig) - 1) >> xeig); + os_units->y = ((os_units->y + (1 << yeig) - 1) >> yeig); +} + + +/** + * Converts the supplied os_coord from pixels to OS units. + * + * \param pixels values to convert + * \param mode mode to use EIG factors for, or -1 for current + */ +void ro_convert_pixels_to_os_units(os_coord *pixels, os_mode mode) +{ + int xeig = 1, yeig = 1; + + ro_gui_wimp_read_eig_factors(mode, &xeig, &yeig); + pixels->x = (pixels->x << xeig); + pixels->y = (pixels->y << yeig); +} + + +/** + * Redraws an icon + * + * \param w window handle + * \param i icon handle + */ + +#define ro_gui_redraw_icon(w, i) xwimp_set_icon_state(w, i, 0, 0) + + +/** + * Forces an icon to be redrawn entirely (ie not just updated). + * + * \param w window handle + * \param i icon handle + */ +void ro_gui_force_redraw_icon(wimp_w w, wimp_i i) +{ + wimp_icon_state ic; + os_error *error; + + /* Get the icon data + */ + ic.w = w; + ic.i = i; + error = xwimp_get_icon_state(&ic); + if (error) { + LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + error = xwimp_force_redraw(w, ic.icon.extent.x0, ic.icon.extent.y0, + ic.icon.extent.x1, ic.icon.extent.y1); + if (error) { + LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } +} + + +/** + * Read the contents of a text or sprite icon. + * + * \param w window handle + * \param i icon handle + * \return NUL terminated string in icon + * + * If the icon contains direct text then the returned data will + * be invalidated by the next call to this function. Therefore, + * all client calls to this function must either copy the string or + * ensure that this function is not called again until they are + * finished with the string data returned. + * + * \todo this doesn't do local encoding -> UTF-8 to match what is done in + * ro_gui_set_icon_string. + */ +const char *ro_gui_get_icon_string(wimp_w w, wimp_i i) +{ + static wimp_icon_state ic; + os_error *error; + char *itext; + + ic.w = w; + ic.i = i; + error = xwimp_get_icon_state(&ic); + if (error) { + LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return NULL; + } + itext = (ic.icon.flags & wimp_ICON_INDIRECTED) + ? ic.icon.data.indirected_text.text : ic.icon.data.text; + /* Guarantee NUL termination. */ + itext[ro_gui_strlen(itext)] = '\0'; + + return itext; +} + + +/** + * Set the contents of a text or sprite icon to a string. + * + * \param w window handle + * \param i icon handle + * \param text NUL terminated string (copied) + * \param is_utf8 When true, the given string is UTF-8 encoded and will be + * converted to local encoding currently used by the Wimp. When false, the + * given string is assumed to be in local encoding in use by the Wimp. + */ +void ro_gui_set_icon_string(wimp_w w, wimp_i i, const char *text, bool is_utf8) +{ + wimp_caret caret; + wimp_icon_state ic; + os_error *error; + size_t old_len, new_len; + char *local_text = NULL; + const char *text_for_icon; + char *dst_text; + size_t dst_max_len; + unsigned int button_type; + + if (is_utf8) { + nserror err; + /* convert text to local encoding */ + err = utf8_to_local_encoding(text, 0, &local_text); + if (err != NSERROR_OK) { + /* A bad encoding should never happen, so assert this */ + assert(err != NSERROR_BAD_ENCODING); + LOG("utf8_to_enc failed"); + /* Paranoia */ + local_text = NULL; + } + text_for_icon = local_text ? local_text : text; + } + else + text_for_icon = text; + new_len = strlen(text_for_icon); + + /* get the icon data */ + ic.w = w; + ic.i = i; + error = xwimp_get_icon_state(&ic); + if (error) { + LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + goto exit; + } + + if (ic.icon.flags & wimp_ICON_INDIRECTED) { + dst_text = ic.icon.data.indirected_text.text; + dst_max_len = ic.icon.data.indirected_text.size; + } + else { + dst_text = ic.icon.data.text; + dst_max_len = sizeof(ic.icon.data.text); + } + old_len = ro_gui_strlen(dst_text); + assert(old_len < dst_max_len); + + /* check that the existing text is not the same as the updated text + * to stop flicker */ + if (dst_max_len) { + if (!ro_gui_strncmp(dst_text, text_for_icon, dst_max_len)) + goto exit; + + /* copy the text across */ + strncpy(dst_text, text_for_icon, dst_max_len - 1); + dst_text[dst_max_len - 1] = '\0'; + + /* handle the caret being in the icon */ + button_type = (ic.icon.flags & wimp_ICON_BUTTON_TYPE) + >> wimp_ICON_BUTTON_TYPE_SHIFT; + if ((button_type == wimp_BUTTON_WRITABLE) || + (button_type == wimp_BUTTON_WRITE_CLICK_DRAG)) { + error = xwimp_get_caret_position(&caret); + if (error) { + LOG("xwimp_get_caret_position: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + goto exit; + } + if ((caret.w == w) && (caret.i == i)) { + if ((size_t)caret.index > new_len + || (size_t)caret.index == old_len) + caret.index = new_len; + error = xwimp_set_caret_position(w, i, caret.pos.x, + caret.pos.y, -1, caret.index); + if (error) { + LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + } + } + ro_gui_redraw_icon(w, i); + } + +exit: + free(local_text); +} + + +/** + * Set the contents of an icon to a number. + * + * \param w window handle + * \param i icon handle + * \param value value + */ +void ro_gui_set_icon_integer(wimp_w w, wimp_i i, int value) +{ + char buffer[20]; // Big enough for 64-bit int + + setlocale(LC_NUMERIC, ""); + + sprintf(buffer, "%d", value); + + setlocale(LC_NUMERIC, "C"); + + ro_gui_set_icon_string(w, i, buffer, true); +} + + +/** + * Set the contents of an icon to a number. + * + * \param w window handle + * \param i icon handle + * \param value value to use in icon. + * \param decimal_places The number of decimal places to use. + */ +void ro_gui_set_icon_decimal(wimp_w w, wimp_i i, int value, int decimal_places) +{ + char buffer[20]; // Big enough for 64-bit int + + setlocale(LC_NUMERIC, ""); + + switch (decimal_places) { + case 0: + sprintf(buffer, "%d", value); + break; + case 1: + sprintf(buffer, "%.1f", (float)value / 10); + break; + case 2: + sprintf(buffer, "%.2f", (float)value / 100); + break; + default: + assert(!"Unsupported decimal format"); + break; + } + + setlocale(LC_NUMERIC, "C"); + + ro_gui_set_icon_string(w, i, buffer, true); +} + + +/** + * Get the contents of an icon as a number. + * + * \param w window handle + * \param i icon handle + * \param decimal_places number of places to show. + * \return value used. + */ +int ro_gui_get_icon_decimal(wimp_w w, wimp_i i, int decimal_places) +{ + double value; + int multiple = 1; + + for (; decimal_places > 0; decimal_places--) + multiple *= 10; + + setlocale(LC_NUMERIC, ""); + + value = atof(ro_gui_get_icon_string(w, i)) * multiple; + + setlocale(LC_NUMERIC, "C"); + + return (int)value; +} + + +/** + * Set the selected state of an icon. + * + * \param w window handle + * \param i icon handle + * \param state selected state + */ +void ro_gui_set_icon_selected_state(wimp_w w, wimp_i i, bool state) +{ + os_error *error; + if (ro_gui_get_icon_selected_state(w, i) == state) return; + error = xwimp_set_icon_state(w, i, + (state ? wimp_ICON_SELECTED : 0), wimp_ICON_SELECTED); + if (error) { + LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } +} + +/** + * Gets the selected state of an icon. + * + * \param w window handle + * \param i icon handle + */ +bool ro_gui_get_icon_selected_state(wimp_w w, wimp_i i) +{ + os_error *error; + wimp_icon_state ic; + ic.w = w; + ic.i = i; + error = xwimp_get_icon_state(&ic); + if (error) { + LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + return ((ic.icon.flags & wimp_ICON_SELECTED) != 0); +} + + +/** + * Set the shaded state of an icon. + * + * \param w window handle + * \param i icon handle + * \param state shaded state + */ +void ro_gui_set_icon_shaded_state(wimp_w w, wimp_i i, bool state) +{ + wimp_caret caret; + os_error *error; + + /* update the state */ + if (ro_gui_get_icon_shaded_state(w, i) == state) + return; + error = xwimp_set_icon_state(w, i, + (state ? wimp_ICON_SHADED : 0), wimp_ICON_SHADED); + if (error) { + LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + if (!state) + return; + + /* ensure the caret is not in a shaded icon */ + error = xwimp_get_caret_position(&caret); + if (error) { + LOG("xwimp_get_caret_position: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + if ((caret.w != w) || (caret.i != i)) + return; + /* move the caret to the first avaiable writable */ + if (ro_gui_set_caret_first(w)) + return; + /* lose the caret */ + error = xwimp_set_caret_position((wimp_w)-1, (wimp_i)-1, -1, -1, -1, -1); + if (error) { + LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } +} + + +/** + * Gets the shaded state of an icon. + * + * \param w window handle + * \param i icon handle + */ +bool ro_gui_get_icon_shaded_state(wimp_w w, wimp_i i) +{ + wimp_icon_state ic; + ic.w = w; + ic.i = i; + xwimp_get_icon_state(&ic); + return (ic.icon.flags & wimp_ICON_SHADED) != 0; +} + + +/** + * Set the deleted state of an icon. + * + * \param w window handle + * \param i icon handle + * \param state shaded state + */ +void ro_gui_set_icon_deleted_state(wimp_w w, wimp_i i, bool state) +{ + wimp_caret caret; + os_error *error; + + /* update the state */ + if (ro_gui_get_icon_deleted_state(w, i) == state) + return; + error = xwimp_set_icon_state(w, i, + (state ? wimp_ICON_DELETED : 0), wimp_ICON_DELETED); + if (error) { + LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + if (!state) + return; + + /* ensure the caret is not in a shaded icon */ + error = xwimp_get_caret_position(&caret); + if (error) { + LOG("xwimp_get_caret_position: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + if ((caret.w != w) || (caret.i != i)) + return; + /* move the caret to the first avaiable writable */ + if (ro_gui_set_caret_first(w)) + return; + /* lose the caret */ + error = xwimp_set_caret_position((wimp_w)-1, (wimp_i)-1, -1, -1, -1, -1); + if (error) { + LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } +} + + +/** + * Gets the deleted state of an icon. + * + * \param w window handle + * \param i icon handle + */ +bool ro_gui_get_icon_deleted_state(wimp_w w, wimp_i i) +{ + wimp_icon_state ic; + ic.w = w; + ic.i = i; + xwimp_get_icon_state(&ic); + return (ic.icon.flags & wimp_ICON_DELETED) != 0; +} + + +/** + * Set the button type of an icon. + * + * \param w window handle + * \param i icon handle + * \param type button type + */ +void ro_gui_set_icon_button_type(wimp_w w, wimp_i i, int type) +{ + os_error *error; + error = xwimp_set_icon_state(w, i, wimp_ICON_BUTTON_TYPE, + (type << wimp_ICON_BUTTON_TYPE_SHIFT)); + if (error) { + LOG("xwimp_set_icon_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } +} + + +/** + * Set an icon's sprite + * + * \param w window handle + * \param i icon handle + * \param area sprite area containing sprite + * \param name name of sprite in area (in local encoding) + */ +void ro_gui_set_icon_sprite(wimp_w w, wimp_i i, osspriteop_area *area, + const char *name) +{ + wimp_icon_state ic; + os_error *error; + + /* get the icon data */ + ic.w = w; + ic.i = i; + error = xwimp_get_icon_state(&ic); + if (error) { + LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + /* copy the name across */ + if (ic.icon.data.indirected_text.size) { + strncpy(ic.icon.data.indirected_text.text, name, + (unsigned int)ic.icon.data.indirected_text.size - 1); + ic.icon.data.indirected_text.text[ + ic.icon.data.indirected_text.size - 1] = '\0'; + } + + ic.icon.data.indirected_sprite.area = area; + + ro_gui_redraw_icon(w, i); +} + + +/** + * Set a window title + * + * \param w window handle + * \param text new title (copied) + */ +void ro_gui_set_window_title(wimp_w w, const char *text) +{ + wimp_window_info_base window; + os_error *error; + char *title_local_enc; + nserror err; + + /* Get the window details + */ + window.w = w; + error = xwimp_get_window_info_header_only((wimp_window_info *)&window); + if (error) { + LOG("xwimp_get_window_info: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + /* convert text to local encoding */ + err = utf8_to_local_encoding(text, 0, &title_local_enc); + if (err != NSERROR_OK) { + /* A bad encoding should never happen, + * so assert this */ + assert(err != NSERROR_BAD_ENCODING); + LOG("utf8_to_enc failed"); + return; + } + + /* Set the title string + */ + strncpy(window.title_data.indirected_text.text, title_local_enc, + (unsigned int)window.title_data.indirected_text.size + - 1); + window.title_data.indirected_text.text[ + window.title_data.indirected_text.size - 1] = '\0'; + + /* Redraw accordingly + */ + error = xwimp_force_redraw_title(w); + if (error) { + LOG("xwimp_force_redraw_title: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + free(title_local_enc); +} + + +/** + * Places the caret in the first available icon + * + * \param w the window to place the caret in + * \return true if the caret was placed, false otherwise + */ +bool ro_gui_set_caret_first(wimp_w w) +{ + int icon, b; + wimp_window_state win_state; + wimp_window_info_base window; + wimp_icon_state state; + os_error *error; + + /* check the window is open */ + win_state.w = w; + error = xwimp_get_window_state(&win_state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + if (!(win_state.flags & wimp_WINDOW_OPEN)) + return false; + + /* get the window details for the icon count */ + window.w = w; + error = xwimp_get_window_info_header_only((wimp_window_info *)&window); + if (error) { + LOG("xwimp_get_window_info: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + + /* work through all the icons */ + state.w = w; + for (icon = 0; icon < window.icon_count; icon++) { + state.i = icon; + error = xwimp_get_icon_state(&state); + if (error) { + LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + + /* ignore if it's shaded or not writable */ + if (state.icon.flags & wimp_ICON_SHADED) + continue; + b = (state.icon.flags >> wimp_ICON_BUTTON_TYPE_SHIFT) & 0xf; + if ((b != wimp_BUTTON_WRITE_CLICK_DRAG) && + (b != wimp_BUTTON_WRITABLE)) + continue; + + /* move the caret */ + error = xwimp_set_caret_position(w, icon, 0, 0, -1, + strlen(state.icon.data.indirected_text.text)); + if (error) { + LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + return true; + } + return false; +} + + +/** + * Load a sprite file into memory. + * + * \param pathname file to load + * \return sprite area, or 0 on memory exhaustion or error and error reported + */ + +osspriteop_area *ro_gui_load_sprite_file(const char *pathname) +{ + int len; + fileswitch_object_type obj_type; + osspriteop_area *area; + os_error *error; + + error = xosfile_read_stamped_no_path(pathname, + &obj_type, 0, 0, &len, 0, 0); + if (error) { + LOG("xosfile_read_stamped_no_path: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MiscError", error->errmess); + return 0; + } + if (obj_type != fileswitch_IS_FILE) { + ro_warn_user("FileError", pathname); + return 0; + } + + area = malloc(len + 4); + if (!area) { + ro_warn_user("NoMemory", 0); + return 0; + } + + area->size = len + 4; + area->sprite_count = 0; + area->first = 16; + area->used = 16; + + error = xosspriteop_load_sprite_file(osspriteop_USER_AREA, + area, pathname); + if (error) { + LOG("xosspriteop_load_sprite_file: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MiscError", error->errmess); + free(area); + return 0; + } + + return area; +} + + +/** + * Check if a sprite is present in the Wimp sprite pool. + * + * \param sprite name of sprite + * \return true if the sprite is present + */ + +bool ro_gui_wimp_sprite_exists(const char *sprite) +{ + static char last_sprite_found[16]; + os_error *error; + + /* make repeated calls fast */ + if (!strncmp(sprite, last_sprite_found, sizeof(last_sprite_found))) + return true; + + /* fallback if not known to exist */ + error = xwimpspriteop_select_sprite(sprite, 0); + if (error) { + if (error->errnum != error_SPRITE_OP_DOESNT_EXIST) { + LOG("xwimpspriteop_select_sprite: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MiscError", error->errmess); + } + return false; + } + snprintf(last_sprite_found, sizeof(last_sprite_found), sprite); + return true; +} + + +/** + * Locate a sprite in the Wimp sprite pool, returning a pointer to it. + * + * \param name sprite name + * \param sprite receives pointer to sprite if found + * \return error ptr iff not found + */ + +os_error *ro_gui_wimp_get_sprite(const char *name, osspriteop_header **sprite) +{ + osspriteop_area *rom_base, *ram_base; + os_error *error; + + error = xwimp_base_of_sprites(&rom_base, &ram_base); + if (error) return error; + + error = xosspriteop_select_sprite(osspriteop_USER_AREA, + ram_base, (osspriteop_id)name, sprite); + + if (error && error->errnum == error_SPRITE_OP_DOESNT_EXIST) + error = xosspriteop_select_sprite(osspriteop_USER_AREA, + rom_base, (osspriteop_id)name, sprite); + + return error; +} + + +/** + * Get the dimensions of a sprite + * + * \param *area The sprite area to use. + * \param *sprite Pointer to the sprite name. + * \param *width Return the sprite width. + * \param *height Return the sprite height. + * \return true if successful; else false. + */ + +bool ro_gui_wimp_get_sprite_dimensions(osspriteop_area *area, char *sprite, + int *width, int *height) +{ + os_error *error = NULL; + os_mode mode; + os_coord dimensions; + + dimensions.x = 0; + dimensions.y = 0; + + if (area != (osspriteop_area *) -1) + error = xosspriteop_read_sprite_info(osspriteop_USER_AREA, + area, (osspriteop_id) sprite, + &dimensions.x, &dimensions.y, 0, &mode); + + if (error != NULL || area == (osspriteop_area *) -1) + error = xwimpspriteop_read_sprite_info(sprite, + &dimensions.x, &dimensions.y, 0, &mode); + + if (error == NULL) { + ro_convert_pixels_to_os_units(&dimensions, mode); + if (width != NULL) + *width = dimensions.x; + if (height != NULL) + *height = dimensions.y; + } else if (error->errnum != error_SPRITE_OP_DOESNT_EXIST) { + LOG("xosspriteop_read_sprite_info: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MiscError", error->errmess); + return false; + } + + return true; +} + + +/** + * Performs simple user redraw for a window. + * + * \param redraw wimp draw + * \param user_fill whether to fill the redraw area + * \param user_colour the colour to use when filling + */ + +void ro_gui_user_redraw(wimp_draw *redraw, bool user_fill, + os_colour user_colour) +{ + os_error *error; + osbool more; + + error = xwimp_redraw_window(redraw, &more); + if (error) { + LOG("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + while (more) { + if (user_fill) { + error = xcolourtrans_set_gcol(user_colour, + colourtrans_SET_BG_GCOL, + os_ACTION_OVERWRITE, 0, 0); + if (error) { + LOG("xcolourtrans_set_gcol: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MiscError", error->errmess); + } + os_clg(); + } + error = xwimp_get_rectangle(redraw, &more); + if (error) { + LOG("xwimp_get_rectangle: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + } +} + + +/** + * Sets whether a piece of window furniture is present for a window. + * + * \param w the window to modify + * \param bic_mask the furniture flags to clear + * \param xor_mask the furniture flags to toggle + */ +void ro_gui_wimp_update_window_furniture(wimp_w w, wimp_window_flags bic_mask, + wimp_window_flags xor_mask) +{ + wimp_window_state state; + wimp_w parent; + bits linkage; + os_error *error; + bool open; + + state.w = w; + error = xwimp_get_window_state_and_nesting(&state, &parent, &linkage); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + open = state.flags & wimp_WINDOW_OPEN; + state.flags &= ~(63 << 16); /* clear bits 16-21 */ + state.flags &= ~bic_mask; + state.flags ^= xor_mask; + if (!open) + state.next = wimp_HIDDEN; + error = xwimp_open_window_nested_with_flags(&state, parent, linkage); + if (error) { + LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + if (!open) { + error = xwimp_close_window(w); + if (error) { + LOG("xwimp_close_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + } +} + + +/** + * Checks whether a piece of window furniture is present for a window. + * + * \param w the window to modify + * \param mask the furniture flags to check + */ +bool ro_gui_wimp_check_window_furniture(wimp_w w, wimp_window_flags mask) +{ + wimp_window_state state; + os_error *error; + + state.w = w; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + return state.flags & mask; +} + +/** + * RO GUI-specific strlen, for control character terminated strings + * + * \param str The string to measure the length of + * \return The length of the string + */ +size_t ro_gui_strlen(const char *str) +{ + const char *str_begin; + + if (str == NULL) + return 0; + + for (str_begin = str; *str++ >= ' '; /* */) + /* */; + + return str - str_begin - 1; +} + +/** + * RO GUI-specific strncmp, for control character terminated strings + * + * \param s1 The first string for comparison + * \param s2 The second string for comparison + * \param len Maximum number of bytes to be checked + * \return 0 for equal strings up to len bytes; pos for s1 being bigger than + * s2; neg for s1 being smaller than s2. + */ +int ro_gui_strncmp(const char *s1, const char *s2, size_t len) +{ + while (len--) { + char c1 = *s1++; + char c2 = *s2++; + if (c1 < ' ' || c2 < ' ') + return (c1 < ' ' ? 0 : c1) - (c2 < ' ' ? 0 : c2); + int diff = c1 - c2; + if (diff) + return diff; + } + return 0; +} + + +/** + * Generic window scroll event handler. + * + * \param *scroll Pointer to Scroll Event block. + */ + +void ro_gui_scroll(wimp_scroll *scroll) +{ + os_error *error; + int x = scroll->visible.x1 - scroll->visible.x0 - 32; + int y = scroll->visible.y1 - scroll->visible.y0 - 32; + + switch (scroll->xmin) { + case wimp_SCROLL_PAGE_LEFT: + scroll->xscroll -= x; + break; + case wimp_SCROLL_COLUMN_LEFT: + scroll->xscroll -= 100; + break; + case wimp_SCROLL_COLUMN_RIGHT: + scroll->xscroll += 100; + break; + case wimp_SCROLL_PAGE_RIGHT: + scroll->xscroll += x; + break; + default: + scroll->xscroll += (x * (scroll->xmin>>2)) >> 2; + break; + } + + switch (scroll->ymin) { + case wimp_SCROLL_PAGE_UP: + scroll->yscroll += y; + break; + case wimp_SCROLL_LINE_UP: + scroll->yscroll += 100; + break; + case wimp_SCROLL_LINE_DOWN: + scroll->yscroll -= 100; + break; + case wimp_SCROLL_PAGE_DOWN: + scroll->yscroll -= y; + break; + default: + scroll->yscroll += (y * (scroll->ymin>>2)) >> 2; + break; + } + + error = xwimp_open_window((wimp_open *) scroll); + if (error) { + LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess); + } +} + diff --git a/frontends/riscos/wimp.h b/frontends/riscos/wimp.h new file mode 100644 index 000000000..fdcf67b95 --- /dev/null +++ b/frontends/riscos/wimp.h @@ -0,0 +1,83 @@ +/* + * Copyright 2004 Richard Wilson <not_ginger_matt@users.sourceforge.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * General RISC OS WIMP/OS library functions (interface). + */ + + +#ifndef _NETSURF_RISCOS_WIMP_H_ +#define _NETSURF_RISCOS_WIMP_H_ + +#include <assert.h> +#include <stdbool.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include "oslib/os.h" +#include "oslib/wimp.h" +#include "rufl.h" + + +int ro_get_hscroll_height(wimp_w w); +int ro_get_vscroll_width(wimp_w w); +int ro_get_title_height(wimp_w w); +bool ro_gui_wimp_read_eig_factors(os_mode mode, int *xeig, int *yeig); +void ro_convert_os_units_to_pixels(os_coord *os_units, os_mode mode); +void ro_convert_pixels_to_os_units(os_coord *pixels, os_mode mode); + +#define ro_gui_redraw_icon(w, i) xwimp_set_icon_state(w, i, 0, 0) +void ro_gui_force_redraw_icon(wimp_w w, wimp_i i); +const char *ro_gui_get_icon_string(wimp_w w, wimp_i i); +void ro_gui_set_icon_string(wimp_w w, wimp_i i, const char *text, bool is_utf8); + +void ro_gui_set_icon_integer(wimp_w w, wimp_i i, int value); +void ro_gui_set_icon_decimal(wimp_w w, wimp_i i, int value, int decimal_places); +int ro_gui_get_icon_decimal(wimp_w w, wimp_i i, int decimal_places); + +void ro_gui_set_icon_selected_state(wimp_w w, wimp_i i, bool state); +bool ro_gui_get_icon_selected_state(wimp_w w, wimp_i i); +void ro_gui_set_icon_shaded_state(wimp_w w, wimp_i i, bool state); +bool ro_gui_get_icon_shaded_state(wimp_w w, wimp_i i); +void ro_gui_set_icon_deleted_state(wimp_w w, wimp_i i, bool state); +bool ro_gui_get_icon_deleted_state(wimp_w w, wimp_i i); +void ro_gui_set_icon_button_type(wimp_w w, wimp_i i, int type); +void ro_gui_set_icon_sprite(wimp_w w, wimp_i i, osspriteop_area *area, + const char *name); +void ro_gui_set_window_title(wimp_w w, const char *title); +bool ro_gui_set_caret_first(wimp_w w); +void ro_gui_open_window_centre(wimp_w parent, wimp_w child); + +osspriteop_area *ro_gui_load_sprite_file(const char *pathname); +bool ro_gui_wimp_sprite_exists(const char *sprite); +os_error *ro_gui_wimp_get_sprite(const char *name, osspriteop_header **sprite); +bool ro_gui_wimp_get_sprite_dimensions(osspriteop_area *area, char *sprite, + int *width, int *height); + +wimp_w ro_gui_set_window_background_colour(wimp_w window, wimp_colour background); +void ro_gui_set_icon_colours(wimp_w window, wimp_i icon, + wimp_colour foreground, wimp_colour background); +void ro_gui_user_redraw(wimp_draw *redraw, bool user_fill, os_colour user_colour); +void ro_gui_wimp_update_window_furniture(wimp_w w, wimp_window_flags bic_mask, + wimp_window_flags xor_mask); +bool ro_gui_wimp_check_window_furniture(wimp_w w, wimp_window_flags mask); + +void ro_gui_scroll(wimp_scroll *scroll); + +#endif + diff --git a/frontends/riscos/wimp_event.c b/frontends/riscos/wimp_event.c new file mode 100644 index 000000000..015e87baf --- /dev/null +++ b/frontends/riscos/wimp_event.c @@ -0,0 +1,1814 @@ +/* + * Copyright 2005 Richard Wilson <info@tinct.net> + * Copyright 2010, 2011 Stephen Fryatt <stevef@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Automated RISC OS WIMP event handling (implementation). + */ + +#include <assert.h> +#include <inttypes.h> +#include <stdbool.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include "oslib/os.h" +#include "oslib/osbyte.h" +#include "oslib/serviceinternational.h" +#include "oslib/wimp.h" + +#include "utils/log.h" + +#include "riscos/gui.h" +#include "riscos/dialog.h" +#include "riscos/menus.h" +#include "riscos/ucstables.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" +#include "riscos/wimputils.h" + +#define WIN_HASH_SIZE 32 +#define WIN_HASH(w) (((unsigned)(w) >> 5) % WIN_HASH_SIZE) + +typedef enum { + EVENT_NUMERIC_FIELD, + EVENT_TEXT_FIELD, + EVENT_UP_ARROW, + EVENT_DOWN_ARROW, + EVENT_MENU_GRIGHT, + EVENT_CHECKBOX, + EVENT_RADIO, + EVENT_BUTTON, + EVENT_CANCEL, + EVENT_OK +} event_type; + +struct event_data_numeric_field { + int stepping; + int min; + int max; + int decimal_places; +}; + +struct event_data_menu_gright { + wimp_i field; + wimp_menu *menu; +}; + +struct icon_event { + event_type type; + wimp_i i; + union { + struct event_data_numeric_field numeric_field; + struct event_data_menu_gright menu_gright; + wimp_i linked_icon; + int radio_group; + void (*callback)(wimp_pointer *pointer); + } data; + union { + char *textual; + bool boolean; + } previous_value; + bool previous_shaded; + struct icon_event *next; +}; + +struct event_window { + wimp_w w; + bool (*ok_click)(wimp_w w); + bool (*mouse_click)(wimp_pointer *pointer); + bool (*keypress)(wimp_key *key); + void (*open_window)(wimp_open *open); + void (*close_window)(wimp_w w); + void (*redraw_window)(wimp_draw *redraw); + void (*scroll_window)(wimp_scroll *scroll); + void (*entering_window)(wimp_entering *entering); + bool (*menu_prepare)(wimp_w w, wimp_i i, wimp_menu *m, + wimp_pointer *p); + bool (*menu_selection)(wimp_w w, wimp_i i, wimp_menu *m, + wimp_selection *s, menu_action a); + void (*menu_warning)(wimp_w w, wimp_i i, wimp_menu *m, + wimp_selection *s, menu_action a); + void (*menu_close)(wimp_w w, wimp_i i, wimp_menu *m); + wimp_menu *window_menu; + bool window_menu_auto; + bool window_menu_iconbar; + const char *help_prefix; + const char *(*get_help_suffix)(wimp_w w, wimp_i i, os_coord *pos, + wimp_mouse_state buttons); + void *user_data; + struct icon_event *first; + struct event_window *next; + int max_radio_group; +}; + +static void ro_gui_wimp_event_ok_click(struct event_window *window, + wimp_mouse_state state); +static struct event_window *ro_gui_wimp_event_get_window(wimp_w w); +static struct event_window *ro_gui_wimp_event_find_window(wimp_w w); +static struct icon_event *ro_gui_wimp_event_get_event(wimp_w w, wimp_i i, + event_type type); +static void ro_gui_wimp_event_prepare_gright_menu(wimp_w w, struct icon_event *event); +static struct event_window *ro_gui_wimp_event_remove_window(wimp_w w); + +static struct event_window *ro_gui_wimp_event_windows[WIN_HASH_SIZE]; + +static wimp_w ro_gui_wimp_event_submenu; + +/** + * Memorises the current state of any registered components in a window. + * + * \param w the window to memorise + * \return true on success, false on memory exhaustion or for an unknown window + */ +bool ro_gui_wimp_event_memorise(wimp_w w) +{ + struct event_window *window; + struct icon_event *event; + bool error = false; + + window = ro_gui_wimp_event_find_window(w); + if (!window) + return false; + + for (event = window->first; event; event = event->next) { + switch (event->type) { + case EVENT_NUMERIC_FIELD: + case EVENT_TEXT_FIELD: + if (event->previous_value.textual) + free(event->previous_value.textual); + event->previous_value.textual = strdup( + ro_gui_get_icon_string(window->w, event->i)); + if (!event->previous_value.textual) { + error = true; + LOG("Unable to store state for icon %i", event->i); + } + break; + case EVENT_CHECKBOX: + case EVENT_RADIO: + event->previous_value.boolean = + ro_gui_get_icon_selected_state(window->w, event->i); + break; + default: + break; + } + if (event->type != EVENT_MENU_GRIGHT) + event->previous_shaded = ro_gui_get_icon_shaded_state(window->w, + event->i); + } + return !error; +} + + +/** + * Restore the state of any registered components in a window to their memorised state. + * + * \param w the window to restore + * \return true on success, false for an unknown window + */ +bool ro_gui_wimp_event_restore(wimp_w w) +{ + struct event_window *window; + struct icon_event *event; + + window = ro_gui_wimp_event_find_window(w); + if (!window) + return false; + + for (event = window->first; event; event = event->next) { + switch (event->type) { + case EVENT_NUMERIC_FIELD: + case EVENT_TEXT_FIELD: + if (event->previous_value.textual) + ro_gui_set_icon_string(window->w, event->i, + event->previous_value.textual, true); + break; + case EVENT_CHECKBOX: + case EVENT_RADIO: + ro_gui_set_icon_selected_state(window->w, event->i, + event->previous_value.boolean); + break; + default: + break; + } + if (event->type != EVENT_MENU_GRIGHT) + ro_gui_set_icon_shaded_state(window->w, event->i, + event->previous_shaded); + } + return true; +} + + +/** + * Ensures all values are within pre-determined boundaries. + * + * \param w the window to memorise + * \return true on success, false for an unknown window + */ +bool ro_gui_wimp_event_validate(wimp_w w) +{ + struct event_window *window; + struct icon_event *event; + int value; + + window = ro_gui_wimp_event_find_window(w); + if (!window) + return false; + + for (event = window->first; event; event = event->next) { + switch (event->type) { + case EVENT_NUMERIC_FIELD: + value = ro_gui_get_icon_decimal(window->w, event->i, + event->data.numeric_field.decimal_places); + if (value < event->data.numeric_field.min) + value = event->data.numeric_field.min; + else if (value > event->data.numeric_field.max) + value = event->data.numeric_field.max; + ro_gui_set_icon_decimal(window->w, event->i, value, + event->data.numeric_field.decimal_places); + break; + default: + break; + } + } + return true; +} + +/** + * Transfer event data from one window to another. This can be used as an + * alternative to ro_gui_wimp_event_finalise() and re-registering, if + * events need to continue across a change of window handle. + * + * All aspects of the registered events MUST remain the same in the new + * window! + * + * \param from The current window, which is to be deleted. + * \param to The window to which the events should transfer. + * \return true on success; false for an unknown window. + */ + +bool ro_gui_wimp_event_transfer(wimp_w from, wimp_w to) +{ + struct event_window *window; + int h; + + LOG("Transferring all events from window 0x%x to window 0x%x", (unsigned int)from, (unsigned int)to); + + window = ro_gui_wimp_event_remove_window(from); + if (window == NULL || window->w != from) + return false; + + h = WIN_HASH(to); + window->w = to; + window->next = ro_gui_wimp_event_windows[h]; + ro_gui_wimp_event_windows[h] = window; + + ro_gui_menu_window_changed(from, to); + + return true; +} + +/** + * Free any resources associated with a window. + * + * \param w the window to free resources for + */ +void ro_gui_wimp_event_finalise(wimp_w w) +{ + struct event_window *window; + struct icon_event *event; + + LOG("Removing all events for window 0x%x", (unsigned int)w); + window = ro_gui_wimp_event_remove_window(w); + if (!window) + return; + + while (window->first) { + event = window->first; + window->first = event->next; + switch (event->type) { + case EVENT_NUMERIC_FIELD: + case EVENT_TEXT_FIELD: + if (event->previous_value.textual) + free(event->previous_value.textual); + event->previous_value.textual = NULL; + break; + default: + break; + } + free(event); + } + free(window); + return; +} + + +/** + * Free any resources associated with a specific icon in a window. + * + * \param w The window containing the icon. + * \param i The icon to free resources for. + */ + +void ro_gui_wimp_event_deregister(wimp_w w, wimp_i i) +{ + struct event_window *window; + struct icon_event *event, *parent, *child; + + LOG("Removing all events for window 0x%x, icon %d", (unsigned int)w, (int)i); + window = ro_gui_wimp_event_get_window(w); + if (!window) + return; + + /* Remove any events that apply to the given icon. */ + + event = window->first; + parent = NULL; + + while (event != NULL) { + child = event->next; + + if (event->i == i) { + LOG("Removing event 0x%x", (unsigned int)event); + + if (parent == NULL) + window->first = child; + else + parent->next = child; + + switch (event->type) { + case EVENT_NUMERIC_FIELD: + case EVENT_TEXT_FIELD: + if (event->previous_value.textual) + free(event->previous_value.textual); + event->previous_value.textual = NULL; + break; + default: + break; + } + + free(event); + } else { + parent = event; + } + + event = child; + } +} + + +/** + * Set the associated help prefix for a given window. + * + * \param w the window to get the prefix for + * \param help_prefix the prefix to associate with the window (used directly) + * \return true on success, or NULL for memory exhaustion + */ +bool ro_gui_wimp_event_set_help_prefix(wimp_w w, const char *help_prefix) +{ + struct event_window *window; + + window = ro_gui_wimp_event_get_window(w); + if (!window) + return false; + window->help_prefix = help_prefix; + return true; +} + + +/** + * Get the associated help prefix. + * + * \param w the window to get the prefix for + * \return the associated prefix, or NULL + */ +const char *ro_gui_wimp_event_get_help_prefix(wimp_w w) +{ + struct event_window *window; + + window = ro_gui_wimp_event_find_window(w); + if (window) + return window->help_prefix; + return NULL; +} + + +/** + * Register a handler to decode help suffixes for a given window. + * + */ + +bool ro_gui_wimp_event_register_help_suffix(wimp_w w, + const char *(*get_help_suffix)(wimp_w w, wimp_i i, + os_coord *pos, wimp_mouse_state buttons)) +{ + struct event_window *window; + + window = ro_gui_wimp_event_get_window(w); + if (!window) + return false; + window->get_help_suffix = get_help_suffix; + return true; +} + + +/** + * Get the associated help suffix. + * + * \param w The window to get the suffix for + * \param i The icon + * \param pos The os coordinates + * \param buttons The button state. + * \return The associated prefix, or NULL + */ + +const char *ro_gui_wimp_event_get_help_suffix(wimp_w w, wimp_i i, + os_coord *pos, wimp_mouse_state buttons) +{ + struct event_window *window; + + window = ro_gui_wimp_event_find_window(w); + if (window == NULL || window->get_help_suffix == NULL) + return NULL; + + return window->get_help_suffix(w, i, pos, buttons); +} + + +/** + * Sets the user data associated with a window. + * + * \param w the window to associate the data with + * \param user the data to associate + */ +bool ro_gui_wimp_event_set_user_data(wimp_w w, void *user) +{ + struct event_window *window; + + window = ro_gui_wimp_event_get_window(w); + if (!window) + return false; + window->user_data = user; + return true; + +} + + +/** + * Gets the user data associated with a window. + * + * \param w the window to retrieve the data for + * \return the associated data, or NULL + */ +void *ro_gui_wimp_event_get_user_data(wimp_w w) +{ + struct event_window *window; + + window = ro_gui_wimp_event_find_window(w); + if (window) + return window->user_data; + return NULL; +} + + +/** + * Handles a menu selection event. + * + * (At present, this is tied to being called from menus.c and relies on that + * module decoding the menu into an action code. If menus.c loses its + * menu handling in the future, such decoding might need to move here.) + * + * The order of execution is: + * + * 1. Try to match the menu to a pop-up menu. If successful, handle it as + * this. + * 2. Try to match the menu to a window menu. If successful, pass control to + * the menu's registered _select handler. + * 3. Return event as unhandled. + * + * \param w the window to owning the menu + * \param i the icon owning the menu + * \param menu the menu that has been selected + * \param selection the selection information + * \param action the menu action info from menus.c + * \return true if the menu is OK for an Adjust re-open; + * else false. + */ +bool ro_gui_wimp_event_menu_selection(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_selection *selection, menu_action action) +{ + struct event_window *window; + struct icon_event *event; + wimp_menu_entry *menu_entry; + wimp_key key; + os_error *error; + wimp_caret caret; + wimp_icon_state ic; + unsigned int button_type; + bool prepared; + + window = ro_gui_wimp_event_find_window(w); + if (window == NULL) + return false; + + /* Start by looking for an icon event that matches. If there isn't one, + * then return details for an unconnected menu. It's up to the + * event recipient to sort out if this is a window menu or not, based + * on the menu handle passed back. + */ + + for (event = window->first; event; event = event->next) + if ((event->type == EVENT_MENU_GRIGHT) && (event->i == i)) + break; + if (!event) { + if (window->menu_selection) + window->menu_selection(window->w, wimp_ICON_WINDOW, + menu, selection, action); + + /* Prepare the menu pending a possible Adjust click. */ + if (window->menu_prepare) + if (!window->menu_prepare(window->w, wimp_ICON_WINDOW, + menu, NULL)) + return false; + + return true; + } + + menu_entry = &menu->entries[selection->items[0]]; + for (i = 1; selection->items[i] != -1; i++) + menu_entry = &menu_entry->sub_menu-> + entries[selection->items[i]]; + + /* if the entry is already ticked then we do nothing */ + if (menu_entry->menu_flags & wimp_MENU_TICKED) + return true; + + ro_gui_set_icon_string(window->w, event->data.menu_gright.field, + menu_entry->data.indirected_text.text, false); + if (window->menu_selection) + window->menu_selection(window->w, event->i, menu, + selection, action); + prepared = true; + if (window->menu_prepare) + prepared = window->menu_prepare(window->w, event->i, + menu, NULL); + if (prepared) + ro_gui_wimp_event_prepare_gright_menu(window->w, event); + + /* set the caret for writable icons and send a CTRL+U keypress to + * stimulate activity if needed */ + ic.w = window->w; + ic.i = event->data.menu_gright.field; + error = xwimp_get_icon_state(&ic); + if (error) { + LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + button_type = (ic.icon.flags & wimp_ICON_BUTTON_TYPE) >> wimp_ICON_BUTTON_TYPE_SHIFT; + if ((button_type != wimp_BUTTON_WRITABLE) && + (button_type != wimp_BUTTON_WRITE_CLICK_DRAG)) + return prepared; + error = xwimp_get_caret_position(&caret); + if (error) { + LOG("xwimp_get_caret_position: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + if ((caret.w != window->w) || (caret.i != event->data.menu_gright.field)) { + error = xwimp_set_caret_position(window->w, event->data.menu_gright.field, + -1, -1, -1, strlen(menu_entry->data.indirected_text.text)); + if (error) { + LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + } + if (window->keypress) { + key.w = window->w; + key.c = 21; // ctrl+u + window->keypress(&key); + } + return prepared; +} + + +/** + * Handles a mouse click event in a registered window. + * + * The order of execution is: + * + * 1. If a menu click, and the window has an automatic window menu, this is + * processed immediately. + * 2. Any registered mouse_click routine (see ro_gui_wimp_register_mouse_click()) + * 3. If the current icon is not registered with a type then it is assumed that no + * action is necessary, and the click is deemed to have been handled. + * 4. If the registered mouse_click routine returned false, or there was no registered + * routine then the automated action for the registered icon type is performed + * + * \param pointer the current pointer state + * \return true if the event was handled, false otherwise + */ +bool ro_gui_wimp_event_mouse_click(wimp_pointer *pointer) +{ + struct event_window *window; + struct icon_event *event; + wimp_w w; + struct icon_event *search; + int current, step, stepping, min, max, decimal_places; + wimp_window_state open; + wimp_caret caret; + bool prepared; + + w = pointer->w; + window = ro_gui_wimp_event_find_window(w); + if (!window) + return false; + + /* Menu clicks take priority if there is an auto menu defined. */ + if ((pointer->buttons == wimp_CLICK_MENU) && + (window->window_menu != NULL) && + (window->window_menu_auto)) { + ro_gui_wimp_event_process_window_menu_click(pointer); + return true; + } + + /* registered routines take next priority */ + if ((window->mouse_click) && (window->mouse_click(pointer))) + return true; + + for (event = window->first; event; event = event->next) + if (event->i == pointer->i) + break; + if (!event) + return true; + + switch (event->type) { + case EVENT_NUMERIC_FIELD: + case EVENT_TEXT_FIELD: + break; + case EVENT_UP_ARROW: + case EVENT_DOWN_ARROW: + for (search = window->first; search; search = search->next) + if (search->i == event->data.linked_icon) break; + if (!search) { + LOG("Incorrect reference."); + return false; + } + stepping = search->data.numeric_field.stepping; + min = search->data.numeric_field.min; + max = search->data.numeric_field.max; + decimal_places = search->data.numeric_field.decimal_places; + + if (pointer->buttons & wimp_CLICK_ADJUST) + step = -stepping; + else if (pointer->buttons & wimp_CLICK_SELECT) + step = stepping; + else + return true; + if (event->type == EVENT_DOWN_ARROW) + step = -step; + + current = ro_gui_get_icon_decimal(pointer->w, event->data.linked_icon, + decimal_places); + current += step; + if (current < min) + current = min; + if (current > max) + current = max; + ro_gui_set_icon_decimal(pointer->w, event->data.linked_icon, current, + decimal_places); + break; + case EVENT_MENU_GRIGHT: + /* if there's already a menu open then we assume that we are part of it. + * to follow the standard RISC OS behaviour we add a 'send to the back' + * button, then close the menu (which closes us) and then finally + * re-open ourselves. ugh! */ + if (current_menu != NULL) { + os_error *error; + open.w = pointer->w; + error = xwimp_get_window_state(&open); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + error = xwimp_get_caret_position(&caret); + if (error) { + LOG("xwimp_get_caret_position: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + ro_gui_dialog_add_persistent(current_menu_window, + pointer->w); + ro_gui_menu_destroy(); + error = xwimp_open_window(PTR_WIMP_OPEN(&open)); + if (error) { + LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + if (caret.w == pointer->w) { + error = xwimp_set_caret_position(caret.w, + caret.i, + caret.pos.x, caret.pos.y, + -1, caret.index); + if (error) { + LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + } + } + /* display the menu */ + + prepared = true; + if (window->menu_prepare != NULL) + prepared = window->menu_prepare(pointer->w, pointer->i, + event->data.menu_gright.menu, pointer); + if (prepared) { + ro_gui_wimp_event_prepare_gright_menu(pointer->w, event); + ro_gui_popup_menu(event->data.menu_gright.menu, pointer->w, pointer->i); + } + break; + case EVENT_CHECKBOX: + break; + case EVENT_RADIO: + for (search = window->first; search; search = search->next) + if ((search->type == EVENT_RADIO) && + (search->data.radio_group == + event->data.radio_group)) + ro_gui_set_icon_selected_state(pointer->w, + search->i, (search == event)); + break; + case EVENT_BUTTON: + if (event->data.callback) + event->data.callback(pointer); + break; + case EVENT_CANCEL: + if (pointer->buttons & wimp_CLICK_SELECT) { + ro_gui_dialog_close(pointer->w); + ro_gui_wimp_event_close_window(pointer->w); + ro_gui_menu_destroy(); + } else { + ro_gui_wimp_event_restore(pointer->w); + } + break; + case EVENT_OK: + ro_gui_wimp_event_ok_click(window, pointer->buttons); + break; + } + return true; +} + + +/** + * Prepare a menu ready for use + * + * /param w the window owning the menu + * /param event the icon event owning the menu + */ +void ro_gui_wimp_event_prepare_gright_menu(wimp_w w, struct icon_event *event) +{ + int i; + const char *text; + unsigned int button_type; + wimp_icon_state ic; + wimp_menu *menu; + os_error *error; + + /* if the linked icon is not writable then we set the ticked state + * of the menu item that matches the contents */ + ic.w = w; + ic.i = event->data.menu_gright.field; + error = xwimp_get_icon_state(&ic); + if (error) { + LOG("xwimp_get_icon_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + button_type = (ic.icon.flags & wimp_ICON_BUTTON_TYPE) + >> wimp_ICON_BUTTON_TYPE_SHIFT; + if ((button_type == wimp_BUTTON_WRITABLE) || + (button_type == wimp_BUTTON_WRITE_CLICK_DRAG)) + return; + text = ro_gui_get_icon_string(w, event->data.menu_gright.field); + menu = event->data.menu_gright.menu; + i = 0; + do { + if (!strcmp(menu->entries[i].data.indirected_text.text, text)) + menu->entries[i].menu_flags |= wimp_MENU_TICKED; + else + menu->entries[i].menu_flags &= ~wimp_MENU_TICKED; + } while (!(menu->entries[i++].menu_flags & wimp_MENU_LAST)); +} + + +/** + * Perform the necessary actions following a click on the OK button. + * + * /param window the window to perform the action on + * /param state the mouse button state + */ +void ro_gui_wimp_event_ok_click(struct event_window *window, + wimp_mouse_state state) +{ + struct icon_event *search; + + for (search = window->first; search; search = search->next) + if (search->type == EVENT_OK) { + if (ro_gui_get_icon_shaded_state(window->w, search->i)) + return; + break; + } + ro_gui_wimp_event_validate(window->w); + + if (window->ok_click) + if (!window->ok_click(window->w)) + return; + + if (state & wimp_CLICK_SELECT) { + ro_gui_dialog_close(window->w); + ro_gui_wimp_event_close_window(window->w); + ro_gui_menu_destroy(); + } else { + ro_gui_wimp_event_memorise(window->w); + } +} + + +/** + * Handle any registered keypresses, and the standard RISC OS ones + * + * \param key the key state + * \return true if keypress handled, false otherwise + */ +bool ro_gui_wimp_event_keypress(wimp_key *key) +{ + static const int *ucstable = NULL; + static int alphabet = 0; + static uint32_t wc = 0; /* buffer for UTF8 alphabet */ + static int shift = 0; + struct event_window *window; + struct icon_event *event; + wimp_pointer pointer; + wimp_key k; + uint32_t c = (uint32_t) key->c; + int t_alphabet; + os_error *error; + + window = ro_gui_wimp_event_find_window(key->w); + if (!window) + return false; + + /* copy key state so we can corrupt it safely */ + memcpy(&k, key, sizeof(wimp_key)); + + /* In order to make sensible use of the 0x80->0xFF ranges specified + * in the RISC OS 8bit alphabets, we must do the following: + * + * + Read the currently selected alphabet + * + Acquire a pointer to the UCS conversion table for this alphabet: + * + Try using ServiceInternational 8 to get the table + * + If that fails, use our internal table (see ucstables.c) + * + If the alphabet is not UTF8 and the conversion table exists: + * + Lookup UCS code in the conversion table + * + If code is -1 (i.e. undefined): + * + Use codepoint 0xFFFD instead + * + If the alphabet is UTF8, we must buffer input, thus: + * + If the keycode is < 0x80: + * + Handle it directly + * + If the keycode is a UTF8 sequence start: + * + Initialise the buffer appropriately + * + Otherwise: + * + OR in relevant bits from keycode to buffer + * + If we've received an entire UTF8 character: + * + Handle UCS code + * + Otherwise: + * + Simply handle the keycode directly, as there's no easy way + * of performing the mapping from keycode -> UCS4 codepoint. + */ + error = xosbyte1(osbyte_ALPHABET_NUMBER, 127, 0, &t_alphabet); + if (error) { + LOG("failed reading alphabet: 0x%x: %s", error->errnum, error->errmess); + /* prevent any corruption of ucstable */ + t_alphabet = alphabet; + } + + if (t_alphabet != alphabet) { + void *ostable; + osbool unclaimed; + /* Alphabet has changed, so read UCS table location */ + alphabet = t_alphabet; + + error = xserviceinternational_get_ucs_conversion_table( + alphabet, &unclaimed, &ostable); + if (error != NULL) { + LOG("failed reading UCS conversion table: 0x%x: %s", error->errnum, error->errmess); + /* Try using our own table instead */ + ucstable = ucstable_from_alphabet(alphabet); + } else if (unclaimed) { + /* Service wasn't claimed so use our own ucstable */ + ucstable = ucstable_from_alphabet(alphabet); + } else { + /* Use the table provided by the OS */ + ucstable = ostable; + } + } + + if (c < 256) { + if (alphabet != 111 /* UTF8 */ && ucstable != NULL) { + /* defined in this alphabet? */ + if (ucstable[c] == -1) + return true; + + /* read UCS4 value out of table */ + k.c = ucstable[c]; + } + else if (alphabet == 111 /* UTF8 */) { + if ((c & 0x80) == 0x00 || (c & 0xC0) == 0xC0) { + /* UTF8 start sequence */ + if ((c & 0xE0) == 0xC0) { + wc = ((c & 0x1F) << 6); + shift = 1; + return true; + } + else if ((c & 0xF0) == 0xE0) { + wc = ((c & 0x0F) << 12); + shift = 2; + return true; + } + else if ((c & 0xF8) == 0xF0) { + wc = ((c & 0x07) << 18); + shift = 3; + return true; + } + /* These next two have been removed + * from RFC3629, but there's no + * guarantee that RISC OS won't + * generate a UCS4 value outside the + * UTF16 plane, so we handle them + * anyway. */ + else if ((c & 0xFC) == 0xF8) { + wc = ((c & 0x03) << 24); + shift = 4; + } + else if ((c & 0xFE) == 0xFC) { + wc = ((c & 0x01) << 30); + shift = 5; + } + else if (c >= 0x80) { + /* If this ever happens, + * RISC OS' UTF8 keyboard + * drivers are broken */ + LOG("unexpected UTF8 start"" byte %x (ignoring)", c); + return true; + } + /* Anything else is ASCII, so just + * handle it directly. */ + } + else { + if ((c & 0xC0) != 0x80) { + /* If this ever happens, + * RISC OS' UTF8 keyboard + * drivers are broken */ + LOG("unexpected keycode: ""%x (ignoring)", c); + return true; + } + + /* Continuation of UTF8 character */ + wc |= ((c & 0x3F) << (6 * --shift)); + if (shift > 0) + /* partial character */ + return true; + else + /* got entire character, so + * fetch from buffer and + * handle it */ + k.c = wc; + } + } + } else { + k.c |= IS_WIMP_KEY; + } + + /* registered routines take priority */ + if (window->keypress) + if (window->keypress(&k)) + return true; + + switch (key->c) { + /* Escape performs the CANCEL action (simulated click) */ + case wimp_KEY_ESCAPE: + for (event = window->first; event; event = event->next) { + switch (event->type) { + case EVENT_CANCEL: + pointer.w = key->w; + pointer.i = event->i; + pointer.buttons = wimp_CLICK_SELECT; + ro_gui_wimp_event_mouse_click(&pointer); + return true; + default: + break; + } + } + return false; + /* CTRL+F2 closes a window with a close icon */ + case wimp_KEY_CONTROL + wimp_KEY_F2: + if (!ro_gui_wimp_check_window_furniture(key->w, + wimp_WINDOW_CLOSE_ICON)) + return false; + ro_gui_dialog_close(key->w); + ro_gui_wimp_event_close_window(key->w); + ro_gui_menu_destroy(); + return true; + /* Return performs the OK action */ + case wimp_KEY_RETURN: + if (!window->ok_click) + return false; + /* todo: check we aren't greyed out */ + ro_gui_wimp_event_ok_click(window, wimp_CLICK_SELECT); + return true; + } + return false; +} + + +/** + * Handle any open window requests + * + * \param open the window open request + */ +bool ro_gui_wimp_event_open_window(wimp_open *open) +{ + struct event_window *window; + + window = ro_gui_wimp_event_find_window(open->w); + if ((window) && (window->open_window)) { + window->open_window(open); + return true; + } + return false; +} + + +/** + * Service any close window handlers + * + * \param w the window being closed + */ +bool ro_gui_wimp_event_close_window(wimp_w w) +{ + struct event_window *window; + + LOG("Close event received for window 0x%x", (unsigned int)w); + if (w == ro_gui_wimp_event_submenu) + ro_gui_wimp_event_submenu = 0; + window = ro_gui_wimp_event_find_window(w); + if ((window) && (window->close_window)) { + window->close_window(w); + return true; + } + return false; +} + + +/** + * Handle any redraw window requests + * + * \param redraw the window redraw request + */ +bool ro_gui_wimp_event_redraw_window(wimp_draw *redraw) +{ + struct event_window *window; + + window = ro_gui_wimp_event_find_window(redraw->w); + if ((window) && (window->redraw_window)) { + window->redraw_window(redraw); + return true; + } + return false; +} + + +/** + * Handle any scroll window requests + * + * \param scroll the window scroll request + */ +bool ro_gui_wimp_event_scroll_window(wimp_scroll *scroll) +{ + struct event_window *window; + + window = ro_gui_wimp_event_find_window(scroll->w); + if ((window) && (window->scroll_window)) { + window->scroll_window(scroll); + return true; + } + return false; +} + + +/** + * Handle any pointer entering window requests + * + * \param entering the pointer entering window request + */ +bool ro_gui_wimp_event_pointer_entering_window(wimp_entering *entering) +{ + struct event_window *window; + + window = ro_gui_wimp_event_find_window(entering->w); + if ((window) && (window->entering_window)) { + window->entering_window(entering); + return true; + } + return false; +} + + +/** + * Process a Menu click in a window, by checking for a registered window + * menu and opening it if one is found. + * + * \param pointer The pointer block from the mouse click event. + * \return true if the click was actioned; else false. + */ + +bool ro_gui_wimp_event_process_window_menu_click(wimp_pointer *pointer) +{ + struct event_window *window; + + window = ro_gui_wimp_event_find_window(pointer->w); + if ((window) && (window->window_menu) + && (pointer->buttons == wimp_CLICK_MENU)) { + int xpos, ypos; + + if (window->menu_prepare) + if (!window->menu_prepare(window->w, wimp_ICON_WINDOW, + window->window_menu, pointer)) + return false; + + if (window->window_menu_iconbar) { + int entry = 0; + int line_height = window->window_menu->height + + window->window_menu->gap; + int gap_height = 24; /* The fixed dotted line height */ + + xpos = pointer->pos.x; + ypos = 96; + do { + ypos += line_height; + if ((window->window_menu-> + entries[entry].menu_flags & + wimp_MENU_SEPARATE) != 0) + ypos += gap_height; + } while ((window->window_menu-> + entries[entry++].menu_flags & + wimp_MENU_LAST) == 0); + } else { + xpos = pointer->pos.x; + ypos = pointer->pos.y; + } + + ro_gui_menu_create(window->window_menu, xpos, ypos, window->w); + return true; + } + return false; +} + + +/** + * Trigger a window's Prepare Menu event. + * + * \param w The window to use. + * \param i The icon to use. + * \param *menu The menu handle to use. + * \return true if the affected menu was prepared OK; else + * false. + */ + +bool ro_gui_wimp_event_prepare_menu(wimp_w w, wimp_i i, wimp_menu *menu) +{ + struct event_window *window; + + window = ro_gui_wimp_event_find_window(w); + if (window == NULL) + return false; + + if (window->menu_prepare) + return window->menu_prepare(w, i, menu, NULL); + + /* The menu is always OK if there's no event handler. */ + + return true; +} + +/** + * Register a window menu to be (semi-)automatically handled. + * + * \param w The window to attach the menu to. + * \param m The menu to be attached. + * \param menu_auto true if the menu should be opened autimatically on + * Menu clicks with no task intervention; false to pass + * clicks to the window's Mouse Event handler and leave + * that to pass the menu click back to us for handling + * and menu opening. + * \param position_ibar true if the menu should open in an iconbar + * position; false to open at the pointer. + * \return true if the menu was registed ok; else false. + */ + +bool ro_gui_wimp_event_register_menu(wimp_w w, wimp_menu *m, + bool menu_auto, bool position_ibar) +{ + struct event_window *window; + + window = ro_gui_wimp_event_get_window(w); + if (!window) + return false; + window->window_menu = m; + window->window_menu_auto = menu_auto; + window->window_menu_iconbar = position_ibar; + return true; +} + +/** + * Register a numeric field to be automatically handled + */ +bool ro_gui_wimp_event_register_numeric_field(wimp_w w, wimp_i i, + wimp_i up, wimp_i down, + int min, int max, int stepping, int decimal_places) +{ + struct icon_event *event; + + event = ro_gui_wimp_event_get_event(w, i, EVENT_NUMERIC_FIELD); + if (!event) + return false; + event->data.numeric_field.min = min; + event->data.numeric_field.max = max; + event->data.numeric_field.stepping = stepping; + event->data.numeric_field.decimal_places = decimal_places; + + event = ro_gui_wimp_event_get_event(w, up, EVENT_UP_ARROW); + if (!event) + return false; + event->data.linked_icon = i; + + event = ro_gui_wimp_event_get_event(w, down, EVENT_DOWN_ARROW); + if (!event) + return false; + event->data.linked_icon = i; + + return true; +} + + +/** + * Register a text field to be automatically handled + */ +bool ro_gui_wimp_event_register_text_field(wimp_w w, wimp_i i) { + struct icon_event *event; + + event = ro_gui_wimp_event_get_event(w, i, EVENT_TEXT_FIELD); + if (!event) + return false; + return true; +} + + +/** + * Register an icon menu to be automatically handled + */ +bool ro_gui_wimp_event_register_menu_gright(wimp_w w, wimp_i i, + wimp_i gright, wimp_menu *menu) +{ + struct icon_event *event; + + event = ro_gui_wimp_event_get_event(w, gright, EVENT_MENU_GRIGHT); + if (!event) + return false; + event->data.menu_gright.field = i; + event->data.menu_gright.menu = menu; + + return ro_gui_wimp_event_register_text_field(w, i); +} + + +/** + * Register a checkbox to be automatically handled + */ +bool ro_gui_wimp_event_register_checkbox(wimp_w w, wimp_i i) +{ + struct icon_event *event; + + event = ro_gui_wimp_event_get_event(w, i, EVENT_CHECKBOX); + if (!event) + return false; + return true; +} + + +/** + * Register a group of radio icons to be automatically handled + */ +bool ro_gui_wimp_event_register_radio(wimp_w w, wimp_i *i) +{ + struct event_window *window; + + window = ro_gui_wimp_event_get_window(w); + if (!window) + return false; + window->max_radio_group++; + + while (*i != -1) { + struct icon_event *event = ro_gui_wimp_event_get_event(w, *i, + EVENT_RADIO); + if (!event) + return false; + event->data.radio_group = window->max_radio_group; + i++; + } + return true; +} + + +/** + * Register a function to be called when a particular button is pressed. + */ +bool ro_gui_wimp_event_register_button(wimp_w w, wimp_i i, + void (*callback)(wimp_pointer *pointer)) +{ + struct icon_event *event; + + event = ro_gui_wimp_event_get_event(w, i, EVENT_BUTTON); + if (!event) + return false; + event->data.callback = callback; + return true; +} + + +/** + * Register a function to be called for the Cancel action on a window. + */ +bool ro_gui_wimp_event_register_cancel(wimp_w w, wimp_i i) +{ + struct icon_event *event; + + event = ro_gui_wimp_event_get_event(w, i, EVENT_CANCEL); + if (!event) + return false; + return true; +} + + +/** + * Register a function to be called for the OK action on a window. + */ +bool ro_gui_wimp_event_register_ok(wimp_w w, wimp_i i, + bool (*callback)(wimp_w w)) +{ + struct event_window *window; + struct icon_event *event; + + window = ro_gui_wimp_event_get_window(w); + if (!window) + return false; + window->ok_click = callback; + + event = ro_gui_wimp_event_get_event(w, i, EVENT_OK); + if (!event) + return false; + return true; +} + + +/** + * Register a function to be called for all mouse-clicks to icons + * in a window that don't have registered actions. + */ +bool ro_gui_wimp_event_register_mouse_click(wimp_w w, + bool (*callback)(wimp_pointer *pointer)) +{ + struct event_window *window; + + window = ro_gui_wimp_event_get_window(w); + if (!window) + return false; + window->mouse_click = callback; + return true; +} + + +/** + * Register a function to be called for all keypresses within a + * particular window. + * + * Important: the character code passed to the callback in key->c + * is UTF-32 (i.e. in the range [0, &10ffff]). WIMP keys (e.g. F1) + * will have bit 31 set. + * + */ +bool ro_gui_wimp_event_register_keypress(wimp_w w, + bool (*callback)(wimp_key *key)) +{ + struct event_window *window; + + window = ro_gui_wimp_event_get_window(w); + if (!window) + return false; + window->keypress = callback; + return true; +} + + +/** + * Register a function to be called for all window opening requests. + */ +bool ro_gui_wimp_event_register_open_window(wimp_w w, + void (*callback)(wimp_open *open)) +{ + struct event_window *window; + + window = ro_gui_wimp_event_get_window(w); + if (!window) + return false; + window->open_window = callback; + return true; +} + +/** + * Register a function to be called after the window has been closed. + */ +bool ro_gui_wimp_event_register_close_window(wimp_w w, + void (*callback)(wimp_w w)) +{ + struct event_window *window; + + window = ro_gui_wimp_event_get_window(w); + if (!window) + return false; + window->close_window = callback; + return true; +} + +/** + * Register a function to be called for all window redraw operations. + */ +bool ro_gui_wimp_event_register_redraw_window(wimp_w w, + void (*callback)(wimp_draw *redraw)) +{ + struct event_window *window; + + window = ro_gui_wimp_event_get_window(w); + if (!window) + return false; + window->redraw_window = callback; + return true; +} + +/** + * Register a function to be called for all window scroll requests. + */ + +bool ro_gui_wimp_event_register_scroll_window(wimp_w w, + void (*callback)(wimp_scroll *scroll)) +{ + struct event_window *window; + + window = ro_gui_wimp_event_get_window(w); + if (!window) + return false; + window->scroll_window = callback; + return true; +} + +/** + * Register a function to be called for all pointer entering window requests. + */ + +bool ro_gui_wimp_event_register_pointer_entering_window(wimp_w w, + void (*callback)(wimp_entering *entering)) +{ + struct event_window *window; + + window = ro_gui_wimp_event_get_window(w); + if (!window) + return false; + window->entering_window = callback; + return true; +} + +/** + * Register a function to be called before a menu is (re-)opened. + * + * \param *w The window for which events should be returned. + * \param *callback A function to be called beofre the menu is + * (re-)opened. + * \return true if the menu was registed ok; else false. + */ +bool ro_gui_wimp_event_register_menu_prepare(wimp_w w, + bool (*callback)(wimp_w w, wimp_i i, wimp_menu *m, + wimp_pointer *p)) +{ + struct event_window *window; + + window = ro_gui_wimp_event_get_window(w); + if (!window) + return false; + window->menu_prepare = callback; + return true; +} + + +/** + * Register a function to be called following a menu selection. + * + * \param *w The window for which events should be returned. + * \param *callback A function to be called when a selection is + * made. + * \return true if the menu was registed ok; else false. + */ +bool ro_gui_wimp_event_register_menu_selection(wimp_w w, + bool (*callback)(wimp_w w, wimp_i i, wimp_menu *m, + wimp_selection *s, menu_action a)) +{ + struct event_window *window; + + window = ro_gui_wimp_event_get_window(w); + if (!window) + return false; + window->menu_selection = callback; + return true; +} + + +/** + * Register a function to be called when a sub-menu warning is received. + * + * \param *w The window for which events should be returned. + * \param *callback A function to be called whenever a submenu + * warning is received for the menu. + * \return true if the menu was registed ok; else false. + */ +bool ro_gui_wimp_event_register_menu_warning(wimp_w w, + void (*callback)(wimp_w w, wimp_i i, wimp_menu *m, + wimp_selection *s, menu_action a)) +{ + struct event_window *window; + + window = ro_gui_wimp_event_get_window(w); + if (!window) + return false; + window->menu_warning = callback; + return true; +} + + +/** + * Register a function to be called before a menu is finally closed. + * + * \param *w The window for which events should be returned. + * \param *callback A function to be called when the menu is closed. + * \return true if the menu was registed ok; else false. + */ +bool ro_gui_wimp_event_register_menu_close(wimp_w w, + void (*callback)(wimp_w w, wimp_i i, wimp_menu *m)) +{ + struct event_window *window; + + window = ro_gui_wimp_event_get_window(w); + if (!window) + return false; + window->menu_close = callback; + return true; +} + + +/** + * Finds the event data associated with a given window handle, or creates a + * new one. + * + * \param w the window to find data for + */ +struct event_window *ro_gui_wimp_event_get_window(wimp_w w) +{ + struct event_window *window; + int h; + + assert((int)w != 0); + window = ro_gui_wimp_event_find_window(w); + if (window) + return window; + + LOG("Creating structure for window 0x%x", (unsigned int)w); + window = calloc(1, sizeof(struct event_window)); + if (!window) + return NULL; + + h = WIN_HASH(w); + window->w = w; + window->next = ro_gui_wimp_event_windows[h]; + ro_gui_wimp_event_windows[h] = window; + return window; +} + + +/** + * Removes the event data associated with a given handle from the hash tables, + * but does not delete it. + * + * \param w the window to be removed + * \return pointer to the event data or NULL if not found + */ + +struct event_window *ro_gui_wimp_event_remove_window(wimp_w w) +{ + struct event_window **prev; + int h = WIN_HASH(w); + + /* search hash chain for the window */ + prev = &ro_gui_wimp_event_windows[h]; + while (*prev) { + struct event_window *window = *prev; + + if (window->w == w) { + /* remove from chain */ + *prev = window->next; + return window; + } + prev = &window->next; + } + + /* not found */ + return NULL; +} + +/** + * Find the event data associated with a given window handle + * + * \param w the window to find data for + */ +struct event_window *ro_gui_wimp_event_find_window(wimp_w w) +{ + struct event_window *window; + int h = WIN_HASH(w); + + /* search hash chain for window */ + for (window = ro_gui_wimp_event_windows[h]; window; window = window->next) { + if (window->w == w) + return window; + } + return NULL; +} + +struct icon_event *ro_gui_wimp_event_get_event(wimp_w w, wimp_i i, + event_type type) +{ + struct event_window *window; + struct icon_event *event; + + window = ro_gui_wimp_event_get_window(w); + if (!window) + return NULL; + + for (event = window->first; event; event = event->next) { + if (event->i == i) { + event->type = type; + return event; + } + } + + event = calloc(1, sizeof(struct icon_event)); + if (!event) + return NULL; + event->i = i; + event->type = type; + event->next = window->first; + window->first = event; + + return event; +} + +/* Handle sumbenu warnings. This is called from ro_gui_menu_warning(), and + * returns to that function to have the submenu opened correctly. + * + * \param w the window to owning the menu + * \param i the icon owning the menu + * \param menu the menu that has been selected + * \param selection the selection information + * \param action the menu action info from menus.c + * \return true if the event was handled, false otherwise + */ + +bool ro_gui_wimp_event_submenu_warning(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_selection *selection, menu_action action) +{ + struct event_window *window; + struct icon_event *event; + + ro_gui_wimp_event_register_submenu(0); + + /* Process the event for any window menus. Find the window data, then + * try and match to an icon event. If we can, then there isn't anything + * to do. + */ + + window = ro_gui_wimp_event_find_window(w); + if (!window) + return false; + + for (event = window->first; event; event = event->next) + if ((event->type == EVENT_MENU_GRIGHT) && (event->i == i)) + break; + if (event) { + if (window->menu_close != NULL && + event->type == EVENT_MENU_GRIGHT && + event->data.menu_gright.menu == menu) { + window->menu_close(w, i, menu); + return true; + } + + return false; + } + + /* If the warning is for a window menu, then pass the event on to it. */ + + if ((window->window_menu) && (window->window_menu == menu)) { + if (window->menu_warning) { + window->menu_warning(w, wimp_ICON_WINDOW, menu, + selection, action); + return true; + } + } + + return false; +} + +/** + * Handle menus being closed. This is called from the menus modules, in + * every scenario when one of our own menus is open. + * + * \param w the window to owning the menu + * \param i the icon owning the menu + * \param menu the menu that has been selected + */ + +void ro_gui_wimp_event_menus_closed(wimp_w w, wimp_i i, wimp_menu *menu) +{ + struct event_window *window; + struct icon_event *event; + + ro_gui_wimp_event_register_submenu(0); + + /* Process the event for any window menus. Find the window data, then + * try and match to an icon event. If we can, then GRight menus are + * sent the event; otherwise, we do nothing. + */ + + window = ro_gui_wimp_event_find_window(w); + if (!window) + return; + + for (event = window->first; event; event = event->next) + if ((event->type == EVENT_MENU_GRIGHT) && (event->i == i)) + break; + if (event) { + if (window->menu_close != NULL && + event->type == EVENT_MENU_GRIGHT && + event->data.menu_gright.menu == menu) + window->menu_close(w, i, menu); + return; + } + + /* If the close is for a window menu, then pass the event on to it. */ + + if ((window->window_menu) && (window->window_menu == menu) && + (window->menu_close)) + window->menu_close(w, wimp_ICON_WINDOW, menu); +} + +/** + * Register a submenu as being opened + */ +void ro_gui_wimp_event_register_submenu(wimp_w w) +{ + if (ro_gui_wimp_event_submenu) + ro_gui_wimp_event_close_window(ro_gui_wimp_event_submenu); + ro_gui_wimp_event_submenu = w; +} + diff --git a/frontends/riscos/wimp_event.h b/frontends/riscos/wimp_event.h new file mode 100644 index 000000000..0a54ab04d --- /dev/null +++ b/frontends/riscos/wimp_event.h @@ -0,0 +1,116 @@ +/*
+ * Copyright 2005 Richard Wilson <info@tinct.net>
+ * Copyright 2010, 2011 Stephen Fryatt <stevef@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** \file
+ * Automated RISC OS WIMP event handling (interface).
+ */
+
+
+#ifndef _NETSURF_RISCOS_WIMP_EVENT_H_
+#define _NETSURF_RISCOS_WIMP_EVENT_H_
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "oslib/os.h"
+#include "oslib/wimp.h"
+#include "riscos/menus.h"
+
+#define IS_WIMP_KEY (1u<<31)
+
+bool ro_gui_wimp_event_memorise(wimp_w w);
+bool ro_gui_wimp_event_restore(wimp_w w);
+bool ro_gui_wimp_event_validate(wimp_w w);
+bool ro_gui_wimp_event_transfer(wimp_w from, wimp_w to);
+void ro_gui_wimp_event_finalise(wimp_w w);
+void ro_gui_wimp_event_deregister(wimp_w w, wimp_i i);
+
+bool ro_gui_wimp_event_set_help_prefix(wimp_w w, const char *help_prefix);
+const char *ro_gui_wimp_event_get_help_prefix(wimp_w w);
+bool ro_gui_wimp_event_register_help_suffix(wimp_w w,
+ const char *(*get_help_suffix)(wimp_w w, wimp_i i,
+ os_coord *pos, wimp_mouse_state buttons));
+const char *ro_gui_wimp_event_get_help_suffix(wimp_w w, wimp_i i,
+ os_coord *pos, wimp_mouse_state buttons);
+bool ro_gui_wimp_event_set_user_data(wimp_w w, void *user);
+void *ro_gui_wimp_event_get_user_data(wimp_w w);
+
+bool ro_gui_wimp_event_menu_selection(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_selection *selection, menu_action action);
+bool ro_gui_wimp_event_mouse_click(wimp_pointer *pointer);
+bool ro_gui_wimp_event_keypress(wimp_key *key);
+bool ro_gui_wimp_event_open_window(wimp_open *open);
+bool ro_gui_wimp_event_close_window(wimp_w w);
+bool ro_gui_wimp_event_redraw_window(wimp_draw *redraw);
+bool ro_gui_wimp_event_scroll_window(wimp_scroll *scroll);
+bool ro_gui_wimp_event_pointer_entering_window(wimp_entering *entering);
+
+bool ro_gui_wimp_event_process_window_menu_click(wimp_pointer *pointer);
+bool ro_gui_wimp_event_prepare_menu(wimp_w w, wimp_i i, wimp_menu *menu);
+
+bool ro_gui_wimp_event_register_menu(wimp_w w, wimp_menu *m,
+ bool menu_auto, bool position_ibar);
+bool ro_gui_wimp_event_register_numeric_field(wimp_w w, wimp_i i, wimp_i up,
+ wimp_i down, int min, int max, int stepping,
+ int decimal_places);
+bool ro_gui_wimp_event_register_text_field(wimp_w w, wimp_i i);
+bool ro_gui_wimp_event_register_menu_gright(wimp_w w, wimp_i i,
+ wimp_i gright, wimp_menu *menu);
+bool ro_gui_wimp_event_register_checkbox(wimp_w w, wimp_i i);
+bool ro_gui_wimp_event_register_radio(wimp_w w, wimp_i *i);
+bool ro_gui_wimp_event_register_button(wimp_w w, wimp_i i,
+ void (*callback)(wimp_pointer *pointer));
+bool ro_gui_wimp_event_register_cancel(wimp_w w, wimp_i i);
+bool ro_gui_wimp_event_register_ok(wimp_w w, wimp_i i,
+ bool (*callback)(wimp_w w));
+
+bool ro_gui_wimp_event_register_mouse_click(wimp_w w,
+ bool (*callback)(wimp_pointer *pointer));
+bool ro_gui_wimp_event_register_keypress(wimp_w w,
+ bool (*callback)(wimp_key *key));
+bool ro_gui_wimp_event_register_open_window(wimp_w w,
+ void (*callback)(wimp_open *open));
+bool ro_gui_wimp_event_register_close_window(wimp_w w,
+ void (*callback)(wimp_w w));
+bool ro_gui_wimp_event_register_redraw_window(wimp_w w,
+ void (*callback)(wimp_draw *redraw));
+bool ro_gui_wimp_event_register_scroll_window(wimp_w w,
+ void (*callback)(wimp_scroll *scroll));
+bool ro_gui_wimp_event_register_pointer_entering_window(wimp_w w,
+ void (*callback)(wimp_entering *entering));
+bool ro_gui_wimp_event_register_menu_prepare(wimp_w w,
+ bool (*callback)(wimp_w w, wimp_i i, wimp_menu *m,
+ wimp_pointer *p));
+bool ro_gui_wimp_event_register_menu_selection(wimp_w w,
+ bool (*callback)(wimp_w w, wimp_i i, wimp_menu *m,
+ wimp_selection *s, menu_action a));
+bool ro_gui_wimp_event_register_menu_warning(wimp_w w,
+ void (*callback)(wimp_w w, wimp_i i, wimp_menu *m,
+ wimp_selection *s, menu_action a));
+bool ro_gui_wimp_event_register_menu_close(wimp_w w,
+ void (*callback)(wimp_w w, wimp_i i, wimp_menu *m));
+
+bool ro_gui_wimp_event_submenu_warning(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_selection *selection, menu_action action);
+void ro_gui_wimp_event_menus_closed(wimp_w w, wimp_i i, wimp_menu *menu);
+void ro_gui_wimp_event_register_submenu(wimp_w w);
+
+#endif
diff --git a/frontends/riscos/wimputils.h b/frontends/riscos/wimputils.h new file mode 100644 index 000000000..5225a720e --- /dev/null +++ b/frontends/riscos/wimputils.h @@ -0,0 +1,65 @@ +/* + * Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * A collection of grubby utilities for working with OSLib's wimp API. + */ + +#ifndef riscos_wimputils_h_ +#define riscos_wimputils_h_ + +#include <oslib/wimp.h> + +/* Magical union to permit aliasing of wimp_window_state and wimp_open + * Do not use this directly. Use the macros, instead. */ +typedef union window_open_state { + wimp_window_state state; + wimp_open open; +} window_open_state; + +/* Convert a pointer to a wimp_window_state into a pointer to a wimp_open */ +#define PTR_WIMP_OPEN(pstate) ((wimp_open *) (window_open_state *) (pstate)) + +/* Similarly for wimp_message_list */ +typedef struct ns_wimp_message_list { + /* Nasty hack to ensure that we have at least one field in the struct */ + int first; + int rest[]; +} ns_wimp_message_list; + +typedef union message_list { + wimp_message_list wimp; + ns_wimp_message_list ns; +} message_list; + +#define PTR_WIMP_MESSAGE_LIST(l) ((wimp_message_list *) (message_list *) (l)) + +/* Also for VDU variable lists */ +typedef struct ns_os_vdu_var_list { + os_vdu_var first; + os_vdu_var rest[]; +} ns_os_vdu_var_list; + +typedef union vdu_var_list { + os_vdu_var_list os; + ns_os_vdu_var_list ns; +} vdu_var_list; + +#define PTR_OS_VDU_VAR_LIST(l) ((os_vdu_var_list *) (vdu_var_list *) (l)) + +#endif diff --git a/frontends/riscos/window.c b/frontends/riscos/window.c new file mode 100644 index 000000000..ab1501cd6 --- /dev/null +++ b/frontends/riscos/window.c @@ -0,0 +1,5025 @@ +/* + * Copyright 2003 Phil Mellor <monkeyson@users.sourceforge.net> + * Copyright 2004 James Bursa <bursa@users.sourceforge.net> + * Copyright 2003 John M Bell <jmb202@ecs.soton.ac.uk> + * Copyright 2004 Andrew Timmins <atimmins@blueyonder.co.uk> + * Copyright 2005 Richard Wilson <info@tinct.net> + * Copyright 2005 Adrian Lees <adrianl@users.sourceforge.net> + * Copyright 2010-2014 Stephen Fryatt <stevef@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * \file + * Implementation of RISC OS browser window handling. + */ + +#include <assert.h> +#include <ctype.h> +#include <inttypes.h> +#include <math.h> +#include <stdio.h> +#include <stdbool.h> +#include <time.h> +#include <string.h> +#include <oslib/colourtrans.h> +#include <oslib/osbyte.h> +#include <oslib/osfile.h> +#include <oslib/osspriteop.h> +#include <oslib/wimp.h> +#include <oslib/wimpspriteop.h> +#include <nsutils/time.h> + +#include "utils/config.h" +#include "utils/nsoption.h" +#include "utils/log.h" +#include "utils/talloc.h" +#include "utils/file.h" +#include "utils/utf8.h" +#include "utils/utils.h" +#include "utils/messages.h" +#include "utils/string.h" +#include "content/content.h" +#include "content/hlcache.h" +#include "content/urldb.h" +#include "desktop/browser_history.h" +#include "desktop/browser.h" +#include "desktop/cookie_manager.h" +#include "desktop/scrollbar.h" +#include "desktop/frames.h" +#include "desktop/mouse.h" +#include "desktop/plotters.h" +#include "desktop/textinput.h" +#include "desktop/tree.h" +#include "desktop/gui_window.h" +#include "image/bitmap.h" +#include "render/form.h" + +#include "riscos/bitmap.h" +#include "riscos/buffer.h" +#include "riscos/cookies.h" +#include "riscos/dialog.h" +#include "riscos/global_history.h" +#include "riscos/gui.h" +#include "riscos/gui/status_bar.h" +#include "riscos/help.h" +#include "riscos/hotlist.h" +#include "riscos/menus.h" +#include "riscos/mouse.h" +#include "riscos/oslib_pre7.h" +#include "riscos/save.h" +#include "riscos/content-handlers/sprite.h" +#include "riscos/textselection.h" +#include "riscos/toolbar.h" +#include "riscos/url_complete.h" +#include "riscos/url_suggest.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" +#include "riscos/wimputils.h" +#include "riscos/window.h" +#include "riscos/ucstables.h" +#include "riscos/filetype.h" + +void gui_window_redraw_window(struct gui_window *g); + +static void gui_window_set_extent(struct gui_window *g, int width, int height); + +static void ro_gui_window_redraw(wimp_draw *redraw); +static void ro_gui_window_scroll(wimp_scroll *scroll); +static void ro_gui_window_pointer_entering(wimp_entering *entering); +static void ro_gui_window_track_end(wimp_leaving *leaving, void *data); +static void ro_gui_window_open(wimp_open *open); +static void ro_gui_window_close(wimp_w w); +static bool ro_gui_window_click(wimp_pointer *mouse); +static bool ro_gui_window_keypress(wimp_key *key); +static bool ro_gui_window_toolbar_keypress(void *data, wimp_key *key); +static bool ro_gui_window_handle_local_keypress(struct gui_window *g, + wimp_key *key, bool is_toolbar); +static bool ro_gui_window_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_pointer *pointer); +static void ro_gui_window_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_selection *selection, menu_action action); +static bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_selection *selection, menu_action action); +static void ro_gui_window_menu_close(wimp_w w, wimp_i i, wimp_menu *menu); + +static void ro_gui_window_scroll_end(wimp_dragged *drag, void *data); + +static void ro_gui_window_scroll_action(struct gui_window *g, + int scroll_x, int scroll_y); + +static void ro_gui_window_toolbar_click(void *data, + toolbar_action_type action_type, union toolbar_action action); + +static bool ro_gui_window_content_export_types(hlcache_handle *h, + bool *export_draw, bool *export_sprite); +static void ro_gui_window_prepare_pageinfo(struct gui_window *g); +static void ro_gui_window_prepare_objectinfo(hlcache_handle *object, + nsurl *target_url); + +static void ro_gui_window_launch_url(struct gui_window *g, const char *url); +static void ro_gui_window_action_home(struct gui_window *g); +static void ro_gui_window_action_new_window(struct gui_window *g); +static void ro_gui_window_action_local_history(struct gui_window *g); +static void ro_gui_window_action_save(struct gui_window *g, + gui_save_type save_type); +static void ro_gui_window_action_search(struct gui_window *g); +static void ro_gui_window_action_zoom(struct gui_window *g); +static void ro_gui_window_action_add_bookmark(struct gui_window *g); +static void ro_gui_window_action_remove_bookmark(struct gui_window *g); +static void ro_gui_window_action_print(struct gui_window *g); +static void ro_gui_window_action_page_info(struct gui_window *g); + +static void ro_gui_window_remove_update_boxes(struct gui_window *g); +static void ro_gui_window_update_toolbar_buttons(struct gui_window *g); +static void ro_gui_window_update_toolbar(void *data); +static void ro_gui_window_save_toolbar_buttons(void *data, char *config); +static void ro_gui_window_update_theme(void *data, bool ok); + +static bool ro_gui_window_import_text(struct gui_window *g, + const char *filename); +static void ro_gui_window_clone_options( + struct gui_window *new_gui, + struct gui_window *old_gui); + +static bool ro_gui_window_prepare_form_select_menu(struct gui_window *bw, + struct form_control *control); +static void ro_gui_window_process_form_select_menu(struct gui_window *g, + wimp_selection *selection); + +#ifndef wimp_KEY_END +#define wimp_KEY_END wimp_KEY_COPY +#endif + +#ifndef wimp_WINDOW_GIVE_SHADED_ICON_INFO + /* RISC OS 5+. Requires OSLib trunk. */ +#define wimp_WINDOW_GIVE_SHADED_ICON_INFO ((wimp_extra_window_flags) 0x10u) +#endif + +#define SCROLL_VISIBLE_PADDING 32 + +/** Remembers which iconised sprite numbers are in use */ +static bool iconise_used[64]; +static int iconise_next = 0; + +/** Whether a pressed mouse button has become a drag */ +static bool mouse_drag_select; +static bool mouse_drag_adjust; + +/** List of all browser windows. */ +static struct gui_window *window_list = 0; +/** GUI window which is being redrawn. Valid only during redraw. */ +struct gui_window *ro_gui_current_redraw_gui; +/** Form control which gui_form_select_menu is for. */ +static struct form_control *gui_form_select_control; +/** The browser window menu handle. */ +static wimp_menu *ro_gui_browser_window_menu = NULL; +/** Menu of options for form select controls. */ +static wimp_menu *gui_form_select_menu = NULL; +/** Main content object under menu, or 0 if none. */ +static hlcache_handle *current_menu_main = 0; +/** Object under menu, or 0 if no object. */ +static hlcache_handle *current_menu_object = 0; +/** URL of link under menu, or 0 if no link. */ +static nsurl *current_menu_url = 0; + +static float scale_snap_to[] = {0.10, 0.125, 0.25, 0.333, 0.5, 0.75, + 1.0, + 1.5, 2.0, 3.0, 4.0, 6.0, 8.0, 12.0, 16.0}; +#define SCALE_SNAP_TO_SIZE (sizeof scale_snap_to) / (sizeof(float)) + +/** An entry in ro_gui_pointer_table. */ +struct ro_gui_pointer_entry { + bool wimp_area; /** The pointer is in the Wimp's sprite area. */ + char sprite_name[16]; + int xactive; + int yactive; +}; + +/** Map from gui_pointer_shape to pointer sprite data. Must be ordered as + * enum gui_pointer_shape. */ +struct ro_gui_pointer_entry ro_gui_pointer_table[] = { + { true, "ptr_default", 0, 0 }, + { false, "ptr_point", 6, 0 }, + { false, "ptr_caret", 4, 9 }, + { false, "ptr_menu", 6, 4 }, + { false, "ptr_ud", 6, 7 }, + { false, "ptr_ud", 6, 7 }, + { false, "ptr_lr", 7, 6 }, + { false, "ptr_lr", 7, 6 }, + { false, "ptr_ld", 7, 7 }, + { false, "ptr_ld", 7, 7 }, + { false, "ptr_rd", 7, 7 }, + { false, "ptr_rd", 6, 7 }, + { false, "ptr_cross", 7, 7 }, + { false, "ptr_move", 8, 0 }, + { false, "ptr_wait", 7, 10 }, + { false, "ptr_help", 0, 0 }, + { false, "ptr_nodrop", 0, 0 }, + { false, "ptr_nt_allwd", 10, 10 }, + { false, "ptr_progress", 0, 0 }, +}; + +struct update_box { + int x0; + int y0; + int x1; + int y1; + bool use_buffer; + struct gui_window *g; + struct update_box *next; +}; + +struct update_box *pending_updates; +#define MARGIN 4 + +static const struct toolbar_callbacks ro_gui_window_toolbar_callbacks = { + ro_gui_window_update_theme, + ro_gui_window_update_toolbar, + (void (*)(void *)) ro_gui_window_update_toolbar_buttons, + ro_gui_window_toolbar_click, + ro_gui_window_toolbar_keypress, + ro_gui_window_save_toolbar_buttons +}; + + +/** + * Initialise the browser window module and its menus. + */ + +void ro_gui_window_initialise(void) +{ + /* Build the browser window menu. */ + + static const struct ns_menu browser_definition = { + "NetSurf", { + { "Page", BROWSER_PAGE, 0 }, + { "Page.PageInfo",BROWSER_PAGE_INFO, &dialog_pageinfo }, + { "Page.Save", BROWSER_SAVE, &dialog_saveas }, + { "Page.SaveComp", BROWSER_SAVE_COMPLETE, &dialog_saveas }, + { "Page.Export", NO_ACTION, 0 }, +#ifdef WITH_DRAW_EXPORT + { "Page.Export.Draw", BROWSER_EXPORT_DRAW, &dialog_saveas }, +#endif +#ifdef WITH_PDF_EXPORT + { "Page.Export.PDF", BROWSER_EXPORT_PDF, &dialog_saveas }, +#endif + { "Page.Export.Text", BROWSER_EXPORT_TEXT, &dialog_saveas }, + { "Page.SaveURL", NO_ACTION, 0 }, + { "Page.SaveURL.URI", BROWSER_SAVE_URL_URI, &dialog_saveas }, + { "Page.SaveURL.URL", BROWSER_SAVE_URL_URL, &dialog_saveas }, + { "Page.SaveURL.LinkText", BROWSER_SAVE_URL_TEXT, &dialog_saveas }, + { "_Page.Print", BROWSER_PRINT, &dialog_print }, + { "Page.NewWindow", BROWSER_NEW_WINDOW, 0 }, + { "Page.FindText", BROWSER_FIND_TEXT, &dialog_search }, + { "Page.ViewSrc", BROWSER_VIEW_SOURCE, 0 }, + { "Object", BROWSER_OBJECT, 0 }, + { "Object.Object", BROWSER_OBJECT_OBJECT, 0 }, + { "Object.Object.ObjInfo", BROWSER_OBJECT_INFO, &dialog_objinfo }, + { "Object.Object.ObjSave", BROWSER_OBJECT_SAVE, &dialog_saveas }, + { "Object.Object.Export", BROWSER_OBJECT_EXPORT, 0 }, + { "Object.Object.Export.Sprite", BROWSER_OBJECT_EXPORT_SPRITE, &dialog_saveas }, +#ifdef WITH_DRAW_EXPORT + { "Object.Object.Export.ObjDraw", BROWSER_OBJECT_EXPORT_DRAW, &dialog_saveas }, +#endif + { "Object.Object.SaveURL", NO_ACTION, 0 }, + { "Object.Object.SaveURL.URI", BROWSER_OBJECT_SAVE_URL_URI, &dialog_saveas }, + { "Object.Object.SaveURL.URL", BROWSER_OBJECT_SAVE_URL_URL, &dialog_saveas }, + { "Object.Object.SaveURL.LinkText", BROWSER_OBJECT_SAVE_URL_TEXT, &dialog_saveas }, + { "Object.Object.ObjPrint", BROWSER_OBJECT_PRINT, 0 }, + { "Object.Object.ObjReload", BROWSER_OBJECT_RELOAD, 0 }, + { "Object.Link", BROWSER_OBJECT_LINK, 0 }, + { "Object.Link.LinkSave", BROWSER_LINK_SAVE, 0 }, + { "Object.Link.LinkSave.URI", BROWSER_LINK_SAVE_URI, &dialog_saveas }, + { "Object.Link.LinkSave.URL", BROWSER_LINK_SAVE_URL, &dialog_saveas }, + { "Object.Link.LinkSave.LinkText", BROWSER_LINK_SAVE_TEXT, &dialog_saveas }, + { "_Object.Link.LinkDload", BROWSER_LINK_DOWNLOAD, 0 }, + { "Object.Link.LinkNew", BROWSER_LINK_NEW_WINDOW, 0 }, + { "Selection", BROWSER_SELECTION, 0 }, + { "_Selection.SelSave", BROWSER_SELECTION_SAVE, &dialog_saveas }, + { "Selection.Copy", BROWSER_SELECTION_COPY, 0 }, + { "Selection.Cut", BROWSER_SELECTION_CUT, 0 }, + { "_Selection.Paste", BROWSER_SELECTION_PASTE, 0 }, + { "Selection.Clear", BROWSER_SELECTION_CLEAR, 0 }, + { "Selection.SelectAll", BROWSER_SELECTION_ALL, 0 }, + { "Navigate", NO_ACTION, 0 }, + { "Navigate.Home", BROWSER_NAVIGATE_HOME, 0 }, + { "Navigate.Back", BROWSER_NAVIGATE_BACK, 0 }, + { "Navigate.Forward", BROWSER_NAVIGATE_FORWARD, 0 }, + { "_Navigate.UpLevel", BROWSER_NAVIGATE_UP, 0 }, + { "Navigate.Reload", BROWSER_NAVIGATE_RELOAD_ALL, 0 }, + { "Navigate.Stop", BROWSER_NAVIGATE_STOP, 0 }, + { "View", NO_ACTION, 0 }, + { "View.ScaleView", BROWSER_SCALE_VIEW, &dialog_zoom }, + { "View.Images", NO_ACTION, 0 }, + { "View.Images.ForeImg", BROWSER_IMAGES_FOREGROUND, 0 }, + { "View.Images.BackImg", BROWSER_IMAGES_BACKGROUND, 0 }, + { "View.Toolbars", NO_ACTION, 0 }, + { "View.Toolbars.ToolButtons", TOOLBAR_BUTTONS, 0 }, + { "View.Toolbars.ToolAddress", TOOLBAR_ADDRESS_BAR, 0 }, + { "_View.Toolbars.ToolThrob", TOOLBAR_THROBBER, 0 }, + { "View.Toolbars.EditToolbar", TOOLBAR_EDIT, 0 }, + { "_View.Render", NO_ACTION, 0 }, + { "View.Render.RenderAnims", BROWSER_BUFFER_ANIMS, 0 }, + { "View.Render.RenderAll", BROWSER_BUFFER_ALL, 0 }, + { "_View.OptDefault", BROWSER_SAVE_VIEW, 0 }, + { "View.Window", NO_ACTION, 0 }, + { "View.Window.WindowSave", BROWSER_WINDOW_DEFAULT, 0 }, + { "View.Window.WindowStagr", BROWSER_WINDOW_STAGGER, 0 }, + { "_View.Window.WindowSize", BROWSER_WINDOW_COPY, 0 }, + { "View.Window.WindowReset", BROWSER_WINDOW_RESET, 0 }, + { "Utilities", NO_ACTION, 0 }, + { "Utilities.Hotlist", HOTLIST_SHOW, 0 }, + { "Utilities.Hotlist.HotlistAdd", HOTLIST_ADD_URL, 0 }, + { "Utilities.Hotlist.HotlistShow", HOTLIST_SHOW, 0 }, + { "Utilities.History", HISTORY_SHOW_GLOBAL, 0 }, + { "Utilities.History.HistLocal", HISTORY_SHOW_LOCAL, 0 }, + { "Utilities.History.HistGlobal", HISTORY_SHOW_GLOBAL, 0 }, + { "Utilities.Cookies", COOKIES_SHOW, 0 }, + { "Utilities.Cookies.ShowCookies", COOKIES_SHOW, 0 }, + { "Utilities.Cookies.DeleteCookies", COOKIES_DELETE, 0 }, + { "Help", HELP_OPEN_CONTENTS, 0 }, + { "Help.HelpContent", HELP_OPEN_CONTENTS, 0 }, + { "Help.HelpGuide", HELP_OPEN_GUIDE, 0 }, + { "_Help.HelpInfo", HELP_OPEN_INFORMATION, 0 }, + { "Help.HelpCredits", HELP_OPEN_CREDITS, 0 }, + { "_Help.HelpLicence", HELP_OPEN_LICENCE, 0 }, + { "Help.HelpInter", HELP_LAUNCH_INTERACTIVE, 0 }, + {NULL, 0, 0} + } + }; + ro_gui_browser_window_menu = + ro_gui_menu_define_menu(&browser_definition); + +} + + +/* + * Interface With Core + */ + +/** + * Place the caret in a browser window. + * + * \param g window with caret + * \param x coordinates of caret + * \param y coordinates of caret + * \param height height of caret + * \param clip clip rectangle, or NULL if none + */ + +static void gui_window_place_caret(struct gui_window *g, int x, int y, int height, + const struct rect *clip) +{ + os_error *error; + + error = xwimp_set_caret_position(g->window, -1, + x * 2, -(y + height) * 2, height * 2, -1); + if (error) { + LOG("xwimp_set_caret_position: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } +} + +/** + * Create and open a new browser window. + * + * \param bw bw to create gui_window for + * \param existing an existing gui_window, may be NULL + * \param flags flags for gui window creation + * \return gui window, or NULL on error + */ + +static struct gui_window *gui_window_create(struct browser_window *bw, + struct gui_window *existing, + gui_window_create_flags flags) +{ + int screen_width, screen_height; + static int window_count = 2; + wimp_window window; + wimp_window_state state; + os_error *error; + bool open_centred = true; + struct gui_window *g; + + g = malloc(sizeof *g); + if (!g) { + ro_warn_user("NoMemory", 0); + return 0; + } + g->bw = bw; + g->toolbar = 0; + g->status_bar = 0; + g->old_width = 0; + g->old_height = 0; + g->update_extent = true; + g->active = false; + strcpy(g->title, "NetSurf"); + g->iconise_icon = -1; + g->scale = browser_window_get_scale(bw); + + /* Set the window position */ + if (existing != NULL && + flags & GW_CREATE_CLONE && + nsoption_bool(window_size_clone)) { + state.w = existing->window; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + window.visible.x0 = state.visible.x0; + window.visible.x1 = state.visible.x1; + window.visible.y0 = state.visible.y0 - 48; + window.visible.y1 = state.visible.y1 - 48; + open_centred = false; + } else { + int win_width, win_height; + ro_gui_screen_size(&screen_width, &screen_height); + + /* Check if we have a preferred position */ + if ((nsoption_int(window_screen_width) != 0) && + (nsoption_int(window_screen_height) != 0)) { + win_width = (nsoption_int(window_width) * + screen_width) / + nsoption_int(window_screen_width); + win_height = (nsoption_int(window_height) * + screen_height) / + nsoption_int(window_screen_height); + window.visible.x0 = (nsoption_int(window_x) * + screen_width) / + nsoption_int(window_screen_width); + window.visible.y0 = (nsoption_int(window_y) * + screen_height) / + nsoption_int(window_screen_height); + if (nsoption_bool(window_stagger)) { + window.visible.y0 += 96 - + (48 * (window_count % 5)); + } + open_centred = false; + if (win_width < 100) + win_width = 100; + if (win_height < 100) + win_height = 100; + } else { + + /* Base how we define the window height/width + on the compile time options set */ + win_width = screen_width * 3 / 4; + if (1600 < win_width) + win_width = 1600; + win_height = win_width * 3 / 4; + + window.visible.x0 = (screen_width - win_width) / 2; + window.visible.y0 = ((screen_height - win_height) / 2) + + 96 - (48 * (window_count % 5)); + } + window.visible.x1 = window.visible.x0 + win_width; + window.visible.y1 = window.visible.y0 + win_height; + } + + /* General flags for a non-movable, non-resizable, no-title bar window */ + window.xscroll = 0; + window.yscroll = 0; + window.next = wimp_TOP; + window.flags = wimp_WINDOW_MOVEABLE | + wimp_WINDOW_NEW_FORMAT | + wimp_WINDOW_VSCROLL | + wimp_WINDOW_HSCROLL | + wimp_WINDOW_IGNORE_XEXTENT | + wimp_WINDOW_IGNORE_YEXTENT | + wimp_WINDOW_SCROLL_REPEAT; + window.title_fg = wimp_COLOUR_BLACK; + window.title_bg = wimp_COLOUR_LIGHT_GREY; + window.work_fg = wimp_COLOUR_LIGHT_GREY; + window.work_bg = wimp_COLOUR_TRANSPARENT; + window.scroll_outer = wimp_COLOUR_DARK_GREY; + window.scroll_inner = wimp_COLOUR_MID_LIGHT_GREY; + window.highlight_bg = wimp_COLOUR_CREAM; + window.extra_flags = wimp_WINDOW_USE_EXTENDED_SCROLL_REQUEST | + wimp_WINDOW_GIVE_SHADED_ICON_INFO; + window.extent.x0 = 0; + window.extent.y0 = -(window.visible.y1 - window.visible.y0); + window.extent.x1 = window.visible.x1 - window.visible.x0; + window.extent.y1 = 0; + window.title_flags = wimp_ICON_TEXT | + wimp_ICON_INDIRECTED | + wimp_ICON_HCENTRED; + window.work_flags = wimp_BUTTON_DOUBLE_CLICK_DRAG << + wimp_ICON_BUTTON_TYPE_SHIFT; + window.sprite_area = wimpspriteop_AREA; + window.xmin = 1; + window.ymin = 1; + window.title_data.indirected_text.text = g->title; + window.title_data.indirected_text.validation = (char *) -1; + window.title_data.indirected_text.size = 255; + window.icon_count = 0; + + /* Add in flags */ + window.flags |= wimp_WINDOW_SIZE_ICON | + wimp_WINDOW_BACK_ICON | + wimp_WINDOW_CLOSE_ICON | + wimp_WINDOW_TITLE_ICON | + wimp_WINDOW_TOGGLE_ICON; + + if (open_centred) { + int scroll_width = ro_get_vscroll_width(NULL); + window.visible.x0 -= scroll_width; + } + + error = xwimp_create_window(&window, &g->window); + if (error) { + LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + free(g); + return 0; + } + + /* Link into window list */ + g->prev = 0; + g->next = window_list; + if (window_list) + window_list->prev = g; + window_list = g; + window_count++; + + /* Add in a toolbar and status bar */ + g->status_bar = ro_gui_status_bar_create(g->window, + nsoption_int(toolbar_status_size)); + g->toolbar = ro_toolbar_create(NULL, g->window, + THEME_STYLE_BROWSER_TOOLBAR, TOOLBAR_FLAGS_NONE, + &ro_gui_window_toolbar_callbacks, g, + "HelpToolbar"); + if (g->toolbar != NULL) { + ro_toolbar_add_buttons(g->toolbar, + brower_toolbar_buttons, + nsoption_charp(toolbar_browser)); + ro_toolbar_add_url(g->toolbar); + ro_toolbar_add_throbber(g->toolbar); + ro_toolbar_rebuild(g->toolbar); + } + + /* Register event handlers. Do this quickly, as some of the things + * that follow will indirectly look up our user data: this MUST + * be set first! + */ + ro_gui_wimp_event_set_user_data(g->window, g); + ro_gui_wimp_event_register_open_window(g->window, ro_gui_window_open); + ro_gui_wimp_event_register_close_window(g->window, ro_gui_window_close); + ro_gui_wimp_event_register_redraw_window(g->window, ro_gui_window_redraw); + ro_gui_wimp_event_register_scroll_window(g->window, ro_gui_window_scroll); + ro_gui_wimp_event_register_pointer_entering_window(g->window, ro_gui_window_pointer_entering); + ro_gui_wimp_event_register_keypress(g->window, ro_gui_window_keypress); + ro_gui_wimp_event_register_mouse_click(g->window, ro_gui_window_click); + ro_gui_wimp_event_register_menu(g->window, ro_gui_browser_window_menu, + true, false); + ro_gui_wimp_event_register_menu_prepare(g->window, + ro_gui_window_menu_prepare); + ro_gui_wimp_event_register_menu_selection(g->window, + ro_gui_window_menu_select); + ro_gui_wimp_event_register_menu_warning(g->window, + ro_gui_window_menu_warning); + ro_gui_wimp_event_register_menu_close(g->window, + ro_gui_window_menu_close); + + /* Set the window options */ + ro_gui_window_clone_options(g, existing); + ro_gui_window_update_toolbar_buttons(g); + + /* Open the window at the top of the stack */ + state.w = g->window; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return g; + } + + state.next = wimp_TOP; + + ro_gui_window_open(PTR_WIMP_OPEN(&state)); + + /* Claim the caret */ + if (ro_toolbar_take_caret(g->toolbar)) + ro_gui_url_complete_start(g->toolbar); + else + gui_window_place_caret(g, -100, -100, 0, NULL); + + return g; +} + + +/** + * Close a browser window and free any related resources. + * + * \param g gui_window to destroy + */ + +static void gui_window_destroy(struct gui_window *g) +{ + os_error *error; + wimp_w w; + + assert(g); + + /* stop any tracking */ + ro_mouse_kill(g); + + /* remove from list */ + if (g->prev) + g->prev->next = g->next; + else + window_list = g->next; + if (g->next) + g->next->prev = g->prev; + + /* destroy toolbar */ + if (g->toolbar) + ro_toolbar_destroy(g->toolbar); + if (g->status_bar) + ro_gui_status_bar_destroy(g->status_bar); + + w = g->window; + ro_gui_url_complete_close(); + ro_gui_dialog_close_persistent(w); + if (current_menu_window == w) + ro_gui_menu_destroy(); + ro_gui_window_remove_update_boxes(g); + + /* delete window */ + error = xwimp_delete_window(w); + if (error) { + LOG("xwimp_delete_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + ro_gui_wimp_event_finalise(w); + + free(g); +} + + +/** + * Set the title of a browser window. + * + * \param g gui_window to update + * \param title new window title, copied + */ + +static void gui_window_set_title(struct gui_window *g, const char *title) +{ + assert(g); + assert(title); + + if (g->scale != 1.0) { + int scale_disp = g->scale * 100; + + if (ABS((float)scale_disp - g->scale * 100) >= 0.05) + snprintf(g->title, sizeof g->title, "%s (%.1f%%)", + title, g->scale * 100); + else + snprintf(g->title, sizeof g->title, "%s (%i%%)", + title, scale_disp); + } else { + strncpy(g->title, title, sizeof g->title); + } + + ro_gui_set_window_title(g->window, g->title); +} + + +/** + * Force a redraw of the entire contents of a browser window. + * + * \param g gui_window to redraw + */ +void gui_window_redraw_window(struct gui_window *g) +{ + wimp_window_info info; + os_error *error; + + assert(g); + info.w = g->window; + error = xwimp_get_window_info_header_only(&info); + if (error) { + LOG("xwimp_get_window_info_header_only: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + error = xwimp_force_redraw(g->window, info.extent.x0, info.extent.y0, + info.extent.x1, info.extent.y1); + if (error) { + LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } +} + + +/** + * Redraw an area of a window. + * + * \param g The window to update + * \param rect The area of the window to update. + */ + +static void gui_window_update_box(struct gui_window *g, const struct rect *rect) +{ + bool use_buffer; + int x0, y0, x1, y1; + struct update_box *cur; + + x0 = floorf(rect->x0 * 2 * g->scale); + y0 = -ceilf(rect->y1 * 2 * g->scale); + x1 = ceilf(rect->x1 * 2 * g->scale) + 1; + y1 = -floorf(rect->y0 * 2 * g->scale) + 1; + use_buffer = + (g->option.buffer_everything || g->option.buffer_animations); + + /* try to optimise buffered redraws */ + if (use_buffer) { + for (cur = pending_updates; cur != NULL; cur = cur->next) { + if ((cur->g != g) || (!cur->use_buffer)) + continue; + if ((((cur->x0 - x1) < MARGIN) || ((cur->x1 - x0) < MARGIN)) && + (((cur->y0 - y1) < MARGIN) || ((cur->y1 - y0) < MARGIN))) { + cur->x0 = min(cur->x0, x0); + cur->y0 = min(cur->y0, y0); + cur->x1 = max(cur->x1, x1); + cur->y1 = max(cur->y1, y1); + return; + } + + } + } + cur = malloc(sizeof(struct update_box)); + if (!cur) { + LOG("No memory for malloc."); + ro_warn_user("NoMemory", 0); + return; + } + cur->x0 = x0; + cur->y0 = y0; + cur->x1 = x1; + cur->y1 = y1; + cur->next = pending_updates; + pending_updates = cur; + cur->g = g; + cur->use_buffer = use_buffer; +} + + +/** + * Get the scroll position of a browser window. + * + * \param g gui_window + * \param sx receives x ordinate of point at top-left of window + * \param sy receives y ordinate of point at top-left of window + * \return true iff successful + */ + +static bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy) +{ + wimp_window_state state; + os_error *error; + int toolbar_height = 0; + + assert(g); + + state.w = g->window; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + + if (g->toolbar) + toolbar_height = ro_toolbar_full_height(g->toolbar); + *sx = state.xscroll / (2 * g->scale); + *sy = -(state.yscroll - toolbar_height) / (2 * g->scale); + return true; +} + + +/** + * Set the scroll position of a browser window. + * + * \param g gui_window to scroll + * \param sx point to place at top-left of window + * \param sy point to place at top-left of window + */ + +static void gui_window_set_scroll(struct gui_window *g, int sx, int sy) +{ + wimp_window_state state; + os_error *error; + + assert(g); + + state.w = g->window; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + state.xscroll = sx * 2 * g->scale; + state.yscroll = -sy * 2 * g->scale; + if (g->toolbar) + state.yscroll += ro_toolbar_full_height(g->toolbar); + ro_gui_window_open(PTR_WIMP_OPEN(&state)); +} + + +/** + * Scrolls the specified area of a browser window into view. + * + * \param g gui_window to scroll + * \param x0 left point to ensure visible + * \param y0 bottom point to ensure visible + * \param x1 right point to ensure visible + * \param y1 top point to ensure visible + */ +static void gui_window_scroll_visible(struct gui_window *g, int x0, int y0, int x1, int y1) +{ + wimp_window_state state; + os_error *error; + int cx0, cy0, width, height; + int padding_available; + int toolbar_height = 0; + int correction; + + assert(g); + + state.w = g->window; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + if (g->toolbar) + toolbar_height = ro_toolbar_full_height(g->toolbar); + + x0 = x0 * 2 * g->scale; + y0 = y0 * 2 * g->scale; + x1 = x1 * 2 * g->scale; + y1 = y1 * 2 * g->scale; + + cx0 = state.xscroll; + cy0 = -state.yscroll + toolbar_height; + width = state.visible.x1 - state.visible.x0; + height = state.visible.y1 - state.visible.y0 - toolbar_height; + + /* make sure we're visible */ + correction = (x1 - cx0 - width); + if (correction > 0) + cx0 += correction; + correction = (y1 - cy0 - height); + if (correction > 0) + cy0 += correction; + if (x0 < cx0) + cx0 = x0; + if (y0 < cy0) + cy0 = y0; + + /* try to give a SCROLL_VISIBLE_PADDING border of space around us */ + padding_available = (width - x1 + x0) / 2; + if (padding_available > 0) { + if (padding_available > SCROLL_VISIBLE_PADDING) + padding_available = SCROLL_VISIBLE_PADDING; + correction = (cx0 + width - x1); + if (correction < padding_available) + cx0 += padding_available; + correction = (x0 - cx0); + if (correction < padding_available) + cx0 -= padding_available; + } + padding_available = (height - y1 + y0) / 2; + if (padding_available > 0) { + if (padding_available > SCROLL_VISIBLE_PADDING) + padding_available = SCROLL_VISIBLE_PADDING; + correction = (cy0 + height - y1); + if (correction < padding_available) + cy0 += padding_available; + correction = (y0 - cy0); + if (correction < padding_available) + cy0 -= padding_available; + } + + state.xscroll = cx0; + state.yscroll = -cy0 + toolbar_height; + ro_gui_window_open(PTR_WIMP_OPEN(&state)); +} + + +/** + * Find the current dimensions of a browser window's content area. + * + * \param g gui_window to measure + * \param width receives width of window + * \param height receives height of window + * \param scaled whether to return scaled values + */ + +static void gui_window_get_dimensions(struct gui_window *g, int *width, int *height, bool scaled) +{ + /* use the cached window sizes */ + *width = g->old_width / 2; + *height = g->old_height / 2; + if (scaled) { + *width /= g->scale; + *height /= g->scale; + } +} + + +/** + * Update the extent of the inside of a browser window to that of the + * current content. + * + * \param g gui_window to update the extent of + */ + +static void gui_window_update_extent(struct gui_window *g) +{ + os_error *error; + wimp_window_info info; + + assert(g); + + info.w = g->window; + error = xwimp_get_window_info_header_only(&info); + if (error) { + LOG("xwimp_get_window_info_header_only: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + /* scroll on toolbar height change */ + if (g->toolbar) { + int scroll = ro_toolbar_height(g->toolbar) - info.extent.y1; + info.yscroll += scroll; + } + + /* Handle change of extents */ + g->update_extent = true; + ro_gui_window_open(PTR_WIMP_OPEN(&info)); +} + + +/** + * Set the status bar of a browser window. + * + * \param g gui_window to update + * \param text new status text + */ + +static void riscos_window_set_status(struct gui_window *g, const char *text) +{ + if (g->status_bar) + ro_gui_status_bar_set_text(g->status_bar, text); +} + + +/** + * Change mouse pointer shape + */ + +void gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape) +{ + static gui_pointer_shape curr_pointer = GUI_POINTER_DEFAULT; + struct ro_gui_pointer_entry *entry; + os_error *error; + + if (shape == curr_pointer) + return; + + assert(shape < sizeof ro_gui_pointer_table / + sizeof ro_gui_pointer_table[0]); + + entry = &ro_gui_pointer_table[shape]; + + if (entry->wimp_area) { + /* pointer in the Wimp's sprite area */ + error = xwimpspriteop_set_pointer_shape(entry->sprite_name, + 1, entry->xactive, entry->yactive, 0, 0); + if (error) { + LOG("xwimpspriteop_set_pointer_shape: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + } else { + /* pointer in our own sprite area */ + error = xosspriteop_set_pointer_shape(osspriteop_USER_AREA, + gui_sprites, + (osspriteop_id) entry->sprite_name, + 1, entry->xactive, entry->yactive, 0, 0); + if (error) { + LOG("xosspriteop_set_pointer_shape: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + } + + curr_pointer = shape; +} + + +/* exported function documented in riscos/window.h */ +nserror ro_gui_window_set_url(struct gui_window *g, nsurl *url) +{ + size_t idn_url_l; + char *idn_url_s = NULL; + + if (g->toolbar) { + if (nsoption_bool(display_decoded_idn) == true) { + if (nsurl_get_utf8(url, &idn_url_s, &idn_url_l) != NSERROR_OK) + idn_url_s = NULL; + } + + ro_toolbar_set_url(g->toolbar, idn_url_s ? idn_url_s : nsurl_access(url), true, false); + + if (idn_url_s) + free(idn_url_s); + + ro_gui_url_complete_start(g->toolbar); + } + + return NSERROR_OK; +} + + +/** + * Update the interface to reflect start of page loading. + * + * \param g window with start of load + */ + +static void gui_window_start_throbber(struct gui_window *g) +{ + ro_gui_window_update_toolbar_buttons(g); + ro_gui_menu_refresh(ro_gui_browser_window_menu); + if (g->toolbar != NULL) + ro_toolbar_start_throbbing(g->toolbar); + g->active = true; +} + + + +/** + * Update the interface to reflect page loading stopped. + * + * \param g window with start of load + */ + +static void gui_window_stop_throbber(struct gui_window *g) +{ + ro_gui_window_update_toolbar_buttons(g); + ro_gui_menu_refresh(ro_gui_browser_window_menu); + if (g->toolbar != NULL) + ro_toolbar_stop_throbbing(g->toolbar); + g->active = false; +} + +/** + * set favicon + */ + +static void gui_window_set_icon(struct gui_window *g, hlcache_handle *icon) +{ + if (g == NULL || g->toolbar == NULL) + return; + + ro_toolbar_set_site_favicon(g->toolbar, icon); +} + + + +/** + * Remove the caret, if present. + * + * \param g window with caret + */ + +static void gui_window_remove_caret(struct gui_window *g) +{ + wimp_caret caret; + os_error *error; + + error = xwimp_get_caret_position(&caret); + if (error) { + LOG("xwimp_get_caret_position: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + if (caret.w != g->window) + /* we don't have the caret: do nothing */ + return; + + /* hide caret, but keep input focus */ + gui_window_place_caret(g, -100, -100, 0, NULL); +} + + +/** + * Called when the gui_window has new content. + * + * \param g the gui_window that has new content + */ + +static void gui_window_new_content(struct gui_window *g) +{ + ro_gui_menu_refresh(ro_gui_browser_window_menu); + ro_gui_window_update_toolbar_buttons(g); + ro_gui_dialog_close_persistent(g->window); + ro_toolbar_set_content_favicon(g->toolbar, g); +} + + +/** + * Starts drag scrolling of a browser window + * + * \param g the window to scroll + */ + +static bool gui_window_scroll_start(struct gui_window *g) +{ + wimp_window_info_base info; + wimp_pointer pointer; + os_error *error; + wimp_drag drag; + int height; + int width; + + error = xwimp_get_pointer_info(&pointer); + if (error) { + LOG("xwimp_get_pointer_info 0x%x : %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + + info.w = g->window; + error = xwimp_get_window_info_header_only((wimp_window_info*)&info); + if (error) { + LOG("xwimp_get_window_state: 0x%x : %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + + width = info.extent.x1 - info.extent.x0; + height = info.extent.y1 - info.extent.y0; + + drag.type = wimp_DRAG_USER_POINT; + drag.bbox.x1 = pointer.pos.x + info.xscroll; + drag.bbox.y0 = pointer.pos.y + info.yscroll; + drag.bbox.x0 = drag.bbox.x1 - (width - (info.visible.x1 - info.visible.x0)); + drag.bbox.y1 = drag.bbox.y0 + (height - (info.visible.y1 - info.visible.y0)); + + if (g->toolbar) { + int tbar_height = ro_toolbar_full_height(g->toolbar); + drag.bbox.y0 -= tbar_height; + drag.bbox.y1 -= tbar_height; + } + + error = xwimp_drag_box(&drag); + if (error) { + LOG("xwimp_drag_box: 0x%x : %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + + ro_mouse_drag_start(ro_gui_window_scroll_end, ro_gui_window_mouse_at, + NULL, g); + return true; +} + + +/** + * Platform-dependent part of starting drag operation. + * + * \param g gui window containing the drag + * \param type type of drag the core is performing + * \param rect rectangle to constrain pointer to (relative to drag start coord) + * \return true iff succesful + */ + +static bool gui_window_drag_start(struct gui_window *g, gui_drag_type type, + const struct rect *rect) +{ + wimp_pointer pointer; + wimp_drag drag; + + if (rect != NULL) { + /* We have a box to constrain the pointer to, for the drag + * duration */ + os_error *error = xwimp_get_pointer_info(&pointer); + if (error) { + LOG("xwimp_get_pointer_info 0x%x : %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + + drag.type = wimp_DRAG_USER_POINT; + drag.bbox.x0 = pointer.pos.x + + (int)(rect->x0 * 2 * g->scale); + drag.bbox.y0 = pointer.pos.y + + (int)(rect->y0 * 2 * g->scale); + drag.bbox.x1 = pointer.pos.x + + (int)(rect->x1 * 2 * g->scale); + drag.bbox.y1 = pointer.pos.y + + (int)(rect->y1 * 2 * g->scale); + + error = xwimp_drag_box(&drag); + if (error) { + LOG("xwimp_drag_box: 0x%x : %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + } + + switch (type) { + case GDRAGGING_SCROLLBAR: + /* Dragging a core scrollbar */ + ro_mouse_drag_start(ro_gui_window_scroll_end, ro_gui_window_mouse_at, + NULL, g); + break; + + default: + /* Not handled here yet */ + break; + } + + return true; +} + + +/** + * Save the specified content as a link. + * + * \param g The window containing the content + * \param url The url of the link + * \param title The title of the link + */ +static nserror +gui_window_save_link(struct gui_window *g, nsurl *url, const char *title) +{ + ro_gui_save_prepare(GUI_SAVE_LINK_URL, NULL, NULL, url, title); + ro_gui_dialog_open_persistent(g->window, dialog_saveas, true); + return NSERROR_OK; +} + + +/** + * Updates a windows extent. + * + * \param g the gui_window to update + * \param width the minimum width, or -1 to use window width + * \param height the minimum height, or -1 to use window height + */ + +void gui_window_set_extent(struct gui_window *g, int width, int height) +{ + int screen_width; + int toolbar_height = 0; + wimp_window_state state; + os_error *error; + + if (g->toolbar) + toolbar_height = ro_toolbar_full_height(g->toolbar); + + /* get the current state */ + if ((height == -1) || (width == -1)) { + state.w = g->window; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + if (width == -1) + width = state.visible.x1 - state.visible.x0; + if (height == -1) { + height = state.visible.y1 - state.visible.y0; + height -= toolbar_height; + } + } + + /* the top-level framed window is a total pain. to get it to maximise + * to the top of the screen we need to fake it having a suitably large + * extent */ + if (browser_window_is_frameset(g->bw)) { + ro_gui_screen_size(&screen_width, &height); + if (g->toolbar) + height -= ro_toolbar_full_height(g->toolbar); + height -= ro_get_hscroll_height(g->window); + height -= ro_get_title_height(g->window); + } + if (browser_window_has_content(g->bw)) { + int w, h; + browser_window_get_extents(g->bw, true, &w, &h); + width = max(width, w * 2); + height = max(height, h * 2); + } + os_box extent = { 0, -height, width, toolbar_height }; + error = xwimp_set_extent(g->window, &extent); + if (error) { + LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } +} + + +/** + * Display a menu of options for a form select control. + * + * \param g gui window containing form control + * \param control form control of type GADGET_SELECT + */ + +static void gui_window_create_form_select_menu(struct gui_window *g, + struct form_control *control) +{ + os_error *error; + wimp_pointer pointer; + + /* The first time the menu is opened, control bypasses the normal + * Menu Prepare event and so we prepare here. On any re-opens, + * ro_gui_window_prepare_form_select_menu() is called from the + * normal wimp event. + */ + + if (!ro_gui_window_prepare_form_select_menu(g, control)) + return; + + error = xwimp_get_pointer_info(&pointer); + if (error) { + LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + ro_gui_menu_destroy(); + return; + } + + gui_form_select_control = control; + ro_gui_menu_create(gui_form_select_menu, + pointer.pos.x, pointer.pos.y, g->window); +} + + +/* + * RISC OS Wimp Event Handlers + */ + + +/** + * Handle a Redraw_Window_Request for a browser window. + */ + +void ro_gui_window_redraw(wimp_draw *redraw) +{ + osbool more; + struct gui_window *g = (struct gui_window *)ro_gui_wimp_event_get_user_data(redraw->w); + os_error *error; + struct redraw_context ctx = { + .interactive = true, + .background_images = true, + .plot = &ro_plotters + }; + + /* We can't render locked contents. If the browser window is not + * ready for redraw, do nothing. Else, in the case of buffered + * rendering we'll show random data. */ + if (!browser_window_redraw_ready(g->bw)) + return; + + ro_gui_current_redraw_gui = g; + + error = xwimp_redraw_window(redraw, &more); + if (error) { + LOG("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + while (more) { + struct rect clip; + + /* OS's redraw request coordinates are in screen coordinates, + * with an origin at the bottom left of the screen. + * Find the coordinate of the top left of the document in terms + * of OS screen coordinates. + * NOTE: OS units are 2 per px. */ + ro_plot_origin_x = redraw->box.x0 - redraw->xscroll; + ro_plot_origin_y = redraw->box.y1 - redraw->yscroll; + + /* Convert OS redraw rectangle request coordinates into NetSurf + * coordinates. NetSurf coordinates have origin at top left of + * document and units are in px. */ + clip.x0 = (redraw->clip.x0 - ro_plot_origin_x) / 2; /* left */ + clip.y0 = (ro_plot_origin_y - redraw->clip.y1) / 2; /* top */ + clip.x1 = (redraw->clip.x1 - ro_plot_origin_x) / 2; /* right */ + clip.y1 = (ro_plot_origin_y - redraw->clip.y0) / 2; /* bottom */ + + if (ro_gui_current_redraw_gui->option.buffer_everything) + ro_gui_buffer_open(redraw); + + browser_window_redraw(g->bw, 0, 0, &clip, &ctx); + + if (ro_gui_current_redraw_gui->option.buffer_everything) + ro_gui_buffer_close(); + + /* Check to see if there are more rectangles to draw and + * get next one */ + error = xwimp_get_rectangle(redraw, &more); + /* RISC OS 3.7 returns an error here if enough buffer was + claimed to cause a new dynamic area to be created. It + doesn't actually stop anything working, so we mask it out + for now until a better fix is found. This appears to be a + bug in RISC OS. */ + if (error && !(ro_gui_current_redraw_gui-> + option.buffer_everything && + error->errnum == error_WIMP_GET_RECT)) { + LOG("xwimp_get_rectangle: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + ro_gui_current_redraw_gui = NULL; + return; + } + } + ro_gui_current_redraw_gui = NULL; +} + + +/** + * Set a gui_window's scale + */ +void ro_gui_window_set_scale(struct gui_window *g, float scale) +{ + g->scale = scale; + browser_window_set_scale(g->bw, scale, true); +} + + +/** + * Open a window using the given wimp_open, handling toolbars and resizing. + */ + +void ro_gui_window_open(wimp_open *open) +{ + struct gui_window *g = (struct gui_window *)ro_gui_wimp_event_get_user_data(open->w); + int width = open->visible.x1 - open->visible.x0; + int height = open->visible.y1 - open->visible.y0; + browser_scrolling h_scroll; + browser_scrolling v_scroll; + int toolbar_height = 0; + float new_scale = 0; + wimp_window_state state; + os_error *error; + wimp_w parent; + bits linkage; + bool have_content; + + if (open->next == wimp_TOP && g->iconise_icon >= 0) { + /* window is no longer iconised, release its sprite number */ + iconise_used[g->iconise_icon] = false; + g->iconise_icon = -1; + } + + have_content = browser_window_has_content(g->bw); + + /* get the current flags/nesting state */ + state.w = g->window; + error = xwimp_get_window_state_and_nesting(&state, &parent, &linkage); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + /* account for toolbar height, if present */ + if (g->toolbar) + toolbar_height = ro_toolbar_full_height(g->toolbar); + height -= toolbar_height; + + /* work with the state from now on so we can modify flags */ + state.visible = open->visible; + state.xscroll = open->xscroll; + state.yscroll = open->yscroll; + state.next = open->next; + + browser_window_get_scrollbar_type(g->bw, &h_scroll, &v_scroll); + + /* handle 'auto' scroll bars' and non-fitting scrollbar removal */ + if ((h_scroll != BW_SCROLLING_NO) && (v_scroll != BW_SCROLLING_NO)) { + int size; + + /* windows lose scrollbars when containing a frameset */ + bool no_hscroll = false; + bool no_vscroll = browser_window_is_frameset(g->bw); + + /* hscroll */ + size = ro_get_hscroll_height(NULL); + size -= 2; /* 1px border on both sides */ + if (!no_hscroll) { + if (!(state.flags & wimp_WINDOW_HSCROLL)) { + height -= size; + state.visible.y0 += size; + if (have_content) { + browser_window_schedule_reformat(g->bw); + } + } + state.flags |= wimp_WINDOW_HSCROLL; + } else { + if (state.flags & wimp_WINDOW_HSCROLL) { + height += size; + state.visible.y0 -= size; + if (have_content) { + browser_window_schedule_reformat(g->bw); + } + } + state.flags &= ~wimp_WINDOW_HSCROLL; + } + + /* vscroll */ + size = ro_get_vscroll_width(NULL); + size -= 2; /* 1px border on both sides */ + if (!no_vscroll) { + if (!(state.flags & wimp_WINDOW_VSCROLL)) { + width -= size; + state.visible.x1 -= size; + if (have_content) { + browser_window_schedule_reformat(g->bw); + } + } + state.flags |= wimp_WINDOW_VSCROLL; + } else { + if (state.flags & wimp_WINDOW_VSCROLL) { + width += size; + state.visible.x1 += size; + if (have_content) { + browser_window_schedule_reformat(g->bw); + } + } + state.flags &= ~wimp_WINDOW_VSCROLL; + } + } + + /* reformat or change extent if necessary */ + if (have_content && + (g->old_width != width || g->old_height != height)) { + /* Ctrl-resize of a top-level window scales the content size */ + if ((g->old_width > 0) && (g->old_width != width) && + (ro_gui_ctrl_pressed())) + new_scale = (g->scale * width) / g->old_width; + browser_window_schedule_reformat(g->bw); + } + if (g->update_extent || g->old_width != width || + g->old_height != height) { + g->old_width = width; + g->old_height = height; + g->update_extent = false; + gui_window_set_extent(g, width, height); + } + + /* first resize stops any flickering by making the URL window on top */ + ro_gui_url_complete_resize(g->toolbar, PTR_WIMP_OPEN(&state)); + + /* Windows containing framesets can only be scrolled via the core, which + * is implementing frame scrollbars itself. The x and y offsets are + * therefore fixed. + */ + + if (browser_window_is_frameset(g->bw)) { + state.xscroll = 0; + state.yscroll = toolbar_height; + } + + error = xwimp_open_window_nested_with_flags(&state, parent, linkage); + if (error) { + LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + /* update the toolbar */ + if (g->status_bar) + ro_gui_status_bar_resize(g->status_bar); + if (g->toolbar) { + ro_toolbar_process(g->toolbar, -1, false); + /* second resize updates to the new URL bar width */ + ro_gui_url_complete_resize(g->toolbar, open); + } + + /* set the new scale from a ctrl-resize. this must be done at the end as + * it may cause a frameset recalculation based on the new window size. + */ + if (new_scale > 0) { + ro_gui_window_set_scale(g, new_scale); + } +} + + +/** + * Handle wimp closing event + */ + +void ro_gui_window_close(wimp_w w) +{ + struct gui_window *g = (struct gui_window *)ro_gui_wimp_event_get_user_data(w); + wimp_pointer pointer; + os_error *error; + char *temp_name; + char *filename = NULL; + struct nsurl *url; + bool destroy; + + error = xwimp_get_pointer_info(&pointer); + if (error) { + LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + if (pointer.buttons & wimp_CLICK_ADJUST) { + destroy = !ro_gui_shift_pressed(); + + url = browser_window_get_url(g->bw); + if (url != NULL) { + netsurf_nsurl_to_path(url, &filename); + } + if (filename != NULL) { + temp_name = malloc(strlen(filename) + 32); + if (temp_name) { + char *r; + sprintf(temp_name, "Filer_OpenDir %s", + filename); + r = temp_name + strlen(temp_name); + while (r > temp_name) { + if (*r == '.') { + *r = '\0'; + break; + } + r--; + } + error = xos_cli(temp_name); + if (error) { + LOG("xos_cli: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MiscError", error->errmess); + return; + } + free(temp_name); + } + free(filename); + } else { + /* this is pointless if we are about to close the + * window */ + if (!destroy && url != NULL) + browser_window_navigate_up(g->bw, false); + } + } + else + destroy = true; + + if (destroy) + browser_window_destroy(g->bw); +} + + +/** + * Handle Mouse_Click events in a browser window. This should never see + * Menu clicks, as these will be routed to the menu handlers. + * + * \param *pointer details of mouse click + * \return true if click handled, false otherwise + */ + +bool ro_gui_window_click(wimp_pointer *pointer) +{ + struct gui_window *g; + os_coord pos; + + /* We should never see Menu clicks. */ + + if (pointer->buttons == wimp_CLICK_MENU) + return false; + + g = (struct gui_window *) ro_gui_wimp_event_get_user_data(pointer->w); + + /* try to close url-completion */ + ro_gui_url_complete_close(); + + /* set input focus */ + if (pointer->buttons & (wimp_SINGLE_SELECT | wimp_SINGLE_ADJUST)) + gui_window_place_caret(g, -100, -100, 0, NULL); + + if (ro_gui_window_to_window_pos(g, pointer->pos.x, pointer->pos.y, &pos)) + browser_window_mouse_click(g->bw, + ro_gui_mouse_click_state(pointer->buttons, + wimp_BUTTON_DOUBLE_CLICK_DRAG), + pos.x, pos.y); + + return true; +} + + +/** + * Process Key_Pressed events in a browser window. + * + * \param *key The wimp keypress block for the event. + * \return true if the event was handled, else false. + */ + +bool ro_gui_window_keypress(wimp_key *key) +{ + struct gui_window *g; + uint32_t c = (uint32_t) key->c; + + g = (struct gui_window *) ro_gui_wimp_event_get_user_data(key->w); + if (g == NULL) + return false; + + /* First send the key to the browser window, eg. form fields. */ + + if ((unsigned)c < 0x20 || (0x7f <= c && c <= 0x9f) || + (c & IS_WIMP_KEY)) { + /* Munge control keys into unused control chars */ + /* We can't map onto 1->26 (reserved for ctrl+<qwerty> + That leaves 27->31 and 128->159 */ + switch (c & ~IS_WIMP_KEY) { + case wimp_KEY_TAB: c = 9; break; + case wimp_KEY_SHIFT | wimp_KEY_TAB: c = 11; break; + + /* cursor movement keys */ + case wimp_KEY_HOME: + case wimp_KEY_CONTROL | wimp_KEY_LEFT: + c = NS_KEY_LINE_START; + break; + case wimp_KEY_END: + if (os_version >= RISCOS5) + c = NS_KEY_LINE_END; + else + c = NS_KEY_DELETE_RIGHT; + break; + case wimp_KEY_CONTROL | wimp_KEY_RIGHT: c = NS_KEY_LINE_END; break; + case wimp_KEY_CONTROL | wimp_KEY_UP: c = NS_KEY_TEXT_START; break; + case wimp_KEY_CONTROL | wimp_KEY_DOWN: c = NS_KEY_TEXT_END; break; + case wimp_KEY_SHIFT | wimp_KEY_LEFT: c = NS_KEY_WORD_LEFT ; break; + case wimp_KEY_SHIFT | wimp_KEY_RIGHT: c = NS_KEY_WORD_RIGHT; break; + case wimp_KEY_SHIFT | wimp_KEY_UP: c = NS_KEY_PAGE_UP; break; + case wimp_KEY_SHIFT | wimp_KEY_DOWN: c = NS_KEY_PAGE_DOWN; break; + case wimp_KEY_LEFT: c = NS_KEY_LEFT; break; + case wimp_KEY_RIGHT: c = NS_KEY_RIGHT; break; + case wimp_KEY_UP: c = NS_KEY_UP; break; + case wimp_KEY_DOWN: c = NS_KEY_DOWN; break; + + /* editing */ + case wimp_KEY_CONTROL | wimp_KEY_END: + c = NS_KEY_DELETE_LINE_END; + break; + case wimp_KEY_DELETE: + if (ro_gui_ctrl_pressed()) + c = NS_KEY_DELETE_LINE_START; + else if (os_version < RISCOS5) + c = NS_KEY_DELETE_LEFT; + break; + + case wimp_KEY_F8: + c = NS_KEY_UNDO; + break; + case wimp_KEY_F9: + c = NS_KEY_REDO; + break; + + default: + break; + } + } + + if (!(c & IS_WIMP_KEY)) { + if (browser_window_key_press(g->bw, c)) + return true; + } + + return ro_gui_window_handle_local_keypress(g, key, false); +} + + +/** + * Callback handler for keypresses within browser window toolbars. + * + * \param *data Client data, pointing to the GUI Window. + * \param *key The keypress data. + * \return true if the keypress was handled; else false. + */ + +bool ro_gui_window_toolbar_keypress(void *data, wimp_key *key) +{ + struct gui_window *g = (struct gui_window *) data; + + if (g != NULL) + return ro_gui_window_handle_local_keypress(g, key, true); + + return false; +} + + +/** + * Handle keypresses within the RISC OS GUI: this is to be called after the + * core has been given a chance to act, or on keypresses in the toolbar where + * the core doesn't get involved. + * + * \param *g The gui window to which the keypress applies. + * \param *key The keypress data. + * \param is_toolbar true if the keypress is from a toolbar; + * else false. + * \return true if the keypress was claimed; else false. + */ + +bool ro_gui_window_handle_local_keypress(struct gui_window *g, wimp_key *key, + bool is_toolbar) +{ + struct browser_window_features cont; + os_error *ro_error; + wimp_pointer pointer; + os_coord pos; + float scale; + uint32_t c = (uint32_t) key->c; + wimp_scroll_direction xscroll = wimp_SCROLL_NONE; + wimp_scroll_direction yscroll = wimp_SCROLL_NONE; + nsurl *url; + + if (g == NULL) + return false; + + ro_error = xwimp_get_pointer_info(&pointer); + if (ro_error) { + LOG("xwimp_get_pointer_info: 0x%x: %s\n", ro_error->errnum, ro_error->errmess); + ro_warn_user("WimpError", ro_error->errmess); + return false; + } + + if (!ro_gui_window_to_window_pos(g, pointer.pos.x, pointer.pos.y, &pos)) + return false; + + browser_window_get_features(g->bw, pos.x, pos.y, &cont); + + switch (c) { + case IS_WIMP_KEY + wimp_KEY_F1: /* Help. */ + { + nserror error = nsurl_create( + "http://www.netsurf-browser.org/documentation/", + &url); + if (error == NSERROR_OK) { + error = browser_window_create(BW_CREATE_HISTORY, + url, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + if (error != NSERROR_OK) { + ro_warn_user(messages_get_errorcode(error), 0); + } + return true; + } + case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F1: + ro_gui_window_action_page_info(g); + return true; + + case IS_WIMP_KEY + wimp_KEY_F2: + if (g->toolbar == NULL) + return false; + ro_gui_url_complete_close(); + ro_toolbar_set_url(g->toolbar, "www.", true, true); + ro_gui_url_complete_start(g->toolbar); + ro_gui_url_complete_keypress(g->toolbar, wimp_KEY_DOWN); + return true; + + case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F2: + /* Close window. */ + ro_gui_url_complete_close(); + gui_window_set_pointer(g, GUI_POINTER_DEFAULT); + browser_window_destroy(g->bw); + return true; + + case 19: /* Ctrl + S */ + case IS_WIMP_KEY + wimp_KEY_F3: + ro_gui_window_action_save(g, GUI_SAVE_SOURCE); + return true; + + case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F3: + ro_gui_window_action_save(g, GUI_SAVE_TEXT); + return true; + + case IS_WIMP_KEY + wimp_KEY_SHIFT + wimp_KEY_F3: + ro_gui_window_action_save(g, GUI_SAVE_COMPLETE); + return true; + + case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_SHIFT + wimp_KEY_F3: + ro_gui_window_action_save(g, GUI_SAVE_DRAW); + return true; + + case 6: /* Ctrl + F */ + case IS_WIMP_KEY + wimp_KEY_F4: /* Search */ + ro_gui_window_action_search(g); + return true; + + case IS_WIMP_KEY + wimp_KEY_F5: /* Reload */ + if (g->bw != NULL) + browser_window_reload(g->bw, false); + return true; + + case 18: /* Ctrl+R (Full reload) */ + case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F5: + if (g->bw != NULL) + browser_window_reload(g->bw, true); + return true; + + case IS_WIMP_KEY + wimp_KEY_F6: /* Hotlist */ + ro_gui_hotlist_open(); + return true; + + case IS_WIMP_KEY + wimp_KEY_F7: /* Show local history */ + ro_gui_window_action_local_history(g); + return true; + + case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F7: + /* Show global history */ + ro_gui_global_history_open(); + return true; + + case IS_WIMP_KEY + wimp_KEY_F8: /* View source */ + ro_gui_view_source((cont.main != NULL) ? cont.main : + browser_window_get_content(g->bw)); + return true; + + case IS_WIMP_KEY + wimp_KEY_F9: + /* Dump content for debugging. */ + ro_gui_dump_browser_window(g->bw); + return true; + + case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F9: + urldb_dump(); + return true; + + case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_SHIFT + wimp_KEY_F9: + talloc_report_full(0, stderr); + return true; + + case IS_WIMP_KEY + wimp_KEY_F11: /* Zoom */ + ro_gui_window_action_zoom(g); + return true; + + case IS_WIMP_KEY + wimp_KEY_SHIFT + wimp_KEY_F11: + /* Toggle display of box outlines. */ + browser_window_debug(g->bw, CONTENT_DEBUG_REDRAW); + + gui_window_redraw_window(g); + return true; + + case wimp_KEY_RETURN: + if (is_toolbar) { + const char *toolbar_url; + toolbar_url = ro_toolbar_get_url(g->toolbar); + if (toolbar_url != NULL) + ro_gui_window_launch_url(g, toolbar_url); + } + return true; + + case wimp_KEY_ESCAPE: + if (ro_gui_url_complete_close()) { + ro_gui_url_complete_start(g->toolbar); + return true; + } + + if (g->bw != NULL) + browser_window_stop(g->bw); + return true; + + case 14: /* CTRL+N */ + ro_gui_window_action_new_window(g); + return true; + + case 17: /* CTRL+Q (Zoom out) */ + case 23: /* CTRL+W (Zoom in) */ + if (browser_window_has_content(g->bw) == false) + break; + scale = g->scale; + if (ro_gui_shift_pressed() && c == 17) + scale = g->scale - 0.1; + else if (ro_gui_shift_pressed() && c == 23) + scale = g->scale + 0.1; + else if (c == 17) { + for (int i = SCALE_SNAP_TO_SIZE - 1; i >= 0; i--) + if (scale_snap_to[i] < g->scale) { + scale = scale_snap_to[i]; + break; + } + } else { + for (unsigned int i = 0; i < SCALE_SNAP_TO_SIZE; i++) + if (scale_snap_to[i] > g->scale) { + scale = scale_snap_to[i]; + break; + } + } + if (scale < scale_snap_to[0]) + scale = scale_snap_to[0]; + if (scale > scale_snap_to[SCALE_SNAP_TO_SIZE - 1]) + scale = scale_snap_to[SCALE_SNAP_TO_SIZE - 1]; + if (g->scale != scale) { + ro_gui_window_set_scale(g, scale); + } + return true; + + case IS_WIMP_KEY + wimp_KEY_PRINT: + ro_gui_window_action_print(g); + return true; + + case IS_WIMP_KEY | wimp_KEY_LEFT: + case IS_WIMP_KEY | wimp_KEY_RIGHT: + case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_LEFT: + case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_RIGHT: + case IS_WIMP_KEY | wimp_KEY_UP: + case IS_WIMP_KEY | wimp_KEY_DOWN: + case IS_WIMP_KEY | wimp_KEY_PAGE_UP: + case IS_WIMP_KEY | wimp_KEY_PAGE_DOWN: + case wimp_KEY_HOME: + case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_UP: + case IS_WIMP_KEY | wimp_KEY_END: + case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_DOWN: + if (is_toolbar) + return false; + break; + default: + return false; /* This catches any keys we don't want to claim */ + } + + /* Any keys that exit from the above switch() via break should be + * processed as scroll actions in the browser window. */ + + switch (c) { + case IS_WIMP_KEY | wimp_KEY_LEFT: + xscroll = wimp_SCROLL_COLUMN_LEFT; + break; + case IS_WIMP_KEY | wimp_KEY_RIGHT: + xscroll = wimp_SCROLL_COLUMN_RIGHT; + break; + case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_LEFT: + xscroll = 0x7fffffff; + break; + case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_RIGHT: + xscroll = 0x80000000; + break; + case IS_WIMP_KEY | wimp_KEY_UP: + yscroll = wimp_SCROLL_LINE_UP; + break; + case IS_WIMP_KEY | wimp_KEY_DOWN: + yscroll = wimp_SCROLL_LINE_DOWN; + break; + case IS_WIMP_KEY | wimp_KEY_PAGE_UP: + yscroll = wimp_SCROLL_PAGE_UP; + break; + case IS_WIMP_KEY | wimp_KEY_PAGE_DOWN: + yscroll = wimp_SCROLL_PAGE_DOWN; + break; + case wimp_KEY_HOME: + case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_UP: + yscroll = 0x7fffffff; + break; + case IS_WIMP_KEY | wimp_KEY_END: + case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_DOWN: + yscroll = 0x80000000; + break; + } + + ro_gui_window_scroll_action(g, xscroll, yscroll); + + return true; +} + + +/** + * Prepare the browser window menu for (re-)opening + * + * \param w The window owning the menu. + * \param i The icon owning the menu. + * \param *menu The menu about to be opened. + * \param *pointer Pointer to the relevant wimp event block, or + * NULL for an Adjust click. + * \return true if the event was handled; else false. + */ + +bool ro_gui_window_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_pointer *pointer) +{ + struct gui_window *g; + struct browser_window *bw; + struct toolbar *toolbar; + struct browser_window_features cont; + bool export_sprite, export_draw, have_content; + os_coord pos; + browser_editor_flags editor_flags; + + g = (struct gui_window *) ro_gui_wimp_event_get_user_data(w); + toolbar = g->toolbar; + bw = g->bw; + have_content = browser_window_has_content(g->bw); + editor_flags = browser_window_get_editor_flags(bw); + + /* If this is the form select menu, handle it now and then exit. + * Otherwise, carry on to the main browser window menu. + */ + + if (menu == gui_form_select_menu) { + return ro_gui_window_prepare_form_select_menu(g, + gui_form_select_control); + } + + if (menu != ro_gui_browser_window_menu) + return false; + + /* If this is a new opening for the browser window menu (ie. not for a + * toolbar menu), get details of the object under the pointer. + */ + + if (pointer != NULL && g->window == w) { + ro_gui_url_complete_close(); + + current_menu_main = NULL; + current_menu_object = NULL; + current_menu_url = NULL; + + if (ro_gui_window_to_window_pos(g, pointer->pos.x, + pointer->pos.y, &pos)) { + browser_window_get_features(bw, pos.x, pos.y, &cont); + + current_menu_main = cont.main; + current_menu_object = cont.object; + current_menu_url = cont.link; + } + } + + /* Shade menu entries according to the state of the window and object + * under the pointer. + */ + + /* Toolbar (Sub)Menu */ + + ro_gui_menu_set_entry_shaded(menu, TOOLBAR_BUTTONS, + ro_toolbar_menu_option_shade(toolbar)); + ro_gui_menu_set_entry_ticked(menu, TOOLBAR_BUTTONS, + ro_toolbar_menu_buttons_tick(toolbar)); + + ro_gui_menu_set_entry_shaded(menu, TOOLBAR_ADDRESS_BAR, + ro_toolbar_menu_edit_shade(toolbar)); + ro_gui_menu_set_entry_ticked(menu, TOOLBAR_ADDRESS_BAR, + ro_toolbar_menu_url_tick(toolbar)); + + ro_gui_menu_set_entry_shaded(menu, TOOLBAR_THROBBER, + ro_toolbar_menu_edit_shade(toolbar)); + ro_gui_menu_set_entry_ticked(menu, TOOLBAR_THROBBER, + ro_toolbar_menu_throbber_tick(toolbar)); + + ro_gui_menu_set_entry_shaded(menu, TOOLBAR_EDIT, + ro_toolbar_menu_edit_shade(toolbar)); + ro_gui_menu_set_entry_ticked(menu, TOOLBAR_EDIT, + ro_toolbar_menu_edit_tick(toolbar)); + + /* Page Submenu */ + + ro_gui_menu_set_entry_shaded(menu, BROWSER_PAGE, + !browser_window_can_search(bw)); + + ro_gui_menu_set_entry_shaded(menu, BROWSER_PAGE_INFO, !have_content); + + ro_gui_menu_set_entry_shaded(menu, BROWSER_PRINT, !have_content); + + ro_gui_menu_set_entry_shaded(menu, BROWSER_NEW_WINDOW, !have_content); + + ro_gui_menu_set_entry_shaded(menu, BROWSER_FIND_TEXT, + !browser_window_can_search(bw)); + + + ro_gui_menu_set_entry_shaded(menu, BROWSER_VIEW_SOURCE, !have_content); + + ro_gui_menu_set_entry_shaded(menu, BROWSER_SAVE_URL_URI, !have_content); + ro_gui_menu_set_entry_shaded(menu, BROWSER_SAVE_URL_URL, !have_content); + ro_gui_menu_set_entry_shaded(menu, BROWSER_SAVE_URL_TEXT, + !have_content); + + ro_gui_menu_set_entry_shaded(menu, BROWSER_SAVE, !have_content); + ro_gui_menu_set_entry_shaded(menu, BROWSER_SAVE_COMPLETE, + !have_content); + ro_gui_menu_set_entry_shaded(menu, BROWSER_EXPORT_DRAW, !have_content); + ro_gui_menu_set_entry_shaded(menu, BROWSER_EXPORT_PDF, !have_content); + ro_gui_menu_set_entry_shaded(menu, BROWSER_EXPORT_TEXT, !have_content); + + ro_gui_menu_set_entry_shaded(menu, BROWSER_LINK_SAVE_URI, + !current_menu_url); + ro_gui_menu_set_entry_shaded(menu, BROWSER_LINK_SAVE_URL, + !current_menu_url); + ro_gui_menu_set_entry_shaded(menu, BROWSER_LINK_SAVE_TEXT, + !current_menu_url); + + + + /* Object Submenu */ + + ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT, + current_menu_object == NULL && + current_menu_url == NULL); + + ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_LINK, + current_menu_url == NULL); + + ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_INFO, + current_menu_object == NULL); + ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_RELOAD, + current_menu_object == NULL); + ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_OBJECT, + current_menu_object == NULL); + + ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_PRINT, true); + /* Not yet implemented */ + + ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_SAVE, + current_menu_object == NULL); + + ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_SAVE_URL_URI, + current_menu_object == NULL); + ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_SAVE_URL_URL, + current_menu_object == NULL); + ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_SAVE_URL_TEXT, + current_menu_object == NULL); + + if (current_menu_object != NULL) + ro_gui_window_content_export_types(current_menu_object, + &export_draw, &export_sprite); + else + ro_gui_window_content_export_types( + browser_window_get_content(bw), + &export_draw, &export_sprite); + + ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_EXPORT, + (!have_content && current_menu_object == NULL) + || !(export_sprite || export_draw)); + + ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_EXPORT_SPRITE, + (!have_content && current_menu_object == NULL) + || !export_sprite); + + ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_EXPORT_DRAW, + (!have_content && current_menu_object == NULL) + || !export_draw); + + + /* Selection Submenu */ + + ro_gui_menu_set_entry_shaded(menu, BROWSER_SELECTION, + !browser_window_can_select(bw)); + + ro_gui_menu_set_entry_shaded(menu, BROWSER_SELECTION_SAVE, + ~editor_flags & BW_EDITOR_CAN_COPY); + + ro_gui_menu_set_entry_shaded(menu, BROWSER_SELECTION_COPY, + ~editor_flags & BW_EDITOR_CAN_COPY); + + ro_gui_menu_set_entry_shaded(menu, BROWSER_SELECTION_CUT, + ~editor_flags & BW_EDITOR_CAN_CUT); + + ro_gui_menu_set_entry_shaded(menu, BROWSER_SELECTION_PASTE, + ~editor_flags & BW_EDITOR_CAN_PASTE); + + ro_gui_menu_set_entry_shaded(menu, BROWSER_SELECTION_CLEAR, + ~editor_flags & BW_EDITOR_CAN_COPY); + + + /* Navigate Submenu */ + + ro_gui_menu_set_entry_shaded(menu, BROWSER_NAVIGATE_BACK, + !browser_window_back_available(bw)); + + ro_gui_menu_set_entry_shaded(menu, BROWSER_NAVIGATE_FORWARD, + !browser_window_forward_available(bw)); + + ro_gui_menu_set_entry_shaded(menu, BROWSER_NAVIGATE_RELOAD_ALL, + !browser_window_reload_available(bw)); + + ro_gui_menu_set_entry_shaded(menu, BROWSER_NAVIGATE_STOP, + !browser_window_stop_available(bw)); + + ro_gui_menu_set_entry_shaded(menu, BROWSER_NAVIGATE_UP, + !browser_window_up_available(bw)); + + + + /* View Submenu */ + + ro_gui_menu_set_entry_ticked(menu, BROWSER_IMAGES_FOREGROUND, + g != NULL && nsoption_bool(foreground_images)); + + ro_gui_menu_set_entry_ticked(menu, BROWSER_IMAGES_BACKGROUND, + g != NULL && nsoption_bool(background_images)); + + ro_gui_menu_set_entry_shaded(menu, BROWSER_BUFFER_ANIMS, + g == NULL || g->option.buffer_everything); + ro_gui_menu_set_entry_ticked(menu, BROWSER_BUFFER_ANIMS, g != NULL && + (g->option.buffer_animations || + g->option.buffer_everything)); + + ro_gui_menu_set_entry_shaded(menu, BROWSER_BUFFER_ALL, g == NULL); + ro_gui_menu_set_entry_ticked(menu, BROWSER_BUFFER_ALL, + g != NULL && g->option.buffer_everything); + + ro_gui_menu_set_entry_shaded(menu, BROWSER_SCALE_VIEW, !have_content); + + ro_gui_menu_set_entry_shaded(menu, BROWSER_WINDOW_STAGGER, + nsoption_int(window_screen_width) == 0); + ro_gui_menu_set_entry_ticked(menu, BROWSER_WINDOW_STAGGER, + ((nsoption_int(window_screen_width) == 0) || + nsoption_bool(window_stagger))); + + ro_gui_menu_set_entry_ticked(menu, BROWSER_WINDOW_COPY, + nsoption_bool(window_size_clone)); + + ro_gui_menu_set_entry_shaded(menu, BROWSER_WINDOW_RESET, + nsoption_int(window_screen_width) == 0); + + + /* Utilities Submenu */ + + ro_gui_menu_set_entry_shaded(menu, HOTLIST_ADD_URL, !have_content); + + ro_gui_menu_set_entry_shaded(menu, HISTORY_SHOW_LOCAL, + (bw == NULL || + !(have_content || browser_window_back_available(bw) || + browser_window_forward_available(bw)))); + + + /* Help Submenu */ + + ro_gui_menu_set_entry_ticked(menu, HELP_LAUNCH_INTERACTIVE, + ro_gui_interactive_help_available() && + nsoption_bool(interactive_help)); + + return true; +} + + +/** + * Handle submenu warnings for a browser window menu + * + * \param w The window owning the menu. + * \param i The icon owning the menu. + * \param *menu The menu to which the warning applies. + * \param *selection The wimp menu selection data. + * \param action The selected menu action. + */ + +void ro_gui_window_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_selection *selection, menu_action action) +{ + struct gui_window *g; + hlcache_handle *h; + struct toolbar *toolbar; + bool export; + + if (menu != ro_gui_browser_window_menu) + return; + + g = (struct gui_window *) ro_gui_wimp_event_get_user_data(w); + toolbar = g->toolbar; + h = browser_window_get_content(g->bw); + + switch (action) { + case BROWSER_PAGE_INFO: + if (h != NULL) + ro_gui_window_prepare_pageinfo(g); + break; + + case BROWSER_FIND_TEXT: + if (h != NULL && (content_get_type(h) == CONTENT_HTML || + content_get_type(h) == CONTENT_TEXTPLAIN)) + ro_gui_search_prepare(g->bw); + break; + + case BROWSER_SCALE_VIEW: + if (h != NULL) + ro_gui_dialog_prepare_zoom(g); + break; + + case BROWSER_PRINT: + if (h != NULL) + ro_gui_print_prepare(g); + break; + + case BROWSER_OBJECT_INFO: + if (current_menu_object != NULL) + ro_gui_window_prepare_objectinfo(current_menu_object, + current_menu_url); + break; + + case BROWSER_OBJECT_SAVE: + if (current_menu_object != NULL) + ro_gui_save_prepare(GUI_SAVE_OBJECT_ORIG, + current_menu_object, NULL, NULL, NULL); + break; + + case BROWSER_SELECTION_SAVE: + if (browser_window_get_editor_flags(g->bw) & BW_EDITOR_CAN_COPY) + ro_gui_save_prepare(GUI_SAVE_TEXT_SELECTION, NULL, + browser_window_get_selection(g->bw), + NULL, NULL); + break; + + case BROWSER_SAVE_URL_URI: + if (h != NULL) + ro_gui_save_prepare(GUI_SAVE_LINK_URI, NULL, NULL, + hlcache_handle_get_url(h), + content_get_title(h)); + break; + + case BROWSER_SAVE_URL_URL: + if (h != NULL) + ro_gui_save_prepare(GUI_SAVE_LINK_URL, NULL, NULL, + hlcache_handle_get_url(h), + content_get_title(h)); + break; + + case BROWSER_SAVE_URL_TEXT: + if (h != NULL) + ro_gui_save_prepare(GUI_SAVE_LINK_TEXT, NULL, NULL, + hlcache_handle_get_url(h), + content_get_title(h)); + break; + + case BROWSER_OBJECT_SAVE_URL_URI: + if (current_menu_object != NULL) + ro_gui_save_prepare(GUI_SAVE_LINK_URI, NULL, NULL, + hlcache_handle_get_url( + current_menu_object), + content_get_title(current_menu_object)); + break; + + case BROWSER_OBJECT_SAVE_URL_URL: + if (current_menu_object != NULL) + ro_gui_save_prepare(GUI_SAVE_LINK_URL, NULL, NULL, + hlcache_handle_get_url( + current_menu_object), + content_get_title(current_menu_object)); + break; + + case BROWSER_OBJECT_SAVE_URL_TEXT: + if (current_menu_object != NULL) + ro_gui_save_prepare(GUI_SAVE_LINK_TEXT, NULL, NULL, + hlcache_handle_get_url( + current_menu_object), + content_get_title(current_menu_object)); + break; + + case BROWSER_SAVE: + if (h != NULL) + ro_gui_save_prepare(GUI_SAVE_SOURCE, h, NULL, NULL, NULL); + break; + + case BROWSER_SAVE_COMPLETE: + if (h != NULL) + ro_gui_save_prepare(GUI_SAVE_COMPLETE, h, NULL, NULL, NULL); + break; + + case BROWSER_EXPORT_DRAW: + if (h != NULL) + ro_gui_save_prepare(GUI_SAVE_DRAW, h, NULL, NULL, NULL); + break; + + case BROWSER_EXPORT_PDF: + if (h != NULL) + ro_gui_save_prepare(GUI_SAVE_PDF, h, NULL, NULL, NULL); + break; + + case BROWSER_EXPORT_TEXT: + if (h != NULL) + ro_gui_save_prepare(GUI_SAVE_TEXT, h, NULL, NULL, NULL); + break; + + case BROWSER_LINK_SAVE_URI: + if (current_menu_url != NULL) + ro_gui_save_prepare(GUI_SAVE_LINK_URI, NULL, NULL, + current_menu_url, NULL); + break; + + case BROWSER_LINK_SAVE_URL: + if (current_menu_url != NULL) + ro_gui_save_prepare(GUI_SAVE_LINK_URL, NULL, NULL, + current_menu_url, NULL); + break; + + case BROWSER_LINK_SAVE_TEXT: + if (current_menu_url != NULL) + ro_gui_save_prepare(GUI_SAVE_LINK_TEXT, NULL, NULL, + current_menu_url, NULL); + break; + + case BROWSER_OBJECT_EXPORT_SPRITE: + if (current_menu_object != NULL) { + ro_gui_window_content_export_types(current_menu_object, + NULL, &export); + + if (export) + ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE, + current_menu_object, + NULL, NULL, NULL); + } else if (h != NULL) { + ro_gui_window_content_export_types(h, NULL, &export); + + if (export) + ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE, + h, NULL, NULL, NULL); + } + break; + + case BROWSER_OBJECT_EXPORT_DRAW: + if (current_menu_object != NULL) { + ro_gui_window_content_export_types(current_menu_object, + &export, NULL); + + if (export) + ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE, + current_menu_object, + NULL, NULL, NULL); + } else if (h != NULL) { + ro_gui_window_content_export_types(h, &export, NULL); + + if (export) + ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE, + h, NULL, NULL, NULL); + } + break; + + default: + break; + } +} + + +static void ro_gui_window_paste_cb(void *pw) +{ + struct browser_window *bw = pw; + + browser_window_key_press(bw, NS_KEY_PASTE); +} + + +/** + * Handle selections from a browser window menu + * + * \param w The window owning the menu. + * \param i The icon owning the menu. + * \param *menu The menu from which the selection was made. + * \param *selection The wimp menu selection data. + * \param action The selected menu action. + * \return true if action accepted; else false. + */ + +bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu, + wimp_selection *selection, menu_action action) +{ + struct gui_window *g; + struct browser_window *bw; + hlcache_handle *h; + struct toolbar *toolbar; + wimp_window_state state; + nsurl *url; + nserror error = NSERROR_OK; + + g = (struct gui_window *) ro_gui_wimp_event_get_user_data(w); + toolbar = g->toolbar; + bw = g->bw; + h = browser_window_get_content(bw); + + /* If this is a form menu from the core, handle it now and then exit. + * Otherwise, carry on to the main browser window menu. + */ + + if (menu == gui_form_select_menu && w == g->window) { + ro_gui_window_process_form_select_menu(g, selection); + + return true; + } + + /* We're now safe to assume that this is either the browser or + * toolbar window menu. + */ + + switch (action) { + + /* help actions */ + case HELP_OPEN_CONTENTS: + error = nsurl_create("http://www.netsurf-browser.org/documentation/", &url); + if (error == NSERROR_OK) { + error = browser_window_create(BW_CREATE_HISTORY, + url, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + break; + + case HELP_OPEN_GUIDE: + error = nsurl_create("http://www.netsurf-browser.org/documentation/guide", &url); + if (error == NSERROR_OK) { + error = browser_window_create(BW_CREATE_HISTORY, + url, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + break; + + case HELP_OPEN_INFORMATION: + error = nsurl_create("http://www.netsurf-browser.org/documentation/info", &url); + if (error == NSERROR_OK) { + error = browser_window_create(BW_CREATE_HISTORY, + url, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + break; + + case HELP_OPEN_CREDITS: + error = nsurl_create("about:credits", &url); + if (error == NSERROR_OK) { + error = browser_window_create(BW_CREATE_HISTORY, + url, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + break; + + case HELP_OPEN_LICENCE: + error = nsurl_create("about:licence", &url); + if (error == NSERROR_OK) { + error = browser_window_create(BW_CREATE_HISTORY, + url, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + break; + + case HELP_LAUNCH_INTERACTIVE: + if (!ro_gui_interactive_help_available()) { + ro_gui_interactive_help_start(); + nsoption_set_bool(interactive_help, true); + } else { + nsoption_set_bool(interactive_help, !nsoption_bool(interactive_help)); + } + break; + + /* history actions */ + case HISTORY_SHOW_LOCAL: + ro_gui_window_action_local_history(g); + break; + case HISTORY_SHOW_GLOBAL: + ro_gui_global_history_open(); + break; + + /* hotlist actions */ + case HOTLIST_ADD_URL: + ro_gui_window_action_add_bookmark(g); + break; + case HOTLIST_SHOW: + ro_gui_hotlist_open(); + break; + + /* cookies actions */ + case COOKIES_SHOW: + ro_gui_cookies_open(); + break; + + case COOKIES_DELETE: + cookie_manager_keypress(NS_KEY_SELECT_ALL); + cookie_manager_keypress(NS_KEY_DELETE_LEFT); + break; + + /* page actions */ + case BROWSER_PAGE_INFO: + ro_gui_window_action_page_info(g); + break; + case BROWSER_PRINT: + ro_gui_window_action_print(g); + break; + case BROWSER_NEW_WINDOW: + ro_gui_window_action_new_window(g); + break; + case BROWSER_VIEW_SOURCE: + if (current_menu_main != NULL) { + ro_gui_view_source(current_menu_main); + } else if (h != NULL) { + ro_gui_view_source(h); + } + break; + + /* object actions */ + case BROWSER_OBJECT_INFO: + if (current_menu_object != NULL) { + ro_gui_window_prepare_objectinfo(current_menu_object, + current_menu_url); + ro_gui_dialog_open_persistent(g->window, + dialog_objinfo, false); + } + break; + case BROWSER_OBJECT_RELOAD: + if (current_menu_object != NULL) { + content_invalidate_reuse_data(current_menu_object); + browser_window_reload(bw, false); + } + break; + + /* link actions */ + case BROWSER_LINK_SAVE_URI: + if (current_menu_url != NULL) { + ro_gui_save_prepare(GUI_SAVE_LINK_URI, NULL, NULL, + current_menu_url, NULL); + ro_gui_dialog_open_persistent(g->window, dialog_saveas, + false); + } + break; + case BROWSER_LINK_SAVE_URL: + if (current_menu_url != NULL) { + ro_gui_save_prepare(GUI_SAVE_LINK_URL, NULL, NULL, + current_menu_url, NULL); + ro_gui_dialog_open_persistent(g->window, dialog_saveas, + false); + } + break; + case BROWSER_LINK_SAVE_TEXT: + if (current_menu_url != NULL) { + ro_gui_save_prepare(GUI_SAVE_LINK_TEXT, NULL, NULL, + current_menu_url, NULL); + ro_gui_dialog_open_persistent(g->window, dialog_saveas, + false); + } + break; + + case BROWSER_LINK_DOWNLOAD: + if (current_menu_url != NULL) { + error = browser_window_navigate(bw, + current_menu_url, + browser_window_get_url(bw), + BW_NAVIGATE_DOWNLOAD, + NULL, + NULL, + NULL); + } + break; + + case BROWSER_LINK_NEW_WINDOW: + if (current_menu_url != NULL) { + error = browser_window_create( + BW_CREATE_HISTORY | + BW_CREATE_CLONE, + current_menu_url, + browser_window_get_url(bw), + bw, + NULL); + } + break; + + + /* save actions */ + case BROWSER_OBJECT_SAVE: + if (current_menu_object != NULL) { + ro_gui_save_prepare(GUI_SAVE_OBJECT_ORIG, + current_menu_object, NULL, NULL, NULL); + ro_gui_dialog_open_persistent(g->window, dialog_saveas, + false); + } + break; + case BROWSER_OBJECT_EXPORT_SPRITE: + if (current_menu_object != NULL) { + ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE, + current_menu_object, NULL, NULL, NULL); + ro_gui_dialog_open_persistent(g->window, dialog_saveas, + false); + } + break; + case BROWSER_OBJECT_EXPORT_DRAW: + if (current_menu_object != NULL) { + ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE, + current_menu_object, NULL, NULL, NULL); + ro_gui_dialog_open_persistent(g->window, dialog_saveas, + false); + } + break; + case BROWSER_SAVE: + ro_gui_window_action_save(g, GUI_SAVE_SOURCE); + break; + case BROWSER_SAVE_COMPLETE: + ro_gui_window_action_save(g, GUI_SAVE_COMPLETE); + break; + case BROWSER_EXPORT_DRAW: + ro_gui_window_action_save(g, GUI_SAVE_DRAW); + break; + case BROWSER_EXPORT_PDF: + ro_gui_window_action_save(g, GUI_SAVE_PDF); + break; + case BROWSER_EXPORT_TEXT: + ro_gui_window_action_save(g, GUI_SAVE_TEXT); + break; + case BROWSER_SAVE_URL_URI: + ro_gui_window_action_save(g, GUI_SAVE_LINK_URI); + break; + case BROWSER_SAVE_URL_URL: + ro_gui_window_action_save(g, GUI_SAVE_LINK_URL); + break; + case BROWSER_SAVE_URL_TEXT: + ro_gui_window_action_save(g, GUI_SAVE_LINK_TEXT); + break; + + /* selection actions */ + case BROWSER_SELECTION_SAVE: + if (h != NULL) { + ro_gui_save_prepare(GUI_SAVE_TEXT_SELECTION, NULL, + browser_window_get_selection(bw), + NULL, NULL); + ro_gui_dialog_open_persistent(g->window, dialog_saveas, + false); + } + break; + case BROWSER_SELECTION_COPY: + browser_window_key_press(bw, NS_KEY_COPY_SELECTION); + break; + case BROWSER_SELECTION_CUT: + browser_window_key_press(bw, NS_KEY_CUT_SELECTION); + break; + case BROWSER_SELECTION_PASTE: + ro_gui_selection_prepare_paste(w, ro_gui_window_paste_cb, bw); + break; + case BROWSER_SELECTION_ALL: + browser_window_key_press(bw, NS_KEY_SELECT_ALL); + break; + case BROWSER_SELECTION_CLEAR: + browser_window_key_press(bw, NS_KEY_CLEAR_SELECTION); + break; + + /* navigation actions */ + case BROWSER_NAVIGATE_HOME: + ro_gui_window_action_home(g); + break; + case BROWSER_NAVIGATE_BACK: + if (bw != NULL) + browser_window_history_back(bw, false); + break; + case BROWSER_NAVIGATE_FORWARD: + if (bw != NULL) + browser_window_history_forward(bw, false); + break; + case BROWSER_NAVIGATE_UP: + if (bw != NULL && h != NULL) + browser_window_navigate_up(g->bw, false); + break; + case BROWSER_NAVIGATE_RELOAD_ALL: + if (bw != NULL) + browser_window_reload(bw, true); + break; + case BROWSER_NAVIGATE_STOP: + if (bw != NULL) + browser_window_stop(bw); + break; + + /* browser window/display actions */ + case BROWSER_SCALE_VIEW: + ro_gui_window_action_zoom(g); + break; + case BROWSER_FIND_TEXT: + ro_gui_window_action_search(g); + break; + case BROWSER_IMAGES_FOREGROUND: + if (g != NULL) + nsoption_set_bool(foreground_images, + !nsoption_bool(foreground_images)); + break; + case BROWSER_IMAGES_BACKGROUND: + if (g != NULL) + nsoption_set_bool(background_images, + !nsoption_bool(background_images)); + break; + case BROWSER_BUFFER_ANIMS: + if (g != NULL) + g->option.buffer_animations = + !g->option.buffer_animations; + break; + case BROWSER_BUFFER_ALL: + if (g != NULL) + g->option.buffer_everything = + !g->option.buffer_everything; + break; + case BROWSER_SAVE_VIEW: + if (bw != NULL) { + ro_gui_window_default_options(g); + ro_gui_save_options(); + } + break; + case BROWSER_WINDOW_DEFAULT: + if (g != NULL) { + os_error *oserror; + + ro_gui_screen_size(&nsoption_int(window_screen_width), + &nsoption_int(window_screen_height)); + state.w = w; + oserror = xwimp_get_window_state(&state); + if (oserror) { + LOG("xwimp_get_window_state: 0x%x: %s", oserror->errnum, oserror->errmess); + ro_warn_user("WimpError", oserror->errmess); + } + nsoption_set_int(window_x, state.visible.x0); + nsoption_set_int(window_y, state.visible.y0); + nsoption_set_int(window_width, + state.visible.x1 - state.visible.x0); + nsoption_set_int(window_height, + state.visible.y1 - state.visible.y0); + ro_gui_save_options(); + } + break; + case BROWSER_WINDOW_STAGGER: + nsoption_set_bool(window_stagger, + !nsoption_bool(window_stagger)); + ro_gui_save_options(); + break; + case BROWSER_WINDOW_COPY: + nsoption_set_bool(window_size_clone, + !nsoption_bool(window_size_clone)); + ro_gui_save_options(); + break; + case BROWSER_WINDOW_RESET: + nsoption_set_int(window_screen_width, 0); + nsoption_set_int(window_screen_height, 0); + ro_gui_save_options(); + break; + + /* toolbar actions */ + case TOOLBAR_BUTTONS: + assert(toolbar); + ro_toolbar_set_display_buttons(toolbar, + !ro_toolbar_get_display_buttons(toolbar)); + break; + case TOOLBAR_ADDRESS_BAR: + assert(toolbar); + ro_toolbar_set_display_url(toolbar, + !ro_toolbar_get_display_url(toolbar)); + if (ro_toolbar_get_display_url(toolbar)) + ro_toolbar_take_caret(toolbar); + break; + case TOOLBAR_THROBBER: + assert(toolbar); + ro_toolbar_set_display_throbber(toolbar, + !ro_toolbar_get_display_throbber(toolbar)); + break; + case TOOLBAR_EDIT: + assert(toolbar); + ro_toolbar_toggle_edit(toolbar); + break; + + default: + return false; + } + + if (error != NSERROR_OK) { + ro_warn_user(messages_get_errorcode(error), 0); + } + + return true; +} + + +/** + * Handle the closure of a browser window menu + * + * \param w The window owning the menu. + * \param i The icon owning the menu. + * \param *menu The menu that is being closed. + */ + +void ro_gui_window_menu_close(wimp_w w, wimp_i i, wimp_menu *menu) +{ + if (menu == ro_gui_browser_window_menu) { + current_menu_object = NULL; + current_menu_url = NULL; + } else if (menu == gui_form_select_menu) { + gui_form_select_control = NULL; + } +} + + +/** + * Process Scroll_Request events in a browser window. + * + * \param *scroll The wimp scroll event data block. + */ + +void ro_gui_window_scroll(wimp_scroll *scroll) +{ + struct gui_window *g = ro_gui_window_lookup(scroll->w); + + if (g && browser_window_has_content(g->bw) && ro_gui_shift_pressed()) { + /* extended scroll request with shift held down; change zoom */ + float scale, inc; + + if (scroll->ymin & 3) + inc = 0.02; /* RO5 sends the msg 5 times; + * don't ask me why + * + * @todo this is liable to break if + * HID is configured optimally for + * frame scrolling. *5 appears to be + * an artifact of non-HID mode scrolling. + */ + else + inc = (1 << (ABS(scroll->ymin)>>2)) / 20.0F; + + if (scroll->ymin > 0) { + scale = g->scale + inc; + if (scale > scale_snap_to[SCALE_SNAP_TO_SIZE - 1]) + scale = scale_snap_to[SCALE_SNAP_TO_SIZE - 1]; + } else { + scale = g->scale - inc; + if (scale < scale_snap_to[0]) + scale = scale_snap_to[0]; + } + if (g->scale != scale) + ro_gui_window_set_scale(g, scale); + } else if (g != NULL) { + ro_gui_window_scroll_action(g, scroll->xmin, scroll->ymin); + } +} + +/** + * Process Pointer Entering Window events in a browser window. + * + * \param *entering The wimp pointer entering event data block. + */ + +static void ro_gui_window_pointer_entering(wimp_entering *entering) +{ + struct gui_window *g = ro_gui_window_lookup(entering->w); + + if (g != NULL) + ro_mouse_track_start(ro_gui_window_track_end, + ro_gui_window_mouse_at, g); +} + +/** + * Process Pointer Leaving Window events in a browser window. These arrive via + * the termination callback handler from ro_mouse's mouse tracking. + * + * \param *leaving The wimp pointer leaving event data block. + * \param *data The GUI window that the pointer is leaving. + */ + +static void ro_gui_window_track_end(wimp_leaving *leaving, void *data) +{ + struct gui_window *g = (struct gui_window *) data; + + if (g != NULL) + gui_window_set_pointer(g, GUI_POINTER_DEFAULT); +} + + +/** + * Scroll a browser window, either via the core or directly using the + * normal Wimp_OpenWindow interface. + * + * Scroll steps are supplied in terms of the (extended) Scroll Event direction + * values returned by Wimp_Poll. Special values of 0x7fffffff and 0x80000000 + * are added to mean "Home" and "End". + * + * \param *g The GUI Window to be scrolled. + * \param scroll_x The X scroll step to be applied. + * \param scroll_y The Y scroll step to be applied. + */ + +void ro_gui_window_scroll_action(struct gui_window *g, + wimp_scroll_direction scroll_x, wimp_scroll_direction scroll_y) +{ + int visible_x, visible_y; + int step_x = 0, step_y = 0; + int toolbar_y; + wimp_window_state state; + wimp_pointer pointer; + os_error *error; + os_coord pos; + bool handled = false; + struct toolbar *toolbar; + + if (g == NULL) + return; + + /* Get the current window, toolbar and pointer details. */ + + state.w = g->window; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); + return; + } + + toolbar = ro_toolbar_parent_window_lookup(g->window); + assert(g == NULL || g->toolbar == NULL || g->toolbar == toolbar); + + toolbar_y = (toolbar == NULL) ? 0 : ro_toolbar_full_height(toolbar); + + visible_x = state.visible.x1 - state.visible.x0 - 32; + visible_y = state.visible.y1 - state.visible.y0 - 32 - toolbar_y; + + error = xwimp_get_pointer_info(&pointer); + if (error) { + LOG("xwimp_get_pointer_info 0x%x : %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + /* Turn the scroll requirement from Scroll Event codes into coordinates + * that the core can understand. + */ + + switch (scroll_x) { + case wimp_SCROLL_PAGE_LEFT: + step_x = SCROLL_PAGE_DOWN; + break; + case wimp_SCROLL_AUTO_LEFT: + case wimp_SCROLL_COLUMN_LEFT: + step_x = -16; + break; + case wimp_SCROLL_AUTO_RIGHT: + case wimp_SCROLL_COLUMN_RIGHT: + step_x = 16; + break; + case wimp_SCROLL_PAGE_RIGHT: + step_x = SCROLL_PAGE_UP; + break; + case 0x80000000: + step_x = SCROLL_BOTTOM; + break; + case 0x7fffffff: + step_x = SCROLL_TOP; + break; + default: + step_x = (visible_x * (scroll_x>>2)) >> 2; + break; + } + + switch (scroll_y) { + case wimp_SCROLL_PAGE_UP: + step_y = SCROLL_PAGE_UP; + break; + case wimp_SCROLL_AUTO_UP: + case wimp_SCROLL_LINE_UP: + step_y = -16; + break; + case wimp_SCROLL_AUTO_DOWN: + case wimp_SCROLL_LINE_DOWN: + step_y = 16; + break; + case wimp_SCROLL_PAGE_DOWN: + step_y = SCROLL_PAGE_DOWN; + break; + case 0x80000000: + step_y = SCROLL_BOTTOM; + break; + case 0x7fffffff: + step_y = SCROLL_TOP; + break; + default: + step_y = -((visible_y * (scroll_y>>2)) >> 2); + break; + } + + /* If no scrolling is required, there's no point trying to do any. */ + + if (step_x == 0 && step_y == 0) + return; + + /* If the pointer is over the window being scrolled, then try to get + * the core to do the scrolling on the object under the pointer. + */ + + if (pointer.w == g->window && + ro_gui_window_to_window_pos(g, + pointer.pos.x, pointer.pos.y, &pos)) + handled = browser_window_scroll_at_point(g->bw, pos.x, pos.y, + step_x, step_y); + + /* If the core didn't do the scrolling, handle it via the Wimp. + * Windows which contain frames can only be scrolled by the core, + * because it implements frame scroll bars. + */ + + if (!handled && (browser_window_is_frameset(g->bw) == false)) { + switch (step_x) { + case SCROLL_TOP: + state.xscroll -= 0x10000000; + break; + case SCROLL_BOTTOM: + state.xscroll += 0x10000000; + break; + case SCROLL_PAGE_UP: + state.xscroll += visible_x; + break; + case SCROLL_PAGE_DOWN: + state.xscroll -= visible_x; + break; + default: + state.xscroll += 2 * step_x; + break; + } + + switch (step_y) { + case SCROLL_TOP: + state.yscroll += 0x10000000; + break; + case SCROLL_BOTTOM: + state.yscroll -= 0x10000000; + break; + case SCROLL_PAGE_UP: + state.yscroll += visible_y; + break; + case SCROLL_PAGE_DOWN: + state.yscroll -= visible_y; + break; + default: + state.yscroll -= 2 * step_y; + break; + } + + error = xwimp_open_window((wimp_open *) &state); + if (error) { + LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess); + } + } +} + + +/** + * Handle Message_DataLoad (file dragged in) for a window. + * + * \param g window + * \param message Message_DataLoad block + * \return true if the load was processed + * + * If the file was dragged into a form file input, it is used as the value. + */ + +bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message) +{ + os_error *error; + os_coord pos; + + /* Ignore directories etc. */ + if (0x1000 <= message->data.data_xfer.file_type) + return false; + + if (!ro_gui_window_to_window_pos(g, message->data.data_xfer.pos.x, + message->data.data_xfer.pos.y, &pos)) + return false; + + if (browser_window_drop_file_at_point(g->bw, pos.x, pos.y, + message->data.data_xfer.file_name) == false) + return false; + + /* send DataLoadAck */ + message->action = message_DATA_LOAD_ACK; + message->your_ref = message->my_ref; + error = xwimp_send_message(wimp_USER_MESSAGE, message, message->sender); + if (error) { + LOG("xwimp_send_message: 0x%x: %s\n", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + + return true; +} + + +/** + * Handle pointer movements in a browser window. + * + * \param *pointer new mouse position + * \param *data browser window that the pointer is in + */ + +void ro_gui_window_mouse_at(wimp_pointer *pointer, void *data) +{ + os_coord pos; + struct gui_window *g = (struct gui_window *) data; + + if (ro_gui_window_to_window_pos(g, pointer->pos.x, pointer->pos.y, &pos)) + browser_window_mouse_track(g->bw, + ro_gui_mouse_drag_state(pointer->buttons, + wimp_BUTTON_DOUBLE_CLICK_DRAG), + pos.x, pos.y); +} + + +/** + * Window is being iconised. Create a suitable thumbnail sprite + * (which, sadly, must be in the Wimp sprite pool), and return + * the sprite name and truncated title to the iconiser + * + * \param g the gui window being iconised + * \param wi the WindowInfo message from the iconiser + */ + +void ro_gui_window_iconise(struct gui_window *g, + wimp_full_message_window_info *wi) +{ + /* sadly there is no 'legal' way to get the sprite into + * the Wimp sprite pool other than via a filing system */ + const char *temp_fname = "Pipe:$._tmpfile"; + struct browser_window *bw = g->bw; + osspriteop_header *overlay = NULL; + osspriteop_header *sprite_header; + struct bitmap *bitmap; + osspriteop_area *area; + int width = 34, height = 34; + hlcache_handle *h; + os_error *error; + int len, id; + + assert(bw); + + h = browser_window_get_content(bw); + if (!h) return; + + /* if an overlay sprite is defined, locate it and gets its dimensions + * so that we can produce a thumbnail with the same dimensions */ + if (!ro_gui_wimp_get_sprite("ic_netsfxx", &overlay)) { + error = xosspriteop_read_sprite_info(osspriteop_PTR, + (osspriteop_area *)0x100, + (osspriteop_id)overlay, &width, &height, NULL, + NULL); + if (error) { + LOG("xosspriteop_read_sprite_info: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("MiscError", error->errmess); + overlay = NULL; + } + else if (sprite_bpp(overlay) != 8) { + LOG("overlay sprite is not 8bpp"); + overlay = NULL; + } + } + + /* create the thumbnail sprite */ + bitmap = riscos_bitmap_create(width, height, BITMAP_NEW | BITMAP_OPAQUE | + BITMAP_CLEAR_MEMORY); + if (!bitmap) { + LOG("Thumbnail initialisation failed."); + return; + } + riscos_bitmap_render(bitmap, h); + if (overlay) { + riscos_bitmap_overlay_sprite(bitmap, overlay); + } + area = riscos_bitmap_convert_8bpp(bitmap); + riscos_bitmap_destroy(bitmap); + if (!area) { + LOG("Thumbnail conversion failed."); + return; + } + + /* choose a suitable sprite name */ + id = 0; + while (iconise_used[id]) + if ((unsigned)++id >= NOF_ELEMENTS(iconise_used)) { + id = iconise_next; + if ((unsigned)++iconise_next >= + NOF_ELEMENTS(iconise_used)) + iconise_next = 0; + break; + } + + sprite_header = (osspriteop_header *)(area + 1); + len = sprintf(sprite_header->name, "ic_netsf%.2d", id); + + error = xosspriteop_save_sprite_file(osspriteop_USER_AREA, + area, temp_fname); + if (error) { + LOG("xosspriteop_save_sprite_file: 0x%x:%s", error->errnum, error->errmess); + ro_warn_user("MiscError", error->errmess); + free(area); + return; + } + + error = xwimpspriteop_merge_sprite_file(temp_fname); + if (error) { + LOG("xwimpspriteop_merge_sprite_file: 0x%x:%s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + remove(temp_fname); + free(area); + return; + } + + memcpy(wi->sprite_name, sprite_header->name + 3, len - 2); /* inc NUL */ + strncpy(wi->title, g->title, sizeof(wi->title)); + wi->title[sizeof(wi->title) - 1] = '\0'; + + if (wimptextop_string_width(wi->title, 0) > 182) { + /* work around bug in Pinboard where it will fail to display + * the icon if the text is very wide */ + if (strlen(wi->title) > 10) + wi->title[10] = '\0'; /* pinboard does this anyway */ + while (wimptextop_string_width(wi->title, 0) > 182) + wi->title[strlen(wi->title) - 1] = '\0'; + } + + wi->size = sizeof(wimp_full_message_window_info); + wi->your_ref = wi->my_ref; + error = xwimp_send_message(wimp_USER_MESSAGE, (wimp_message*)wi, + wi->sender); + if (error) { + LOG("xwimp_send_message: 0x%x:%s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + else { + g->iconise_icon = id; + iconise_used[id] = true; + } + + free(area); +} + + +/** + * Completes scrolling of a browser window + * + * \param *drag The DragEnd event data block. + * \param *data gui window block pointer. + */ + +static void ro_gui_window_scroll_end(wimp_dragged *drag, void *data) +{ + wimp_pointer pointer; + os_error *error; + os_coord pos; + struct gui_window *g = (struct gui_window *) data; + + if (!g) + return; + + error = xwimp_drag_box((wimp_drag*)-1); + if (error) { + LOG("xwimp_drag_box: 0x%x : %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + + error = xwimp_get_pointer_info(&pointer); + if (error) { + LOG("xwimp_get_pointer_info 0x%x : %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + error = xwimpspriteop_set_pointer_shape("ptr_default", 0x31, 0, 0, 0, 0); + if (error) { + LOG("xwimpspriteop_set_pointer_shape: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + + if (ro_gui_window_to_window_pos(g, drag->final.x0, drag->final.y0, &pos)) + browser_window_mouse_track(g->bw, 0, pos.x, pos.y); +} + + +/** + * Process Mouse_Click events in a toolbar's button bar. This does not handle + * other clicks in a toolbar: these are handled by the toolbar module itself. + * + * \param *data The GUI window associated with the click. + * \param action_type The action type to be handled. + * \param action The action to process. + */ + +void ro_gui_window_toolbar_click(void *data, + toolbar_action_type action_type, union toolbar_action action) +{ + struct gui_window *g = data; + nserror err; + + if (g == NULL) + return; + + + if (action_type == TOOLBAR_ACTION_URL) { + switch (action.url) { + case TOOLBAR_URL_DRAG_URL: + { + gui_save_type save_type; + + if (!browser_window_has_content(g->bw)) + break; + + if (ro_gui_shift_pressed()) + save_type = GUI_SAVE_LINK_URL; + else + save_type = GUI_SAVE_LINK_TEXT; + + ro_gui_drag_save_link(save_type, + browser_window_get_url(g->bw), + browser_window_get_title(g->bw), g); + } + break; + + case TOOLBAR_URL_SELECT_HOTLIST: + ro_gui_window_action_add_bookmark(g); + break; + + case TOOLBAR_URL_ADJUST_HOTLIST: + ro_gui_window_action_remove_bookmark(g); + break; + + default: + break; + } + + return; + } + + + /* By now, the only valid action left is a button click. If it isn't + * one of those, give up. + */ + + if (action_type != TOOLBAR_ACTION_BUTTON) + return; + + switch (action.button) { + case TOOLBAR_BUTTON_BACK: + if (g->bw != NULL) + browser_window_history_back(g->bw, false); + break; + + case TOOLBAR_BUTTON_BACK_NEW: + if (g->bw != NULL) + browser_window_history_back(g->bw, true); + break; + + case TOOLBAR_BUTTON_FORWARD: + if (g->bw != NULL) + browser_window_history_forward(g->bw, false); + break; + + case TOOLBAR_BUTTON_FORWARD_NEW: + if (g->bw != NULL) + browser_window_history_forward(g->bw, true); + break; + + case TOOLBAR_BUTTON_STOP: + if (g->bw != NULL) + browser_window_stop(g->bw); + break; + + case TOOLBAR_BUTTON_RELOAD: + if (g->bw != NULL) + browser_window_reload(g->bw, false); + break; + + case TOOLBAR_BUTTON_RELOAD_ALL: + if (g->bw != NULL) + browser_window_reload(g->bw, true); + break; + + case TOOLBAR_BUTTON_HISTORY_LOCAL: + ro_gui_window_action_local_history(g); + break; + + case TOOLBAR_BUTTON_HISTORY_GLOBAL: + ro_gui_global_history_open(); + break; + + case TOOLBAR_BUTTON_HOME: + ro_gui_window_action_home(g); + break; + + case TOOLBAR_BUTTON_SEARCH: + ro_gui_window_action_search(g); + break; + + case TOOLBAR_BUTTON_SCALE: + ro_gui_window_action_zoom(g); + break; + + case TOOLBAR_BUTTON_BOOKMARK_OPEN: + ro_gui_hotlist_open(); + break; + + case TOOLBAR_BUTTON_BOOKMARK_ADD: + ro_gui_window_action_add_bookmark(g); + break; + + case TOOLBAR_BUTTON_SAVE_SOURCE: + ro_gui_window_action_save(g, GUI_SAVE_SOURCE); + break; + + case TOOLBAR_BUTTON_SAVE_COMPLETE: + ro_gui_window_action_save(g, GUI_SAVE_COMPLETE); + break; + + case TOOLBAR_BUTTON_PRINT: + ro_gui_window_action_print(g); + break; + + case TOOLBAR_BUTTON_UP: + err = browser_window_navigate_up(g->bw, false); + if (err != NSERROR_OK) { + ro_warn_user(messages_get_errorcode(err), NULL); + } + break; + + case TOOLBAR_BUTTON_UP_NEW: + err = browser_window_navigate_up(g->bw, true); + if (err != NSERROR_OK) { + ro_warn_user(messages_get_errorcode(err), NULL); + } + break; + + default: + break; + } + + ro_gui_window_update_toolbar_buttons(g); +} + + +/** + * Handle Message_DataLoad (file dragged in) for a toolbar + * + * @todo This belongs in the toolbar module, and should be moved there + * once the module is able to usefully handle its own events. + * + * \param g window + * \param message Message_DataLoad block + * \return true if the load was processed + */ + +bool ro_gui_toolbar_dataload(struct gui_window *g, wimp_message *message) +{ + if (message->data.data_xfer.file_type == osfile_TYPE_TEXT && + ro_gui_window_import_text(g, + message->data.data_xfer.file_name)) { + os_error *error; + + /* send DataLoadAck */ + message->action = message_DATA_LOAD_ACK; + message->your_ref = message->my_ref; + error = xwimp_send_message(wimp_USER_MESSAGE, message, + message->sender); + if (error) { + LOG("xwimp_send_message: 0x%x: %s\n", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + } + return true; + } + return false; +} + + +/* + * Helper code for the Wimp Event Handlers. + */ + +/** + * Check if a particular menu handle is a browser window menu + * + * \param *menu The menu in question. + * \return true if this menu is a browser window menu + */ + +bool ro_gui_window_check_menu(wimp_menu *menu) +{ + return (ro_gui_browser_window_menu == menu) ? true : false; +} + + +/** + * Return boolean flags to show what RISC OS types we can sensibly convert + * the given object into. + * + * \todo This should probably be somewhere else but in window.c, and + * should probably even be done in content_(). + * + * \param h The object to test. + * \param export_draw true on exit if a drawfile would be possible. + * \param export_sprite true on exit if a sprite would be possible. + * \return true if valid data is returned; else false. + */ + +bool ro_gui_window_content_export_types(hlcache_handle *h, + bool *export_draw, bool *export_sprite) +{ + bool found_type = false; + + if (export_draw != NULL) + *export_draw = false; + if (export_sprite != NULL) + *export_sprite = false; + + if (h != NULL && content_get_type(h) == CONTENT_IMAGE) { + switch (ro_content_native_type(h)) { + case osfile_TYPE_SPRITE: + /* bitmap types (Sprite export possible) */ + found_type = true; + if (export_sprite != NULL) + *export_sprite = true; + break; + case osfile_TYPE_DRAW: + /* vector types (Draw export possible) */ + found_type = true; + if (export_draw != NULL) + *export_draw = true; + break; + default: + break; + } + } + + return found_type; +} + + +/** + * Prepare the page info window for use. + * + * \param *g The GUI window block to use. + */ + +void ro_gui_window_prepare_pageinfo(struct gui_window *g) +{ + hlcache_handle *h = browser_window_get_content(g->bw); + char icon_buf[20] = "file_xxx"; + char enc_buf[40]; + const char *icon = icon_buf; + const char *title, *url; + lwc_string *mime; + const char *enc = "-"; + + assert(h); + + title = content_get_title(h); + if (title == NULL) + title = "-"; + url = nsurl_access(hlcache_handle_get_url(h)); + if (url == NULL) + url = "-"; + mime = content_get_mime_type(h); + + sprintf(icon_buf, "file_%x", ro_content_filetype(h)); + if (!ro_gui_wimp_sprite_exists(icon_buf)) + sprintf(icon_buf, "file_xxx"); + + if (content_get_type(h) == CONTENT_HTML) { + if (content_get_encoding(h, CONTENT_ENCODING_NORMAL)) { + snprintf(enc_buf, sizeof enc_buf, "%s (%s)", + content_get_encoding(h, CONTENT_ENCODING_NORMAL), + content_get_encoding(h, CONTENT_ENCODING_SOURCE)); + enc = enc_buf; + } else { + enc = messages_get("EncodingUnk"); + } + } + + ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_ICON, + icon, true); + ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_TITLE, + title, true); + ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_URL, + url, true); + ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_ENC, + enc, true); + ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_TYPE, + lwc_string_data(mime), true); + + lwc_string_unref(mime); +} + + +/** + * Prepare the object info window for use + * + * \param *object the object for which information is to be displayed + * \param *target_url corresponding url, if any + */ + +void ro_gui_window_prepare_objectinfo(hlcache_handle *object, nsurl *target_url) +{ + char icon_buf[20] = "file_xxx"; + const char *url; + lwc_string *mime; + const char *target = "-"; + + sprintf(icon_buf, "file_%.3x",ro_content_filetype(object)); + if (!ro_gui_wimp_sprite_exists(icon_buf)) { + sprintf(icon_buf, "file_xxx"); + } + + url = nsurl_access(hlcache_handle_get_url(object)); + if (url == NULL) { + url = "-"; + } + mime = content_get_mime_type(object); + + if (target_url != NULL) { + target = nsurl_access(target_url); + } + + ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_ICON, + icon_buf, true); + ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_URL, + url, true); + ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_TARGET, + target, true); + ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_TYPE, + lwc_string_data(mime), true); + + lwc_string_unref(mime); +} + + +/* + * User Actions in the browser window + */ + +/** + * Launch a new url in the given window. + * + * \param g gui_window to update + * \param url1 url to be launched + */ + +void ro_gui_window_launch_url(struct gui_window *g, const char *url1) +{ + nserror error; + nsurl *url; + + if (url1 == NULL) + return; + + ro_gui_url_complete_close(); + + error = nsurl_create(url1, &url); + if (error != NSERROR_OK) { + ro_warn_user(messages_get_errorcode(error), 0); + } else { + ro_gui_window_set_url(g, url); + + browser_window_navigate(g->bw, url, + NULL, BW_NAVIGATE_HISTORY, + NULL, NULL, NULL); + nsurl_unref(url); + } +} + + +/** + * Perform a Navigate Home action on a browser window. + * + * \param *g The browser window to act on. + */ + +void ro_gui_window_action_home(struct gui_window *g) +{ + static const char *addr = NETSURF_HOMEPAGE; + nsurl *url; + nserror error; + + if (g == NULL || g->bw == NULL) + return; + + if (nsoption_charp(homepage_url) != NULL) { + addr = nsoption_charp(homepage_url); + } + + error = nsurl_create(addr, &url); + if (error == NSERROR_OK) { + error = browser_window_navigate(g->bw, + url, + NULL, + BW_NAVIGATE_HISTORY, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + if (error != NSERROR_OK) { + ro_warn_user(messages_get_errorcode(error), 0); + } +} + + +/** + * Open a new browser window. + * + * \param *g The browser window to act on. + */ + +void ro_gui_window_action_new_window(struct gui_window *g) +{ + nserror error; + + if (g == NULL || g->bw == NULL) + return; + + error = browser_window_create(BW_CREATE_CLONE, + browser_window_get_url(g->bw), + NULL, g->bw, NULL); + + if (error != NSERROR_OK) { + ro_warn_user(messages_get_errorcode(error), 0); + } +} + + +/** + * Open a local history pane for a browser window. + * + * \param *g The browser window to act on. + */ + +void ro_gui_window_action_local_history(struct gui_window *g) +{ + if (g != NULL && g->bw != NULL) + ro_gui_history_open(g, true); +} + + +/** + * Open a save dialogue for a browser window contents. + * + * \param *g The browser window to act on. + * \param save_type The type of save to open. + */ + +void ro_gui_window_action_save(struct gui_window *g, gui_save_type save_type) +{ + hlcache_handle *h; + + if (g == NULL || g->bw == NULL || !browser_window_has_content(g->bw)) + return; + + h = browser_window_get_content(g->bw); + if (h == NULL) + return; + + ro_gui_save_prepare(save_type, h, NULL, NULL, NULL); + ro_gui_dialog_open_persistent(g->window, dialog_saveas, true); +} + + +/** + * Open a text search dialogue for a browser window. + * + * \param *g The browser window to act on. + */ + +void ro_gui_window_action_search(struct gui_window *g) +{ + if (g == NULL || g->bw == NULL || !browser_window_can_search(g->bw)) + return; + + ro_gui_search_prepare(g->bw); + ro_gui_dialog_open_persistent(g->window, dialog_search, true); +} + + +/** + * Open a zoom dialogue for a browser window. + * + * \param *g The browser window to act on. + */ + +void ro_gui_window_action_zoom(struct gui_window *g) +{ + if (g == NULL) + return; + + ro_gui_dialog_prepare_zoom(g); + ro_gui_dialog_open_persistent(g->window, dialog_zoom, true); +} + + +/** + * Add a hotlist entry for a browser window. + * + * \param *g The browser window to act on. + */ + +static void ro_gui_window_action_add_bookmark(struct gui_window *g) +{ + nsurl *url; + + if (g == NULL || g->bw == NULL || g->toolbar == NULL || + browser_window_has_content(g->bw) == false) + return; + + url = browser_window_get_url(g->bw); + + ro_gui_hotlist_add_page(url); + ro_toolbar_update_hotlist(g->toolbar); +} + + +/** + * Remove a hotlist entry for a browser window. + * + * \param *g The browser window to act on. + */ + +static void ro_gui_window_action_remove_bookmark(struct gui_window *g) +{ + nsurl *url; + + if (g == NULL || g->bw == NULL || g->toolbar == NULL || + browser_window_has_content(g->bw) == false) + return; + + url = browser_window_get_url(g->bw); + + ro_gui_hotlist_remove_page(url); +} + + +/** + * Open a print dialogue for a browser window. + * + * \param *g The browser window to act on. + */ + +void ro_gui_window_action_print(struct gui_window *g) +{ + if (g == NULL) + return; + + ro_gui_print_prepare(g); + ro_gui_dialog_open_persistent(g->window, dialog_print, true); +} + + +/** + * Open a page info box for a browser window. + * + * \param *g The browser window to act on. + */ + +void ro_gui_window_action_page_info(struct gui_window *g) +{ + if (g == NULL || g->bw == NULL || + browser_window_has_content(g->bw) == false) + return; + + ro_gui_window_prepare_pageinfo(g); + ro_gui_dialog_open_persistent(g->window, dialog_pageinfo, false); +} + + +/* + * Window and Toolbar Redraw and Update + */ + +/** + * Redraws the content for all windows. + */ + +void ro_gui_window_redraw_all(void) +{ + struct gui_window *g; + for (g = window_list; g; g = g->next) + gui_window_redraw_window(g); +} + + +/** + * Remove all pending update boxes for a window + * + * \param g gui_window + */ +void ro_gui_window_remove_update_boxes(struct gui_window *g) +{ + struct update_box *cur; + + for (cur = pending_updates; cur != NULL; cur = cur->next) { + if (cur->g == g) + cur->g = NULL; + } +} + + +/** + * Redraw any pending update boxes. + */ +void ro_gui_window_update_boxes(void) +{ + osbool more; + bool use_buffer; + wimp_draw update; + struct rect clip; + os_error *error; + struct update_box *cur; + struct gui_window *g; + struct redraw_context ctx = { + .interactive = true, + .background_images = true, + .plot = &ro_plotters + }; + + for (cur = pending_updates; cur != NULL; cur = cur->next) { + g = cur->g; + if (!g) + continue; + + use_buffer = cur->use_buffer; + + update.w = g->window; + update.box.x0 = cur->x0; + update.box.y0 = cur->y0; + update.box.x1 = cur->x1; + update.box.y1 = cur->y1; + + error = xwimp_update_window(&update, &more); + if (error) { + LOG("xwimp_update_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + continue; + } + + /* Set the current redraw gui_window to get options from */ + ro_gui_current_redraw_gui = g; + + ro_plot_origin_x = update.box.x0 - update.xscroll; + ro_plot_origin_y = update.box.y1 - update.yscroll; + + while (more) { + clip.x0 = (update.clip.x0 - ro_plot_origin_x) / 2; + clip.y0 = (ro_plot_origin_y - update.clip.y1) / 2; + clip.x1 = (update.clip.x1 - ro_plot_origin_x) / 2; + clip.y1 = (ro_plot_origin_y - update.clip.y0) / 2; + + if (use_buffer) + ro_gui_buffer_open(&update); + + browser_window_redraw(g->bw, 0, 0, &clip, &ctx); + + if (use_buffer) + ro_gui_buffer_close(); + + error = xwimp_get_rectangle(&update, &more); + /* RISC OS 3.7 returns an error here if enough buffer + * was claimed to cause a new dynamic area to be + * created. It doesn't actually stop anything working, + * so we mask it out for now until a better fix is + * found. This appears to be a bug in RISC OS. */ + if (error && !(use_buffer && + error->errnum == error_WIMP_GET_RECT)) { + LOG("xwimp_get_rectangle: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + ro_gui_current_redraw_gui = NULL; + continue; + } + } + + /* Reset the current redraw gui_window to prevent + * thumbnails from retaining options */ + ro_gui_current_redraw_gui = NULL; + } + while (pending_updates) { + cur = pending_updates; + pending_updates = pending_updates->next; + free(cur); + } +} + + +/** + * callback from core to reformat a window. + */ +static void riscos_window_reformat(struct gui_window *gw) +{ + if (gw != NULL) { + browser_window_reformat(gw->bw, false, + gw->old_width / 2, + gw->old_height / 2); + } +} + +/** + * Destroy all browser windows. + */ + +void ro_gui_window_quit(void) +{ + while (window_list) { + struct gui_window *cur = window_list; + window_list = window_list->next; + + browser_window_destroy(cur->bw); + } +} + + +/** + * Animate the "throbbers" of all browser windows. + */ + +void ro_gui_throb(void) +{ + struct gui_window *g; + + for (g = window_list; g; g = g->next) { + if (!g->active) + continue; + if (g->toolbar != NULL) + ro_toolbar_throb(g->toolbar); + } +} + + +/** + * Update the toolbar buttons for a given browser window to reflect the + * current state of its contents. + * + * Note that the parameters to this function are arranged so that it can be + * supplied to the toolbar module as an button state update callback. + * + * \param *g The browser window to update. + */ + +void ro_gui_window_update_toolbar_buttons(struct gui_window *g) +{ + struct browser_window *bw; + struct toolbar *toolbar; + + if (g == NULL || g->toolbar == NULL) + return; + + bw = g->bw; + toolbar = g->toolbar; + + ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_RELOAD, + !browser_window_reload_available(bw)); + + ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_STOP, + !browser_window_stop_available(bw)); + + ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_BACK, + !browser_window_back_available(bw)); + + ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_FORWARD, + !browser_window_forward_available(bw)); + + ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_UP, + !browser_window_up_available(bw)); + + ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_SEARCH, + !browser_window_can_search(bw)); + + ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_SCALE, + !browser_window_has_content(bw)); + + ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_PRINT, + !browser_window_has_content(bw)); + + ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_SAVE_SOURCE, + !browser_window_has_content(bw)); + + ro_toolbar_update_urlsuggest(toolbar); +} + + +/** + * Update a window to reflect a change in toolbar size: used as a callback by + * the toolbar module when a toolbar height changes. + * + * \param *data void pointer the window's gui_window struct + */ + +void ro_gui_window_update_toolbar(void *data) +{ + struct gui_window *g = (struct gui_window *) data; + + if (g != NULL) + gui_window_update_extent(g); +} + + +/** + * Save a new toolbar button configuration: used as a callback by the toolbar + * module when a buttonbar edit has finished. + * + * \param *data void pointer to the window's gui_window struct + * \param *config pointer to a malloc()'d button config string. + */ + +void ro_gui_window_save_toolbar_buttons(void *data, char *config) +{ + nsoption_set_charp(toolbar_browser, config); + ro_gui_save_options(); +} + + +/** + * Update a window and its toolbar to reflect a new theme: used as a callback + * by the toolbar module when a theme change affects a toolbar. + * + * \param *data void pointer to the window's gui_window struct + * \param ok true if the bar still exists; else false. + */ + +void ro_gui_window_update_theme(void *data, bool ok) +{ + struct gui_window *g = (struct gui_window *) data; + + if (g != NULL && g->toolbar != NULL) { + if (ok) { + gui_window_update_extent(g); + } else { + g->toolbar = NULL; + } + } +} + + +/* + * General Window Support + */ + +/** + * Import text file into window + * + * \param g gui window containing textarea + * \param filename pathname of file to be imported + * \return true iff successful + */ + +bool ro_gui_window_import_text(struct gui_window *g, const char *filename) +{ + fileswitch_object_type obj_type; + os_error *error; + char *buf, *utf8_buf, *sp; + int size; + nserror ret; + const char *ep; + char *p; + + error = xosfile_read_stamped(filename, &obj_type, NULL, NULL, + &size, NULL, NULL); + if (error) { + LOG("xosfile_read_stamped: 0x%x:%s", error->errnum, error->errmess); + ro_warn_user("FileError", error->errmess); + return true; /* was for us, but it didn't work! */ + } + + /* Allocate one byte more than needed to ensure that the buffer is + * always terminated, regardless of file contents. + */ + + buf = calloc(size + 1, sizeof(char)); + if (!buf) { + ro_warn_user("NoMemory", NULL); + return true; + } + + error = xosfile_load_stamped(filename, (byte*)buf, + NULL, NULL, NULL, NULL, NULL); + + if (error) { + LOG("xosfile_load_stamped: 0x%x:%s", error->errnum, error->errmess); + ro_warn_user("LoadError", error->errmess); + free(buf); + return true; + } + + ret = utf8_from_local_encoding(buf, size, &utf8_buf); + if (ret != NSERROR_OK) { + /* bad encoding shouldn't happen */ + assert(ret != NSERROR_BAD_ENCODING); + LOG("utf8_from_local_encoding failed"); + free(buf); + ro_warn_user("NoMemory", NULL); + return true; + } + size = strlen(utf8_buf); + + ep = utf8_buf + size; + p = utf8_buf; + + /* skip leading whitespace */ + while (isspace(*p)) p++; + + sp = p; + while (*p && *p != '\r' && *p != '\n') + p += utf8_next(p, ep - p, 0); + *p = '\0'; + + if (p > sp) + ro_gui_window_launch_url(g, sp); + + free(buf); + free(utf8_buf); + return true; +} + + +/** + * Clones a browser window's options. + * + * \param new_gui the new gui window + * \param old_gui the gui window to clone from, or NULL for default + */ + +void ro_gui_window_clone_options( + struct gui_window *new_gui, + struct gui_window *old_gui) +{ + assert(new_gui); + + /* Clone the basic options + */ + if (!old_gui) { + new_gui->option.buffer_animations = nsoption_bool(buffer_animations); + new_gui->option.buffer_everything = nsoption_bool(buffer_everything); + } else { + new_gui->option = old_gui->option; + } + + /* Set up the toolbar + */ + if (new_gui->toolbar) { + ro_toolbar_set_display_buttons(new_gui->toolbar, + nsoption_bool(toolbar_show_buttons)); + ro_toolbar_set_display_url(new_gui->toolbar, + nsoption_bool(toolbar_show_address)); + ro_toolbar_set_display_throbber(new_gui->toolbar, + nsoption_bool(toolbar_show_throbber)); + if ((old_gui) && (old_gui->toolbar)) { + ro_toolbar_set_display_buttons(new_gui->toolbar, + ro_toolbar_get_display_buttons( + old_gui->toolbar)); + ro_toolbar_set_display_url(new_gui->toolbar, + ro_toolbar_get_display_url( + old_gui->toolbar)); + ro_toolbar_set_display_throbber(new_gui->toolbar, + ro_toolbar_get_display_throbber( + old_gui->toolbar)); + ro_toolbar_process(new_gui->toolbar, -1, true); + } + } +} + + +/** + * Makes a browser window's options the default. + * + * \param gui The riscos gui window to set default options in. + */ + +void ro_gui_window_default_options(struct gui_window *gui) +{ + if (gui == NULL) + return; + + /* Save the basic options + */ + nsoption_set_int(scale, gui->scale * 100); + nsoption_set_bool(buffer_animations, gui->option.buffer_animations); + nsoption_set_bool(buffer_everything, gui->option.buffer_everything); + + /* Set up the toolbar + */ + if (gui->toolbar != NULL) { + nsoption_set_bool(toolbar_show_buttons, + ro_toolbar_get_display_buttons(gui->toolbar)); + nsoption_set_bool(toolbar_show_address, + ro_toolbar_get_display_url(gui->toolbar)); + nsoption_set_bool(toolbar_show_throbber, + ro_toolbar_get_display_throbber(gui->toolbar)); + } + if (gui->status_bar != NULL) + nsoption_set_int(toolbar_status_size, + ro_gui_status_bar_get_width(gui->status_bar)); +} + + +/* + * Custom Menu Support + */ + +/** + * Prepare or reprepare a form select menu, setting up the menu handle + * globals in the process. + * + * \param g The RISC OS gui window the menu is in. + * \param control The form control needing a menu. + * \return true if the menu is OK to be opened; else false. + */ + +bool ro_gui_window_prepare_form_select_menu(struct gui_window *g, + struct form_control *control) +{ + unsigned int item, entries; + char *text_convert, *temp; + struct form_option *option; + bool reopen = true; + nserror err; + + assert(control); + + /* enumerate the entries */ + entries = 0; + option = form_select_get_option(control, entries); + while (option != NULL) { + entries++; + option = form_select_get_option(control, entries); + } + + if (entries == 0) { + /* no menu to display */ + ro_gui_menu_destroy(); + return false; + } + + /* free riscos menu if there already is one */ + if ((gui_form_select_menu) && (control != gui_form_select_control)) { + for (item = 0; ; item++) { + free(gui_form_select_menu->entries[item].data. + indirected_text.text); + if (gui_form_select_menu->entries[item].menu_flags & + wimp_MENU_LAST) + break; + } + free(gui_form_select_menu->title_data.indirected_text.text); + free(gui_form_select_menu); + gui_form_select_menu = 0; + } + + /* allocate new riscos menu */ + if (!gui_form_select_menu) { + reopen = false; + gui_form_select_menu = malloc(wimp_SIZEOF_MENU(entries)); + if (!gui_form_select_menu) { + ro_warn_user("NoMemory", 0); + ro_gui_menu_destroy(); + return false; + } + err = utf8_to_local_encoding(messages_get("SelectMenu"), 0, + &text_convert); + if (err != NSERROR_OK) { + /* badenc should never happen */ + assert(err != NSERROR_BAD_ENCODING); + LOG("utf8_to_local_encoding failed"); + ro_warn_user("NoMemory", 0); + ro_gui_menu_destroy(); + return false; + } + gui_form_select_menu->title_data.indirected_text.text = + text_convert; + ro_gui_menu_init_structure(gui_form_select_menu, entries); + } + + /* initialise menu entries from form control */ + for (item = 0; item < entries; item++) { + option = form_select_get_option(control, item); + gui_form_select_menu->entries[item].menu_flags = 0; + if (option->selected) + gui_form_select_menu->entries[item].menu_flags = + wimp_MENU_TICKED; + if (!reopen) { + + /* convert spaces to hard spaces to stop things + * like 'Go Home' being treated as if 'Home' is a + * keyboard shortcut and right aligned in the menu. + */ + + temp = cnv_space2nbsp(option->text); + if (!temp) { + LOG("cnv_space2nbsp failed"); + ro_warn_user("NoMemory", 0); + ro_gui_menu_destroy(); + return false; + } + + err = utf8_to_local_encoding(temp, + 0, &text_convert); + if (err != NSERROR_OK) { + /* A bad encoding should never happen, + * so assert this */ + assert(err != NSERROR_BAD_ENCODING); + LOG("utf8_to_enc failed"); + ro_warn_user("NoMemory", 0); + ro_gui_menu_destroy(); + return false; + } + + free(temp); + + gui_form_select_menu->entries[item].data.indirected_text.text = + text_convert; + gui_form_select_menu->entries[item].data.indirected_text.size = + strlen(gui_form_select_menu->entries[item]. + data.indirected_text.text) + 1; + } + } + + gui_form_select_menu->entries[0].menu_flags |= + wimp_MENU_TITLE_INDIRECTED; + gui_form_select_menu->entries[item - 1].menu_flags |= wimp_MENU_LAST; + + return true; +} + +/** + * Process selections from a form select menu, passing them back to the core. + * + * \param *g The browser window affected by the menu. + * \param *selection The menu selection. + */ + +void ro_gui_window_process_form_select_menu(struct gui_window *g, + wimp_selection *selection) +{ + assert(g != NULL); + + if (selection->items[0] >= 0) + form_select_process_selection(gui_form_select_control, + selection->items[0]); +} + + +/* + * Window and Toolbar Lookup + */ + +/** + * Convert a RISC OS window handle to a gui_window. + * + * \param window RISC OS window handle. + * \return A pointer to a riscos gui window if found or NULL. + */ + +struct gui_window *ro_gui_window_lookup(wimp_w window) +{ + struct gui_window *g; + for (g = window_list; g; g = g->next) + if (g->window == window) + return g; + return NULL; +} + + +/** + * Convert a toolbar RISC OS window handle to a gui_window. + * + * \param window RISC OS window handle of a toolbar + * \return pointer to a structure if found, NULL otherwise + */ + +struct gui_window *ro_gui_toolbar_lookup(wimp_w window) +{ + struct gui_window *g = NULL; + struct toolbar *toolbar; + wimp_w parent; + + toolbar = ro_toolbar_window_lookup(window); + + if (toolbar != NULL) { + parent = ro_toolbar_get_parent_window(toolbar); + g = ro_gui_window_lookup(parent); + } + + return g; +} + + +/* + * Core to RISC OS Conversions + */ + +/** + * Convert x,y screen co-ordinates into window co-ordinates. + * + * \param g gui window + * \param x x ordinate + * \param y y ordinate + * \param pos receives position in window co-ordinatates + * \return true iff conversion successful + */ + +bool ro_gui_window_to_window_pos(struct gui_window *g, int x, int y, + os_coord *pos) +{ + wimp_window_state state; + os_error *error; + + assert(g); + + state.w = g->window; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x:%s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + pos->x = (x - (state.visible.x0 - state.xscroll)) / 2 / g->scale; + pos->y = ((state.visible.y1 - state.yscroll) - y) / 2 / g->scale; + return true; +} + + +/** + * Convert x,y window co-ordinates into screen co-ordinates. + * + * \param g gui window + * \param x x ordinate + * \param y y ordinate + * \param pos receives position in screen co-ordinatates + * \return true iff conversion successful + */ + +bool ro_gui_window_to_screen_pos(struct gui_window *g, int x, int y, + os_coord *pos) +{ + wimp_window_state state; + os_error *error; + + assert(g); + + state.w = g->window; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x:%s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + pos->x = (x * 2 * g->scale) + (state.visible.x0 - state.xscroll); + pos->y = (state.visible.y1 - state.yscroll) - (y * 2 * g->scale); + return true; +} + + +/* + * Miscellaneous Functions + * + * \TODO -- These items might well belong elsewhere. + */ + +/** + * Returns the state of the mouse buttons and modifiers keys for a + * mouse action, suitable for passing to the OS-independent + * browser window/ treeview/ etc code. + * + * \param buttons Wimp button state. + * \param type Wimp work-area/icon type for decoding. + * \return NetSurf core button state. + */ + +browser_mouse_state ro_gui_mouse_click_state(wimp_mouse_state buttons, + wimp_icon_flags type) +{ + browser_mouse_state state = 0; /* Blank state with nothing set */ + static struct { + enum { CLICK_SINGLE, CLICK_DOUBLE, CLICK_TRIPLE } type; + uint64_t time; + } last_click; + + switch (type) { + case wimp_BUTTON_CLICK_DRAG: + /* Handle single clicks. */ + + /* We fire core PRESS and CLICK events together for "action on + * press" behaviour. */ + if (buttons & (wimp_CLICK_SELECT)) /* Select click */ + state |= BROWSER_MOUSE_PRESS_1 | BROWSER_MOUSE_CLICK_1; + if (buttons & (wimp_CLICK_ADJUST)) /* Adjust click */ + state |= BROWSER_MOUSE_PRESS_2 | BROWSER_MOUSE_CLICK_2; + break; + + case wimp_BUTTON_DOUBLE_CLICK_DRAG: + /* Handle single, double, and triple clicks. */ + + /* Single clicks: Fire PRESS and CLICK events together + * for "action on press" behaviour. */ + if (buttons & (wimp_SINGLE_SELECT)) { + /* Select single click */ + state |= BROWSER_MOUSE_PRESS_1 | BROWSER_MOUSE_CLICK_1; + } else if (buttons & (wimp_SINGLE_ADJUST)) { + /* Adjust single click */ + state |= BROWSER_MOUSE_PRESS_2 | BROWSER_MOUSE_CLICK_2; + } + + /* Double clicks: Fire PRESS, CLICK, and DOUBLE_CLICK + * events together for "action on 2nd press" behaviour. */ + if (buttons & (wimp_DOUBLE_SELECT)) { + /* Select double click */ + state |= BROWSER_MOUSE_PRESS_1 | BROWSER_MOUSE_CLICK_1 | + BROWSER_MOUSE_DOUBLE_CLICK; + } else if (buttons & (wimp_DOUBLE_ADJUST)) { + /* Adjust double click */ + state |= BROWSER_MOUSE_PRESS_2 | BROWSER_MOUSE_CLICK_2 | + BROWSER_MOUSE_DOUBLE_CLICK; + } + + /* Need to consider what we have and decide whether to fire + * triple click instead */ + if ((state == (BROWSER_MOUSE_PRESS_1 | + BROWSER_MOUSE_CLICK_1)) || + (state == (BROWSER_MOUSE_PRESS_2 | + BROWSER_MOUSE_CLICK_2))) { + /* WIMP told us single click, but maybe we want to call + * it a triple click */ + + if (last_click.type == CLICK_DOUBLE) { + uint64_t ms_now; + nsu_getmonotonic_ms(&ms_now); + + if (ms_now < (last_click.time + 500)) { + /* Triple click! Fire PRESS, CLICK, and + * TRIPLE_CLICK events together for + * "action on 3nd press" behaviour. */ + last_click.type = CLICK_TRIPLE; + state |= BROWSER_MOUSE_TRIPLE_CLICK; + } else { + /* Single click */ + last_click.type = CLICK_SINGLE; + } + } else { + /* Single click */ + last_click.type = CLICK_SINGLE; + } + } else if ((state == (BROWSER_MOUSE_PRESS_1 | + BROWSER_MOUSE_CLICK_1 | + BROWSER_MOUSE_DOUBLE_CLICK)) || + (state == (BROWSER_MOUSE_PRESS_2 | + BROWSER_MOUSE_CLICK_2 | + BROWSER_MOUSE_DOUBLE_CLICK))) { + /* Wimp told us double click, but we may want to + * call it single click */ + + if (last_click.type == CLICK_TRIPLE) { + state &= ~BROWSER_MOUSE_DOUBLE_CLICK; + last_click.type = CLICK_SINGLE; + } else { + last_click.type = CLICK_DOUBLE; + nsu_getmonotonic_ms(&last_click.time); + } + } else { + last_click.type = CLICK_SINGLE; + } + break; + } + + /* Check if a drag has started */ + if (buttons & (wimp_DRAG_SELECT)) { + /* A drag was _started_ with Select; Fire DRAG_1. */ + state |= BROWSER_MOUSE_DRAG_1; + mouse_drag_select = true; + } + if (buttons & (wimp_DRAG_ADJUST)) { + /* A drag was _started_ with Adjust; Fire DRAG_2. */ + state |= BROWSER_MOUSE_DRAG_2; + mouse_drag_adjust = true; + } + + /* Set modifier key state */ + if (ro_gui_shift_pressed()) state |= BROWSER_MOUSE_MOD_1; + if (ro_gui_ctrl_pressed()) state |= BROWSER_MOUSE_MOD_2; + if (ro_gui_alt_pressed()) state |= BROWSER_MOUSE_MOD_3; + + return state; +} + + +/** + * Returns the state of the mouse buttons and modifiers keys whilst + * dragging, for passing to the OS-independent browser window/ treeview/ + * etc code + * + * \param buttons Wimp button state. + * \param type Wimp work-area/icon type for decoding. + * \return NetSurf core button state. + */ + +browser_mouse_state ro_gui_mouse_drag_state(wimp_mouse_state buttons, + wimp_icon_flags type) +{ + browser_mouse_state state = 0; /* Blank state with nothing set */ + + /* If mouse buttons aren't held, turn off drags */ + if (!(buttons & (wimp_CLICK_SELECT | wimp_CLICK_ADJUST))) { + mouse_drag_select = false; + mouse_drag_adjust = false; + } + + /* If there's a drag happening, set DRAG_ON and record which button + * the drag is happening with, i.e. HOLDING_1 or HOLDING_2 */ + if (mouse_drag_select) { + state |= BROWSER_MOUSE_DRAG_ON | BROWSER_MOUSE_HOLDING_1; + } + if (mouse_drag_adjust) { + state |= BROWSER_MOUSE_DRAG_ON | BROWSER_MOUSE_HOLDING_2; + } + + /* Set modifier key state */ + if (ro_gui_shift_pressed()) state |= BROWSER_MOUSE_MOD_1; + if (ro_gui_ctrl_pressed()) state |= BROWSER_MOUSE_MOD_2; + if (ro_gui_alt_pressed()) state |= BROWSER_MOUSE_MOD_3; + + return state; +} + + +/** + * Returns true iff one or more Shift keys is held down + */ + +bool ro_gui_shift_pressed(void) +{ + int shift = 0; + xosbyte1(osbyte_SCAN_KEYBOARD, 0 ^ 0x80, 0, &shift); + return (shift == 0xff); +} + + +/** + * Returns true iff one or more Ctrl keys is held down + */ + +bool ro_gui_ctrl_pressed(void) +{ + int ctrl = 0; + xosbyte1(osbyte_SCAN_KEYBOARD, 1 ^ 0x80, 0, &ctrl); + return (ctrl == 0xff); +} + + +/** + * Returns true iff one or more Alt keys is held down + */ + +bool ro_gui_alt_pressed(void) +{ + int alt = 0; + xosbyte1(osbyte_SCAN_KEYBOARD, 2 ^ 0x80, 0, &alt); + return (alt == 0xff); +} + +static struct gui_window_table window_table = { + .create = gui_window_create, + .destroy = gui_window_destroy, + .redraw = gui_window_redraw_window, + .update = gui_window_update_box, + .get_scroll = gui_window_get_scroll, + .set_scroll = gui_window_set_scroll, + .get_dimensions = gui_window_get_dimensions, + .update_extent = gui_window_update_extent, + .reformat = riscos_window_reformat, + + .set_title = gui_window_set_title, + .set_url = ro_gui_window_set_url, + .set_icon = gui_window_set_icon, + .set_status = riscos_window_set_status, + .set_pointer = gui_window_set_pointer, + .place_caret = gui_window_place_caret, + .remove_caret = gui_window_remove_caret, + .save_link = gui_window_save_link, + .drag_start = gui_window_drag_start, + .scroll_visible = gui_window_scroll_visible, + .scroll_start = gui_window_scroll_start, + .new_content = gui_window_new_content, + .start_throbber = gui_window_start_throbber, + .stop_throbber = gui_window_stop_throbber, + .create_form_select_menu = gui_window_create_form_select_menu, + + /* from save */ + .drag_save_object = gui_drag_save_object, + .drag_save_selection =gui_drag_save_selection, + + /* from textselection */ + .start_selection = gui_start_selection, +}; + +struct gui_window_table *riscos_window_table = &window_table; diff --git a/frontends/riscos/window.h b/frontends/riscos/window.h new file mode 100644 index 000000000..2e6f6e9aa --- /dev/null +++ b/frontends/riscos/window.h @@ -0,0 +1,46 @@ +/* + * Copyright 2010, 2011 Stephen Fryatt <stevef@netsurf-browser.org> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** \file + * Browser window handling (interface). + */ + +#include <stdbool.h> + +#ifndef _NETSURF_RISCOS_WINDOW_H_ +#define _NETSURF_RISCOS_WINDOW_H_ + +struct gui_window; +struct nsurl; + +extern struct gui_window_table *riscos_window_table; + +void ro_gui_window_initialise(void); + +bool ro_gui_window_check_menu(wimp_menu *menu); + +/** + * Set the contents of a window's address bar. + * + * \param g gui_window to update + * \param url new url for address bar + */ +nserror ro_gui_window_set_url(struct gui_window *g, struct nsurl *url); + +#endif + |