From 133c3ee759bdc27f661390633064d7554027fbcb Mon Sep 17 00:00:00 2001 From: John Mark Bell Date: Mon, 7 Jul 2003 22:10:51 +0000 Subject: [PATCH] [project @ 2003-07-07 22:10:51 by jmb] Rewrite plugin system backend. svn path=/import/netsurf/; revision=210 --- Docs/TODO-General | 3 +- Docs/TODO-HTML | 6 +- Docs/developer | 7 +- content/content.c | 12 +- content/content.h | 12 +- content/fetchcache.c | 4 +- render/box.c | 120 +++++------ render/html.c | 6 +- riscos/plugin.c | 475 ++++++++++++++++++++++--------------------- riscos/plugin.h | 12 +- 10 files changed, 343 insertions(+), 314 deletions(-) diff --git a/Docs/TODO-General b/Docs/TODO-General index 4048d4126..93190c501 100644 --- a/Docs/TODO-General +++ b/Docs/TODO-General @@ -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. This file documents general things which need doing. -Browser Redirect Disk Cache Saving Printing diff --git a/Docs/TODO-HTML b/Docs/TODO-HTML index bac217d79..66717dc85 100644 --- a/Docs/TODO-HTML +++ b/Docs/TODO-HTML @@ -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. @@ -15,13 +15,13 @@ Text Formatting: , and tags tag -Lists +Lists:
    1. ,
        Tables: Borders, - row spanning + row spanning (only rowspan=0 needs implementing) column spanning (only colspan=0 needs implementing) Images: diff --git a/Docs/developer b/Docs/developer index 5af1ae8c3..7278dc81c 100644 --- a/Docs/developer +++ b/Docs/developer @@ -11,6 +11,7 @@ The source is split at top level as follows: content -- fetching, caching, and converting content css -- CSS parser and interfaces +debug -- defines functions which allow debugging under *nix desktop -- non-platform specific front-end render -- HTML processing and layout 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 loading any images and styles required and updating pointers to them). -Code should not usually use the fetch_* and cache_* functions directly, except -for cache_free(). Instead use fetchcache(), which checks the cache for a url and +Code should not usually use the fetch_* and cache_* functions directly. +Instead use fetchcache(), which checks the cache for a url and fetches, converts, and caches it if not present. +See content/overview for more information. + ________________________________________________________________________________ css -- CSS parser and interfaces diff --git a/content/content.c b/content/content.c index 6520b6805..9b15a3b83 100644 --- a/content/content.c +++ b/content/content.c @@ -16,17 +16,22 @@ #include "netsurf/riscos/jpeg.h" #include "netsurf/riscos/png.h" #include "netsurf/riscos/gif.h" +#include "netsurf/riscos/plugin.h" #include "netsurf/utils/log.h" #include "netsurf/utils/utils.h" /* mime_map must be in sorted order by mime_type */ struct mime_entry { - char mime_type[16]; + char mime_type[40]; content_type type; }; static const struct mime_entry mime_map[] = { #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/jpeg", CONTENT_JPEG}, {"image/png", CONTENT_PNG}, @@ -63,6 +68,8 @@ static const struct handler_entry handler_map[] = { nspng_reformat, nspng_destroy, nspng_redraw}, {nsgif_create, nsgif_process_data, nsgif_convert, nsgif_revive, nsgif_reformat, nsgif_destroy, nsgif_redraw}, + {plugin_create, plugin_process_data, plugin_convert, plugin_revive, + plugin_reformat, plugin_destroy, plugin_redraw}, #endif {other_create, other_process_data, other_convert, other_revive, 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 */ -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(type < CONTENT_UNKNOWN); LOG(("content %s, type %i", c->url, type)); c->type = type; + c->mime_type = mime_type; c->status = CONTENT_STATUS_LOADING; content_broadcast(c, CONTENT_MSG_LOADING, 0); handler_map[type].create(c); diff --git a/content/content.h b/content/content.h index 786013938..dd9b50592 100644 --- a/content/content.h +++ b/content/content.h @@ -48,6 +48,7 @@ typedef enum { #ifdef riscos CONTENT_PNG, CONTENT_GIF, + CONTENT_PLUGIN, #endif CONTENT_OTHER, CONTENT_UNKNOWN /* content-type not received yet */ @@ -85,6 +86,7 @@ struct content { char *url; content_type type; + char *mime_type; enum { CONTENT_STATUS_TYPE_UNKNOWN, /* type not yet known */ CONTENT_STATUS_LOADING, /* content is being fetched or converted @@ -156,6 +158,14 @@ struct content osspriteop_area *sprite_area; // Sprite area char *sprite_image; // Sprite image } gif; + + /* Structure for plugin */ + struct + { + char *data; /* object data */ + unsigned long length; /* object length */ + char* sysvar; /* system variable set by plugin */ + } plugin; #endif /* downloads */ struct @@ -180,7 +190,7 @@ struct content content_type content_lookup(const char *mime_type); 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_convert(struct content *c, unsigned long width, unsigned long height); void content_revive(struct content *c, unsigned long width, unsigned long height); diff --git a/content/fetchcache.c b/content/fetchcache.c index ebd5e66d1..844111376 100644 --- a/content/fetchcache.c +++ b/content/fetchcache.c @@ -64,9 +64,9 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size) if ((semic = strchr(mime_type, ';')) != 0) *semic = 0; /* remove "; charset=..." */ type = content_lookup(mime_type); - free(mime_type); LOG(("FETCH_TYPE, type %u", type)); - content_set_type(c, type); + content_set_type(c, type, mime_type); + free(mime_type); break; case FETCH_DATA: diff --git a/render/box.c b/render/box.c index a829d84f5..13480ad2a 100644 --- a/render/box.c +++ b/render/box.c @@ -75,12 +75,12 @@ void box_normalise_table_row(struct box *row, static void box_normalise_inline_container(struct box *cont); static void gadget_free(struct gui_gadget* g); static void box_free_box(struct box *box); -static struct box* box_object(xmlNode *n, struct content *content, - struct css_style *style, char *href); -static struct box* box_embed(xmlNode *n, struct content *content, - struct css_style *style, char *href); -static struct box* box_applet(xmlNode *n, struct content *content, - struct css_style *style, char *href); +static struct result box_object(xmlNode *n, struct status *status, + struct css_style *style); +static struct result box_embed(xmlNode *n, struct status *status, + struct css_style *style); +static struct result box_applet(xmlNode *n, struct status *status, + struct css_style *style); static struct form* create_form(xmlNode* n); 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); @@ -93,9 +93,12 @@ struct element_entry { }; static const struct element_entry element_table[] = { {"a", box_a}, +// {"applet", box_applet}, + {"embed", box_embed}, {"form", box_form}, {"img", box_image}, {"input", box_input}, + {"object", box_object}, {"select", box_select}, {"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 */ - -/* } else if (strcmp((const char*) n->name, "object") == 0) { LOG(("object")); - 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 result box_object(xmlNode *n, struct status *status, + struct css_style *style) { struct box *box; struct plugin_object *po; 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)); - /* object data */ + /* 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 */ if ((s = (char *) xmlGetProp(n, (const xmlChar *) "data"))) { po->data = strdup(s); - url = url_join(strdup(s), content->url); - LOG(("object '%s'", url)); + url = url_join(strdup(s), status->content->url); + LOG(("object '%s'", po->data)); xmlFree(s); } @@ -1434,7 +1422,7 @@ struct box* box_object(xmlNode *n, struct content *content, if ((s = (char *) xmlGetProp(n, (const xmlChar *) "type"))) { po->type = strdup(s); - LOG(("type: %s", po->type)); + LOG(("type: %s", s)); xmlFree(s); } @@ -1442,7 +1430,7 @@ struct box* box_object(xmlNode *n, struct content *content, if ((s = (char *) xmlGetProp(n, (const xmlChar *) "codetype"))) { po->codetype = strdup(s); - LOG(("codetype: %s", po->codetype)); + LOG(("codetype: %s", s)); xmlFree(s); } @@ -1450,7 +1438,7 @@ struct box* box_object(xmlNode *n, struct content *content, if ((s = (char *) xmlGetProp(n, (const xmlChar *) "codebase"))) { po->codebase = strdup(s); - LOG(("codebase: %s", po->codebase)); + LOG(("codebase: %s", s)); xmlFree(s); } @@ -1458,7 +1446,7 @@ struct box* box_object(xmlNode *n, struct content *content, if ((s = (char *) xmlGetProp(n, (const xmlChar *) "classid"))) { po->classid = strdup(s); - LOG(("classid: %s", po->classid)); + LOG(("classid: %s", s)); xmlFree(s); } @@ -1466,7 +1454,7 @@ struct box* box_object(xmlNode *n, struct content *content, if ((s = (char *) xmlGetProp(n, (const xmlChar *) "width"))) { po->width = (unsigned int)atoi(s); - LOG(("width: %u", po->width)); + LOG(("width: %u", (unsigned int)atoi(s))); xmlFree(s); } @@ -1474,45 +1462,54 @@ struct box* box_object(xmlNode *n, struct content *content, if ((s = (char *) xmlGetProp(n, (const xmlChar *) "height"))) { po->height = (unsigned int)atoi(s); - LOG(("height: %u", po->height)); + LOG(("height: %u", (unsigned int)atoi(s))); xmlFree(s); } /* 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 */ -struct box* box_embed(xmlNode *n, struct content *content, - struct css_style *style, char *href) +struct result box_embed(xmlNode *n, struct status *status, + struct css_style *style) { struct box *box; struct plugin_object *po; char *s, *url; - xmlChar *s2; - box = box_create(style, href, 0); + box = box_create(style, status->href, 0); 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 */ if ((s = (char *) xmlGetProp(n, (const xmlChar *) "src"))) { po->data = strdup(s); - url = url_join(strdup(s), content->url); + url = url_join(strdup(s), status->content->url); LOG(("embed '%s'", url)); xmlFree(s); } /* 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 */ -struct box* box_applet(xmlNode *n, struct content *content, - struct css_style *style, char *href) +struct result box_applet(xmlNode *n, struct status *status, + struct css_style *style) { struct box *box; - struct plugin_object *po; char *s, *url; - xmlChar *s2; - /* box type is decided by caller, BOX_INLINE is just a default */ - box = box_create(style, href, 0); - - po = xcalloc(1,sizeof(struct plugin_object)); + box = box_create(style, status->href, 0); /* object without data is an error */ 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)); xmlFree(s); /* start fetch */ //plugin_decode(content, url, box, po); - return box; + return (struct result) {box,0}; } diff --git a/render/html.c b/render/html.c index a079cac78..60d218121 100644 --- a/render/html.c +++ b/render/html.c @@ -176,7 +176,7 @@ void html_convert_css_callback(content_msg msg, struct content *css, c, i, css->width, css->height); if (c->data.html.stylesheet_content[i]->status != CONTENT_STATUS_DONE) c->active++; - break; + break; default: assert(0); @@ -305,7 +305,7 @@ void html_find_stylesheets(struct content *c, xmlNode *head) LOG(("style element")); if (c->data.html.stylesheet_content[1] == 0) { 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 @@ -450,7 +450,7 @@ void html_object_callback(content_msg msg, struct content *object, c, i, 0, 0); if (c->data.html.object[i].content->status != CONTENT_STATUS_DONE) c->active++; - break; + break; default: assert(0); diff --git a/riscos/plugin.c b/riscos/plugin.c index 821d9d82e..42619ae96 100644 --- a/riscos/plugin.c +++ b/riscos/plugin.c @@ -19,268 +19,275 @@ #include "oslib/mimemap.h" -char* create_mime_from_ext(char* data); -char* create_sysvar(char* mime); -void plugin_fetch(struct plugin_object* po, - char* alias_sysvar/* vars here */); +bool plugin_handleable(struct content* c); /** * plugin_decode - * Processes the contents of the plugin_object struct (defined in plugin.h) - * in order to work out if NetSurf can handle the object. - * For more information, read - * http://www.ecs.soton.ac.uk/~jmb202/riscos/acorn/browse-plugins.html - * as this code is based heavily on that description. + * This function checks that the contents of the plugin_object struct + * are valid. If they are, it initiates the fetch process. If they are + * not, it exits, leaving the box structure as it was on entry. This is + * necessary as there are multiple ways of declaring an object's attributes. + * + * 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, - struct plugin_object* po) { + struct plugin_object* po) +{ + os_error *e; + unsigned int *fv; + /* Check if the codebase attribute is defined. + * If it is not, set it to the codebase of the current document. + */ + if(po->codebase == 0) + po->codebase = strdup(content->url); + else + po->codebase = url_join(po->codebase, content->url); - content_type mime_type; - bool can_handle = TRUE; - char* alias_sysvar; + /* Check that we have some data specified. + * First, check the data attribute. + * Second, check the classid attribute. + * The data attribute takes precedence. + * If neither are specified or if classid begins "clsid:", + * we can't handle this object. + */ + if(po->data == 0 && po->classid == 0) { + xfree(po); + return; + } + if(po->data == 0 && po->classid != 0) { + if(strnicmp(po->classid, "clsid:", 6) == 0) { + LOG(("ActiveX object - n0")); + xfree(po); + return; + } + else { + url = url_join(po->classid, po->codebase); + } + } + else { + url = url_join(po->data, po->codebase); + } + /* Check if the declared mime type is understandable. + * 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 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 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->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->type != NULL) - mime_type = content_lookup((const char*)po->type); - - else { - - /* failed to create mime type, clean up and exit */ - 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. - */ - 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; - } - else { /* not an image; is sys var set? */ - - /* Create Alias variable */ - alias_sysvar = create_sysvar(po->type); - if (alias_sysvar == NULL) { - - /* oh dear, you can't handle it */ - xfree(po); - xfree(alias_sysvar); - can_handle = FALSE; - } - else { - - /* Right, we have a variable. - * Does it actually exist? - */ - int used; - xos_read_var_val_size( - (const char*)alias_sysvar, - 0, os_VARTYPE_STRING, - &used, 0, os_VARTYPE_STRING); - - if (used == 0) { - - /* no, doesn't exist */ - xfree(po); - 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) { - - /* Get alternative HTML as we can't handle the object */ - 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); } /** - * create_mime_from_ext - * attempts to create a mime type from the filename extension. - * returns NULL if it fails. + * 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 */ -char* create_mime_from_ext(char* data){ + LOG(("mime type: %s", c->mime_type)); - char* ret; - os_error *e; + /* 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")); - LOG(("Creating Mime Type from File Extension")); + if(!can_handle) { + /* TODO: need to find a way of stopping the fetch + * if we can't handle this type + */ + } - ret = xcalloc(90, sizeof(char)); - ret = strrchr(data, '.'); - LOG(("Extension = %s", ret)); + /* 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. + */ - /* 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; + /* 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; + os_error *e; + + /* 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); + + if(used == 0) + /* No system variable set => no plugin available */ + ret = FALSE; + + if(ret) + c->data.plugin.sysvar = strdup(sysvar); + + xfree(sysvar); + + return ret; } /** - * create_sysvar - * attempts to create a system variable of the form Alias$@PlugInType_XXX - * where XXX is the filetype. - * returns NULL if unsuccessful. + * plugin_process_data + * processes data retrieved by the fetch process + * + * TODO: plugin stream protocol + * */ +void plugin_process_data(struct content *c, char *data, unsigned long size) +{ -char* create_sysvar(char* mime) { + /* 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* 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 - * attempts to negotiate with the plugin. - * also fetches the object for the plugin to handle. + * plugin_convert + * This isn't needed by the plugin system as all the data processing is done + * externally. Therefore, just tell NetSurf that everything's OK. */ -void plugin_fetch (struct plugin_object* po, - char* alias_sysvar/* insert vars here */) { - - LOG(("Entering plugin_fetch")); - xfree(po); - xfree(alias_sysvar); - return; +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. + */ } diff --git a/riscos/plugin.h b/riscos/plugin.h index 392bf0016..22083342f 100644 --- a/riscos/plugin.h +++ b/riscos/plugin.h @@ -8,6 +8,8 @@ #ifndef _NETSURF_RISCOS_PLUGIN_H_ #define _NETSURF_RISCOS_PLUGIN_H_ +#include "netsurf/content/content.h" + struct plugin_object { char* data; @@ -21,8 +23,16 @@ struct plugin_object { }; - +/* function definitions */ void plugin_decode(struct content* content, char* url, struct box* box, 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