From fba46de9cbe8778919f68a7d24e242c7ee3f1331 Mon Sep 17 00:00:00 2001 From: James Bursa Date: Thu, 11 Mar 2004 02:19:14 +0000 Subject: [project @ 2004-03-11 02:19:13 by bursa] Add source_data to content structure and remove equivalents from individual contents. svn path=/import/netsurf/; revision=606 --- content/content.c | 79 ++++++++++++++++++++++++++++++-------------------- content/content.h | 5 ++-- content/fetchcache.c | 12 ++++---- css/css.c | 24 +++------------ css/css.h | 4 --- makefile | 4 +-- render/html.c | 20 ++++--------- render/html.h | 2 -- render/textplain.c | 31 ++------------------ render/textplain.h | 8 ++--- riscos/download.c | 8 ++--- riscos/draw.c | 52 ++++++++------------------------- riscos/draw.h | 7 ----- riscos/filetype.c | 48 ++++++++++++++++++++---------- riscos/gif.c | 20 +------------ riscos/gif.h | 5 ---- riscos/gui.c | 22 ++++---------- riscos/gui.h | 3 ++ riscos/jpeg.c | 35 ++++------------------ riscos/jpeg.h | 5 ---- riscos/menus.c | 7 ++++- riscos/png.c | 21 ++------------ riscos/png.h | 6 ---- riscos/save.c | 14 ++++----- riscos/save_complete.c | 79 +++++++++++++++++++------------------------------- riscos/save_draw.c | 12 ++++---- 26 files changed, 187 insertions(+), 346 deletions(-) diff --git a/content/content.c b/content/content.c index b189dd5ee..cb92cb2db 100644 --- a/content/content.c +++ b/content/content.c @@ -109,30 +109,30 @@ static const struct handler_entry handler_map[] = { {html_create, html_process_data, html_convert, html_revive, html_reformat, html_destroy, html_redraw, html_add_instance, html_remove_instance, html_reshape_instance}, - {textplain_create, textplain_process_data, textplain_convert, - textplain_revive, textplain_reformat, textplain_destroy, 0, 0, 0, 0}, - {css_create, css_process_data, css_convert, css_revive, - css_reformat, css_destroy, 0, 0, 0, 0}, + {textplain_create, html_process_data, textplain_convert, + 0, 0, 0, 0, 0, 0, 0}, + {css_create, 0, css_convert, css_revive, + 0, css_destroy, 0, 0, 0, 0}, #ifdef riscos #ifdef WITH_JPEG - {nsjpeg_create, nsjpeg_process_data, nsjpeg_convert, nsjpeg_revive, - nsjpeg_reformat, nsjpeg_destroy, nsjpeg_redraw, 0, 0, 0}, + {nsjpeg_create, 0, nsjpeg_convert, 0, + 0, nsjpeg_destroy, nsjpeg_redraw, 0, 0, 0}, #endif #ifdef WITH_PNG - {nspng_create, nspng_process_data, nspng_convert, nspng_revive, - nspng_reformat, nspng_destroy, nspng_redraw, 0, 0, 0}, + {nspng_create, nspng_process_data, nspng_convert, 0, + 0, nspng_destroy, nspng_redraw, 0, 0, 0}, #endif #ifdef WITH_GIF - {nsgif_create, nsgif_process_data, nsgif_convert, nsgif_revive, - nsgif_reformat, nsgif_destroy, nsgif_redraw, 0, 0, 0}, + {nsgif_create, 0, nsgif_convert, 0, + 0, nsgif_destroy, nsgif_redraw, 0, 0, 0}, #endif #ifdef WITH_SPRITE {sprite_create, sprite_process_data, sprite_convert, sprite_revive, sprite_reformat, sprite_destroy, sprite_redraw, 0, 0, 0}, #endif #ifdef WITH_DRAW - {draw_create, draw_process_data, draw_convert, draw_revive, - draw_reformat, draw_destroy, draw_redraw, 0, 0, 0}, + {0, 0, draw_convert, 0, + 0, draw_destroy, draw_redraw, 0, 0, 0}, #endif #ifdef WITH_PLUGIN {plugin_create, plugin_process_data, plugin_convert, plugin_revive, @@ -141,8 +141,7 @@ static const struct handler_entry handler_map[] = { plugin_reshape_instance}, #endif #endif - {other_create, other_process_data, other_convert, other_revive, - other_reformat, other_destroy, 0, 0, 0, 0} + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; #define HANDLER_MAP_COUNT (sizeof(handler_map) / sizeof(handler_map[0])) @@ -190,6 +189,8 @@ struct content * content_create(char *url) c->cache = 0; c->size = sizeof(struct content); c->fetch = 0; + c->source_data = 0; + c->source_size = 0; c->mime_type = 0; strcpy(c->status_message, messages_get("Loading")); user_sentinel = xcalloc(1, sizeof(*user_sentinel)); @@ -227,7 +228,9 @@ void content_set_type(struct content *c, content_type type, char* mime_type, c->type = type; c->mime_type = xstrdup(mime_type); c->status = CONTENT_STATUS_LOADING; - handler_map[type].create(c, params); + c->source_data = xcalloc(0, 1); + if (handler_map[type].create) + handler_map[type].create(c, params); content_broadcast(c, CONTENT_MSG_LOADING, 0); /* c may be destroyed at this point as a result of * CONTENT_MSG_LOADING, so must not be accessed */ @@ -245,7 +248,12 @@ void content_process_data(struct content *c, char *data, unsigned long size) assert(c != 0); assert(c->status == CONTENT_STATUS_LOADING); LOG(("content %s, size %lu", c->url, size)); - handler_map[c->type].process_data(c, data, size); + c->source_data = xrealloc(c->source_data, c->source_size + size); + memcpy(c->source_data + c->source_size, data, size); + c->source_size += size; + c->size += size; + if (handler_map[c->type].process_data) + handler_map[c->type].process_data(c, data, size); } @@ -270,13 +278,18 @@ void content_convert(struct content *c, unsigned long width, unsigned long heigh assert(c->status == CONTENT_STATUS_LOADING); LOG(("content %s", c->url)); c->available_width = width; - if (handler_map[c->type].convert(c, width, height)) { - /* convert failed, destroy content */ - content_broadcast(c, CONTENT_MSG_ERROR, "Conversion failed"); - if (c->cache) - cache_destroy(c); - content_destroy(c); - return; + if (handler_map[c->type].convert) { + if (handler_map[c->type].convert(c, width, height)) { + /* convert failed, destroy content */ + content_broadcast(c, CONTENT_MSG_ERROR, + "Conversion failed"); + if (c->cache) + cache_destroy(c); + content_destroy(c); + return; + } + } else { + c->status = CONTENT_STATUS_DONE; } assert(c->status == CONTENT_STATUS_READY || c->status == CONTENT_STATUS_DONE); @@ -295,6 +308,7 @@ void content_convert(struct content *c, unsigned long width, unsigned long heigh void content_revive(struct content *c, unsigned long width, unsigned long height) { + assert(0); /* unmaintained */ assert(c != 0); if (c->status != CONTENT_STATUS_DONE) return; @@ -315,8 +329,10 @@ void content_reformat(struct content *c, unsigned long width, unsigned long heig assert(c->status == CONTENT_STATUS_READY || c->status == CONTENT_STATUS_DONE); c->available_width = width; - handler_map[c->type].reformat(c, width, height); - content_broadcast(c, CONTENT_MSG_REFORMAT, 0); + if (handler_map[c->type].reformat) { + handler_map[c->type].reformat(c, width, height); + content_broadcast(c, CONTENT_MSG_REFORMAT, 0); + } } @@ -339,7 +355,7 @@ void content_destroy(struct content *c) return; } - if (c->type < HANDLER_MAP_COUNT) + if (c->type < HANDLER_MAP_COUNT && handler_map[c->type].destroy) handler_map[c->type].destroy(c); for (user = c->user_list; user != 0; user = next) { next = user->next; @@ -347,6 +363,7 @@ void content_destroy(struct content *c) } free(c->mime_type); xfree(c->url); + free(c->source_data); xfree(c); } @@ -362,7 +379,7 @@ void content_reset(struct content *c) { assert(c != 0); LOG(("content %p %s", c, c->url)); - if (c->type < HANDLER_MAP_COUNT) + if (c->type < HANDLER_MAP_COUNT && handler_map[c->type].destroy) handler_map[c->type].destroy(c); c->type = CONTENT_UNKNOWN; c->status = CONTENT_STATUS_TYPE_UNKNOWN; @@ -384,7 +401,7 @@ void content_redraw(struct content *c, long x, long y, float scale) { assert(c != 0); - if (handler_map[c->type].redraw != 0) + if (handler_map[c->type].redraw) handler_map[c->type].redraw(c, x, y, width, height, clip_x0, clip_y0, clip_x1, clip_y1, scale); } @@ -497,7 +514,7 @@ void content_add_instance(struct content *c, struct browser_window *bw, assert(c != 0); assert(c->type < CONTENT_UNKNOWN); LOG(("content %s", c->url)); - if (handler_map[c->type].add_instance != 0) + if (handler_map[c->type].add_instance) handler_map[c->type].add_instance(c, bw, page, box, params, state); } @@ -515,7 +532,7 @@ void content_remove_instance(struct content *c, struct browser_window *bw, assert(c != 0); assert(c->type < CONTENT_UNKNOWN); LOG(("content %s", c->url)); - if (handler_map[c->type].remove_instance != 0) + if (handler_map[c->type].remove_instance) handler_map[c->type].remove_instance(c, bw, page, box, params, state); } @@ -533,7 +550,7 @@ void content_reshape_instance(struct content *c, struct browser_window *bw, assert(c != 0); assert(c->type < CONTENT_UNKNOWN); LOG(("content %s", c->url)); - if (handler_map[c->type].reshape_instance != 0) + if (handler_map[c->type].reshape_instance) handler_map[c->type].reshape_instance(c, bw, page, box, params, state); } diff --git a/content/content.h b/content/content.h index 2d2e498fe..5520453a8 100644 --- a/content/content.h +++ b/content/content.h @@ -30,7 +30,6 @@ #include "netsurf/content/cache.h" #include "netsurf/content/content_type.h" #include "netsurf/content/fetch.h" -#include "netsurf/content/other.h" #include "netsurf/css/css.h" #include "netsurf/render/box.h" #include "netsurf/render/font.h" @@ -123,7 +122,6 @@ struct content { struct content_plugin_data plugin; #endif #endif - struct content_other_data other; } data; struct cache_entry *cache; /**< Used by cache, 0 if not cached. */ @@ -137,7 +135,8 @@ struct content { char status_message[80]; /**< Text for status bar. */ struct fetch *fetch; /**< Associated fetch, or 0. */ - unsigned long fetch_size; /**< Amount of data fetched so far. */ + char *source_data; /**< Source data, as received. */ + unsigned long source_size; /**< Amount of data fetched so far. */ unsigned long total_size; /**< Total data size, 0 if unknown. */ int lock; /**< Content in use, do not destroy. */ diff --git a/content/fetchcache.c b/content/fetchcache.c index 21b50ee0b..3ac499c07 100644 --- a/content/fetchcache.c +++ b/content/fetchcache.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 2003 James Bursa + * Copyright 2004 James Bursa */ /** \file @@ -108,7 +108,6 @@ struct content * fetchcache(const char *url, char *referer, #endif cache_put(c); - c->fetch_size = 0; c->width = width; c->height = height; c->no_error_pages = no_error_pages; @@ -169,17 +168,16 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size) case FETCH_DATA: LOG(("FETCH_DATA")); - c->fetch_size += size; if (c->total_size) sprintf(c->status_message, messages_get("RecPercent"), - c->fetch_size, c->total_size, - (unsigned int) (c->fetch_size * + c->source_size + size, c->total_size, + (unsigned int) ((c->source_size + size) * 100.0 / c->total_size)); else sprintf(c->status_message, messages_get("Received"), - c->fetch_size); + c->source_size + size); content_broadcast(c, CONTENT_MSG_STATUS, 0); content_process_data(c, data, size); break; @@ -187,7 +185,7 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size) case FETCH_FINISHED: LOG(("FETCH_FINISHED")); sprintf(c->status_message, messages_get("Converting"), - c->fetch_size); + c->source_size); c->fetch = 0; content_broadcast(c, CONTENT_MSG_STATUS, 0); content_convert(c, c->width, c->height); diff --git a/css/css.c b/css/css.c index ee125da19..3b8dbeee9 100644 --- a/css/css.c +++ b/css/css.c @@ -167,16 +167,6 @@ void css_create(struct content *c, const char *params[]) c->data.css.import_url = xcalloc(0, sizeof(*c->data.css.import_url)); c->data.css.import_content = xcalloc(0, sizeof(*c->data.css.import_content)); c->active = 0; - c->data.css.data = xcalloc(0, 1); - c->data.css.length = 0; -} - - -void css_process_data(struct content *c, char *data, unsigned long size) -{ - c->data.css.data = xrealloc(c->data.css.data, c->data.css.length + size + 2); - memcpy(c->data.css.data + c->data.css.length, data, size); - c->data.css.length += size; } @@ -186,9 +176,10 @@ int css_convert(struct content *c, unsigned int width, unsigned int height) YY_BUFFER_STATE buffer; struct parse_params param = {0, c, 0, false}; - c->data.css.data[c->data.css.length] = - c->data.css.data[c->data.css.length + 1] = 0; - buffer = css__scan_buffer(c->data.css.data, c->data.css.length + 2, + c->source_data = xrealloc(c->source_data, c->source_size + 2); + c->source_data[c->source_size] = 0; + c->source_data[c->source_size + 1] = 0; + buffer = css__scan_buffer(c->source_data, c->source_size + 2, c->data.css.css->lexer); assert(buffer); while ((token = css_lex(c->data.css.css->lexer))) { @@ -250,18 +241,11 @@ void css_revive(struct content *c, unsigned int width, unsigned int height) } -void css_reformat(struct content *c, unsigned int width, unsigned int height) -{ -} - - void css_destroy(struct content *c) { unsigned int i; struct css_node *r; - xfree(c->data.css.data); - for (i = 0; i != HASH_SIZE; i++) { for (r = c->data.css.css->rule[i]; r != 0; r = r->next) xfree(r->style); diff --git a/css/css.h b/css/css.h index 0c5f6d899..0c1f65e6f 100644 --- a/css/css.h +++ b/css/css.h @@ -169,8 +169,6 @@ struct content_css_data { unsigned int import_count; /**< Number of entries in import_url. */ char **import_url; /**< Imported stylesheet urls. */ struct content **import_content; /**< Imported stylesheet contents. */ - char *data; /**< Source data. */ - unsigned int length; /**< Current length of data. */ }; @@ -258,10 +256,8 @@ struct parse_params { struct content; void css_create(struct content *c, const char *params[]); -void css_process_data(struct content *c, char *data, unsigned long size); int css_convert(struct content *c, unsigned int width, unsigned int height); void css_revive(struct content *c, unsigned int width, unsigned int height); -void css_reformat(struct content *c, unsigned int width, unsigned int height); void css_destroy(struct content *c); #ifdef CSS_INTERNALS diff --git a/makefile b/makefile index f5661b48d..b80163ccb 100644 --- a/makefile +++ b/makefile @@ -6,7 +6,7 @@ CC = /riscos/bin/gcc CC_DEBUG = gcc -OBJECTS_COMMON = cache.o content.o fetch.o fetchcache.o other.o \ +OBJECTS_COMMON = cache.o content.o fetch.o fetchcache.o \ css.o css_enum.o parser.o ruleset.o scanner.o \ box.o form.o html.o layout.o textplain.o \ messages.o utils.o translit.o pool.o url.o @@ -19,7 +19,7 @@ OBJECTS = $(OBJECTS_COMMON) \ draw.o gif.o jpeg.o plugin.o png.o sprite.o \ about.o filetype.o font.o uri.o url_protocol.o history.o \ version.o thumbnail.o \ - save.o save_complete.o save_draw.o save_html.o + save.o save_complete.o save_draw.o OBJECTS_DEBUG = $(OBJECTS_COMMON) \ netsurfd.o \ options.o filetyped.o fontd.o diff --git a/render/html.c b/render/html.c index aaf0c4bf6..5a6d4dd0c 100644 --- a/render/html.c +++ b/render/html.c @@ -69,8 +69,6 @@ void html_create(struct content *c, const char *params[]) } html->parser = htmlCreatePushParserCtxt(0, 0, "", 0, 0, html->encoding); - html->source = xcalloc(0, 1); - html->length = 0; html->base_url = xstrdup(c->url); html->layout = 0; html->background_colour = TRANSPARENT; @@ -98,21 +96,16 @@ void html_process_data(struct content *c, char *data, unsigned long size) unsigned long x; LOG(("content %s, size %lu", c->url, size)); /*cache_dump();*/ - c->data.html.source = xrealloc(c->data.html.source, c->data.html.length + size); - memcpy(c->data.html.source + c->data.html.length, data, size); - c->data.html.length += size; - c->size += size; - /* First time through, check if we need to get the encoding + /* First time through, check if we need to get the encoding * if so, get it and reset the parser instance with it. * if it fails, assume Latin1 */ if (c->data.html.getenc) { - c->data.html.encoding = xmlDetectCharEncoding(c->data.html.source, c->data.html.length); - if (c->data.html.encoding == XML_CHAR_ENCODING_ERROR || - c->data.html.encoding == XML_CHAR_ENCODING_NONE) { - c->data.html.encoding = XML_CHAR_ENCODING_8859_1; - } - xmlSwitchEncoding((xmlParserCtxtPtr)c->data.html.parser, c->data.html.encoding); + c->data.html.encoding = xmlDetectCharEncoding(data, size); + if (c->data.html.encoding == XML_CHAR_ENCODING_ERROR || + c->data.html.encoding == XML_CHAR_ENCODING_NONE) + c->data.html.encoding = XML_CHAR_ENCODING_8859_1; + xmlSwitchEncoding(c->data.html.parser, c->data.html.encoding); c->data.html.getenc = false; LOG(("Encoding: %s", xmlGetCharEncodingName(c->data.html.encoding))); } @@ -758,7 +751,6 @@ void html_destroy(struct content *c) if (c->data.html.parser) htmlFreeParserCtxt(c->data.html.parser); - free(c->data.html.source); free(c->data.html.base_url); if (c->data.html.layout) diff --git a/render/html.h b/render/html.h index b20040a2e..d029a7554 100644 --- a/render/html.h +++ b/render/html.h @@ -37,8 +37,6 @@ struct box_position { struct content_html_data { htmlParserCtxt *parser; /**< HTML parser context. */ - char *source; /**< Source data. */ - int length; /**< Length of source. */ xmlCharEncoding encoding; /**< Encoding of source. */ bool getenc; /**< Need to get the encoding from the document, as server is broken. */ diff --git a/render/textplain.c b/render/textplain.c index 524865846..72ad98a4f 100644 --- a/render/textplain.c +++ b/render/textplain.c @@ -2,16 +2,13 @@ * 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 2003 James Bursa + * Copyright 2004 James Bursa */ -#include -#include -#include #include "libxml/HTMLparser.h" +#include "netsurf/content/content.h" #include "netsurf/render/html.h" #include "netsurf/render/textplain.h" -#include "netsurf/utils/log.h" static const char header[] = "
";
@@ -25,33 +22,9 @@ void textplain_create(struct content *c, const char *params[])
 }
 
 
