summaryrefslogtreecommitdiff
path: root/riscos/theme.c
diff options
context:
space:
mode:
Diffstat (limited to 'riscos/theme.c')
-rw-r--r--riscos/theme.c312
1 files changed, 216 insertions, 96 deletions
diff --git a/riscos/theme.c b/riscos/theme.c
index 68f5a60d4..34bea778c 100644
--- a/riscos/theme.c
+++ b/riscos/theme.c
@@ -16,8 +16,11 @@
#include <string.h>
#include "oslib/os.h"
#include "oslib/osgbpb.h"
+#include "oslib/osgbpb.h"
#include "oslib/osfile.h"
+#include "oslib/osfind.h"
#include "oslib/osspriteop.h"
+#include "oslib/squash.h"
#include "oslib/wimp.h"
#include "oslib/wimpextend.h"
#include "oslib/wimpspriteop.h"
@@ -32,6 +35,33 @@
#define THEME_THROBBER_MEMORY 12
#define THEME_STATUS_MEMORY 256
+struct toolbar_icon {
+ int icon_number; /**< wimp icon number */
+ bool display; /**< whether to display the icon */
+ int width; /**< icon width */
+ int height; /**< icon height */
+ char name[12]; /**< icon name */
+ char validation[40]; /**< validation string */
+ struct toolbar_icon *next; /**< next toolbar icon, or NULL for no more */
+};
+
+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;
@@ -66,8 +96,8 @@ static wimp_window theme_toolbar_window = {
12,
1,
{""},
- 0/*,
- { } */
+ 0,
+ { }
};
@@ -133,13 +163,15 @@ 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];
int context = 0;
int read_count;
osgbpb_INFO(100) info;
- fileswitch_object_type obj_type;
+ int output_left;
+ os_fw file_handle;
os_error *error;
/* Close any descriptors we've got so far
@@ -168,50 +200,78 @@ struct theme_descriptor *ro_gui_theme_get_available(void) {
/* Only process files
*/
- if ((info.obj_type == fileswitch_IS_DIR) && (!ro_gui_theme_find(info.name))) {
+ if ((info.obj_type == fileswitch_IS_FILE) && (!ro_gui_theme_find(info.name))) {
+
/* Get our full filename
*/
- snprintf(pathname, sizeof pathname, "%s.%s.Sprites",
+ snprintf(pathname, sizeof pathname, "%s.%s",
THEMES_DIR, info.name);
pathname[sizeof pathname - 1] = 0;
- /* Check for sprites file
+ /* Get the header
*/
- error = xosfile_read_stamped_no_path(pathname,
- &obj_type, (bits *)0, (bits *)0, (int *)0,
- (fileswitch_attr *)0, (bits *)0);
+ error = xosfind_openinw(osfind_NO_PATH, pathname, 0, &file_handle);
if (error) {
- LOG(("xosfile_read_stamped_no_path: 0x%x: %s",
+ LOG(("xosfind_openinw: 0x%x: %s",
error->errnum, error->errmess));
- warn_user("MiscError", error->errmess);
- } else if (obj_type == fileswitch_IS_FILE) {
-
- /* Create a new theme descriptor
- */
- current = (struct theme_descriptor *)calloc(1,
- sizeof(struct theme_descriptor));
- if (!current) {
- LOG(("calloc failed"));
- warn_user("NoMemory", 0);
- return theme_descriptors;
- }
- current->filename = malloc(strlen(info.name) + 1);
- if (!current->filename) {
- LOG(("malloc failed"));
- warn_user("NoMemory", 0);
- free(current);
- return theme_descriptors;
- }
- strcpy(current->filename, info.name);
-
- /* Link in our new descriptor alphabetically
- */
- if (theme_descriptors) {
- current->next = theme_descriptors;
- theme_descriptors->previous = current;
- }
- theme_descriptors = current;
+ warn_user("FileError", error->errmess);
+ continue;
}
+ if (file_handle == 0)
+ continue;
+ error = xosgbpb_read_atw(file_handle, (char *)&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));
+ warn_user("FileError", error->errmess);
+ continue;
+ }
+ 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,
+ sizeof(struct theme_descriptor));
+ if (!current) {
+ LOG(("calloc failed"));
+ warn_user("NoMemory", 0);
+ return theme_descriptors;
+ }
+ current->filename = malloc(strlen(info.name) + 1);
+ if (!current->filename) {
+ LOG(("malloc failed"));
+ warn_user("NoMemory", 0);
+ free(current);
+ return theme_descriptors;
+ }
+ 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
+ */
+ if (theme_descriptors) {
+ current->next = theme_descriptors;
+ theme_descriptors->previous = current;
+ }
+ theme_descriptors = current;
}
}
@@ -220,7 +280,7 @@ struct theme_descriptor *ro_gui_theme_get_available(void) {
if (theme_descriptors->next) {
current = theme_descriptors;
while ((test = current->next)) {
- if (strcmp(current->filename, test->filename) > 0) {
+ if (strcmp(current->name, test->name) > 0) {
current->next->previous = current->previous;
if (current->previous)
current->previous->next = current->next;
@@ -251,11 +311,17 @@ struct theme_descriptor *ro_gui_theme_get_available(void) {
* \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;
char pathname[256];
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.
@@ -271,7 +337,7 @@ bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list) {
*/
if (descriptor->theme) {
descriptor->theme->users = descriptor->theme->users + 1;
- } else {
+ } else if (descriptor->decompressed_size > 0) {
/* Create a new theme
*/
descriptor->theme = (struct theme *)calloc(1, sizeof(struct theme));
@@ -284,22 +350,83 @@ bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list) {
/* Get our full filename
*/
- snprintf(pathname, sizeof pathname, "%s.%s.Sprites",
+ snprintf(pathname, sizeof pathname, "%s.%s",
THEMES_DIR, descriptor->filename);
pathname[sizeof pathname - 1] = 0;
- /* Load the sprites
+ /* 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.
*/
- descriptor->theme->sprite_area = ro_gui_load_sprite_file(pathname);
- if (!descriptor->theme->sprite_area) {
- result = false;
- free(descriptor->theme);
- descriptor->theme = NULL;
- continue;
+ error = xosfile_read_stamped_no_path(pathname,
+ &obj_type, 0, 0, &file_size, 0, 0);
+ if (error) {
+ LOG(("xosfile_read_stamped_no_path: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("FileError", error->errmess);
+ goto ro_gui_theme_open_continue;
+ }
+ if (obj_type != fileswitch_IS_FILE)
+ goto ro_gui_theme_open_continue;
+ raw_data = malloc(file_size);
+ if (!raw_data) {
+ LOG(("No memory for malloc()"));
+ warn_user("NoMemory", 0);
+ return false;
+ }
+ error = xosfile_load_stamped_no_path(pathname, (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));
+ warn_user("FileError", error->errmess);
+ goto ro_gui_theme_open_continue;
+ }
+
+ /* Decompress the sprites
+ */
+ 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));
+ warn_user("MiscError", error->errmess);
+ goto ro_gui_theme_open_continue;
+ }
+ decompressed = (osspriteop_area *)malloc(descriptor->decompressed_size);
+ workspace = malloc(workspace_size);
+ if ((!decompressed) || (!workspace)) {
+ if (decompressed) free(decompressed);
+ if (workspace) free(raw_data);
+ LOG(("No memory for malloc()"));
+ warn_user("NoMemory", 0);
+ return false;
+ }
+ 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));
+ warn_user("MiscError", error->errmess);
+ goto ro_gui_theme_open_continue;
}
+ if (status != 0) {
+ free(decompressed);
+ goto ro_gui_theme_open_continue;
+ }
+ descriptor->theme->sprite_area = decompressed;
- /* Find the highest sprite called 'throbber%i', and get the maximum
- dimensions for all 'thobber%i' icons.
+ /* 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++) {
osspriteop_return_name(osspriteop_USER_AREA,
@@ -324,18 +451,10 @@ bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list) {
if (descriptor->theme->throbber_frames < n)
descriptor->theme->throbber_frames = n;
}
- }
-
- /* Load the options
- */
- descriptor->theme->throbber_right = true;
- descriptor->theme->browser_background = wimp_COLOUR_VERY_LIGHT_GREY;
- descriptor->theme->hotlist_background = wimp_COLOUR_VERY_LIGHT_GREY;
- descriptor->theme->status_background = wimp_COLOUR_VERY_LIGHT_GREY;
- descriptor->theme->status_foreground = wimp_COLOUR_BLACK;
-// FINISH ME - NEEDS FINAL FILE FORMAT DECIDING
+ }
}
+ro_gui_theme_open_continue:
/* Loop or return depending on whether the entire list
is to be processed.
*/
@@ -412,8 +531,6 @@ void ro_gui_theme_close(struct theme_descriptor *descriptor, bool list) {
descriptor->theme->users = descriptor->theme->users - 1;
if (descriptor->theme->users <= 0) {
free(descriptor->theme->sprite_area);
- free(descriptor->theme->author);
- free(descriptor->theme->details);
free(descriptor->theme);
descriptor->theme = NULL;
}
@@ -514,7 +631,7 @@ struct toolbar *ro_gui_theme_create_toolbar(struct theme_descriptor *descriptor,
/* Store the theme
*/
if (!descriptor) descriptor = theme_current;
- if (descriptor) toolbar->theme = descriptor->theme;
+ toolbar->descriptor = descriptor;
/* Apply the default settings
*/
@@ -593,13 +710,9 @@ bool ro_gui_theme_update_toolbar(struct theme_descriptor *descriptor, struct too
/* Set the theme and window sprite area
*/
if (!descriptor) descriptor = theme_current;
- if (descriptor) {
- toolbar->theme = descriptor->theme;
- } else {
- toolbar->theme = NULL;
- }
- if (toolbar->theme) {
- sprite_area = toolbar->theme->sprite_area;
+ toolbar->descriptor = descriptor;
+ if ((toolbar->descriptor) && (toolbar->descriptor->theme)) {
+ sprite_area = toolbar->descriptor->theme->sprite_area;
} else {
sprite_area = (osspriteop_area *)1;
}
@@ -615,11 +728,11 @@ bool ro_gui_theme_update_toolbar(struct theme_descriptor *descriptor, struct too
/* Recreate the toolbar window
*/
- if (toolbar->theme) {
+ if (toolbar->descriptor) {
if (toolbar->type == THEME_BROWSER_TOOLBAR) {
- theme_toolbar_window.work_bg = toolbar->theme->browser_background;
+ theme_toolbar_window.work_bg = toolbar->descriptor->browser_background;
} else {
- theme_toolbar_window.work_bg = toolbar->theme->hotlist_background;
+ theme_toolbar_window.work_bg = toolbar->descriptor->hotlist_background;
}
} else {
theme_toolbar_window.work_bg = wimp_COLOUR_VERY_LIGHT_GREY;
@@ -640,6 +753,7 @@ bool ro_gui_theme_update_toolbar(struct theme_descriptor *descriptor, struct too
warn_user("WimpError", error->errmess);
return false;
}
+ LOG(("Created window 1"));
/* Create the basic icons
*/
@@ -650,8 +764,8 @@ bool ro_gui_theme_update_toolbar(struct theme_descriptor *descriptor, struct too
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->theme) {
- new_icon.icon.flags |= (toolbar->theme->browser_background
+ if (toolbar->descriptor) {
+ new_icon.icon.flags |= (toolbar->descriptor->browser_background
<< wimp_ICON_BG_COLOUR_SHIFT);
} else {
new_icon.icon.flags |= (wimp_COLOUR_VERY_LIGHT_GREY
@@ -724,8 +838,8 @@ bool ro_gui_theme_update_toolbar(struct theme_descriptor *descriptor, struct too
xwimp_delete_window(toolbar->status_handle);
toolbar->status_handle = NULL;
}
- if (toolbar->theme) {
- theme_toolbar_window.work_bg = toolbar->theme->status_background;
+ if (toolbar->descriptor) {
+ theme_toolbar_window.work_bg = toolbar->descriptor->status_background;
} else {
theme_toolbar_window.work_bg = wimp_COLOUR_VERY_LIGHT_GREY;
}
@@ -762,10 +876,10 @@ 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->theme) {
+ if (toolbar->descriptor) {
new_icon.icon.flags |=
- (toolbar->theme->status_foreground << wimp_ICON_FG_COLOUR_SHIFT) |
- (toolbar->theme->status_background << wimp_ICON_BG_COLOUR_SHIFT);
+ (toolbar->descriptor->status_foreground << wimp_ICON_FG_COLOUR_SHIFT) |
+ (toolbar->descriptor->status_background << wimp_ICON_BG_COLOUR_SHIFT);
} else {
new_icon.icon.flags |=
(wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT) |
@@ -940,13 +1054,14 @@ bool ro_gui_theme_process_toolbar(struct toolbar *toolbar, int width) {
left_edge = 6;
right_edge = width - 8;
toolbar->height = 0;
- if ((toolbar->theme) && (toolbar->type == THEME_BROWSER_TOOLBAR) &&
+ if ((toolbar->descriptor) && (toolbar->descriptor->theme) &&
+ (toolbar->type == THEME_BROWSER_TOOLBAR) &&
(toolbar->display_throbber)) {
- if (!toolbar->theme->throbber_right) {
+ if (!toolbar->descriptor->throbber_right) {
throbber_x = left_edge;
- left_edge += toolbar->theme->throbber_width + 8;
+ left_edge += toolbar->descriptor->theme->throbber_width + 8;
}
- toolbar->height = toolbar->theme->throbber_height + 8;
+ toolbar->height = toolbar->descriptor->theme->throbber_height + 8;
}
if ((toolbar->type == THEME_BROWSER_TOOLBAR) && (toolbar->display_url)) {
if (toolbar->height < 52 + 8) toolbar->height = 52 + 8;
@@ -955,7 +1070,8 @@ bool ro_gui_theme_process_toolbar(struct toolbar *toolbar, int width) {
/* Get the minimum height of the icons
*/
bottom_edge = left_edge;
- if (toolbar->display_buttons) {
+ if ((toolbar->display_buttons) && (toolbar->descriptor) &&
+ (toolbar->descriptor->theme)) {
toolbar_icon = toolbar->icon;
while (toolbar_icon) {
if (toolbar_icon->display) {
@@ -977,12 +1093,13 @@ bool ro_gui_theme_process_toolbar(struct toolbar *toolbar, int width) {
if (!toolbar->reformat_buttons) left_edge = bottom_edge;
if (toolbar->display_url) bottom_edge += 32;
if (bottom_edge > right_edge) right_edge = bottom_edge;
- if ((toolbar->theme) && (toolbar->display_throbber) &&
- (toolbar->theme->throbber_right)) {
- bottom_edge += toolbar->theme->throbber_width;
+ if ((toolbar->descriptor) && (toolbar->descriptor->theme) &&
+ (toolbar->display_throbber) &&
+ (toolbar->descriptor->throbber_right)) {
+ bottom_edge += toolbar->descriptor->theme->throbber_width;
if (bottom_edge > right_edge) right_edge = bottom_edge;
- throbber_x = right_edge - toolbar->theme->throbber_width;
- right_edge -= toolbar->theme->throbber_width + 8;
+ throbber_x = right_edge - toolbar->descriptor->theme->throbber_width;
+ right_edge -= toolbar->descriptor->theme->throbber_width + 8;
}
}
@@ -1053,11 +1170,13 @@ bool ro_gui_theme_process_toolbar(struct toolbar *toolbar, int width) {
/* Move the throbber
*/
- if ((toolbar->theme) && (throbber_x >= 0) && (toolbar->display_throbber)) {
+ if ((toolbar->descriptor) && (toolbar->descriptor->theme) &&
+ (throbber_x >= 0) && (toolbar->display_throbber)) {
xwimp_resize_icon(toolbar->toolbar_handle, ICON_TOOLBAR_THROBBER,
throbber_x, 0,
- throbber_x + toolbar->theme->throbber_width, toolbar->height);
- if (toolbar->theme->throbber_right)
+ throbber_x + toolbar->descriptor->theme->throbber_width,
+ toolbar->height);
+ if (toolbar->descriptor->throbber_right)
xwimp_force_redraw(toolbar->toolbar_handle,
old_width - width + throbber_x, 0, 16384, 16384);
xwimp_force_redraw(toolbar->toolbar_handle,
@@ -1246,8 +1365,9 @@ void ro_gui_theme_update_toolbar_icon(struct toolbar *toolbar, struct toolbar_ic
/* Handle no theme/no sprite area
*/
if (!toolbar) return;
- if ((!toolbar->theme) || (!toolbar->theme->sprite_area)) {
- icon->width = default_width;
+ if ((!toolbar->descriptor) || (!toolbar->descriptor->theme) ||
+ (!toolbar->descriptor->theme->sprite_area)) {
+ icon->width = 0;
icon->height = 0;
return;
}
@@ -1255,7 +1375,7 @@ void ro_gui_theme_update_toolbar_icon(struct toolbar *toolbar, struct toolbar_ic
/* Get the sprite details
*/
error = xosspriteop_read_sprite_info(osspriteop_USER_AREA,
- toolbar->theme->sprite_area, (osspriteop_id)icon->name,
+ toolbar->descriptor->theme->sprite_area, (osspriteop_id)icon->name,
&dimensions.x, &dimensions.y, 0, &mode);
if (error) {
icon->width = default_width;