[project @ 2003-07-07 22:10:51 by jmb]

Rewrite plugin system backend.

svn path=/import/netsurf/; revision=210
This commit is contained in:
John Mark Bell 2003-07-07 22:10:51 +00:00
parent 1abf8018a9
commit 133c3ee759
10 changed files with 343 additions and 314 deletions

View File

@ -1,11 +1,10 @@
$Id: TODO-General,v 1.3 2003/06/01 21:56:27 jmb Exp $ $Id: TODO-General,v 1.4 2003/07/07 22:10:51 jmb Exp $
TODO-General for NetSurf. TODO-General for NetSurf.
This file documents general things which need doing. This file documents general things which need doing.
Browser Redirect
Disk Cache Disk Cache
Saving Saving
Printing Printing

View File

@ -1,4 +1,4 @@
$Id: TODO-HTML,v 1.2 2003/06/01 01:02:29 jmb Exp $ $Id: TODO-HTML,v 1.3 2003/07/07 22:10:51 jmb Exp $
TODO-HTML file for NetSurf. TODO-HTML file for NetSurf.
@ -15,13 +15,13 @@ Text Formatting:
<VAR>, <ABBR> and <ACRONYM> tags <VAR>, <ABBR> and <ACRONYM> tags
<Q> tag <Q> tag
Lists Lists:
<LI> <LI>
<OL>,<UL> <OL>,<UL>
Tables: Tables:
Borders, Borders,
row spanning row spanning (only rowspan=0 needs implementing)
column spanning (only colspan=0 needs implementing) column spanning (only colspan=0 needs implementing)
Images: Images:

View File

@ -11,6 +11,7 @@ The source is split at top level as follows:
content -- fetching, caching, and converting content content -- fetching, caching, and converting content
css -- CSS parser and interfaces css -- CSS parser and interfaces
debug -- defines functions which allow debugging under *nix
desktop -- non-platform specific front-end desktop -- non-platform specific front-end
render -- HTML processing and layout render -- HTML processing and layout
riscos -- RISC OS specific code riscos -- RISC OS specific code
@ -33,10 +34,12 @@ The cache stores this converted content. When content is retrieved from the
cache, content_revive() should result in content which can be displayed (eg. by cache, content_revive() should result in content which can be displayed (eg. by
loading any images and styles required and updating pointers to them). loading any images and styles required and updating pointers to them).
Code should not usually use the fetch_* and cache_* functions directly, except Code should not usually use the fetch_* and cache_* functions directly.
for cache_free(). Instead use fetchcache(), which checks the cache for a url and Instead use fetchcache(), which checks the cache for a url and
fetches, converts, and caches it if not present. fetches, converts, and caches it if not present.
See content/overview for more information.
________________________________________________________________________________ ________________________________________________________________________________
css -- CSS parser and interfaces css -- CSS parser and interfaces

View File