-void textplain_process_data(struct content *c, char *data, unsigned long size)
-{
-	html_process_data(c, data, size);
-}
-
-
 int textplain_convert(struct content *c, unsigned int width, unsigned int height)
 {
 	htmlParseChunk(c->data.html.parser, footer, sizeof(footer) - 1, 0);
 	c->type = CONTENT_HTML;
 	return html_convert(c, width, height);
 }
-
-
-void textplain_revive(struct content *c, unsigned int width, unsigned int height)
-{
-	assert(0);
-}
-
-
-void textplain_reformat(struct content *c, unsigned int width, unsigned int height)
-{
-	assert(0);
-}
-
-
-void textplain_destroy(struct content *c)
-{
-	html_destroy(c);
-}
diff --git a/render/textplain.h b/render/textplain.h
index 75b52dd23..859ff9e62 100644
--- a/render/textplain.h
+++ b/render/textplain.h
@@ -2,19 +2,15 @@
  * 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 2003 James Bursa 
+ * Copyright 2004 James Bursa 
  */
 
 #ifndef _NETSURF_RENDER_TEXTPLAIN_H_
 #define _NETSURF_RENDER_TEXTPLAIN_H_
 
-#include "netsurf/content/content.h"
+struct content;
 
 void textplain_create(struct content *c, const char *params[]);
