From 1f07fc6de5ae4e9999efb1fc1cd0f25a27f1bd64 Mon Sep 17 00:00:00 2001 From: James Bursa Date: Sat, 24 Apr 2004 23:42:32 +0000 Subject: [project @ 2004-04-24 23:42:31 by bursa] Replace void pointer in content callbacks with union content_msg_data. Fix animated gif flickering (except for scaled or masked gifs). Add gif to the debug builds. svn path=/import/netsurf/; revision=801 --- content/content.c | 34 ++++++++++++++++++--------------- content/content.h | 35 +++++++++++++++++++++++++-------- content/content_type.h | 6 +++--- content/fetchcache.c | 22 ++++++++++++--------- content/fetchcache.h | 2 +- debug/netsurfd.c | 14 +++++++++++++- desktop/browser.c | 41 ++++++++++++++++----------------------- desktop/gui.h | 3 ++- makefile | 4 ++-- render/box.c | 3 ++- render/html.c | 52 +++++++++++++++++++++++++++++++------------------- riscos/gif.c | 28 ++++++++++++++++++++------- riscos/menus.c | 10 +++++----- riscos/window.c | 45 ++++++++++++++++++++++++++----------------- 14 files changed, 184 insertions(+), 115 deletions(-) diff --git a/content/content.c b/content/content.c index db4fcb406..e8cfade5d 100644 --- a/content/content.c +++ b/content/content.c @@ -58,10 +58,10 @@ static const struct mime_entry mime_map[] = { {"application/x-drawfile", CONTENT_DRAW}, {"image/drawfile", CONTENT_DRAW}, #endif +#endif #ifdef WITH_GIF {"image/gif", CONTENT_GIF}, #endif -#endif #ifdef WITH_JPEG {"image/jpeg", CONTENT_JPEG}, {"image/pjpeg", CONTENT_JPEG}, @@ -118,15 +118,15 @@ static const struct handler_entry handler_map[] = { {nsjpeg_create, 0, nsjpeg_convert, 0, 0, nsjpeg_destroy, nsjpeg_redraw, 0, 0, 0}, #endif +#ifdef WITH_GIF + {nsgif_create, 0, nsgif_convert, 0, + 0, nsgif_destroy, nsgif_redraw, 0, 0, 0}, +#endif #ifdef riscos #ifdef WITH_PNG {nspng_create, nspng_process_data, nspng_convert, 0, 0, nspng_destroy, nspng_redraw, 0, 0, 0}, #endif -#ifdef WITH_GIF - {nsgif_create, 0, nsgif_convert, 0, - 0, nsgif_destroy, nsgif_redraw, 0, 0, 0}, -#endif #ifdef WITH_SPRITE {sprite_create, sprite_process_data, sprite_convert, sprite_revive, sprite_reformat, sprite_destroy, sprite_redraw, 0, 0, 0}, @@ -222,6 +222,7 @@ struct content * content_create(char *url) void content_set_type(struct content *c, content_type type, char* mime_type, const char *params[]) { + union content_msg_data data; assert(c != 0); assert(c->status == CONTENT_STATUS_TYPE_UNKNOWN); assert(type < CONTENT_UNKNOWN); @@ -232,7 +233,7 @@ void content_set_type(struct content *c, content_type type, char* mime_type, c->source_data = xcalloc(0, 1); if (handler_map[type].create) handler_map[type].create(c, params); - content_broadcast(c, CONTENT_MSG_LOADING, 0); + 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 */ } @@ -274,6 +275,7 @@ void content_process_data(struct content *c, char *data, unsigned long size) void content_convert(struct content *c, unsigned long width, unsigned long height) { + union content_msg_data data; assert(c != 0); assert(c->type < HANDLER_MAP_COUNT); assert(c->status == CONTENT_STATUS_LOADING); @@ -282,8 +284,8 @@ void content_convert(struct content *c, unsigned long width, unsigned long heigh if (handler_map[c->type].convert) { if (handler_map[c->type].convert(c, width, height)) { /* convert failed, destroy content */ - content_broadcast(c, CONTENT_MSG_ERROR, - "Conversion failed"); + data.error = "Conversion failed"; + content_broadcast(c, CONTENT_MSG_ERROR, data); if (c->cache) cache_destroy(c); content_destroy(c); @@ -294,9 +296,9 @@ void content_convert(struct content *c, unsigned long width, unsigned long heigh } assert(c->status == CONTENT_STATUS_READY || c->status == CONTENT_STATUS_DONE); - content_broadcast(c, CONTENT_MSG_READY, 0); + content_broadcast(c, CONTENT_MSG_READY, data); if (c->status == CONTENT_STATUS_DONE) - content_broadcast(c, CONTENT_MSG_DONE, 0); + content_broadcast(c, CONTENT_MSG_DONE, data); } @@ -326,13 +328,14 @@ void content_revive(struct content *c, unsigned long width, unsigned long height void content_reformat(struct content *c, unsigned long width, unsigned long height) { + union content_msg_data data; assert(c != 0); assert(c->status == CONTENT_STATUS_READY || c->status == CONTENT_STATUS_DONE); c->available_width = width; if (handler_map[c->type].reformat) { handler_map[c->type].reformat(c, width, height); - content_broadcast(c, CONTENT_MSG_REFORMAT, 0); + content_broadcast(c, CONTENT_MSG_REFORMAT, data); } } @@ -417,7 +420,7 @@ void content_redraw(struct content *c, long x, long y, void content_add_user(struct content *c, void (*callback)(content_msg msg, struct content *c, void *p1, - void *p2, const char *error), + void *p2, union content_msg_data data), void *p1, void *p2) { struct content_user *user; @@ -440,7 +443,7 @@ void content_add_user(struct content *c, void content_remove_user(struct content *c, void (*callback)(content_msg msg, struct content *c, void *p1, - void *p2, const char *error), + void *p2, union content_msg_data data), void *p1, void *p2) { struct content_user *user, *next; @@ -487,14 +490,15 @@ void content_remove_user(struct content *c, * Send a message to all users. */ -void content_broadcast(struct content *c, content_msg msg, char *error) +void content_broadcast(struct content *c, content_msg msg, + union content_msg_data data) { struct content_user *user, *next; c->lock++; for (user = c->user_list->next; user != 0; user = next) { next = user->next; /* user may be destroyed during callback */ if (user->callback != 0) - user->callback(msg, c, user->p1, user->p2, error); + user->callback(msg, c, user->p1, user->p2, data); } if (--(c->lock) == 0 && c->destroy_pending) content_destroy(c); diff --git a/content/content.h b/content/content.h index b865e6b4c..ff7742868 100644 --- a/content/content.h +++ b/content/content.h @@ -37,10 +37,10 @@ #ifdef WITH_JPEG #include "netsurf/riscos/jpeg.h" #endif -#ifdef riscos #ifdef WITH_GIF #include "netsurf/riscos/gif.h" #endif +#ifdef riscos #ifdef WITH_PLUGIN #include "netsurf/riscos/plugin.h" #endif @@ -71,11 +71,29 @@ typedef enum { #endif } content_msg; +/** Extra data for some content_msg messages. */ +union content_msg_data { + const char *error; /**< Error message, for CONTENT_MSG_ERROR. */ + char *redirect; /**< Redirect URL, for CONTENT_MSG_REDIRECT. */ + /** Area of content which needs redrawing, for CONTENT_MSG_REDRAW. */ + struct { + int x, y, width, height; + /** Redraw the area fully. If false, object must be set, + * and only the object will be redrawn. */ + bool full_redraw; + /** Object to redraw if full_redraw is false. */ + struct content *object; + /** Coordinates to plot object at. */ + int object_x, object_y; + } redraw; + char *auth_realm; /**< Realm, for CONTENT_MSG_AUTH. */ +}; + /** Linked list of users of a content. */ struct content_user { void (*callback)(content_msg msg, struct content *c, void *p1, - void *p2, const char *error); + void *p2, union content_msg_data data); void *p1; void *p2; struct content_user *next; @@ -106,13 +124,13 @@ struct content { #ifdef WITH_JPEG struct content_jpeg_data jpeg; #endif +#ifdef WITH_GIF + struct content_gif_data gif; +#endif #ifdef riscos #ifdef WITH_PNG struct content_png_data png; #endif -#ifdef WITH_GIF - struct content_gif_data gif; -#endif #ifdef WITH_SPRITE struct content_sprite_data sprite; #endif @@ -165,13 +183,14 @@ void content_redraw(struct content *c, long x, long y, float scale); void content_add_user(struct content *c, void (*callback)(content_msg msg, struct content *c, void *p1, - void *p2, const char *error), + void *p2, union content_msg_data data), void *p1, void *p2); void content_remove_user(struct content *c, void (*callback)(content_msg msg, struct content *c, void *p1, - void *p2, const char *error), + void *p2, union content_msg_data data), void *p1, void *p2); -void content_broadcast(struct content *c, content_msg msg, char *error); +void content_broadcast(struct content *c, content_msg msg, + union content_msg_data data); void content_add_instance(struct content *c, struct browser_window *bw, struct content *page, struct box *box, struct object_params *params, void **state); diff --git a/content/content_type.h b/content/content_type.h index 96fa70575..66d2faad1 100644 --- a/content/content_type.h +++ b/content/content_type.h @@ -25,13 +25,13 @@ typedef enum { #ifdef WITH_JPEG CONTENT_JPEG, #endif +#ifdef WITH_GIF + CONTENT_GIF, +#endif #ifdef riscos #ifdef WITH_PNG CONTENT_PNG, #endif -#ifdef WITH_GIF - CONTENT_GIF, -#endif #ifdef WITH_SPRITE CONTENT_SPRITE, #endif diff --git a/content/fetchcache.c b/content/fetchcache.c index b87df6a36..c8c10db01 100644 --- a/content/fetchcache.c +++ b/content/fetchcache.c @@ -64,7 +64,7 @@ static void fetchcache_error_page(struct content *c, const char *error); struct content * fetchcache(const char *url, char *referer, void (*callback)(content_msg msg, struct content *c, void *p1, - void *p2, const char *error), + void *p2, union content_msg_data data), void *p1, void *p2, unsigned long width, unsigned long height, bool no_error_pages #ifdef WITH_POST @@ -150,6 +150,7 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size) char *mime_type, *url; char **params; unsigned int i; + union content_msg_data msg_data; c->lock++; @@ -180,7 +181,7 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size) sprintf(c->status_message, messages_get("Received"), c->source_size + size); - content_broadcast(c, CONTENT_MSG_STATUS, 0); + content_broadcast(c, CONTENT_MSG_STATUS, msg_data); content_process_data(c, data, size); break; @@ -189,7 +190,7 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size) sprintf(c->status_message, messages_get("Converting"), c->source_size); c->fetch = 0; - content_broadcast(c, CONTENT_MSG_STATUS, 0); + content_broadcast(c, CONTENT_MSG_STATUS, msg_data); content_convert(c, c->width, c->height); break; @@ -199,7 +200,8 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size) if (c->cache) cache_destroy(c); if (c->no_error_pages) { - content_broadcast(c, CONTENT_MSG_ERROR, data); + msg_data.error = data; + content_broadcast(c, CONTENT_MSG_ERROR, msg_data); content_destroy(c); } else { content_reset(c); @@ -214,11 +216,12 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size) * relative ones: treat them as relative to requested URL */ url = url_join(data, c->url); if (url) { - content_broadcast(c, CONTENT_MSG_REDIRECT, url); - xfree(url); + msg_data.redirect = url; + content_broadcast(c, CONTENT_MSG_REDIRECT, msg_data); + free(url); } else { - content_broadcast(c, CONTENT_MSG_ERROR, - messages_get("BadRedirect")); + msg_data.error = messages_get("BadRedirect"); + content_broadcast(c, CONTENT_MSG_ERROR, msg_data); } if (c->cache) cache_destroy(c); @@ -229,7 +232,8 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size) /* data -> string containing the Realm */ LOG(("FETCH_AUTH, '%s'", data)); c->fetch = 0; - content_broadcast(c, CONTENT_MSG_AUTH, data); + msg_data.auth_realm = data; + content_broadcast(c, CONTENT_MSG_AUTH, msg_data); cache_destroy(c); break; #endif diff --git a/content/fetchcache.h b/content/fetchcache.h index 37d3e1f18..3fadc3459 100644 --- a/content/fetchcache.h +++ b/content/fetchcache.h @@ -25,7 +25,7 @@ struct form_successful_control; struct content * fetchcache(const char *url, char *referer, void (*callback)(content_msg msg, struct content *c, void *p1, - void *p2, const char *error), + void *p2, union content_msg_data data), void *p1, void *p2, unsigned long width, unsigned long height, bool no_error_pages #ifdef WITH_POST diff --git a/debug/netsurfd.c b/debug/netsurfd.c index 60fc9a1a6..ead7c693c 100644 --- a/debug/netsurfd.c +++ b/debug/netsurfd.c @@ -76,7 +76,8 @@ int main(int argc, char *argv[]) cache_dump(); if (!destroyed) { /* content_reformat(c, 1, 1000); */ - save_complete(c, "save_complete"); +/* save_complete(c, "save_complete");*/ + box_dump(c->data.html.layout, 0); content_remove_user(c, callback, 0, 0); } } @@ -251,3 +252,14 @@ void warn_user(const char *warn) printf("WARNING: %s\n", warn); } +#ifndef riscos +void schedule(int t, void (*callback)(void *p), void *p) +{ + printf("UNIMPLEMENTED: schedule(%i, %p, %p)\n", t, callback, p); +} + +void schedule_remove(void (*callback)(void *p), void *p) +{ + printf("UNIMPLEMENTED: schedule_remove(%p, %p)\n", callback, p); +} +#endif diff --git a/desktop/browser.c b/desktop/browser.c index b36be419f..d7fbaac2b 100644 --- a/desktop/browser.c +++ b/desktop/browser.c @@ -37,7 +37,7 @@ static void browser_window_callback(content_msg msg, struct content *c, - void *p1, void *p2, const char *error); + void *p1, void *p2, union content_msg_data data); static void browser_window_convert_to_download(struct browser_window *bw, content_msg msg); static void browser_window_start_throbber(struct browser_window *bw); @@ -48,7 +48,7 @@ static void browser_window_set_status(struct browser_window *bw, const char *text); static void browser_window_set_pointer(gui_pointer_shape shape); static void download_window_callback(content_msg msg, struct content *c, - void *p1, void *p2, const char *error); + void *p1, void *p2, union content_msg_data data); static void browser_window_text_selection(struct browser_window* bw, unsigned long click_x, unsigned long click_y, int click_type); @@ -152,6 +152,7 @@ void browser_window_go_post(struct browser_window *bw, const char *url, { struct content *c; char *url2; + union content_msg_data data; url2 = url_normalize(url); if (!url2) { @@ -185,14 +186,14 @@ void browser_window_go_post(struct browser_window *bw, const char *url, browser_window_start_throbber(bw); if (c->status == CONTENT_STATUS_READY) { - browser_window_callback(CONTENT_MSG_READY, c, bw, 0, 0); + browser_window_callback(CONTENT_MSG_READY, c, bw, 0, data); } else if (c->status == CONTENT_STATUS_DONE) { - browser_window_callback(CONTENT_MSG_READY, c, bw, 0, 0); + browser_window_callback(CONTENT_MSG_READY, c, bw, 0, data); if (c->type == CONTENT_OTHER) - download_window_callback(CONTENT_MSG_DONE, c, bw, 0, 0); + download_window_callback(CONTENT_MSG_DONE, c, bw, 0, data); else - browser_window_callback(CONTENT_MSG_DONE, c, bw, 0, 0); + browser_window_callback(CONTENT_MSG_DONE, c, bw, 0, data); } } @@ -202,10 +203,9 @@ void browser_window_go_post(struct browser_window *bw, const char *url, */ void browser_window_callback(content_msg msg, struct content *c, - void *p1, void *p2, const char *error) + void *p1, void *p2, union content_msg_data data) { struct browser_window *bw = p1; - struct box *box; char status[40]; if (c->type == CONTENT_OTHER) { @@ -259,7 +259,7 @@ void browser_window_callback(content_msg msg, struct content *c, break; case CONTENT_MSG_ERROR: - browser_window_set_status(bw, error); + browser_window_set_status(bw, data.error); if (c == bw->loading_content) bw->loading_content = 0; else if (c == bw->current_content) @@ -275,8 +275,7 @@ void browser_window_callback(content_msg msg, struct content *c, bw->loading_content = 0; browser_window_set_status(bw, messages_get("Redirecting")); - /* error actually holds the new URL */ - browser_window_go(bw, error); + browser_window_go(bw, data.redirect); break; case CONTENT_MSG_REFORMAT: @@ -284,21 +283,12 @@ void browser_window_callback(content_msg msg, struct content *c, break; case CONTENT_MSG_REDRAW: - /* error actually holds the box */ - box = (struct box *) error; - if (box) { - int x, y; - box_coords(box, &x, &y); - gui_window_update_box(bw->window, x, y, - x + box->width, - y + box->height); - } else - gui_window_redraw_window(bw->window); + gui_window_update_box(bw->window, &data); break; #ifdef WITH_AUTH case CONTENT_MSG_AUTH: - gui_401login_open(bw, c, error); + gui_401login_open(bw, c, data.auth_realm); if (c == bw->loading_content) bw->loading_content = 0; else if (c == bw->current_content) @@ -322,6 +312,7 @@ void browser_window_convert_to_download(struct browser_window *bw, { gui_window *download_window; struct content *c = bw->loading_content; + union content_msg_data data; assert(c); /* create download window and add content to it */ @@ -330,7 +321,7 @@ void browser_window_convert_to_download(struct browser_window *bw, if (msg == CONTENT_MSG_DONE) download_window_callback(CONTENT_MSG_DONE, c, download_window, - 0, 0); + 0, data); /* remove content from browser window */ bw->loading_content = 0; @@ -475,7 +466,7 @@ void browser_window_destroy(struct browser_window *bw) */ void download_window_callback(content_msg msg, struct content *c, - void *p1, void *p2, const char *error) + void *p1, void *p2, union content_msg_data data) { gui_window *download_window = p1; @@ -489,7 +480,7 @@ void download_window_callback(content_msg msg, struct content *c, break; case CONTENT_MSG_ERROR: - gui_download_window_error(download_window, error); + gui_download_window_error(download_window, data.error); break; case CONTENT_MSG_READY: diff --git a/desktop/gui.h b/desktop/gui.h index 95b18083f..8b23e81b3 100644 --- a/desktop/gui.h +++ b/desktop/gui.h @@ -21,6 +21,7 @@ typedef enum { GUI_POINTER_DEFAULT, GUI_POINTER_POINT, GUI_POINTER_CARET, GUI_POINTER_MOVE } gui_pointer_shape; #include +#include "netsurf/content/content.h" #include "netsurf/desktop/browser.h" bool gui_window_in_list(gui_window *g); @@ -32,7 +33,7 @@ void gui_window_hide(gui_window* g); void gui_window_redraw(gui_window* g, unsigned long x0, unsigned long y0, unsigned long x1, unsigned long y1); void gui_window_redraw_window(gui_window* g); -void gui_window_update_box(gui_window *g, int x0, int y0, int x1, int y1); +void gui_window_update_box(gui_window *g, const union content_msg_data *data); void gui_window_set_scroll(gui_window* g, unsigned long sx, unsigned long sy); unsigned long gui_window_get_width(gui_window* g); void gui_window_set_extent(gui_window* g, unsigned long width, unsigned long height); diff --git a/makefile b/makefile index 1832b9457..846a5ded1 100644 --- a/makefile +++ b/makefile @@ -10,14 +10,14 @@ OBJECTS_COMMON = cache.o content.o fetch.o fetchcache.o \ css.o css_enum.o parser.o ruleset.o scanner.o \ box.o form.o html.o layout.o textplain.o \ messages.o utils.o translit.o pool.o url.o imagemap.o \ - jpeg.o save_complete.o loginlist.o + jpeg.o save_complete.o loginlist.o gif.o gifread.o OBJECTS = $(OBJECTS_COMMON) \ browser.o netsurf.o options.o \ htmlinstance.o htmlredraw.o \ 401login.o constdata.o dialog.o download.o frames.o gui.o \ menus.o mouseactions.o \ textselection.o theme.o window.o \ - draw.o gif.o gifread.o plugin.o png.o sprite.o \ + draw.o plugin.o png.o sprite.o \ about.o filetype.o font.o uri.o url_protocol.o history.o \ version.o thumbnail.o \ save.o save_draw.o save_text.o schedule.o diff --git a/render/box.c b/render/box.c index 3e2443ee8..c7edf9e7e 100644 --- a/render/box.c +++ b/render/box.c @@ -765,8 +765,9 @@ struct result box_br(xmlNode *n, struct status *status, } static const content_type image_types[] = { + CONTENT_JPEG, CONTENT_GIF, #ifdef riscos - CONTENT_JPEG, CONTENT_PNG, CONTENT_GIF, CONTENT_SPRITE, CONTENT_DRAW, + CONTENT_PNG, CONTENT_SPRITE, CONTENT_DRAW, #endif CONTENT_UNKNOWN }; diff --git a/render/html.c b/render/html.c index c3a9b87b4..9047e661f 100644 --- a/render/html.c +++ b/render/html.c @@ -33,11 +33,11 @@ static void html_convert_css_callback(content_msg msg, struct content *css, - void *p1, void *p2, const char *error); + void *p1, void *p2, union content_msg_data data); static void html_head(struct content *c, xmlNode *head); static void html_find_stylesheets(struct content *c, xmlNode *head); static void html_object_callback(content_msg msg, struct content *object, - void *p1, void *p2, const char *error); + void *p1, void *p2, union content_msg_data data); static bool html_object_type_permitted(const content_type type, const content_type *permitted_types); @@ -136,6 +136,7 @@ int html_convert(struct content *c, unsigned int width, unsigned int height) { xmlDoc *document; xmlNode *html, *head; + union content_msg_data data; /* finish parsing */ htmlParseChunk(c->data.html.parser, "", 0, 1); @@ -176,7 +177,7 @@ int html_convert(struct content *c, unsigned int width, unsigned int height) /* convert xml tree to box tree */ LOG(("XML to box")); sprintf(c->status_message, messages_get("Processing")); - content_broadcast(c, CONTENT_MSG_STATUS, 0); + content_broadcast(c, CONTENT_MSG_STATUS, data); xml_to_box(html, c); /*box_dump(c->data.html.layout->children, 0);*/ @@ -189,7 +190,7 @@ int html_convert(struct content *c, unsigned int width, unsigned int height) /* layout the box tree */ sprintf(c->status_message, messages_get("Formatting")); - content_broadcast(c, CONTENT_MSG_STATUS, 0); + content_broadcast(c, CONTENT_MSG_STATUS, data); LOG(("Layout document")); layout_document(c->data.html.layout->children, width); /*box_dump(c->data.html.layout->children, 0);*/ @@ -262,6 +263,7 @@ void html_find_stylesheets(struct content *c, xmlNode *head) char *rel, *type, *media, *href, *data, *url; unsigned int i = 2; unsigned int last_active = 0; + union content_msg_data msg_data; /* stylesheet 0 is the base style sheet, stylesheet 1 is any