@ -16,17 +16,22 @@
#include "netsurf/riscos/jpeg.h" #include "netsurf/riscos/jpeg.h"
#include "netsurf/riscos/png.h" #include "netsurf/riscos/png.h"
#include "netsurf/riscos/gif.h" #include "netsurf/riscos/gif.h"
#include "netsurf/riscos/plugin.h"
#include "netsurf/utils/log.h" #include "netsurf/utils/log.h"
#include "netsurf/utils/utils.h" #include "netsurf/utils/utils.h"
/* mime_map must be in sorted order by mime_type */ /* mime_map must be in sorted order by mime_type */
struct mime_entry { struct mime_entry {
char mime_type[16]; char mime_type[40];
content_type type; content_type type;
}; };
static const struct mime_entry mime_map[] = { static const struct mime_entry mime_map[] = {
#ifdef riscos #ifdef riscos
{"application/java-vm", CONTENT_PLUGIN},
{"application/x-shockwave-flash", CONTENT_PLUGIN},
{"audio/midi", CONTENT_PLUGIN},
{"audio/x-midi", CONTENT_PLUGIN},
{"image/gif", CONTENT_GIF}, {"image/gif", CONTENT_GIF},
{"image/jpeg", CONTENT_JPEG}, {"image/jpeg", CONTENT_JPEG},
{"image/png", CONTENT_PNG}, {"image/png", CONTENT_PNG},
@ -63,6 +68,8 @@ static const struct handler_entry handler_map[] = {
nspng_reformat, nspng_destroy, nspng_redraw}, nspng_reformat, nspng_destroy, nspng_redraw},
{nsgif_create, nsgif_process_data, nsgif_convert, nsgif_revive, {nsgif_create, nsgif_process_data, nsgif_convert, nsgif_revive,
nsgif_reformat, nsgif_destroy, nsgif_redraw}, nsgif_reformat, nsgif_destroy, nsgif_redraw},
{plugin_create, plugin_process_data, plugin_convert, plugin_revive,
plugin_reformat, plugin_destroy, plugin_redraw},
#endif #endif
{other_create, other_process_data, other_convert, other_revive, {other_create, other_process_data, other_convert, other_revive,
other_reformat, other_destroy, 0} other_reformat, other_destroy, 0}
@ -114,12 +121,13 @@ struct content * content_create(char *url)
* content_set_type -- initialise the content for the specified mime type * content_set_type -- initialise the content for the specified mime type
*/ */
void content_set_type(struct content *c, content_type type) void content_set_type(struct content *c, content_type type, char* mime_type)
{ {
assert(c->status == CONTENT_STATUS_TYPE_UNKNOWN); assert(c->status == CONTENT_STATUS_TYPE_UNKNOWN);
assert(type < CONTENT_UNKNOWN); assert(type < CONTENT_UNKNOWN);
LOG(("content %s, type %i", c->url, type)); LOG(("content %s, type %i", c->url, type));
c->type = type; c->type = type;
c->mime_type = mime_type;
c->status = CONTENT_STATUS_LOADING; c->status = CONTENT_STATUS_LOADING;
content_broadcast(c, CONTENT_MSG_LOADING, 0); content_broadcast(c, CONTENT_MSG_LOADING, 0);
handler_map[type].create(c); handler_map[type].create(c);

View File

@ -48,6 +48,7 @@ typedef enum {
#ifdef riscos #ifdef riscos
CONTENT_PNG, CONTENT_PNG,
CONTENT_GIF, CONTENT_GIF,
CONTENT_PLUGIN,
#endif #endif
CONTENT_OTHER, CONTENT_OTHER,
CONTENT_UNKNOWN /* content-type not received yet */ CONTENT_UNKNOWN /* content-type not received yet */
@ -85,6 +86,7 @@ struct content
{ {
char *url; char *url;
content_type type; content_type type;
char *mime_type;
enum { enum {
CONTENT_STATUS_TYPE_UNKNOWN, /* type not yet known */ CONTENT_STATUS_TYPE_UNKNOWN, /* type not yet known */
CONTENT_STATUS_LOADING, /* content is being fetched or converted CONTENT_STATUS_LOADING, /* content is being fetched or converted
@ -156,6 +158,14 @@ struct content
osspriteop_area *sprite_area; // Sprite area osspriteop_area *sprite_area; // Sprite area
char *sprite_image; // Sprite image char *sprite_image; // Sprite image
} gif; } gif;
/* Structure for plugin */
struct
{
char *data; /* object data */
unsigned long length; /* object length */
char* sysvar; /* system variable set by plugin */
} plugin;
#endif #endif
/* downloads */ /* downloads */
struct struct
@ -180,7 +190,7 @@ struct content
content_type content_lookup(const char *mime_type); content_type content_lookup(const char *mime_type);
struct content * content_create(char *url); struct content * content_create(char *url);
void content_set_type(struct content *c, content_type type); void content_set_type(struct content *c, content_type type, char *mime_type);
void content_process_data(struct content *c, char *data, unsigned long size); 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_convert(struct content *c, unsigned long width, unsigned long height);
void content_revive(struct content *c, unsigned long width, unsigned long height); void content_revive(struct content *c, unsigned long width, unsigned long height);

View File

@ -64,9 +64,9 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size)
if ((semic = strchr(mime_type, ';')) != 0) if ((semic = strchr(mime_type, ';')) != 0)
*semic = 0; /* remove "; charset=..." */ *semic = 0; /* remove "; charset=..." */
type = content_lookup(mime_type); type = content_lookup(mime_type);
free(mime_type);
LOG(("FETCH_TYPE, type %u", type)); LOG(("FETCH_TYPE, type %u", type));
content_set_type(c, type); content_set_type(c, type, mime_type);
free(mime_type);
break; break;
case FETCH_DATA: case FETCH_DATA:

View File

@ -75,12 +75,12 @@ void box_normalise_table_row(struct box *row,
static void box_normalise_inline_container(struct box *cont); static void box_normalise_inline_container(struct box *cont);
static void gadget_free(struct gui_gadget* g); static void gadget_free(struct gui_gadget* g);
static void box_free_box(struct box *box); static void box_free_box(struct box *box);
static struct box* box_object(xmlNode *n, struct content *content, static struct result box_object(xmlNode *n, struct status *status,
struct css_style *style, char *href); struct css_style *style);
static struct box* box_embed(xmlNode *n, struct content *content, static struct result box_embed(xmlNode *n, struct status *status,
struct css_style *style, char *href); struct css_style *style);
static struct box* box_applet(xmlNode *n, struct content *content, static struct result box_applet(xmlNode *n, struct status *status,
struct css_style *style, char *href); struct css_style *style);
static struct form* create_form(xmlNode* n); static struct form* create_form(xmlNode* n);
static void add_form_element(struct page_elements* pe, struct form* f); static void add_form_element(struct page_elements* pe, struct form* f);
static void add_gadget_element(struct page_elements* pe, struct gui_gadget* g); static void add_gadget_element(struct page_elements* pe, struct gui_gadget* g);
@ -93,9 +93,12 @@ struct element_entry {
}; };
static const struct element_entry element_table[] = { static const struct element_entry element_table[] = {
{"a", box_a}, {"a", box_a},
// {"applet", box_applet},
{"embed", box_embed},
{"form", box_form}, {"form", box_form},
{"img", box_image}, {"img", box_image},
{"input", box_input}, {"input", box_input},
{"object", box_object},
{"select", box_select}, {"select", box_select},
{"textarea", box_textarea} {"textarea", box_textarea}
}; };
@ -1385,48 +1388,33 @@ void add_gadget_element(struct page_elements* pe, struct gui_gadget* g)
/** /**
* add an object to the box tree * add an object to the box tree
*/ */
struct result box_object(xmlNode *n, struct status *status,
/* } else if (strcmp((const char*) n->name, "object") == 0) { LOG(("object")); struct css_style *style)
box = box_object(n, content, style, href);
*/ /* TODO - param data structure
for (c = n->children; c != 0; c = c->next) {
if (strcmp((const char*) c->name, "param") == 0) {
LOG(("param"));
current_param = box_param(c, style, current_object);
}
} */
/*
} else if (strcmp((const char*) n->name, "embed") == 0) { LOG(("embed"));
box = box_embed(n, content, style, href);
} else if (strcmp((const char*) n->name, "applet") == 0) { LOG(("applet"));
box = box_applet(n, content, style, href);
}
*/
struct box* box_object(xmlNode *n, struct content *content,
struct css_style *style, char *href)
{ {
struct box *box; struct box *box;
struct plugin_object *po; struct plugin_object *po;
char *s, *url; char *s, *url;
xmlChar *s2;
box = box_create(style, href, 0); box = box_create(style, status->href, 0);
po = xcalloc(1,sizeof(*po)); po = xcalloc(1, sizeof(*po));
/* initialise po struct */
po->data = 0;
po->type = 0;
po->codetype = 0;
po->codebase = 0;
po->classid = 0;
po->paramds = 0;
po->width = 0;
po->height = 0;
/* object data */ /* object data */
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "data"))) { if ((s = (char *) xmlGetProp(n, (const xmlChar *) "data"))) {
po->data = strdup(s); po->data = strdup(s);
url = url_join(strdup(s), content->url); url = url_join(strdup(s), status->content->url);
LOG(("object '%s'", url)); LOG(("object '%s'", po->data));
xmlFree(s); xmlFree(s);
} }
@ -1434,7 +1422,7 @@ struct box* box_object(xmlNode *n, struct content *content,
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "type"))) { if ((s = (char *) xmlGetProp(n, (const xmlChar *) "type"))) {
po->type = strdup(s); po->type = strdup(s);
LOG(("type: %s", po->type)); LOG(("type: %s", s));
xmlFree(s); xmlFree(s);
} }
@ -1442,7 +1430,7 @@ struct box* box_object(xmlNode *n, struct content *content,
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "codetype"))) { if ((s = (char *) xmlGetProp(n, (const xmlChar *) "codetype"))) {
po->codetype = strdup(s); po->codetype = strdup(s);
LOG(("codetype: %s", po->codetype)); LOG(("codetype: %s", s));
xmlFree(s); xmlFree(s);
} }
@ -1450,7 +1438,7 @@ struct box* box_object(xmlNode *n, struct content *content,
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "codebase"))) { if ((s = (char *) xmlGetProp(n, (const xmlChar *) "codebase"))) {
po->codebase = strdup(s); po->codebase = strdup(s);
LOG(("codebase: %s", po->codebase)); LOG(("codebase: %s", s));
xmlFree(s); xmlFree(s);
} }
@ -1458,7 +1446,7 @@ struct box* box_object(xmlNode *n, struct content *content,
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "classid"))) { if ((s = (char *) xmlGetProp(n, (const xmlChar *) "classid"))) {
po->classid = strdup(s); po->classid = strdup(s);
LOG(("classid: %s", po->classid)); LOG(("classid: %s", s));
xmlFree(s); xmlFree(s);
} }
@ -1466,7 +1454,7 @@ struct box* box_object(xmlNode *n, struct content *content,
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "width"))) { if ((s = (char *) xmlGetProp(n, (const xmlChar *) "width"))) {
po->width = (unsigned int)atoi(s); po->width = (unsigned int)atoi(s);
LOG(("width: %u", po->width)); LOG(("width: %u", (unsigned int)atoi(s)));
xmlFree(s); xmlFree(s);
} }
@ -1474,45 +1462,54 @@ struct box* box_object(xmlNode *n, struct content *content,
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "height"))) { if ((s = (char *) xmlGetProp(n, (const xmlChar *) "height"))) {
po->height = (unsigned int)atoi(s); po->height = (unsigned int)atoi(s);
LOG(("height: %u", po->height)); LOG(("height: %u", (unsigned int)atoi(s)));
xmlFree(s); xmlFree(s);
} }
/* start fetch */ /* start fetch */
plugin_decode(content, url, box, po); plugin_decode(status->content, url, box, po);
return box; return (struct result) {box, 0};
} }
/** /**
* add an embed to the box tree * add an embed to the box tree
*/ */
struct box* box_embed(xmlNode *n, struct content *content, struct result box_embed(xmlNode *n, struct status *status,
struct css_style *style, char *href) struct css_style *style)
{ {
struct box *box; struct box *box;
struct plugin_object *po; struct plugin_object *po;
char *s, *url; char *s, *url;
xmlChar *s2;
box = box_create(style, href, 0); box = box_create(style, status->href, 0);
po = xcalloc(1, sizeof(*po)); po = xcalloc(1, sizeof(*po));
/* initialise po struct */
po->data = 0;
po->type = 0;
po->codetype = 0;
po->codebase = 0;
po->classid = 0;
po->paramds = 0;
po->width = 0;
po->height = 0;
/* embed src */ /* embed src */
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "src"))) { if ((s = (char *) xmlGetProp(n, (const xmlChar *) "src"))) {
po->data = strdup(s); po->data = strdup(s);
url = url_join(strdup(s), content->url); url = url_join(strdup(s), status->content->url);
LOG(("embed '%s'", url)); LOG(("embed '%s'", url));
xmlFree(s); xmlFree(s);
} }
/* start fetch */ /* start fetch */
plugin_decode(content, url, box, po); plugin_decode(status->content, url, box, po);
return box; return (struct result) {box,0};
} }
/** /**
@ -1520,29 +1517,24 @@ struct box* box_embed(xmlNode *n, struct content *content,
* add an applet to the box tree * add an applet to the box tree
*/ */
struct box* box_applet(xmlNode *n, struct content *content, struct result box_applet(xmlNode *n, struct status *status,
struct css_style *style, char *href) struct css_style *style)
{ {
struct box *box; struct box *box;
struct plugin_object *po;
char *s, *url; char *s, *url;
xmlChar *s2;
/* box type is decided by caller, BOX_INLINE is just a default */ box = box_create(style, status->href, 0);
box = box_create(style, href, 0);
po = xcalloc(1,sizeof(struct plugin_object));
/* object without data is an error */ /* object without data is an error */
if (!(s = (char *) xmlGetProp(n, (const xmlChar *) "data"))) if (!(s = (char *) xmlGetProp(n, (const xmlChar *) "data")))
return box; return (struct result) {box,0};
url = url_join(strdup(s), content->url); url = url_join(strdup(s), status->content->url);
LOG(("object '%s'", url)); LOG(("object '%s'", url));
xmlFree(s); xmlFree(s);
/* start fetch */ /* start fetch */
//plugin_decode(content, url, box, po); //plugin_decode(content, url, box, po);
return box; return (struct result) {box,0};
} }

