From 5ac45472c7af8ccf686ea93791e491899889f087 Mon Sep 17 00:00:00 2001 From: Chris Young Date: Sun, 6 Mar 2011 13:58:02 +0000 Subject: Fix broken CONTENT_PLUGIN API. Add a default content handler for Amiga using the plugin interface, which passes unknown files (currently images only) through DataTypes. svn path=/trunk/netsurf/; revision=11924 --- Makefile.defaults | 4 + amiga/Makefile.target | 3 +- amiga/filetype.c | 102 +++++++++++---------- amiga/filetype.h | 4 + amiga/gui.c | 12 +-- amiga/icon.c | 3 +- amiga/menu.c | 9 +- amiga/plugin.c | 218 ++++++++++++++++++++++++++++++++++++++++++++ amiga/plugin.h | 37 ++++++++ content/content.c | 4 +- content/content_protected.h | 2 +- desktop/plugin.h | 59 ++++++++++++ render/box_construct.c | 3 + riscos/plugin.c | 25 ++++- riscos/plugin.h | 22 +---- 15 files changed, 421 insertions(+), 86 deletions(-) create mode 100644 amiga/plugin.c create mode 100644 amiga/plugin.h create mode 100644 desktop/plugin.h diff --git a/Makefile.defaults b/Makefile.defaults index effead2e7..e84d2935d 100644 --- a/Makefile.defaults +++ b/Makefile.defaults @@ -213,6 +213,10 @@ ifeq ($(TARGET),amiga) # Valid options: YES, NO (recommended) NETSURF_USE_AMIGA_ICON := YES + # Enable NetSurf's use of DataTypes for unknown filetypes + # Valid options: YES, NO + NETSURF_USE_PLUGINS := YES + # Enable NetSurf's use of libsvgtiny for displaying SVGs # (NB: Requires NETSURF_AMIGA_USE_CAIRO) # Valid options: YES, NO diff --git a/amiga/Makefile.target b/amiga/Makefile.target index 151590db8..a68167641 100644 --- a/amiga/Makefile.target +++ b/amiga/Makefile.target @@ -20,6 +20,7 @@ ifeq ($(HOST),amiga) $(eval $(call feature_enabled,MNG,,-llcms -ljpeg,PNG/JNG/MNG (libmng))) $(eval $(call feature_enabled,WEBP,-DWITH_WEBP,-lwebp -lvpx,WebP (libwebp))) $(eval $(call feature_enabled,AMIGA_ICON,-DWITH_AMIGA_ICON,,Amiga icon )) + $(eval $(call feature_enabled,PLUGINS,-DWITH_PLUGIN,,DataTypes images)) CFLAGS += -D__USE_INLINE__ -D__USE_BASETYPE__ -I /SDK/local/common/include/libpng12 LDFLAGS += -lxml2 -lcurl -lrtmp -lpthread -lregex -lauto -lpbl @@ -54,7 +55,7 @@ endif # ---------------------------------------------------------------------------- # S_AMIGA are sources purely for the Amiga build -S_AMIGA := gui.c tree.c history.c hotlist.c schedule.c \ +S_AMIGA := gui.c tree.c history.c hotlist.c schedule.c plugin.c \ thumbnail.c misc.c bitmap.c font.c filetype.c utf8.c login.c \ plotters.c object.c menu.c save_pdf.c arexx.c version.c \ cookies.c context_menu.c clipboard.c save_complete.c \ diff --git a/amiga/filetype.c b/amiga/filetype.c index 68ccca0bc..a3606805b 100644 --- a/amiga/filetype.c +++ b/amiga/filetype.c @@ -18,6 +18,7 @@ #include #include +#include "amiga/filetype.h" #include "content/fetch.h" #include "content/content_type.h" #include "utils/log.h" @@ -37,7 +38,6 @@ const char *fetch_filetype(const char *unix_path) STRPTR ttype = NULL; struct DiskObject *dobj = NULL; BPTR lock = 0; - struct DataTypeHeader *dth = NULL; struct DataType *dtn; BOOL found = FALSE; @@ -80,53 +80,7 @@ const char *fetch_filetype(const char *unix_path) { if (dtn = ObtainDataTypeA (DTST_FILE, (APTR)lock, NULL)) { - dth = dtn->dtn_Header; - - switch(dth->dth_GroupID) - { - case GID_SYSTEM: - if(strcmp("directory",dth->dth_BaseName)==0) - { - strcpy(mimetype,"application/x-netsurf-directory"); - } - else if(strcmp("binary",dth->dth_BaseName)==0) - { - strcpy(mimetype,"application/octet-stream"); - } - else sprintf(mimetype,"application/%s",dth->dth_BaseName); - break; - case GID_TEXT: - case GID_DOCUMENT: - if(strcmp("ascii",dth->dth_BaseName)==0) - { - strcpy(mimetype,"text/plain"); - } - else if(strcmp("simplehtml",dth->dth_BaseName)==0) - { - strcpy(mimetype,"text/html"); - } - else - { - sprintf(mimetype,"text/%s",dth->dth_BaseName); - } - break; - case GID_SOUND: - case GID_INSTRUMENT: - case GID_MUSIC: - sprintf(mimetype,"audio/%s",dth->dth_BaseName); - break; - case GID_PICTURE: - sprintf(mimetype,"image/%s",dth->dth_BaseName); - if(strcmp("sprite",dth->dth_BaseName)==0) - { - strcpy(mimetype,"image/x-riscos-sprite"); - } - break; - case GID_ANIMATION: - case GID_MOVIE: - sprintf(mimetype,"video/%s",dth->dth_BaseName); - break; - } + ami_datatype_to_mimetype(dtn, &mimetype); found = TRUE; ReleaseDataType(dtn); } @@ -214,3 +168,55 @@ const char *ami_content_type_to_file_type(content_type type) break; } } + +void ami_datatype_to_mimetype(struct DataType *dtn, char *mimetype) +{ + struct DataTypeHeader *dth = dtn->dtn_Header; + + switch(dth->dth_GroupID) + { + case GID_TEXT: + case GID_DOCUMENT: + if(strcmp("ascii",dth->dth_BaseName)==0) + { + strcpy(mimetype,"text/plain"); + } + else if(strcmp("simplehtml",dth->dth_BaseName)==0) + { + strcpy(mimetype,"text/html"); + } + else + { + sprintf(mimetype,"text/%s",dth->dth_BaseName); + } + break; + case GID_SOUND: + case GID_INSTRUMENT: + case GID_MUSIC: + sprintf(mimetype,"audio/%s",dth->dth_BaseName); + break; + case GID_PICTURE: + sprintf(mimetype,"image/%s",dth->dth_BaseName); + if(strcmp("sprite",dth->dth_BaseName)==0) + { + strcpy(mimetype,"image/x-riscos-sprite"); + } + break; + case GID_ANIMATION: + case GID_MOVIE: + sprintf(mimetype,"video/%s",dth->dth_BaseName); + break; + case GID_SYSTEM: + default: + if(strcmp("directory",dth->dth_BaseName)==0) + { + strcpy(mimetype,"application/x-netsurf-directory"); + } + else if(strcmp("binary",dth->dth_BaseName)==0) + { + strcpy(mimetype,"application/octet-stream"); + } + else sprintf(mimetype,"application/%s",dth->dth_BaseName); + break; + } +} diff --git a/amiga/filetype.h b/amiga/filetype.h index 7fb958571..b7a1a54a9 100644 --- a/amiga/filetype.h +++ b/amiga/filetype.h @@ -18,5 +18,9 @@ #ifndef AMIGA_FILETYPE_H #define AMIGA_FILETYPE_H +#include "content/content_type.h" +#include + const char *ami_content_type_to_file_type(content_type type); +void ami_datatype_to_mimetype(struct DataType *dtn, char *mimetype); #endif diff --git a/amiga/gui.c b/amiga/gui.c index f95951e57..d4352a9f1 100755 --- a/amiga/gui.c +++ b/amiga/gui.c @@ -3154,8 +3154,8 @@ void ami_do_redraw_limits(struct gui_window *g, struct browser_window *bw, clip.y0 = (y0 - sy) + bbox->Top; clip.x1 = (x1 - sx) + bbox->Left; clip.y1 = (y1 - sy) + bbox->Top; - posx = bbox->Left - sx; /* wrong */ - posy = bbox->Top - sy; /* wrong */ + posx = bbox->Left - sx; + posy = bbox->Top - sy; } if(browser_window_redraw(bw, posx, posy, &clip)) @@ -3604,12 +3604,12 @@ void gui_window_set_icon(struct gui_window *g, hlcache_handle *icon) if ((icon != NULL) && (content_get_status(icon) != CONTENT_STATUS_READY) && (content_get_status(icon) != CONTENT_STATUS_DONE)) return; - +#ifdef WITH_BMP if ((icon != NULL) && (content_get_type(icon) == CONTENT_ICO)) { nsico_set_bitmap_from_size(icon, 16, 16); } - +#endif if ((icon != NULL) && (content_get_bitmap(icon) != NULL)) { bm = ami_getcachenativebm(content_get_bitmap(icon), 16, 16, @@ -3661,12 +3661,12 @@ void gui_window_set_search_ico(hlcache_handle *ico) if(IsMinListEmpty(window_list)) return; if(option_kiosk_mode == true) return; if (ico == NULL) ico = search_web_ico(); - +#ifdef WITH_BMP if ((ico != NULL) && (content_get_type(ico) == CONTENT_ICO)) { nsico_set_bitmap_from_size(ico, 16, 16); } - +#endif if ((ico != NULL) && (content_get_bitmap(ico) != NULL)) { bm = ami_getcachenativebm(content_get_bitmap(ico), 16, 16, NULL); diff --git a/amiga/icon.c b/amiga/icon.c index 57827adeb..86d01bcd7 100644 --- a/amiga/icon.c +++ b/amiga/icon.c @@ -317,11 +317,12 @@ void ami_superimpose_favicon(char *path, struct hlcache_handle *icon, char *type if((format == IDFMT_DIRECTMAPPED) || (format == IDFMT_PALETTEMAPPED)) { +#ifdef WITH_BMP if ((icon != NULL) && (content_get_type(icon) == CONTENT_ICO)) { nsico_set_bitmap_from_size(icon, 16, 16); } - +#endif if ((icon != NULL) && (content_get_bitmap(icon) != NULL)) { bm = ami_getcachenativebm(content_get_bitmap(icon), 16, 16, NULL); diff --git a/amiga/menu.c b/amiga/menu.c index d2c828da3..f70ace127 100755 --- a/amiga/menu.c +++ b/amiga/menu.c @@ -862,6 +862,7 @@ static const ULONG ami_asl_mime_hook(struct Hook *mh,struct FileRequester *fr,st char fname[1024]; BOOL ret = FALSE; char *mt = NULL; + content_type ct; if(ap->ap_Info.fib_DirEntryType > 0) return(TRUE); @@ -869,8 +870,14 @@ static const ULONG ami_asl_mime_hook(struct Hook *mh,struct FileRequester *fr,st AddPart(fname,ap->ap_Info.fib_FileName,1024); mt = fetch_mimetype(fname); + ct = content_lookup(mt); + + if(ct != CONTENT_OTHER) ret = TRUE; + +#ifdef WITH_PLUGIN + if(ct == CONTENT_PLUGIN) ret = plugin_handleable(mt); +#endif - if(content_lookup(mt) != CONTENT_OTHER) ret = TRUE; free(mt); return ret; } diff --git a/amiga/plugin.c b/amiga/plugin.c new file mode 100644 index 000000000..b49fe349b --- /dev/null +++ b/amiga/plugin.c @@ -0,0 +1,218 @@ +/* + * Copyright 2011 Chris Young + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** \file + * Temporary "plugin" to pass unknown MIME types to DataTypes (implementation) +*/ + +#ifdef WITH_PLUGIN +#include "amiga/filetype.h" +#include "amiga/gui.h" +#include "amiga/plugin.h" +#include "content/content_protected.h" +#include "desktop/plotters.h" +#include "render/box.h" +#include "utils/log.h" +#include "utils/messages.h" + +#include +#include +#include + +bool plugin_create(struct content *c, const struct http_parameter *params) +{ + LOG(("plugin_create")); + + return true; +} + +bool plugin_convert(struct content *c) +{ + LOG(("plugin_convert")); + + union content_msg_data msg_data; + int width, height; + char title[100]; + const uint8 *data; + UBYTE *bm_buffer; + ULONG size; + Object *dto; + struct BitMapHeader *bmh; + unsigned int bm_flags = BITMAP_NEW; + int bm_format = PBPAFMT_RGBA; + + /* This is only relevant for picture datatypes... */ + + data = (uint8 *)content__get_source_data(c, &size); + + if(c->data.plugin.dto = NewDTObject(NULL, + DTA_SourceType, DTST_MEMORY, + DTA_SourceAddress, data, + DTA_SourceSize, size, + DTA_GroupID, GID_PICTURE, + PDTA_DestMode, PMODE_V43, + TAG_DONE)) + { + if(GetDTAttrs(c->data.plugin.dto, PDTA_BitMapHeader, &bmh, TAG_DONE)) + { + width = (int)bmh->bmh_Width; + height = (int)bmh->bmh_Height; + + c->bitmap = bitmap_create(width, height, bm_flags); + if (!c->bitmap) { + msg_data.error = messages_get("NoMemory"); + content_broadcast(c, CONTENT_MSG_ERROR, msg_data); + return false; + } + + bm_buffer = bitmap_get_buffer(c->bitmap); + + IDoMethod(c->data.plugin.dto, PDTM_READPIXELARRAY, + bm_buffer, bm_format, bitmap_get_rowstride(c->bitmap), + 0, 0, width, height); + } + else return false; + } + else return false; + + c->width = width; + c->height = height; + +/* + snprintf(title, sizeof(title), "image (%lux%lu, %lu bytes)", + width, height, size); + content__set_title(c, title); +*/ + + bitmap_modified(c->bitmap); + + content_set_ready(c); + content_set_done(c); + + content_set_status(c, ""); + return true; +} + +void plugin_destroy(struct content *c) +{ + LOG(("plugin_destroy")); + + if (c->bitmap != NULL) + bitmap_destroy(c->bitmap); + + DisposeDTObject(c->data.plugin.dto); + + return; +} + +bool plugin_redraw(struct content *c, int x, int y, + int width, int height, const struct rect *clip, + float scale, colour background_colour) +{ + LOG(("plugin_redraw")); + + return plot.bitmap(x, y, width, height, + c->bitmap, background_colour, BITMAPF_NONE); +} + +/** + * Handle a window containing a CONTENT_PLUGIN being opened. + * + * \param c content that has been opened + * \param bw browser window containing the content + * \param page content of type CONTENT_HTML containing c, or 0 if not an + * object within a page + * \param index index in page->data.html.object, or 0 if not an object + * \param box box containing c, or 0 if not an object + * \param params object parameters, or 0 if not an object + */ +void plugin_open(struct content *c, struct browser_window *bw, + struct content *page, unsigned int index, struct box *box, + struct object_params *params) +{ + LOG(("plugin_open")); + + return; +} + +void plugin_close(struct content *c) +{ + LOG(("plugin_close")); + return; +} + +void plugin_reformat(struct content *c, int width, int height) +{ + LOG(("plugin_reformat")); + return; +} + +bool plugin_clone(const struct content *old, struct content *new_content) +{ + LOG(("plugin_clone")); + /* We "clone" the old content by replaying creation and conversion */ + if (plugin_create(new_content, NULL) == false) + return false; + + if (old->status == CONTENT_STATUS_READY || + old->status == CONTENT_STATUS_DONE) { + if (plugin_convert(new_content) == false) + return false; + } + + return true; +} + +/** + * Determines whether a content is handleable by a plugin + * + * \param mime_type The mime type of the content + * \return true if the content is handleable, false otherwise + */ +bool plugin_handleable(const char *mime_type) +{ + LOG(("plugin_handleable %s", mime_type)); + + char dt_mime[50]; + struct DataType *dt, *prevdt = NULL; + bool found = false; + + while((dt = ObtainDataType(DTST_RAM, NULL, + DTA_DataType, prevdt, + DTA_GroupID, GID_PICTURE, // we only support images for now + TAG_DONE)) != NULL) + { + ReleaseDataType(prevdt); + prevdt = dt; + ami_datatype_to_mimetype(dt, &dt_mime); + + LOG(("Guessed MIME from DT: %s", dt_mime)); + + if(strcmp(dt_mime, mime_type) == 0) + { + found = true; + break; + } + } + + ReleaseDataType(prevdt); + + return found; +} + +#endif diff --git a/amiga/plugin.h b/amiga/plugin.h new file mode 100644 index 000000000..669c5af5a --- /dev/null +++ b/amiga/plugin.h @@ -0,0 +1,37 @@ +/* + * Copyright 2011 Chris Young + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef NETSURF_AMIGA_PLUGIN_H_ +#define NETSURF_AMIGA_PLUGIN_H_ + +#ifdef WITH_PLUGIN + +#include + +#include "desktop/plugin.h" + +struct content_plugin_data { + Object *dto; + int x; + int y; + int w; + int h; +}; + +#endif /* WITH_PLUGIN */ +#endif diff --git a/content/content.c b/content/content.c index 41d922d62..427cc6313 100644 --- a/content/content.c +++ b/content/content.c @@ -69,7 +69,7 @@ #include "riscos/draw.h" #endif #ifdef WITH_PLUGIN -#include "riscos/plugin.h" +#include "desktop/plugin.h" #endif #ifdef WITH_ARTWORKS #include "riscos/artworks.h" @@ -367,7 +367,7 @@ static const struct handler_entry handler_map[] = { #endif #ifdef WITH_PLUGIN {plugin_create, 0, plugin_convert, - plugin_reformat, plugin_destroy, 0, plugin_redraw, 0, 0, 0, + plugin_reformat, plugin_destroy, 0, 0, 0, plugin_redraw, 0, plugin_open, plugin_close, plugin_clone, true}, #endif diff --git a/content/content_protected.h b/content/content_protected.h index 50ece50a5..a37d96c42 100644 --- a/content/content_protected.h +++ b/content/content_protected.h @@ -52,7 +52,7 @@ #include "image/ico.h" #endif #ifdef WITH_PLUGIN -#include "riscos/plugin.h" +#include "desktop/plugin.h" #endif #ifdef WITH_MNG #include "image/mng.h" diff --git a/desktop/plugin.h b/desktop/plugin.h new file mode 100644 index 000000000..3fb207e8e --- /dev/null +++ b/desktop/plugin.h @@ -0,0 +1,59 @@ +/* + * Copyright 2011 Chris Young + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file Content handler for plugins (interface) + */ + +#ifndef NETSURF_DESKTOP_PLUGIN_H_ +#define NETSURF_DESKTOP_PLUGIN_H_ + +#ifdef WITH_PLUGIN + +#include + +#if defined(riscos) +#include "riscos/plugin.h" +#elif defined(nsamiga) +#include "amiga/plugin.h" +#endif + +struct box; +struct browser_window; +struct content; +struct object_params; +struct rect; +struct http_parameter; + +/* function definitions */ +bool plugin_handleable(const char *mime_type); +bool plugin_create(struct content *c, const struct http_parameter *params); +bool plugin_convert(struct content *c); +void plugin_reformat(struct content *c, int width, int height); +void plugin_destroy(struct content *c); +bool plugin_redraw(struct content *c, int x, int y, + int width, int height, const struct rect *clip, + float scale, colour background_colour); +void plugin_open(struct content *c, struct browser_window *bw, + struct content *page, unsigned int index, struct box *box, + struct object_params *params); +void plugin_close(struct content *c); +bool plugin_clone(const struct content *old, struct content *new_content); + +#endif /* WITH_PLUGIN */ +#endif diff --git a/render/box_construct.c b/render/box_construct.c index 44fcb54b1..ae7c1787b 100644 --- a/render/box_construct.c +++ b/render/box_construct.c @@ -78,6 +78,9 @@ static const content_type image_types[] = { #ifdef WITH_DRAW CONTENT_DRAW, #endif +#ifdef WITH_PLUGIN + CONTENT_PLUGIN, +#endif #ifdef WITH_ARTWORKS CONTENT_ARTWORKS, #endif diff --git a/riscos/plugin.c b/riscos/plugin.c index 25b2afe54..c3065ed37 100644 --- a/riscos/plugin.c +++ b/riscos/plugin.c @@ -183,8 +183,7 @@ static void plugin_fetch_callback(fetch_msg msg, void *p, const void *data, * \param params Parameters associated with the content * \return true on success, false otherwise */ -bool plugin_create(struct content *c, struct content *parent, - const char *params[]) +bool plugin_create(struct content *c, const http_parameter *params) { LOG(("plugin_create")); c->data.plugin.bw = 0; @@ -213,11 +212,9 @@ bool plugin_create(struct content *c, struct content *parent, * \param height Height of available space * \return true on success, false otherwise */ -bool plugin_convert(struct content *c, int width, int height) +bool plugin_convert(struct content *c) { LOG(("plugin_convert")); - c->width = width; - c->height = height; content_set_ready(c); content_set_done(c); @@ -535,6 +532,24 @@ void plugin_reformat(struct content *c, int width, int height) } } + +bool plugin_clone(const struct content *old, struct content *new_content) +{ + LOG(("plugin_clone")); + /* We "clone" the old content by replaying creation and conversion */ + if (plugin_create(new_content, NULL) == false) + return false; + + if (old->status == CONTENT_STATUS_READY || + old->status == CONTENT_STATUS_DONE) { + if (plugin_convert(new_content) == false) + return false; + } + + return true; +} + + /** * Creates a system variable from the mimetype * diff --git a/riscos/plugin.h b/riscos/plugin.h index d23e6539e..a3586b284 100644 --- a/riscos/plugin.h +++ b/riscos/plugin.h @@ -22,16 +22,12 @@ #include "utils/config.h" #ifdef WITH_PLUGIN +#include "desktop/plugin.h" #include #include "oslib/plugin.h" #include "oslib/wimp.h" -struct box; -struct browser_window; -struct content; -struct object_params; struct plugin_stream; -struct rect; /* We have one content per instance of a plugin */ struct content_plugin_data { @@ -50,22 +46,6 @@ struct content_plugin_data { struct plugin_stream *streams; /* list of active streams */ }; -/* function definitions */ -bool plugin_handleable(const char *mime_type); -void plugin_msg_parse(wimp_message *message, int ack); -bool plugin_create(struct content *c, struct content *parent, - const char *params[]); -bool plugin_convert(struct content *c, int width, int height); -void plugin_reformat(struct content *c, int width, int height); -void plugin_destroy(struct content *c); -bool plugin_redraw(struct content *c, int x, int y, - int width, int height, const struct rect *clip, - float scale, colour background_colour); -void plugin_open(struct content *c, struct browser_window *bw, - struct content *page, unsigned int index, struct box *box, - struct object_params *params); -void plugin_close(struct content *c); - /* message handlers */ void plugin_open_msg(wimp_message *message); void plugin_opening(wimp_message *message); -- cgit v1.2.3