summaryrefslogtreecommitdiff
path: root/riscos/plugin.c
diff options
context:
space:
mode:
authorMichael Drake <tlsa@netsurf-browser.org>2011-10-06 10:21:50 +0000
committerMichael Drake <tlsa@netsurf-browser.org>2011-10-06 10:21:50 +0000
commit149ac31cacdd75871938fa9930376d6d792922fc (patch)
treea1cc2935b26845c57b661f55d34f02cc5c5c105a /riscos/plugin.c
parent22f2ffeeeaf1c0f35306a969b8c99be50887edc3 (diff)
downloadnetsurf-149ac31cacdd75871938fa9930376d6d792922fc.tar.gz
netsurf-149ac31cacdd75871938fa9930376d6d792922fc.tar.bz2
Remove old plugin.c.
svn path=/trunk/netsurf/; revision=12967
Diffstat (limited to 'riscos/plugin.c')
-rw-r--r--riscos/plugin.c1859
1 files changed, 0 insertions, 1859 deletions
diff --git a/riscos/plugin.c b/riscos/plugin.c
deleted file mode 100644
index d39944d07..000000000
--- a/riscos/plugin.c
+++ /dev/null
@@ -1,1859 +0,0 @@
-/*
- * Copyright 2003,4 John M Bell <jmb202@ecs.soton.ac.uk>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-/** \file
- * Acorn Plugin protocol (implementation)
- *
- * This file implements the Acorn plugin protocol.
- * See http://www.ecs.soton.ac.uk/~jmb202/riscos/acorn/funcspec.html
- * for more details.
- *
- * The are still a number of outstanding issues:
- *
- * Stream Protocol:
- * Streaming data from a plugin is not supported
- *
- * Messages:
- * Most Plugin_Opening flags not supported
- * No support for Plugin_Focus, Plugin_Busy, Plugin_Action
- * No support for Plugin_Abort, Plugin_Inform, Plugin_Informed
- * Plugin_URL_Access ignores POST requests.
- *
- * Helpers are not supported (system variable detection is #if 0ed out)
- */
-
-#include "utils/config.h"
-#ifdef WITH_PLUGIN
-
-#include <assert.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "oslib/mimemap.h"
-#include "oslib/os.h"
-#include "oslib/osfile.h"
-#include "oslib/osfind.h"
-#include "oslib/osgbpb.h"
-#include "oslib/plugin.h"
-#include "oslib/wimp.h"
-#include "utils/config.h"
-#include "content/content_protected.h"
-#include "content/fetch.h"
-#include "desktop/browser.h"
-#include "desktop/gui.h"
-#include "render/html.h"
-#include "render/box.h"
-#include "riscos/gui.h"
-#include "riscos/options.h"
-#include "riscos/plugin.h"
-#include "riscos/toolbar.h"
-#include "utils/log.h"
-#include "utils/messages.h"
-#include "utils/schedule.h"
-#include "utils/talloc.h"
-#include "utils/url.h"
-#include "utils/utils.h"
-
-struct plugin_stream;
-
-/* We have one content per instance of a plugin */
-typedef struct plugin_content {
- struct content base;
-
- struct browser_window *bw; /* window containing this content */
- struct content *page; /* parent content */
- struct box *box; /* box containing this content */
- char *taskname; /* plugin task to launch */
- char *filename; /* filename of parameters file */
- bool opened; /* has this plugin been opened? */
- int repeated; /* indication of opening state */
- unsigned int browser; /* browser handle */
- unsigned int plugin; /* plugin handle */
- unsigned int plugin_task; /* plugin task handle */
- bool reformat_pending; /* is a reformat pending? */
- int width, height; /* reformat width & height */
- struct plugin_stream *streams; /* list of active streams */
-} plugin_content;
-
-typedef enum {
- PLUGIN_PARAMETER_DATA = 1,
- PLUGIN_PARAMETER_URL = 2,
- PLUGIN_PARAMETER_OBJECT = 3,
- PLUGIN_PARAMETER_SPECIAL = 4
-} plugin_parameter_type;
-
-struct plugin_param_item {
- plugin_parameter_type type;
- int rsize;
- int nsize;
- char *name;
- int npad;
- int vsize;
- char *value;
- int vpad;
- int msize;
- char *mime_type;
- int mpad;
-
- struct plugin_param_item *next;
-};
-
-struct plugin_stream {
- struct plugin_stream *next; /* next in list */
-
- plugin_content *plugin; /* the plugin content */
- plugin_content *c; /* the content being fetched for
- * this stream (may be the same as
- * plugin iff we've been asked to
- * fetch the data resource for the
- * plugin task) */
-
- /* browser stream handle is the address of this struct in memory */
- plugin_s pluginh; /* plugin stream handle */
-
- /* We only support stream types 0 and 3 (Normal and As file only)
- * Type 1 (Seek only) streams are treated as type 0.
- * Type 2 (As file) streams are treated as type 3.
- * Streams are never seekable.
- */
- enum { NORMAL = plugin_STREAM_NEW_TYPE_NORMAL,
- AS_FILE = plugin_STREAM_NEW_TYPE_AS_FILE_ONLY } type;
- union {
- struct {
- char *datafile; /* filename of filestreamed file */
-
- /* we need this flag as we should only send stream
- * destroy once. This struct may still persist after
- * the stream has ended in the case where it's a
- * file only stream, as we've still got to destroy
- * the temporary file. We can only do this when
- * we're certain the plugin's no longer using it
- * (i.e. after we've sent the plugin close message)
- */
- bool destroyed; /* have we destroyed this stream? */
- bool waiting; /* waiting for data to arrive */
- } file;
- struct {
- unsigned int consumed; /* size of data consumed by plugin */
- /* The following is nasty, but necessary to prevent
- * a race condition between the plugin application
- * handling the stream write message and our fetch
- * code reallocing the data buffer (and potentially
- * relocating it)
- */
-#define PLUGIN_STREAM_BUFFER_SIZE (32*1024)
- char buffer[PLUGIN_STREAM_BUFFER_SIZE]; /* buffer for data chunk */
- } normal;
- } stream;
-};
-
-#define PLUGIN_SCHEDULE_WAIT (40) /* time (in cs) to wait between processing data chunks */
-
-#define PLUGIN_PREFIX "Alias$@PlugInType_"
-#define HELPER_PREFIX "Alias$@HelperType_"
-#define SYSVAR_BUF_SIZE (25) /* size of buffer to hold system variable */
-
-static nserror plugin_create(const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
- llcache_handle *llcache, const char *fallback_charset,
- bool quirks, struct content **c);
-static nserror plugin_create_plugin_data(plugin_content *c);
-static bool plugin_convert(struct content *c);
-static void plugin_reformat(struct content *c, int width, int height);
-static void plugin_destroy(struct content *c);
-static bool plugin_redraw(struct content *c, int x, int y,
- int width, int height, const struct rect *clip,
- float scale, colour background_colour);
-static void plugin_open(struct content *c, struct browser_window *bw,
- struct content *page, struct box *box,
- struct object_params *params);
-static void plugin_close(struct content *c);
-static nserror plugin_clone(const struct content *old, struct content **newc);
-
-static bool plugin_create_sysvar(lwc_string *mime_type, char *sysvar,
- bool helper);
-static void plugin_create_stream(plugin_content *plugin, plugin_content *c,
- const char *url);
-static bool plugin_send_stream_new(struct plugin_stream *p);
-static void plugin_write_stream(struct plugin_stream *p,
- unsigned int consumed);
-static void plugin_stream_write_callback(void *p);
-static void plugin_stream_as_file_callback(void *p);
-static void plugin_write_stream_as_file(struct plugin_stream *p);
-static void plugin_destroy_stream(struct plugin_stream *p,
- plugin_stream_destroy_reason reason);
-static bool plugin_write_parameters_file(plugin_content *c,
- struct object_params *params, const char *base);
-static int plugin_calculate_rsize(const char* name, const char* data,
- const char* mime);
-static bool plugin_add_item_to_pilist(struct plugin_param_item **pilist,
- plugin_parameter_type type, const char* name,
- const char* value, const char* mime_type);
-static char *plugin_get_string_value(os_string_value string, char *msg);
-static bool plugin_active(struct content *c);
-static void plugin_stream_free(struct plugin_stream *p);
-static bool plugin_start_fetch(struct plugin_stream *p, const char *url);
-static void plugin_stream_callback(content_msg msg, struct content *c,
- intptr_t p1, intptr_t p2, union content_msg_data data);
-static void plugin_fetch_callback(fetch_msg msg, void *p, const void *data,
- unsigned long size);
-
-nserror plugin_create(const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
- llcache_handle *llcache, const char *fallback_charset,
- bool quirks, struct content **c)
-{
- plugin_content *plugin;
- nserror error;
-
- plugin = talloc_zero(0, plugin_content);
- if (plugin == NULL)
- return NSERROR_NOMEM;
-
- error = content__init(&plugin->base, handler, imime_type, params,
- llcache, fallback_charset, quirks);
- if (error != NSERROR_OK) {
- talloc_free(plugin);
- return error;
- }
-
- error = plugin_create_plugin_data(plugin);
- if (error != NSERROR_OK) {
- talloc_free(plugin);
- return error;
- }
-
- *c = (struct content *) plugin;
-
- return NSERROR_OK;
-}
-
-/**
- * Initialises plugin system in readiness for receiving object data
- *
- * \param c The content to hold the data
- * \return NSERROR_OK on success, appropriate error otherwise
- */
-nserror plugin_create_plugin_data(plugin_content *c)
-{
- LOG(("plugin_create"));
- c->bw = 0;
- c->page = 0;
- c->box = 0;
- c->taskname = 0;
- c->filename = 0;
- c->opened = false;
- c->repeated = 0;
- c->browser = 0;
- c->plugin = 0;
- c->plugin_task = 0;
- c->reformat_pending = false;
- c->width = 0;
- c->height = 0;
- c->streams = 0;
-
- return NSERROR_OK;
-}
-
-/**
- * Convert a plugin ready for display (does nothing)
- *
- * \param c The content to convert
- * \param width Width of available space
- * \param height Height of available space
- * \return true on success, false otherwise
- */
-bool plugin_convert(struct content *c)
-{
- LOG(("plugin_convert"));
-
- content_set_ready(c);
- content_set_done(c);
-
- return true;
-}
-
-/**
- * Destroy a plugin content
- *
- * \param c The content to destroy
- */
-void plugin_destroy(struct content *c)
-{
- plugin_content *plugin = (plugin_content *) c;
-
- LOG(("plugin_destroy"));
- if (plugin->taskname)
- free(plugin->taskname);
- if (plugin->filename)
- free(plugin->filename);
-}
-
-/**
- * Redraw a content
- *
- * \param c The content to redraw
- * \param x Left of content box
- * \param y Top of content box
- * \param width Width of content box
- * \param height Height of content box
- * \param clip Clipping rectangle
- * \param scale Scale of page (1.0 = 100%)
- */
-bool plugin_redraw(struct content *c, int x, int y,
- int width, int height, const struct rect *clip,
- float scale, colour background_colour)
-{
- /* do nothing */
- LOG(("plugin_redraw"));
- return true;
-}
-
-
-/**
- * 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 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, struct box *box,
- struct object_params *params)
-{
- plugin_content *plugin = (plugin_content *) c;
- bool standalone = false, helper = false;
- const char *base;
- char sysvar[SYSVAR_BUF_SIZE];
- char *varval;
- plugin_full_message_open pmo;
- wimp_window_state state;
- os_error *error;
- lwc_string *mime_type;
-
- if (option_no_plugins)
- return;
-
- mime_type = content__get_mime_type(c);
-
- if (!params) {
- /* this is a standalone plugin, so fudge the parameters */
- params = calloc(1, sizeof(struct object_params));
- if (!params) {
- warn_user("NoMemory", 0);
- goto error;
- }
-
- params->data = strdup(content__get_url(c));
- if (!params->data) {
- warn_user("NoMemory", 0);
- goto error;
- }
-
- params->type = strndup(lwc_string_data(mime_type),
- lwc_string_length(mime_type));
- if (!params->type) {
- warn_user("NoMemory", 0);
- goto error;
- }
- standalone = true;
- }
-
- /* we only do this here because the box is needed by
- * write_parameters_file. Ideally it would be at the
- * end of this function with the other writes to plugin
- */
- plugin->box = box;
-
- if (params->codebase)
- base = params->codebase;
- else if (page)
- base = page->data.html.base_url;
- else
- base = c->url;
-
- LOG(("writing parameters file"));
- if (!plugin_write_parameters_file(plugin, params, base))
- goto error;
-
- /* get contents of Alias$@PlugInType_xxx variable */
- if (!plugin_create_sysvar(mime_type, sysvar, false))
- goto error;
-
- varval = getenv(sysvar);
- LOG(("%s: '%s'", sysvar, varval));
- if(!varval) {
-#if 0
- if (!plugin_create_sysvar(c->mime_type, sysvar, true))
- goto error;
- varval = getenv(sysvar);
- if (!varval)
- goto error;
- helper = true;
-#else
- goto error;
-#endif
- }
-
- /* The browser instance handle is the content struct pointer */
- plugin->browser = (unsigned int)c;
-
- pmo.size = 60;
- pmo.your_ref = 0;
- pmo.action = message_PLUG_IN_OPEN;
- pmo.flags = helper ? plugin_OPEN_AS_HELPER : 0;
- pmo.reserved = 0;
- pmo.browser = (plugin_b)plugin->browser;
- pmo.parent_window = bw->window->window;
-
- /* initial position/dimensions */
- if (standalone) {
- /* if standalone, try to fill the browser window */
- state.w = bw->window->window;
- error = xwimp_get_window_state(&state);
- if (error)
- goto error;
-
- pmo.bbox.x0 = 10;
- /* avoid toolbar */
- pmo.bbox.y1 = -10 - ro_toolbar_height(bw->window->toolbar);
- pmo.bbox.x1 = (state.visible.x1 - state.visible.x0) - 10;
- pmo.bbox.y0 = (state.visible.y0 - state.visible.y1) - 10;
- }
- else {
- /* open off the left hand edge of the work area */
- pmo.bbox.x0 = -100;
- pmo.bbox.x1 = pmo.bbox.y0 = 0;
- pmo.bbox.y1 = 100;
- }
-
- error = xmimemaptranslate_mime_type_to_filetype(
- lwc_string_data(mime_type), &pmo.file_type);
- if (error) {
- goto error;
- }
- pmo.filename.pointer = plugin->filename;
-
- plugin->repeated = 0;
-
- LOG(("sending message"));
- error = xwimp_send_message(wimp_USER_MESSAGE_RECORDED,
- (wimp_message *)&pmo, wimp_BROADCAST);
- if (error) {
- LOG(("xwimp_send_message: 0x%x: %s",
- error->errnum, error->errmess));
- goto error;
- }
-
- plugin->bw = bw;
- plugin->page = page;
- plugin->taskname = strdup(varval);
-
-error:
- /* clean up standalone stuff */
- if (standalone) {
- free(params->type);
- free(params->data);
- free(params);
- }
-
- lwc_string_unref(mime_type);
-
- LOG(("done"));
-}
-
-
-/**
- * Handle a window containing a CONTENT_PLUGIN being closed.
- *
- * \param c The content to close
- */
-void plugin_close(struct content *c)
-{
- plugin_content *plugin = (plugin_content *) c;
- struct plugin_stream *p, *q;
- plugin_full_message_close pmc;
- os_error *error;
-
- LOG(("plugin_close"));
-
- if (!plugin_active(c) || !plugin->opened)
- return;
-
- /* destroy all active streams */
- for (p = plugin->streams; p; p = q) {
- q = p->next;
-
- plugin_destroy_stream(p, plugin_STREAM_DESTROY_USER_REQUEST);
- }
-
- pmc.size = 32;
- pmc.your_ref = 0;
- pmc.action = message_PLUG_IN_CLOSE;
- pmc.flags = 0;
- pmc.browser = (plugin_b)plugin->browser;
- pmc.plugin = (plugin_p)plugin->plugin;
-
- LOG(("sending message"));
- error = xwimp_send_message(wimp_USER_MESSAGE_RECORDED,
- (wimp_message *)&pmc, (wimp_t)plugin->plugin_task);
- if (error) {
- return;
- }
-
- /* delete any temporary files */
- for (p = plugin->streams; p; p = q) {
- q = p->next;
-
- assert(p->type == AS_FILE);
-
- /* delete the data file used to send the
- * data to the plugin */
- xosfile_delete(p->stream.file.datafile, 0, 0, 0, 0, 0);
-
- /* and destroy the struct */
- free(p->stream.file.datafile);
- free(p);
- }
-
- /* paranoia */
- plugin->streams = 0;
-}
-
-/**
- * Reformat a plugin content on a page
- *
- * \param c The content to reformat
- * \param width New width
- * \param height New height
- */
-void plugin_reformat(struct content *c, int width, int height)
-{
- plugin_content *plugin = (plugin_content *) c;
- plugin_full_message_reshape pmr;
- int x, y;
- os_error *error;
-
- LOG(("plugin_reformat"));
-
- if (!plugin_active(c))
- return;
-
- /* if the plugin hasn't yet been opened, queue the reformat */
- if (!plugin->opened) {
- LOG(("queuing"));
- plugin->reformat_pending = true;
- plugin->width = width;
- plugin->height = height;
- return;
- }
-
- plugin->reformat_pending = false;
-
- /* top left of plugin area, relative to top left of browser window */
- if (plugin->box) {
- box_coords(plugin->box, &x, &y);
- }
- else {
- /* standalone */
- x = 10 / 2;
- /* avoid toolbar */
- y = (10 + ro_toolbar_height(
- plugin->bw->window->toolbar)) / 2;
- }
-
- pmr.size = 52;
- pmr.your_ref = 0;
- pmr.action = message_PLUG_IN_RESHAPE;
- pmr.flags = 0;
-
- pmr.plugin = (plugin_p)plugin->plugin;
- pmr.browser = (plugin_b)plugin->browser;
- pmr.parent_window = plugin->bw->window->window;
- pmr.bbox.x0 = x * 2;
- pmr.bbox.y1 = -y * 2;
-
- if (plugin->box) {
- pmr.bbox.x1 = pmr.bbox.x0 + plugin->box->width * 2;
- pmr.bbox.y0 = pmr.bbox.y1 - plugin->box->height * 2;
- }
- else {
- /* standalone */
- pmr.bbox.x1 = pmr.bbox.x0 + width * 2;
- pmr.bbox.y0 = pmr.bbox.y1 - height * 2;
- }
-
- LOG(("sending message"));
- error = xwimp_send_message(wimp_USER_MESSAGE, (wimp_message *) &pmr,
- (wimp_t)plugin->plugin_task);
- if (error) {
- return;
- }
-}
-
-
-nserror plugin_clone(const struct content *old, struct content **newc)
-{
- plugin_content *plugin;
- nserror error;
-
- LOG(("plugin_clone"));
-
- plugin = talloc_zero(0, plugin_content);
- if (plugin == NULL)
- return NSERROR_NOMEM;
-
- error = content__clone(old, &plugin->base);
- if (error != NSERROR_OK) {
- content_destroy(&plugin->base);
- return error;
- }
-
- /* We "clone" the old content by replaying creation and conversion */
- error = plugin_create_plugin_data(plugin);
- if (error != NSERROR_OK) {
- content_destroy(&plugin->base);
- return error;
- }
-
- if (old->status == CONTENT_STATUS_READY ||
- old->status == CONTENT_STATUS_DONE) {
- if (plugin_convert(&plugin->base) == false) {
- content_destroy(&plugin->base);
- return NSERROR_CLONE_FAILED;
- }
- }
-
- return NSERROR_OK;
-}
-
-
-/**
- * Creates a system variable from the mimetype
- *
- * \param mime_type The mime type
- * \param sysvar Pointer to buffer of length >= SYSVAR_BUF_SIZE into
- * which the string should be written
- * \param helper Whether we're interested in the helper variable
- * \return true on success, false otherwise.
- */
-bool plugin_create_sysvar(lwc_string *mime_type, char* sysvar, bool helper)
-{
- unsigned int *fv;
- os_error *e;
-
- e = xmimemaptranslate_mime_type_to_filetype(
- lwc_string_data(mime_type), (bits *) &fv);
- if (e) {
- return false;
- }
-
- snprintf(sysvar, SYSVAR_BUF_SIZE, "%s%03x",
- helper ? HELPER_PREFIX : PLUGIN_PREFIX,
- (unsigned int)fv);
-
- return true;
-}
-
-/**
- * Handle a bounced plugin_open message
- *
- * \param message The message to handle
- */
-void plugin_open_msg(wimp_message *message)
-{
- plugin_content *c;
- os_error *error;
- plugin_message_open *pmo = (plugin_message_open *)&message->data;
-
- /* retrieve our content */
- c = (plugin_content *)pmo->browser;
-
- /* check we expect this message */
- if (!c || !plugin_active(&c->base))
- return;
-
- LOG(("bounced"));
-
- /* bail if we've already tried twice */
- if (c->repeated >= 1)
- return;
-
- /* start plugin app */
- error = xwimp_start_task((char const*)c->taskname, 0);
- if (error) {
- return;
- }
-
- /* indicate we've already sent this message once */
- c->repeated++;
-
- /* and resend the message */
- LOG(("resending"));
- message->your_ref = 0;
- error = xwimp_send_message(wimp_USER_MESSAGE_RECORDED, message,
- wimp_BROADCAST);
- if (error) {
- return;
- }
-}
-
-/**
- * Handle a plugin_opening message
- *
- * \param message The message to handle
- */
-void plugin_opening(wimp_message *message)
-{
- plugin_content *c;
- plugin_message_opening *pmo =
- (plugin_message_opening *)&message->data;
-
- /* retrieve our content */
- c = (plugin_content *)pmo->browser;
-
- /* check we expect this message */
- if (!c || !plugin_active(&c->base))
- return;
-
- c->repeated = 2; /* make sure open_msg does nothing */
- c->plugin = (unsigned int)pmo->plugin;
- c->plugin_task = (unsigned int)message->sender;
- c->opened = true;
-
- LOG(("opening"));
-
- /* if there's a reformat pending, do so now */
- if (c->reformat_pending) {
- LOG(("do pending reformat"));
- plugin_reformat(&c->base, c->width, c->height);
- }
-
- if (pmo->flags & plugin_OPENING_WANTS_DATA_FETCHING) {
- LOG(("wants stream"));
- plugin_create_stream(c, c, NULL);
- }
-
- if (!(pmo->flags & plugin_OPENING_WILL_DELETE_PARAMETERS)) {
- LOG(("we delete file"));
- /* we don't care if this fails */
- xosfile_delete(c->filename, 0, 0, 0, 0, 0);
- }
-}
-
-/**
- * Handle a bounced plugin_close message
- *
- * \param message The message to handle
- */
-void plugin_close_msg(wimp_message *message)
-{
- plugin_message_close *pmc = (plugin_message_close *)&message->data;
- /* not necessarily true - some plugins don't stop this bouncing */
- LOG(("failed to close plugin: %p", pmc->plugin));
-}
-
-/**
- * Handle a plugin_closed message
- *
- * \param message The message to handle
- */
-void plugin_closed(wimp_message *message)
-{
- plugin_content *c;
- plugin_message_closed *pmc = (plugin_message_closed *)&message->data;
-
- /* retrieve our content */
- c = (plugin_content*)pmc->browser;
-
- /* check we expect this message */
- if (!c || !plugin_active(&c->base))
- return;
-
- LOG(("died"));
- c->opened = false;
-
- if (pmc->flags & plugin_CLOSED_WITH_ERROR) {
- LOG(("plugin_closed: 0x%x: %s", pmc->error_number,
- pmc->error_text));
- /* not really important enough to do a warn_user */
- gui_window_set_status(c->bw->window, pmc->error_text);
- }
-}
-
-/**
- * Handles receipt of plugin_reshape_request messages
- *
- * \param message The message to handle
- */
-void plugin_reshape_request(wimp_message *message)
-{
- plugin_content *c;
- struct box *b;
- union content_msg_data data;
- plugin_message_reshape_request *pmrr = (plugin_message_reshape_request*)&message->data;
-
- /* retrieve our content */
- c = (plugin_content *)pmrr->browser;
-
- /* check we expect this message */
- if (!c || !plugin_active(&c->base))
- return;
-
- LOG(("handling reshape request"));
-
- /* we can be called prior to the box content being set up,
- * so we set it up here. This is ok as the content won't change
- * under us. However, the box may not exist (if we're standalone)
- */
- if (c->box)
- c->box->object = c;
-
- /* should probably shift by x and y eig values here */
- c->base.width = pmrr->size.x / 2;
- c->base.height = pmrr->size.y / 2;
-
- if (c->box)
- /* invalidate parent box widths */
- for (b = c->box->parent; b; b = b->parent)
- b->max_width = UNKNOWN_MAX_WIDTH;
-
- if (c->page)
- /* force a reformat of the parent */
- content__reformat(c->page, c->page->available_width, 0);
-
- /* redraw the window */
- content_broadcast(c->bw->current_content, CONTENT_MSG_REFORMAT, data);
- /* reshape the plugin */
- plugin_reformat(&c->base, c->base.width, c->base.height);
-}
-
-/**
- * Handles receipt of plugin_status messages
- *
- * \param message The message to handle
- */
-void plugin_status(wimp_message *message)
-{
- plugin_content *c;
- plugin_message_status *pms = (plugin_message_status*)&message->data;
-
- /* retrieve our content */
- c = (plugin_content *)pms->browser;
-
- /* check we expect this message */
- if (!c || !plugin_active(&c->base))
- return;
-
- gui_window_set_status(c->bw->window,
- (const char*)plugin_get_string_value(pms->message,
- (char*)pms));
-}
-
-/**
- * Handles receipt of plugin_stream_new messages
- *
- * \param message The message to handle
- */
-void plugin_stream_new(wimp_message *message)
-{
- struct plugin_stream *p;
- int stream_type;
- plugin_message_stream_new *pmsn =
- (plugin_message_stream_new*)&message->data;
-
- LOG(("plugin_stream_new"));
-
- p = (struct plugin_stream *)pmsn->browser_stream;
-
- /* check we expect this message */
- if (!p || !p->plugin || !plugin_active(&p->plugin->base))
- return;
-
- /* response to a message we sent */
- if (message->my_ref != 0) {
- p->pluginh = pmsn->stream;
-
- LOG(("flags: %x", pmsn->flags));
-
- /* extract the stream type */
- stream_type = pmsn->flags & plugin_STREAM_NEW_TYPE;
-
- if (stream_type == plugin_STREAM_NEW_TYPE_AS_FILE_ONLY ||
- stream_type ==
- plugin_STREAM_NEW_TYPE_AS_FILE) {
- LOG(("as file"));
-
- p->type = AS_FILE;
-
- /* received all data => go ahead and stream
- * we have to check the content's status too, as
- * we could be dealing with a stream of unknown
- * length (ie c->total_size == 0). If the status
- * is CONTENT_STATUS_DONE, we've received all the
- * data anyway, regardless of the total size.
- */
- if (p->c->source_size == p->c->total_size ||
- p->c->status == CONTENT_STATUS_DONE)
- plugin_write_stream_as_file(p);
- else {
- LOG(("waiting for data"));
- p->stream.file.waiting = true;
- /* schedule a callback */
- schedule(PLUGIN_SCHEDULE_WAIT,
- plugin_stream_as_file_callback, p);
- }
- }
- else if (stream_type == plugin_STREAM_NEW_TYPE_SEEK_ONLY ||
- stream_type ==
- plugin_STREAM_NEW_TYPE_NORMAL) {
- LOG(("write stream"));
- plugin_write_stream(p, 0);
- }
- }
- /* new stream, initiated by plugin */
- else {
- /** \todo plugin-initiated streams */
- }
-}
-
-/**
- * Handles receipt of plugin_stream_written messages
- *
- * \param message The message to handle
- */
-void plugin_stream_written(wimp_message *message)
-{
- struct plugin_stream *p;
- plugin_message_stream_written *pmsw =
- (plugin_message_stream_written*)&message->data;
-
- /* retrieve our stream context */
- p = (struct plugin_stream *)pmsw->browser_stream;
-
- /* check we expect this message */
- if (!p || !p->plugin || !plugin_active(&p->plugin->base))
- return;
-
- LOG(("got written"));
-
- plugin_write_stream(p, pmsw->length);
-}
-
-/**
- * Handles plugin_url_access messages
- *
- * \param message The message to handle
- */
-void plugin_url_access(wimp_message *message)
-{
- plugin_content *c;
- plugin_full_message_notify pmn;
- os_error *error;
- plugin_message_url_access *pmua =
- (plugin_message_url_access*)&message->data;
- bool notify = false, post = false, file = false;
- char *url = plugin_get_string_value(pmua->url, (char*)pmua);
- char *window;
-
- notify = (pmua->flags & plugin_URL_ACCESS_NOTIFY_COMPLETION);
- post = (pmua->flags & plugin_URL_ACCESS_USE_POST);
- file = (pmua->flags & plugin_URL_ACCESS_POST_FILE);
-
- /* retrieve our content */
- c = (plugin_content *)pmua->browser;
-
- /* check we expect this message */
- if (!c || !plugin_active(&c->base))
- return;
-
- /* fetch url to window */
- if (pmua->target_window.offset != 0 &&
- pmua->target_window.pointer != 0) {
- window = plugin_get_string_value(pmua->target_window,
- (char*)pmua);
- LOG(("flags: %d, url: %s, window: %s", pmua->flags, url, window));
- /** \todo proper _parent and _self support (needs frames)
- * other window names
- */
- if (!post) { /* GET request */
- if (strcasecmp(url,
- c->bw->current_content->url) &&
- (strcasecmp(window, "_self") == 0 ||
- strcasecmp(window, "_parent") == 0 ||
- strcasecmp(window, "_top") == 0 ||
- strcasecmp(window, "") == 0)) {
- /* only open in current window if not
- * already at the URL requested, else you
- * end up in an infinite loop of fetching
- * the same page
- */
- browser_window_go(c->bw, url, 0, true);
- }
- else if (!option_block_popups &&
- strcasecmp(window, "_blank") == 0) {
- /* don't do this if popups are blocked */
- browser_window_create(url, NULL, 0, true,
- false);
- }
- }
- else { /* POST request */
- /* fetch URL */
- }
- }
- /* fetch data and stream to plugin */
- else {
- if (!post) { /* GET request */
- /* stream to plugin */
- plugin_create_stream(c, NULL, url);
- }
- else { /* POST request */
- /* fetch URL */
- }
- }
-
- /* this may be a little early to send this, but tough. */
- if (notify) {
- /* send message_plugin_notify to plugin task */
- pmn.size = 44;
- pmn.your_ref = message->my_ref;
- pmn.action = message_PLUG_IN_NOTIFY;
- pmn.flags = 0;
- pmn.plugin = pmua->plugin;
- pmn.browser = pmua->browser;
- pmn.url.pointer = url;
- pmn.reason = (plugin_notify_reason)0;
- pmn.notify_data = pmua->notify_data;
-
- error = xwimp_send_message(wimp_USER_MESSAGE,
- (wimp_message*)&pmn, message->sender);
- if (error) {
- return;
- }
- }
-}
-
-/**
- * Creates a plugin stream
- *
- * \param plugin The content to fetch the data for
- * \param c The content being fetched, or NULL.
- * \param url The url of the resource to fetch, or NULL if content provided.
- */
-void plugin_create_stream(plugin_content *plugin, plugin_content *c,
- const char *url)
-{
- struct plugin_stream *p;
-
- assert(plugin && ((c && !url) || (!c && url)));
-
- p = malloc(sizeof(struct plugin_stream));
- if (!p)
- return;
-
- if (url) {
- if (!plugin_start_fetch(p, url)) {
- free(p);
- return;
- }
- }
- else
- p->c = c;
-
- p->plugin = plugin;
- p->pluginh = 0;
- p->type = NORMAL;
- p->stream.normal.consumed = 0;
-
- /* add to head of list */
- p->next = plugin->streams;
- plugin->streams = p;
-
- if (url)
- /* we'll send this later, once some data is arriving */
- return;
-
- plugin_send_stream_new(p);
-}
-
-/**
- * Send a plugin stream new message
- *
- * \param p The stream context
- * \return true on success, false otherwise
- */
-bool plugin_send_stream_new(struct plugin_stream *p)
-{
- plugin_full_message_stream_new pmsn;
- os_error *error;
-
- pmsn.size = 64;
- pmsn.your_ref = 0;
- pmsn.action = message_PLUG_IN_STREAM_NEW;
- pmsn.flags = 0;
- pmsn.plugin = (plugin_p)p->plugin->plugin;
- pmsn.browser = (plugin_b)p->plugin->browser;
- pmsn.stream = (plugin_s)0;
- pmsn.browser_stream = (plugin_bs)p;
- pmsn.url.pointer = (char *) content__get_url(&p->c->base);
- pmsn.end = p->c->total_size;
- pmsn.last_modified_date = 0;
- pmsn.notify_data = 0;
- pmsn.mime_type.pointer = p->c->mime_type;
- pmsn.target_window.offset = 0;
-
- LOG(("Sending message &4D548"));
- error = xwimp_send_message(wimp_USER_MESSAGE_RECORDED,
- (wimp_message*)&pmsn,
- (wimp_t)p->plugin->plugin_task);
- if (error) {
- plugin_stream_free(p);
- return false;
- }
-
- return true;
-}
-
-/**
- * Writes to an open stream
- *
- * \param c The stream context
- * \param consumed The amount of data consumed
- */
-void plugin_write_stream(struct plugin_stream *p, unsigned int consumed)
-{
- plugin_full_message_stream_write pmsw;
- os_error *error;
-
- assert(p->type == NORMAL);
-
- p->stream.normal.consumed += consumed;
-
- pmsw.size = 68;
- pmsw.your_ref = 0;
- pmsw.action = message_PLUG_IN_STREAM_WRITE;
- pmsw.flags = 0;
- pmsw.plugin = (plugin_p)p->plugin->plugin;
- pmsw.browser = (plugin_b)p->plugin->browser;
- pmsw.stream = (plugin_s)p->pluginh;
- pmsw.browser_stream = (plugin_bs)p;
- pmsw.url.pointer = (char *) content__get_url(&p->c->base);
- /* end of stream is p->c->total_size
- * (which is conveniently 0 if unknown)
- */
- pmsw.end = p->c->total_size;
- pmsw.last_modified_date = 0;
- pmsw.notify_data = 0;
- /* offset into data is amount of data consumed by plugin already */
- pmsw.offset = p->stream.normal.consumed;
- /* length of data available is <= sizeof fixed buffer */
- pmsw.length = p->c->source_size - p->stream.normal.consumed;
- if (pmsw.length >= PLUGIN_STREAM_BUFFER_SIZE)
- pmsw.length = PLUGIN_STREAM_BUFFER_SIZE;
-
- /* copy data into buffer */
- memcpy(p->stream.normal.buffer,
- p->c->source_data + p->stream.normal.consumed, pmsw.length);
-
- /* pointer to available data */
- pmsw.data = (byte*)(p->stream.normal.buffer);
-
- /* still have data to send */
- if (p->stream.normal.consumed < p->c->source_size) {
- LOG(("Sending message &4D54A"));
- error = xwimp_send_message(wimp_USER_MESSAGE_RECORDED,
- (wimp_message *)&pmsw,
- (wimp_t)p->plugin->plugin_task);
- if (error) {
- plugin_destroy_stream(p,
- plugin_STREAM_DESTROY_ERROR);
- return;
- }
- }
- else if (p->c->source_size < p->c->total_size) {
- /* the plugin has consumed all the available data,
- * but there's still more to fetch, so we wait for
- * 40 cs then try again (note that streams of unknown
- * total length won't ever get in here as
- * p->c->total_size will be 0)
- */
- schedule(PLUGIN_SCHEDULE_WAIT,
- plugin_stream_write_callback, p);
- }
- /* no further data => destroy stream */
- else {
- plugin_destroy_stream(p, plugin_STREAM_DESTROY_FINISHED);
- }
-}
-
-/**
- * Stream write callback - used to wait for data to download
- *
- * \param p The stream context
- */
-void plugin_stream_write_callback(void *p)
-{
- /* remove ourselves from the schedule queue */
- schedule_remove(plugin_stream_write_callback, p);
-
- /* continue writing stream */
- plugin_write_stream((struct plugin_stream *)p, 0);
-}
-
-/**
- * Stream as file callback - used to wait for data to download
- *
- * \param p The stream context
- */
-void plugin_stream_as_file_callback(void *p)
-{
- struct plugin_stream *s = (struct plugin_stream *)p;
-
- /* remove ourselves from the schedule queue */
- schedule_remove(plugin_stream_as_file_callback, p);
-
- if (s->c->source_size < s->c->total_size ||
- content__get_status(&s->c->base) !=
- CONTENT_STATUS_DONE) {
- /* not got all the data so wait some more */
- schedule(PLUGIN_SCHEDULE_WAIT,
- plugin_stream_as_file_callback, p);
- return;
- }
-
- /* deal with a plugin waiting for a file stream */
- if (s->stream.file.waiting) {
- s->stream.file.waiting = false;
- plugin_write_stream_as_file(s);
- }
-}
-
-/**
- * Writes a stream as a file
- *
- * \param c The stream context
- */
-void plugin_write_stream_as_file(struct plugin_stream *p)
-{
- plugin_full_message_stream_as_file pmsaf;
- unsigned int filetype;
- os_error *error;
-
- assert(p->type == AS_FILE);
-
- p->stream.file.datafile =
- calloc(strlen(getenv("Wimp$ScrapDir"))+13+10, sizeof(char));
-
- if (!p->stream.file.datafile) {
- LOG(("malloc failed"));
- warn_user("NoMemory", 0);
- plugin_destroy_stream(p, plugin_STREAM_DESTROY_ERROR);
- return;
- }
-
- /* create filename */
- sprintf(p->stream.file.datafile, "%s.WWW.NetSurf.d%x",
- getenv("Wimp$ScrapDir"), (unsigned int)p);
-
- pmsaf.size = 60;
- pmsaf.your_ref = 0;
- pmsaf.action = message_PLUG_IN_STREAM_AS_FILE;
- pmsaf.flags = 0;
- pmsaf.plugin = (plugin_p)p->plugin->plugin;
- pmsaf.browser = (plugin_b)p->plugin->browser;
- pmsaf.stream = (plugin_s)p->pluginh;
- pmsaf.browser_stream = (plugin_bs)p;
- pmsaf.url.pointer = (char *) content__get_url(&p->c->base);
- pmsaf.end = p->c->total_size;
- pmsaf.last_modified_date = 0;
- pmsaf.notify_data = 0;
- pmsaf.filename.pointer = p->stream.file.datafile;
-
- error = xmimemaptranslate_mime_type_to_filetype(p->c->mime_type,
- (bits *) &filetype);
- if (error) {
- plugin_destroy_stream(p, plugin_STREAM_DESTROY_ERROR);
- return;
- }
-
- error = xosfile_save_stamped((char const*)p->stream.file.datafile,
- filetype, p->c->source_data,
- p->c->source_data + p->c->source_size);
- if (error) {
- plugin_destroy_stream(p, plugin_STREAM_DESTROY_ERROR);
- return;
- }
-
- LOG(("Sending message &4D54C"));
- error = xwimp_send_message(wimp_USER_MESSAGE,
- (wimp_message *)&pmsaf,
- (wimp_t)p->plugin->plugin_task);
- if (error) {
- plugin_destroy_stream(p, plugin_STREAM_DESTROY_ERROR);
- return;
- }
-
- plugin_destroy_stream(p, plugin_STREAM_DESTROY_FINISHED);
-}
-
-/**
- * Destroys a plugin stream
- *
- * \param c The stream context to destroy
- * \param reason The reason for the destruction
- */
-void plugin_destroy_stream(struct plugin_stream *p,
- plugin_stream_destroy_reason reason)
-{
- plugin_full_message_stream_destroy pmsd;
- os_error *error;
-
- if (p->type == AS_FILE && p->stream.file.destroyed)
- /* we've already destroyed this stream */
- return;
-
- /* stop any scheduled callbacks */
- if (p->type == NORMAL)
- schedule_remove(plugin_stream_write_callback, p);
- else
- schedule_remove(plugin_stream_as_file_callback, p);
-
- pmsd.size = 60;
- pmsd.your_ref = 0;
- pmsd.action = message_PLUG_IN_STREAM_DESTROY;
- pmsd.flags = 0;
- pmsd.plugin = (plugin_p)p->plugin->plugin;
- pmsd.browser = (plugin_b)p->plugin->browser;
- pmsd.stream = (plugin_s)p->pluginh;
- pmsd.browser_stream = (plugin_bs)p;
- pmsd.url.pointer = (char *) content__get_url(&p->c->base);
- pmsd.end = p->c->total_size;
- pmsd.last_modified_date = 0;
- pmsd.notify_data = 0;
- pmsd.reason = reason;
-
- LOG(("Sending message &4D549"));
- error = xwimp_send_message(wimp_USER_MESSAGE,
- (wimp_message *)&pmsd,
- (wimp_t)p->plugin->plugin_task);
- if (error) {
- LOG(("0x%x %s", error->errnum, error->errmess));
- }
-
- plugin_stream_free(p);
-}
-
-/**
- * Writes the plugin parameters file
- *
- * \param c Content to write parameters for
- * \param params Plugin parameters struct
- * \param base base URL for object
- * \return true on success, false otherwise
- */
-bool plugin_write_parameters_file(plugin_content *c,
- struct object_params *params, const char *base)
-{
- struct object_param *p;
- struct plugin_param_item *ppi;
- struct plugin_param_item *pilist = 0;
- char bgcolor[10] = {0};
- FILE *fp;
-
- /* Create the file */
- xosfile_create_dir("<Wimp$ScrapDir>.WWW", 77);
- xosfile_create_dir("<Wimp$ScrapDir>.WWW.NetSurf", 77);
- /* path + filename + terminating NUL */
- c->filename =
- calloc(strlen(getenv("Wimp$ScrapDir"))+13+10, sizeof(char));
-
- if (!c->filename) {
- LOG(("malloc failed"));
- warn_user("NoMemory", 0);
- return false;
- }
- sprintf(c->filename, "%s.WWW.NetSurf.p%x",
- getenv("Wimp$ScrapDir"), (unsigned int)params);
- LOG(("filename: %s", c->filename));
-
- /* Write object attributes first */
-
- /* classid is checked first */
- if (params->classid != 0 && params->codetype != 0) {
- if (!plugin_add_item_to_pilist(&pilist,
- PLUGIN_PARAMETER_DATA, "CLASSID",
- (const char*)params->classid,
- (const char*)params->codetype))
- goto error;
- }
- /* otherwise, we check the data attribute */
- else if (params->data !=0 && params->type != 0) {
- if (!plugin_add_item_to_pilist(&pilist,
- PLUGIN_PARAMETER_DATA, "DATA",
- (const char *)params->data,
- (const char *)params->type))
- goto error;
- }
-
- /* if codebase is specified, write it as well */
- if (params->codebase != 0) {
- if (!plugin_add_item_to_pilist(&pilist,
- PLUGIN_PARAMETER_DATA, "CODEBASE",
- (const char *)params->codebase,
- NULL))
- goto error;
- }
-
- /* Iterate through the parameter list, creating the parameters
- * file as we go.
- */
- for (p = params->params; p != 0; p = p->next) {
- LOG(("name: %s", p->name == 0 ? "not set" : p->name));
- LOG(("value: %s", p->value == 0 ? "not set" : p->value));
- LOG(("type: %s", p->type == 0 ? "not set" : p->type));
- LOG(("valuetype: %s", p->valuetype));
-
-
- if (strcasecmp(p->valuetype, "data") == 0)
- if (!plugin_add_item_to_pilist(&pilist,
- PLUGIN_PARAMETER_DATA,
- (const char *)p->name,
- (const char *)p->value,
- (const char *)p->type))
- goto error;
- if (strcasecmp(p->valuetype, "ref") == 0)
- if (!plugin_add_item_to_pilist(&pilist,
- PLUGIN_PARAMETER_URL,
- (const char *)p->name,
- (const char *)p->value,
- (const char *)p->type))
- goto error;
- if (strcasecmp(p->valuetype, "object") == 0)
- if (!plugin_add_item_to_pilist(&pilist,
- PLUGIN_PARAMETER_OBJECT,
- (const char *)p->name,
- (const char *)p->value,
- (const char *)p->type))
- goto error;
- }
-
- /* Now write mandatory special parameters */
-
- /* BASEHREF */
- if (!plugin_add_item_to_pilist(&pilist, PLUGIN_PARAMETER_SPECIAL,
- "BASEHREF", base,
- NULL))
- goto error;
-
- /* USERAGENT */
- if (!plugin_add_item_to_pilist(&pilist, PLUGIN_PARAMETER_SPECIAL,
- "USERAGENT", "NetSurf", NULL))
- goto error;
-
- /* UAVERSION */
- if (!plugin_add_item_to_pilist(&pilist, PLUGIN_PARAMETER_SPECIAL,
- "UAVERSION", "0.01", NULL))
- goto error;
-
- /* APIVERSION */
- if (!plugin_add_item_to_pilist(&pilist, PLUGIN_PARAMETER_SPECIAL,
- "APIVERSION", "1.10", NULL))
- goto error;
-
- /* BGCOLOR */
- if (c->box && c->box->style &&
- c->box->style->background_color <= 0xFFFFFF)
- sprintf(bgcolor, "%X00",
- (unsigned int)c->box->style->background_color);
- else
- sprintf(bgcolor, "FFFFFF");
- if (!plugin_add_item_to_pilist(&pilist, PLUGIN_PARAMETER_SPECIAL,
- "BGCOLOR",
- (const char *)bgcolor,
- NULL))
- goto error;
-
- /* Write file */
- fp = fopen(c->filename, "wb+");
-
- while (pilist != 0) {
- fwrite(&pilist->type, sizeof(int), 1, fp);
- fwrite(&pilist->rsize, sizeof(int), 1, fp);
-
- fwrite(&pilist->nsize, sizeof(int), 1, fp);
- fwrite(pilist->name, strlen(pilist->name), 1, fp);
- for (; pilist->npad != 0; pilist->npad--)
- fputc('\0', fp);
-
- fwrite(&pilist->vsize, sizeof(int), 1, fp);
- fwrite(pilist->value, strlen(pilist->value), 1, fp);
- for(; pilist->vpad != 0; pilist->vpad--)
- fputc('\0', fp);
-
- fwrite(&pilist->msize, sizeof(int), 1, fp);
- if (pilist->msize > 0) {
- fwrite(pilist->mime_type,
- strlen(pilist->mime_type), 1, fp);
- for (; pilist->mpad != 0; pilist->mpad--)
- fputc('\0', fp);
- }
-
- ppi = pilist;
- pilist = pilist->next;
-
- free(ppi->name);
- free(ppi->value);
- free(ppi->mime_type);
- ppi->name = ppi->value = ppi->mime_type = 0;
- free(ppi);
- ppi = 0;
- }
-
- fwrite("", sizeof(char), 4, fp);
-
- fclose(fp);
-
- return true;
-
-error:
- while (pilist != 0) {
- ppi = pilist;
- pilist = pilist->next;
-
- free(ppi->name);
- free(ppi->value);
- free(ppi->mime_type);
- ppi->name = ppi->value = ppi->mime_type = 0;
- free(ppi);
- ppi = 0;
- }
-
- free(c->filename);
- c->filename = 0;
- return false;
-}
-
-/**
- * Calculates the size of a parameter file record
- *
- * \param name Record name
- * \param data Record data
- * \param mime Record mime type
- * \return length of record
- */
-int plugin_calculate_rsize(const char* name, const char* data,
- const char* mime)
-{
- int ret = 0;
-
- ret += (4 + strlen(name) + 3) / 4 * 4; /* name */
- ret += (4 + strlen(data) + 3) / 4 * 4; /* data */
-
- if (mime != NULL)
- ret += (4 + strlen(mime) + 3) / 4 * 4; /* mime type */
- else
- ret += 4;
-
- return ret;
-}
-
-/**
- * Adds an item to the list of parameter file records
- *
- * \param pilist Pointer to list of parameters
- * \param type Type of record to add
- * \param name Name of record
- * \param value Value of record
- * \param mime_type Mime type of record
- * \return true on success, false otherwise
- */
-bool plugin_add_item_to_pilist(struct plugin_param_item **pilist,
- plugin_parameter_type type, const char* name,
- const char* value, const char* mime_type)
-{
- struct plugin_param_item *ppi = calloc(1, sizeof(*ppi));
-
- if (!ppi)
- return false;
-
- /* initialise struct */
- ppi->type = 0;
- ppi->rsize = 0;
- ppi->nsize = 0;
- ppi->name = 0;
- ppi->npad = 0;
- ppi->vsize = 0;
- ppi->value = 0;
- ppi->vpad = 0;
- ppi->msize = 0;
- ppi->mime_type = 0;
- ppi->mpad = 0;
-
- ppi->type = type;
- ppi->rsize = plugin_calculate_rsize(name, value, mime_type);
- ppi->nsize = strlen(name);
- ppi->name = strdup(name);
- if (!ppi->name) {
- free(ppi);
- return false;
- }
-
- ppi->npad = 4 - (ppi->nsize%4 == 0 ? 4 : ppi->nsize%4);
- ppi->vsize = strlen(value);
- ppi->value = strdup(value);
- if (!ppi->value) {
- free(ppi->name);
- free(ppi);
- return false;
- }
-
- ppi->vpad = 4 - (ppi->vsize%4 == 0 ? 4 : ppi->vsize%4);
- if(mime_type != 0) {
- ppi->msize = strlen(mime_type);
- ppi->mime_type = strdup(mime_type);
- if (!ppi->mime_type) {
- free(ppi->name);
- free(ppi->value);
- free(ppi);
- return false;
- }
-
- ppi->mpad = 4 - (ppi->msize%4 == 0 ? 4 : ppi->msize%4);
- }
-
- ppi->next = (*pilist);
- (*pilist) = ppi;
- return true;
-}
-
-/**
- * Utility function to grab string data from plugin message blocks
- *
- * \param string Containing structure
- * \param msg Containing message
- * \return the string data
- */
-char *plugin_get_string_value(os_string_value string, char *msg)
-{
- if(string.offset == 0 || string.offset > 256) {
- return string.pointer;
- }
- return &msg[string.offset];
-}
-
-/**
- * Determines whether a content is still active
- *
- * \param c The content to examine
- * \return true if active, false otherwise
- */
-bool plugin_active(struct content *c)
-{
- struct content *d;
-
- if (c->user_list == 0)
- return false;
-
- for (d = content_list; d; d = d->next) {
- if (d == c)
- return true;
- }
-
- return false;
-}
-
-/**
- * Free a plugin_stream struct and unlink it from the list
- */
-void plugin_stream_free(struct plugin_stream *p)
-{
- if (p->c != p->plugin) {
- if (p->c->fetch) {
- /* abort fetch, if active */
- fetch_abort(p->c->fetch);
- p->c->fetch = 0;
- p->c->status = CONTENT_STATUS_DONE;
- }
- content_remove_user(p->c, plugin_stream_callback,
- (intptr_t)p, 0);
- }
-
- /* free normal stream context. file streams get freed later */
- if (p->type == NORMAL) {
- struct plugin_stream *q;
- for (q = p->plugin->streams; q && q->next != p;
- q = q->next)
- /* do nothing */;
- assert(q || p == p->plugin->streams);
- if (q)
- q->next = p->next;
- else
- p->plugin->streams = p->next;
-
- free(p);
- }
- else
- p->stream.file.destroyed = true;
-}
-
-/**
- * Initialise a fetch for a plugin
- *
- * \param p The stream context to fetch for
- * \param url The URL to fetch
- * \return true on successful fetch initiation and p->c filled in, false
- * otherwise.
- */
-bool plugin_start_fetch(struct plugin_stream *p, const char *url)
-{
- char *url2;
- struct content *c;
- url_func_result res;
-
- assert(p && url);
-
- res = url_normalize(url, &url2);
- if (res != URL_FUNC_OK) {
- return false;
- }
-
- if (!fetch_can_fetch(url2)) {
- free(url2);
- return false;
- }
-
- c = fetchcache(url2, plugin_stream_callback, (intptr_t)p, 0,
- 100, 100, true, 0, 0, false, true);
- free(url2);
- if (!c) {
- return false;
- }
-
- p->c = c;
- fetchcache_go(c, 0, plugin_stream_callback, (intptr_t)p, 0,
- 100, 100, 0, 0, false, 0);
-
- return true;
-}
-
-/**
- * Callback for fetchcache() for plugin stream fetches.
- */
-void plugin_stream_callback(content_msg msg, struct content *c,
- intptr_t p1, intptr_t p2, union content_msg_data data)
-{
- struct plugin_stream *p = (struct plugin_stream *)p1;
-
- switch (msg) {
- case CONTENT_MSG_LOADING:
- assert(p->c == c);
- assert(c->type == CONTENT_OTHER);
- fetch_change_callback(c->fetch,
- plugin_fetch_callback, p);
- /* and kickstart the stream protocol */
- plugin_send_stream_new(p);
- break;
-
- case CONTENT_MSG_LAUNCH:
- /* Fall through */
- case CONTENT_MSG_ERROR:
- /* The plugin we were fetching may have been
- * redirected, in that case, the object pointers
- * will differ, so ensure that the object that's
- * in error is still in use by us before destroying
- * the stream */
- if (p->c == c)
- plugin_destroy_stream(p,
- plugin_STREAM_DESTROY_ERROR);
- break;
-
- case CONTENT_MSG_NEWPTR:
- p->c = c;
- break;
-
- case CONTENT_MSG_AUTH:
- /**\todo handle authentication */
- plugin_destroy_stream(p, plugin_STREAM_DESTROY_ERROR);
- break;
-
- case CONTENT_MSG_STATUS:
- /* ignore this */
- break;
-
- case CONTENT_MSG_SSL:
- plugin_destroy_stream(p, plugin_STREAM_DESTROY_ERROR);
- break;
-
- case CONTENT_MSG_READY:
- case CONTENT_MSG_DONE:
- case CONTENT_MSG_REFORMAT:
- case CONTENT_MSG_REDRAW:
- default:
- /* not possible */
- assert(0);
- break;
- }
-}
-
-/**
- * Callback for plugin fetch
- */
-void plugin_fetch_callback(fetch_msg msg, void *p, const void *data,
- unsigned long size)
-{
- struct plugin_stream *s = p;
- union content_msg_data msg_data;
-
- switch (msg) {
- case FETCH_PROGRESS:
- break;
-
- case FETCH_DATA:
- if (!content_process_data(s->c, data, size)) {
- fetch_abort(s->c->fetch);
- s->c->fetch = 0;
- }
- break;
-
- case FETCH_FINISHED:
- s->c->fetch = 0;
- s->c->status = CONTENT_STATUS_DONE;
- break;
-
- case FETCH_ERROR:
- s->c->fetch = 0;
- s->c->status = CONTENT_STATUS_ERROR;
- msg_data.error = data;
- content_broadcast(s->c, CONTENT_MSG_ERROR, msg_data);
- break;
-
- case FETCH_NOTMODIFIED:
- case FETCH_AUTH:
- case FETCH_CERT_ERR:
- default:
- /* not possible */
- assert(0);
- break;
- }
-}
-
-#endif