-void textplain_process_data(struct content *c, char *data, unsigned long size);
 int textplain_convert(struct content *c, unsigned int width, unsigned int height);
-void textplain_revive(struct content *c, unsigned int width, unsigned int height);
-void textplain_reformat(struct content *c, unsigned int width, unsigned int height);
-void textplain_destroy(struct content *c);
 
 #endif
diff --git a/riscos/download.c b/riscos/download.c
index 8ed132b5e..28db3bb1f 100644
--- a/riscos/download.c
+++ b/riscos/download.c
@@ -180,7 +180,7 @@ void gui_download_window_error(gui_window *g, const char *error)
 void gui_download_window_done(gui_window *g)
 {
 	snprintf(g->status, 256, messages_get("Downloaded"),
-			g->data.download.content->data.other.length);
+			g->data.download.content->source_size);
 	wimp_set_icon_state(g->window,
 			ICON_DOWNLOAD_STATUS, 0, 0);
 
@@ -239,7 +239,7 @@ void ro_download_drag_end(wimp_dragged *drag)
 	message.data.data_xfer.pos.x = pointer.pos.x;
 	message.data.data_xfer.pos.y = pointer.pos.y;
 	message.data.data_xfer.est_size = (int)
-			current_gui->data.download.content->data.other.length;
+			current_gui->data.download.content->source_size;
 	message.data.data_xfer.file_type = current_gui->data.download.file_type;
 	strncpy(message.data.data_xfer.file_name,
 			current_gui->data.download.path, 212);
