summaryrefslogtreecommitdiff
path: root/riscos
diff options
context:
space:
mode:
Diffstat (limited to 'riscos')
-rw-r--r--riscos/dialog.c7
-rw-r--r--riscos/gui.c22
-rw-r--r--riscos/gui.h4
-rw-r--r--riscos/theme.c316
-rw-r--r--riscos/theme.h20
-rw-r--r--riscos/theme_install.c140
-rw-r--r--riscos/wimp.c52
-rw-r--r--riscos/wimp.h2
-rw-r--r--riscos/window.c12
9 files changed, 394 insertions, 181 deletions
diff --git a/riscos/dialog.c b/riscos/dialog.c
index f55cb7b55..c6cb54fc7 100644
--- a/riscos/dialog.c
+++ b/riscos/dialog.c
@@ -139,6 +139,7 @@ void ro_gui_dialog_init(void)
dialog_print = ro_gui_dialog_create("print");
dialog_config_font = ro_gui_dialog_create("config_font");
dialog_config_image = ro_gui_dialog_create("config_img");
+ dialog_theme_install = ro_gui_dialog_create("theme_inst");
}
@@ -455,6 +456,8 @@ void ro_gui_dialog_click(wimp_pointer *pointer)
#endif
else if (pointer->w == dialog_config_font)
ro_gui_dialog_click_config_font(pointer);
+ else if (pointer->w == dialog_theme_install)
+ ro_gui_theme_install_click(pointer);
}
/**
@@ -1004,7 +1007,7 @@ void ro_gui_dialog_click_config_th(wimp_pointer *pointer)
{
switch (pointer->i) {
case ICON_CONFIG_TH_MANAGE:
- os_cli("Filer_OpenDir " THEMES_DIR);
+ os_cli("Filer_OpenDir Choices:WWW.NetSurf.Themes");
break;
case ICON_CONFIG_TH_GET:
browser_window_create(
@@ -1419,6 +1422,8 @@ void ro_gui_dialog_load_themes(void) {
if (link->next) extent.y0 -= 16;
if (extent.y0 > min_extent) extent.y0 = min_extent;
xwimp_set_extent(dialog_config_th_pane, &extent);
+ ro_gui_set_icon_button_type(link->toolbar->toolbar_handle,
+ ICON_TOOLBAR_URL, wimp_BUTTON_NEVER);
/* Create the descriptor icons and separator line
*/
diff --git a/riscos/gui.c b/riscos/gui.c
index f7e8fa12c..9545ba458 100644
--- a/riscos/gui.c
+++ b/riscos/gui.c
@@ -68,7 +68,7 @@ int __feature_imagefs_is_file = 1; /**< For UnixLib. */
int __riscosify_control = __RISCOSIFY_NO_SUFFIX |
__RISCOSIFY_NO_REVERSE_SUFFIX;
-char *NETSURF_DIR;
+const char * NETSURF_DIR;
char *default_stylesheet_url;
char *adblock_stylesheet_url;
@@ -175,6 +175,7 @@ static char *ro_path_to_url(const char *path);
void gui_init(int argc, char** argv)
{
+ char theme_path[256];
char path[40];
os_error *error;
int length;
@@ -232,13 +233,6 @@ void gui_init(int argc, char** argv)
if (getenv("NetSurf$Start_URI_Handler"))
xwimp_start_task("Desktop", 0);
- /* Load our chosen theme
- */
- ro_gui_theme_initialise();
- descriptor = ro_gui_theme_find(option_theme);
- if (!descriptor) descriptor = ro_gui_theme_find("NetSurf");
- ro_gui_theme_apply(descriptor);
-
/* Open the templates
*/
if ((length = snprintf(path, sizeof(path),
@@ -258,12 +252,22 @@ void gui_init(int argc, char** argv)
ro_gui_401login_init();
#endif
ro_gui_history_init();
- ro_gui_theme_install_init();
wimp_close_template();
ro_gui_sprites_init();
ro_gui_tree_initialise(); /* must be done after sprite loading */
ro_gui_hotlist_initialise();
+ /* Load our chosen theme
+ */
+ ro_gui_theme_initialise();
+ descriptor = ro_gui_theme_find(option_theme);
+ if (!descriptor) {
+ snprintf(theme_path, 256, "%s.Resources.Theme", NETSURF_DIR);
+ theme_path[255] = '\0';
+ descriptor = ro_gui_theme_find(theme_path);
+ }
+ ro_gui_theme_apply(descriptor);
+
/* We don't create an Iconbar icon on NCOS */
#ifndef ncos
ro_gui_icon_bar_create();
diff --git a/riscos/gui.h b/riscos/gui.h
index 0d25890bc..8d78b411f 100644
--- a/riscos/gui.h
+++ b/riscos/gui.h
@@ -21,7 +21,7 @@
#include "netsurf/desktop/options.h"
#include "netsurf/desktop/tree.h"
-#define THEMES_DIR "<NetSurf$Dir>.Themes"
+extern const char * NETSURF_DIR;
struct toolbar;
struct plotter_table;
@@ -252,7 +252,7 @@ extern int ro_plot_origin_y;
void ro_plot_set_scale(float scale);
/* in theme_install.c */
-void ro_gui_theme_install_init(void);
+void ro_gui_theme_install_click(wimp_pointer *pointer);
/* toolbar types */
#define TOOLBAR_BROWSER 0
diff --git a/riscos/theme.c b/riscos/theme.c
index 648460f10..2d7750e82 100644
--- a/riscos/theme.c
+++ b/riscos/theme.c
@@ -2,7 +2,7 @@
* This file is part of NetSurf, http://netsurf.sourceforge.net/
* Licensed under the GNU General Public License,
* http://www.opensource.org/licenses/gpl-license
- * Copyright 2004 Richard Wilson <not_ginger_matt@users.sourceforge.net>
+ * Copyright 2004, 2005 Richard Wilson <info@tinct.net>
*/
/** \file
@@ -30,32 +30,14 @@
#include "netsurf/utils/log.h"
#include "netsurf/utils/utils.h"
-
#define THEME_URL_MEMORY 256
#define THEME_THROBBER_MEMORY 12
#define THEME_STATUS_MEMORY 256
-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 throbber_left;
- char future_expansion_1;
- char future_expansion_2;
- char future_expansion_3;
- unsigned int compressed_sprite_size;
- unsigned int decompressed_sprite_size;
-};
-
-
static struct theme_descriptor *theme_current = NULL;
static struct theme_descriptor *theme_descriptors = NULL;
+static void ro_gui_theme_get_available_in_dir(const char *directory);
static void ro_gui_theme_free(struct theme_descriptor *descriptor, bool list);
static void ro_gui_theme_add_toolbar_icon(struct toolbar *toolbar, const char *name, int icon_number);
static void ro_gui_theme_update_toolbar_icon(struct toolbar *toolbar, struct toolbar_icon *icon);
@@ -104,6 +86,9 @@ static char theme_separator_name[] = "separator\0";
void ro_gui_theme_initialise(void) {
/* Get an initial theme list
*/
+ xosfile_create_dir("<Choices$Write>.WWW", 0);
+ xosfile_create_dir("<Choices$Write>.WWW.NetSurf", 0);
+ xosfile_create_dir("<Choices$Write>.WWW.NetSurf.Themes", 0);
theme_descriptors = ro_gui_theme_get_available();
}
@@ -153,10 +138,58 @@ struct theme_descriptor *ro_gui_theme_find(const char *filename) {
* \return the requested theme_descriptor, or NULL if not found
*/
struct theme_descriptor *ro_gui_theme_get_available(void) {
- struct theme_file_header file_header;
struct theme_descriptor *current;
struct theme_descriptor *test;
char pathname[256];
+
+ /* Close any descriptors we've got so far
+ */
+ ro_gui_theme_free(theme_descriptors, true);
+
+ /* Open a variety of directories
+ */
+ snprintf(pathname, 256, "%s.Resources", NETSURF_DIR);
+ pathname[255] = '\0';
+ ro_gui_theme_get_available_in_dir(pathname);
+ ro_gui_theme_get_available_in_dir("Choices:WWW.NetSurf.Themes");
+
+ /* 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) {
+ struct theme_file_header file_header;
+ struct theme_descriptor *current;
+ char pathname[256];
int context = 0;
int read_count;
osgbpb_INFO(100) info;
@@ -164,21 +197,19 @@ struct theme_descriptor *ro_gui_theme_get_available(void) {
os_fw file_handle;
os_error *error;
- /* Close any descriptors we've got so far
- */
- ro_gui_theme_free(theme_descriptors, true);
-
/* Create a new set
*/
while (context != -1) {
/* Get the next entry
*/
- error = xosgbpb_dir_entries_info(THEMES_DIR,
+ 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;
warn_user("MiscError", error->errmess);
break;
}
@@ -188,15 +219,15 @@ struct theme_descriptor *ro_gui_theme_get_available(void) {
if (read_count == 0)
continue;
- /* Only process files
+ /* Get our full filename
*/
- if ((info.obj_type == fileswitch_IS_FILE) && (!ro_gui_theme_find(info.name))) {
+ snprintf(pathname, sizeof pathname, "%s.%s",
+ directory, info.name);
+ pathname[sizeof pathname - 1] = 0;
- /* Get our full filename
- */
- snprintf(pathname, sizeof pathname, "%s.%s",
- THEMES_DIR, info.name);
- pathname[sizeof pathname - 1] = 0;
+ /* Only process files
+ */
+ if ((info.obj_type == fileswitch_IS_FILE) && (!ro_gui_theme_find(pathname))) {
/* Get the header
*/
@@ -222,12 +253,6 @@ struct theme_descriptor *ro_gui_theme_get_available(void) {
if (output_left > 0)
continue; /* should try to read more? */
- /* Check we are a valid theme
- */
- if ((file_header.magic_value != 0x4d54534e) ||
- (file_header.parser_version > 1))
- continue;
-
/* Create a new theme descriptor
*/
current = (struct theme_descriptor *)calloc(1,
@@ -235,27 +260,24 @@ struct theme_descriptor *ro_gui_theme_get_available(void) {
if (!current) {
LOG(("calloc failed"));
warn_user("NoMemory", 0);
- return theme_descriptors;
+ return;
}
- current->filename = malloc(strlen(info.name) + 1);
+
+ if (!ro_gui_theme_read_file_header(current, &file_header)) {
+ free(current);
+ continue;
+ }
+
+ current->filename = malloc(strlen(pathname) + 1);
if (!current->filename) {
LOG(("malloc failed"));
warn_user("NoMemory", 0);
free(current);
- return theme_descriptors;
+ return;
}
- strcpy(current->filename, info.name);
- strcpy(current->name, file_header.name);
- strcpy(current->author, file_header.author);
- current->browser_background = file_header.browser_bg;
- current->hotlist_background = file_header.hotlist_bg;
- current->status_background = file_header.status_bg;
- current->status_foreground = file_header.status_fg;
- current->throbber_right = (file_header.throbber_left == 0x00);
- current->decompressed_size = file_header.decompressed_sprite_size;
- current->compressed_size = file_header.compressed_sprite_size;
-
- /* Link in our new descriptor alphabetically
+ strcpy(current->filename, pathname);
+
+ /* Link in our new descriptor
*/
if (theme_descriptors) {
current->next = theme_descriptors;
@@ -264,32 +286,40 @@ struct theme_descriptor *ro_gui_theme_get_available(void) {
theme_descriptors = current;
}
}
+}
- /* Sort alphabetically in a very rubbish way
- */
- if (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;
+/**
+ * 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 theme_descriptors;
+ return true;
}
@@ -306,17 +336,17 @@ bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list) {
os_coord dimensions;
os_mode mode;
os_error *error;
- char pathname[256];
+ char sprite_name[16];
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) {
+ if (list && descriptor) {
while (descriptor->previous) descriptor = descriptor->previous;
}
@@ -338,17 +368,11 @@ bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list) {
}
descriptor->theme->users = 1;
- /* Get our full filename
- */
- snprintf(pathname, sizeof pathname, "%s.%s",
- THEMES_DIR, descriptor->filename);
- pathname[sizeof pathname - 1] = 0;
-
/* Load the file. We use a goto to exit from here on in as using
a continue leaves us in an infinite loop - it's nasty, and really
should be rewritten properly.
*/
- error = xosfile_read_stamped_no_path(pathname,
+ 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",
@@ -364,7 +388,7 @@ bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list) {
warn_user("NoMemory", 0);
return false;
}
- error = xosfile_load_stamped_no_path(pathname, (byte *)raw_data,
+ error = xosfile_load_stamped_no_path(descriptor->filename, (byte *)raw_data,
0, 0, 0, 0, 0);
if (error) {
free(raw_data);
@@ -410,7 +434,7 @@ bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list) {
goto ro_gui_theme_open_continue;
}
if (status != 0) {
- free(decompressed);
+ free(decompressed);
goto ro_gui_theme_open_continue;
}
descriptor->theme->sprite_area = decompressed;
@@ -419,14 +443,14 @@ bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list) {
maximum dimensions for all 'thobber%i' icons.
*/
for (i = 1; i <= descriptor->theme->sprite_area->sprite_count; i++) {
- osspriteop_return_name(osspriteop_USER_AREA,
- descriptor->theme->sprite_area, pathname, 12, i);
- if (strncmp(pathname, "throbber", 8) == 0) {
+ xosspriteop_return_name(osspriteop_USER_AREA,
+ descriptor->theme->sprite_area, sprite_name, 16, i, 0);
+ if (strncmp(sprite_name, "throbber", 8) == 0) {
/* Get the max sprite width/height
*/
xosspriteop_read_sprite_info(osspriteop_USER_AREA,
descriptor->theme->sprite_area,
- (osspriteop_id)pathname,
+ (osspriteop_id)sprite_name,
&dimensions.x, &dimensions.y,
(osbool *)0, &mode);
ro_convert_pixels_to_os_units(&dimensions, mode);
@@ -437,22 +461,21 @@ bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list) {
/* Get the throbber number
*/
- n = atoi(pathname + 8);
+ n = atoi(sprite_name + 8);
if (descriptor->theme->throbber_frames < n)
descriptor->theme->throbber_frames = n;
}
- }
+ }
}
-
ro_gui_theme_open_continue:
+
/* Loop or return depending on whether the entire list
is to be processed.
*/
- if (list) {
+ if (list && descriptor)
descriptor = descriptor->next;
- } else {
+ else
return result;
- }
}
return result;
}
@@ -569,16 +592,14 @@ void ro_gui_theme_redraw(struct toolbar *toolbar, wimp_draw *redraw) {
perform_redraw &= toolbar->display_buttons;
while (more) {
- if (perform_redraw) {
- for (icon = toolbar->icon; icon; icon = icon->next) {
- if ((icon->icon_number == -1) && (icon->display)) {
+ if (perform_redraw) {
+ for (icon = toolbar->icon; icon; icon = icon->next) {
+ if ((icon->icon_number == -1) && (icon->display)) {
separator_icon.extent.x0 = icon->x;
separator_icon.extent.x1 = icon->x + icon->width;
wimp_plot_icon(&separator_icon);
}
}
-
-
}
more = wimp_get_rectangle(redraw);
}
@@ -602,22 +623,17 @@ void ro_gui_theme_free(struct theme_descriptor *descriptor, bool list) {
/* If we are freeing the whole of the list then we need to
start at the first descriptor.
*/
- if (list) {
- while (descriptor->previous) descriptor = descriptor->previous;
- }
+ while ((list) && (descriptor->previous))
+ descriptor = descriptor->previous;
/* Close the themes
*/
while (descriptor) {
- /* Remember where we are going next
- */
next_descriptor = descriptor->next;
/* If we have no loaded theme then we can kill the descriptor
*/
if (!descriptor->theme) {
- /* De-link the descriptor
- */
if (descriptor->previous)
descriptor->previous->next = descriptor->next;
if (descriptor->next)
@@ -627,20 +643,17 @@ void ro_gui_theme_free(struct theme_descriptor *descriptor, bool list) {
*/
if (theme_descriptors == descriptor)
theme_descriptors = next_descriptor;
+
/* Release any memory
*/
free(descriptor->filename);
free(descriptor);
}
- /* Loop or return depending on whether the entire list
- is to be processed.
- */
- if (list) {
+ if (list)
descriptor = next_descriptor;
- } else {
+ else
return;
- }
}
}
@@ -741,36 +754,31 @@ bool ro_gui_theme_update_toolbar(struct theme_descriptor *descriptor, struct too
os_error *error;
osspriteop_area *sprite_area;
struct toolbar_icon *toolbar_icon;
- int width;
+ int width, max_icon;
if (!toolbar) return false;
/* Set the theme and window sprite area
*/
if (!descriptor) descriptor = theme_current;
toolbar->descriptor = descriptor;
- if ((toolbar->descriptor) && (toolbar->descriptor->theme)) {
+ if ((toolbar->descriptor) && (toolbar->descriptor->theme))
sprite_area = toolbar->descriptor->theme->sprite_area;
- } else {
+ else
sprite_area = (osspriteop_area *)1;
- }
theme_toolbar_window.sprite_area = sprite_area;
/* Update the icon sizes
*/
- toolbar_icon = toolbar->icon;
- while (toolbar_icon) {
+ for (toolbar_icon = toolbar->icon; toolbar_icon; toolbar_icon = toolbar_icon->next)
ro_gui_theme_update_toolbar_icon(toolbar, toolbar_icon);
- toolbar_icon = toolbar_icon->next;
- }
/* Recreate the toolbar window
*/
if (toolbar->descriptor) {
- if (toolbar->type == THEME_BROWSER_TOOLBAR) {
+ if (toolbar->type == THEME_BROWSER_TOOLBAR)
theme_toolbar_window.work_bg = toolbar->descriptor->browser_background;
- } else {
+ else
theme_toolbar_window.work_bg = toolbar->descriptor->hotlist_background;
- }
} else {
theme_toolbar_window.work_bg = wimp_COLOUR_VERY_LIGHT_GREY;
}
@@ -780,8 +788,12 @@ bool ro_gui_theme_update_toolbar(struct theme_descriptor *descriptor, struct too
theme_toolbar_window.ymin = 1;
theme_toolbar_window.extent.x1 = 16384;
theme_toolbar_window.extent.y1 = 16384;
+ theme_toolbar_window.sprite_area = sprite_area;
if (toolbar->toolbar_handle) {
- xwimp_delete_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;
}
error = xwimp_create_window(&theme_toolbar_window, &toolbar->toolbar_handle);
@@ -793,22 +805,24 @@ bool ro_gui_theme_update_toolbar(struct theme_descriptor *descriptor, struct too
}
/* Create the basic icons
- */
- int max_icon = ICON_TOOLBAR_URL;
- if (toolbar->type == THEME_HOTLIST_TOOLBAR) max_icon = ICON_TOOLBAR_HOTLIST_LAST;
+ */
+ if (toolbar->type == THEME_HOTLIST_TOOLBAR)
+ max_icon = ICON_TOOLBAR_HOTLIST_LAST;
+ else
+ max_icon = ICON_TOOLBAR_URL;
new_icon.w = toolbar->toolbar_handle;
new_icon.icon.data.indirected_text.size = 1;
new_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);
- if (toolbar->descriptor) {
+ if (toolbar->descriptor)
new_icon.icon.flags |= (toolbar->descriptor->browser_background
<< wimp_ICON_BG_COLOUR_SHIFT);
- } else {
+ else
new_icon.icon.flags |= (wimp_COLOUR_VERY_LIGHT_GREY
<< wimp_ICON_BG_COLOUR_SHIFT);
- }
+
for (int i = 0; i < max_icon; i++) {
new_icon.icon.data.indirected_text.text = theme_null_text_string;
toolbar_icon = toolbar->icon;
@@ -876,11 +890,10 @@ bool ro_gui_theme_update_toolbar(struct theme_descriptor *descriptor, struct too
xwimp_delete_window(toolbar->status_handle);
toolbar->status_handle = NULL;
}
- if (toolbar->descriptor) {
+ if (toolbar->descriptor)
theme_toolbar_window.work_bg = toolbar->descriptor->status_background;
- } else {
+ else
theme_toolbar_window.work_bg = wimp_COLOUR_VERY_LIGHT_GREY;
- }
theme_toolbar_window.flags &= ~wimp_WINDOW_NO_BOUNDS;
theme_toolbar_window.flags |= wimp_WINDOW_AUTO_REDRAW;
theme_toolbar_window.xmin = 12;
@@ -915,15 +928,14 @@ bool ro_gui_theme_update_toolbar(struct theme_descriptor *descriptor, struct too
/* And finally our status display icon
*/
new_icon.icon.flags = wimp_ICON_TEXT | wimp_ICON_INDIRECTED | wimp_ICON_VCENTRED;
- if (toolbar->descriptor) {
+ if (toolbar->descriptor)
new_icon.icon.flags |=
(toolbar->descriptor->status_foreground << wimp_ICON_FG_COLOUR_SHIFT) |
(toolbar->descriptor->status_background << wimp_ICON_BG_COLOUR_SHIFT);
- } else {
+ else
new_icon.icon.flags |=
(wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT) |
(wimp_COLOUR_VERY_LIGHT_GREY << wimp_ICON_BG_COLOUR_SHIFT);
- }
new_icon.icon.data.indirected_text.text = toolbar->status_buffer;
new_icon.icon.data.indirected_text.validation = theme_null_text_string;
new_icon.icon.data.indirected_text.size = THEME_STATUS_MEMORY;
@@ -1187,7 +1199,7 @@ bool ro_gui_theme_process_toolbar(struct toolbar *toolbar, int width) {
while (toolbar_icon) {
if ((toolbar->display_buttons) && (toolbar_icon->display)
&& (toolbar_icon->width > 0)) {
- visible_icon = true;
+ visible_icon = true;
bottom_edge = (toolbar->height -
toolbar_icon->height) / 2;
toolbar_icon->x = left_edge;
@@ -1256,11 +1268,11 @@ bool ro_gui_theme_process_toolbar(struct toolbar *toolbar, int width) {
*/
toolbar->toolbar_current = width;
if (toolbar->reformat_buttons) {
- extent.x1 = 16384;
- extent.y0 = 0;
- extent.y1 = toolbar->height;
- xwimp_set_extent(toolbar->toolbar_handle, &extent);
- if ((parent) && (old_height != toolbar->height)) {
+ extent.x1 = 16384;
+ extent.y0 = 0;
+ extent.y1 = toolbar->height;
+ xwimp_set_extent(toolbar->toolbar_handle, &extent);
+ if ((parent) && (old_height != toolbar->height)) {
ro_gui_theme_attach_toolbar(toolbar, parent);
}
}
@@ -1384,7 +1396,7 @@ void ro_gui_theme_destroy_toolbar(struct toolbar *toolbar) {
* Adds a toolbar icon to the end of a toolbar
*
* \param toolbar the toolbar to add the icon to the end of
- * \param name the icon name, or NULL for a separator
+ * \param name the icon name, or NULL for a separator
* \param icon_number the RISC OS Wimp icon number for the icon (not used for separators)
*/
void ro_gui_theme_add_toolbar_icon(struct toolbar *toolbar, const char *name, int icon_number) {
@@ -1488,13 +1500,13 @@ void ro_gui_theme_destroy_toolbar_icon(struct toolbar_icon *icon) {
* Returns the toolbar icon at a specified position
*
* \param toolbar the toolbar to examine
- * \param x the x co-ordinate to check
- * \param y the y co-ordinate to check
+ * \param x the x co-ordinate to check
+ * \param y the y co-ordinate to check
* \return the toolbar icon at the specified position, or NULL for no icon
*/
struct toolbar_icon *ro_gui_theme_toolbar_get_icon(struct toolbar *toolbar, int x, int y) {
- struct toolbar_icon *icon;
- icon = toolbar->icon;
+ struct toolbar_icon *icon;
+ icon = toolbar->icon;
/* FINISH ME */
return NULL;
}
diff --git a/riscos/theme.h b/riscos/theme.h
index 1f6e90b2e..aa8061a78 100644
--- a/riscos/theme.h
+++ b/riscos/theme.h
@@ -19,6 +19,23 @@ typedef enum {
THEME_HOTLIST_TOOLBAR
} toolbar_type;
+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 toolbar_icon {
int icon_number; /**< wimp icon number */
bool display; /**< whether to display the icon */
@@ -70,6 +87,7 @@ struct theme_descriptor {
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) */
@@ -81,6 +99,8 @@ void ro_gui_theme_initialise(void);
void ro_gui_theme_finalise(void);
struct theme_descriptor *ro_gui_theme_find(const char *filename);
struct theme_descriptor *ro_gui_theme_get_available(void);
+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);
diff --git a/riscos/theme_install.c b/riscos/theme_install.c
index 75991f47f..b1b733b2f 100644
--- a/riscos/theme_install.c
+++ b/riscos/theme_install.c
@@ -11,18 +11,24 @@
#include <assert.h>
#include <stdbool.h>
+#include "oslib/osfile.h"
#include "netsurf/content/content.h"
#include "netsurf/desktop/browser.h"
#include "netsurf/riscos/gui.h"
+#include "netsurf/riscos/options.h"
+#include "netsurf/riscos/theme.h"
#include "netsurf/riscos/wimp.h"
#include "netsurf/utils/messages.h"
+#include "netsurf/utils/url.h"
#include "netsurf/utils/utils.h"
-static bool theme_install_active = false;
+static bool theme_install_active;
+static struct content *theme_install_content = NULL;
+static struct theme_descriptor theme_install_descriptor;
wimp_w dialog_theme_install;
-
+static void theme_install_close(void);
void theme_install_callback(content_msg msg, struct content *c,
void *p1, void *p2, union content_msg_data data);
@@ -64,25 +70,49 @@ void theme_install_start(struct content *c)
void theme_install_callback(content_msg msg, struct content *c,
void *p1, void *p2, union content_msg_data data)
{
+ char txt_buffer[256];
+ bool error = false;
+ int author_indent = 0;
+
switch (msg) {
case CONTENT_MSG_READY:
break;
case CONTENT_MSG_DONE:
- /** \todo: parse the theme data, extract name & author,
- * and ask the user if they want to install */
+ theme_install_content = c;
+ if ((c->source_size < sizeof(struct theme_file_header)) ||
+ (!ro_gui_theme_read_file_header(&theme_install_descriptor,
+ (struct theme_file_header *)c->source_data)))
+ error = true;
+ else if (c->source_size - sizeof(struct theme_file_header) !=
+ theme_install_descriptor.compressed_size)
+ error = true;
+
+ if (error) {
+ warn_user("ThemeInvalid", 0);
+ theme_install_close();
+ 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(txt_buffer, 256, messages_get("ThemeInstall"),
+ theme_install_descriptor.name,
+ &theme_install_descriptor.author[author_indent]);
+ txt_buffer[255] = '\0';
ro_gui_set_icon_string(dialog_theme_install,
ICON_THEME_INSTALL_MESSAGE,
- "Would you like to install the theme "
- "\"x\" by y?");
+ txt_buffer);
ro_gui_set_icon_shaded_state(dialog_theme_install,
ICON_THEME_INSTALL_INSTALL, false);
break;
case CONTENT_MSG_ERROR:
- ro_gui_dialog_close(dialog_theme_install);
+ theme_install_close();
warn_user(data.error, 0);
- theme_install_active = false;
break;
case CONTENT_MSG_STATUS:
@@ -102,10 +132,96 @@ void theme_install_callback(content_msg msg, struct content *c,
/**
- * Create theme install window.
+ * Handle clicks in the theme install window
*/
+void ro_gui_theme_install_click(wimp_pointer *pointer) {
+ os_error *error;
+ fileswitch_object_type obj_type;
+ char theme_save[256];
+ char theme_leaf[256];
+ char *theme_file;
+ int theme_number = 1;
+ bool theme_found;
+ struct theme_descriptor *theme_install;
+
+ switch (pointer->i) {
+ case ICON_THEME_INSTALL_INSTALL:
+ if (theme_install_content) {
+ if (url_nice(theme_install_descriptor.name, &theme_file) != URL_FUNC_OK) {
+ warn_user("ThemeInstallErr", 0);
+ theme_install_close();
+ return;
+ }
+ theme_found = false;
+ while (!theme_found) {
+ if (theme_number == 1)
+ snprintf(theme_leaf, 256,
+ "WWW.NetSurf.Themes.%s",
+ theme_file);
+ else
+ snprintf(theme_leaf, 256,
+ "WWW.NetSurf.Themes.%s%i",
+ theme_file, theme_number);
+ theme_leaf[255] = '\0';
+ theme_number++;
+ snprintf(theme_save, 256,
+ "<Choices$Write>.%s",
+ theme_leaf);
+ theme_save[255] = '\0';
+ error = xosfile_read_stamped(theme_save,
+ &obj_type, 0, 0, 0, 0, 0);
+ if (error) {
+ warn_user("ThemeInstallErr", 0);
+ theme_install_close();
+ free(theme_file);
+ return;
+ }
+ theme_found = (obj_type == osfile_NOT_FOUND);
+ }
+ free(theme_file);
+ error = xosfile_save_stamped(theme_save, 0xffd,
+ theme_install_content->source_data,
+ theme_install_content->source_data +
+ theme_install_content->source_size);
+ if (error) {
+ warn_user("ThemeInstallErr", 0);
+ theme_install_close();
+ return;
+ }
+ /* apply theme only on Select clicks */
+ if (pointer->buttons == wimp_CLICK_SELECT) {
+ ro_gui_theme_get_available();
+ snprintf(theme_save, 256, "Choices:%s", theme_leaf);
+ theme_save[255] = '\0';
+ theme_install = ro_gui_theme_find(theme_save);
+ if ((!theme_install) ||
+ (!ro_gui_theme_apply(theme_install))) {
+ warn_user("ThemeApplyErr", 0);
+ } else {
+ theme_file = strdup(theme_save);
+ if (!theme_file) {
+ warn_user("NoMemory", 0);
+ } else {
+ free(option_theme);
+ option_theme = theme_file;
+ }
+ }
+ }
+ theme_install_close();
+ }
+ break;
+ case ICON_THEME_INSTALL_CANCEL:
+ if (pointer->buttons == wimp_CLICK_ADJUST)
+ break;
+ theme_install_close();
+ break;
+ }
+}
-void ro_gui_theme_install_init(void)
-{
- dialog_theme_install = ro_gui_dialog_create("theme_inst");
+static void theme_install_close(void) {
+ theme_install_active = false;
+ if (theme_install_content)
+ content_close(theme_install_content);
+ theme_install_content = NULL;
+ ro_gui_dialog_close(dialog_theme_install);
}
diff --git a/riscos/wimp.c b/riscos/wimp.c
index 012cdd6fb..a9e2a29d4 100644
--- a/riscos/wimp.c
+++ b/riscos/wimp.c
@@ -128,6 +128,37 @@ void ro_convert_pixels_to_os_units(os_coord *pixels, os_mode mode) {
/**
+ * 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));
+ 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));
+ warn_user("WimpError", error->errmess);
+ }
+}
+
+
+/**
* Read the contents of an icon.
*
* \param w window handle
@@ -222,7 +253,7 @@ void ro_gui_set_icon_selected_state(wimp_w w, wimp_i i, bool state) {
error = xwimp_set_icon_state(w, i,
(state ? wimp_ICON_SELECTED : 0), wimp_ICON_SELECTED);
if (error) {
- LOG(("xwimp_get_icon_state: 0x%x: %s",
+ LOG(("xwimp_set_icon_state: 0x%x: %s",
error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
}
@@ -286,6 +317,25 @@ bool ro_gui_get_icon_shaded_state(wimp_w w, wimp_i i) {
/**
+ * 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));
+ warn_user("WimpError", error->errmess);
+ }
+}
+
+
+/**
* Set a window title (does *not* redraw the title)
*
* \param w window handle
diff --git a/riscos/wimp.h b/riscos/wimp.h
index 744917efb..b0ab4c7df 100644
--- a/riscos/wimp.h
+++ b/riscos/wimp.h
@@ -34,6 +34,7 @@ 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);
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);
void ro_gui_set_icon_integer(wimp_w w, wimp_i i, int value);
@@ -41,6 +42,7 @@ 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_button_type(wimp_w w, wimp_i i, int type);
void ro_gui_set_window_title(wimp_w w, const char *title);
void ro_gui_set_caret_first(wimp_w w);
void ro_gui_open_window_centre(wimp_w parent, wimp_w child);
diff --git a/riscos/window.c b/riscos/window.c
index cdf98130b..2bbd46e9f 100644
--- a/riscos/window.c
+++ b/riscos/window.c
@@ -444,9 +444,8 @@ void ro_gui_window_redraw(struct gui_window *g, wimp_draw *redraw)
return;
}
while (more) {
- if (ro_gui_current_redraw_gui->option.buffer_everything) {
+ if (ro_gui_current_redraw_gui->option.buffer_everything)
ro_gui_buffer_open(redraw);
- }
if (clear_background) {
error = xcolourtrans_set_gcol(os_COLOUR_WHITE,
colourtrans_SET_BG,
@@ -472,9 +471,8 @@ void ro_gui_window_redraw(struct gui_window *g, wimp_draw *redraw)
g->option.scale,
0xFFFFFF);
}
- if (ro_gui_current_redraw_gui->option.buffer_everything) {
+ if (ro_gui_current_redraw_gui->option.buffer_everything)
ro_gui_buffer_close();
- }
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
@@ -1002,6 +1000,9 @@ void ro_gui_throb(void)
sprintf(throb_buf, "throbber%i", g->throbber);
ro_gui_set_icon_string(g->toolbar->toolbar_handle,
ICON_TOOLBAR_THROBBER, throb_buf);
+ if (g->toolbar->descriptor->throbber_redraw)
+ ro_gui_force_redraw_icon(g->toolbar->toolbar_handle,
+ ICON_TOOLBAR_THROBBER);
}
}
@@ -1316,6 +1317,9 @@ void gui_window_stop_throbber(struct gui_window *g)
strcpy(throb_buf, "throbber0");
ro_gui_set_icon_string(g->toolbar->toolbar_handle,
ICON_TOOLBAR_THROBBER, throb_buf);
+ if ((g->toolbar->descriptor) && (g->toolbar->descriptor->throbber_redraw))
+ ro_gui_force_redraw_icon(g->toolbar->toolbar_handle,
+ ICON_TOOLBAR_THROBBER);
}
}