View File

@ -305,7 +305,7 @@ void html_find_stylesheets(struct content *c, xmlNode *head)
LOG(("style element")); LOG(("style element"));
if (c->data.html.stylesheet_content[1] == 0) { if (c->data.html.stylesheet_content[1] == 0) {
c->data.html.stylesheet_content[1] = content_create(c->url); c->data.html.stylesheet_content[1] = content_create(c->url);
content_set_type(c->data.html.stylesheet_content[1], CONTENT_CSS); content_set_type(c->data.html.stylesheet_content[1], CONTENT_CSS, "text/css");
} }
/* can't just use xmlNodeGetContent(node), because that won't give /* can't just use xmlNodeGetContent(node), because that won't give

View File

@ -19,268 +19,275 @@
#include "oslib/mimemap.h" #include "oslib/mimemap.h"
char* create_mime_from_ext(char* data); bool plugin_handleable(struct content* c);
char* create_sysvar(char* mime);
void plugin_fetch(struct plugin_object* po,
char* alias_sysvar/* vars here */);
/** /**
* plugin_decode * plugin_decode
* Processes the contents of the plugin_object struct (defined in plugin.h) * This function checks that the contents of the plugin_object struct
* in order to work out if NetSurf can handle the object. * are valid. If they are, it initiates the fetch process. If they are
* For more information, read * not, it exits, leaving the box structure as it was on entry. This is
* http://www.ecs.soton.ac.uk/~jmb202/riscos/acorn/browse-plugins.html * necessary as there are multiple ways of declaring an object's attributes.
* as this code is based heavily on that description. *
* TODO: alt html
* params - create parameters file and put the filename string
* somewhere such that it is accessible from plugin_create.
*/ */
void plugin_decode(struct content* content, char* url, struct box* box, void plugin_decode(struct content* content, char* url, struct box* box,
struct plugin_object* po) { struct plugin_object* po)
{
os_error *e;
unsigned int *fv;
/* Check if the codebase attribute is defined.
content_type mime_type; * If it is not, set it to the codebase of the current document.
bool can_handle = TRUE;
char* alias_sysvar;
if (po->data != NULL) {
if (po->type != NULL) {
/* acquire NS mime type from actual mime type */
mime_type = content_lookup((const char*)po->type);
}
else {
/* create actual mime type - if we're wrong,
* it doesn't matter as the HTTP content-type
* header should override whatever we think.
* however, checking the header hasn't been
* implemented yet so it will just b0rk :(
*/ */
po->type = strdup(create_mime_from_ext(po->data)); if(po->codebase == 0)
po->codebase = strdup(content->url);
else
po->codebase = url_join(po->codebase, content->url);
if (po->type != NULL) /* Check that we have some data specified.
mime_type = content_lookup((const char*)po->type); * First, check the data attribute.
* Second, check the classid attribute.
else { * The data attribute takes precedence.
* If neither are specified or if classid begins "clsid:",
/* failed to create mime type, clean up and exit */ * we can't handle this object.
xfree(po);
can_handle = FALSE;
}
}
}
else {
/* no data so try using classid instead */
if (po->classid != NULL) {
po->data = strdup(po->classid);
if (strnicmp(po->data,"clsid:",6) == 0) {
/* We can't handle ActiveX objects */
LOG(("Can't Handle ActiveX"));
xfree(po);
can_handle = FALSE;
}
else {
if (po->codetype != NULL) {
/* use codetype instead of type if we can */
po->type = strdup(po->codetype);
mime_type = content_lookup(
(const char*)po->codetype);
}
else {
/* try ye olde file extension munging */
po->codetype = strdup(
create_mime_from_ext(po->data));
if (po->codetype != NULL) {
/* well, it appeared to work... */
mime_type = content_lookup(
(const char*)po->codetype);
po->type = strdup(
po->codetype);
}
else {
/* arse, failed. oh well */
xfree(po);
can_handle = FALSE;
}
}
}
}
else {
/* we don't have sufficient data to handle this
* object :(
* TODO: start fetch anyway and check header.
* if we can handle the content, continue
* fetch and carry on as if the proper HTML
* was written.
* if we can't handle the content, stop fetch
* and clean up.
*/ */
if(po->data == 0 && po->classid == 0) {
xfree(po); xfree(po);
can_handle = FALSE;
}
}
/* so, you think you can handle it do you? */
if (can_handle == TRUE) {
/* We think we can handle this object. Now check that
* we can.
* 1) Is it an image? Yes - send to image handler
* No - continue checking
* 2) Is a suitable Alias$... System Variable set?
* Yes - invoke plugin
* No - we can't handle it. Display alternative HTML
*/
/* TODO: There must be a better way than this...
* Perhaps checking if the mime type begins "image/"
* would be better?
*/
if (mime_type == CONTENT_JPEG || mime_type == CONTENT_PNG
|| mime_type == CONTENT_GIF) {
/* OK, we have an image. Let's make the image handler
* deal with it.
*/
xfree(po);
LOG(("sending data to image handler"));
html_fetch_object(content, url, box);
return; return;
} }
else { /* not an image; is sys var set? */ if(po->data == 0 && po->classid != 0) {
if(strnicmp(po->classid, "clsid:", 6) == 0) {
/* Create Alias variable */ LOG(("ActiveX object - n0"));
alias_sysvar = create_sysvar(po->type);
if (alias_sysvar == NULL) {
/* oh dear, you can't handle it */
xfree(po); xfree(po);
xfree(alias_sysvar); return;
can_handle = FALSE;
} }
else { else {
url = url_join(po->classid, po->codebase);
}
}
else {
url = url_join(po->data, po->codebase);
}
/* Right, we have a variable. /* Check if the declared mime type is understandable.
* Does it actually exist? * ie. is it referenced in the mimemap file?
* Checks type and codetype attributes.
*/ */
if(po->type != 0) {
e = xmimemaptranslate_mime_type_to_filetype((const char*)po->type,
(unsigned int*)&fv);
LOG(("fv: &%x", (int) fv));
if(e != NULL) {
xfree(po);
return;
}
/* If a filetype of &ffd (Data) is returned,
* one of the following mime types is possible :
* application/octet-stream
* multipart/x-mixed-replace
* unknown mime type (* / *)
* we assume it to be the last one as the other two
* are unlikely to occur in an <object> definition.
*/
if((int)fv == 0xffd) {
xfree(po);
return;
}
/* TODO: implement GUI for iframes/frames
* For now, we just discard the data and
* render the alternative html
*/
if((int)fv == 0xfaf) {
xfree(po);
return;
}
}
if(po->codetype != 0) {
e = xmimemaptranslate_mime_type_to_filetype((const char*)po->codetype,
(unsigned int*)&fv);
if(e != NULL) {
xfree(po);
return;
}
/* If a filetype of &ffd (Data) is returned,
* one of the following mime types is possible :
* application/octet-stream
* multipart/x-mixed-replace
* unknown mime type (* / *)
* we assume it to be the last one as the other two
* are unlikely to occur in an <object> definition.
*/
if((int)fv == 0xffd) {
xfree(po);
return;
}
/* TODO: implement GUI for iframes/frames
* For now, we just discard the data and
* render the alternative html
*/
if((int)fv == 0xfaf) {
xfree(po);
return;
}
}
/* If we've got to here, the object declaration has provided us with
* enough data to enable us to have a go at downloading and displaying it.
*/
xfree(po);
html_fetch_object(content, url, box);
}
/**
* plugin_create
* initialises plugin system in readiness for recieving object data
*
* TODO: implement aborting the fetch
* get parameter filename from wherever it was put by plugin_decode
* launch plugin system
*/
void plugin_create(struct content *c)
{
bool can_handle = TRUE; /* we assume we can handle all types */
LOG(("mime type: %s", c->mime_type));
/* check if we can handle this type */
can_handle = plugin_handleable(c);
LOG(("can_handle = %s", can_handle ? "TRUE" : "FALSE"));
LOG(("sysvar: %s", can_handle ? c->data.plugin.sysvar : "not set"));
if(!can_handle) {
/* TODO: need to find a way of stopping the fetch
* if we can't handle this type
*/
}
/* ok, it looks like we can handle this object.
* Broadcast Message_PlugIn_Open (&4D540) and listen for response
* Message_PlugIn_Opening (&4D541). If no response, try to launch
* plugin by Wimp_StartTask(sysvar). Then re-broadcast Message_PlugIn_Open
* and listen for response. If there is still no response, give up and set
* can_handle to FALSE.
* NB: For the bounding box in Message_PlugIn_Open, we choose arbitrary
* values outside the area displayed. This is corrected when
* plugin_redraw is called.
*/
/* Recheck if can_handle is false. If it is, stop fetch and exit .*/
if(!can_handle) {
/* TODO: need to find a way of stopping the fetch
* if we can't handle this type
*/
}
}
static const char * const ALIAS_PREFIX = "Alias$@PlugInType_";
/**
* plugin_handleable
* Tests whether we can handle an object using a browser plugin
* returns TRUE if we can handle it, FALSE if we can't.
*/
bool plugin_handleable(struct content* c)
{
bool ret = TRUE;
char *sysvar;
unsigned int *fv;
int used; int used;
xos_read_var_val_size( os_error *e;
(const char*)alias_sysvar,
0, os_VARTYPE_STRING, /* prefix + 3 for file type + 1 for terminating \0 */
sysvar = xcalloc(strlen(ALIAS_PREFIX)+4, sizeof(char));
e = xmimemaptranslate_mime_type_to_filetype((const char*)c->mime_type,
(unsigned int*)&fv);
sprintf(sysvar, "%s%x", ALIAS_PREFIX, e == NULL ? (int)fv : 0 );
xos_read_var_val_size((const char*)sysvar,0, os_VARTYPE_STRING,
&used, 0, os_VARTYPE_STRING); &used, 0, os_VARTYPE_STRING);
if (used == 0) { if(used == 0)
/* No system variable set => no plugin available */
ret = FALSE;
/* no, doesn't exist */ if(ret)
xfree(po); c->data.plugin.sysvar = strdup(sysvar);
xfree(alias_sysvar);
can_handle = FALSE;
}
else {
/* yes, it exists */
LOG(("%s exists", alias_sysvar));
plugin_fetch(po, alias_sysvar/* insert vars here */);
}
}
}
}
if (can_handle == FALSE) { xfree(sysvar);
/* Get alternative HTML as we can't handle the object */
return;
}
}
/**
* create_mime_from_ext
* attempts to create a mime type from the filename extension.
* returns NULL if it fails.
*/
char* create_mime_from_ext(char* data){
char* ret;
os_error *e;
LOG(("Creating Mime Type from File Extension"));
ret = xcalloc(90, sizeof(char));
ret = strrchr(data, '.');
LOG(("Extension = %s", ret));
/* Let's make the mime map module do the work for us */
e = xmimemaptranslate_extension_to_mime_type((const char*)ret,
ret);
LOG(("Mime Type = %s", ret));
if (e != NULL) ret = NULL;
return ret; return ret;
} }
/** /**
* create_sysvar * plugin_process_data
* attempts to create a system variable of the form Alias$@PlugInType_XXX * processes data retrieved by the fetch process
* where XXX is the filetype. *
* returns NULL if unsuccessful. * TODO: plugin stream protocol
*
*/
void plugin_process_data(struct content *c, char *data, unsigned long size)
{
/* If the plugin requests, we send the data to it via the
* plugin stream protocol.
* Also, we should listen for Message_PlugIn_URL_Access (&4D54D)
* as the plugin may need us to retrieve URLs for it.
* We should also listen for Message_PlugIn_Closed (&4D543).
* If this occurs, the plugin has exited with an error.
* Therefore, we need to stop the fetch and exit.
*/ */
char* create_sysvar(char* mime) {
char* ret;
char* ft;
unsigned int* fv;
os_error *e;
LOG(("Creating System Variable from Mime Type"));
ret = xcalloc(22, sizeof(char));
ft = xcalloc(10, sizeof(char));
strcpy(ret, "Alias$@PlugInType_");
LOG(("Mime Type: %s", mime));
e = xmimemaptranslate_mime_type_to_filetype((const char*)mime,
(unsigned int*)&fv);
if (e != NULL) ret = NULL;
else {
sprintf(ft, "%x", (int)fv);
strcat(ret, ft);
LOG(("Alias Var: %s", ret));
}
xfree(ft);
return ret;
} }
/** /**
* plugin_fetch * plugin_convert
* attempts to negotiate with the plugin. * This isn't needed by the plugin system as all the data processing is done
* also fetches the object for the plugin to handle. * externally. Therefore, just tell NetSurf that everything's OK.
*/
int plugin_convert(struct content *c, unsigned int width, unsigned int height)
{
c->status=CONTENT_STATUS_DONE;
return 0;
}
void plugin_revive(struct content *c, unsigned int width, unsigned int height)
{
}
void plugin_reformat(struct content *c, unsigned int width, unsigned int height)
{
}
/**
* plugin_destroy
* we've finished with this data, destroy it. Also, shutdown plugin.
*
* TODO: clean up
*/
void plugin_destroy(struct content *c)
{
}
/**
* plugin_redraw
* redraw plugin on page.
*
* TODO: Message_PlugIn_Reshape
*/
void plugin_redraw(struct content *c, long x, long y,
unsigned long width, unsigned long height)
{
/* By now, we've got the plugin up and running in a nested window
* off the viewable page area. Now we want to display it in its place.
* Therefore, broadcast a Message_PlugIn_Reshape (&4D544) with the values
* given to us.
*/ */
void plugin_fetch (struct plugin_object* po,
char* alias_sysvar/* insert vars here */) {
LOG(("Entering plugin_fetch"));
xfree(po);
xfree(alias_sysvar);
return;
} }

View File

@ -8,6 +8,8 @@
#ifndef _NETSURF_RISCOS_PLUGIN_H_ #ifndef _NETSURF_RISCOS_PLUGIN_H_
#define _NETSURF_RISCOS_PLUGIN_H_ #define _NETSURF_RISCOS_PLUGIN_H_
#include "netsurf/content/content.h"
struct plugin_object { struct plugin_object {
char* data; char* data;
@ -21,8 +23,16 @@ struct plugin_object {
}; };
/* function definitions */
void plugin_decode(struct content* content, char* url, struct box* box, void plugin_decode(struct content* content, char* url, struct box* box,
struct plugin_object* po); struct plugin_object* po);
void plugin_create(struct content *c);
void plugin_process_data(struct content *c, char *data, unsigned long size);
int plugin_convert(struct content *c, unsigned int width, unsigned int height);
void plugin_revive(struct content *c, unsigned int width, unsigned int height);
void plugin_reformat(struct content *c, unsigned int width, unsigned int height);
void plugin_destroy(struct content *c);
void plugin_redraw(struct content *c, long x, long y,
unsigned long width, unsigned long height);
#endif #endif