From 33cc86a8bbcdc9ac6d379c85c51abf54b3426790 Mon Sep 17 00:00:00 2001 From: John Mark Bell Date: Thu, 17 Jul 2003 14:26:15 +0000 Subject: [PATCH] [project @ 2003-07-17 14:26:15 by jmb] create parameters file for plugins svn path=/import/netsurf/; revision=227 --- content/content.c | 2 +- render/box.c | 186 +++++++++++--- render/box.h | 16 +- riscos/plugin.c | 625 ++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 777 insertions(+), 52 deletions(-) diff --git a/content/content.c b/content/content.c index 253caea16..af9850145 100644 --- a/content/content.c +++ b/content/content.c @@ -145,7 +145,7 @@ void content_set_type(struct content *c, content_type type, char* mime_type) assert(type < CONTENT_UNKNOWN); LOG(("content %s, type %i", c->url, type)); c->type = type; - c->mime_type = mime_type; + c->mime_type = strdup(mime_type); c->status = CONTENT_STATUS_LOADING; content_broadcast(c, CONTENT_MSG_LOADING, 0); handler_map[type].create(c); diff --git a/render/box.c b/render/box.c index cdff305fa..f77f37913 100644 --- a/render/box.c +++ b/render/box.c @@ -96,7 +96,7 @@ struct element_entry { }; static const struct element_entry element_table[] = { {"a", box_a}, -// {"applet", box_applet}, + {"applet", box_applet}, {"embed", box_embed}, {"form", box_form}, {"img", box_image}, @@ -490,13 +490,13 @@ struct css_style * box_get_style(struct content ** stylesheet, } if ((s = (char *) xmlGetProp(n, (const xmlChar *) "height"))) { - if (strrchr(s, '%')) { - /* tne specification doesn't make clear what - * percentage heights mean, so ignore them */ - } else { - style->height.height = CSS_HEIGHT_LENGTH; - style->height.length.unit = CSS_UNIT_PX; - style->height.length.value = atof(s); + if (strrchr(s, '%')) { + /*the specification doesn't make clear what + * percentage heights mean, so ignore them */ + } else { + style->height.height = CSS_HEIGHT_LENGTH; + style->height.length.unit = CSS_UNIT_PX; + style->height.length.value = atof(s); } xmlFree(s); } @@ -558,6 +558,7 @@ struct result box_a(xmlNode *n, struct status *status, { struct box *box; char *s; + box = box_create(style, status->href, status->title); if ((s = (char *) xmlGetProp(n, (const xmlChar *) "href"))) status->href = s; box = box_create(style, status->href, status->title); @@ -1408,7 +1409,9 @@ struct result box_object(xmlNode *n, struct status *status, { struct box *box; struct object_params *po; + struct plugin_params* pp; char *s, *url; + xmlNode *c; box = box_create(style, status->href, 0); @@ -1420,7 +1423,7 @@ struct result box_object(xmlNode *n, struct status *status, po->codetype = 0; po->codebase = 0; po->classid = 0; - po->paramds = 0; + po->params = 0; /* object data */ if ((s = (char *) xmlGetProp(n, (const xmlChar *) "data"))) { @@ -1463,8 +1466,53 @@ struct result box_object(xmlNode *n, struct status *status, xmlFree(s); } - /* TODO: go through children looking for , and add - * somewhere in po */ + /* parameters + * parameter data is stored in a singly linked list. + * po->params points to the head of the list. + * new parameters are added to the head of the list. + */ + for (c = n->children; c != 0; c = c->next) { + if (strcmp((const char *) c->name, "param") == 0) { + + pp = xcalloc(1, sizeof(*pp)); + + /* initialise pp struct */ + pp->name = 0; + pp->value = 0; + pp->type = 0; + pp->next = 0; + + if ((s = (char *) xmlGetProp(c, (const xmlChar *) "name"))) { + pp->name = strdup(s); + xmlFree(s); + } + if ((s = (char *) xmlGetProp(c, (const xmlChar *) "value"))) { + pp->value = strdup(s); + xmlFree(s); + } + if ((s = (char *) xmlGetProp(c, (const xmlChar *) "type"))) { + pp->type = strdup(s); + xmlFree(s); + } + if ((s = (char *) xmlGetProp(c, (const xmlChar *) "valuetype"))) { + pp->valuetype = strdup(s); + xmlFree(s); + } + else { + + pp->valuetype = strdup("data"); + } + + pp->next = po->params; + po->params = pp; + } + else { + /* The first non-param child is the start of the + * alt html. Therefore, we should break out of this loop. + */ + continue; + } + } box->object_params = po; @@ -1496,7 +1544,7 @@ struct result box_embed(xmlNode *n, struct status *status, po->codetype = 0; po->codebase = 0; po->classid = 0; - po->paramds = 0; + po->params = 0; /* embed src */ if ((s = (char *) xmlGetProp(n, (const xmlChar *) "src"))) { @@ -1516,7 +1564,6 @@ struct result box_embed(xmlNode *n, struct status *status, } /** - * TODO - finish this ;-) * add an applet to the box tree */ @@ -1524,22 +1571,93 @@ struct result box_applet(xmlNode *n, struct status *status, struct css_style *style) { struct box *box; + struct object_params *po; + struct plugin_params *pp; char *s, *url; + xmlNode *c; box = box_create(style, status->href, 0); - /* object without data is an error */ - if (!(s = (char *) xmlGetProp(n, (const xmlChar *) "data"))) - return (struct result) {box,0}; + po = xcalloc(1, sizeof(*po)); - url = url_join(strdup(s), status->content->url); - LOG(("object '%s'", url)); - xmlFree(s); + /* initialise po struct */ + po->data = 0; + po->type = 0; + po->codetype = 0; + po->codebase = 0; + po->classid = 0; + po->params = 0; + + /* code */ + if ((s = (char *) xmlGetProp(n, (const xmlChar *) "code"))) { + + po->classid = strdup(s); + url = url_join(strdup(s), status->content->url); + LOG(("applet '%s'", url)); + xmlFree(s); + } + + /* object codebase */ + if ((s = (char *) xmlGetProp(n, (const xmlChar *) "codebase"))) { + + po->codebase = strdup(s); + LOG(("codebase: %s", s)); + xmlFree(s); + } + + /* parameters + * parameter data is stored in a singly linked list. + * po->params points to the head of the list. + * new parameters are added to the head of the list. + */ + for (c = n->children; c != 0; c = c->next) { + if (strcmp((const char *) c->name, "param") == 0) { + + pp = xcalloc(1, sizeof(*pp)); + + /* initialise pp struct */ + pp->name = 0; + pp->value = 0; + pp->type = 0; + pp->next = 0; + + if ((s = (char *) xmlGetProp(c, (const xmlChar *) "name"))) { + pp->name = strdup(s); + xmlFree(s); + } + if ((s = (char *) xmlGetProp(c, (const xmlChar *) "value"))) { + pp->value = strdup(s); + xmlFree(s); + } + if ((s = (char *) xmlGetProp(c, (const xmlChar *) "type"))) { + pp->type = strdup(s); + xmlFree(s); + } + if ((s = (char *) xmlGetProp(c, (const xmlChar *) "valuetype"))) { + pp->valuetype = strdup(s); + xmlFree(s); + } + else { + + pp->valuetype = strdup("data"); + } + + pp->next = po->params; + po->params = pp; + } + else { + /* The first non-param child is the start of the + * alt html. Therefore, we should break out of this loop. + */ + continue; + } + } /* start fetch */ - //plugin_decode(content, url, box, po); + if(plugin_decode(status->content, url, box, po)) + return (struct result) {box,0}; - return (struct result) {box,0}; + return (struct result) {box,1}; } @@ -1551,19 +1669,18 @@ struct result box_applet(xmlNode *n, struct status *status, * necessary as there are multiple ways of declaring an object's attributes. * * Returns false if the object could not be handled. - * - * TODO: alt html - * params - create parameters file and put the filename string - * somewhere such that it is accessible from plugin_create. */ bool plugin_decode(struct content* content, char* url, struct box* box, struct object_params* po) { + /* Set basehref */ + po->basehref = strdup(content->url); + /* 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); + po->codebase = url_join("./", content->url); else po->codebase = url_join(po->codebase, content->url); @@ -1575,15 +1692,22 @@ bool plugin_decode(struct content* content, char* url, struct box* box, * we can't handle this object. */ if(po->data == 0 && po->classid == 0) { - return false; + return FALSE; } if(po->data == 0 && po->classid != 0) { if(strncasecmp(po->classid, "clsid:", 6) == 0) { LOG(("ActiveX object - n0")); - return false; + return FALSE; } else { url = url_join(po->classid, po->codebase); + + /* The java plugin doesn't need the .class extension + * so we strip it. + */ + if(stricmp((&po->classid[strlen(po->classid)-6]), + ".class") == 0) + po->classid[strlen(po->classid)-6] = 0; } } else { @@ -1595,11 +1719,11 @@ bool plugin_decode(struct content* content, char* url, struct box* box, */ if(po->type != 0) { if (content_lookup(po->type) == CONTENT_OTHER) - return false; + return FALSE; } if(po->codetype != 0) { if (content_lookup(po->codetype) == CONTENT_OTHER) - return false; + return FALSE; } /* If we've got to here, the object declaration has provided us with @@ -1611,6 +1735,6 @@ bool plugin_decode(struct content* content, char* url, struct box* box, */ html_fetch_object(content, url, box); - return true; + return TRUE; } diff --git a/render/box.h b/render/box.h index 4faaef19a..dfb0a2603 100644 --- a/render/box.h +++ b/render/box.h @@ -88,7 +88,19 @@ struct object_params { char* codetype; char* codebase; char* classid; - char* paramds; /* very likely to change */ + struct plugin_params* params; + /* not a parameter, but stored here for convenience */ + char* basehref; + char* filename; +}; + +struct plugin_params { + + char* name; + char* value; + char* type; + char* valuetype; + struct plugin_params* next; }; struct box { @@ -116,7 +128,7 @@ struct box { struct gui_gadget* gadget; struct content* object; /* usually an image */ struct object_params *object_params; - void *object_state; /* state of any object */ + void* object_state; /* state of any object */ }; struct form diff --git a/riscos/plugin.c b/riscos/plugin.c index 6d7b80f1a..3f454ac21 100644 --- a/riscos/plugin.c +++ b/riscos/plugin.c @@ -13,23 +13,26 @@ #include "netsurf/content/content.h" #include "netsurf/render/html.h" +#include "netsurf/render/box.h" #include "netsurf/riscos/plugin.h" #include "netsurf/utils/log.h" #include "netsurf/utils/utils.h" #include "oslib/mimemap.h" +#include "oslib/osfile.h" +#include "oslib/osfind.h" +#include "oslib/osgbpb.h" +void plugin_write_parameters_file(struct object_params *params); /** * plugin_create - * initialises plugin system in readiness for recieving object data - * - * TODO: implement aborting the fetch + * initialises plugin system in readiness for receiving object data */ void plugin_create(struct content *c) { - c->data.plugin.data = xcalloc(0, 1); - c->data.plugin.length = 0; + c->data.plugin.data = xcalloc(0, 1); + c->data.plugin.length = 0; /* we can't create the plugin here, because this is only called * once, even if the object appears several times */ } @@ -44,14 +47,23 @@ void plugin_create(struct content *c) * * bw is the window which the plugin is in * page, box, params are 0 if the object is standalone - * state may be used to store a pointer to state data + * state may be use to store a pointer to state data */ void plugin_add_instance(struct content *c, struct browser_window *bw, - struct content *page, struct box *box, - struct object_params *params, void **state) + struct content *page, struct box *box, + struct object_params *params, void **state) { - /* ok, it looks like we can handle this object. - * Broadcast Message_PlugIn_Open (&4D540) and listen for response + char sysvar[40]; + + assert(params != 0); + + /* write parameters file */ + plugin_write_parameters_file(params); + + plugin_create_sysvar(c->mime_type, &sysvar); + + + /* 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 @@ -60,6 +72,7 @@ void plugin_add_instance(struct content *c, struct browser_window *bw, * values outside the area displayed. This is corrected when * plugin_redraw is called. */ + } @@ -72,11 +85,14 @@ void plugin_add_instance(struct content *c, struct browser_window *bw, * Any storage associated with state must be freed. */ void plugin_remove_instance(struct content *c, struct browser_window *bw, - struct content *page, struct box *box, - struct object_params *params, void **state) + struct content *page, struct box *box, + struct object_params *params, void **state) { -} + assert(params != 0); + /* delete parameters file */ + xosfile_delete((char const*)params->filename, NULL, NULL, NULL, NULL, NULL); +} /** * plugin_reshape_instance @@ -98,6 +114,20 @@ void plugin_reshape_instance(struct content *c, struct browser_window *bw, static const char * const ALIAS_PREFIX = "Alias$@PlugInType_"; +/** + * plugin_create_sysvar + * creates system variable from mime type + */ +void plugin_create_sysvar(const char *mime_type, char* sysvar) +{ + unsigned int *fv; + os_error *e; + + e = xmimemaptranslate_mime_type_to_filetype(mime_type, (bits *) &fv); + + sprintf(sysvar, "%s%x", ALIAS_PREFIX, fv); +} + /** * plugin_handleable * Tests whether we can handle an object using a browser plugin @@ -105,7 +135,7 @@ static const char * const ALIAS_PREFIX = "Alias$@PlugInType_"; */ bool plugin_handleable(const char *mime_type) { - char sysvar[40]; /* must be sufficient for ALIAS_PREFIX and a hex number */ + char sysvar[40]; unsigned int *fv; os_error *e; @@ -143,7 +173,7 @@ void plugin_process_data(struct content *c, char *data, unsigned long size) /* I think we should just buffer the data here, in case the * plugin requests it sometime in the future. - James */ - c->data.plugin.data = xrealloc(c->data.plugin.data, c->data.plugin.length + size); + c->data.plugin.data = xrealloc(c->data.plugin.data, c->data.plugin.length + size); memcpy(c->data.plugin.data + c->data.plugin.length, data, size); c->data.plugin.length += size; c->size += size; @@ -171,8 +201,6 @@ 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) { @@ -187,5 +215,566 @@ void plugin_destroy(struct content *c) void plugin_redraw(struct content *c, long x, long y, unsigned long width, unsigned long height) { - +} + + +/** + * plugin_write_parameters_file + * Writes the parameters file. + * Beware, this function is long and nasty. It appears to work, however. + */ +void plugin_write_parameters_file(struct object_params *params) +{ + struct plugin_params* temp; + int *time; + byte pdata[4] = {0, 0, 0, 0}; + os_fw *pfile; + int i, j, rsize; + + /* Create the file */ + xosfile_create_dir(".NetSurf", 77); + /* path + filename + terminating NUL */ + params->filename = xcalloc(23+10+1 , sizeof(char)); + xos_read_monotonic_time((int*)&time); + sprintf(params->filename, ".NetSurf.p%7d", (int)time<<8); + LOG(("filename: %s", params->filename)); + + xosfind_openoutw(osfind_NO_PATH, params->filename, NULL, &pfile); + + /* Write object attributes first */ + + /* classid is checked first */ + if(params->classid != 0 && params->codetype != 0) { + + /* Record Type */ + pdata[0] = 1; + xosgbpb_writew(pfile, pdata, 4, NULL); + + /* Record size */ + rsize = 0; + rsize += (4 + 7 + 1); + rsize += (4 + strlen(params->classid)); + if((strlen(params->classid)%4) != 0) + rsize += (4-(strlen(params->classid)%4)); + rsize += (4 + strlen(params->codetype)); + if((strlen(params->codetype)%4) != 0) + rsize += (4-(strlen(params->codetype)%4)); + + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + /* name */ + /* size */ + rsize = strlen("CLASSID"); + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + /* name */ + xosgbpb_writew(pfile, (byte const*)"CLASSID", rsize, NULL); + + /* pad to word boundary */ + for(i=0; i!=4; i++) + pdata[i] = 0; + xosgbpb_writew(pfile, pdata, (4 - ((rsize%4) == 0 ? 4 : (rsize%4))), NULL); + + /* value */ + /* size */ + rsize = strlen(params->classid); + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + /* name */ + xosgbpb_writew(pfile, (byte const*)params->classid, rsize, NULL); + + /* pad to word boundary */ + for(i=0; i!=4; i++) + pdata[i] = 0; + xosgbpb_writew(pfile, pdata, (4 - ((rsize%4) == 0 ? 4 : (rsize%4))), NULL); + + /* type */ + /* size */ + rsize = strlen(params->codetype); + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + /* name */ + xosgbpb_writew(pfile, (byte const*)params->codetype, rsize, NULL); + + /* pad to word boundary */ + for(i=0; i!=4; i++) + pdata[i] = 0; + xosgbpb_writew(pfile, pdata, (4 - ((rsize%4) == 0 ? 4 : (rsize%4))), NULL); + + } + /* otherwise, we check the data attribute */ + else if(params->data !=0 && params->type != 0) { + + /* Record Type */ + pdata[0] = 1; + xosgbpb_writew(pfile, pdata, 4, NULL); + + /* Record size */ + rsize = 0; + rsize += (4 + 4); + rsize += (4 + strlen(params->data)); + if((strlen(params->data)%4) != 0) + rsize += (4-(strlen(params->data)%4)); + rsize += (4 + strlen(params->type)); + if((strlen(params->type)%4) != 0) + rsize += (4-(strlen(params->type)%4)); + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + /* name */ + /* size */ + rsize = strlen("DATA"); + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + /* name */ + xosgbpb_writew(pfile, (byte const*)"DATA", rsize, NULL); + + /* pad to word boundary */ + for(i=0; i!=4; i++) + pdata[i] = 0; + xosgbpb_writew(pfile, pdata, (4 - ((rsize%4) == 0 ? 4 : (rsize%4))), NULL); + + /* value */ + /* size */ + rsize = strlen(params->data); + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + /* name */ + xosgbpb_writew(pfile, (byte const*)params->data, rsize, NULL); + + /* pad to word boundary */ + for(i=0; i!=4; i++) + pdata[i] = 0; + xosgbpb_writew(pfile, pdata, (4 - ((rsize%4) == 0 ? 4 : (rsize%4))), NULL); + + /* type */ + /* size */ + rsize = strlen(params->type); + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + /* name */ + xosgbpb_writew(pfile, (byte const*)params->type, rsize, NULL); + + /* pad to word boundary */ + for(i=0; i!=4; i++) + pdata[i] = 0; + xosgbpb_writew(pfile, pdata, (4 - ((rsize%4) == 0 ? 4 : (rsize%4))), NULL); + } + + /* if codebase is specified, write it as well */ + if(params->codebase != 0) { + + /* Record Type */ + pdata[0] = 1; + xosgbpb_writew(pfile, pdata, 4, NULL); + + /* Record size */ + rsize = 0; + rsize += (4 + 8 + 1); + rsize += (4 + strlen(params->codebase)); + if((strlen(params->codebase)%4) != 0) + rsize += (4-(strlen(params->codebase)%4)); + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + /* name */ + /* size */ + rsize = strlen("CODEBASE"); + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + /* name */ + xosgbpb_writew(pfile, (byte const*)"CODEBASE", rsize, NULL); + + /* pad to word boundary */ + for(i=0; i!=4; i++) + pdata[i] = 0; + xosgbpb_writew(pfile, pdata, (4 - ((rsize%4) == 0 ? 4 : (rsize%4))), NULL); + + /* value */ + /* size */ + rsize = strlen(params->codebase); + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + /* name */ + xosgbpb_writew(pfile, (byte const*)params->codebase, rsize, NULL); + + /* pad to word boundary */ + for(i=0; i!=4; i++) + pdata[i] = 0; + xosgbpb_writew(pfile, pdata, (4 - ((rsize%4) == 0 ? 4 : (rsize%4))), NULL); + + } + + /* Iterate through the parameter list, creating the parameters + * file as we go. We can free up the memory as we go. + */ + while(params->params != 0) { + + LOG(("name: %s", params->params->name == 0 ? "not set" : params->params->name)); + LOG(("value: %s", params->params->value == 0 ? "not set" : params->params->value)); + LOG(("type: %s", params->params->type == 0 ? "not set" : params->params->type)); + LOG(("valuetype: %s", params->params->valuetype)); + + + /* Record Type */ + if(strcasecmp(params->params->valuetype, "data") == 0) + pdata[0] = 1; + if(strcasecmp(params->params->valuetype, "ref") == 0) + pdata[0] = 2; + if(strcasecmp(params->params->valuetype, "object") == 0) + pdata[0] = 3; + xosgbpb_writew(pfile, pdata, 4, NULL); + + /* Record Size */ + rsize = 0; + if(params->params->name != 0) { + rsize += 4; + rsize += strlen(params->params->name); + if((strlen(params->params->name) % 4) != 0) + rsize += (4 - (strlen(params->params->name) % 4)); + } + if(params->params->value != 0) { + rsize += 4; + rsize += strlen(params->params->value); + if((strlen(params->params->value) % 4) != 0) + rsize += 4 - ((strlen(params->params->value) % 4)); + } + if(params->params->type != 0) { + rsize += 4; + rsize += strlen(params->params->type); + if((strlen(params->params->type) % 4) != 0) + rsize += (4 - (strlen(params->params->type) % 4)); + } + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + /* Record Name */ + if(params->params->name != 0) { + + /* Size */ + rsize = strlen(params->params->name); + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + /* Name */ + xosgbpb_writew(pfile, (byte const*)params->params->name, rsize, NULL); + + /* Pad to word boundary */ + for(i=0; i!=4; i++) + pdata[i] = 0; + + xosgbpb_writew(pfile, pdata, (4 - ((rsize%4) == 0 ? 4 : (rsize%4))), NULL); + } + + /* Record Value */ + if(params->params->value != 0) { + + /* Size */ + rsize = strlen(params->params->value); + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + /* Name */ + xosgbpb_writew(pfile, (byte const*)params->params->value, rsize, NULL); + + /* Pad to word boundary */ + for(i=0; i!=4; i++) + pdata[i] = 0; + + xosgbpb_writew(pfile, pdata, (4 - ((rsize%4) == 0 ? 4 : (rsize%4))), NULL); + } + + /* Record Type */ + if(params->params->type != 0) { + + /* Size */ + rsize = strlen(params->params->type); + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + /* Name */ + xosgbpb_writew(pfile, (byte const*)params->params->type, rsize, NULL); + + /* Pad to word boundary */ + for(i=0; i!=4; i++) + pdata[i] = 0; + + xosgbpb_writew(pfile, pdata, (4 - ((rsize%4) == 0 ? 4 : (rsize%4))), NULL); + } + + temp = params->params; + params->params = params->params->next; + xfree(temp); + } + + /* Now write mandatory special parameters + * + * Case: Parameter: + * + * 0 BASEHREF + * 1 USERAGENT + * 2 UAVERSION + * 3 APIVERSION + * 4 BGCOLOR - needs fixing to work properly. + * Currently, it assumes FFFFFF00 (BBGGRR00) + */ + for(j=0; j!=5; j++) { + + pdata[0] = 4; + xosgbpb_writew(pfile, pdata, 4, NULL); + + switch(j) { + + case 0: rsize = 0; + rsize += (4 + 8); + rsize += (4 + strlen(params->basehref)); + if((strlen(params->basehref)%4) != 0) + rsize += (4-(strlen(params->basehref)%4)); + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + rsize = strlen("BASEHREF"); + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + xosgbpb_writew(pfile, (byte const*)"BASEHREF", rsize, NULL); + + for(i=0; i!=4; i++) + pdata[i] = 0; + xosgbpb_writew(pfile, pdata, (4 - ((rsize%4) == 0 ? 4 : (rsize%4))), NULL); + + rsize = strlen(params->basehref); + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + xosgbpb_writew(pfile, (byte const*)params->basehref, rsize, NULL); + + for(i=0; i!=4; i++) + pdata[i] = 0; + xosgbpb_writew(pfile, pdata, (4 - ((rsize%4) == 0 ? 4 : (rsize%4))), NULL); + break; + + case 1: rsize = 0; + rsize += (4 + 9 + 3); + rsize += (4 + strlen("NetSurf")); + if((strlen("NetSurf")%4) != 0) + rsize += (4-(strlen("NetSurf")%4)); + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + rsize = strlen("USERAGENT"); + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + xosgbpb_writew(pfile, (byte const*)"USERAGENT", rsize, NULL); + + for(i=0; i!=4; i++) + pdata[i] = 0; + xosgbpb_writew(pfile, pdata, (4 - ((rsize%4) == 0 ? 4 : (rsize%4))), NULL); + + rsize = strlen("NetSurf"); + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + xosgbpb_writew(pfile, (byte const*)"NetSurf", rsize, NULL); + + for(i=0; i!=4; i++) + pdata[i] = 0; + xosgbpb_writew(pfile, pdata, (4 - ((rsize%4) == 0 ? 4 : (rsize%4))), NULL); + break; + + case 2: rsize = 0; + rsize += (4 + 9 + 3); + rsize += (4 + strlen("0.01")); + if((strlen("0.01")%4) != 0) + rsize += (4-(strlen("0.01")%4)); + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + rsize = strlen("UAVERSION"); + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + xosgbpb_writew(pfile, (byte const*)"UAVERSION", rsize, NULL); + + for(i=0; i!=4; i++) + pdata[i] = 0; + xosgbpb_writew(pfile, pdata, (4 - ((rsize%4) == 0 ? 4 : (rsize%4))), NULL); + + rsize = strlen("0.01"); + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + xosgbpb_writew(pfile, (byte const*)"0.01", rsize, NULL); + + for(i=0; i!=4; i++) + pdata[i] = 0; + xosgbpb_writew(pfile, pdata, (4 - ((rsize%4) == 0 ? 4 : (rsize%4))), NULL); + break; + + case 3: rsize = 0; + rsize += (4 + 10 + 2); + rsize += (4 + strlen("1.10")); + if((strlen("1.10")%4) != 0) + rsize += (4-(strlen("1.10")%4)); + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + rsize = strlen("APIVERSION"); + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + xosgbpb_writew(pfile, (byte const*)"APIVERSION", rsize, NULL); + + for(i=0; i!=4; i++) + pdata[i] = 0; + xosgbpb_writew(pfile, pdata, (4 - ((rsize%4) == 0 ? 4 : (rsize%4))), NULL); + + rsize = strlen("1.10"); + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + xosgbpb_writew(pfile, (byte const*)"1.10", rsize, NULL); + + for(i=0; i!=4; i++) + pdata[i] = 0; + xosgbpb_writew(pfile, pdata, (4 - ((rsize%4) == 0 ? 4 : (rsize%4))), NULL); + break; + case 4: rsize = 0; + rsize += (4 + 7 + 1); + rsize += (4 + strlen("FFFFFF00")); + if((strlen("FFFFFF00")%4) != 0) + rsize += (4-(strlen("FFFFFF00")%4)); + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + rsize = strlen("BGCOLOR"); + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + xosgbpb_writew(pfile, (byte const*)"BGCOLOR", rsize, NULL); + + for(i=0; i!=4; i++) + pdata[i] = 0; + xosgbpb_writew(pfile, pdata, (4 - ((rsize%4) == 0 ? 4 : (rsize%4))), NULL); + + rsize = strlen("FFFFFF00"); + pdata[0] = rsize & 0xff; + pdata[1] = (rsize >> 0x08) & 0xff; + pdata[2] = (rsize >> 0x10) & 0xff; + pdata[3] = (rsize >> 0x18) & 0xff; + xosgbpb_writew(pfile, pdata, 4, NULL); + + xosgbpb_writew(pfile, (byte const*)"FFFFFF00", rsize, NULL); + + for(i=0; i!=4; i++) + pdata[i] = 0; + xosgbpb_writew(pfile, pdata, (4 - ((rsize%4) == 0 ? 4 : (rsize%4))), NULL); + break; + } + + } + + /* Write terminator */ + for(i=0; i!=4; i++) + pdata[i] = 0; + + xosgbpb_writew(pfile, pdata, 4, NULL); + xosfind_closew(pfile); }