summaryrefslogtreecommitdiff
path: root/image/mng.c
diff options
context:
space:
mode:
Diffstat (limited to 'image/mng.c')
-rw-r--r--image/mng.c430
1 files changed, 316 insertions, 114 deletions
diff --git a/image/mng.c b/image/mng.c
index 6067aa8e8..a6b0377c4 100644
--- a/image/mng.c
+++ b/image/mng.c
@@ -23,9 +23,6 @@
#include "utils/config.h"
#ifdef WITH_MNG
-/* This must come first due to libpng issues */
-#include "content/content_protected.h"
-
#include <assert.h>
#include <stdbool.h>
#include <string.h>
@@ -33,6 +30,7 @@
#include <sys/time.h>
#include <time.h>
#include <libmng.h>
+#include "content/content_protected.h"
#include "desktop/options.h"
#include "desktop/plotters.h"
#include "image/bitmap.h"
@@ -40,12 +38,44 @@
#include "utils/log.h"
#include "utils/messages.h"
#include "utils/schedule.h"
+#include "utils/talloc.h"
#include "utils/utils.h"
/* We do not currently support any form of colour/gamma correction, nor do
we support dynamic MNGs.
*/
+typedef struct nsmng_content
+{
+ struct content base;
+
+ bool opaque_test_pending;
+ bool read_start;
+ bool read_resume;
+ int read_size;
+ bool waiting;
+ bool displayed;
+ void *handle;
+} nsmng_content;
+
+static nserror nsmng_create(const content_handler *handler,
+ lwc_string *imime_type, const struct http_parameter *params,
+ llcache_handle *llcache, const char *fallback_charset,
+ bool quirks, struct content **c);
+static nserror nsmng_create_mng_data(nsmng_content *c);
+static bool nsmng_process_data(struct content *c, const char *data,
+ unsigned int size);
+static bool nsmng_convert(struct content *c);
+static void nsmng_destroy(struct content *c);
+static bool nsmng_redraw(struct content *c, int x, int y,
+ int width, int height, const struct rect *clip,
+ float scale, colour background_colour);
+static bool nsmng_redraw_tiled(struct content *c, int x, int y,
+ int width, int height, const struct rect *clip,
+ float scale, colour background_colour,
+ bool repeat_x, bool repeat_y);
+static nserror nsmng_clone(const struct content *old, struct content **newc);
+static content_type nsmng_content_type(lwc_string *mime_type);
static mng_bool nsmng_openstream(mng_handle mng);
static mng_bool nsmng_readdata(mng_handle mng, mng_ptr buffer,
@@ -59,7 +89,7 @@ static mng_bool nsmng_refresh(mng_handle mng, mng_uint32 x, mng_uint32 y,
mng_uint32 w, mng_uint32 h);
static mng_bool nsmng_settimer(mng_handle mng, mng_uint32 msecs);
static void nsmng_animate(void *p);
-static bool nsmng_broadcast_error(struct content *c, mng_retcode code);
+static nserror nsmng_broadcast_error(nsmng_content *c, mng_retcode code);
static mng_bool nsmng_errorproc(mng_handle mng, mng_int32 code,
mng_int8 severity, mng_chunkid chunktype, mng_uint32 chunkseq,
mng_int32 extra1, mng_int32 extra2, mng_pchar text);
@@ -68,8 +98,131 @@ static mng_ptr nsmng_alloc(mng_size_t n);
static void nsmng_free(mng_ptr p, mng_size_t n);
#endif
+static const content_handler nsmng_content_handler = {
+ nsmng_create,
+ nsmng_process_data,
+ nsmng_convert,
+ NULL,
+ nsmng_destroy,
+ NULL,
+ NULL,
+ NULL,
+ nsmng_redraw,
+ nsmng_redraw_tiled,
+ NULL,
+ NULL,
+ nsmng_clone,
+ NULL,
+ nsmng_content_type,
+ false
+};
+
+static const char *jng_types[] = {
+ "image/jng",
+ "image/x-jng"
+};
+
+static const char *mng_types[] = {
+ "image/mng",
+ "image/x-mng",
+ "video/mng",
+ "video/x-mng"
+};
+
+static const char *png_types[] = {
+ "image/png"
+};
+
+static lwc_string *jng_mime_types[NOF_ELEMENTS(jng_types)];
+static lwc_string *mng_mime_types[NOF_ELEMENTS(mng_types)];
+static lwc_string *png_mime_types[NOF_ELEMENTS(png_types)];
+
+nserror nsmng_init(void)
+{
+ uint32_t i;
+ lwc_error lerror;
+ nserror error;
+
+#define register_types(type) \
+ for (i = 0; i < NOF_ELEMENTS(type##_mime_types); i++) { \
+ lerror = lwc_intern_string(type##_types[i], \
+ strlen(type##_types[i]), \
+ &type##_mime_types[i]); \
+ if (lerror != lwc_error_ok) { \
+ error = NSERROR_NOMEM; \
+ goto error; \
+ } \
+ \
+ error = content_factory_register_handler( \
+ type##_mime_types[i], \
+ &nsmng_content_handler); \
+ if (error != NSERROR_OK) \
+ goto error; \
+ }
+
+ register_types(jng)
+ register_types(mng)
+ register_types(png)
+
+ return NSERROR_OK;
+
+error:
+ nsmng_fini();
+
+ return error;
+}
+
+void nsmng_fini(void)
+{
+ uint32_t i;
+
+ for (i = 0; i < NOF_ELEMENTS(jng_mime_types); i++) {
+ if (jng_mime_types[i] != NULL)
+ lwc_string_unref(jng_mime_types[i]);
+ }
+
+ for (i = 0; i < NOF_ELEMENTS(mng_mime_types); i++) {
+ if (mng_mime_types[i] != NULL)
+ lwc_string_unref(mng_mime_types[i]);
+ }
+
+ for (i = 0; i < NOF_ELEMENTS(png_mime_types); i++) {
+ if (png_mime_types[i] != NULL)
+ lwc_string_unref(png_mime_types[i]);
+ }
+}
+
+nserror nsmng_create(const content_handler *handler,
+ lwc_string *imime_type, const struct http_parameter *params,
+ llcache_handle *llcache, const char *fallback_charset,
+ bool quirks, struct content **c)
+{
+ nsmng_content *mng;
+ nserror error;
+
+ mng = talloc_zero(0, nsmng_content);
+ if (mng == NULL)
+ return NSERROR_NOMEM;
+
+ error = content__init(&mng->base, handler, imime_type, params,
+ llcache, fallback_charset, quirks);
+ if (error != NSERROR_OK) {
+ talloc_free(mng);
+ return error;
+ }
+
+ error = nsmng_create_mng_data(mng);
+ if (error != NSERROR_OK) {
+ talloc_free(mng);
+ return error;
+ }
+
+ *c = (struct content *) mng;
-bool nsmng_create(struct content *c, const struct http_parameter *params)
+ return NSERROR_OK;
+}
+
+nserror nsmng_create_mng_data(nsmng_content *c)
{
mng_retcode code;
union content_msg_data msg_data;
@@ -79,20 +232,20 @@ bool nsmng_create(struct content *c, const struct http_parameter *params)
/* Initialise the library
*/
#ifdef MNG_INTERNAL_MEMMNGMT
- c->data.mng.handle = mng_initialize(c, MNG_NULL, MNG_NULL, MNG_NULL);
+ c->handle = mng_initialize(c, MNG_NULL, MNG_NULL, MNG_NULL);
#else
- c->data.mng.handle = mng_initialize(c, nsmng_alloc, nsmng_free, MNG_NULL);
+ c->handle = mng_initialize(c, nsmng_alloc, nsmng_free, MNG_NULL);
#endif
- if (c->data.mng.handle == MNG_NULL) {
+ if (c->handle == MNG_NULL) {
LOG(("Unable to initialise MNG library."));
msg_data.error = messages_get("NoMemory");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
- return false;
+ content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data);
+ return NSERROR_NOMEM;
}
/* We need to decode in suspension mode
*/
- code = mng_set_suspensionmode(c->data.mng.handle, MNG_TRUE);
+ code = mng_set_suspensionmode(c->handle, MNG_TRUE);
if (code) {
LOG(("Unable to set suspension mode."));
return nsmng_broadcast_error(c, code);
@@ -100,22 +253,22 @@ bool nsmng_create(struct content *c, const struct http_parameter *params)
/* We need to register our callbacks
*/
- code = mng_setcb_openstream(c->data.mng.handle, nsmng_openstream);
+ code = mng_setcb_openstream(c->handle, nsmng_openstream);
if (code) {
LOG(("Unable to set openstream callback."));
return nsmng_broadcast_error(c, code);
}
- code = mng_setcb_readdata(c->data.mng.handle, nsmng_readdata);
+ code = mng_setcb_readdata(c->handle, nsmng_readdata);
if (code) {
LOG(("Unable to set readdata callback."));
return nsmng_broadcast_error(c, code);
}
- code = mng_setcb_closestream(c->data.mng.handle, nsmng_closestream);
+ code = mng_setcb_closestream(c->handle, nsmng_closestream);
if (code) {
LOG(("Unable to set closestream callback."));
return nsmng_broadcast_error(c, code);
}
- code = mng_setcb_processheader(c->data.mng.handle, nsmng_processheader);
+ code = mng_setcb_processheader(c->handle, nsmng_processheader);
if (code) {
LOG(("Unable to set processheader callback."));
return nsmng_broadcast_error(c, code);
@@ -123,29 +276,29 @@ bool nsmng_create(struct content *c, const struct http_parameter *params)
/* Register our callbacks for displaying
*/
- code = mng_setcb_getcanvasline(c->data.mng.handle, nsmng_getcanvasline);
+ code = mng_setcb_getcanvasline(c->handle, nsmng_getcanvasline);
if (code) {
LOG(("Unable to set getcanvasline callback."));
return nsmng_broadcast_error(c, code);
}
- code = mng_setcb_refresh(c->data.mng.handle, nsmng_refresh);
+ code = mng_setcb_refresh(c->handle, nsmng_refresh);
if (code) {
LOG(("Unable to set refresh callback."));
return nsmng_broadcast_error(c, code);
}
- code = mng_setcb_gettickcount(c->data.mng.handle, nsmng_gettickcount);
+ code = mng_setcb_gettickcount(c->handle, nsmng_gettickcount);
if (code) {
LOG(("Unable to set gettickcount callback."));
return nsmng_broadcast_error(c, code);
}
- code = mng_setcb_settimer(c->data.mng.handle, nsmng_settimer);
+ code = mng_setcb_settimer(c->handle, nsmng_settimer);
if (code) {
LOG(("Unable to set settimer callback."));
return nsmng_broadcast_error(c, code);
}
/* register error handling function */
- code = mng_setcb_errorproc(c->data.mng.handle, nsmng_errorproc);
+ code = mng_setcb_errorproc(c->handle, nsmng_errorproc);
if (code) {
LOG(("Unable to set errorproc"));
return nsmng_broadcast_error(c, code);
@@ -153,13 +306,14 @@ bool nsmng_create(struct content *c, const struct http_parameter *params)
/* Initialise the reading
*/
- c->data.mng.read_start = true;
- c->data.mng.read_resume = false;
- c->data.mng.read_size = 0;
- c->data.mng.waiting = false;
+ c->read_start = true;
+ c->read_resume = false;
+ c->read_size = 0;
+ c->waiting = false;
- c->data.mng.displayed = false;
- return true;
+ c->displayed = false;
+
+ return NSERROR_OK;
}
@@ -176,7 +330,7 @@ mng_bool nsmng_openstream(mng_handle mng)
mng_bool nsmng_readdata(mng_handle mng, mng_ptr buffer, mng_uint32 size,
mng_uint32 *bytesread)
{
- struct content *c;
+ nsmng_content *c;
const char *data;
unsigned long data_size;
@@ -186,19 +340,19 @@ mng_bool nsmng_readdata(mng_handle mng, mng_ptr buffer, mng_uint32 size,
/* Get our content back
*/
- c = (struct content *) mng_get_userdata(mng);
+ c = (nsmng_content *) mng_get_userdata(mng);
assert(c != NULL);
/* Copy any data we have (maximum of 'size')
*/
- data = content__get_source_data(c, &data_size);
+ data = content__get_source_data(&c->base, &data_size);
- *bytesread = ((data_size - c->data.mng.read_size) < size) ?
- (data_size - c->data.mng.read_size) : size;
+ *bytesread = ((data_size - c->read_size) < size) ?
+ (data_size - c->read_size) : size;
if ((*bytesread) > 0) {
- memcpy(buffer, data + c->data.mng.read_size, *bytesread);
- c->data.mng.read_size += *bytesread;
+ memcpy(buffer, data + c->read_size, *bytesread);
+ c->read_size += *bytesread;
}
/* Return success
@@ -215,7 +369,7 @@ mng_bool nsmng_closestream(mng_handle mng)
mng_bool nsmng_processheader(mng_handle mng, mng_uint32 width,
mng_uint32 height)
{
- struct content *c;
+ nsmng_content *c;
union content_msg_data msg_data;
uint8_t *buffer;
@@ -224,31 +378,31 @@ mng_bool nsmng_processheader(mng_handle mng, mng_uint32 width,
/* This function is called when the header has been read and we
know the dimensions of the canvas.
*/
- c = (struct content *)mng_get_userdata(mng);
+ c = (nsmng_content *) mng_get_userdata(mng);
assert(c != NULL);
- c->bitmap = bitmap_create(width, height, BITMAP_NEW);
- if (!c->bitmap) {
+ c->base.bitmap = bitmap_create(width, height, BITMAP_NEW);
+ if (c->base.bitmap == NULL) {
msg_data.error = messages_get("NoMemory");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data);
LOG(("Insufficient memory to create canvas."));
return MNG_FALSE;
}
/* Get the buffer to ensure that it is allocated and the calls in
* nsmng_getcanvasline() succeed. */
- buffer = bitmap_get_buffer(c->bitmap);
- if (!buffer) {
+ buffer = bitmap_get_buffer(c->base.bitmap);
+ if (buffer == NULL) {
msg_data.error = messages_get("NoMemory");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
+ content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data);
LOG(("Insufficient memory to create canvas."));
return MNG_FALSE;
}
/* Initialise the content size
*/
- c->width = width;
- c->height = height;
+ c->base.width = width;
+ c->base.height = height;
/* Set the canvas style
*/
@@ -268,6 +422,7 @@ mng_bool nsmng_processheader(mng_handle mng, mng_uint32 width,
bool nsmng_process_data(struct content *c, const char *data, unsigned int size)
{
+ nsmng_content *mng = (nsmng_content *) c;
mng_retcode status;
assert(c != NULL);
@@ -275,21 +430,21 @@ bool nsmng_process_data(struct content *c, const char *data, unsigned int size)
/* We only need to do any processing if we're starting/resuming reading.
*/
- if ((!c->data.mng.read_resume) && (!c->data.mng.read_start))
+ if ((!mng->read_resume) && (!mng->read_start))
return true;
/* Try to start processing, or process some more data
*/
- if (c->data.mng.read_start) {
- status = mng_read(c->data.mng.handle);
- c->data.mng.read_start = false;
+ if (mng->read_start) {
+ status = mng_read(mng->handle);
+ mng->read_start = false;
} else {
- status = mng_read_resume(c->data.mng.handle);
+ status = mng_read_resume(mng->handle);
}
- c->data.mng.read_resume = (status == MNG_NEEDMOREDATA);
+ mng->read_resume = (status == MNG_NEEDMOREDATA);
if ((status != MNG_NOERROR) && (status != MNG_NEEDMOREDATA)) {
LOG(("Failed to start/continue reading (%i).", status));
- return nsmng_broadcast_error(c, status);
+ return nsmng_broadcast_error(mng, status) == NSERROR_OK;
}
/* Continue onwards
@@ -300,9 +455,14 @@ bool nsmng_process_data(struct content *c, const char *data, unsigned int size)
bool nsmng_convert(struct content *c)
{
+ nsmng_content *mng = (nsmng_content *) c;
mng_retcode status;
const char *data;
unsigned long size;
+ lwc_string *content_type;
+ bool match;
+ bool is_mng = false;
+ uint32_t i;
char title[100];
assert(c != NULL);
@@ -312,15 +472,26 @@ bool nsmng_convert(struct content *c)
/* by this point, the png should have been parsed
* and the bitmap created, so ensure that's the case
*/
- if (!c->bitmap)
- return nsmng_broadcast_error(c, -1);
+ if (content__get_bitmap(c) == NULL)
+ return nsmng_broadcast_error(mng, -1) == NSERROR_OK;
/* Set the title
*/
- if (c->type == CONTENT_MNG) {
+ content_type = content__get_mime_type(c);
+
+ for (i = 0; i < NOF_ELEMENTS(mng_mime_types); i++) {
+ if (lwc_string_caseless_isequal(content_type, mng_mime_types[i],
+ &match) == lwc_error_ok && match) {
+ is_mng = true;
+ break;
+ }
+ }
+
+ if (is_mng) {
snprintf(title, sizeof(title), messages_get("MNGTitle"),
c->width, c->height, size);
- } else if (c->type == CONTENT_PNG) {
+ } else if (lwc_string_caseless_isequal(content_type, png_mime_types[0],
+ &match) == lwc_error_ok && match) {
snprintf(title, sizeof(title), messages_get("PNGTitle"),
c->width, c->height, size);
} else {
@@ -329,6 +500,8 @@ bool nsmng_convert(struct content *c)
}
content__set_title(c, title);
+ lwc_string_unref(content_type);
+
c->size += c->width * c->height * 4;
content_set_ready(c);
content_set_done(c);
@@ -349,28 +522,27 @@ bool nsmng_convert(struct content *c)
*/
/* Start displaying
*/
- status = mng_display(c->data.mng.handle);
+ status = mng_display(mng->handle);
if ((status != MNG_NOERROR) && (status != MNG_NEEDTIMERWAIT)) {
LOG(("Unable to start display (%i)", status));
- return nsmng_broadcast_error(c, status);
+ return nsmng_broadcast_error(mng, status) == NSERROR_OK;
}
bitmap_modified(c->bitmap);
/* Optimise the plotting of JNG/PNGs
*/
- c->data.mng.opaque_test_pending = (c->type == CONTENT_PNG) ||
- (c->type == CONTENT_JNG);
- if (c->data.mng.opaque_test_pending)
+ mng->opaque_test_pending = (is_mng == false);
+ if (mng->opaque_test_pending)
bitmap_set_opaque(c->bitmap, false);
/* free associated memory except for mngs where it may be subsequently needed for
* animation decoding. */
- if (c->type != CONTENT_MNG) {
- mng_handle handle = c->data.mng.handle;
+ if (is_mng == false) {
+ mng_handle handle = mng->handle;
mng_cleanup(&handle);
- c->data.mng.handle = NULL;
+ mng->handle = NULL;
}
return true;
@@ -383,19 +555,19 @@ bool nsmng_convert(struct content *c)
mng_ptr nsmng_getcanvasline(mng_handle mng, mng_uint32 line)
{
- struct content *c;
+ nsmng_content *c;
assert(mng != NULL);
/* Get our content back
*/
- c = (struct content *)mng_get_userdata(mng);
+ c = (nsmng_content *) mng_get_userdata(mng);
assert(c != NULL);
/* Calculate the address
*/
- return bitmap_get_buffer(c->bitmap) +
- bitmap_get_rowstride(c->bitmap) * line;
+ return bitmap_get_buffer(c->base.bitmap) +
+ bitmap_get_rowstride(c->base.bitmap) * line;
}
@@ -433,13 +605,13 @@ mng_bool nsmng_refresh(mng_handle mng, mng_uint32 x, mng_uint32 y,
mng_uint32 w, mng_uint32 h)
{
union content_msg_data data;
- struct content *c;
+ nsmng_content *c;
assert(mng != NULL);
/* Get our content back
*/
- c = (struct content *)mng_get_userdata(mng);
+ c = (nsmng_content *) mng_get_userdata(mng);
assert(c != NULL);
/* Set the minimum redraw area
@@ -463,11 +635,11 @@ mng_bool nsmng_refresh(mng_handle mng, mng_uint32 x, mng_uint32 y,
/* Set the object characteristics
*/
- data.redraw.object = c;
+ data.redraw.object = &c->base;
data.redraw.object_x = 0;
data.redraw.object_y = 0;
- data.redraw.object_width = c->width;
- data.redraw.object_height = c->height;
+ data.redraw.object_width = c->base.width;
+ data.redraw.object_height = c->base.height;
/* Only attempt to force the redraw if we've been requested to
* display the image in the first place (i.e. nsmng_redraw has
@@ -475,21 +647,21 @@ mng_bool nsmng_refresh(mng_handle mng, mng_uint32 x, mng_uint32 y,
* an image that shouldn't be shown (e.g. if the image is a fallback
* for an object that can't be rendered)
*/
- if (c->data.mng.displayed)
- content_broadcast(c, CONTENT_MSG_REDRAW, data);
+ if (c->displayed)
+ content_broadcast(&c->base, CONTENT_MSG_REDRAW, data);
return MNG_TRUE;
}
mng_bool nsmng_settimer(mng_handle mng, mng_uint32 msecs)
{
- struct content *c;
+ nsmng_content *c;
assert(mng != NULL);
/* Get our content back
*/
- c = (struct content *)mng_get_userdata(mng);
+ c = (nsmng_content *) mng_get_userdata(mng);
assert(c != NULL);
/* Perform the scheduling
@@ -505,18 +677,20 @@ mng_bool nsmng_settimer(mng_handle mng, mng_uint32 msecs)
void nsmng_destroy(struct content *c)
{
+ nsmng_content *mng = (nsmng_content *) c;
assert (c != NULL);
/* Cleanup the MNG structure and release the canvas memory
*/
schedule_remove(nsmng_animate, c);
- if (c->type == CONTENT_MNG) {
- mng_handle handle = c->data.mng.handle;
+
+ if (mng->handle != NULL) {
+ mng_handle handle = mng->handle;
mng_cleanup(&handle);
- c->data.mng.handle = NULL;
+ mng->handle = NULL;
}
if (c->bitmap)
@@ -528,14 +702,15 @@ bool nsmng_redraw(struct content *c, int x, int y,
int width, int height, const struct rect *clip,
float scale, colour background_colour)
{
+ nsmng_content *mng = (nsmng_content *) c;
bool ret;
/* mark image as having been requested to display */
- c->data.mng.displayed = true;
+ mng->displayed = true;
- if ((c->bitmap) && (c->data.mng.opaque_test_pending)) {
+ if ((c->bitmap) && (mng->opaque_test_pending)) {
bitmap_set_opaque(c->bitmap, bitmap_test_opaque(c->bitmap));
- c->data.mng.opaque_test_pending = false;
+ mng->opaque_test_pending = false;
}
ret = plot.bitmap(x, y, width, height,
@@ -543,7 +718,7 @@ bool nsmng_redraw(struct content *c, int x, int y,
/* Check if we need to restart the animation
*/
- if ((c->data.mng.waiting) && (option_animate_images))
+ if ((mng->waiting) && (option_animate_images))
nsmng_animate(c);
return ret;
@@ -555,15 +730,16 @@ bool nsmng_redraw_tiled(struct content *c, int x, int y,
float scale, colour background_colour,
bool repeat_x, bool repeat_y)
{
+ nsmng_content *mng = (nsmng_content *) c;
bool ret;
bitmap_flags_t flags = BITMAPF_NONE;
/* mark image as having been requested to display */
- c->data.mng.displayed = true;
+ mng->displayed = true;
- if ((c->bitmap) && (c->data.mng.opaque_test_pending)) {
+ if ((c->bitmap) && (mng->opaque_test_pending)) {
bitmap_set_opaque(c->bitmap, bitmap_test_opaque(c->bitmap));
- c->data.mng.opaque_test_pending = false;
+ mng->opaque_test_pending = false;
}
if (repeat_x)
@@ -577,35 +753,61 @@ bool nsmng_redraw_tiled(struct content *c, int x, int y,
/* Check if we need to restart the animation
*/
- if ((c->data.mng.waiting) && (option_animate_images))
+ if ((mng->waiting) && (option_animate_images))
nsmng_animate(c);
return ret;
}
-bool nsmng_clone(const struct content *old, struct content *new_content)
+nserror nsmng_clone(const struct content *old, struct content **newc)
{
+ nsmng_content *mng;
+ nserror error;
const char *data;
unsigned long size;
+ mng = talloc_zero(0, nsmng_content);
+ if (mng == NULL)
+ return NSERROR_NOMEM;
+
+ error = content__clone(old, &mng->base);
+ if (error != NSERROR_OK) {
+ content_destroy(&mng->base);
+ return error;
+ }
+
/* Simply replay create/process/convert */
- if (nsmng_create(new_content, NULL) == false)
- return false;
+ error = nsmng_create_mng_data(mng);
+ if (error != NSERROR_OK) {
+ content_destroy(&mng->base);
+ return error;
+ }
- data = content__get_source_data(new_content, &size);
+ data = content__get_source_data(&mng->base, &size);
if (size > 0) {
- if (nsmng_process_data(new_content, data, size) == false)
- return false;
+ if (nsmng_process_data(&mng->base, data, size) == false) {
+ content_destroy(&mng->base);
+ return NSERROR_CLONE_FAILED;
+ }
}
if (old->status == CONTENT_STATUS_READY ||
old->status == CONTENT_STATUS_DONE) {
- if (nsmng_convert(new_content) == false)
- return false;
+ if (nsmng_convert(&mng->base) == false) {
+ content_destroy(&mng->base);
+ return NSERROR_CLONE_FAILED;
+ }
}
- return true;
+ *newc = (struct content *) mng;
+
+ return NSERROR_OK;
+}
+
+content_type nsmng_content_type(lwc_string *mime_type)
+{
+ return CONTENT_IMAGE;
}
/**
@@ -613,22 +815,22 @@ bool nsmng_clone(const struct content *old, struct content *new_content)
*/
void nsmng_animate(void *p)
{
- struct content *c;
+ nsmng_content *c;
assert(p != NULL);
- c = (struct content *)p;
+ c = (nsmng_content *) p;
/* If we used the last animation we advance, if not we try again later
*/
- if (c->user_list->next == NULL) {
- c->data.mng.waiting = true;
+ if (c->base.user_list->next == NULL) {
+ c->waiting = true;
} else {
- c->data.mng.waiting = false;
- mng_display_resume(c->data.mng.handle);
- c->data.mng.opaque_test_pending = true;
- if (c->bitmap)
- bitmap_modified(c->bitmap);
+ c->waiting = false;
+ mng_display_resume(c->handle);
+ c->opaque_test_pending = true;
+ if (c->base.bitmap)
+ bitmap_modified(c->base.bitmap);
}
}
@@ -638,9 +840,9 @@ void nsmng_animate(void *p)
* Broadcasts an error message and returns false
*
* \param c the content to broadcast for
- * \return false
+ * \return Appropriate error
*/
-bool nsmng_broadcast_error(struct content *c, mng_retcode code)
+nserror nsmng_broadcast_error(nsmng_content *c, mng_retcode code)
{
union content_msg_data msg_data;
char error[100];
@@ -649,14 +851,14 @@ bool nsmng_broadcast_error(struct content *c, mng_retcode code)
if (code == MNG_OUTOFMEMORY) {
msg_data.error = messages_get("NoMemory");
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
- return false;
+ content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data);
+ return NSERROR_NOMEM;
}
snprintf(error, sizeof error, messages_get("MNGError"), code);
msg_data.error = error;
- content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
- return false;
+ content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data);
+ return NSERROR_MNG_ERROR;
}
@@ -664,12 +866,12 @@ mng_bool nsmng_errorproc(mng_handle mng, mng_int32 code,
mng_int8 severity, mng_chunkid chunktype, mng_uint32 chunkseq,
mng_int32 extra1, mng_int32 extra2, mng_pchar text)
{
- struct content *c;
+ nsmng_content *c;
char chunk[5];
assert(mng != NULL);
- c = (struct content *)mng_get_userdata(mng);
+ c = (nsmng_content *) mng_get_userdata(mng);
assert(c != NULL);
chunk[0] = (char)((chunktype >> 24) & 0xFF);
@@ -679,11 +881,11 @@ mng_bool nsmng_errorproc(mng_handle mng, mng_int32 code,
chunk[4] = '\0';
LOG(("error playing '%s' chunk %s (%d):",
- content__get_url(c), chunk, chunkseq));
+ content__get_url(&c->base), chunk, chunkseq));
LOG(("code %d severity %d extra1 %d extra2 %d text:'%s'", code,
severity, extra1, extra2, text));
- return (0);
+ return (0);
}