summaryrefslogtreecommitdiff
path: root/content/content.h
blob: 52a22e5ef4475420046b653848e02cc32c8fb23a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
/*
 * This file is part of NetSurf, http://netsurf.sourceforge.net/
 * Licensed under the GNU General Public License,
 *                http://www.opensource.org/licenses/gpl-license
 * Copyright 2005 James Bursa <bursa@users.sourceforge.net>
 * Copyright 2003 Philip Pemberton <philpem@users.sourceforge.net>
 */

/** \file
 * Content handling (interface).
 *
 * The content functions manipulate struct contents, which correspond to URLs.
 *
 * 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.
 *
 * Depending on the type of content, there may be either one content structure
 * per URL which is shared among all users, or one per URL per user. For
 * example, CONTENT_JPEGs are shared, while there is one CONTENT_HTML per user
 * (because each instance of an HTML page may have different parameters such as
 * window width). This is controlled by no_share in ::handler_map.
 *
 * 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 -> LOADING [label="MSG_NEWPTR\nMSG_LOADING"];
 *     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];
 *     READY -> content_stop;
 *     content_stop -> DONE [label=MSG_DONE];
 *
 *     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>_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>_open(): called when a window containing the content is
 *   opened. Probably only makes sense if no_share is set for the content type
 *   in handler_map. Optional.
 *
 * - <i>type</i>_close(): called when the window containing the content is
 *   closed. Optional.
 *
 * - <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.
 *
 * Each content structure is allocated using talloc, and all data related to a
 * content should be allocated as a child block of the content structure using
 * talloc. This will ensure that all memory used by a page is freed.
 */

#ifndef _NETSURF_DESKTOP_CONTENT_H_
#define _NETSURF_DESKTOP_CONTENT_H_

#include <stdint.h>
#include "netsurf/utils/config.h"
#include "netsurf/content/content_type.h"
#include "netsurf/css/css.h"
#include "netsurf/render/html.h"
#include "netsurf/render/textplain.h"
#ifdef WITH_JPEG
#include "netsurf/image/jpeg.h"
#endif
#ifdef WITH_GIF
#include "netsurf/image/gif.h"
#endif
#ifdef WITH_BMP
#include "netsurf/image/bmp.h"
#endif
#ifdef WITH_PLUGIN
#include "netsurf/riscos/plugin.h"
#endif
#ifdef WITH_MNG
#include "netsurf/image/mng.h"
#endif
#ifdef WITH_SPRITE
#include "netsurf/riscos/sprite.h"
#endif
#ifdef WITH_DRAW
#include "netsurf/riscos/draw.h"
#endif
#ifdef WITH_ARTWORKS
#include "netsurf/riscos/artworks.h"
#endif


struct bitmap;
struct box;
struct browser_window;
struct cache_data;
struct content;
struct fetch;
struct object_params;
struct ssl_cert_info;


/** Used in callbacks to indicate what has occurred. */
typedef enum {
	CONTENT_MSG_LOADING,   /**< fetching or converting */
	CONTENT_MSG_READY,     /**< may be displayed */
	CONTENT_MSG_DONE,      /**< finished */
	CONTENT_MSG_ERROR,     /**< error occurred */
	CONTENT_MSG_STATUS,    /**< new status string */
	CONTENT_MSG_REDIRECT,  /**< replacement URL */
	CONTENT_MSG_REFORMAT,  /**< content_reformat done */
	CONTENT_MSG_REDRAW,    /**< needs redraw (eg. new animation frame) */
	CONTENT_MSG_NEWPTR,    /**< address of structure has changed */
	CONTENT_MSG_REFRESH,   /**< wants refresh */
#ifdef WITH_AUTH
	CONTENT_MSG_AUTH,      /**< authentication required */
#endif
#ifdef WITH_SSL
	CONTENT_MSG_SSL        /**< SSL cert verify failed */
#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 {
		float 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. */
		float object_x, object_y;
		/** Dimensions to plot object with. */
		float object_width, object_height;
	} redraw;
	const char *auth_realm;	/**< Realm, for CONTENT_MSG_AUTH. */
	int delay;	/**< Minimum delay, for CONTENT_MSG_REFRESH */
	struct {
		/** Certificate chain (certs[0] == server) */
		const struct ssl_cert_info *certs;
		unsigned long num;	/**< Number of certs in chain */
	} ssl;
};

