mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-12-22 12:12:35 +03:00
[project @ 2003-07-07 22:10:51 by jmb]
Rewrite plugin system backend. svn path=/import/netsurf/; revision=210
This commit is contained in:
parent
1abf8018a9
commit
133c3ee759
@ -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
|
||||
|
@ -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:
|
||||
<VAR>, <ABBR> and <ACRONYM> tags
|
||||
<Q> tag
|
||||
|
||||
Lists
|
||||
Lists:
|
||||
<LI>
|
||||
<OL>,<UL>
|
||||
|
||||
Tables:
|
||||
Borders,
|
||||
row spanning
|
||||
row spanning (only rowspan=0 needs implementing)
|
||||
column spanning (only colspan=0 needs implementing)
|
||||
|
||||
Images:
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
120
render/box.c
120
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};
|
||||
}
|
||||
|
@ -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);
|
||||
|
475
riscos/plugin.c
475
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 <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 (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.
|
||||
*/
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user