/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "xp.h"
#include "net.h"
#include "pa_parse.h"
#include "layout.h"
#include "laylayer.h"
#include "np.h"
#include "np2.h"
#include "laystyle.h"
#include "layers.h"
#ifdef XP_WIN16
#define SIZE_LIMIT 32000
#endif /* XP_WIN16 */
#define EMBED_DEF_DIM 50
#define EMBED_DEF_BORDER 0
#define EMBED_DEF_VERTICAL_SPACE 0
#define EMBED_DEF_HORIZONTAL_SPACE 0
void lo_FinishEmbed(MWContext *, lo_DocState *, LO_EmbedStruct *);
static void lo_FormatEmbedInternal(MWContext *, lo_DocState *, PA_Tag *,
LO_EmbedStruct *, Bool, Bool);
void
lo_AddEmbedData(MWContext *context, void *session_data, lo_FreeProc freeProc, int32 indx)
{
int32 doc_id;
lo_TopState *top_state;
lo_DocState *state;
lo_SavedEmbedListData *embed_list;
lo_EmbedDataElement* embed_data_list;
int32 old_count;
/*
* Get the state, so we can access the savedEmbedListData
* list for this document.
*/
doc_id = XP_DOCID(context);
top_state = lo_FetchTopState(doc_id);
if ((top_state != NULL) && (top_state->doc_state != NULL))
state = top_state->doc_state;
else
return;
embed_list = state->top_state->savedData.EmbedList;
if (embed_list == NULL)
return;
/*
* We may have to grow the list to fit this new data.
*/
if (indx >= embed_list->embed_count)
{
PA_Block old_embed_data_list; /* really a (lo_EmbedDataElement **) */
#ifdef XP_WIN16
/*
* On 16 bit windows arrays can just get too big.
*/
if (((indx + 1) * sizeof(lo_EmbedDataElement)) > SIZE_LIMIT)
return;
#endif /* XP_WIN16 */
old_count = embed_list->embed_count;
embed_list->embed_count = indx + 1;
old_embed_data_list = NULL;
if (old_count == 0) /* Allocate new array */
{
embed_list->embed_data_list = PA_ALLOC(
embed_list->embed_count * sizeof(lo_EmbedDataElement));
}
else /* Enlarge existing array */
{
old_embed_data_list = embed_list->embed_data_list;
embed_list->embed_data_list = PA_REALLOC(
embed_list->embed_data_list,
(embed_list->embed_count * sizeof(lo_EmbedDataElement)));
}
/*
* If we ran out of memory to grow the array.
*/
if (embed_list->embed_data_list == NULL)
{
embed_list->embed_data_list = old_embed_data_list;
embed_list->embed_count = old_count;
state->top_state->out_of_memory = TRUE;
return;
}
/*
* We enlarged the array, so make sure
* the new slots are zero-filled.
*/
PA_LOCK(embed_data_list, lo_EmbedDataElement*, embed_list->embed_data_list);
while (old_count < embed_list->embed_count)
{
embed_data_list[old_count].data = NULL;
embed_data_list[old_count].freeProc = NULL;
old_count++;
}
PA_UNLOCK(embed_list->embed_data_list);
}
/*
* Store the new data into the list.
*/
PA_LOCK(embed_data_list, lo_EmbedDataElement*, embed_list->embed_data_list);
embed_data_list[indx].data = session_data;
embed_data_list[indx].freeProc = freeProc;
PA_UNLOCK(embed_list->embed_data_list);
}
void
LO_ClearEmbedBlock(MWContext *context, LO_EmbedStruct *embed)
{
int32 doc_id;
lo_TopState *top_state;
lo_DocState *main_doc_state;
lo_DocState *state;
/*
* Get the unique document ID, and retreive this
* documents layout state.
*/
doc_id = XP_DOCID(context);
top_state = lo_FetchTopState(doc_id);
if ((top_state == NULL)||(top_state->doc_state == NULL))
{
return;
}
if (top_state->layout_blocking_element == (LO_Element *)embed)
{
if (embed->objTag.width == 0)
{
embed->objTag.width = EMBED_DEF_DIM;
}
if (embed->objTag.height == 0)
{
embed->objTag.height = EMBED_DEF_DIM;
}
main_doc_state = top_state->doc_state;
state = lo_CurrentSubState(main_doc_state);
lo_FinishEmbed(context, state, embed);
lo_FlushBlockage(context, state, main_doc_state);
}
}
void
lo_FormatEmbed(MWContext *context, lo_DocState *state, PA_Tag *tag)
{
LO_EmbedStruct *embed;
embed = (LO_EmbedStruct *)lo_NewElement(context, state, LO_EMBED, NULL, 0);
if (embed == NULL)
{
return;
}
embed->objTag.type = LO_EMBED;
embed->objTag.ele_id = NEXT_ELEMENT;
embed->objTag.x = state->x;
embed->objTag.x_offset = 0;
embed->objTag.y = state->y;
embed->objTag.y_offset = 0;
embed->objTag.width = 0;
embed->objTag.height = 0;
embed->objTag.next = NULL;
embed->objTag.prev = NULL;
LO_NVList_Init( &embed->attributes );
LO_NVList_Init( &embed->parameters );
embed->attributes.n = PA_FetchAllNameValues(tag,
&(embed->attributes.names), &(embed->attributes.values), CS_FE_ASCII);
lo_FormatEmbedInternal(context, state, tag, embed, FALSE, FALSE);
}
void
lo_FormatEmbedObject(MWContext* context, lo_DocState* state,
PA_Tag* tag , LO_EmbedStruct* embed, Bool streamStarted,
uint32 param_count, char** param_names, char** param_values)
{
uint32 count;
#if !defined(OJI)
int32 typeIndex;
int32 classidIndex;
#endif
LO_NVList_Init(&embed->attributes);
embed->attributes.n = PA_FetchAllNameValues(tag,
&(embed->attributes.names), &(embed->attributes.values), CS_FE_ASCII);
for (count = 0; count < (uint32)embed->attributes.n; count++)
{
if ( (XP_STRCASECMP(embed->attributes.names[count], PARAM_MAYSCRIPT) == 0)
&&(embed->attributes.values[count] == NULL) ) {
StrAllocCopy(embed->attributes.values[count], "true");
}
}
/* beard: should the following still be used? */
#if !defined(OJI)
/*
* Look through the parameters and replace "id"
* with "name" and "data" with "src", so that
* other code that looks up parameters by name
* can believe this is a normal EMBED.
*/
for (count = 0; count < (uint32)embed->attributes.n; count++)
{
char* attrName = embed->attributes.names[count];
if (XP_STRCASECMP(attrName, PARAM_ID) == 0)
StrAllocCopy(embed->attributes.names[count], PARAM_NAME);
else if (XP_STRCASECMP(attrName, PARAM_DATA) == 0)
StrAllocCopy(embed->attributes.names[count], "src");
else if (XP_STRCASECMP(attrName, PARAM_TYPE) == 0)
typeIndex = count;
else if (XP_STRCASECMP(attrName, PARAM_CLASSID) == 0)
classidIndex = count;
}
/*
* If we have a CLASSID attribute, add the appropriate
* TYPE attribute.
*/
if (classidIndex >= 0)
{
if (typeIndex >= 0)
{
/* Change current value of TYPE to application/oleobject */
if (XP_STRCASECMP(embed->attributes.values[typeIndex], APPLICATION_OLEOBJECT) != 0)
StrAllocCopy(embed->attributes.values[typeIndex], APPLICATION_OLEOBJECT);
}
else
{
/* Add TYPE=application/oleobject to the attribute list */
char* names[1];
char* values[1];
names[0] = XP_STRDUP(PARAM_TYPE);
values[0] = XP_STRDUP(APPLICATION_OLEOBJECT);
lo_AppendParamList((uint32*) &(embed->attributes.n),
&(embed->attributes.names),
&(embed->attributes.values),
1, names, values);
}
/* Lop off the "clsid:" prefix from the CLASSID attribute */
if (XP_STRNCASECMP(embed->attributes.values[classidIndex], "clsid:", 6) == 0)
{
char* classID = &(embed->attributes.values[classidIndex][6]);
XP_MEMMOVE(embed->attributes.values[classidIndex], classID,
(XP_STRLEN(classID) + 1) * sizeof(char));
}
}
#endif /* !OJI */
/*
* Merge any parameters passed in with the ones in this tag.
* Separate the merged tag attributes from the
*