summaryrefslogtreecommitdiff
path: root/riscos/theme.c
diff options
context:
space:
mode:
authorRichard Wilson <rjw@netsurf-browser.org>2005-01-23 16:09:05 +0000
committerRichard Wilson <rjw@netsurf-browser.org>2005-01-23 16:09:05 +0000
commit422df9008913857667ff20bf3ec295c1839cbc45 (patch)
treee3a122c9b871a9487372ca0d958e3c520f89f777 /riscos/theme.c
parent54f903d1b457a280f2cf0a677667428dd3dee239 (diff)
downloadnetsurf-422df9008913857667ff20bf3ec295c1839cbc45.tar.gz
netsurf-422df9008913857667ff20bf3ec295c1839cbc45.tar.bz2
[project @ 2005-01-23 16:09:05 by rjw]
Further work on theme installing svn path=/import/netsurf/; revision=1463
Diffstat (limited to 'riscos/theme.c')
-rw-r--r--riscos/theme.c316
1 files changed, 164 insertions, 152 deletions
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;
}