/** Linked list of users of a content. */
struct content_user
{
	void (*callback)(content_msg msg, struct content *c, intptr_t p1,
			intptr_t p2, union content_msg_data data);
	intptr_t p1;
	intptr_t p2;
	bool stop;
	struct content_user *next;
};

/** Corresponds to a single URL. */
struct content {
	char *url;		/**< URL, in standard form as from url_join. */
	content_type type;	/**< Type of content. */
	char *mime_type;	/**< Original MIME type of data, or 0. */

	enum {
		CONTENT_STATUS_TYPE_UNKNOWN,	/**< Type not yet known. */
		CONTENT_STATUS_LOADING,	/**< Content is being fetched or
					  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_ERROR	/**< Error occurred, content will be
					  destroyed imminently. */
	} status;		/**< Current status. */

	int width, height;	/**< Dimensions, if applicable. */
	int available_width;	/**< Available width (eg window width). */

	/** Data dependent on type. */
	union {
		struct content_html_data html;
		struct content_textplain_data textplain;
		struct content_css_data css;
#ifdef WITH_JPEG
		struct content_jpeg_data jpeg;
#endif
#ifdef WITH_GIF
		struct content_gif_data gif;
#endif
#ifdef WITH_BMP
		struct content_bmp_data bmp;
#endif
#ifdef WITH_MNG
		struct content_mng_data mng;
#endif
#ifdef WITH_SPRITE
		struct content_sprite_data sprite;
#endif
#ifdef WITH_DRAW
		struct content_draw_data draw;
#endif
#ifdef WITH_PLUGIN
		struct content_plugin_data plugin;
#endif
#ifdef WITH_ARTWORKS
		struct content_artworks_data artworks;
#endif
	} data;

	/**< URL for refresh request, in standard form as from url_join. */
	char *refresh;

	/** Bitmap, for various image contents. */
	struct bitmap *bitmap;

	/** This content may be given to new users. Indicates that the content
	 *  was fetched using a simple GET, has not expired, and may be
	 *  shared between users. */
	bool fresh;
	struct cache_data *cache_data;	/**< Cache control data */

	unsigned int size;		/**< Estimated size of all data
					  associated with this content. */
	char *title;			/**< Title for browser window. */
	unsigned int active;		/**< Number of child fetches or
					  conversions currently in progress. */
	struct content_user *user_list;	/**< List of users. */
	char status_message[80];	/**< Text for status bar. */
	/** Content is being processed: data structures may be inconsistent
	 * and content must not be redrawn or modified. */
	bool locked;

	struct fetch *fetch;		/**< Associated fetch, or 0. */
	char *source_data;		/**< Source data, as received. */
	unsigned long source_size;	/**< Amount of data fetched so far. */
	unsigned long source_allocated;	/**< Amount of space allocated so far. */
	unsigned long total_size;	/**< Total data size, 0 if unknown. */

	bool no_error_pages;		/**< Used by fetchcache(). */
	bool download;			/**< 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[];


content_type content_lookup(const char *mime_type);
struct content * content_create(const char *url);
struct content * content_get(const char *url);
struct content * content_get_ready(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, ...);
bool content_process_data(struct content *c, const 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_reset(struct content *c);
void content_quit(void);
bool 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, unsigned long background_colour);
bool content_redraw_tiled(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 long background_colour,
		bool repeat_x, bool repeat_y);
bool content_add_user(struct content *c,
		void (*callback)(content_msg msg, struct content *c,
			intptr_t p1, intptr_t p2, union content_msg_data data),
		intptr_t p1, intptr_t p2);
struct content_user * content_find_user(struct content *c,
		void (*callback)(content_msg msg, struct content *c,
			intptr_t p1, intptr_t p2, union content_msg_data data),
		intptr_t p1, intptr_t p2);
void content_remove_user(struct content *c,
		void (*callback)(content_msg msg, struct content *c,
			intptr_t p1, intptr_t p2, union content_msg_data data),
		intptr_t p1, intptr_t 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,
			intptr_t p1, intptr_t p2, union content_msg_data data),
		intptr_t p1, intptr_t p2);
void content_open(struct content *c, struct browser_window *bw,
		struct content *page, unsigned int index, struct box *box,
		struct object_params *params);
void content_close(struct content *c);
void content_add_error(struct content *c, const char *token,
		unsigned int line);

#endif