summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--!NetSurf/Resources/en/Messages3
-rw-r--r--!NetSurf/Resources/en/Templates,fecbin6298 -> 6410 bytes
-rw-r--r--!NetSurf/Resources/fr/Messages3
-rw-r--r--!NetSurf/Resources/fr/Templates,fecbin6404 -> 6516 bytes
-rw-r--r--content/content.c292
-rw-r--r--content/content.h100
-rw-r--r--content/fetch.c8
-rw-r--r--content/fetchcache.c41
-rw-r--r--css/css.c119
-rw-r--r--css/css.h4
-rw-r--r--debug/netsurfd.c10
-rw-r--r--desktop/browser.c1
-rw-r--r--desktop/gui.h2
-rw-r--r--desktop/netsurf.c12
-rw-r--r--makefile14
-rw-r--r--render/html.c111
-rw-r--r--render/html.h15
-rw-r--r--render/textplain.c10
-rw-r--r--render/textplain.h4
-rw-r--r--riscos/dialog.c3
-rw-r--r--riscos/draw.c51
-rw-r--r--riscos/draw.h8
-rw-r--r--riscos/gif.c64
-rw-r--r--riscos/gif.h11
-rw-r--r--riscos/gifread.c29
-rw-r--r--riscos/gui.c11
-rw-r--r--riscos/gui.h8
-rw-r--r--riscos/htmlredraw.c6
-rw-r--r--riscos/jpeg.c35
-rw-r--r--riscos/jpeg.h10
-rw-r--r--riscos/png.c72
-rw-r--r--riscos/png.h13
-rw-r--r--riscos/sprite.c92
-rw-r--r--riscos/sprite.h15
-rw-r--r--riscos/wimp.c1
-rw-r--r--utils/utils.h1
36 files changed, 743 insertions, 436 deletions
diff --git a/!NetSurf/Resources/en/Messages b/!NetSurf/Resources/en/Messages
index 6d727b91d..25a7e3acb 100644
--- a/!NetSurf/Resources/en/Messages
+++ b/!NetSurf/Resources/en/Messages
@@ -117,6 +117,9 @@ FetchStyle2:Loading %u stylesheets: %s
NotCSS:Warning: stylesheet is not CSS
BadObject:Warning: bad object type
ObjError:Error loading object: %s
+ParsingFail:Parsing the document failed.
+BadGIF:Reading GIF failed.
+PNGError:PNG library error.
DrawTitle:Draw image (%lux%lu, %lu bytes)
GIFTitle:GIF image (%lux%lu)
diff --git a/!NetSurf/Resources/en/Templates,fec b/!NetSurf/Resources/en/Templates,fec
index 58f6c17c5..afad82c15 100644
--- a/!NetSurf/Resources/en/Templates,fec
+++ b/!NetSurf/Resources/en/Templates,fec
Binary files differ
diff --git a/!NetSurf/Resources/fr/Messages b/!NetSurf/Resources/fr/Messages
index 67cc4cc18..5077b78c9 100644
--- a/!NetSurf/Resources/fr/Messages
+++ b/!NetSurf/Resources/fr/Messages
@@ -115,6 +115,9 @@ FetchStyle2:Chargement de %u feuilles de styles: %s
NotCSS:Attention: feuille de style non CSS
BadObject:Attention: mauvais type d'objet
ObjError:Erreur lors du chargement de: %s
+ParsingFail:Parsing the document failed.
+BadGIF:Reading GIF failed.
+PNGError:PNG library error.
DrawTitle:Image Draw (%lux%lu, %lu octets)
GIFTitle:Image GIF (%lux%lu)
diff --git a/!NetSurf/Resources/fr/Templates,fec b/!NetSurf/Resources/fr/Templates,fec
index ec487e3d1..1f2934814 100644
--- a/!NetSurf/Resources/fr/Templates,fec
+++ b/!NetSurf/Resources/fr/Templates,fec
Binary files differ
diff --git a/content/content.c b/content/content.c
index a002c04fd..268b36433 100644
--- a/content/content.c
+++ b/content/content.c
@@ -45,6 +45,10 @@
#include "netsurf/utils/utils.h"
+/** Linked list of all content structures. May include more than one content
+ * per URL. Doubly-linked. */
+struct content *content_list = 0;
+
/** An entry in mime_map. */
struct mime_entry {
char mime_type[40];
@@ -79,17 +83,50 @@ static const struct mime_entry mime_map[] = {
};
#define MIME_MAP_COUNT (sizeof(mime_map) / sizeof(mime_map[0]))
+const char *content_type_name[] = {
+ "HTML",
+ "TEXTPLAIN",
+ "CSS",
+#ifdef WITH_JPEG
+ "JPEG",
+#endif
+#ifdef WITH_GIF
+ "GIF",
+#endif
+#ifdef WITH_PNG
+ "PNG",
+#endif
+#ifdef WITH_SPRITE
+ "SPRITE",
+#endif
+#ifdef WITH_DRAW
+ "DRAW",
+#endif
+#ifdef WITH_PLUGIN
+ "PLUGIN",
+#endif
+ "OTHER",
+ "UNKNOWN"
+};
+
+const char *content_status_name[] = {
+ "TYPE_UNKNOWN",
+ "LOADING",
+ "READY",
+ "DONE",
+ "ERROR"
+};
+
/** An entry in handler_map. */
struct handler_entry {
- void (*create)(struct content *c, const char *params[]);
- void (*process_data)(struct content *c, char *data, unsigned long size);
- int (*convert)(struct content *c, unsigned int width, unsigned int height);
- void (*revive)(struct content *c, unsigned int width, unsigned int height);
- void (*reformat)(struct content *c, unsigned int width, unsigned int height);
+ bool (*create)(struct content *c, const char *params[]);
+ bool (*process_data)(struct content *c, char *data, unsigned int size);
+ bool (*convert)(struct content *c, int width, int height);
+ void (*reformat)(struct content *c, int width, int height);
void (*destroy)(struct content *c);
- void (*redraw)(struct content *c, long x, long y,
- unsigned long width, unsigned long height,
- long clip_x0, long clip_y0, long clip_x1, long clip_y1,
+ void (*redraw)(struct content *c, int x, int y,
+ int width, int height,
+ int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale);
void (*add_instance)(struct content *c, struct browser_window *bw,
struct content *page, struct box *box,
@@ -104,39 +141,39 @@ struct handler_entry {
/** A table of handler functions, indexed by ::content_type.
* Must be ordered as enum ::content_type. */
static const struct handler_entry handler_map[] = {
- {html_create, html_process_data, html_convert, html_revive,
+ {html_create, html_process_data, html_convert,
html_reformat, html_destroy, html_redraw,
html_add_instance, html_remove_instance, html_reshape_instance},
{textplain_create, html_process_data, textplain_convert,
- 0, 0, 0, 0, 0, 0, 0},
- {0, 0, css_convert, css_revive, 0, css_destroy, 0, 0, 0, 0},
+ 0, 0, 0, 0, 0, 0},
+ {0, 0, css_convert, 0, css_destroy, 0, 0, 0, 0},
#ifdef WITH_JPEG
- {nsjpeg_create, 0, nsjpeg_convert, 0,
+ {nsjpeg_create, 0, nsjpeg_convert,
0, nsjpeg_destroy, nsjpeg_redraw, 0, 0, 0},
#endif
#ifdef WITH_GIF
- {nsgif_create, 0, nsgif_convert, 0,
+ {nsgif_create, 0, nsgif_convert,
0, nsgif_destroy, nsgif_redraw, 0, 0, 0},
#endif
#ifdef WITH_PNG
- {nspng_create, nspng_process_data, nspng_convert, 0,
+ {nspng_create, nspng_process_data, nspng_convert,
0, nspng_destroy, nspng_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},
+ {sprite_create, sprite_process_data, sprite_convert,
+ 0, sprite_destroy, sprite_redraw, 0, 0, 0},
#endif
#ifdef WITH_DRAW
- {0, 0, draw_convert, 0,
+ {0, 0, draw_convert,
0, draw_destroy, draw_redraw, 0, 0, 0},
#endif
#ifdef WITH_PLUGIN
- {plugin_create, plugin_process_data, plugin_convert, plugin_revive,
+ {plugin_create, plugin_process_data, plugin_convert,
plugin_reformat, plugin_destroy, plugin_redraw,
plugin_add_instance, plugin_remove_instance,
plugin_reshape_instance},
#endif
- {0, 0, 0, 0, 0, 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]))
@@ -166,33 +203,62 @@ content_type content_lookup(const char *mime_type)
/**
* Create a new content structure.
*
+ * \param url URL of content, copied
+ * \return the new content structure, or 0 on memory exhaustion
+ *
* The type is initialised to CONTENT_UNKNOWN, and the status to
* CONTENT_STATUS_TYPE_UNKNOWN.
*/
-struct content * content_create(char *url)
+struct content * content_create(const char *url)
{
struct content *c;
struct content_user *user_sentinel;
LOG(("url %s", url));
- c = xcalloc(1, sizeof(struct content));
- c->url = xstrdup(url);
+ c = malloc(sizeof(struct content));
+ if (!c)
+ return 0;
+ user_sentinel = malloc(sizeof *user_sentinel);
+ if (!user_sentinel) {
+ free(c);
+ return 0;
+ }
+ c->url = strdup(url);
+ if (!c->url) {
+ free(c);
+ free(user_sentinel);
+ return 0;
+ }
c->type = CONTENT_UNKNOWN;
+ c->mime_type = 0;
c->status = CONTENT_STATUS_TYPE_UNKNOWN;
+ c->width = 0;
+ c->height = 0;
+ c->available_width = 0;
c->cache = 0;
c->size = sizeof(struct content);
- c->fetch = 0;
- c->source_data = 0;
- c->source_size = 0;
- c->mime_type = 0;
- content_set_status(c, messages_get("Loading"));
- user_sentinel = xcalloc(1, sizeof(*user_sentinel));
+ c->title = 0;
+ c->active = 0;
user_sentinel->callback = 0;
user_sentinel->p1 = user_sentinel->p2 = 0;
user_sentinel->next = 0;
c->user_list = user_sentinel;
+ content_set_status(c, messages_get("Loading"));
+ c->fetch = 0;
+ c->source_data = 0;
+ c->source_size = 0;
+ c->total_size = 0;
c->lock = 0;
c->destroy_pending = false;
+ c->no_error_pages = false;
+ c->error_count = 0;
+
+ c->prev = 0;
+ c->next = content_list;
+ if (content_list)
+ content_list->prev = c;
+ content_list = c;
+
return c;
}
@@ -200,34 +266,51 @@ struct content * content_create(char *url)
/**
* Initialise the content for the specified type.
*
+ * \param c content structure
+ * \param type content_type to initialise to
+ * \param mime_type MIME-type string for this content
+ * \param params array of strings, ordered attribute, value, attribute, ..., 0
+ * \return true on success, false on error and error broadcast to users and
+ * possibly reported
+ *
* The type is updated to the given type, and a copy of mime_type is taken. The
* status is changed to CONTENT_STATUS_LOADING. CONTENT_MSG_LOADING is sent to
* all users. The create function for the type is called to initialise the type
* specific parts of the content structure.
- *
- * \param c content structure
- * \param type content_type to initialise to
- * \param mime_type MIME-type string for this content
- * \param params array of strings, ordered attribute, value, attribute, ..., 0
*/
-void content_set_type(struct content *c, content_type type,
+bool content_set_type(struct content *c, content_type type,
const char *mime_type, const char *params[])
{
- union content_msg_data data;
+ union content_msg_data msg_data;
+
assert(c != 0);
assert(c->status == CONTENT_STATUS_TYPE_UNKNOWN);
assert(type < CONTENT_UNKNOWN);
+
LOG(("content %s, type %i", c->url, type));
+
+ c->mime_type = strdup(mime_type);
+ if (!c->mime_type) {
+ c->status = CONTENT_STATUS_ERROR;
+ msg_data.error = messages_get("NoMemory");
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ warn_user("NoMemory", 0);
+ return false;
+ }
+
c->type = type;
- c->mime_type = xstrdup(mime_type);
c->status = CONTENT_STATUS_LOADING;
- c->source_data = xcalloc(0, 1);
- if (handler_map[type].create)
- handler_map[type].create(c, params);
- content_broadcast(c, CONTENT_MSG_LOADING, data);
- /* c may be destroyed at this point as a result of
- * CONTENT_MSG_LOADING, so must not be accessed */
+
+ if (handler_map[type].create) {
+ if (!handler_map[type].create(c, params)) {
+ c->status = CONTENT_STATUS_ERROR;
+ return false;
+ }
+ }
+
+ content_broadcast(c, CONTENT_MSG_LOADING, msg_data);
+ return true;
}
@@ -255,19 +338,44 @@ void content_set_status(struct content *c, const char *status_message, ...)
* Process a block of source data.
*
* Calls the process_data function for the content.
+ *
+ * \param c content structure
+ * \param data new data to process
+ * \param size size of data
+ * \return true on success, false on error and error broadcast to users and
+ * possibly reported
*/
-void content_process_data(struct content *c, char *data, unsigned long size)
+bool content_process_data(struct content *c, char *data, unsigned int size)
{
- assert(c != 0);
+ char *source_data;
+ union content_msg_data msg_data;
+
+ assert(c);
+ assert(c->type < HANDLER_MAP_COUNT);
assert(c->status == CONTENT_STATUS_LOADING);
- LOG(("content %s, size %lu", c->url, size));
- c->source_data = xrealloc(c->source_data, c->source_size + size);
+ LOG(("content %s, size %u", c->url, size));
+
+ source_data = realloc(c->source_data, c->source_size + size);
+ if (!source_data) {
+ c->status = CONTENT_STATUS_ERROR;
+ msg_data.error = messages_get("NoMemory");
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ warn_user("NoMemory", 0);
+ return false;
+ }
+ c->source_data = source_data;
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);
+
+ if (handler_map[c->type].process_data) {
+ if (!handler_map[c->type].process_data(c, data, size)) {
+ c->status = CONTENT_STATUS_ERROR;
+ return false;
+ }
+ }
+ return true;
}
@@ -281,54 +389,34 @@ void content_process_data(struct content *c, char *data, unsigned long size)
* CONTENT_MSG_READY is sent to all users.
* - If the conversion succeeds and is complete, the content gets status
* CONTENT_STATUS_DONE, and CONTENT_MSG_READY then CONTENT_MSG_DONE are sent.
- * - If the conversion fails, CONTENT_MSG_ERROR is sent. The content is then
- * destroyed and must no longer be used.
+ * - If the conversion fails, CONTENT_MSG_ERROR is sent. The content will soon
+ * be destroyed and must no longer be used.
*/
-void content_convert(struct content *c, unsigned long width, unsigned long height)
+void content_convert(struct content *c, int width, int height)
{
- union content_msg_data data;
- assert(c != 0);
+ union content_msg_data msg_data;
+
+ assert(c);
assert(c->type < HANDLER_MAP_COUNT);
assert(c->status == CONTENT_STATUS_LOADING);
LOG(("content %s", c->url));
+
c->available_width = width;
if (handler_map[c->type].convert) {
- if (handler_map[c->type].convert(c, width, height)) {
- /* convert failed, destroy content */
- data.error = "Conversion failed";
- content_broadcast(c, CONTENT_MSG_ERROR, data);
- if (c->cache)
- cache_destroy(c);
- content_destroy(c);
+ if (!handler_map[c->type].convert(c, width, height)) {
+ c->status = CONTENT_STATUS_ERROR;
return;
}
} else {
c->status = CONTENT_STATUS_DONE;
}
+
assert(c->status == CONTENT_STATUS_READY ||
c->status == CONTENT_STATUS_DONE);
- content_broadcast(c, CONTENT_MSG_READY, data);
+ content_broadcast(c, CONTENT_MSG_READY, msg_data);
if (c->status == CONTENT_STATUS_DONE)
- content_broadcast(c, CONTENT_MSG_DONE, data);
-}
-
-
-/**
- * Fix content that has been loaded from the cache.
- *
- * Calls the revive function for the content. The content will be processed for
- * display, for example dependencies loaded or reformated to current width.
- */
-
-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;
- c->available_width = width;
- handler_map[c->type].revive(c, width, height);
+ content_broadcast(c, CONTENT_MSG_DONE, msg_data);
}
@@ -338,7 +426,7 @@ void content_revive(struct content *c, unsigned long width, unsigned long height
* Calls the reformat function for the content.
*/
-void content_reformat(struct content *c, unsigned long width, unsigned long height)
+void content_reformat(struct content *c, int width, int height)
{
union content_msg_data data;
assert(c != 0);
@@ -353,6 +441,29 @@ void content_reformat(struct content *c, unsigned long width, unsigned long heig
/**
+ * Destroys any contents in the content_list with no users or in
+ * CONTENT_STATUS_ERROR, and not with an active fetch or cached.
+ */
+
+void content_clean(void)
+{
+ struct content *c, *next;
+
+ for (c = content_list; c; c = next) {
+ next = c->next;
+ if (((!c->user_list->next && !c->cache) ||
+ c->status == CONTENT_STATUS_ERROR) &&
+ !c->fetch) {
+ LOG(("%p %s", c, c->url));
+ if (c->cache)
+ cache_destroy(c);
+ content_destroy(c);
+ }
+ }
+}
+
+
+/**
* Destroy and free a content.
*
* Calls the destroy function for the content, and frees the structure.
@@ -371,6 +482,13 @@ void content_destroy(struct content *c)
return;
}
+ if (c->next)
+ c->next->prev = c->prev;
+ if (c->prev)
+ c->prev->next = c->next;
+ else
+ content_list = c->next;
+
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) {
@@ -411,9 +529,9 @@ void content_reset(struct content *c)
* Calls the redraw function for the content, if it exists.
*/
-void content_redraw(struct content *c, long x, long y,
- unsigned long width, unsigned long height,
- long clip_x0, long clip_y0, long clip_x1, long clip_y1,
+void content_redraw(struct content *c, int x, int y,
+ int width, int height,
+ int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale)
{
assert(c != 0);
@@ -570,3 +688,9 @@ void content_reshape_instance(struct content *c, struct browser_window *bw,
handler_map[c->type].reshape_instance(c, bw, page, box, params, state);
}
+
+
+void content_add_error(struct content *c, const char *token,
+ unsigned int line)
+{
+}
diff --git a/content/content.h b/content/content.h
index 13c4092ce..3fcbd39fe 100644
--- a/content/content.h
+++ b/content/content.h
@@ -14,12 +14,73 @@
* Each content has a type. The type is used to call a specific implementation
* of functions such as content_process_data().
*
+ * The source data fetched from the URL is placed in the source_data buffer as
+ * it arrives.
+ *
* Contents have an associated set of users, which are informed by a callback
* when the state of the content changes or something interesting happens.
*
* Optionally, contents may have instances (depending on type). Instances
* represent copies of the same URL, for example if a page is open in two
* windows, or a page contains the same image twice.
+ *
+ * The status of a content follows a fixed order. Certain content functions
+ * change the state, and each change of state results in a message to all users
+ * of the content. The diagram below shows this:
+ * \dot
+ * digraph status {
+ * node [shape=plaintext, fontname=Helvetica, fontsize=9];
+ * edge [fontname=Helvetica, fontsize=9];
+ *
+ * content_create -> TYPE_UNKNOWN [style=bold];
+ * TYPE_UNKNOWN -> content_set_type [style=bold];
+ * content_set_type -> LOADING [label=MSG_LOADING, style=bold];
+ * content_set_type -> ERROR [label=MSG_ERROR];
+ * LOADING -> content_process_data [style=bold];
+ * content_process_data -> LOADING [style=bold];
+ * content_process_data -> ERROR [label=MSG_ERROR];
+ * LOADING -> content_convert [style=bold];
+ * content_convert -> READY [label=MSG_READY, style=bold];
+ * content_convert -> DONE [label="MSG_READY\nMSG_DONE", style=bold];
+ * content_convert -> ERROR [label=MSG_ERROR];
+ * READY -> READY [style=bold];
+ * READY -> DONE [label=MSG_DONE, style=bold];
+ *
+ * TYPE_UNKNOWN [shape=ellipse];
+ * LOADING [shape=ellipse];
+ * READY [shape=ellipse];
+ * DONE [shape=ellipse];
+ * ERROR [shape=ellipse];
+ * }
+ * \enddot
+ *
+ * To implement a new content type, implement the following functions:
+ *
+ * - <i>type</i>_create(): called to initialise type-specific fields in the
+ * content structure. Optional.
+ *
+ * - <i>type</i>_process_data(): called when some data arrives. Optional.
+ *
+ * - <i>type</i>_convert(): called when data has finished arriving. The
+ * content needs to be converted for display. Must set the status to one of
+ * CONTENT_STATUS_READY or CONTENT_STATUS_DONE if no error occurs. Optional,
+ * but probably required for non-trivial types.
+ *
+ * - <i>type</i>_reformat(): called when, for example, the window has been
+ * resized, and the content needs reformatting for the new size. Optional.
+ *
+ * - <i>type</i>_destroy(): called when the content is being destroyed. Free all
+ * resources. Optional.
+ *
+ * - <i>type</i>_redraw(): called to plot the content to screen.
+ *
+ * - <i>type</i>_(add|remove|reshape)_instance: ask James, this will probably
+ * be redesigned sometime.
+ *
+ * - <i>type</i>_create(), <i>type</i>_process_data(), <i>type</i>_convert():
+ * if an error occurs, must broadcast CONTENT_MSG_ERROR and return false.
+ * Optionally use warn_user() for serious errors. The _destroy function will
+ * be called soon after.
*/
#ifndef _NETSURF_DESKTOP_CONTENT_H_
@@ -111,7 +172,9 @@ struct content {
converted and is not safe to display. */
CONTENT_STATUS_READY, /**< Some parts of content still being
loaded, but can be displayed. */
- CONTENT_STATUS_DONE /**< All finished. */
+ CONTENT_STATUS_DONE, /**< All finished. */
+ CONTENT_STATUS_ERROR /**< Error occurred, content will be
+ destroyed imminently. */
} status; /**< Current status. */
int width, height; /**< Dimensions, if applicable. */
@@ -147,7 +210,6 @@ struct content {
char *title; /**< Title for browser window. */
unsigned int active; /**< Number of child fetches or
conversions currently in progress. */
- int error; /**< Non-0 if an error has occurred. */
struct content_user *user_list; /**< List of users. */
char status_message[80]; /**< Text for status bar. */
@@ -159,26 +221,40 @@ struct content {
int lock; /**< Content in use, do not destroy. */
bool destroy_pending; /**< Destroy when lock returns to 0. */
bool no_error_pages; /**< Used by fetchcache(). */
+
+ /** Array of first n rendering errors or warnings. */
+ struct {
+ const char *token;
+ unsigned int line; /**< Line no, 0 if not applicable. */
+ } error_list[40];
+ unsigned int error_count; /**< Number of valid error entries. */
+
+ struct content *prev; /**< Previous in global content list. */
+ struct content *next; /**< Next in global content list. */
};
+extern struct content *content_list;
+extern const char *content_type_name[];
+extern const char *content_status_name[];
+
struct browser_window;
content_type content_lookup(const char *mime_type);
-struct content * content_create(char *url);
-void content_set_type(struct content *c, content_type type,
+struct content * content_create(const char *url);
+bool content_set_type(struct content *c, content_type type,
const char *mime_type, const char *params[]);
void content_set_status(struct content *c, const char *status_message, ...);
-void content_process_data(struct content *c, char *data, unsigned long size);
-void content_convert(struct content *c, unsigned long width, unsigned long height);
-void content_revive(struct content *c, unsigned long width, unsigned long height);
-void content_reformat(struct content *c, unsigned long width, unsigned long height);
+bool content_process_data(struct content *c, char *data, unsigned int size);
+void content_convert(struct content *c, int width, int height);
+void content_reformat(struct content *c, int width, int height);
+void content_clean(void);
void content_destroy(struct content *c);
void content_reset(struct content *c);
-void content_redraw(struct content *c, long x, long y,
- unsigned long width, unsigned long height,
- long clip_x0, long clip_y0, long clip_x1, long clip_y1,
+void content_redraw(struct content *c, int x, int y,
+ int width, int height,
+ int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale);
void content_add_user(struct content *c,
void (*callback)(content_msg msg, struct content *c, void *p1,
@@ -199,5 +275,7 @@ void content_remove_instance(struct content *c, struct browser_window *bw,
void content_reshape_instance(struct content *c, struct browser_window *bw,
struct content *page, struct box *box,
struct object_params *params, void **state);
+void content_add_error(struct content *c, const char *token,
+ unsigned int line);
#endif
diff --git a/content/fetch.c b/content/fetch.c
index c8630f343..52d7effc5 100644
--- a/content/fetch.c
+++ b/content/fetch.c
@@ -31,9 +31,6 @@
#include "curl/curl.h"
#include "netsurf/utils/config.h"
#include "netsurf/content/fetch.h"
-#ifdef riscos
-#include "netsurf/desktop/gui.h"
-#endif
#include "netsurf/desktop/options.h"
#ifdef WITH_AUTH
#include "netsurf/desktop/401login.h"
@@ -587,6 +584,11 @@ size_t fetch_curl_data(void * data, size_t size, size_t nmemb, struct fetch *f)
/* send data to the caller */
LOG(("FETCH_DATA"));
f->callback(FETCH_DATA, f->p, data, size * nmemb);
+ if (f->aborting) {
+ f->locked--;
+ f->stopped = true;
+ return 0;
+ }
f->locked--;
return size * nmemb;
diff --git a/content/fetchcache.c b/content/fetchcache.c
index 164a11231..359b59809 100644
--- a/content/fetchcache.c
+++ b/content/fetchcache.c
@@ -59,7 +59,7 @@ static void fetchcache_error_page(struct content *c, const char *error);
* \param post_urlenc url encoded post data, or 0 if none
* \param post_multipart multipart post data, or 0 if none
* \param cookies send and accept cookies
- * \return a new content, or 0 if an error occurred and no_error_pages is true
+ * \return a new content, or 0 if an error occurred
*/
struct content * fetchcache(const char *url, char *referer,
@@ -77,12 +77,16 @@ struct content * fetchcache(const char *url, char *referer,
)
{
struct content *c;
- char *url1 = xstrdup(url);
- char *hash = strchr(url1, '#');
+ char *url1;
+ char *hash;
char error_message[500];
+ url1 = strdup(url);
+ if (!url1)
+ return 0;
+
/* strip fragment identifier */
- if (hash != 0)
+ if ((hash = strchr(url1, '#')))
*hash = 0;
LOG(("url %s", url1));
@@ -100,6 +104,10 @@ struct content * fetchcache(const char *url, char *referer,
}
c = content_create(url1);
+ if (!c) {
+ free(url1);
+ return 0;
+ }
content_add_user(c, callback, p1, p2);
#ifdef WITH_POST
@@ -118,12 +126,10 @@ struct content * fetchcache(const char *url, char *referer,
,cookies
#endif
);
- if (c->fetch == 0) {
+ if (!c->fetch) {
LOG(("warning: fetch_start failed"));
- if (c->cache)
- cache_destroy(c);
+ c->status = CONTENT_STATUS_ERROR;
if (no_error_pages) {
- content_destroy(c);
free(url1);
return 0;
}
@@ -144,6 +150,7 @@ struct content * fetchcache(const char *url, char *referer,
void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size)
{
+ bool res;
struct content *c = p;
content_type type;
char *mime_type, *url;
@@ -159,11 +166,13 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size)
mime_type = fetchcache_parse_type(data, &params);
type = content_lookup(mime_type);
LOG(("FETCH_TYPE, type %u", type));
- content_set_type(c, type, mime_type, (const char**)params);
+ res = content_set_type(c, type, mime_type, params);
free(mime_type);
for (i = 0; params[i]; i++)
free(params[i]);
free(params);
+ if (!res)
+ fetch_abort(c->fetch);
if (c->cache && c->type == CONTENT_OTHER)
cache_destroy(c);
break;
@@ -181,7 +190,8 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size)
messages_get("Received"),
human_friendly_bytesize(c->source_size + size));
content_broadcast(c, CONTENT_MSG_STATUS, msg_data);
- content_process_data(c, data, size);
+ if (!content_process_data(c, data, size))
+ fetch_abort(c->fetch);
break;
case FETCH_FINISHED:
@@ -199,9 +209,10 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size)
if (c->cache)
cache_destroy(c);
if (c->no_error_pages) {
+ c->status = CONTENT_STATUS_ERROR;
msg_data.error = data;
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
- content_destroy(c);
+ content_broadcast(c, CONTENT_MSG_ERROR,
+ msg_data);
} else {
content_reset(c);
fetchcache_error_page(c, data);
@@ -233,15 +244,15 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size)
c->fetch = 0;
msg_data.auth_realm = data;
content_broadcast(c, CONTENT_MSG_AUTH, msg_data);
- cache_destroy(c);
+ if (c->cache)
+ cache_destroy(c);
break;
#endif
default:
assert(0);
}
- if (--(c->lock) == 0 && c->destroy_pending)
- content_destroy(c);
+ c->lock--;
}
diff --git a/css/css.c b/css/css.c
index c42ad3d21..8239d77bf 100644
--- a/css/css.c
+++ b/css/css.c
@@ -87,6 +87,7 @@
#include "netsurf/desktop/gui.h"
#endif
#include "netsurf/utils/log.h"
+#include "netsurf/utils/messages.h"
#include "netsurf/utils/url.h"
#include "netsurf/utils/utils.h"
@@ -241,7 +242,7 @@ const struct css_style css_blank_style = {
* Convert a CONTENT_CSS for use.
*/
-int css_convert(struct content *c, unsigned int width, unsigned int height)
+bool css_convert(struct content *c, int width, int height)
{
unsigned char *source_data;
unsigned char *current, *end, *token_text;
@@ -250,6 +251,7 @@ int css_convert(struct content *c, unsigned int width, unsigned int height)
void *parser;
struct css_parser_params param = {false, c, 0, false, false};
struct css_parser_token token_data;
+ union content_msg_data msg_data;
c->data.css.css = malloc(sizeof *c->data.css.css);
parser = css_parser_Alloc(malloc);
@@ -258,7 +260,11 @@ int css_convert(struct content *c, unsigned int width, unsigned int height)
if (!c->data.css.css || !parser || !source_data) {
free(c->data.css.css);
css_parser_Free(parser, free);
- return 1;
+
+ msg_data.error = messages_get("NoMemory");
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ warn_user("NoMemory", 0);
+ return false;
}
for (i = 0; i != HASH_SIZE; i++)
@@ -292,8 +298,12 @@ int css_convert(struct content *c, unsigned int width, unsigned int height)
css_parser_(parser, 0, token_data, &param);
css_parser_Free(parser, free);
- if (param.memory_error)
- return 1;
+ if (param.memory_error) {
+ msg_data.error = messages_get("NoMemory");
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ warn_user("NoMemory", 0);
+ return false;
+ }
/*css_dump_stylesheet(c->data.css.css);*/
@@ -305,35 +315,7 @@ int css_convert(struct content *c, unsigned int width, unsigned int height)
}
c->status = CONTENT_STATUS_DONE;
- return 0;
-}
-
-
-void css_revive(struct content *c, unsigned int width, unsigned int height)
-{
- unsigned int i;
- /* imported stylesheets */
- for (i = 0; i != c->data.css.import_count; i++) {
- c->data.css.import_content[i] = fetchcache(
- c->data.css.import_url[i], c->url,
- css_atimport_callback, c, (void*)i,
- c->width, c->height, true
-#ifdef WITH_POST
- , 0, 0
-#endif
-#ifdef WITH_COOKIES
- , false
-#endif
- );
- if (c->data.css.import_content[i] == 0)
- continue;
- if (c->data.css.import_content[i]->status != CONTENT_STATUS_DONE)
- c->active++;
- }
- while (c->active != 0) {
- fetch_poll();
- gui_multitask();
- }
+ return true;
}
@@ -371,6 +353,7 @@ void css_destroy(struct content *c)
/**
* Create a new struct css_node.
*
+ * \param stylesheet content of type CONTENT_CSS
* \param type type of node
* \param data string for data, not copied
* \param data_length length of data
@@ -610,7 +593,7 @@ void css_atimport_callback(content_msg msg, struct content *css,
content_remove_user(css, css_atimport_callback, c, (void*)i);
c->data.css.import_content[i] = 0;
c->active--;
- c->error = 1;
+ content_add_error(c, "NotCSS", 0);
}
break;
@@ -626,7 +609,7 @@ void css_atimport_callback(content_msg msg, struct content *css,
case CONTENT_MSG_ERROR:
c->data.css.import_content[i] = 0;
c->active--;
- c->error = 1;
+ content_add_error(c, "?", 0);
break;
case CONTENT_MSG_STATUS:
@@ -638,7 +621,7 @@ void css_atimport_callback(content_msg msg, struct content *css,
c->data.css.import_url[i] = strdup(data.redirect);
if (!c->data.css.import_url[i]) {
/** \todo report to user */
- c->error = 1;
+ /* c->error = 1; */
return;
}
c->data.css.import_content[i] = fetchcache(
@@ -996,9 +979,41 @@ void css_dump_style(const struct css_style * const style)
if (style->z != css_empty_style.z) \
fprintf(stderr, s ": %s; ", n[style->z]);
- DUMP_KEYWORD(background_attachment, "background-attachment", css_background_attachment_name);
DUMP_COLOR(background_color, "background-color");
- DUMP_KEYWORD(background_repeat, "background-repeat", css_background_repeat_name);
+ if (style->background_attachment !=
+ css_empty_style.background_attachment ||
+ style->background_image.type !=
+ css_empty_style.background_image.type ||
+ style->background_position.horz.pos !=
+ css_empty_style.background_position.horz.pos ||
+ style->background_position.vert.pos !=
+ css_empty_style.background_position.vert.pos ||
+ style->background_repeat !=
+ css_empty_style.background_repeat) {
+ fprintf(stderr, "background: ");
+ switch (style->background_image.type) {
+ case CSS_BACKGROUND_IMAGE_NONE:
+ fprintf(stderr, "none");
+ break;
+ case CSS_BACKGROUND_IMAGE_INHERIT:
+ fprintf(stderr, "inherit");
+ break;
+ case CSS_BACKGROUND_IMAGE_URI:
+ fprintf(stderr, "(%p) \"%s\"",
+ style->background_image.uri,
+ style->background_image.uri);
+ break;
+ default:
+ fprintf(stderr, "UNKNOWN");
+ break;
+ }
+ fprintf(stderr, " %s %s ",
+ css_background_attachment_name[
+ style->background_attachment],
+ css_background_repeat_name[
+ style->background_repeat]);
+ fprintf(stderr, "; ");
+ }
DUMP_KEYWORD(clear, "clear", css_clear_name);
DUMP_COLOR(color, "color");
DUMP_KEYWORD(cursor, "cursor", css_cursor_name);
@@ -1078,7 +1093,7 @@ void css_dump_style(const struct css_style * const style)
if (style->margin[0].margin != css_empty_style.margin[0].margin ||
style->margin[1].margin != css_empty_style.margin[1].margin ||
style->margin[2].margin != css_empty_style.margin[2].margin ||
- style->margin[3].margin != css_empty_style.margin[3].margin) {
+ style->margin[3].margin != css_empty_style.margin[3].margin) {
fprintf(stderr, "margin:");
for (i = 0; i != 4; i++) {
switch (style->margin[i].margin) {
@@ -1152,19 +1167,19 @@ void css_dump_style(const struct css_style * const style)
if (style->text_indent.size != css_empty_style.text_indent.size) {
fprintf(stderr, "text-indent: ");
switch (style->text_indent.size) {
- case CSS_TEXT_INDENT_LENGTH:
- css_dump_length(&style->text_indent.value.length);
- break;
- case CSS_TEXT_INDENT_PERCENT:
- fprintf(stderr, "%g%%",
- style->text_indent.value.percent);
- break;
- case CSS_TEXT_INDENT_INHERIT:
- fprintf(stderr, "inherit");
- break;
- default:
- fprintf(stderr, "UNKNOWN");
- break;
+ case CSS_TEXT_INDENT_LENGTH:
+ css_dump_length(&style->text_indent.value.length);
+ break;
+ case CSS_TEXT_INDENT_PERCENT:
+ fprintf(stderr, "%g%%",
+ style->text_indent.value.percent);
+ break;
+ case CSS_TEXT_INDENT_INHERIT:
+ fprintf(stderr, "inherit");
+ break;
+ default:
+ fprintf(stderr, "UNKNOWN");
+ break;
}
fprintf(stderr, "; ");
}
diff --git a/css/css.h b/css/css.h
index d80df9333..e3ebca02e 100644
--- a/css/css.h
+++ b/css/css.h
@@ -311,8 +311,7 @@ struct css_parser_token {
struct content;
-int css_convert(struct content *c, unsigned int width, unsigned int height);
-void css_revive(struct content *c, unsigned int width, unsigned int height);
+bool css_convert(struct content *c, int width, int height);
void css_destroy(struct content *c);
#ifdef CSS_INTERNALS
@@ -340,6 +339,7 @@ void *css_parser_Alloc(void *(*mallocProc)(/*size_t*/ int));
void css_parser_Free(void *p, void (*freeProc)(void*));
void css_parser_(void *yyp, int yymajor, struct css_parser_token yyminor,
struct css_parser_params *param);
+const char *css_parser_TokenName(int tokenType);
#endif
diff --git a/debug/netsurfd.c b/debug/netsurfd.c
index fefc5d483..417af1d50 100644
--- a/debug/netsurfd.c
+++ b/debug/netsurfd.c
@@ -119,9 +119,9 @@ void plugin_decode(void *a, void *b, void *c, void *d)
}
#endif
-void html_redraw(struct content *c, long x, long y,
- unsigned long width, unsigned long height,
- long x0, long y0, long x1, long y1,
+void html_redraw(struct content *c, int x, int y,
+ int width, int height,
+ int x0, int y0, int x1, int y1,
float scale)
{
}
@@ -262,9 +262,9 @@ extern os_t os_read_monotonic_time(void)
}
#endif
-void warn_user(const char *warn)
+void warn_user(const char *warning, const char *detail)
{
- printf("WARNING: %s\n", warn);
+ printf("WARNING: %s %s\n", warning, detail);
}
void *ro_gui_current_redraw_gui = 0;
diff --git a/desktop/browser.c b/desktop/browser.c
index 8f1bb9a0c..2c8c28441 100644
--- a/desktop/browser.c
+++ b/desktop/browser.c
@@ -260,6 +260,7 @@ void browser_window_callback(content_msg msg, struct content *c,
case CONTENT_MSG_ERROR:
browser_window_set_status(bw, data.error);
+ warn_user(data.error, 0);
if (c == bw->loading_content)
bw->loading_content = 0;
else if (c == bw->current_content)
diff --git a/desktop/gui.h b/desktop/gui.h
index d7f98609d..f388f2d7d 100644
--- a/desktop/gui.h
+++ b/desktop/gui.h
@@ -62,6 +62,4 @@ void gui_window_place_caret(gui_window *g, int x, int y, int height);
void gui_launch_url(const char *url);
-void warn_user(const char *warning, const char *detail);
-
#endif
diff --git a/desktop/netsurf.c b/desktop/netsurf.c
index 106a33193..21f01177e 100644
--- a/desktop/netsurf.c
+++ b/desktop/netsurf.c
@@ -54,6 +54,7 @@ void netsurf_init(int argc, char** argv)
struct utsname utsname;
stdout = stderr;
+ curl_memdebug("memdump");
if (uname(&utsname) != 0)
LOG(("Failed to extract machine information\n"));
else
@@ -63,12 +64,6 @@ void netsurf_init(int argc, char** argv)
fetch_init();
cache_init();
fetchcache_init();
-#ifdef WITH_PNG
- nspng_init();
-#endif
-#ifdef WITH_GIF
- nsgif_init();
-#endif
url_init();
}
@@ -79,8 +74,9 @@ void netsurf_init(int argc, char** argv)
void netsurf_poll(void)
{
- gui_poll(fetch_active);
- fetch_poll();
+ content_clean();
+ gui_poll(fetch_active);
+ fetch_poll();
}
diff --git a/makefile b/makefile
index 93940fa2a..22573d354 100644
--- a/makefile
+++ b/makefile
@@ -24,13 +24,13 @@ OBJECTS_COMMON += imagemap.o loginlist.o options.o # desktop/
OBJECTS_RISCOS = $(OBJECTS_COMMON)
OBJECTS_RISCOS += browser.o netsurf.o version.o # desktop/
-OBJECTS_RISCOS += 401login.o about.o constdata.o dialog.o download.o \
- draw.o filetype.o font.o gif.o gifread.o gui.o help.o \
- history.o htmlinstance.o htmlredraw.o jpeg.o menus.o \
- mouseactions.o plugin.o png.o save.o save_complete.o \
- save_draw.o save_text.o schedule.o sprite.o \
- textselection.o theme.o thumbnail.o toolbar.o uri.o \
- url_protocol.o wimp.o window.o # riscos/
+OBJECTS_RISCOS += 401login.o about.o constdata.o debugwin.o \
+ dialog.o download.o draw.o filetype.o font.o gif.o \
+ gifread.o gui.o help.o history.o htmlinstance.o \
+ htmlredraw.o jpeg.o menus.o mouseactions.o plugin.o \
+ png.o save.o save_complete.o save_draw.o save_text.o \
+ schedule.o sprite.o textselection.o theme.o thumbnail.o \
+ toolbar.o uri.o url_protocol.o wimp.o window.o # riscos/
OBJECTS_DEBUG = $(OBJECTS_COMMON)
OBJECTS_DEBUG += filetyped.o fontd.o netsurfd.o # debug/
diff --git a/render/html.c b/render/html.c
index f3d19a072..d39dd32da 100644
--- a/render/html.c
+++ b/render/html.c
@@ -51,10 +51,11 @@ static bool html_object_type_permitted(const content_type type,
* created.
*/
-void html_create(struct content *c, const char *params[])
+bool html_create(struct content *c, const char *params[])
{
unsigned int i;
struct content_html_data *html = &c->data.html;
+ union content_msg_data msg_data;
xmlCharEncoding encoding = XML_CHAR_ENCODING_NONE;
html->encoding = NULL;
@@ -74,7 +75,7 @@ void html_create(struct content *c, const char *params[])
}
html->parser = htmlCreatePushParserCtxt(0, 0, "", 0, 0, encoding);
- html->base_url = xstrdup(c->url);
+ html->base_url = strdup(c->url);
html->layout = 0;
html->background_colour = TRANSPARENT;
html->stylesheet_count = 0;
@@ -85,9 +86,24 @@ void html_create(struct content *c, const char *params[])
html->object = 0;
html->imagemaps = 0;
html->string_pool = pool_create(8000);
- assert(html->string_pool);
html->box_pool = pool_create(sizeof (struct box) * 100);
- assert(html->box_pool);
+
+ if (!html->parser || !html->base_url || !html->string_pool ||
+ !html->box_pool) {
+ htmlFreeParserCtxt(html->parser);
+ free(html->base_url);
+ if (html->string_pool)
+ pool_destroy(html->string_pool);
+ if (html->box_pool)
+ pool_destroy(html->box_pool);
+
+ msg_data.error = messages_get("NoMemory");
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ warn_user("NoMemory", 0);
+ return false;
+ }
+
+ return true;
}
@@ -97,7 +113,7 @@ void html_create(struct content *c, const char *params[])
* The data is parsed in chunks of size CHUNK, multitasking in between.
*/
-void html_process_data(struct content *c, char *data, unsigned long size)
+bool html_process_data(struct content *c, char *data, unsigned int size)
{
unsigned long x;
@@ -120,6 +136,8 @@ void html_process_data(struct content *c, char *data, unsigned long size)
gui_multitask();
}
htmlParseChunk(c->data.html.parser, data + x, (int) (size - x), 0);
+
+ return true;
}
@@ -138,11 +156,11 @@ void html_process_data(struct content *c, char *data, unsigned long size)
* being fetched.
*/
-int html_convert(struct content *c, unsigned int width, unsigned int height)
+bool html_convert(struct content *c, int width, int height)
{
xmlDoc *document;
xmlNode *html, *head;
- union content_msg_data data;
+ union content_msg_data msg_data;
/* finish parsing */
htmlParseChunk(c->data.html.parser, "", 0, 1);
@@ -150,9 +168,12 @@ int html_convert(struct content *c, unsigned int width, unsigned int height)
/*xmlDebugDumpDocument(stderr, c->data.html.parser->myDoc);*/
htmlFreeParserCtxt(c->data.html.parser);
c->data.html.parser = 0;
- if (document == NULL) {
+ if (!document) {
LOG(("Parsing failed"));
- return 1;
+ msg_data.error = messages_get("ParsingFail");
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ warn_user("ParsingFail", 0);
+ return false;
}
/* Last change to pick the Content-Type charset information if the
* server didn't send it (or we're reading the HTML from disk)
@@ -168,7 +189,10 @@ int html_convert(struct content *c, unsigned int width, unsigned int height)
if (html == 0 || strcmp((const char *) html->name, "html") != 0) {
LOG(("html element not found"));
xmlFreeDoc(document);
- return 1;
+ msg_data.error = messages_get("ParsingFail");
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ warn_user("ParsingFail", 0);
+ return false;
}
for (head = html->children;
head != 0 && head->type != XML_ELEMENT_NODE;
@@ -188,7 +212,7 @@ int html_convert(struct content *c, unsigned int width, unsigned int height)
/* convert xml tree to box tree */
LOG(("XML to box"));
content_set_status(c, messages_get("Processing"));
- content_broadcast(c, CONTENT_MSG_STATUS, data);
+ content_broadcast(c, CONTENT_MSG_STATUS, msg_data);
xml_to_box(html, c);
/*box_dump(c->data.html.layout->children, 0);*/
@@ -201,7 +225,7 @@ int html_convert(struct content *c, unsigned int width, unsigned int height)
/* layout the box tree */
content_set_status(c, messages_get("Formatting"));
- content_broadcast(c, CONTENT_MSG_STATUS, data);
+ content_broadcast(c, CONTENT_MSG_STATUS, msg_data);
LOG(("Layout document"));
layout_document(c->data.html.layout->children, width,
c->data.html.box_pool);
@@ -218,7 +242,7 @@ int html_convert(struct content *c, unsigned int width, unsigned int height)
content_set_status(c, messages_get("FetchObjs"), c->active);
}
- return 0;
+ return true;
}
@@ -281,7 +305,6 @@ void html_find_stylesheets(struct content *c, xmlNode *head)
c->data.html.stylesheet_content[1] = 0;
c->data.html.stylesheet_count = 2;
- c->error = 0;
c->active = 0;
c->data.html.stylesheet_content[0] = fetchcache(
@@ -396,6 +419,8 @@ void html_find_stylesheets(struct content *c, xmlNode *head)
const char *params[] = { 0 };
c->data.html.stylesheet_content[1] =
content_create(c->data.html.base_url);
+ if (!c->data.html.stylesheet_content[1])
+ return false;
content_set_type(c->data.html.stylesheet_content[1],
CONTENT_CSS, "text/css", params);
}
@@ -434,10 +459,10 @@ void html_find_stylesheets(struct content *c, xmlNode *head)
gui_multitask();
}
- if (c->error) {
- content_set_status(c, "Warning: some stylesheets failed to load");
- content_broadcast(c, CONTENT_MSG_STATUS, msg_data);
- }
+/* if (c->error) { */
+/* content_set_status(c, "Warning: some stylesheets failed to load"); */
+/* content_broadcast(c, CONTENT_MSG_STATUS, msg_data); */
+/* } */
}
@@ -457,7 +482,7 @@ void html_convert_css_callback(content_msg msg, struct content *css,
if (css->type != CONTENT_CSS) {
c->data.html.stylesheet_content[i] = 0;
c->active--;
- c->error = 1;
+ content_add_error(c, "NotCSS", 0);
content_set_status(c, messages_get("NotCSS"));
content_broadcast(c, CONTENT_MSG_STATUS, data);
content_remove_user(css, html_convert_css_callback, c, (void*)i);
@@ -475,7 +500,7 @@ void html_convert_css_callback(content_msg msg, struct content *css,
case CONTENT_MSG_ERROR:
c->data.html.stylesheet_content[i] = 0;
c->active--;
- c->error = 1;
+ content_add_error(c, "?", 0);
break;
case CONTENT_MSG_STATUS:
@@ -506,7 +531,7 @@ void html_convert_css_callback(content_msg msg, struct content *css,
case CONTENT_MSG_AUTH:
c->data.html.stylesheet_content[i] = 0;
c->active--;
- c->error = 1;
+ content_add_error(c, "?", 0);
break;
#endif
@@ -590,7 +615,7 @@ void html_object_callback(content_msg msg, struct content *object,
/* not acceptable */
c->data.html.object[i].content = 0;
c->active--;
- c->error = 1;
+ content_add_error(c, "?", 0);
content_set_status(c, messages_get("BadObject"));
content_broadcast(c, CONTENT_MSG_STATUS, data);
content_remove_user(object, html_object_callback, c, (void*)i);
@@ -611,7 +636,7 @@ void html_object_callback(content_msg msg, struct content *object,
case CONTENT_MSG_ERROR:
c->data.html.object[i].content = 0;
c->active--;
- c->error = 1;
+ content_add_error(c, "?", 0);
content_set_status(c, messages_get("ObjError"),
data.error);
content_broadcast(c, CONTENT_MSG_STATUS, data);
@@ -674,7 +699,7 @@ void html_object_callback(content_msg msg, struct content *object,
case CONTENT_MSG_AUTH:
c->data.html.object[i].content = 0;
c->active--;
- c->error = 1;
+ content_add_error(c, "?", 0);
break;
#endif
@@ -754,47 +779,11 @@ bool html_object_type_permitted(const content_type type,
}
-void html_revive(struct content *c, unsigned int width, unsigned int height)
-{
- unsigned int i;
-
- assert(0); /* dead code, do not use as is */
-
- /* reload objects and fix pointers */
- for (i = 0; i != c->data.html.object_count; i++) {
- if (c->data.html.object[i].content != 0) {
- c->data.html.object[i].content = fetchcache(
- c->data.html.object[i].url, c->url,
- html_object_callback,
- c, (void*)i, 0, 0, true
-#ifdef WITH_POST
- , 0, 0
-#endif
-#ifdef WITH_COOKIES
- , false
-#endif
- );
- if (c->data.html.object[i].content &&
- c->data.html.object[i].content->status != CONTENT_STATUS_DONE)
- c->active++;
- }
- }
-
- layout_document(c->data.html.layout->children, width,
- c->data.html.box_pool);
- c->width = c->data.html.layout->children->width;
- c->height = c->data.html.layout->children->height;
-
- if (c->active != 0)
- c->status = CONTENT_STATUS_READY;
-}
-
-
/**
* Reformat a CONTENT_HTML to a new width.
*/
-void html_reformat(struct content *c, unsigned int width, unsigned int height)
+void html_reformat(struct content *c, int width, int height)
{
layout_document(c->data.html.layout->children, width,
c->data.html.box_pool);
diff --git a/render/html.h b/render/html.h
index 683c5dc73..9580beacb 100644
--- a/render/html.h
+++ b/render/html.h
@@ -83,11 +83,10 @@ struct content_html_data {
};
-void html_create(struct content *c, const char *params[]);
-void html_process_data(struct content *c, char *data, unsigned long size);
-int html_convert(struct content *c, unsigned int width, unsigned int height);
-void html_revive(struct content *c, unsigned int width, unsigned int height);
-void html_reformat(struct content *c, unsigned int width, unsigned int height);
+bool html_create(struct content *c, const char *params[]);
+bool html_process_data(struct content *c, char *data, unsigned int size);
+bool html_convert(struct content *c, int width, int height);
+void html_reformat(struct content *c, int width, int height);
void html_destroy(struct content *c);
void html_fetch_object(struct content *c, char *url, struct box *box,
const content_type *permitted_types,
@@ -106,9 +105,9 @@ void html_remove_instance(struct content *c, struct browser_window *bw,
struct object_params *params, void **state);
/* in riscos/htmlredraw.c */
-void html_redraw(struct content *c, long x, long y,
- unsigned long width, unsigned long height,
- long clip_x0, long clip_y0, long clip_x1, long clip_y1,
+void html_redraw(struct content *c, int x, int y,
+ int width, int height,
+ int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale);
#endif
diff --git a/render/textplain.c b/render/textplain.c
index 72ad98a4f..0a7f5db7c 100644
--- a/render/textplain.c
+++ b/render/textplain.c
@@ -15,14 +15,18 @@ static const char header[] = "<html><body><pre>";
static const char footer[] = "</pre></body></html>";
-void textplain_create(struct content *c, const char *params[])
+bool textplain_create(struct content *c, const char *params[])
{
- html_create(c, params);
+ if (!html_create(c, params))
+ /* html_create() must have broadcast MSG_ERROR already, so we
+ * don't need to. */
+ return false;
htmlParseChunk(c->data.html.parser, header, sizeof(header) - 1, 0);
+ return true;
}
-int textplain_convert(struct content *c, unsigned int width, unsigned int height)
+bool textplain_convert(struct content *c, int width, int height)
{
htmlParseChunk(c->data.html.parser, footer, sizeof(footer) - 1, 0);
c->type = CONTENT_HTML;
diff --git a/render/textplain.h b/render/textplain.h
index 859ff9e62..63550e181 100644
--- a/render/textplain.h
+++ b/render/textplain.h
@@ -10,7 +10,7 @@
struct content;
-void textplain_create(struct content *c, const char *params[]);
-int textplain_convert(struct content *c, unsigned int width, unsigned int height);
+bool textplain_create(struct content *c, const char *params[]);
+bool textplain_convert(struct content *c, int width, int height);
#endif
diff --git a/riscos/dialog.c b/riscos/dialog.c
index e59b3ba02..47c279515 100644
--- a/riscos/dialog.c
+++ b/riscos/dialog.c
@@ -33,7 +33,7 @@ wimp_w dialog_info, dialog_saveas, dialog_config, dialog_config_br,
dialog_401li,
#endif
dialog_zoom, dialog_pageinfo, dialog_objinfo, dialog_tooltip,
- dialog_warning, dialog_config_th_pane;
+ dialog_warning, dialog_config_th_pane, dialog_debug;
static int font_size;
static int font_min_size;
@@ -83,6 +83,7 @@ void ro_gui_dialog_init(void)
dialog_objinfo = ro_gui_dialog_create("objectinfo");
dialog_tooltip = ro_gui_dialog_create("tooltip");
dialog_warning = ro_gui_dialog_create("warning");
+ dialog_debug = ro_gui_dialog_create("debug");
set_browser_choices();
set_proxy_choices();
diff --git a/riscos/draw.c b/riscos/draw.c
index b59a96261..fbe4251cf 100644
--- a/riscos/draw.c
+++ b/riscos/draw.c
@@ -18,56 +18,47 @@
#ifdef WITH_DRAW
-int draw_convert(struct content *c, unsigned int width, unsigned int height)
+bool draw_convert(struct content *c, int width, int height)
{
+ union content_msg_data msg_data;
+ os_box bbox;
os_error *error;
- os_trfm *matrix = xcalloc(1, sizeof(os_trfm));
- os_box *bbox = xcalloc(1, sizeof(os_box));
-
- /* Full size image (1:1) */
- matrix->entries[0][0] = 1 << 16;
- matrix->entries[0][1] = 0;
- matrix->entries[1][0] = 0;
- matrix->entries[1][1] = 1 << 16;
- matrix->entries[2][0] = 0;
- matrix->entries[2][1] = 0;
/* BBox contents in Draw units (256*OS unit) */
error = xdrawfile_bbox(0, (drawfile_diagram*)(c->source_data),
- (int)c->source_size, matrix, bbox);
-
+ (int) c->source_size, 0, &bbox);
if (error) {
- LOG(("error: %s", error->errmess));
- xfree(matrix);
- xfree(bbox);
- return 1;
+ LOG(("xdrawfile_bbox: 0x%x: %s",
+ error->errnum, error->errmess));
+ msg_data.error = error->errmess;
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ return false;
}
/* c->width & c->height stored as (OS units/2)
=> divide by 512 to convert from draw units */
- c->width = ((bbox->x1 - bbox->x0) / 512);
- c->height = ((bbox->y1 - bbox->y0) / 512);
- c->data.draw.x0 = bbox->x0 / 2;
- c->data.draw.y0 = bbox->y0 / 2;
- c->title = xcalloc(100, 1);
- sprintf(c->title, messages_get("DrawTitle"), c->width,
+ c->width = ((bbox.x1 - bbox.x0) / 512);
+ c->height = ((bbox.y1 - bbox.y0) / 512);
+ c->data.draw.x0 = bbox.x0 / 2;
+ c->data.draw.y0 = bbox.y0 / 2;
+ c->title = malloc(100);
+ if (c->title)
+ snprintf(c->title, 100, messages_get("DrawTitle"), c->width,
c->height, c->source_size);
c->status = CONTENT_STATUS_DONE;
- xfree(matrix);
- xfree(bbox);
- return 0;
+ return true;
}
void draw_destroy(struct content *c)
{
- xfree(c->title);
+ free(c->title);
}
-void draw_redraw(struct content *c, long x, long y,
- unsigned long width, unsigned long height,
- long clip_x0, long clip_y0, long clip_x1, long clip_y1,
+void draw_redraw(struct content *c, int x, int y,
+ int width, int height,
+ int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale)
{
os_trfm matrix;
diff --git a/riscos/draw.h b/riscos/draw.h
index bb1f88d3f..67752a3dd 100644
--- a/riscos/draw.h
+++ b/riscos/draw.h
@@ -14,10 +14,10 @@ struct content_draw_data {
int x0, y0;
};
-int draw_convert(struct content *c, unsigned int width, unsigned int height);
+bool draw_convert(struct content *c, int width, int height);
void draw_destroy(struct content *c);
-void draw_redraw(struct content *c, long x, long y,
- unsigned long width, unsigned long height,
- long clip_x0, long clip_y0, long clip_x1, long clip_y1,
+void draw_redraw(struct content *c, int x, int y,
+ int width, int height,
+ int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale);
#endif
diff --git a/riscos/gif.c b/riscos/gif.c
index e15c5ebe4..9cd50829a 100644
--- a/riscos/gif.c
+++ b/riscos/gif.c
@@ -21,6 +21,7 @@
#include "netsurf/riscos/options.h"
#include "netsurf/riscos/tinct.h"
#include "netsurf/utils/log.h"
+#include "netsurf/utils/messages.h"
#include "netsurf/utils/utils.h"
@@ -38,19 +39,27 @@
static void nsgif_animate(void *p);
-void nsgif_init(void) {
-}
-void nsgif_create(struct content *c, const char *params[]) {
+bool nsgif_create(struct content *c, const char *params[]) {
+ union content_msg_data msg_data;
/* Initialise our data structure
*/
- c->data.gif.gif = (gif_animation *)xcalloc(sizeof(gif_animation), 1);
+ c->data.gif.gif = calloc(sizeof(gif_animation), 1);
+ if (!c->data.gif.gif) {
+ msg_data.error = messages_get("NoMemory");
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ warn_user("NoMemory", 0);
+ return false;
+ }
c->data.gif.current_frame = 0;
+ return true;
}
-int nsgif_convert(struct content *c, unsigned int iwidth, unsigned int iheight) {
+bool nsgif_convert(struct content *c, int iwidth, int iheight) {
+ int res;
struct gif_animation *gif;
+ union content_msg_data msg_data;
/* Create our animation
*/
@@ -61,38 +70,59 @@ int nsgif_convert(struct content *c, unsigned int iwidth, unsigned int iheight)
/* Initialise the GIF
*/
- gif_initialise(gif);
+ res = gif_initialise(gif);
+ if (res < 0) {
+ if (res == GIF_INSUFFICIENT_MEMORY) {
+ msg_data.error = messages_get("NoMemory");
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ warn_user("NoMemory", 0);
+ } else {
+ msg_data.error = messages_get("BadGIF");
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ }
+ return false;
+ }
/* Abort on bad GIFs
*/
- if ((gif->frame_count_partial == 0) || (gif->width == 0) || (gif->height == 0)) return 1;
+ if ((gif->frame_count_partial == 0) || (gif->width == 0) ||
+ (gif->height == 0)) {
+ msg_data.error = messages_get("BadGIF");
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ return false;
+ }
/* Store our content width
*/
c->width = gif->width;
c->height = gif->height;
+ /* Initialise the first frame so if we try to use the image data directly prior to
+ a plot we get some sensible data
+ */
+ res = gif_decode_frame(c->data.gif.gif, 0);
+ if (res < 0 && res != GIF_INSUFFICIENT_FRAME_DATA) {
+ msg_data.error = messages_get("BadGIF");
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ return false;
+ }
+
/* Schedule the animation if we have one
*/
if (gif->frame_count > 1) {
schedule(gif->frames[0].frame_delay, nsgif_animate, c);
}
- /* Initialise the first frame so if we try to use the image data directly prior to
- a plot we get some sensible data
- */
- gif_decode_frame(c->data.gif.gif, 0);
-
/* Exit as a success
*/
c->status = CONTENT_STATUS_DONE;
- return 0;
+ return true;
}
-void nsgif_redraw(struct content *c, long x, long y,
- unsigned long width, unsigned long height,
- long clip_x0, long clip_y0, long clip_x1, long clip_y1,
+void nsgif_redraw(struct content *c, int x, int y,
+ int width, int height,
+ int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale) {
int previous_frame;
@@ -152,7 +182,7 @@ void nsgif_destroy(struct content *c)
*/
schedule_remove(nsgif_animate, c);
gif_finalise(c->data.gif.gif);
- xfree(c->data.gif.gif);
+ free(c->data.gif.gif);
}
diff --git a/riscos/gif.h b/riscos/gif.h
index 526716dec..f6365071a 100644
--- a/riscos/gif.h
+++ b/riscos/gif.h
@@ -25,13 +25,12 @@ struct content_gif_data {
unsigned int current_frame;
};
-void nsgif_init(void);
-void nsgif_create(struct content *c, const char *params[]);
-int nsgif_convert(struct content *c, unsigned int width, unsigned int height);
+bool nsgif_create(struct content *c, const char *params[]);
+bool nsgif_convert(struct content *c, int width, int height);
void nsgif_destroy(struct content *c);
-void nsgif_redraw(struct content *c, long x, long y,
- unsigned long width, unsigned long height,
- long clip_x0, long clip_y0, long clip_x1, long clip_y1,
+void nsgif_redraw(struct content *c, int x, int y,
+ int width, int height,
+ int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale);
#endif
diff --git a/riscos/gifread.c b/riscos/gifread.c
index 3f4306374..3e9d39b69 100644
--- a/riscos/gifread.c
+++ b/riscos/gifread.c
@@ -96,11 +96,12 @@ static int clear_image = FALSE;
any information that hasn't already been decoded.
If an error occurs, all previously decoded frames are retained.
- @return -5 for GIF frame data error
- -4 for insufficient data to process any more frames
- -3 for memory error
- -2 for GIF error
- -1 for insufficient data to do anything
+ @return GIF_FRAME_DATA_ERROR for GIF frame data error
+ GIF_INSUFFICIENT_FRAME_DATA for insufficient data to process
+ any more frames
+ GIF_INSUFFICIENT_MEMORY for memory error
+ GIF_DATA_ERROR for GIF error
+ GIF_INSUFFICIENT_DATA for insufficient data to do anything
0 for successful decoding
1 for successful decoding (all frames completely read)
*/
@@ -112,7 +113,7 @@ int gif_initialise(struct gif_animation *gif) {
/* Check for sufficient data to be a GIF
*/
- if (gif->buffer_size < 13) return -1;
+ if (gif->buffer_size < 13) return GIF_INSUFFICIENT_DATA;
/* Get our current processing position
*/
@@ -244,12 +245,12 @@ int gif_initialise(struct gif_animation *gif) {
if (gif->frame_count_partial > 0) {
/* Set the redraw for the first frame to the maximum frame size
*/
- gif->frames[0].redraw_required = 0;
+ gif->frames[0].redraw_required = 0;
gif->frames[0].redraw_x = 0;
gif->frames[0].redraw_y = 0;
gif->frames[0].redraw_width = gif->width;
gif->frames[0].redraw_height = gif->height;
-
+
/* We now work backwards to update the redraw characteristics of frames
with clear codes to stop a snowball effect of the redraw areas. It doesn't
really make much difference for most images, and will not work as well
@@ -282,7 +283,7 @@ int gif_initialise(struct gif_animation *gif) {
}
}
}
-
+
}
/* If there was a memory error tell the caller
@@ -512,7 +513,7 @@ int gif_initialise_frame(struct gif_animation *gif) {
gif->frames[frame].redraw_width = width;
gif->frames[frame].redraw_height = height;
}
-
+
/* if we are clearing the background then we need to redraw enough to cover the previous
frame too
*/
@@ -584,10 +585,10 @@ int gif_initialise_frame(struct gif_animation *gif) {
/** Decodes a GIF frame.
- @return -5 for GIF frame data error
- -4 for insufficient data to complete the frame
- -2 for GIF error (invalid frame header)
- -1 for insufficient data to do anything
+ @return GIF_FRAME_DATA_ERROR for GIF frame data error
+ GIF_INSUFFICIENT_FRAME_DATA for insufficient data to complete the frame
+ GIF_DATA_ERROR for GIF error (invalid frame header)
+ GIF_INSUFFICIENT_DATA for insufficient data to do anything
0 for successful decoding
*/
int gif_decode_frame(struct gif_animation *gif, unsigned int frame) {
diff --git a/riscos/gui.c b/riscos/gui.c
index 3f33e0581..dc36dd1bf 100644
--- a/riscos/gui.c
+++ b/riscos/gui.c
@@ -374,7 +374,7 @@ void ro_gui_check_resolvers(void)
if (resolvers) {
LOG(("Inet$Resolvers '%s'", resolvers));
} else {
- LOG(("Inet$Resolvers not set", resolvers));
+ LOG(("Inet$Resolvers not set"));
warn_user("Resolvers", 0);
}
}
@@ -613,6 +613,8 @@ void ro_gui_redraw_window_request(wimp_draw *redraw)
ro_gui_redraw_config_th_pane(redraw);
else if (redraw->w == history_window)
ro_gui_history_redraw(redraw);
+ else if (redraw->w == dialog_debug)
+ ro_gui_debugwin_redraw(redraw);
else {
g = ro_lookup_gui_from_w(redraw->w);
if (g != NULL)
@@ -660,6 +662,11 @@ void ro_gui_close_window_request(wimp_close *close)
{
gui_window *g;
+ if (close->w == dialog_debug) {
+ ro_gui_debugwin_close();
+ return;
+ }
+
g = ro_lookup_gui_from_w(close->w);
if (g) {
@@ -719,6 +726,8 @@ void ro_gui_icon_bar_click(wimp_pointer *pointer)
"file:///%%3CNetSurf$Dir%%3E/Docs/intro_%s",
option_language)) >= 0 && length < sizeof(url))
browser_window_create(url, NULL);
+ } else if (pointer->buttons == wimp_CLICK_ADJUST) {
+ ro_gui_debugwin_open();
}
}
diff --git a/riscos/gui.h b/riscos/gui.h
index db56bbc77..91839cc76 100644
--- a/riscos/gui.h
+++ b/riscos/gui.h
@@ -23,7 +23,8 @@
extern wimp_w dialog_info, dialog_saveas, dialog_config, dialog_config_br,
dialog_config_prox, dialog_config_th, dialog_zoom, dialog_pageinfo,
- dialog_objinfo, dialog_tooltip, dialog_warning, dialog_config_th_pane;
+ dialog_objinfo, dialog_tooltip, dialog_warning, dialog_config_th_pane,
+ dialog_debug;
extern wimp_w history_window;
extern wimp_menu *iconbar_menu, *browser_menu, *combo_menu;
extern int iconbar_menu_height;
@@ -195,6 +196,11 @@ void schedule(int t, void (*callback)(void *p), void *p);
void schedule_remove(void (*callback)(void *p), void *p);
void schedule_run(void);
+/* in debugwin.c */
+void ro_gui_debugwin_open(void);
+void ro_gui_debugwin_close(void);
+void ro_gui_debugwin_redraw(wimp_draw *redraw);
+
/* icon numbers */
#define ICON_TOOLBAR_BACK 0
#define ICON_TOOLBAR_FORWARD 1
diff --git a/riscos/htmlredraw.c b/riscos/htmlredraw.c
index 3e40aa6ac..d39acc1f4 100644
--- a/riscos/htmlredraw.c
+++ b/riscos/htmlredraw.c
@@ -60,9 +60,9 @@ static os_trfm trfm = { {
{ 0, 0 } } };
-void html_redraw(struct content *c, long x, long y,
- unsigned long width, unsigned long height,
- long clip_x0, long clip_y0, long clip_x1, long clip_y1,
+void html_redraw(struct content *c, int x, int y,
+ int width, int height,
+ int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale)
{
bool select_on = false;
diff --git a/riscos/jpeg.c b/riscos/jpeg.c
index 14128192d..ea8cb120b 100644
--- a/riscos/jpeg.c
+++ b/riscos/jpeg.c
@@ -40,6 +40,9 @@
#endif
+static char nsjpeg_error_buffer[JMSG_LENGTH_MAX];
+
+
struct nsjpeg_error_mgr {
struct jpeg_error_mgr pub;
jmp_buf setjmp_buffer;
@@ -57,9 +60,10 @@ static void nsjpeg_term_source(j_decompress_ptr cinfo);
* Create a CONTENT_JPEG.
*/
-void nsjpeg_create(struct content *c, const char *params[])
+bool nsjpeg_create(struct content *c, const char *params[])
{
c->data.jpeg.sprite_area = 0;
+ return true;
}
@@ -67,7 +71,7 @@ void nsjpeg_create(struct content *c, const char *params[])
* Convert a CONTENT_JPEG for display.
*/
-int nsjpeg_convert(struct content *c, unsigned int w, unsigned int h)
+bool nsjpeg_convert(struct content *c, int w, int h)
{
struct jpeg_decompress_struct cinfo;
struct nsjpeg_error_mgr jerr;
@@ -80,13 +84,17 @@ int nsjpeg_convert(struct content *c, unsigned int w, unsigned int h)
unsigned int area_size;
osspriteop_area *sprite_area = 0;
osspriteop_header *sprite;
+ union content_msg_data msg_data;
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = nsjpeg_error_exit;
if (setjmp(jerr.setjmp_buffer)) {
jpeg_destroy_decompress(&cinfo);
free(sprite_area);
- return 1;
+
+ msg_data.error = nsjpeg_error_buffer;
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ return false;
}
jpeg_create_decompress(&cinfo);
source_mgr.next_input_byte = c->source_data;
@@ -104,7 +112,12 @@ int nsjpeg_convert(struct content *c, unsigned int w, unsigned int h)
sprite_area = malloc(area_size);
if (!sprite_area) {
LOG(("malloc failed"));
- return 1;
+ jpeg_destroy_decompress(&cinfo);
+
+ msg_data.error = messages_get("NoMemory");
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ warn_user("NoMemory", 0);
+ return false;
}
/* area control block */
@@ -142,10 +155,10 @@ int nsjpeg_convert(struct content *c, unsigned int w, unsigned int h)
c->data.jpeg.sprite_area = sprite_area;
c->title = malloc(100);
if (c->title)
- sprintf(c->title, messages_get("JPEGTitle"),
+ snprintf(c->title, 100, messages_get("JPEGTitle"),
width, height, c->source_size);
c->status = CONTENT_STATUS_DONE;
- return 0;
+ return true;
}
@@ -158,7 +171,7 @@ int nsjpeg_convert(struct content *c, unsigned int w, unsigned int h)
void nsjpeg_error_exit(j_common_ptr cinfo)
{
struct nsjpeg_error_mgr *err = (struct nsjpeg_error_mgr *) cinfo->err;
- (*cinfo->err->output_message) (cinfo);
+ err->pub.format_message(cinfo, nsjpeg_error_buffer);
longjmp(err->setjmp_buffer, 1);
}
@@ -229,9 +242,9 @@ void nsjpeg_destroy(struct content *c)
* Redraw a CONTENT_JPEG.
*/
-void nsjpeg_redraw(struct content *c, long x, long y,
- unsigned long width, unsigned long height,
- long clip_x0, long clip_y0, long clip_x1, long clip_y1,
+void nsjpeg_redraw(struct content *c, int x, int y,
+ int width, int height,
+ int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale)
{
unsigned int tinct_options;
@@ -255,7 +268,7 @@ void nsjpeg_redraw(struct content *c, long x, long y,
_IN(2) | _IN(3) | _IN(4) | _IN(5) | _IN(6) | _IN(7),
(char *) c->data.jpeg.sprite_area +
c->data.jpeg.sprite_area->first,
- x, (int) (y - height),
+ x, y - height,
width, height,
tinct_options);
}
diff --git a/riscos/jpeg.h b/riscos/jpeg.h
index 928ec252f..8db1ba502 100644
--- a/riscos/jpeg.h
+++ b/riscos/jpeg.h
@@ -16,12 +16,12 @@ struct content_jpeg_data {
osspriteop_area *sprite_area;
};
-void nsjpeg_create(struct content *c, const char *params[]);
-int nsjpeg_convert(struct content *c, unsigned int width, unsigned int height);
+bool nsjpeg_create(struct content *c, const char *params[]);
+bool nsjpeg_convert(struct content *c, int width, int height);
void nsjpeg_destroy(struct content *c);
-void nsjpeg_redraw(struct content *c, long x, long y,
- unsigned long width, unsigned long height,
- long clip_x0, long clip_y0, long clip_x1, long clip_y1,
+void nsjpeg_redraw(struct content *c, int x, int y,
+ int width, int height,
+ int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale);
#endif
diff --git a/riscos/png.c b/riscos/png.c
index 2c269c839..b31c992d3 100644
--- a/riscos/png.c
+++ b/riscos/png.c
@@ -32,19 +32,29 @@ static void row_callback(png_structp png, png_bytep new_row,
static void end_callback(png_structp png, png_infop info);
-void nspng_init(void)
+bool nspng_create(struct content *c, const char *params[])
{
-}
-
+ union content_msg_data msg_data;
-void nspng_create(struct content *c, const char *params[])
-{
c->data.png.sprite_area = 0;
c->data.png.png = png_create_read_struct(PNG_LIBPNG_VER_STRING,
0, 0, 0);
- assert(c->data.png.png != 0);
+ if (!c->data.png.png) {
+ msg_data.error = messages_get("NoMemory");
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ warn_user("NoMemory", 0);
+ return false;
+ }
c->data.png.info = png_create_info_struct(c->data.png.png);
- assert(c->data.png.info != 0);
+ if (!c->data.png.info) {
+ png_destroy_read_struct(&c->data.png.png,
+ &c->data.png.info, 0);
+
+ msg_data.error = messages_get("NoMemory");
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ warn_user("NoMemory", 0);
+ return false;
+ }
if (setjmp(png_jmpbuf(c->data.png.png))) {
png_destroy_read_struct(&c->data.png.png,
@@ -52,30 +62,38 @@ void nspng_create(struct content *c, const char *params[])
LOG(("Failed to set callbacks"));
c->data.png.png = NULL;
c->data.png.info = NULL;
- return;
+
+ msg_data.error = messages_get("PNGError");
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ return false;
}
png_set_progressive_read_fn(c->data.png.png, c,
info_callback, row_callback, end_callback);
+
+ return true;
}
-void nspng_process_data(struct content *c, char *data, unsigned long size)
+bool nspng_process_data(struct content *c, char *data, unsigned int size)
{
+ union content_msg_data msg_data;
+
if (setjmp(png_jmpbuf(c->data.png.png))) {
png_destroy_read_struct(&c->data.png.png,
&c->data.png.info, 0);
LOG(("Failed to process data"));
c->data.png.png = NULL;
c->data.png.info = NULL;
- return;
+
+ msg_data.error = messages_get("PNGError");
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ return false;
}
- LOG(("data %p, size %li", data, size));
- png_process_data(c->data.png.png, c->data.png.info,
- data, size);
+ png_process_data(c->data.png.png, c->data.png.info, data, size);
- c->size += size;
+ return true;
}
@@ -224,30 +242,32 @@ void end_callback(png_structp png, png_infop info)
-int nspng_convert(struct content *c, unsigned int width, unsigned int height)
+bool nspng_convert(struct content *c, int width, int height)
{
- if (c->data.png.png == NULL || c->data.png.info == NULL)
- return 1;
+ assert(c->data.png.png);
+ assert(c->data.png.info);
png_destroy_read_struct(&c->data.png.png, &c->data.png.info, 0);
- c->title = xcalloc(100, 1);
- sprintf(c->title, messages_get("PNGTitle"), c->width, c->height);
+ c->title = malloc(100);
+ if (c->title)
+ snprintf(c->title, 100, messages_get("PNGTitle"),
+ c->width, c->height);
c->status = CONTENT_STATUS_DONE;
- return 0;
+ return true;
}
void nspng_destroy(struct content *c)
{
- xfree(c->title);
- xfree(c->data.png.sprite_area);
+ free(c->title);
+ free(c->data.png.sprite_area);
}
-void nspng_redraw(struct content *c, long x, long y,
- unsigned long width, unsigned long height,
- long clip_x0, long clip_y0, long clip_x1, long clip_y1,
+void nspng_redraw(struct content *c, int x, int y,
+ int width, int height,
+ int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale)
{
unsigned int tinct_options;
@@ -269,7 +289,7 @@ void nspng_redraw(struct content *c, long x, long y,
*/
_swix(Tinct_PlotScaledAlpha, _IN(2) | _IN(3) | _IN(4) | _IN(5) | _IN(6) | _IN(7),
((char *) c->data.png.sprite_area + c->data.png.sprite_area->first),
- x, (int)(y - height),
+ x, y - height,
width, height,
tinct_options);
}
diff --git a/riscos/png.h b/riscos/png.h
index ead45d290..49d311efd 100644
--- a/riscos/png.h
+++ b/riscos/png.h
@@ -22,13 +22,12 @@ struct content_png_data {
char *sprite_image;
};
-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);
+bool nspng_create(struct content *c, const char *params[]);
+bool nspng_process_data(struct content *c, char *data, unsigned int size);
+bool nspng_convert(struct content *c, int width, int height);
void nspng_destroy(struct content *c);
-void nspng_redraw(struct content *c, long x, long y,
- unsigned long width, unsigned long height,
- long clip_x0, long clip_y0, long clip_x1, long clip_y1,
+void nspng_redraw(struct content *c, int x, int y,
+ int width, int height,
+ int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale);
#endif
diff --git a/riscos/sprite.c b/riscos/sprite.c
index b7d2bf068..b5c5f64bb 100644
--- a/riscos/sprite.c
+++ b/riscos/sprite.c
@@ -19,74 +19,90 @@
#ifdef WITH_SPRITE
-void sprite_create(struct content *c, const char *params[])
+bool sprite_create(struct content *c, const char *params[])
{
- c->data.sprite.data = xcalloc(4, 1);
+ union content_msg_data msg_data;
+
+ c->data.sprite.data = malloc(4);
+ if (!c->data.sprite.data) {
+ msg_data.error = messages_get("NoMemory");
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ warn_user("NoMemory", 0);
+ return false;
+ }
c->data.sprite.length = 4;
+ return true;
}
-void sprite_process_data(struct content *c, char *data, unsigned long size)
+bool sprite_process_data(struct content *c, char *data, unsigned int size)
{
- c->data.sprite.data = xrealloc(c->data.sprite.data, c->data.sprite.length + size);
- memcpy((char*)(c->data.sprite.data) + c->data.sprite.length, data, size);
+ char *sprite_data;
+ union content_msg_data msg_data;
+
+ sprite_data = realloc(c->data.sprite.data,
+ c->data.sprite.length + size);
+ if (!sprite_data) {
+ msg_data.error = messages_get("NoMemory");
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ warn_user("NoMemory", 0);
+ return false;
+ }
+ c->data.sprite.data = sprite_data;
+ memcpy((char*)(c->data.sprite.data) + c->data.sprite.length,
+ data, size);
c->data.sprite.length += size;
c->size += size;
+ return true;
}
-int sprite_convert(struct content *c, unsigned int width, unsigned int height)
+bool sprite_convert(struct content *c, int width, int height)
{
os_error *error;
int w, h;
+ union content_msg_data msg_data;
osspriteop_area *area = (osspriteop_area*)c->data.sprite.data;
- /* fill in the size (first word) of the area */
+ /* fill in the size (first word) of the area */
area->size = c->data.sprite.length;
error = xosspriteop_read_sprite_info(osspriteop_PTR,
- area,
- (osspriteop_id)((char*)(c->data.sprite.data) + area->first),
- &w, &h, NULL, NULL);
-
- if (error) {
- LOG(("error: %s", error->errmess));
- return 1;
- }
+ area,
+ (osspriteop_id)((char*)(c->data.sprite.data) + area->first),
+ &w, &h, NULL, NULL);
+ if (error) {
+ LOG(("xosspriteop_read_sprite_info: 0x%x: %s",
+ error->errnum, error->errmess));
+ msg_data.error = error->errmess;
+ content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ return false;
+ }
c->width = w;
c->height = h;
- c->title = xcalloc(100, 1);
- sprintf(c->title, messages_get("SpriteTitle"), c->width,
- c->height, c->data.sprite.length);
+ c->title = malloc(100);
+ if (c->title)
+ snprintf(c->title, 100, messages_get("SpriteTitle"), c->width,
+ c->height, c->data.sprite.length);
c->status = CONTENT_STATUS_DONE;
- return 0;
-}
-
-
-void sprite_revive(struct content *c, unsigned int width, unsigned int height)
-{
-}
-
-
-void sprite_reformat(struct content *c, unsigned int width, unsigned int height)
-{
+ return true;
}
void sprite_destroy(struct content *c)
{
- xfree(c->data.sprite.data);
- xfree(c->title);
+ free(c->data.sprite.data);
+ free(c->title);
}
-void sprite_redraw(struct content *c, long x, long y,
- unsigned long width, unsigned long height,
- long clip_x0, long clip_y0, long clip_x1, long clip_y1,
+void sprite_redraw(struct content *c, int x, int y,
+ int width, int height,
+ int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale)
{
- unsigned int size;
+ unsigned int size;
osspriteop_area *area = (osspriteop_area*)c->data.sprite.data;
osspriteop_trans_tab *table;
os_factors factors;
@@ -94,14 +110,14 @@ void sprite_redraw(struct content *c, long x, long y,
xcolourtrans_generate_table_for_sprite(
area,
(osspriteop_id)((char*)(c->data.sprite.data) +
- area->first),
+ area->first),
colourtrans_CURRENT_MODE, colourtrans_CURRENT_PALETTE,
0, colourtrans_GIVEN_SPRITE, 0, 0, &size);
table = xcalloc(size, 1);
xcolourtrans_generate_table_for_sprite(
area,
(osspriteop_id)((char*)(c->data.sprite.data) +
- area->first),
+ area->first),
colourtrans_CURRENT_MODE, colourtrans_CURRENT_PALETTE,
table, colourtrans_GIVEN_SPRITE, 0, 0, 0);
@@ -113,7 +129,7 @@ void sprite_redraw(struct content *c, long x, long y,
xosspriteop_put_sprite_scaled(osspriteop_PTR,
area,
(osspriteop_id)((char*)(c->data.sprite.data) +
- area->first),
+ area->first),
x, (int)(y - height),
osspriteop_USE_MASK | osspriteop_USE_PALETTE, &factors, table);
diff --git a/riscos/sprite.h b/riscos/sprite.h
index 183a5494f..39cf23eb1 100644
--- a/riscos/sprite.h
+++ b/riscos/sprite.h
@@ -17,15 +17,12 @@ struct content_sprite_data {
unsigned long length;
};
-void sprite_init(void);
-void sprite_create(struct content *c, const char *params[]);
-void sprite_process_data(struct content *c, char *data, unsigned long size);
-int sprite_convert(struct content *c, unsigned int width, unsigned int height);
-void sprite_revive(struct content *c, unsigned int width, unsigned int height);
-void sprite_reformat(struct content *c, unsigned int width, unsigned int height);
+bool sprite_create(struct content *c, const char *params[]);
+bool sprite_process_data(struct content *c, char *data, unsigned int size);
+bool sprite_convert(struct content *c, int width, int height);
void sprite_destroy(struct content *c);
-void sprite_redraw(struct content *c, long x, long y,
- unsigned long width, unsigned long height,
- long clip_x0, long clip_y0, long clip_x1, long clip_y1,
+void sprite_redraw(struct content *c, int x, int y,
+ int width, int height,
+ int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale);
#endif
diff --git a/riscos/wimp.c b/riscos/wimp.c
index b5f16e69b..8880232c9 100644
--- a/riscos/wimp.c
+++ b/riscos/wimp.c
@@ -21,6 +21,7 @@
#include "netsurf/desktop/gui.h"
#include "netsurf/riscos/wimp.h"
#include "netsurf/utils/log.h"
+#include "netsurf/utils/utils.h"
/* Wimp_Extend,11 block
*/
diff --git a/utils/utils.h b/utils/utils.h
index b727b7ca8..e606baa6c 100644
--- a/utils/utils.h
+++ b/utils/utils.h
@@ -31,5 +31,6 @@ void regcomp_wrapper(regex_t *preg, const char *regex, int cflags);
void clean_cookiejar(void);
void unicode_transliterate(unsigned int c, char **r);
char *human_friendly_bytesize(unsigned long bytesize);
+void warn_user(const char *warning, const char *detail);
#endif