summaryrefslogtreecommitdiff
path: root/content
diff options
context:
space:
mode:
authorJames Bursa <james@netsurf-browser.org>2004-06-20 23:09:52 +0000
committerJames Bursa <james@netsurf-browser.org>2004-06-20 23:09:52 +0000
commitf8825b81e4e671abbf7f4cbc730030be9c265f69 (patch)
tree7d211a09daf8ee15d3a3f599cf9bde163bd78181 /content
parentb08c7135fe65d383ec96c679ce2a7aedda6a6d1c (diff)
downloadnetsurf-f8825b81e4e671abbf7f4cbc730030be9c265f69.tar.gz
netsurf-f8825b81e4e671abbf7f4cbc730030be9c265f69.tar.bz2
[project @ 2004-06-20 23:09:51 by bursa]
Implement content_stop() and html_stop(). svn path=/import/netsurf/; revision=982
Diffstat (limited to 'content')
-rw-r--r--content/content.c86
-rw-r--r--content/content.h11
2 files changed, 88 insertions, 9 deletions
diff --git a/content/content.c b/content/content.c
index 5b8956ab5..bee8d5350 100644
--- a/content/content.c
+++ b/content/content.c
@@ -124,6 +124,7 @@ struct handler_entry {
bool (*convert)(struct content *c, int width, int height);
void (*reformat)(struct content *c, int width, int height);
void (*destroy)(struct content *c);
+ void (*stop)(struct content *c);
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,
@@ -142,42 +143,45 @@ struct handler_entry {
* Must be ordered as enum ::content_type. */
static const struct handler_entry handler_map[] = {
{html_create, html_process_data, html_convert,
- html_reformat, html_destroy, html_redraw,
+ html_reformat, html_destroy, html_stop, 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, css_convert, 0, css_destroy, 0, 0, 0, 0},
+ {0, 0, css_convert, 0, css_destroy, 0, 0, 0, 0, 0},
#ifdef WITH_JPEG
{nsjpeg_create, 0, nsjpeg_convert,
- 0, nsjpeg_destroy, nsjpeg_redraw, 0, 0, 0},
+ 0, nsjpeg_destroy, 0, nsjpeg_redraw, 0, 0, 0},
#endif
#ifdef WITH_GIF
{nsgif_create, 0, nsgif_convert,
- 0, nsgif_destroy, nsgif_redraw, 0, 0, 0},
+ 0, nsgif_destroy, 0, nsgif_redraw, 0, 0, 0},
#endif
#ifdef WITH_PNG
{nspng_create, nspng_process_data, nspng_convert,
- 0, nspng_destroy, nspng_redraw, 0, 0, 0},
+ 0, nspng_destroy, 0, nspng_redraw, 0, 0, 0},
#endif
#ifdef WITH_SPRITE
{sprite_create, sprite_process_data, sprite_convert,
- 0, sprite_destroy, sprite_redraw, 0, 0, 0},
+ 0, sprite_destroy, 0, sprite_redraw, 0, 0, 0},
#endif
#ifdef WITH_DRAW
{0, 0, draw_convert,
- 0, draw_destroy, draw_redraw, 0, 0, 0},
+ 0, draw_destroy, 0, draw_redraw, 0, 0, 0},
#endif
#ifdef WITH_PLUGIN
{plugin_create, plugin_process_data, plugin_convert,
- plugin_reformat, plugin_destroy, plugin_redraw,
+ plugin_reformat, plugin_destroy, 0, 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]))
+static void content_stop_check(struct content *c);
+
+
/**
* Convert a MIME type to a content_type.
*
@@ -560,6 +564,7 @@ void content_add_user(struct content *c,
user->callback = callback;
user->p1 = p1;
user->p2 = p2;
+ user->stop = false;
user->next = c->user_list->next;
c->user_list->next = user;
}
@@ -613,6 +618,8 @@ void content_remove_user(struct content *c,
else
content_destroy(c);
}
+ } else if (c->status == CONTENT_STATUS_READY) {
+ content_stop_check(c);
}
}
@@ -637,6 +644,67 @@ void content_broadcast(struct content *c, content_msg msg,
/**
+ * Stop a content loading.
+ *
+ * May only be called in CONTENT_STATUS_READY only. If all users have requested
+ * stop, the loading is stopped and the content placed in CONTENT_STATUS_DONE.
+ */
+
+void content_stop(struct content *c,
+ void (*callback)(content_msg msg, struct content *c, void *p1,
+ void *p2, union content_msg_data data),
+ void *p1, void *p2)
+{
+ struct content_user *user;
+
+ assert(c->status == CONTENT_STATUS_READY);
+
+ /* user_list starts with a sentinel */
+ for (user = c->user_list; user->next != 0 &&
+ !(user->next->callback == callback &&
+ user->next->p1 == p1 &&
+ user->next->p2 == p2); user = user->next)
+ ;
+ if (user->next == 0) {
+ LOG(("user not found in list"));
+ assert(0);
+ return;
+ }
+ user = user->next;
+
+ user->stop = true;
+
+ content_stop_check(c);
+}
+
+
+/**
+ * Check if all users have requested a stop, and do it if so.
+ */
+
+void content_stop_check(struct content *c)
+{
+ struct content_user *user;
+ union content_msg_data data;
+
+ assert(c->status == CONTENT_STATUS_READY);
+
+ /* user_list starts with a sentinel */
+ for (user = c->user_list->next; user; user = user->next)
+ if (!user->stop)
+ return;
+
+ /* all users have requested stop */
+ assert(handler_map[c->type].stop);
+ handler_map[c->type].stop(c);
+ assert(c->status == CONTENT_STATUS_DONE);
+
+ content_set_status(c, messages_get("Stopped"));
+ content_broadcast(c, CONTENT_MSG_DONE, data);
+}
+
+
+/**
* Add an instance to a content.
*
* Calls the add_instance function for the content.
diff --git a/content/content.h b/content/content.h
index 3fcbd39fe..478e16b9e 100644
--- a/content/content.h
+++ b/content/content.h
@@ -45,6 +45,8 @@
* content_convert -> ERROR [label=MSG_ERROR];
* READY -> READY [style=bold];
* READY -> DONE [label=MSG_DONE, style=bold];
+ * READY -> content_stop;
+ * content_stop -> DONE [label=MSG_DONE];
*
* TYPE_UNKNOWN [shape=ellipse];
* LOADING [shape=ellipse];
@@ -74,6 +76,10 @@
*
* - <i>type</i>_redraw(): called to plot the content to screen.
*
+ * - <i>type</i>_stop(): called when the user interrupts in status
+ * CONTENT_STATUS_READY. Must stop any processing and set the status to
+ * CONTENT_STATUS_DONE. Required iff the status can be CONTENT_STATUS_READY.
+ *
* - <i>type</i>_(add|remove|reshape)_instance: ask James, this will probably
* be redesigned sometime.
*
@@ -157,6 +163,7 @@ struct content_user
void *p2, union content_msg_data data);
void *p1;
void *p2;
+ bool stop;
struct content_user *next;
};
@@ -266,6 +273,10 @@ void content_remove_user(struct content *c,
void *p1, void *p2);
void content_broadcast(struct content *c, content_msg msg,
union content_msg_data data);
+void content_stop(struct content *c,
+ void (*callback)(content_msg msg, struct content *c, void *p1,
+ void *p2, union content_msg_data data),
+ void *p1, void *p2);
void content_add_instance(struct content *c, struct browser_window *bw,
struct content *page, struct box *box,
struct object_params *params, void **state);