@@ -263,8 +263,8 @@ void ro_download_datasave_ack(wimp_message *message)
 
 	assert(current_gui->data.download.download_status == download_COMPLETE);
 
-	data = current_gui->data.download.content->data.other.data;
-	data_end = data + current_gui->data.download.content->data.other.length;
+	data = current_gui->data.download.content->source_data;
+	data_end = data + current_gui->data.download.content->source_size;
 
 	error = xosfile_save_stamped(message->data.data_xfer.file_name,
 			current_gui->data.download.file_type,
diff --git a/riscos/draw.c b/riscos/draw.c
index 325106f63..b59a96261 100644
--- a/riscos/draw.c
+++ b/riscos/draw.c
@@ -17,21 +17,6 @@
 #include "oslib/drawfile.h"
 
 #ifdef WITH_DRAW
-void draw_create(struct content *c, const char *params[])
-{
-	c->data.draw.data = xcalloc(0, 1);
-	c->data.draw.length = 0;
-}
-
-
-void draw_process_data(struct content *c, char *data, unsigned long size)
-{
-	c->data.draw.data = xrealloc(c->data.draw.data, c->data.draw.length + size);
-	memcpy((char*)c->data.draw.data + c->data.draw.length, data, size);
-	c->data.draw.length += size;
-	c->size += size;
-}
-
 
 int draw_convert(struct content *c, unsigned int width, unsigned int height)
 {
@@ -48,8 +33,8 @@ int draw_convert(struct content *c, unsigned int width, unsigned int height)
         matrix->entries[2][1] = 0;
 
         /* BBox contents in Draw units (256*OS unit) */
-	error = xdrawfile_bbox(0, (drawfile_diagram*)(c->data.draw.data),
-	                       (int)c->data.draw.length, matrix, bbox);
+	error = xdrawfile_bbox(0, (drawfile_diagram*)(c->source_data),
+	                       (int)c->source_size, matrix, bbox);
 
         if (error) {
                 LOG(("error: %s", error->errmess));
@@ -66,7 +51,7 @@ int draw_convert(struct content *c, unsigned int width, unsigned int height)
 	c->data.draw.y0 = bbox->y0 / 2;
 	c->title = xcalloc(100, 1);
 	sprintf(c->title, messages_get("DrawTitle"), c->width,
-	                                c->height, c->data.draw.length);
+	                                c->height, c->source_size);
 	c->status = CONTENT_STATUS_DONE;
 	xfree(matrix);
 	xfree(bbox);
@@ -74,19 +59,8 @@ int draw_convert(struct content *c, unsigned int width, unsigned int height)
 }
 
 
-void draw_revive(struct content *c, unsigned int width, unsigned int height)
-{
-}
-
-
-void draw_reformat(struct content *c, unsigned int width, unsigned int height)
-{
-}
-
-
 void draw_destroy(struct content *c)
 {
-	xfree(c->data.draw.data);
 	xfree(c->title);
 }
 
@@ -96,21 +70,19 @@ void draw_redraw(struct content *c, long x, long y,
 		long clip_x0, long clip_y0, long clip_x1, long clip_y1,
 		float scale)
 {
-        os_trfm *matrix = xcalloc(1, sizeof(os_trfm));
+        os_trfm matrix;
 
         /* Scaled image. Transform units (65536*OS units) */
-        matrix->entries[0][0] = ((width*65536) / (c->width*2));
-        matrix->entries[0][1] = 0;
-        matrix->entries[1][0] = 0;
-        matrix->entries[1][1] = ((height*65536) / (c->height*2));
+        matrix.entries[0][0] = ((width*65536) / (c->width*2));
+        matrix.entries[0][1] = 0;
+        matrix.entries[1][0] = 0;
+        matrix.entries[1][1] = ((height*65536) / (c->height*2));
         /* Draw units. (x,y) = bottom left */
-        matrix->entries[2][0] = x * 256 - c->data.draw.x0 * width / c->width;
-        matrix->entries[2][1] = (y - height) * 256 -
+        matrix.entries[2][0] = x * 256 - c->data.draw.x0 * width / c->width;
+        matrix.entries[2][1] = (y - height) * 256 -
         		c->data.draw.y0 * height / c->height;
 
-	xdrawfile_render(0, (drawfile_diagram*)(c->data.draw.data),
-			(int)c->data.draw.length, matrix, 0, 0);
-
-        xfree(matrix);
+	xdrawfile_render(0, (drawfile_diagram*)(c->source_data),
+			(int)c->source_size, &matrix, 0, 0);
 }
 #endif
diff --git a/riscos/draw.h b/riscos/draw.h
index fbf9cfc4b..bb1f88d3f 100644
--- a/riscos/draw.h
+++ b/riscos/draw.h
@@ -11,17 +11,10 @@
 struct content;
 
 struct content_draw_data {
-	void *data;
-	unsigned long length;
 	int x0, y0;
 };
 
-void draw_init(void);
-void draw_create(struct content *c, const char *params[]);
-void draw_process_data(struct content *c, char *data, unsigned long size);
 int draw_convert(struct content *c, unsigned int width, unsigned int height);
-void draw_revive(struct content *c, unsigned int width, unsigned int height);
-void draw_reformat(struct content *c, unsigned int width, unsigned int height);
 void draw_destroy(struct content *c);
 void draw_redraw(struct content *c, long x, long y,
 		unsigned long width, unsigned long height,
diff --git a/riscos/filetype.c b/riscos/filetype.c
index 98c3005bd..0273558cb 100644
--- a/riscos/filetype.c
+++ b/riscos/filetype.c
@@ -2,15 +2,17 @@
  * 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 2003 James Bursa 
+ * Copyright 2004 James Bursa 
  */
 
 #include 
 #include 
 #include 
+#include "oslib/mimemap.h"
 #include "oslib/osfile.h"
-#include "netsurf/utils/config.h"
+#include "netsurf/content/content.h"
 #include "netsurf/content/fetch.h"
+#include "netsurf/riscos/gui.h"
 #include "netsurf/utils/log.h"
 #include "netsurf/utils/utils.h"
 
@@ -20,26 +22,14 @@ struct type_entry {
 	char mime_type[40];
 };
 static const struct type_entry type_map[] = {
-#ifdef WITH_PLUGIN
         {0x188, "application/x-shockwave-flash"},
-#endif
-#ifdef WITH_GIF
 	{0x695, "image/gif"},
-#endif
-#ifdef WITH_DRAW
 	{0xaff, "image/x-drawfile"},
-#endif
-#ifdef WITH_PNG
 	{0xb60, "image/png"},
-#endif
-#ifdef WITH_JPEG
 	{0xc85, "image/jpeg"},
-#endif
 	{0xf79, "text/css"},
 	{0xfaf, "text/html"},
-#ifdef WITH_SPRITE
 	{0xff9, "image/x-riscos-sprite"},
-#endif
 	{0xfff, "text/plain"},
 };
 #define TYPE_MAP_COUNT (sizeof(type_map) / sizeof(type_map[0]))
@@ -49,7 +39,7 @@ static int cmp_type(const void *x, const void *y);
 
 
 /**
- * filetype -- determine the MIME type of a local file
+ * Determine the MIME type of a local file.
  */
 
 const char *fetch_filetype(const char *unix_path)
@@ -93,3 +83,31 @@ int cmp_type(const void *x, const void *y)
 	return *p < q->file_type ? -1 : (*p == q->file_type ? 0 : +1);
 }
 
+
+/**
+ * Determine the RISC OS filetype for a content.
+ */
+
+int ro_content_filetype(struct content *content)
+{
+	int file_type;
+	os_error *error;
+
+	switch (content->type) {
+		case CONTENT_HTML:	return 0xfaf;
+		case CONTENT_TEXTPLAIN:	return 0xfff;
+		case CONTENT_CSS:	return 0xf79;
+		case CONTENT_JPEG:	return 0xc85;
+		case CONTENT_PNG:	return 0xb60;
+		case CONTENT_GIF:	return 0x695;
+		case CONTENT_SPRITE:	return 0xff9;
+		case CONTENT_DRAW:	return 0xaff;
+		default:		break;
+	}
+
+	error = xmimemaptranslate_mime_type_to_filetype(content->mime_type,
+			&file_type);
+	if (error)
+		return 0xffd;
+	return file_type;
+}
diff --git a/riscos/gif.c b/riscos/gif.c
index 29f1095a2..70d6e23a6 100644
--- a/riscos/gif.c
+++ b/riscos/gif.c
@@ -34,18 +34,9 @@ void nsgif_init(void)
 void nsgif_create(struct content *c, const char *params[])
 {
   c->data.gif.sprite_area = 0;
-  c->data.gif.data = xcalloc(0, 1);
-  c->data.gif.length = 0;
   c->data.gif.buffer_pos = 0;
 }
 
-void nsgif_process_data(struct content *c, char *data, unsigned long size)
-{
-  c->data.gif.data = xrealloc(c->data.gif.data, c->data.gif.length + size);
-  memcpy(c->data.gif.data + c->data.gif.length, data, size);
-  c->data.gif.length += size;
-  c->size += size;
-}
 
 int nsgif_convert(struct content *c, unsigned int iwidth, unsigned int iheight)
 {
@@ -55,7 +46,7 @@ int nsgif_convert(struct content *c, unsigned int iwidth, unsigned int iheight)
   struct osspriteop_header *header;
   struct osspriteop_area *area;
 
-  a = Anim_FromData(c->data.gif.data, c->data.gif.length, NULL, false, false, false);
+  a = Anim_FromData(c->source_data, c->source_size, NULL, false, false, false);
   if (!a) {
 
     LOG(("Error creating anim object"));
@@ -124,14 +115,6 @@ int nsgif_convert(struct content *c, unsigned int iwidth, unsigned int iheight)
   return 0;
 }
 
-void nsgif_revive(struct content *c, unsigned int width, unsigned int height)
-{
-}
-
-
-void nsgif_reformat(struct content *c, unsigned int width, unsigned int height)
-{
-}
 
 void nsgif_redraw(struct content *c, long x, long y,
 		unsigned long width, unsigned long height,
@@ -192,7 +175,6 @@ void nsgif_destroy(struct content *c)
 {
   xfree(c->title);
   xfree(c->data.gif.sprite_area);
-  xfree(c->data.gif.data);
 }
 
 
diff --git a/riscos/gif.h b/riscos/gif.h
index e520481f7..c0f467bda 100644
--- a/riscos/gif.h
+++ b/riscos/gif.h
@@ -13,8 +13,6 @@
 struct content;
 
 struct content_gif_data {
-	char *data;
-	unsigned long length;
 	unsigned long buffer_pos;
 	osspriteop_area *sprite_area;
 	char *sprite_image;
@@ -22,10 +20,7 @@ struct content_gif_data {
 
 void nsgif_init(void);
 void nsgif_create(struct content *c, const char *params[]);
-void nsgif_process_data(struct content *c, char *data, unsigned long size);
 int nsgif_convert(struct content *c, unsigned int width, unsigned int height);
-void nsgif_revive(struct content *c, unsigned int width, unsigned int height);
-void nsgif_reformat(struct content *c, unsigned int width, unsigned int height);
 void nsgif_destroy(struct content *c);
 void nsgif_redraw(struct content *c, long x, long y,
 		unsigned long width, unsigned long height,
diff --git a/riscos/gui.c b/riscos/gui.c
index 1ee590edb..1f0e70e12 100644
--- a/riscos/gui.c
+++ b/riscos/gui.c
@@ -1120,23 +1120,11 @@ void ro_gui_open_help_page(void)
 
 void ro_gui_view_source(struct content *content)
 {
-
-        if (content->type == CONTENT_HTML) {
-               	xosfile_save_stamped("", 0xfff,
-        		        content->data.html.source,
-        		        (content->data.html.source +
-        		        content->data.html.length));
-                xos_cli("Filer_Run ");
-                xosfile_set_type("", 0xfaf);
-        }
-        else if (content->type == CONTENT_CSS) {
-               	xosfile_save_stamped("", 0xfff,
-        		        content->data.css.data,
-        		        (content->data.css.data +
-        		        content->data.css.length));
-                xos_cli("Filer_Run ");
-                xosfile_set_type("", 0xf79);
-        }
+	xosfile_save_stamped("", 0xfff,
+			content->source_data,
+			content->source_data + content->source_size);
+	xos_cli("Filer_Run ");
+	xosfile_set_type("", ro_content_filetype(content));
 }
 
 
diff --git a/riscos/gui.h b/riscos/gui.h
index 5ff526460..081040b2e 100644
--- a/riscos/gui.h
+++ b/riscos/gui.h
@@ -159,6 +159,9 @@ void ro_gui_drag_icon(wimp_pointer *pointer);
 void ro_gui_save_drag_end(wimp_dragged *drag);
 void ro_gui_save_datasave_ack(wimp_message *message);
 
+/* in filetype.c */
+int ro_content_filetype(struct content *content);
+
 /* icon numbers */
 #define ICON_TOOLBAR_THROBBER 1
 #define ICON_TOOLBAR_URL 2
diff --git a/riscos/jpeg.c b/riscos/jpeg.c
index f273207b4..b0ae9a801 100644
--- a/riscos/jpeg.c
+++ b/riscos/jpeg.c
@@ -127,22 +127,10 @@ void nsjpeg_init(void) {
 void nsjpeg_create(struct content *c, const char *params[])
 {
         c->data.jpeg.sprite_area = 0;
-	c->data.jpeg.data = xcalloc(0, 1);
-	c->data.jpeg.length = 0;
 	c->data.jpeg.use_module = true; /* assume the OS can cope */
 }
 
 
-void nsjpeg_process_data(struct content *c, char *data, unsigned long size)
-{
-	c->data.jpeg.data = xrealloc(c->data.jpeg.data, c->data.jpeg.length + size);
-	memcpy((char*)(c->data.jpeg.data) + c->data.jpeg.length, data, size);
-	c->data.jpeg.length += size;
-	c->size += size;
-}
-
-
-
 int nsjpeg_convert(struct content *c, unsigned int width, unsigned int height)
 {
         struct jpeg_decompress_struct cinfo;
@@ -158,8 +146,8 @@ int nsjpeg_convert(struct content *c, unsigned int width, unsigned int height)
         {
           os_error *e;
           int w,h;
-          e = xjpeginfo_dimensions((jpeg_image const*)c->data.jpeg.data,
-	                              (int) c->data.jpeg.length,
+          e = xjpeginfo_dimensions((jpeg_image const*)c->source_data,
+	                              (int) c->source_size,
 			              0, &w, &h, 0, 0, 0);
 
 	  if (!e) {
@@ -167,7 +155,7 @@ int nsjpeg_convert(struct content *c, unsigned int width, unsigned int height)
 	    c->width = w;
 	    c->height = h;
 	    c->title = xcalloc(100, 1);
-	    sprintf(c->title, messages_get("JPEGTitle"), w, h, c->data.jpeg.length);
+	    sprintf(c->title, messages_get("JPEGTitle"), w, h, c->source_size);
 	    c->status = CONTENT_STATUS_DONE;
 	   return 0;
 	  }
@@ -183,7 +171,7 @@ int nsjpeg_convert(struct content *c, unsigned int width, unsigned int height)
           return 1;
         }
         jpeg_create_decompress(&cinfo);
-        jpeg_memory_src(&cinfo, c->data.jpeg.data, c->data.jpeg.length);
+        jpeg_memory_src(&cinfo, c->source_data, c->source_size);
         jpeg_read_header(&cinfo, TRUE);
         jpeg_start_decompress(&cinfo);
 
@@ -311,20 +299,9 @@ int nsjpeg_convert(struct content *c, unsigned int width, unsigned int height)
 }
 
 
-void nsjpeg_revive(struct content *c, unsigned int width, unsigned int height)
-{
-}
-
-
-void nsjpeg_reformat(struct content *c, unsigned int width, unsigned int height)
-{
-}
-
-
 void nsjpeg_destroy(struct content *c)
 {
         xfree(c->data.jpeg.sprite_area);
-	xfree(c->data.jpeg.data);
 	xfree(c->title);
 }
 
@@ -343,9 +320,9 @@ void nsjpeg_redraw(struct content *c, long x, long y,
   factors.ydiv = c->height * 2;
 
   if (c->data.jpeg.use_module) { /* we can use the OS for this one */
-    xjpeg_plot_scaled((jpeg_image *) c->data.jpeg.data,
+    xjpeg_plot_scaled((jpeg_image *) c->source_data,
 			x, (int)(y - height),
-			&factors, (int) c->data.jpeg.length,
+			&factors, (int) c->source_size,
 			jpeg_SCALE_DITHERED);
     return;
   }
diff --git a/riscos/jpeg.h b/riscos/jpeg.h
index d3439fd93..2f6c8d211 100644
--- a/riscos/jpeg.h
+++ b/riscos/jpeg.h
@@ -14,8 +14,6 @@
 struct content;
 
 struct content_jpeg_data {
-	void *data;
-	unsigned long length;
 	osspriteop_area *sprite_area;
 	char *sprite_image;
 	bool use_module;
@@ -23,10 +21,7 @@ struct content_jpeg_data {
 
 void nsjpeg_init(void);
 void nsjpeg_create(struct content *c, const char *params[]);
-void nsjpeg_process_data(struct content *c, char *data, unsigned long size);
 int nsjpeg_convert(struct content *c, unsigned int width, unsigned int height);
-void nsjpeg_revive(struct content *c, unsigned int width, unsigned int height);
-void nsjpeg_reformat(struct content *c, unsigned int width, unsigned int height);
 void nsjpeg_destroy(struct content *c);
 void nsjpeg_redraw(struct content *c, long x, long y,
 		unsigned long width, unsigned long height,
diff --git a/riscos/menus.c b/riscos/menus.c
index d874eb13e..dda598b89 100644
--- a/riscos/menus.c
+++ b/riscos/menus.c
@@ -286,6 +286,8 @@ void ro_gui_menu_selection(wimp_selection *selection)
 
 void ro_gui_menu_warning(wimp_message_menu_warning *warning)
 {
+	char icon[20] = "file_xxx";
+	struct content *c = current_gui->data.browser.bw->current_content;
 	os_error *error;
 
 	if (warning->selection.items[0] != 0)
@@ -304,8 +306,11 @@ void ro_gui_menu_warning(wimp_message_menu_warning *warning)
 		case -1:
 		default: /* Save */
 			gui_current_save_type = GUI_SAVE_SOURCE;
+			if (c)
+				sprintf(icon, "file_%x",
+						ro_content_filetype(c));
 			ro_gui_set_icon_string(dialog_saveas,
-					ICON_SAVE_ICON, "file_faf");
+					ICON_SAVE_ICON, icon);
 			ro_gui_set_icon_string(dialog_saveas,
 					ICON_SAVE_PATH,
 					messages_get("SaveSource"));
diff --git a/riscos/png.c b/riscos/png.c
index 5c1f0d14a..73d581dc5 100644
--- a/riscos/png.c
+++ b/riscos/png.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 2003 James Bursa 
+ * Copyright 2004 James Bursa 
  * Copyright 2004 Richard Wilson 
  */
 
@@ -11,10 +11,7 @@
 #include 
 #include 
 #include 
-#include "ifc.h"
 #include "libpng/png.h"
-#include "oslib/colourtrans.h"
-#include "oslib/os.h"
 #include "oslib/osspriteop.h"
 #include "netsurf/utils/config.h"
 #include "netsurf/content/content.h"
@@ -82,14 +79,12 @@ void nspng_process_data(struct content *c, char *data, unsigned long size)
 
 void info_callback(png_structp png, png_infop info)
 {
-	int i, bit_depth, color_type, interlace;
+	int bit_depth, color_type, interlace;
 	unsigned int rowbytes, sprite_size;
 	unsigned long width, height;
 	struct content *c = png_get_progressive_ptr(png);
 	osspriteop_area *sprite_area;
 	osspriteop_header *sprite;
-	png_color_16 *png_background;
-	png_color_16 default_background = {0, 0xffff, 0xffff, 0xffff, 0xffff};
 
 	/*	Read the PNG details
 	*/
@@ -118,7 +113,7 @@ void info_callback(png_structp png, png_infop info)
 	sprite->left_bit = 0;
 	sprite->right_bit = 31;
 	sprite->mask = sprite->image = sizeof(*sprite);
-	sprite->mode = 0x301680b5;
+	sprite->mode = (os_mode) 0x301680b5;
 
 	/*	Store the sprite area
 	*/
@@ -219,16 +214,6 @@ int nspng_convert(struct content *c, unsigned int width, unsigned int height)
 }
 
 
-void nspng_revive(struct content *c, unsigned int width, unsigned int height)
-{
-}
-
-
-void nspng_reformat(struct content *c, unsigned int width, unsigned int height)
-{
-}
-
-
 void nspng_destroy(struct content *c)
 {
 	xfree(c->title);
diff --git a/riscos/png.h b/riscos/png.h
index 8d91ef7ee..ead45d290 100644
--- a/riscos/png.h
+++ b/riscos/png.h
@@ -20,18 +20,12 @@ struct content_png_data {
 	int interlace;
 	osspriteop_area *sprite_area;
 	char *sprite_image;
-	enum { PNG_PALETTE, PNG_DITHER, PNG_DEEP } type;
-	/** for ImageFileConvert */
-	char *data;
-	unsigned long length;
 };
 
 void nspng_init(void);
 void nspng_create(struct content *c, const char *params[]);
 void nspng_process_data(struct content *c, char *data, unsigned long size);
 int nspng_convert(struct content *c, unsigned int width, unsigned int height);
-void nspng_revive(struct content *c, unsigned int width, unsigned int height);
-void nspng_reformat(struct content *c, unsigned int width, unsigned int height);
 void nspng_destroy(struct content *c);
 void nspng_redraw(struct content *c, long x, long y,
 		unsigned long width, unsigned long height,
diff --git a/riscos/save.c b/riscos/save.c
index f3bb35213..33a5351ba 100644
--- a/riscos/save.c
+++ b/riscos/save.c
@@ -15,7 +15,6 @@
 #include "oslib/wimp.h"
 #include "netsurf/riscos/gui.h"
 #include "netsurf/riscos/save_draw.h"
-#include "netsurf/riscos/save_html.h"
 #include "netsurf/utils/log.h"
 #include "netsurf/utils/messages.h"
 #include "netsurf/utils/utils.h"
@@ -107,22 +106,23 @@ void ro_gui_save_drag_end(wimp_dragged *drag)
 void ro_gui_save_datasave_ack(wimp_message *message)
 {
 	char *path = message->data.data_xfer.file_name;
+	struct content *c = current_gui->data.browser.bw->current_content;
 
 	ro_gui_set_icon_string(dialog_saveas, ICON_SAVE_PATH, path);
 
 	switch (gui_current_save_type) {
 		case GUI_SAVE_SOURCE:
-		        if (!current_gui->data.browser.bw->current_content)
+		        if (!c)
 		                return;
-			save_as_html(current_gui->data.browser.bw->
-			                current_content, path);
+	                xosfile_save_stamped(path, ro_content_filetype(c),
+					c->source_data,
+					c->source_data + c->source_size);
 			break;
 
 		case GUI_SAVE_DRAW:
-			if (!current_gui->data.browser.bw->current_content)
+			if (!c)
 				return;
-			save_as_draw(current_gui->data.browser.bw->
-					current_content, path);
+			save_as_draw(c, path);
 			break;
 	}
 
diff --git a/riscos/save_complete.c b/riscos/save_complete.c
index 08baffbd8..fca18e987 100644
--- a/riscos/save_complete.c
+++ b/riscos/save_complete.c
@@ -13,6 +13,7 @@
 #include "netsurf/css/css.h"
 #include "netsurf/render/form.h"
 #include "netsurf/render/layout.h"
+#include "netsurf/riscos/gui.h"
 #include "netsurf/riscos/save_complete.h"
 #include "netsurf/utils/log.h"
 #include "netsurf/utils/utils.h"
@@ -36,16 +37,11 @@ void save_complete(struct content *c) {
 	char *fname = 0, *spath;
 	unsigned int i;
 
-	if (c->type != CONTENT_HTML) {
+	if (c->type != CONTENT_HTML)
 		return;
-	}
 
 	fname = "test";  /*get_filename(c->data.html.base_url);*/
 
-	if (!fname) { /* no path -> exit */
-		return;
-	}
-
 	spath = xcalloc(strlen(SAVE_PATH)+strlen(OBJ_DIR)+strlen(fname)+50,
 			sizeof(char));
 
@@ -53,55 +49,35 @@ void save_complete(struct content *c) {
 	xosfile_create_dir(spath, 77);
 
         /* save stylesheets, ignoring the base sheet and