home *** CD-ROM | disk | FTP | other *** search
- /* -*- Mode: C++; tab-width: 8; 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.
- */
-
-
- #define M12N
-
- #ifdef MOZILLA_CLIENT
-
- /*
- * xp_cntxt.c
- * Contains various XP context related functions
- * Recomended when FE communicates with lib code in a complex way
- */
-
- #include "xp.h"
- #include "shist.h"
- #include "glhist.h"
- #include "ssl.h"
- #include "libimg.h" /* Image Lib public API. */
- #include "libmocha.h"
- #include "libevent.h"
- #include "intl_csi.h"
- #include "xp_ncent.h"
-
- static XP_List * xp_GlobalContextList = NULL;
- static int32 global_context_id = 0;
-
-
- void
- XP_InitializeContext(MWContext *context)
- {
- if (context != NULL)
- {
- context->context_id = ++global_context_id;
- context->INTL_tag = INTL_TAG;
- }
- }
-
- /* WARNING ! the mac FE does not call this ! */
- MWContext *
- XP_NewContext(void)
- {
- MWContext *context;
-
- context = XP_NEW_ZAP(MWContext);
- XP_ASSERT(NULL != context);
- if (NULL == context)
- {
- return NULL;
- }
- context->INTL_CSIInfo = INTL_CSICreate();
- if (NULL == context->INTL_CSIInfo)
- {
- XP_FREE(context);
- return NULL;
- }
- XP_InitializeContext(context);
- return context;
- }
- /* WARNING ! the mac FE does not call this ! */
- void
- XP_DeleteContext(MWContext *context)
- {
- XP_ASSERT(context);
- INTL_CSIDestroy(context->INTL_CSIInfo);
- XP_FREE(context);
- }
-
- /* give access to the global context list to other code too.
- */
- XP_List *XP_GetGlobalContextList(void)
- {
- return(xp_GlobalContextList);
- }
-
- /* cx_AddChildContext
- * Adds child context to the parents children list
- * NULL-safe
- */
- void cx_AddChildContext(MWContext *parent, MWContext * child)
- {
- if ((parent == NULL) || (child == NULL))
- return;
- if (parent->grid_children == NULL)
- parent->grid_children = XP_ListNew();
- if (parent->grid_children == NULL)
- return;
- XP_ListAddObject(parent->grid_children, child);
- }
-
- /* cx_RemoveChildContext
- * Removes child context from its parent
- * NULL-safe
- */
- void cx_RemoveChildContext(MWContext * child)
- {
- if ((child == NULL) || (child->grid_parent == NULL))
- return;
- XP_ListRemoveObject(child->grid_parent->grid_children, child);
- }
-
- /*
- * if the passed context is in the global context list
- * TRUE is returned. Otherwise false
- */
- Bool XP_IsContextInList(MWContext *context)
- {
- if (context == NULL)
- return FALSE;
-
- if (xp_GlobalContextList == NULL)
- return(FALSE);
-
- return((XP_ListFindObject(xp_GlobalContextList, context)
- ? TRUE : FALSE));
- }
-
- /*
- * The passed context is added to the global context list
- */
- void XP_AddContextToList(MWContext *context)
- {
- if (context == NULL)
- return;
-
- if (xp_GlobalContextList == NULL)
- xp_GlobalContextList = XP_ListNew();
-
- if (xp_GlobalContextList == NULL)
- return;
-
- XP_ListRemoveObject(xp_GlobalContextList, context); /* No dups */
- XP_ListAddObject(xp_GlobalContextList, context);
- cx_AddChildContext(context->grid_parent, context);
- }
-
- void XP_UpdateParentContext(MWContext * child)
- {
- cx_AddChildContext(child->grid_parent, child);
- }
- /*
- * Removes the context from the context list
- * Notifies all its children
- */
- void XP_RemoveContextFromList(MWContext *context)
- {
- int howMany;
- int i;
-
- if (context == NULL)
- return;
- cx_RemoveChildContext(context); /* Its parent does not point to it any more */
- /* Now take care of the children, this should not really happen */
- if (context->grid_children)
- {
- howMany = XP_ListCount(context->grid_children);
- for (i = 1; i <= howMany; i++)
- {
- MWContext * child;
- child = (MWContext *)XP_ListGetObjectNum(context->grid_children, 1);
- if (child)
- child->grid_parent = NULL;
- XP_ListRemoveObject(context->grid_children, child);
- }
- XP_ListDestroy(context->grid_children);
- context->grid_children = NULL;
- }
- XP_ListRemoveObject(xp_GlobalContextList, context);
-
- /* Remove from last active stack.
- * Remove any nav center info about the context.
- */
- XP_RemoveContextFromLastActiveStack(context);
- XP_RemoveNavCenterInfo(context);
- }
-
- /* the following was adapted from xp_FindNamedContextInChildren, but
- simplified for simply matching pointers instead of names. */
- Bool
- XP_IsChildContext(MWContext* parent, MWContext* child)
- {
- int i;
- if (parent == child) {
- return TRUE;
- }
- if (parent->grid_children) {
- int count = XP_ListCount(parent->grid_children);
- for (i = 1; i <= count; i++) {
- MWContext* tchild =
- (MWContext*)XP_ListGetObjectNum(parent->grid_children, i);
- if (child == tchild) {
- return TRUE;
- }
- else{
- XP_Bool found = XP_IsChildContext(tchild, child);
- if (found) return found;
- }
- }
- }
- return FALSE;
- }
-
-
- MWContext*
- xp_FindNamedContextInChildren(MWContext* self, char* name, MWContext* excludeChild)
- {
- int i;
- /*
- XP_TRACE(("Searching for %s: context %0x, name=%s, title=%s\n",
- (name ? name : ""), self,
- (self->name ? self->name : ""), (self->title ? self->title : "")));
- */
- if (self->name && XP_STRCMP(self->name, name) == 0) {
- /*
- XP_TRACE(("Found %s context %0x name=%s\n", (name ? name : ""),
- self, self->name));
- */
- return self;
- }
- if (self->grid_children) {
- int count = XP_ListCount(self->grid_children);
- for (i = 1; i <= count; i++) {
- MWContext* child =
- (MWContext*)XP_ListGetObjectNum(self->grid_children, i);
- if (child != excludeChild) {
- MWContext* found = xp_FindNamedContextInChildren(child, name, NULL);
- if (found) return found;
- }
- }
- }
- return NULL;
- }
-
- /*
- * Finds a context that should be loaded with the URL, given
- * a name and current (refering) context.
- *
- * If the context returned is not NULL, name is already assigned to context
- * structure. You should load the URL into this context.
- *
- * If you get back a NULL, you should create a new window
- *
- * Both context and current context can be null.
- * Once the grids are in, there should be some kind of a logic that searches
- * siblings first.
- */
-
- MWContext * XP_FindNamedContextInList(MWContext * context, char *name)
- {
- int i;
-
- if ((name == NULL) || (xp_GlobalContextList == NULL))
- return context;
-
- /*
- * Check for special magic window target names
- */
- if (name[0] == '_')
- {
- if (XP_STRNCMP(name, "_self", 5) == 0)
- {
- return context;
- }
- else if (XP_STRNCMP(name, "_parent", 7) == 0)
- {
- if ((context)&&(context->grid_parent))
- {
- return context->grid_parent;
- }
- else
- {
- return context;
- }
- }
- else if (XP_STRNCMP(name, "_top", 4) == 0)
- {
- MWContext *top;
-
- top = context;
- while ((top)&&(top->grid_parent))
- {
- top = top->grid_parent;
- }
- return top;
- }
- else if (XP_STRNCMP(name, "_blank", 6) == 0)
- {
- return NULL;
- }
- /* else, search for the name, below */
- }
-
- {
- MWContext* cx = context;
- MWContext* found;
- if (context) {
- /* If our current context has the right name, go there */
- if (cx->name &&
- (XP_STRCMP(cx->name, name) == 0))
- return cx;
- found = xp_FindNamedContextInChildren(cx, name, NULL);
- if (found) return found;
- while (cx->is_grid_cell) {
- MWContext* parent = cx->grid_parent;
- found = xp_FindNamedContextInChildren(parent, name, cx);
- if (found) return found;
- cx = parent;
- }
- }
-
- /* otherwise, just get any other context */
- for (i=1; i<= XP_ListCount(xp_GlobalContextList); i++)
- {
- MWContext* compContext = (MWContext *)XP_ListGetObjectNum(xp_GlobalContextList, i);
- /* Only search other top-level contexts that aren't the one we just came from: */
- if (!compContext->is_grid_cell && compContext != cx) {
- found = xp_FindNamedContextInChildren(compContext, name, NULL);
- if (found) return found;
- }
- }
- }
- return NULL;
- }
-
-
- /*
- * Finds a context that should be loaded with the URL, given
- * a type and current (refering) context. Return NULL if there is none.
- */
- MWContext * XP_FindContextOfType (MWContext * context, MWContextType type)
- {
- int i;
-
- /* The other types aren't "real" - they don't have windows. (Actually,
- neither do all of these, but it's damned useful to be able to find the
- biff context...) */
- XP_ASSERT (type == MWContextBrowser ||
- type == MWContextMail ||
- type == MWContextNews ||
- type == MWContextMessageComposition ||
- type == MWContextBookmarks ||
- type == MWContextAddressBook ||
- type == MWContextBiff ||
- type == MWContextMailMsg ||
- type == MWContextNewsMsg ||
- type == MWContextEditor ||
- type == MWContextPane);
- /* Added MWContextEditor, needed for bug 61630 */
-
- /* If our current context has the right type, go there */
- if (context && context->type == type)
- return context;
-
- /* otherwise, just get any other context */
- for (i=1; i<= XP_ListCount(xp_GlobalContextList); i++)
- {
- MWContext * compContext = (MWContext *)XP_ListGetObjectNum(xp_GlobalContextList, i);
- if (compContext->type == type)
- return compContext;
- }
- return NULL;
- }
-
- MWContext*
- XP_FindSomeContext()
- {
- MWContext* cx = XP_FindContextOfType(NULL, MWContextBrowser);
- if (!cx)
- cx = XP_FindContextOfType(NULL, MWContextMail);
- if (!cx)
- cx = XP_FindContextOfType(NULL, MWContextNews);
- if (!cx)
- cx = XP_FindContextOfType(NULL, MWContextPane);
- #if 0 /* dp says don't do this */
- if (!cx)
- cx = fe_all_MWContexts->context;
- #endif
- return cx;
- }
-
- /* Returns the first non-grid parent of a given context (can be the context
- * itself if it's not a grid cell).
- */
- MWContext *
- XP_GetNonGridContext(MWContext *context)
- {
- MWContext* ctxt = context;
- while (ctxt && ctxt->is_grid_cell)
- ctxt = ctxt->grid_parent;
- return ctxt;
- }
-
- /* FE should call XP_FindNamedAnchor before getting a URL
- * that is going into an HTML window (output_format is FO_CACHE_AND_PRESENT
- *
- * if named anchor is found:
- * XP_FindNamedAnchor
- * - updates context history, and global history properly
- * if it is not found, we do not touch any arguments
- *
- * Usage:
- * In your GetURL routine
- * if (XP_FindNamedAnchor(context, url, &x, &y))
- * {
- * SetDocPosition(x,y);
- * if (url->history_num == 0) // if you are not handling go back this way, do not do this
- * SHIST_AddDocument( &fContext, SHIST_CreateHistoryEntry( url, he->title) );
- * else
- * SHIST_SetCurrent(&fContext->hist, url->history_num);
- * SetURLTextField(url->address);
- * SetURLTextFieldTitle( ... url->is_netsite ... );
- * NET_FreeURLStruct(url);
- * RegenerateHistoryMenuAndDialogBoxContents()
- * }
- * else
- * NET_GetURL
- */
- Bool XP_FindNamedAnchor(MWContext * context, URL_Struct * url,
- int32 *xpos, int32 *ypos)
- {
- History_entry *he;
-
- if (!context)
- return FALSE;
-
- he = SHIST_GetCurrent (&context->hist);
-
- if (he
- && he->address
- && url
- && url->address
- && XP_STRCHR(url->address, '#') /* it must have a named hash */
- && url->method == URL_GET_METHOD
- && url->force_reload == NET_DONT_RELOAD
- && LO_LocateNamedAnchor(context, url, xpos, ypos))
- {
- GH_UpdateGlobalHistory( url );
- /* don't do this - jwz. */
- /* NET_FreeURLStruct( url ); */
- return TRUE;
- }
- return FALSE;
- }
-
- /* XP_RefreshAnchors
- * call it after loading a new URL to refresh all the anchors
- */
- void XP_RefreshAnchors()
- {
- int i;
- for (i=1; i<= XP_ListCount(xp_GlobalContextList); i++)
- {
- MWContext * compContext = (MWContext *)XP_ListGetObjectNum(xp_GlobalContextList, i);
- LO_RefreshAnchors(compContext);
- }
- }
-
- /* XP_InterruptContext
- * interrupts this context, and all the grid cells it encloses
- */
- void XP_InterruptContext(MWContext * context)
- {
- int i = 1;
- MWContext * child;
-
- if (context == NULL)
- return;
-
- /* Interrupt the children recursively first.
- * This avoids the scenario where the context is destroyed during
- * an interrupt and we end up dereferencing a freed context.
- * This also avoids crazy hacks like caching the grid_children
- * context list until after the interrupt, and then doing the
- * below loop. That can also crash if the grid_children context
- * list is freed off....
- * Bug fix 58770
- */
- while(child = (MWContext *)XP_ListGetObjectNum(context->grid_children, i++))
- XP_InterruptContext(child);
-
- NET_InterruptWindow(context);
- if (context->img_cx)
- IL_InterruptContext(context->img_cx);
- ET_InterruptContext(context);
- }
-
- Bool XP_IsContextBusy(MWContext * context)
- {
- int i = 1;
- MWContext * child;
-
- if (context == NULL)
- return FALSE;
-
- if (NET_AreThereActiveConnectionsForWindow(context))
- return TRUE;
-
- while ((child = (MWContext*)XP_ListGetObjectNum (context->grid_children,
- i++)))
- if (XP_IsContextBusy(child))
- return TRUE;
-
- return FALSE;
- }
-
- Bool XP_IsContextStoppable(MWContext * context)
- {
- int i = 1;
- MWContext * child;
-
- if (context == NULL)
- return FALSE;
-
- if (NET_AreThereActiveConnectionsForWindow(context))
- return TRUE;
-
- if (LM_IsActive(context))
- return TRUE;
-
- while ((child = (MWContext*)XP_ListGetObjectNum (context->grid_children,
- i++)))
- if (XP_IsContextStoppable(child))
- return TRUE;
-
- return FALSE;
- }
-
- /*
- * Will return the lowest security status of the context
- * and it's children.
- * Lowest means lowest in security, not in numberic value.
- *
- * Possible returns are:
- * SSL_SECURITY_STATUS_NOOPT
- * SSL_SECURITY_STATUS_OFF
- * SSL_SECURITY_STATUS_ON_HIGH
- * SSL_SECURITY_STATUS_ON_LOW
- */
- int XP_GetSecurityStatus(MWContext *pContext) {
- History_entry *pHistEnt;
- MWContext *pChild;
- int iRetval, iIndex;
-
- /*
- * No context, no security.
- */
- if(pContext == NULL) {
- return(SSL_SECURITY_STATUS_NOOPT);
- }
-
- /*
- * Obtain the context's current history entry (it holds
- * security info).
- */
- pHistEnt = SHIST_GetCurrent(&(pContext->hist));
- if(pHistEnt == NULL) {
- /*
- * Nothing loaded, Confusion ensues here.
- * If we've a parent context, then our security
- * is a noopt (shouldn't be counted towards
- * the whole).
- * If we've no parent context, then our security
- * is off.
- * This allows grids to have empty panes, but to
- * still be secure if all grids which have
- * something loaded are secure.
- */
- if(pContext->grid_parent == NULL) {
- return(SSL_SECURITY_STATUS_OFF);
- }
- else {
- return(SSL_SECURITY_STATUS_NOOPT);
- }
- }
-
- /*
- * Our security status.
- */
- iRetval = pHistEnt->security_on;
-
- /*
- * If we're a grid parent, our security status
- * is a noopt (doesn't affect the whole).
- * This allows the parent grid document to be non
- * secure, and all the inner grids to be secure,
- * and therefore the document should still be
- * considered secure as a whole.
- */
- if(XP_ListIsEmpty(pContext->grid_children)) {
- return(iRetval);
- }
- iRetval = SSL_SECURITY_STATUS_NOOPT;
-
- /*
- * Go through each child, getting it's security status.
- * We combine them all and return that value.
- */
- iIndex = 1;
- while((pChild = (MWContext *)XP_ListGetObjectNum(
- pContext->grid_children, iIndex++))) {
-
- switch(XP_GetSecurityStatus(pChild)) {
- case SSL_SECURITY_STATUS_NOOPT:
- /*
- * No definable security status. Don't
- * change our current value.
- */
- break;
- case SSL_SECURITY_STATUS_OFF:
- /*
- * No need in continuing if we're turning
- * off security altogether.
- */
- return(SSL_SECURITY_STATUS_OFF);
- break;
- case SSL_SECURITY_STATUS_ON_LOW:
- /*
- * Change the return value to lower security.
- */
- iRetval = SSL_SECURITY_STATUS_ON_LOW;
- break;
- case SSL_SECURITY_STATUS_ON_HIGH:
- /*
- * If we're currently noopt, then we should
- * change the security status to HIGH.
- * Otherwise, don't change the cumulative status
- * which could be lower than HIGH.
- */
- if(iRetval == SSL_SECURITY_STATUS_NOOPT) {
- iRetval = SSL_SECURITY_STATUS_ON_HIGH;
- }
- break;
- #ifdef FORTEZZA
- case SSL_SECURITY_STATUS_FORTEZZA:
- /*
- * If any fortezza, set to fortezza..
- */
- iRetval = SSL_SECURITY_STATUS_FORTEZZA;
- break;
- #endif
- default:
- /*
- * Shouldn't be here, unless new security status
- * introduced.
- */
- XP_ASSERT(0);
- break;
- }
- }
-
- /*
- * Context is somewhat secure, either high or low.
- * This could also be noopt, meaning no definable security,
- * so turn off your UI as if SSL_SECURITY_STATUS_OFF.
- * We can't just change the return value of
- * SSL_SECURITY_STATUS_NOOPT to OFF because this
- * breaks the recursive correctness of this routine.
- * Handle it accordingly.
- */
- return(iRetval);
- }
-
- /*
- * Count the contexts of the said type.
- * The second parameter is a flag indicating wether or not the contexts
- * counted can have parent contexts (top level context switch).
- */
- int XP_ContextCount(MWContextType cxType, XP_Bool bTopLevel)
- {
- int iRetval = 0;
- int iTraverse;
- MWContext *pContext;
-
- /*
- * Loop through the contexts.
- */
- for(iTraverse = 1; iTraverse <= XP_ListCount(xp_GlobalContextList); iTraverse++) {
- pContext = (MWContext *)XP_ListGetObjectNum(xp_GlobalContextList, iTraverse);
- if(cxType == MWContextAny || pContext->type == cxType) {
- /*
- * See if there's to be no parent.
- */
- if(bTopLevel == FALSE || pContext->is_grid_cell == FALSE) {
- iRetval++;
- }
- }
- }
-
- return(iRetval);
- }
-
- #endif /* MOZILLA_CLIENT */
-