summaryrefslogtreecommitdiff
path: root/frontends/riscos/theme_install.c
diff options
context:
space:
mode:
Diffstat (limited to 'frontends/riscos/theme_install.c')
-rw-r--r--frontends/riscos/theme_install.c237
1 files changed, 237 insertions, 0 deletions
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;
+}