Merge changes from mozilla-central to electrolysis

This commit is contained in:
Benjamin Smedberg 2009-06-30 12:04:18 -04:00
commit e527ef540e
399 changed files with 99731 additions and 32669 deletions

View File

@ -73,11 +73,5 @@ XPIDLSRCS = \
nsIXBLAccessible.idl \
$(NULL)
ifdef MOZ_XUL
XPIDLSRCS += \
nsIAccessibleTreeCache.idl \
$(NULL)
endif
include $(topsrcdir)/config/rules.mk

View File

@ -1,101 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Louie Zhao <Louie.Zhao@sun.com> (original author)
* Alexander Surkov <surkov.alexander@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
#include "nsITreeColumns.idl"
interface nsIAccessible;
/**
* A private interface to operate with tree accessible.
*
* @status UNDER_REVIEW
*/
[uuid(1dde5c3b-bede-43d1-aabf-dabc461113bd)]
interface nsIAccessibleTreeCache : nsISupports
{
/**
* Get tree item from cache according to row and column, create if doesn't
* exist in cache.
*
* @param aRow the given row index
* @param aColumn the given column object. If is is nsnull then primary
* column is used. It makes sense for ATK only.
*/
nsIAccessible getCachedTreeitemAccessible(in long aRow,
in nsITreeColumn aColumn);
/**
* Invalidates the number of cached treeitem accessibles.
*
* @param aRow row index the invalidation starts from
* @param aCount the number of treeitem accessibles to invalidate,
* the number sign specifies whether rows have been
* inserted (plus) or removed (minus)
*/
void invalidateCache(in long aRow, in long aCount);
/**
* Fires name change events for invalidated area of tree.
*
* @param aStartRow row index invalidation starts from
* @param aEndRow row index invalidation ends, -1 means last row index
* @param aStartCol column index invalidation starts from
* @param aEndCol column index invalidation ends, -1 mens last column
* index
*/
void treeViewInvalidated(in long aStartRow, in long aEndRow,
in long aStartCol, in long aEndCol);
/**
* Invalidates children created for previous tree view.
*/
void treeViewChanged();
};
[uuid(b71532f9-53b2-4647-a5b2-1c5f57e9aed6)]
interface nsPIAccessibleTreeItem : nsISupports
{
/**
* Get/set cached name.
*/
attribute AString cachedName;
};

View File

@ -123,7 +123,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eSortAction,
eNoLiveAttr,
kNoReqStates,
eARIASelected,
eARIASelectable,
eARIAReadonly
},
{
@ -174,7 +174,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoAction,
eNoLiveAttr,
kNoReqStates,
eARIASelected,
eARIASelectable,
eARIAReadonly
},
{
@ -251,7 +251,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoAction, // XXX: should depend on state, parent accessible
eNoLiveAttr,
nsIAccessibleStates::STATE_READONLY,
eARIASelected,
eARIASelectable,
eARIACheckedMixed
},
{
@ -338,7 +338,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eSelectAction,
eNoLiveAttr,
kNoReqStates,
eARIASelected,
eARIASelectable,
eARIACheckedMixed
},
{
@ -395,7 +395,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoAction,
eNoLiveAttr,
kNoReqStates,
eARIASelected
eARIASelectable
},
{
"rowheader",
@ -405,7 +405,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eSortAction,
eNoLiveAttr,
kNoReqStates,
eARIASelected,
eARIASelectable,
eARIAReadonly
},
{
@ -552,7 +552,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
// on states
eNoLiveAttr,
kNoReqStates,
eARIASelected,
eARIASelectable,
eARIACheckedMixed
}
};
@ -655,10 +655,11 @@ nsStateMapEntry nsARIAMap::gWAIStateMap[] = {
nsStateMapEntry(&nsAccessibilityAtoms::aria_required, kBoolType, 0,
nsIAccessibleStates::STATE_REQUIRED, 0),
// eARIASelected
// eARIASelectable
nsStateMapEntry(&nsAccessibilityAtoms::aria_selected, kBoolType,
nsIAccessibleStates::STATE_SELECTABLE,
nsIAccessibleStates::STATE_SELECTED, 0)
nsIAccessibleStates::STATE_SELECTED, 0,
0, 0, PR_TRUE)
};
/**

View File

@ -178,7 +178,7 @@ enum eStateMapEntryID
eARIAReadonly,
eARIAReadonlyOrEditable,
eARIARequired,
eARIASelected
eARIASelectable
};
class nsStateMapEntry

View File

@ -50,6 +50,7 @@
#include "nsAccessibleTreeWalker.h"
#include "nsAccessible.h"
#include "nsARIAMap.h"
#include "nsXULTreeAccessible.h"
#include "nsIDOMXULContainerElement.h"
#include "nsIDOMXULSelectCntrlEl.h"
@ -768,6 +769,28 @@ nsAccUtils::QueryAccessibleDocument(nsIAccessibleDocument *aAccessibleDocument)
return accessible;
}
#ifdef MOZ_XUL
already_AddRefed<nsXULTreeAccessible>
nsAccUtils::QueryAccessibleTree(nsIAccessible *aAccessible)
{
nsXULTreeAccessible* accessible = nsnull;
if (aAccessible)
CallQueryInterface(aAccessible, &accessible);
return accessible;
}
already_AddRefed<nsXULTreeitemAccessible>
nsAccUtils::QueryAccessibleTreeitem(nsIAccessNode *aAccessNode)
{
nsXULTreeitemAccessible* accessible = nsnull;
if (aAccessNode)
CallQueryInterface(aAccessNode, &accessible);
return accessible;
}
#endif
#ifdef DEBUG_A11Y
PRBool

View File

@ -56,6 +56,10 @@ class nsAccessNode;
class nsAccessible;
class nsHTMLTableAccessible;
class nsDocAccessible;
#ifdef MOZ_XUL
class nsXULTreeAccessible;
class nsXULTreeitemAccessible;
#endif
class nsAccUtils
{
@ -354,6 +358,20 @@ public:
static already_AddRefed<nsDocAccessible>
QueryAccessibleDocument(nsIAccessibleDocument *aAccessibleDocument);
#ifdef MOZ_XUL
/**
* Query nsXULTreeAccessible from the given nsIAccessible.
*/
static already_AddRefed<nsXULTreeAccessible>
QueryAccessibleTree(nsIAccessible *aAccessible);
/**
* Query nsXULTreeitemAccessible from the given nsIAccessNode.
*/
static already_AddRefed<nsXULTreeitemAccessible>
QueryAccessibleTreeitem(nsIAccessNode *aAccessNode);
#endif
#ifdef DEBUG_A11Y
/**
* Detect whether the given accessible object implements nsIAccessibleText,

View File

@ -268,6 +268,7 @@ nsAccEvent::GetAccessibleByNode()
nsIAccessible *accessible = nsnull;
accService->GetAccessibleFor(mDOMNode, &accessible);
#ifdef MOZ_XUL
// hack for xul tree table. We need a better way for firing delayed event
// against xul tree table. see bug 386821.
@ -282,18 +283,12 @@ nsAccEvent::GetAccessibleByNode()
PRInt32 treeIndex = -1;
multiSelect->GetCurrentIndex(&treeIndex);
if (treeIndex >= 0) {
nsCOMPtr<nsIAccessibleTreeCache> treeCache(do_QueryInterface(accessible));
NS_IF_RELEASE(accessible);
nsCOMPtr<nsIAccessible> treeItemAccessible;
if (!treeCache ||
NS_FAILED(treeCache->GetCachedTreeitemAccessible(
treeIndex,
nsnull,
getter_AddRefs(treeItemAccessible))) ||
!treeItemAccessible) {
return nsnull;
nsRefPtr<nsXULTreeAccessible> treeCache =
nsAccUtils::QueryAccessibleTree(accessible);
if (treeCache) {
treeCache->GetCachedTreeitemAccessible(treeIndex, nsnull,
&accessible);
}
NS_IF_ADDREF(accessible = treeItemAccessible);
}
}
}

View File

@ -257,12 +257,11 @@ nsDocAccessible::SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry)
mRoleMapEntry = aRoleMapEntry;
// Allow use of ARIA role from outer to override
nsIDocument *parentDoc = mDocument->GetParentDocument();
NS_ASSERTION(parentDoc, "No parent document during initialization!");
if (!parentDoc)
return;
return; // No parent document for the root document
// Allow use of ARIA role from outer to override
nsIContent *ownerContent = parentDoc->FindContentForSubDocument(mDocument);
nsCOMPtr<nsIDOMNode> ownerNode(do_QueryInterface(ownerContent));
if (ownerNode) {
@ -807,8 +806,26 @@ nsresult nsDocAccessible::RemoveEventListeners()
// Remove scroll position listener
RemoveScrollListener();
// Remove document observer
mDocument->RemoveObserver(this);
NS_ASSERTION(mDocument, "No document during removal of listeners.");
if (mDocument) {
mDocument->RemoveObserver(this);
nsCOMPtr<nsISupports> container = mDocument->GetContainer();
nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem(do_QueryInterface(container));
NS_ASSERTION(docShellTreeItem, "doc should support nsIDocShellTreeItem.");
if (docShellTreeItem) {
PRInt32 itemType;
docShellTreeItem->GetItemType(&itemType);
if (itemType == nsIDocShellTreeItem::typeContent) {
nsCOMPtr<nsICommandManager> commandManager = do_GetInterface(docShellTreeItem);
if (commandManager) {
commandManager->RemoveCommandObserver(this, "obs_documentCreated");
}
}
}
}
if (mScrollWatchTimer) {
mScrollWatchTimer->Cancel();
@ -826,19 +843,6 @@ nsresult nsDocAccessible::RemoveEventListeners()
}
}
nsCOMPtr<nsISupports> container = mDocument->GetContainer();
nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem(do_QueryInterface(container));
NS_ENSURE_TRUE(docShellTreeItem, NS_ERROR_FAILURE);
PRInt32 itemType;
docShellTreeItem->GetItemType(&itemType);
if (itemType == nsIDocShellTreeItem::typeContent) {
nsCOMPtr<nsICommandManager> commandManager = do_GetInterface(docShellTreeItem);
if (commandManager) {
commandManager->RemoveCommandObserver(this, "obs_documentCreated");
}
}
return NS_OK;
}
@ -1050,6 +1054,17 @@ NS_IMPL_NSIDOCUMENTOBSERVER_CORE_STUB(nsDocAccessible)
NS_IMPL_NSIDOCUMENTOBSERVER_LOAD_STUB(nsDocAccessible)
NS_IMPL_NSIDOCUMENTOBSERVER_STYLE_STUB(nsDocAccessible)
void
nsDocAccessible::AttributeWillChange(nsIDocument *aDocument,
nsIContent* aContent, PRInt32 aNameSpaceID,
nsIAtom* aAttribute, PRInt32 aModType)
{
// XXX TODO: bugs 381599 467143 472142 472143
// Here we will want to cache whatever state we are potentially interested in,
// such as the existence of aria-pressed for button (so we know if we need to
// newly expose it as a toggle button) etc.
}
void
nsDocAccessible::AttributeChanged(nsIDocument *aDocument, nsIContent* aContent,
PRInt32 aNameSpaceID, nsIAtom* aAttribute,

View File

@ -669,13 +669,16 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
#ifdef MOZ_XUL
if (isTree) {
nsCOMPtr<nsIAccessibleTreeCache> treeAcc(do_QueryInterface(accessible));
nsRefPtr<nsXULTreeAccessible> treeAcc =
nsAccUtils::QueryAccessibleTree(accessible);
NS_ASSERTION(treeAcc,
"Accessible for xul:tree doesn't implement nsIAccessibleTreeCache interface.");
"Accessible for xul:tree isn't nsXULTreeAccessible.");
if (treeAcc) {
if (eventType.EqualsLiteral("TreeViewChanged"))
return treeAcc->TreeViewChanged();
if (eventType.EqualsLiteral("TreeViewChanged")) {
treeAcc->TreeViewChanged();
return NS_OK;
}
if (eventType.EqualsLiteral("TreeRowCountChanged"))
return HandleTreeRowCountChangedEvent(aEvent, treeAcc);
@ -730,16 +733,14 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
PRInt32 treeIndex = -1;
multiSelect->GetCurrentIndex(&treeIndex);
if (treeIndex >= 0) {
nsCOMPtr<nsIAccessibleTreeCache> treeCache(do_QueryInterface(accessible));
if (!treeCache ||
NS_FAILED(treeCache->GetCachedTreeitemAccessible(
treeIndex,
nsnull,
getter_AddRefs(treeItemAccessible))) ||
!treeItemAccessible) {
return NS_ERROR_OUT_OF_MEMORY;
nsRefPtr<nsXULTreeAccessible> treeCache =
nsAccUtils::QueryAccessibleTree(accessible);
if (treeCache) {
treeCache->GetCachedTreeitemAccessible(treeIndex, nsnull,
getter_AddRefs(treeItemAccessible));
if (treeItemAccessible)
accessible = treeItemAccessible;
}
accessible = treeItemAccessible;
}
}
}
@ -1181,7 +1182,7 @@ nsRootAccessible::HandlePopupHidingEvent(nsIDOMNode *aNode,
#ifdef MOZ_XUL
nsresult
nsRootAccessible::HandleTreeRowCountChangedEvent(nsIDOMEvent *aEvent,
nsIAccessibleTreeCache *aAccessible)
nsXULTreeAccessible *aAccessible)
{
nsCOMPtr<nsIDOMDataContainerEvent> dataEvent(do_QueryInterface(aEvent));
if (!dataEvent)
@ -1203,12 +1204,13 @@ nsRootAccessible::HandleTreeRowCountChangedEvent(nsIDOMEvent *aEvent,
indexVariant->GetAsInt32(&index);
countVariant->GetAsInt32(&count);
return aAccessible->InvalidateCache(index, count);
aAccessible->InvalidateCache(index, count);
return NS_OK;
}
nsresult
nsRootAccessible::HandleTreeInvalidatedEvent(nsIDOMEvent *aEvent,
nsIAccessibleTreeCache *aAccessible)
nsXULTreeAccessible *aAccessible)
{
nsCOMPtr<nsIDOMDataContainerEvent> dataEvent(do_QueryInterface(aEvent));
if (!dataEvent)
@ -1240,7 +1242,8 @@ nsRootAccessible::HandleTreeInvalidatedEvent(nsIDOMEvent *aEvent,
if (endColVariant)
endColVariant->GetAsInt32(&endCol);
return aAccessible->TreeViewInvalidated(startRow, endRow, startCol, endCol);
aAccessible->TreeViewInvalidated(startRow, endRow, startCol, endCol);
return NS_OK;
}
#endif

View File

@ -43,7 +43,7 @@
#include "nsIAccessibleDocument.h"
#ifdef MOZ_XUL
#include "nsIAccessibleTreeCache.h"
#include "nsXULTreeAccessible.h"
#endif
#include "nsHashtable.h"
@ -51,7 +51,6 @@
#include "nsIDocument.h"
#include "nsIDOMFocusListener.h"
#include "nsIDOMFormListener.h"
#include "nsIDOMXULListener.h"
#include "nsITimer.h"
#define NS_ROOTACCESSIBLE_IMPL_CID \
@ -140,9 +139,9 @@ public:
#ifdef MOZ_XUL
nsresult HandleTreeRowCountChangedEvent(nsIDOMEvent *aEvent,
nsIAccessibleTreeCache *aAccessible);
nsXULTreeAccessible *aAccessible);
nsresult HandleTreeInvalidatedEvent(nsIDOMEvent *aEvent,
nsIAccessibleTreeCache *aAccessible);
nsXULTreeAccessible *aAccessible);
PRUint32 GetChromeFlags();
#endif

View File

@ -849,7 +849,11 @@ nsHTMLTableAccessible::GetIndexAt(PRInt32 aRow, PRInt32 aColumn,
nsresult rv = GetTableLayout(&tableLayout);
NS_ENSURE_SUCCESS(rv, rv);
return tableLayout->GetIndexByRowAndColumn(aRow, aColumn, aIndex);
rv = tableLayout->GetIndexByRowAndColumn(aRow, aColumn, aIndex);
if (rv == NS_TABLELAYOUT_CELL_NOT_FOUND)
return NS_ERROR_INVALID_ARG;
return NS_OK;
}
NS_IMETHODIMP

View File

@ -133,7 +133,9 @@ mAccessNodeCache(nsnull)
mAccessNodeCache->Init(kDefaultTreeCacheSize);
}
NS_IMPL_ISUPPORTS_INHERITED1(nsXULTreeAccessible, nsXULSelectableAccessible, nsIAccessibleTreeCache)
NS_IMPL_ISUPPORTS_INHERITED1(nsXULTreeAccessible,
nsXULSelectableAccessible,
nsXULTreeAccessible)
@ -220,6 +222,12 @@ NS_IMETHODIMP nsXULTreeAccessible::GetValue(nsAString& _retval)
return NS_OK;
}
PRBool
nsXULTreeAccessible::IsDefunct()
{
return nsXULSelectableAccessible::IsDefunct() || !mTree || !mTreeView;
}
nsresult
nsXULTreeAccessible::Shutdown()
{
@ -262,7 +270,7 @@ NS_IMETHODIMP nsXULTreeAccessible::GetFirstChild(nsIAccessible **aFirstChild)
mTreeView->GetRowCount(&rowCount);
if (rowCount > 0) {
nsCOMPtr<nsITreeColumn> column = GetFirstVisibleColumn(mTree);
return GetCachedTreeitemAccessible(0, column, aFirstChild);
GetCachedTreeitemAccessible(0, column, aFirstChild);
}
}
@ -281,12 +289,11 @@ nsXULTreeAccessible::GetLastChild(nsIAccessible **aLastChild)
mTreeView->GetRowCount(&rowCount);
if (rowCount > 0) {
nsCOMPtr<nsITreeColumn> column = GetLastVisibleColumn(mTree);
nsresult rv = GetCachedTreeitemAccessible(rowCount - 1, column, aLastChild);
NS_ENSURE_SUCCESS(rv, rv);
}
GetCachedTreeitemAccessible(rowCount - 1, column, aLastChild);
if (*aLastChild)
return NS_OK;
if (*aLastChild)
return NS_OK;
}
// If there is not any rows, use treecols as tree's last child.
return nsAccessible::GetLastChild(aLastChild);
@ -316,9 +323,8 @@ NS_IMETHODIMP nsXULTreeAccessible::GetFocusedChild(nsIAccessible **aFocusedChild
multiSelect->GetCurrentIndex(&row);
if (row >= 0) {
GetCachedTreeitemAccessible(row, nsnull, aFocusedChild);
if (*aFocusedChild) {
return NS_OK; // Already addref'd by getter
}
if (*aFocusedChild)
return NS_OK;
}
}
NS_ADDREF(*aFocusedChild = this);
@ -360,13 +366,7 @@ nsXULTreeAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
return nsXULSelectableAccessible::
GetChildAtPoint(aX, aY, aDeepestChild, aChild);
nsCOMPtr<nsIAccessible> treeitemAcc;
nsresult rv = GetCachedTreeitemAccessible(row, column,
getter_AddRefs(treeitemAcc));
NS_ENSURE_SUCCESS(rv, rv);
NS_IF_ADDREF(*aChild = treeitemAcc);
GetCachedTreeitemAccessible(row, column, aChild);
return NS_OK;
}
@ -392,9 +392,10 @@ NS_IMETHODIMP nsXULTreeAccessible::GetSelectedChildren(nsIArray **_retval)
selection->IsSelected(rowIndex, &isSelected);
if (isSelected) {
nsCOMPtr<nsIAccessible> tempAccess;
if (NS_FAILED(GetCachedTreeitemAccessible(rowIndex, nsnull, getter_AddRefs(tempAccess))) || !tempAccess)
GetCachedTreeitemAccessible(rowIndex, nsnull,
getter_AddRefs(tempAccess));
NS_ENSURE_STATE(tempAccess);
return NS_ERROR_OUT_OF_MEMORY;
selectedAccessibles->AppendElement(tempAccess, PR_FALSE);
}
}
@ -468,9 +469,11 @@ NS_IMETHODIMP nsXULTreeAccessible::ClearSelection()
return NS_OK;
}
NS_IMETHODIMP nsXULTreeAccessible::RefSelection(PRInt32 aIndex, nsIAccessible **_retval)
NS_IMETHODIMP
nsXULTreeAccessible::RefSelection(PRInt32 aIndex, nsIAccessible **aAccessible)
{
*_retval = nsnull;
NS_ENSURE_ARG_POINTER(aAccessible);
*aAccessible = nsnull;
NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE);
@ -487,7 +490,8 @@ NS_IMETHODIMP nsXULTreeAccessible::RefSelection(PRInt32 aIndex, nsIAccessible **
selection->IsSelected(rowIndex, &isSelected);
if (isSelected) {
if (selCount == aIndex) {
return GetCachedTreeitemAccessible(rowIndex, nsnull, _retval);
GetCachedTreeitemAccessible(rowIndex, nsnull, aAccessible);
return NS_OK;
}
selCount++;
}
@ -519,14 +523,13 @@ NS_IMETHODIMP nsXULTreeAccessible::SelectAllSelection(PRBool *_retval)
return NS_OK;
}
// nsIAccessible nsIAccessibleTreeCache::
// GetCachedTreeitemAccessible(in long aRow, nsITreeColumn* aColumn)
NS_IMETHODIMP
// nsXULTreeAccessible
void
nsXULTreeAccessible::GetCachedTreeitemAccessible(PRInt32 aRow,
nsITreeColumn* aColumn,
nsIAccessible** aAccessible)
{
NS_ENSURE_ARG_POINTER(aAccessible);
*aAccessible = nsnull;
NS_ASSERTION(mAccessNodeCache, "No accessibility cache for tree");
@ -548,59 +551,61 @@ nsXULTreeAccessible::GetCachedTreeitemAccessible(PRInt32 aRow,
// Do not create accessible for treeitem if there is no column in the tree
// because it doesn't render treeitems properly.
if (!col)
return NS_OK;
return;
col->GetIndex(&columnIndex);
nsCOMPtr<nsIAccessNode> accessNode;
GetCacheEntry(*mAccessNodeCache, (void*)(aRow * kMaxTreeColumns + columnIndex), getter_AddRefs(accessNode));
if (!accessNode)
{
nsXULTreeitemAccessibleWrap* treeItemAcc =
if (!accessNode) {
nsRefPtr<nsAccessNode> treeItemAcc =
new nsXULTreeitemAccessibleWrap(this, mDOMNode, mWeakShell, aRow, col);
NS_ENSURE_TRUE(treeItemAcc, NS_ERROR_OUT_OF_MEMORY);
if (!treeItemAcc)
return;
nsresult rv = treeItemAcc->Init();
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(rv))
return;
accessNode = treeItemAcc;
PutCacheEntry(*mAccessNodeCache, (void*)(aRow * kMaxTreeColumns + columnIndex), accessNode);
}
nsCOMPtr<nsIAccessible> accessible(do_QueryInterface(accessNode));
NS_IF_ADDREF(*aAccessible = accessible);
return NS_OK;
CallQueryInterface(accessNode, aAccessible);
}
// void nsIAccessibleTreeCache::
// invalidateCache(in PRInt32 aRow, in PRInt32 aCount)
NS_IMETHODIMP
void
nsXULTreeAccessible::InvalidateCache(PRInt32 aRow, PRInt32 aCount)
{
if (IsDefunct())
return;
// Do not invalidate the cache if rows have been inserted.
if (aCount > 0)
return NS_OK;
NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE);
return;
nsCOMPtr<nsITreeColumns> cols;
nsresult rv = mTree->GetColumns(getter_AddRefs(cols));
NS_ENSURE_STATE(cols);
mTree->GetColumns(getter_AddRefs(cols));
if (!cols)
return;
#ifdef MOZ_ACCESSIBILITY_ATK
PRInt32 colsCount = 0;
rv = cols->GetCount(&colsCount);
NS_ENSURE_SUCCESS(rv, rv);
nsresult rv = cols->GetCount(&colsCount);
if (NS_FAILED(rv))
return;
#else
nsCOMPtr<nsITreeColumn> col;
rv = cols->GetKeyColumn(getter_AddRefs(col));
NS_ENSURE_SUCCESS(rv, rv);
cols->GetKeyColumn(getter_AddRefs(col));
if (!col)
return NS_OK;
return;
PRInt32 colIdx = 0;
rv = col->GetIndex(&colIdx);
NS_ENSURE_SUCCESS(rv, rv);
nsresult rv = col->GetIndex(&colIdx);
if (NS_FAILED(rv))
return;
#endif
for (PRInt32 rowIdx = aRow; rowIdx < aRow - aCount; rowIdx++) {
@ -629,7 +634,8 @@ nsXULTreeAccessible::InvalidateCache(PRInt32 aRow, PRInt32 aCount)
PRInt32 newRowCount = 0;
rv = mTreeView->GetRowCount(&newRowCount);
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(rv))
return;
PRInt32 oldRowCount = newRowCount - aCount;
@ -643,18 +649,14 @@ nsXULTreeAccessible::InvalidateCache(PRInt32 aRow, PRInt32 aCount)
mAccessNodeCache->Remove(key);
}
}
return NS_OK;
}
// void nsIAccessibleTreeCache::
// treeViewInvalidated(in long aStartRow, in long aEndRow,
// in long aStartCol, in long aEndCol);
NS_IMETHODIMP
void
nsXULTreeAccessible::TreeViewInvalidated(PRInt32 aStartRow, PRInt32 aEndRow,
PRInt32 aStartCol, PRInt32 aEndCol)
{
NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE);
if (IsDefunct())
return;
PRInt32 endRow = aEndRow;
@ -662,14 +664,16 @@ nsXULTreeAccessible::TreeViewInvalidated(PRInt32 aStartRow, PRInt32 aEndRow,
if (endRow == -1) {
PRInt32 rowCount = 0;
rv = mTreeView->GetRowCount(&rowCount);
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(rv))
return;
endRow = rowCount - 1;
}
nsCOMPtr<nsITreeColumns> treeColumns;
mTree->GetColumns(getter_AddRefs(treeColumns));
NS_ENSURE_STATE(treeColumns);
if (!treeColumns)
return;
#ifdef MOZ_ACCESSIBILITY_ATK
PRInt32 endCol = aEndCol;
@ -677,21 +681,22 @@ nsXULTreeAccessible::TreeViewInvalidated(PRInt32 aStartRow, PRInt32 aEndRow,
if (endCol == -1) {
PRInt32 colCount = 0;
rv = treeColumns->GetCount(&colCount);
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(rv))
return;
endCol = colCount - 1;
}
#else
nsCOMPtr<nsITreeColumn> col;
rv = treeColumns->GetKeyColumn(getter_AddRefs(col));
NS_ENSURE_SUCCESS(rv, rv);
if (!col)
return NS_OK;
return;
PRInt32 colIdx = 0;
rv = col->GetIndex(&colIdx);
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(rv))
return;
#endif
for (PRInt32 rowIdx = aStartRow; rowIdx <= endRow; ++rowIdx) {
@ -705,37 +710,29 @@ nsXULTreeAccessible::TreeViewInvalidated(PRInt32 aStartRow, PRInt32 aEndRow,
GetCacheEntry(*mAccessNodeCache, key, getter_AddRefs(accessNode));
if (accessNode) {
nsCOMPtr<nsIAccessible> acc(do_QueryInterface(accessNode));
NS_ENSURE_STATE(acc);
nsCOMPtr<nsPIAccessibleTreeItem> treeItemAcc(
do_QueryInterface(accessNode));
NS_ENSURE_STATE(treeItemAcc);
nsRefPtr<nsXULTreeitemAccessible> treeitemAcc(
nsAccUtils::QueryAccessibleTreeitem(accessNode));
NS_ASSERTION(treeitemAcc, "Wrong accessible at the given key!");
nsAutoString name, cachedName;
rv = acc->GetName(name);
NS_ENSURE_SUCCESS(rv, rv);
rv = treeItemAcc->GetCachedName(cachedName);
NS_ENSURE_SUCCESS(rv, rv);
treeitemAcc->GetName(name);
treeitemAcc->GetCachedName(cachedName);
if (name != cachedName) {
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE, acc);
treeItemAcc->SetCachedName(name);
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE,
treeitemAcc);
treeitemAcc->SetCachedName(name);
}
}
}
}
return NS_OK;
}
// void nsIAccessibleTreeCache::treeViewChanged();
NS_IMETHODIMP
void
nsXULTreeAccessible::TreeViewChanged()
{
if (!mTree)
return NS_ERROR_FAILURE;
if (IsDefunct())
return;
// Fire only notification destroy/create events on accessible tree to lie to
// AT because it should be expensive to fire destroy events for each tree item
@ -743,22 +740,22 @@ nsXULTreeAccessible::TreeViewChanged()
nsCOMPtr<nsIAccessibleEvent> eventDestroy =
new nsAccEvent(nsIAccessibleEvent::EVENT_DOM_DESTROY,
this, PR_FALSE);
NS_ENSURE_TRUE(eventDestroy, NS_ERROR_OUT_OF_MEMORY);
if (!eventDestroy)
return;
nsresult rv = FirePlatformEvent(eventDestroy);
FirePlatformEvent(eventDestroy);
ClearCache(*mAccessNodeCache);
mTree->GetView(getter_AddRefs(mTreeView));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIAccessibleEvent> eventCreate =
new nsAccEvent(nsIAccessibleEvent::EVENT_DOM_CREATE,
this, PR_FALSE);
NS_ENSURE_TRUE(eventCreate, NS_ERROR_OUT_OF_MEMORY);
if (!eventCreate)
return;
return FirePlatformEvent(eventCreate);
FirePlatformEvent(eventCreate);
}
nsresult nsXULTreeAccessible::GetColumnCount(nsITreeBoxObject* aBoxObject, PRInt32* aCount)
@ -795,9 +792,12 @@ nsXULTreeitemAccessible::nsXULTreeitemAccessible(nsIAccessible *aParent, nsIDOMN
}
}
NS_IMPL_ISUPPORTS_INHERITED1(nsXULTreeitemAccessible, nsLeafAccessible,
nsPIAccessibleTreeItem)
NS_IMPL_ISUPPORTS_INHERITED1(nsXULTreeitemAccessible,
nsLeafAccessible,
nsXULTreeitemAccessible)
// nsAccessNode
nsresult
nsXULTreeitemAccessible::Shutdown()
{
@ -807,6 +807,8 @@ nsXULTreeitemAccessible::Shutdown()
return nsLeafAccessible::Shutdown();
}
// nsIAccessible
NS_IMETHODIMP
nsXULTreeitemAccessible::GetName(nsAString& aName)
{
@ -1102,7 +1104,8 @@ NS_IMETHODIMP nsXULTreeitemAccessible::GetNextSibling(nsIAccessible **aNextSibli
if (IsDefunct())
return NS_ERROR_FAILURE;
nsCOMPtr<nsIAccessibleTreeCache> treeCache(do_QueryInterface(mParent));
nsRefPtr<nsXULTreeAccessible> treeCache =
nsAccUtils::QueryAccessibleTree(mParent);
NS_ENSURE_TRUE(treeCache, NS_ERROR_FAILURE);
PRInt32 rowCount;
@ -1110,12 +1113,11 @@ NS_IMETHODIMP nsXULTreeitemAccessible::GetNextSibling(nsIAccessible **aNextSibli
if (!mColumn) {
if (mRow < rowCount - 1)
return treeCache->GetCachedTreeitemAccessible(mRow + 1, nsnull, aNextSibling);
else
return NS_OK;
treeCache->GetCachedTreeitemAccessible(mRow + 1, nsnull, aNextSibling);
return NS_OK;
}
nsresult rv = NS_OK;
PRInt32 row = mRow;
nsCOMPtr<nsITreeColumn> column;
#ifdef MOZ_ACCESSIBILITY_ATK
@ -1136,9 +1138,8 @@ NS_IMETHODIMP nsXULTreeitemAccessible::GetNextSibling(nsIAccessible **aNextSibli
}
#endif //MOZ_ACCESSIBILITY_ATK
rv = treeCache->GetCachedTreeitemAccessible(row, column, aNextSibling);
return rv;
treeCache->GetCachedTreeitemAccessible(row, column, aNextSibling);
return NS_OK;
}
// Return the previous row of tree if mColumn (if any),
@ -1151,12 +1152,13 @@ NS_IMETHODIMP nsXULTreeitemAccessible::GetPreviousSibling(nsIAccessible **aPrevi
if (IsDefunct())
return NS_ERROR_FAILURE;
nsCOMPtr<nsIAccessibleTreeCache> treeCache(do_QueryInterface(mParent));
nsRefPtr<nsXULTreeAccessible> treeCache =
nsAccUtils::QueryAccessibleTree(mParent);
NS_ENSURE_TRUE(treeCache, NS_ERROR_FAILURE);
if (!mColumn && mRow > 0)
return treeCache->GetCachedTreeitemAccessible(mRow - 1, nsnull, aPreviousSibling);
treeCache->GetCachedTreeitemAccessible(mRow - 1, nsnull, aPreviousSibling);
nsresult rv = NS_OK;
@ -1176,9 +1178,8 @@ NS_IMETHODIMP nsXULTreeitemAccessible::GetPreviousSibling(nsIAccessible **aPrevi
}
#endif
rv = treeCache->GetCachedTreeitemAccessible(row, column, aPreviousSibling);
return rv;
treeCache->GetCachedTreeitemAccessible(row, column, aPreviousSibling);
return NS_OK;
}
NS_IMETHODIMP nsXULTreeitemAccessible::DoAction(PRUint8 index)
@ -1294,13 +1295,12 @@ nsXULTreeitemAccessible::GetRelationByType(PRUint32 aRelationType,
if (parentIndex == -1)
return nsRelUtils::AddTarget(aRelationType, aRelation, mParent);
nsCOMPtr<nsIAccessibleTreeCache> cache =
do_QueryInterface(mParent);
nsRefPtr<nsXULTreeAccessible> treeCache =
nsAccUtils::QueryAccessibleTree(mParent);
nsCOMPtr<nsIAccessible> accParent;
nsresult rv = cache->
GetCachedTreeitemAccessible(parentIndex, mColumn,
getter_AddRefs(accParent));
NS_ENSURE_SUCCESS(rv, rv);
treeCache->GetCachedTreeitemAccessible(parentIndex, mColumn,
getter_AddRefs(accParent));
return nsRelUtils::AddTarget(aRelationType, aRelation, accParent);
}
@ -1312,20 +1312,17 @@ nsXULTreeitemAccessible::GetRelationByType(PRUint32 aRelationType,
return nsAccessible::GetRelationByType(aRelationType, aRelation);
}
// attribute AString nsIAccessibleTreeItem::cachedName
NS_IMETHODIMP
// nsXULTreeitemAccessible
void
nsXULTreeitemAccessible::GetCachedName(nsAString &aName)
{
aName = mCachedName;
return NS_OK;
}
// attribute AString nsIAccessibleTreeItem::cachedName
NS_IMETHODIMP
void
nsXULTreeitemAccessible::SetCachedName(const nsAString &aName)
{
mCachedName = aName;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
@ -1355,10 +1352,11 @@ nsXULTreeColumnsAccessible::GetNextSibling(nsIAccessible **aNextSibling)
nsCOMPtr<nsITreeColumn> column =
nsXULTreeAccessible::GetFirstVisibleColumn(tree);
nsCOMPtr<nsIAccessibleTreeCache> treeCache(do_QueryInterface(mParent));
nsRefPtr<nsXULTreeAccessible> treeCache =
nsAccUtils::QueryAccessibleTree(mParent);
NS_ENSURE_TRUE(treeCache, NS_ERROR_FAILURE);
return treeCache->GetCachedTreeitemAccessible(0, column, aNextSibling);
treeCache->GetCachedTreeitemAccessible(0, column, aNextSibling);
}
}
}

View File

@ -42,7 +42,6 @@
#include "nsITreeView.h"
#include "nsITreeColumns.h"
#include "nsXULSelectAccessible.h"
#include "nsIAccessibleTreeCache.h"
/*
* A class the represents the XUL Tree widget.
@ -50,17 +49,30 @@
const PRUint32 kMaxTreeColumns = 100;
const PRUint32 kDefaultTreeCacheSize = 256;
class nsXULTreeAccessible : public nsXULSelectableAccessible,
public nsIAccessibleTreeCache
/**
* Accessible class for XUL tree element.
*/
#define NS_XULTREEACCESSIBLE_IMPL_CID \
{ /* 2692e149-6176-42ee-b8e1-2c44b04185e3 */ \
0x2692e149, \
0x6176, \
0x42ee, \
{ 0xb8, 0xe1, 0x2c, 0x44, 0xb0, 0x41, 0x85, 0xe3 } \
}
class nsXULTreeAccessible : public nsXULSelectableAccessible
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIACCESSIBLESELECTABLE
NS_DECL_NSIACCESSIBLETREECACHE
nsXULTreeAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
virtual ~nsXULTreeAccessible() {}
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
// nsIAccessibleSelectable
NS_DECL_NSIACCESSIBLESELECTABLE
// nsIAccessible
NS_IMETHOD GetValue(nsAString& _retval);
@ -70,6 +82,7 @@ public:
NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild);
// nsAccessNode
virtual PRBool IsDefunct();
virtual nsresult Shutdown();
// nsAccessible
@ -80,6 +93,48 @@ public:
nsIAccessible **aChild);
// nsXULTreeAccessible
NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEACCESSIBLE_IMPL_CID)
/**
* Return tree item accessible at the givem row and column. If accessible
* doesn't exist in the cache then create it.
*
* @param aRow [in] the given row index
* @param aColumn [in] the given column object. If is is nsnull then
* primary column is used
* @param aAccessible [out] tree item accessible
*/
void GetCachedTreeitemAccessible(PRInt32 aRow, nsITreeColumn *aColumn,
nsIAccessible **aAccessible);
/**
* Invalidates the number of cached treeitem accessibles.
*
* @param aRow [in] row index the invalidation starts from
* @param aCount [in] the number of treeitem accessibles to invalidate,
* the number sign specifies whether rows have been
* inserted (plus) or removed (minus)
*/
void InvalidateCache(PRInt32 aRow, PRInt32 aCount);
/**
* Fires name change events for invalidated area of tree.
*
* @param aStartRow [in] row index invalidation starts from
* @param aEndRow [in] row index invalidation ends, -1 means last row index
* @param aStartCol [in] column index invalidation starts from
* @param aEndCol [in] column index invalidation ends, -1 mens last column
* index
*/
void TreeViewInvalidated(PRInt32 aStartRow, PRInt32 aEndRow,
PRInt32 aStartCol, PRInt32 aEndCol);
/**
* Invalidates children created for previous tree view.
*/
void TreeViewChanged();
static void GetTreeBoxObject(nsIDOMNode* aDOMNode, nsITreeBoxObject** aBoxObject);
static nsresult GetColumnCount(nsITreeBoxObject* aBoxObject, PRInt32 *aCount);
@ -96,26 +151,36 @@ protected:
NS_IMETHOD ChangeSelection(PRInt32 aIndex, PRUint8 aMethod, PRBool *aSelState);
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsXULTreeAccessible,
NS_XULTREEACCESSIBLE_IMPL_CID)
/**
* Treeitems -- used in Trees
*/
class nsXULTreeitemAccessible : public nsLeafAccessible,
public nsPIAccessibleTreeItem
* Accessible class for items for XUL tree.
*/
#define NS_XULTREEITEMACCESSIBLE_IMPL_CID \
{ /* 7b1aa039-7270-4523-aeb3-61063a13ac3f */ \
0x7b1aa039, \
0x7270, \
0x4523, \
{ 0xae, 0xb3, 0x61, 0x06, 0x3a, 0x13, 0xac, 0x3f } \
}
class nsXULTreeitemAccessible : public nsLeafAccessible
{
public:
enum { eAction_Click = 0, eAction_Expand = 1 };
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSPIACCESSIBLETREEITEM
nsXULTreeitemAccessible(nsIAccessible *aParent, nsIDOMNode *aDOMNode, nsIWeakReference *aShell, PRInt32 aRow, nsITreeColumn* aColumn = nsnull);
virtual ~nsXULTreeitemAccessible() {}
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
// nsIAccessible
NS_IMETHOD GetName(nsAString& aName);
NS_IMETHOD GetNumActions(PRUint8 *_retval);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
NS_IMETHOD GetParent(nsIAccessible **_retval);
NS_IMETHOD GetNextSibling(nsIAccessible **_retval);
@ -138,9 +203,19 @@ public:
virtual nsresult Shutdown();
// nsAccessible
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
virtual nsresult GetRoleInternal(PRUint32 *aRole);
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
// nsXULTreeitemAccessible
NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEITEMACCESSIBLE_IMPL_CID)
/**
* Get/set cached name.
*/
void GetCachedName(nsAString& aName);
void SetCachedName(const nsAString& aName);
protected:
PRBool IsExpandable();
nsCOMPtr<nsITreeBoxObject> mTree;
@ -150,6 +225,12 @@ protected:
nsString mCachedName;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsXULTreeitemAccessible,
NS_XULTREEITEMACCESSIBLE_IMPL_CID)
/**
* Accessible class for columns element of XUL tree.
*/
class nsXULTreeColumnsAccessible : public nsXULColumnsAccessible
{
public:

View File

@ -126,7 +126,7 @@ _TEST_FILES =\
test_table_2.html \
test_table_3.html \
test_table_4.html \
$(warning test_table_indexes.html temporarily disabled) \
test_table_indexes.html \
test_table_indexes_ariagrid.html \
test_table_sels_ariagrid.html \
test_textattrs.html \

View File

@ -2,70 +2,91 @@
* Test table indexes.
*
* @param aIdentifier [in] table accessible identifier
* @param aLen [in] cells count
* @param aRowIdxes [in] array of row indexes for each cell index
* @param aColIdxes [in] array of column indexes for each cell index
* @param aIdxes [in] two dimensional array of cell indexes
*/
function testTableIndexes(aIdentifier, aLen, aRowIdxes, aColIdxes)
function testTableIndexes(aIdentifier, aIdxes)
{
var tableAcc = getAccessible(aIdentifier, [nsIAccessibleTable]);
if (!tableAcc)
return;
var row, column, index;
var obtainedRowIdx, obtainedColIdx, obtainedIdx;
var cellAcc;
var id = prettyName(aIdentifier);
for (var i = 0; i < aLen; i++) {
try {
row = tableAcc.getRowAtIndex(i);
} catch (e) {
ok(false, id + ": can't get row index for cell index " + i + "," + e);
}
var rowCount = aIdxes.length;
for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
var colCount = aIdxes[rowIdx].length;
for (var colIdx = 0; colIdx < colCount; colIdx++) {
var idx = aIdxes[rowIdx][colIdx];
if (idx != - 1) {
// getRowAtIndex
var origRowIdx = rowIdx;
while (origRowIdx > 0 &&
aIdxes[rowIdx][colIdx] == aIdxes[origRowIdx - 1][colIdx])
origRowIdx--;
try {
column = tableAcc.getColumnAtIndex(i);
} catch (e) {
ok(false, id + ": can't get column index for cell index " + i + "," + e);
}
try {
obtainedRowIdx = tableAcc.getRowAtIndex(idx);
} catch (e) {
ok(false, id + ": can't get row index for cell index " + idx + "," + e);
}
try {
index = tableAcc.getIndexAt(aRowIdxes[i], aColIdxes[i]);
} catch (e) {
ok(false,
id + ": can't get cell index by row index " + aRowIdxes[i] +
" and column index: " + aColIdxes[i] + ", " + e);
}
is(obtainedRowIdx, origRowIdx,
id + ": row for index " + idx +" is not correct");
is(row, aRowIdxes[i], id + ": row for index " + i +" is nor correct");
is(column, aColIdxes[i],
id + ": column for index " + i +" is not correct");
is(index, i,
id + ": row " + row + " /column " + column + " and index " + index + " aren't inconsistent.");
// getColumnAtIndex
var origColIdx = colIdx;
while (origColIdx > 0 &&
aIdxes[rowIdx][colIdx] == aIdxes[rowIdx][origColIdx - 1])
origColIdx--;
try {
cellAcc = null;
cellAcc = tableAcc.cellRefAt(row, column);
} catch (e) { }
try {
obtainedColIdx = tableAcc.getColumnAtIndex(idx);
} catch (e) {
ok(false, id + ": can't get column index for cell index " + idx + "," + e);
}
ok(cellAcc,
id + ": Can't get cell accessible at row = " + row + ", column = " + column);
is(obtainedColIdx, origColIdx,
id + ": column for index " + idx +" is not correct");
if (cellAcc) {
var attrs = cellAcc.attributes;
var strIdx = "";
// cellRefAt
try {
cellAcc = null;
cellAcc = tableAcc.cellRefAt(rowIdx, colIdx);
} catch (e) { }
ok(cellAcc,
id + ": Can't get cell accessible at row = " + rowIdx + ", column = " + colIdx);
// 'table-cell-index' attribute
if (cellAcc) {
var attrs = cellAcc.attributes;
var strIdx = "";
try {
strIdx = attrs.getStringProperty("table-cell-index");
} catch (e) {
ok(false,
id + ": no cell index from object attributes on the cell accessible at index " + idx + ".");
}
if (strIdx) {
is (parseInt(strIdx), idx,
id + ": cell index from object attributes of cell accessible isn't corrent.");
}
}
}
// getIndexAt
try {
strIdx = attrs.getStringProperty("table-cell-index");
obtainedIdx = tableAcc.getIndexAt(rowIdx, colIdx);
} catch (e) {
ok(false,
id + ": no cell index from object attributes on the cell accessible at index " + index + ".");
obtainedIdx = -1;
}
if (strIdx) {
is (parseInt(strIdx), index,
id + ": cell index from object attributes of cell accessible isn't corrent.");
}
is(obtainedIdx, idx,
id + ": row " + rowIdx + " /column " + colIdx + " and index " + obtainedIdx + " aren't inconsistent.");
}
}
}

View File

@ -151,7 +151,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=452388
testStates("treeitem_selected_false", STATE_SELECTABLE, 0, STATE_SELECTED);
testStates("treeitem_selected_empty", 0, 0, (STATE_SELECTABLE | STATE_SELECTED));
testStates("treeitem_selected_undefined", 0, 0, (STATE_SELECTABLE | STATE_SELECTED));
testStates("treeitem_selected_absent", 0, 0, (STATE_SELECTABLE | STATE_SELECTED));
testStates("treeitem_selected_absent", STATE_SELECTABLE, 0, STATE_SELECTED);
// test (treeitem) haspopup states
testStates("treeitem_haspopup_true", STATE_HASPOPUP);

View File

@ -23,38 +23,90 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=410052
{
//////////////////////////////////////////////////////////////////////////
// table
var tRow = new Array(0,0,0,1,1,1,2,2,3,3);
var tCol = new Array(0,1,2,0,1,2,0,1,1,2);
var idxes = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 7],
[6, 8, 9]
];
testTableIndexes("table", 10, tRow, tCol);
//////////////////////////////////////////////////////////////////////////
// tableinsane1
tRow = [0,0,0,1,1,1,2,2,3,3];
tCol = [0,1,2,0,1,2,0,1,1,2];
testTableIndexes("tableinsane1", 10, tRow, tCol);
//////////////////////////////////////////////////////////////////////////
// tableinsane2
tRow = [0,0,0,1,1,1,2,2,3,3,4,4,4];
tCol = [0,1,2,0,1,2,0,1,1,2,1,3,4];
testTableIndexes("tableinsane2", 13, tRow, tCol);
//////////////////////////////////////////////////////////////////////////
// tableinsane4
tRow = [0,0,0,1,1,1,2,2,3,4];
tCol = [0,1,2,0,1,2,0,2,0,0];
testTableIndexes("tableinsane4", 10, tRow, tCol);
testTableIndexes("table", idxes);
//////////////////////////////////////////////////////////////////////////
// tableborder
tRow = [0,0,0,1,1,1,2,2,3,3];
tCol = [0,1,2,0,1,2,0,1,1,2];
idxes = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 7],
[6, 8, 9]
];
testTableIndexes("tableborder", 10, tRow, tCol);
testTableIndexes("tableborder", idxes);
//////////////////////////////////////////////////////////////////////////
// table
var idxes = [
[ 0, 1, 2, 2, 3, 4, 5, 6],
[ 7, 8, 9, 10, 11, 12, 13, 6],
[14, 15, 15, 16, 17, 18, 19, 6],
[20, 15, 15, 21, 22, 18, 23, 6]
];
testTableIndexes("table2", idxes);
//////////////////////////////////////////////////////////////////////////
// tableinsane1 (empty row groups)
idxes = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 7],
[6, 8, 9]
];
testTableIndexes("tableinsane1", idxes);
//////////////////////////////////////////////////////////////////////////
// tableinsane2 (empry rows)
idxes = [
[-1, -1, -1],
[-1, -1, -1],
[ 0, 1, 2]
];
testTableIndexes("tableinsane2", idxes);
//////////////////////////////////////////////////////////////////////////
// tableinsane3 (cell holes)
idxes = [
[0, 1, -1],
[2, 3, 4]
];
testTableIndexes("tableinsane3", idxes);
//////////////////////////////////////////////////////////////////////////
// tableinsane4 (empty row groups/rows and cell holes)
idxes = [
[ 0, 1, 2],
[-1, -1, -1],
[ 3, 4, 5],
[ 6, 6, 7],
[ 8, -1, 7],
[ 9, 9, 9]
];
testTableIndexes("tableinsane4", idxes);
//////////////////////////////////////////////////////////////////////////
// tableinsane4 (just a crazy table)
idxes = [
[ 0, 1, 2, -1, -1],
[-1, -1, -1, -1, -1],
[ 3, 4, 5, -1, -1],
[ 6, 7, 7, 7, 7],
[ 6, 8, 9, -1, -1],
[ 6, 10, 9, 11, 12]
];
testTableIndexes("tableinsane5", idxes);
SimpleTest.finish();
}
@ -127,6 +179,44 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=410052
</tbody>
</table>
<table cellpadding="2" cellspacing="2" border="1" width="50%" id="table2">
<caption>column and row spans</caption>
<tbody>
<tr>
<td>0</td>
<td>1</td>
<td rowspan="1" colspan="2">2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td rowspan="4" colspan="1">6</td>
</tr>
<tr>
<td>7</td>
<td>8</td>
<td>8</td>
<td>10</td>
<td>11</td>
<td>12</td>
<td>13</td>
</tr>
<tr>
<td>14</td>
<td rowspan="2" colspan="2">15</td>
<td>16</td>
<td>17</td>
<td rowspan="2" colspan="1">18</td>
<td>19</td>
</tr>
<tr>
<td>20</td>
<td>21</td>
<td>22</td>
<td>23</td>
</tr>
</tbody>
</table>
<table border="1" id="tableinsane1">
<caption>test empty row groups</caption>
<thead>
@ -156,8 +246,70 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=410052
</tbody>
</table>
<table border="1" id="tableinsane2" >
<caption>empty rowgroup + empty rows</caption>
<table border="1" id="tableinsane2">
<caption>empty rows</caption>
<tbody><tr></tr><tr></tr></tbody>
<tbody></tbody>
<tbody>
<tr>
<td>0</td>
<td>1</td>
<td>2</td>
</tr>
</tbody>
</table>
<table border="1" id="tableinsane3">
<caption>missed cell</caption>
<tbody>
<tr>
<td>0</td>
<td>1</td>
</tr>
</tbody>
<tbody>
<tr>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
</tbody>
</table>
<table border="1" id="tableinsane4">
<caption>test empty rows + cellmap holes</caption>
<thead>
<tr>
<th>col1</th>
<th>col2</th>
<th>col3</th>
</tr>
</thead>
<tbody><tr></tr></tbody>
<tbody></tbody>
<tbody></tbody>
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td colspan="2">4</td>
<td rowspan="2">5</td>
</tr>
<tr>
<td>6</td>
</tr>
<tr>
<td colspan="3">7</td>
</tr>
</tbody>
</table>
<table border="1" id="tableinsane5">
<caption>just a crazy table</caption>
<thead>
<tr>
<th>col1</th>
@ -190,37 +342,5 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=410052
</tbody>
<table border="1" id="tableinsane4" >
<caption>test cellmap holes</caption>
<thead>
<tr>
<th>col1</th>
<th>col2</th>
<th>col3</th>
</tr>
</thead>
<tbody><tr></tr></tbody>
<tbody></tbody>
<tbody></tbody>
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td colspan="2">4</td>
<td rowspan="2">5</td>
</tr>
<tr>
<td>6</td>
</tr>
<tr>
<td colspan="3">7</td>
</tr>
</tbody>
</table>
</body>
</html>

View File

@ -22,10 +22,13 @@
{
//////////////////////////////////////////////////////////////////////////
// ARIA grid
var tRow = new Array(0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3);
var tCol = new Array(0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2);
testTableIndexes("grid", 12, tRow, tCol);
var idxes = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[9, 10, 11]
];
testTableIndexes("grid", idxes);
SimpleTest.finish();
}

View File

@ -58,22 +58,32 @@ fi
add_makefiles "
Makefile
build/Makefile
build/pgo/Makefile
build/pgo/blueprint/Makefile
build/pgo/js-input/Makefile
build/unix/Makefile
build/win32/Makefile
config/Makefile
config/autoconf.mk
config/mkdepend/Makefile
config/nspr/Makefile
config/doxygen.cfg
config/tests/src-simple/Makefile
probes/Makefile
extensions/Makefile
build/wince/tools/Makefile
build/wince/shunt/Makefile
build/wince/shunt/include/windows.h
build/wince/shunt/include/ymath.h
build/wince/shunt/include/stdlib.h
build/wince/shunt/include/sys/Makefile
"
if [ "$WINCE" ]; then
add_makefiles "
build/wince/tools/Makefile
build/wince/shunt/Makefile
build/wince/shunt/include/windows.h
build/wince/shunt/include/ymath.h
build/wince/shunt/include/stdlib.h
build/wince/shunt/include/sys/Makefile
"
fi
if [ "$MOZ_MEMORY" ]; then
add_makefiles "
memory/jemalloc/Makefile

View File

@ -545,7 +545,7 @@
<hbox flex="1" id="browser">
<vbox id="sidebar-box" hidden="true" class="chromeclass-extrachrome">
<sidebarheader align="center">
<sidebarheader id="sidebar-header" align="center">
<label id="sidebar-title" persist="value" flex="1" crop="end" control="sidebar"/>
<image id="sidebar-throbber"/>
<toolbarbutton class="tabs-closebutton" tooltiptext="&sidebarCloseButton.tooltip;" oncommand="toggleSidebar();"/>

View File

@ -546,11 +546,14 @@ PlacesController.prototype = {
if (selectiontype == "single" && aMetaData.length != 1)
return false;
var forceHideRules = aMenuItem.getAttribute("forcehideselection").split("|");
for (var i = 0; i < aMetaData.length; ++i) {
for (var j=0; j < forceHideRules.length; ++j) {
if (forceHideRules[j] in aMetaData[i])
return false;
var forceHideAttr = aMenuItem.getAttribute("forcehideselection");
if (forceHideAttr) {
var forceHideRules = forceHideAttr.split("|");
for (var i = 0; i < aMetaData.length; ++i) {
for (var j=0; j < forceHideRules.length; ++j) {
if (forceHideRules[j] in aMetaData[i])
return false;
}
}
}

View File

@ -1366,7 +1366,7 @@ var PlacesUIUtils = {
aPopup._lmStatusMenuItem.setAttribute("label", this.getString(lmStatus));
aPopup._lmStatusMenuItem.setAttribute("disabled", true);
aPopup.insertBefore(aPopup._lmStatusMenuItem,
aPopup.childNodes[aPopup._startMarker + 1]);
aPopup.childNodes.item(aPopup._startMarker + 1));
aPopup._startMarker++;
}
else if (lmStatus &&

View File

@ -2766,7 +2766,7 @@ SessionStoreService.prototype = {
let normalWindowIndex = 0;
// try to find a non-popup window in this._closedWindows
while (normalWindowIndex < this._closedWindows.length &&
this._closedWindows[normalWindowIndex].isPopup)
!!this._closedWindows[normalWindowIndex].isPopup)
normalWindowIndex++;
if (normalWindowIndex >= maxWindowsUndo)
spliceTo = normalWindowIndex + 1;

View File

@ -113,7 +113,7 @@ function test() {
function test_behavior (callback) {
// helper function that does the actual testing
function openWindowRec(windowsToOpen, expectedResults) {
function openWindowRec(windowsToOpen, expectedResults, recCallback) {
// do actual checking
if (!windowsToOpen.length) {
let closedWindowData = JSON.parse(ss.getClosedWindowData());
@ -130,7 +130,7 @@ function test() {
"There were " + oResults.normal + " normal windows to repoen");
// cleanup & return
executeSoon(callback);
executeSoon(recCallback);
return;
}
// hack to force window to be considered a popup (toolbar=no didn't work)
@ -149,7 +149,7 @@ function test() {
executeSoon(function() {
window.close();
executeSoon(function() {
openWindowRec(windowsToOpen, expectedResults);
openWindowRec(windowsToOpen, expectedResults, recCallback);
});
});
}, true);

View File

@ -641,9 +641,7 @@ msvcr80.dll
#else
mozcrt19.dll
#endif
xpicleanup.exe
#else
xpicleanup
#endif
xpicleanup@BIN_SUFFIX@
chrome.manifest
install.rdf

View File

@ -64,8 +64,6 @@ vpath book%.inc @srcdir@/en-US/profile
endif
run_for_effects_too := if ! test -d $(DIST)/branding; then $(NSINSTALL) -D $(DIST)/branding; fi)
ifdef MOZ_BRANDING_DIRECTORY
SUBMAKEFILES += \
$(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/Makefile \
@ -104,6 +102,11 @@ include $(topsrcdir)/config/rules.mk
include $(topsrcdir)/toolkit/locales/l10n.mk
$(STAGEDIST): $(DIST)/branding
$(DIST)/branding:
$(NSINSTALL) -D $@
libs::
@if test -f "$(LOCALE_SRCDIR)/existing-profile-defaults.js"; then \
$(PERL) $(topsrcdir)/config/preprocessor.pl $(PREF_PPFLAGS) $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) \

View File

@ -42,25 +42,45 @@ browser/app/profile/extensions/Makefile
browser/base/Makefile
browser/components/Makefile
browser/components/build/Makefile
browser/components/certerror/Makefile
browser/components/dirprovider/Makefile
browser/components/feeds/Makefile
browser/components/feeds/public/Makefile
browser/components/feeds/src/Makefile
browser/components/microsummaries/Makefile
browser/components/microsummaries/public/Makefile
browser/components/microsummaries/src/Makefile
browser/components/migration/Makefile
browser/components/migration/public/Makefile
browser/components/migration/src/Makefile
browser/components/places/Makefile
browser/components/places/public/Makefile
browser/components/places/src/Makefile
browser/components/preferences/Makefile
browser/components/privatebrowsing/Makefile
browser/components/privatebrowsing/src/Makefile
browser/components/safebrowsing/Makefile
browser/components/safebrowsing/src/Makefile
browser/components/search/Makefile
browser/components/sessionstore/Makefile
browser/components/sessionstore/src/Makefile
browser/components/sidebar/Makefile
browser/components/sidebar/src/Makefile
browser/components/shell/Makefile
browser/components/shell/public/Makefile
browser/components/shell/src/Makefile
browser/fuel/Makefile
browser/fuel/public/Makefile
browser/fuel/src/Makefile
browser/installer/Makefile
browser/installer/windows/Makefile
browser/locales/Makefile
browser/themes/Makefile
browser/themes/pinstripe/browser/Makefile
browser/themes/pinstripe/communicator/Makefile
browser/themes/pinstripe/Makefile
browser/themes/winstripe/browser/Makefile
browser/themes/winstripe/communicator/Makefile
browser/themes/winstripe/Makefile
"
@ -71,3 +91,25 @@ if test -n "$MOZ_BRANDING_DIRECTORY"; then
$MOZ_BRANDING_DIRECTORY/locales/Makefile
"
fi
if [ "$ENABLE_TESTS" ]; then
add_makefiles "
browser/base/content/test/Makefile
browser/components/certerror/test/Makefile
browser/components/preferences/tests/Makefile
browser/components/search/test/Makefile
browser/components/sessionstore/test/Makefile
browser/components/sessionstore/test/browser/Makefile
browser/components/shell/test/Makefile
browser/components/feeds/test/Makefile
browser/components/feeds/test/chrome/Makefile
browser/components/places/tests/Makefile
browser/components/places/tests/chrome/Makefile
browser/components/places/tests/browser/Makefile
browser/components/places/tests/perf/Makefile
browser/components/privatebrowsing/test/Makefile
browser/components/privatebrowsing/test/browser/Makefile
browser/components/safebrowsing/content/test/Makefile
browser/fuel/test/Makefile
"
fi

View File

@ -238,6 +238,7 @@ MOZ_XTF = @MOZ_XTF@
MOZ_NO_INSPECTOR_APIS = @MOZ_NO_INSPECTOR_APIS@
MOZ_SVG = @MOZ_SVG@
MOZ_ENABLE_CANVAS = @MOZ_ENABLE_CANVAS@
MOZ_ENABLE_CANVAS3D = @MOZ_ENABLE_CANVAS3D@
MOZ_CAIRO_CFLAGS = @MOZ_CAIRO_CFLAGS@
MOZ_SMIL = @MOZ_SMIL@
MOZ_XSLT_STANDALONE = @MOZ_XSLT_STANDALONE@
@ -547,9 +548,6 @@ STATIC_LIBIDL = @STATIC_LIBIDL@
MOZ_NATIVE_MAKEDEPEND = @SYSTEM_MAKEDEPEND@
# Used for LD_LIBRARY_PATH
LIBS_PATH = @LIBS_PATH@
MOZ_AUTO_DEPS = @MOZ_AUTO_DEPS@
COMPILER_DEPEND = @COMPILER_DEPEND@
MDDEPDIR := @MDDEPDIR@

View File

@ -60,6 +60,7 @@ ABS_DIST = $(call core_abspath,$(DIST))
libs::
$(MAKE) -C $(DEPTH)/nsprpub install prefix=$(ABS_DIST)/sdk exec_prefix=$(ABS_DIST)/sdk bindir=$(ABS_DIST)/sdk/dummy includedir=$(ABS_DIST)/include libdir=$(ABS_DIST)/sdk/lib datadir=$(ABS_DIST)/sdk/dummy DESTDIR=
$(INSTALL) $(DEPTH)/nsprpub/config/nspr-config $(DIST)/bin
$(RM) -rf $(DIST)/sdk/dummy
ifneq (,$(filter OS2 WINNT,$(OS_ARCH))) # {
$(RM) -f $(DIST)/sdk/lib/$(DLL_PREFIX)nspr4$(DLL_SUFFIX) $(DIST)/sdk/lib/$(DLL_PREFIX)plc4$(DLL_SUFFIX) $(DIST)/sdk/lib/$(DLL_PREFIX)plds4$(DLL_SUFFIX)

View File

@ -946,12 +946,6 @@ endif # NO_PROFILE_GUIDED_OPTIMIZE
checkout:
$(MAKE) -C $(topsrcdir) -f client.mk checkout
run_viewer: $(FINAL_TARGET)/viewer
cd $(FINAL_TARGET); \
MOZILLA_FIVE_HOME=`pwd` \
LD_LIBRARY_PATH=".:$(LIBS_PATH):$$LD_LIBRARY_PATH" \
viewer
clean clobber realclean clobber_all:: $(SUBMAKEFILES)
-rm -f $(ALL_TRASH)
-rm -rf $(ALL_TRASH_DIRS)
@ -2106,7 +2100,7 @@ endif
# Fake targets. Always run these rules, even if a file/directory with that
# name already exists.
#
.PHONY: all alltags boot checkout chrome realchrome clean clobber clobber_all export install libs makefiles realclean run_viewer run_apprunner tools $(DIRS) $(TOOL_DIRS) FORCE
.PHONY: all alltags boot checkout chrome realchrome clean clobber clobber_all export install libs makefiles realclean run_apprunner tools $(DIRS) $(TOOL_DIRS) FORCE
# Used as a dependency to force targets to rebuild
FORCE:

View File

@ -62,6 +62,7 @@ be/kernel/image.h
be/kernel/OS.h
bfd.h
Bitmap.h
blapi.h
bsd/libc.h
bsd/syscall.h
bstring.h
@ -251,6 +252,7 @@ Finder.h
FinderRegistry.h
FixMath.h
float.h
fnmatch.h
Folders.h
fontconfig/fontconfig.h
fontconfig/fcfreetype.h
@ -272,6 +274,7 @@ fribidi/fribidi.h
FSp_fopen.h
fstream.h
ft2build.h
fts.h
gconf/gconf-client.h
Gdiplus.h
gdk/gdk.h
@ -789,6 +792,7 @@ time.h
Timer.h
tlhelp32.h
ToolUtils.h
tr1/functional
trace.h
Traps.h
typeinfo

View File

@ -4224,7 +4224,6 @@ if test -n "$MOZ_NATIVE_NSPR"; then
AC_MSG_ERROR([system NSPR does not support PR_STATIC_ASSERT]))
CFLAGS=$_SAVE_CFLAGS
else
NSPR_CFLAGS='`$(DEPTH)/nsprpub/config/nspr-config --prefix='${LIBXUL_DIST}' --includedir='${LIBXUL_DIST}'/include/nspr --cflags`'
if test "$OS_ARCH" = "WINCE"; then
NSPR_CFLAGS="-I${LIBXUL_DIST}/include/nspr"
NSPR_LIBS="${LIBXUL_DIST}/lib/nspr${NSPR_VERSION}.lib ${LIBXUL_DIST}/lib/plc${NSPR_VERSION}.lib ${LIBXUL_DIST}/lib/plds${NSPR_VERSION}.lib "
@ -4236,7 +4235,8 @@ else
NSPR_LIBS="${LIBXUL_DIST}/lib/nspr${NSPR_VERSION}.lib ${LIBXUL_DIST}/lib/plc${NSPR_VERSION}.lib ${LIBXUL_DIST}/lib/plds${NSPR_VERSION}.lib "
fi
else
NSPR_LIBS='`$(DEPTH)/nsprpub/config/nspr-config --prefix='${LIBXUL_DIST}' --libdir='${LIBXUL_DIST}'/lib --libs`'
NSPR_CFLAGS='`$(LIBXUL_DIST)/bin/nspr-config --prefix='${LIBXUL_DIST}' --includedir='${LIBXUL_DIST}'/include/nspr --cflags`'
NSPR_LIBS='`$(LIBXUL_DIST)/bin/nspr-config --prefix='${LIBXUL_DIST}' --libdir='${LIBXUL_DIST}'/lib --libs`'
fi
fi
@ -4491,6 +4491,7 @@ MOZ_ACTIVEX_SCRIPTING_SUPPORT=
MOZ_BRANDING_DIRECTORY=
MOZ_DBGRINFO_MODULES=
MOZ_ENABLE_CANVAS=1
MOZ_ENABLE_CANVAS3D=
MOZ_FEEDS=1
MOZ_IMG_DECODERS_DEFAULT="png gif jpeg bmp xbm icon"
MOZ_IMG_ENCODERS_DEFAULT="png jpeg"
@ -5930,6 +5931,15 @@ if test -n "$MOZ_ENABLE_CANVAS"; then
fi
AC_SUBST(MOZ_ENABLE_CANVAS)
MOZ_ARG_ENABLE_BOOL(canvas3d,
[ --enable-canvas3d Enable canvas 3D context],
MOZ_ENABLE_CANVAS3D=1,
MOZ_ENABLE_CANVAS3D= )
if test -n "$MOZ_ENABLE_CANVAS3D"; then
AC_DEFINE(MOZ_ENABLE_CANVAS3D)
fi
AC_SUBST(MOZ_ENABLE_CANVAS3D)
dnl ========================================================
dnl SVG
dnl ========================================================
@ -8335,16 +8345,6 @@ if test "$ACCESSIBILITY" -a "$MOZ_ENABLE_GTK2" ; then
AC_DEFINE_UNQUOTED(ATK_REV_VERSION, $ATK_REV_VERSION)
fi
# Used for LD_LIBRARY_PATH of run_viewer target
LIBS_PATH=
for lib_arg in $NSPR_LIBS $TK_LIBS; do
case $lib_arg in
-L* ) LIBS_PATH="${LIBS_PATH:+$LIBS_PATH:}"`expr $lib_arg : "-L\(.*\)"` ;;
* ) ;;
esac
done
AC_SUBST(LIBS_PATH)
dnl ========================================================
dnl Use cygwin wrapper for win32 builds, except MSYS/MinGW
dnl ========================================================

View File

@ -106,6 +106,7 @@ class nsIWidget;
class nsIDragSession;
class nsPIDOMWindow;
class nsPIDOMEventTarget;
class nsIPresShell;
#ifdef MOZ_XTF
class nsIXTFService;
#endif
@ -1401,6 +1402,21 @@ public:
nsString& aOrigin);
static nsresult GetUTFOrigin(nsIURI* aURI, nsString& aOrigin);
/**
* This method creates and dispatches "command" event, which implements
* nsIDOMXULCommandEvent.
* If aShell is not null, dispatching goes via
* nsIPresShell::HandleDOMEventWithTarget.
*/
static nsresult DispatchXULCommand(nsIContent* aTarget,
PRBool aTrusted,
nsIDOMEvent* aSourceEvent = nsnull,
nsIPresShell* aShell = nsnull,
PRBool aCtrl = PR_FALSE,
PRBool aAlt = PR_FALSE,
PRBool aShift = PR_FALSE,
PRBool aMeta = PR_FALSE);
/**
* Gets the nsIDocument given the script context. Will return nsnull on failure.
*
@ -1411,6 +1427,12 @@ public:
static already_AddRefed<nsIDocument>
GetDocumentFromScriptContext(nsIScriptContext *aScriptContext);
/**
* The method checks whether the caller can access native anonymous content.
* If there is no JS in the stack or privileged JS is running, this
* method returns PR_TRUE, otherwise PR_FALSE.
*/
static PRBool CanAccessNativeAnon();
private:
static PRBool InitializeEventTable();

View File

@ -105,8 +105,8 @@ class nsIBoxObject;
// IID for the nsIDocument interface
#define NS_IDOCUMENT_IID \
{ 0x9abf0b96, 0xc9e2, 0x4d49, \
{ 0x9c, 0x0a, 0x37, 0xc1, 0x22, 0x39, 0x83, 0x50 } }
{0x282f1cd0, 0x6dfb, 0x4cff, \
{0x83, 0x3e, 0x05, 0x98, 0x52, 0xe6, 0xd8, 0x59 } }
// Flag for AddStyleSheet().
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
@ -652,13 +652,6 @@ public:
virtual void StyleRuleRemoved(nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule) = 0;
/**
* Notify document of pending attribute change
*/
virtual void AttributeWillChange(nsIContent* aChild,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute) = 0;
/**
* Flush notifications for this document and its parent documents
* (since those may affect the layout of this one).

View File

@ -45,8 +45,8 @@ class nsIDocument;
class nsINode;
#define NS_IMUTATION_OBSERVER_IID \
{ 0x32e68316, 0x67d4, 0x44a5, \
{ 0x8d, 0x35, 0xd, 0x39, 0xf, 0xa9, 0xdf, 0x11 } }
{0x365d600b, 0x868a, 0x452a, \
{0x8d, 0xe8, 0xf4, 0x6f, 0xad, 0x8f, 0xee, 0x53 } }
/**
* Information details about a characterdata change. Basically, we
@ -138,6 +138,23 @@ public:
nsIContent* aContent,
CharacterDataChangeInfo* aInfo) = 0;
/**
* Notification that an attribute of an element will change.
*
* @param aDocument The owner-document of aContent. Can be null.
* @param aContent The element whose attribute will change
* @param aNameSpaceID The namespace id of the changing attribute
* @param aAttribute The name of the changing attribute
* @param aModType Whether or not the attribute will be added, changed, or
* removed. The constants are defined in
* nsIDOMMutationEvent.h.
*/
virtual void AttributeWillChange(nsIDocument* aDocument,
nsIContent* aContent,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aModType) = 0;
/**
* Notification that an attribute of an element has changed.
*
@ -251,6 +268,13 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIMutationObserver, NS_IMUTATION_OBSERVER_IID)
nsIContent* aContent, \
CharacterDataChangeInfo* aInfo);
#define NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTEWILLCHANGE \
virtual void AttributeWillChange(nsIDocument* aDocument, \
nsIContent* aContent, \
PRInt32 aNameSpaceID, \
nsIAtom* aAttribute, \
PRInt32 aModType);
#define NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED \
virtual void AttributeChanged(nsIDocument* aDocument, \
nsIContent* aContent, \
@ -285,6 +309,7 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIMutationObserver, NS_IMUTATION_OBSERVER_IID)
#define NS_DECL_NSIMUTATIONOBSERVER \
NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATAWILLCHANGE \
NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED \
NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTEWILLCHANGE \
NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED \
NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED \
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED \
@ -312,6 +337,14 @@ _class::CharacterDataChanged(nsIDocument* aDocument, \
{ \
} \
void \
_class::AttributeWillChange(nsIDocument* aDocument, \
nsIContent* aContent, \
PRInt32 aNameSpaceID, \
nsIAtom* aAttribute, \
PRInt32 aModType) \
{ \
} \
void \
_class::AttributeChanged(nsIDocument* aDocument, \
nsIContent* aContent, \
PRInt32 aNameSpaceID, \

View File

@ -439,10 +439,13 @@ public:
* @param aNotify whether to notify the document (current document for
* nsIContent, and |this| for nsIDocument) that the remove has
* occurred
* @param aMutationEvent whether to fire a mutation event
*
* Note: If there is no child at aIndex, this method will simply do nothing.
*/
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify) = 0;
virtual nsresult RemoveChildAt(PRUint32 aIndex,
PRBool aNotify,
PRBool aMutationEvent = PR_TRUE) = 0;
/**
* Get a property associated with this node.

View File

@ -84,6 +84,7 @@ REQUIRES = xpcom \
shistory \
editor \
windowwatcher \
html5 \
$(NULL)
ifdef ACCESSIBILITY

View File

@ -794,7 +794,7 @@ nsContentSink::ProcessStyleLink(nsIContent* aElement,
nsresult
nsContentSink::ProcessMETATag(nsIContent* aContent)
{
NS_ASSERTION(aContent, "missing base-element");
NS_ASSERTION(aContent, "missing meta-element");
nsresult rv = NS_OK;
@ -810,6 +810,16 @@ nsContentSink::ProcessMETATag(nsIContent* aContent)
rv = ProcessHeaderData(fieldAtom, result, aContent);
}
}
NS_ENSURE_SUCCESS(rv, rv);
/* Look for the viewport meta tag. If we find it, process it and put the
* data into the document header. */
if (aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
nsGkAtoms::viewport, eIgnoreCase)) {
nsAutoString value;
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::content, value);
rv = nsContentUtils::ProcessViewportInfo(mDocument, value);
}
return rv;
}

View File

@ -146,6 +146,8 @@ class nsContentSink : public nsICSSLoaderObserver,
virtual void UpdateChildCounts() = 0;
PRBool IsTimeToNotify();
protected:
nsContentSink();
virtual ~nsContentSink();
@ -241,12 +243,14 @@ protected:
nsIURI **aManifestURI,
CacheSelectionAction *aAction);
public:
// Searches for the offline cache manifest attribute and calls one
// of the above defined methods to select the document's application
// cache, let it be associated with the document and eventually
// schedule the cache update process.
void ProcessOfflineManifest(nsIContent *aElement);
protected:
// Tries to scroll to the URI's named anchor. Once we've successfully
// done that, further calls to this method will be ignored.
void ScrollToRef();
@ -255,10 +259,9 @@ protected:
// Start layout. If aIgnorePendingSheets is true, this will happen even if
// we still have stylesheet loads pending. Otherwise, we'll wait until the
// stylesheets are all done loading.
public:
void StartLayout(PRBool aIgnorePendingSheets);
PRBool IsTimeToNotify();
protected:
void
FavorPerformanceHint(PRBool perfOverStarvation, PRUint32 starvationDelay);

View File

@ -162,8 +162,11 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
#include "nsCPrefetchService.h"
#include "nsIChromeRegistry.h"
#include "nsIMIMEHeaderParam.h"
#include "nsIDOMXULCommandEvent.h"
#include "nsIDOMAbstractView.h"
#include "nsIDOMDragEvent.h"
#include "nsDOMDataTransfer.h"
#include "nsHtml5Module.h"
#ifdef IBMBIDI
#include "nsIBidiKeyboard.h"
@ -176,6 +179,7 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
#include "nsIConsoleService.h"
#include "mozAutoDocUpdate.h"
#include "jsinterp.h"
const char kLoadAsData[] = "loadAsData";
@ -3578,6 +3582,58 @@ nsContentUtils::CreateContextualFragment(nsIDOMNode* aContextNode,
// for compiling event handlers... so just bail out.
nsCOMPtr<nsIDocument> document = node->GetOwnerDoc();
NS_ENSURE_TRUE(document, NS_ERROR_NOT_AVAILABLE);
PRBool bCaseSensitive = document->IsCaseSensitive();
nsCOMPtr<nsIHTMLDocument> htmlDoc(do_QueryInterface(document));
PRBool bHTML = htmlDoc && !bCaseSensitive;
if (bHTML && nsHtml5Module::Enabled) {
// See if the document has a cached fragment parser. nsHTMLDocument is the
// only one that should really have one at the moment.
nsCOMPtr<nsIParser> parser = document->GetFragmentParser();
if (parser) {
// Get the parser ready to use.
parser->Reset();
}
else {
// Create a new parser for this operation.
parser = nsHtml5Module::NewHtml5Parser();
if (!parser) {
return NS_ERROR_OUT_OF_MEMORY;
}
document->SetFragmentParser(parser);
}
nsCOMPtr<nsIDOMDocumentFragment> frag;
rv = NS_NewDocumentFragment(getter_AddRefs(frag), document->NodeInfoManager());
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIContent> contextAsContent = do_QueryInterface(aContextNode);
if (contextAsContent && !contextAsContent->IsNodeOfType(nsINode::eELEMENT)) {
contextAsContent = contextAsContent->GetParent();
if (contextAsContent && !contextAsContent->IsNodeOfType(nsINode::eELEMENT)) {
// can this even happen?
contextAsContent = nsnull;
}
}
if (contextAsContent) {
parser->ParseFragment(aFragment,
frag,
contextAsContent->Tag(),
contextAsContent->GetNameSpaceID(),
(document->GetCompatibilityMode() == eCompatibility_NavQuirks));
} else {
parser->ParseFragment(aFragment,
frag,
nsGkAtoms::body,
kNameSpaceID_XHTML,
(document->GetCompatibilityMode() == eCompatibility_NavQuirks));
}
NS_ADDREF(*aReturn = frag);
return NS_OK;
}
nsAutoTArray<nsString, 32> tagStack;
nsAutoString uriStr, nameStr;
@ -3635,14 +3691,9 @@ nsContentUtils::CreateContextualFragment(nsIDOMNode* aContextNode,
}
nsCAutoString contentType;
PRBool bCaseSensitive = PR_TRUE;
nsAutoString buf;
document->GetContentType(buf);
LossyCopyUTF16toASCII(buf, contentType);
bCaseSensitive = document->IsCaseSensitive();
nsCOMPtr<nsIHTMLDocument> htmlDoc(do_QueryInterface(document));
PRBool bHTML = htmlDoc && !bCaseSensitive;
// See if the document has a cached fragment parser. nsHTMLDocument is the
// only one that should really have one at the moment.
@ -4943,3 +4994,94 @@ nsContentTypeParser::GetParameter(const char* aParameterName, nsAString& aResult
EmptyCString(), PR_FALSE, nsnull,
aResult);
}
/* static */
// If you change this code, change also AllowedToAct() in
// XPCSystemOnlyWrapper.cpp!
PRBool
nsContentUtils::CanAccessNativeAnon()
{
JSContext* cx = nsnull;
sThreadJSContextStack->Peek(&cx);
if (!cx) {
return PR_TRUE;
}
JSStackFrame* fp;
nsIPrincipal* principal =
sSecurityManager->GetCxSubjectPrincipalAndFrame(cx, &fp);
NS_ENSURE_TRUE(principal, PR_FALSE);
if (!fp) {
if (!JS_FrameIterator(cx, &fp)) {
// No code at all is running. So we must be arriving here as the result
// of C++ code asking us to do something. Allow access.
return PR_TRUE;
}
// Some code is running, we can't make the assumption, as above, but we
// can't use a native frame, so clear fp.
fp = nsnull;
}
void *annotation = fp ? JS_GetFrameAnnotation(cx, fp) : nsnull;
PRBool privileged;
if (NS_SUCCEEDED(principal->IsCapabilityEnabled("UniversalXPConnect",
annotation,
&privileged)) &&
privileged) {
// UniversalXPConnect things are allowed to touch us.
return PR_TRUE;
}
// XXX HACK EWW! Allow chrome://global/ access to these things, even
// if they've been cloned into less privileged contexts.
static const char prefix[] = "chrome://global/";
const char *filename;
if (fp && fp->script &&
(filename = fp->script->filename) &&
!strncmp(filename, prefix, NS_ARRAY_LENGTH(prefix) - 1)) {
return PR_TRUE;
}
return PR_FALSE;
}
/* static */ nsresult
nsContentUtils::DispatchXULCommand(nsIContent* aTarget,
PRBool aTrusted,
nsIDOMEvent* aSourceEvent,
nsIPresShell* aShell,
PRBool aCtrl,
PRBool aAlt,
PRBool aShift,
PRBool aMeta)
{
NS_ENSURE_STATE(aTarget);
nsIDocument* doc = aTarget->GetOwnerDoc();
nsCOMPtr<nsIDOMDocumentEvent> docEvent = do_QueryInterface(doc);
NS_ENSURE_STATE(docEvent);
nsCOMPtr<nsIDOMEvent> event;
docEvent->CreateEvent(NS_LITERAL_STRING("xulcommandevent"),
getter_AddRefs(event));
nsCOMPtr<nsIDOMXULCommandEvent> xulCommand = do_QueryInterface(event);
nsCOMPtr<nsIPrivateDOMEvent> pEvent = do_QueryInterface(xulCommand);
NS_ENSURE_STATE(pEvent);
nsCOMPtr<nsIDOMAbstractView> view = do_QueryInterface(doc->GetWindow());
nsresult rv = xulCommand->InitCommandEvent(NS_LITERAL_STRING("command"),
PR_TRUE, PR_TRUE, view,
0, aCtrl, aAlt, aShift, aMeta,
aSourceEvent);
NS_ENSURE_SUCCESS(rv, rv);
if (aShell) {
nsEventStatus status = nsEventStatus_eIgnore;
nsCOMPtr<nsIPresShell> kungFuDeathGrip = aShell;
return aShell->HandleDOMEventWithTarget(aTarget, event, &status);
}
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(aTarget);
NS_ENSURE_STATE(target);
PRBool dummy;
return target->DispatchEvent(event, &dummy);
}

View File

@ -699,8 +699,9 @@ nsDOMAttribute::AppendChildTo(nsIContent* aKid, PRBool aNotify)
}
nsresult
nsDOMAttribute::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
nsDOMAttribute::RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent)
{
NS_ASSERTION(aMutationEvent, "Someone tried to inhibit mutations on attribute child removal.");
if (aIndex != 0 || !mChild) {
return NS_OK;
}

View File

@ -98,7 +98,7 @@ public:
virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
PRBool aNotify);
virtual nsresult AppendChildTo(nsIContent* aKid, PRBool aNotify);
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent = PR_TRUE);
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
virtual nsresult DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,

View File

@ -2397,8 +2397,9 @@ nsDocument::ContentRemoved(nsIDocument* aDocument,
}
void
nsDocument::AttributeWillChange(nsIContent* aContent, PRInt32 aNameSpaceID,
nsIAtom* aAttribute)
nsDocument::AttributeWillChange(nsIDocument* aDocument,
nsIContent* aContent, PRInt32 aNameSpaceID,
nsIAtom* aAttribute, PRInt32 aModType)
{
NS_ABORT_IF_FALSE(aContent, "Null content!");
NS_PRECONDITION(aAttribute, "Must have an attribute that's changing!");
@ -3221,8 +3222,9 @@ nsDocument::AppendChildTo(nsIContent* aKid, PRBool aNotify)
}
nsresult
nsDocument::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
nsDocument::RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent)
{
NS_ASSERTION(aMutationEvent, "Someone tried to inhibit mutations on document child removal.");
nsCOMPtr<nsIContent> oldKid = GetChildAt(aIndex);
if (!oldKid) {
return NS_OK;
@ -3234,7 +3236,8 @@ nsDocument::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
}
nsresult rv = nsGenericElement::doRemoveChildAt(aIndex, aNotify, oldKid,
nsnull, this, mChildren);
nsnull, this, mChildren,
aMutationEvent);
mCachedRootContent = nsnull;
return rv;
}

View File

@ -773,10 +773,6 @@ public:
nsIContent* aContent2,
PRInt32 aStateMask);
virtual void AttributeWillChange(nsIContent* aChild,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute);
virtual void StyleRuleChanged(nsIStyleSheet* aStyleSheet,
nsIStyleRule* aOldStyleRule,
nsIStyleRule* aNewStyleRule);
@ -810,7 +806,7 @@ public:
virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
PRBool aNotify);
virtual nsresult AppendChildTo(nsIContent* aKid, PRBool aNotify);
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent = PR_TRUE);
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
virtual nsresult DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
@ -914,6 +910,7 @@ public:
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTEWILLCHANGE
// nsIScriptObjectPrincipal
virtual nsIPrincipal* GetPrincipal();

View File

@ -587,9 +587,9 @@ nsGenericDOMDataNode::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
void
nsGenericDOMDataNode::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
{
// Unset FRAMETREE_DEPENDS_ON_CHARS; if we need it again later, it'll get set
// again.
UnsetFlags(FRAMETREE_DEPENDS_ON_CHARS);
// Unset frame flags; if we need them again later, they'll get set again.
UnsetFlags(NS_CREATE_FRAME_IF_NON_WHITESPACE |
NS_REFRAME_IF_WHITESPACE);
nsIDocument *document = GetCurrentDoc();
if (document) {
@ -752,7 +752,7 @@ nsGenericDOMDataNode::InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
}
nsresult
nsGenericDOMDataNode::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
nsGenericDOMDataNode::RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent)
{
return NS_OK;
}

View File

@ -43,8 +43,14 @@
#ifndef nsGenericDOMDataNode_h___
#define nsGenericDOMDataNode_h___
// This bit is set if the frame tree depends on whether this node is whitespace
#define FRAMETREE_DEPENDS_ON_CHARS (1 << NODE_TYPE_SPECIFIC_BITS_OFFSET)
// This bit is set to indicate that if the text node changes to
// non-whitespace, we may need to create a frame for it. This bit must
// not be set on nodes that already have a frame.
#define NS_CREATE_FRAME_IF_NON_WHITESPACE (1 << NODE_TYPE_SPECIFIC_BITS_OFFSET)
// This bit is set to indicate that if the text node changes to
// whitespace, we may need to reframe it (or its ancestors).
#define NS_REFRAME_IF_WHITESPACE (1 << (NODE_TYPE_SPECIFIC_BITS_OFFSET + 1))
#include "nsIDOMCharacterData.h"
#include "nsIDOMEventTarget.h"
@ -166,7 +172,7 @@ public:
virtual PRInt32 IndexOf(nsINode* aPossibleChild) const;
virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
PRBool aNotify);
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent = PR_TRUE);
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
virtual nsresult DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,

View File

@ -3246,14 +3246,14 @@ nsGenericElement::doInsertChildAt(nsIContent* aKid, PRUint32 aIndex,
}
nsresult
nsGenericElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
nsGenericElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent)
{
nsCOMPtr<nsIContent> oldKid = mAttrsAndChildren.GetSafeChildAt(aIndex);
NS_ASSERTION(oldKid == GetChildAt(aIndex), "Unexpected child in RemoveChildAt");
if (oldKid) {
return doRemoveChildAt(aIndex, aNotify, oldKid, this, GetCurrentDoc(),
mAttrsAndChildren);
mAttrsAndChildren, aMutationEvent);
}
return NS_OK;
@ -3264,7 +3264,8 @@ nsresult
nsGenericElement::doRemoveChildAt(PRUint32 aIndex, PRBool aNotify,
nsIContent* aKid, nsIContent* aParent,
nsIDocument* aDocument,
nsAttrAndChildArray& aChildArray)
nsAttrAndChildArray& aChildArray,
PRBool aMutationEvent)
{
NS_PRECONDITION(aParent || aDocument, "Must have document if no parent!");
NS_PRECONDITION(!aParent || aParent->GetCurrentDoc() == aDocument,
@ -3300,6 +3301,7 @@ nsGenericElement::doRemoveChildAt(PRUint32 aIndex, PRBool aNotify,
mozAutoSubtreeModified subtree(nsnull, nsnull);
if (aNotify &&
aMutationEvent &&
nsContentUtils::HasMutationListeners(aKid,
NS_EVENT_BITS_MUTATION_NODEREMOVED, container)) {
mozAutoRemovableBlockerRemover blockerRemover;
@ -4253,9 +4255,7 @@ nsGenericElement::SetAttrAndNotify(PRInt32 aNamespaceID,
if (aNotify) {
stateMask = PRUint32(IntrinsicState());
if (document) {
document->AttributeWillChange(this, aNamespaceID, aName);
}
nsNodeUtils::AttributeWillChange(this, aNamespaceID, aName, modType);
}
if (aNamespaceID == kNameSpaceID_None) {
@ -4493,15 +4493,16 @@ nsGenericElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
nsIDocument *document = GetCurrentDoc();
mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
if (document) {
if (kNameSpaceID_XLink == aNameSpaceID && nsGkAtoms::href == aName) {
// XLink URI might be changing.
document->ForgetLink(this);
}
if (aNotify) {
document->AttributeWillChange(this, aNameSpaceID, aName);
}
if (aNotify) {
nsNodeUtils::AttributeWillChange(this, aNameSpaceID, aName,
nsIDOMMutationEvent::REMOVAL);
}
if (document && kNameSpaceID_XLink == aNameSpaceID &&
nsGkAtoms::href == aName) {
// XLink URI might be changing.
document->ForgetLink(this);
}
// When notifying, make sure to keep track of states whose value

View File

@ -354,7 +354,7 @@ public:
virtual PRInt32 IndexOf(nsINode* aPossibleChild) const;
virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
PRBool aNotify);
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent = PR_TRUE);
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
virtual nsresult DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
@ -654,7 +654,8 @@ public:
static nsresult doRemoveChildAt(PRUint32 aIndex, PRBool aNotify,
nsIContent* aKid, nsIContent* aParent,
nsIDocument* aDocument,
nsAttrAndChildArray& aChildArray);
nsAttrAndChildArray& aChildArray,
PRBool aMutationEvent);
/**
* Helper methods for implementing querySelector/querySelectorAll

View File

@ -68,6 +68,7 @@
#include "nsLWBrkCIID.h"
#include "nsIScriptElement.h"
#include "nsAttrName.h"
#include "nsHtml5Module.h"
static const char kMozStr[] = "moz";
@ -100,6 +101,7 @@ nsHTMLContentSerializer::AppendDocumentStart(nsIDOMDocument *aDocument,
return NS_OK;
}
#include "nsIHTMLDocument.h"
void
nsHTMLContentSerializer::SerializeAttributes(nsIContent* aContent,
nsIDOMElement *aOriginalElement,
@ -108,19 +110,40 @@ nsHTMLContentSerializer::SerializeAttributes(nsIContent* aContent,
nsIAtom* aTagName,
nsAString& aStr)
{
PRInt32 count = aContent->GetAttrCount();
if (!count)
return;
nsresult rv;
PRUint32 index, count;
nsAutoString nameStr, valueStr;
count = aContent->GetAttrCount();
NS_NAMED_LITERAL_STRING(_mozStr, "_moz");
// Loop backward over the attributes, since the order they are stored in is
// the opposite of the order they were parsed in (see bug 213347 for reason).
// index is unsigned, hence index >= 0 is always true.
for (index = count; index > 0; ) {
--index;
// HTML5 parser stored them in the order they were parsed so we want to
// loop forward in that case.
nsIDocument* doc = aContent->GetOwnerDocument();
PRBool caseSensitive = doc && doc->IsCaseSensitive();
PRBool loopForward = PR_FALSE;
if (!caseSensitive) {
nsCOMPtr<nsIHTMLDocument> htmlDoc(do_QueryInterface(doc));
if (htmlDoc) {
loopForward = nsHtml5Module::Enabled;
}
}
PRInt32 index, limit, step;
if (loopForward) {
index = 0;
limit = count;
step = 1;
}
else {
// Loop backward over the attributes, since the order they are stored in is
// the opposite of the order they were parsed in (see bug 213347 for reason).
index = count - 1;
limit = -1;
step = -1;
}
for (; index != limit; index += step) {
const nsAttrName* name = aContent->GetAttrNameAt(index);
PRInt32 namespaceID = name->NamespaceID();
nsIAtom* attrName = name->LocalName();

View File

@ -97,6 +97,18 @@ nsNodeUtils::CharacterDataChanged(nsIContent* aContent,
(doc, aContent, aInfo));
}
void
nsNodeUtils::AttributeWillChange(nsIContent* aContent,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aModType)
{
nsIDocument* doc = aContent->GetOwnerDoc();
IMPL_MUTATION_NOTIFICATION(AttributeWillChange, aContent,
(doc, aContent, aNameSpaceID, aAttribute,
aModType));
}
void
nsNodeUtils::AttributeChanged(nsIContent* aContent,
PRInt32 aNameSpaceID,

View File

@ -73,6 +73,19 @@ public:
static void CharacterDataChanged(nsIContent* aContent,
CharacterDataChangeInfo* aInfo);
/**
* Send AttributeWillChange notifications to nsIMutationObservers.
* @param aContent Node whose data will change
* @param aNameSpaceID Namespace of changing attribute
* @param aAttribute Local-name of changing attribute
* @param aModType Type of change (add/change/removal)
* @see nsIMutationObserver::AttributeWillChange
*/
static void AttributeWillChange(nsIContent* aContent,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aModType);
/**
* Send AttributeChanged notifications to nsIMutationObservers.
* @param aContent Node whose data changed

View File

@ -52,6 +52,7 @@
#include "nsIObjectFrame.h"
#include "nsIPluginDocument.h"
#include "nsIPluginHost.h"
#include "nsIPluginInstance.h"
#include "nsIPresShell.h"
#include "nsIScriptGlobalObject.h"
#include "nsIScriptSecurityManager.h"

View File

@ -1145,24 +1145,16 @@ RemoveNode(nsIDOMNode* aNode)
}
/**
* Split a data node into two or three parts.
* Split a data node into two parts.
*
* @param aStartNode The original node we are trying to split,
* and first of three.
* @param aStartIndex The index at which to split the first and second
* parts.
* @param aEndIndex The index at which to split the second and third
* parts.
* @param aMiddleNode The second node of three.
* @param aEndNode The third node of three. May be null to indicate
* aEndIndex doesn't apply.
* @param aStartNode The original node we are trying to split.
* @param aStartIndex The index at which to split.
* @param aEndNode The second node.
* @param aCloneAfterOriginal Set PR_FALSE if the original node should be the
* latter one after split.
*/
static nsresult SplitDataNode(nsIDOMCharacterData* aStartNode,
PRUint32 aStartIndex,
PRUint32 aEndIndex,
nsIDOMCharacterData** aMiddleNode,
nsIDOMCharacterData** aEndNode,
PRBool aCloneAfterOriginal = PR_TRUE)
{
@ -1170,21 +1162,12 @@ static nsresult SplitDataNode(nsIDOMCharacterData* aStartNode,
nsCOMPtr<nsINode> node = do_QueryInterface(aStartNode);
NS_ENSURE_STATE(node && node->IsNodeOfType(nsINode::eDATA_NODE));
nsGenericDOMDataNode* dataNode = static_cast<nsGenericDOMDataNode*>(node.get());
// Split the main node, starting with the end.
if (aEndNode && aEndIndex > aStartIndex) {
nsCOMPtr<nsIContent> newData;
rv = dataNode->SplitData(aEndIndex, getter_AddRefs(newData),
aCloneAfterOriginal);
NS_ENSURE_SUCCESS(rv, rv);
rv = CallQueryInterface(newData, aEndNode);
NS_ENSURE_SUCCESS(rv, rv);
}
nsCOMPtr<nsIContent> newData;
rv = dataNode->SplitData(aStartIndex, getter_AddRefs(newData),
aCloneAfterOriginal);
NS_ENSURE_SUCCESS(rv, rv);
return CallQueryInterface(newData, aMiddleNode);
return CallQueryInterface(newData, aEndNode);
}
nsresult PrependChild(nsIDOMNode* aParent, nsIDOMNode* aChild)
@ -1294,13 +1277,20 @@ nsresult nsRange::CutContents(nsIDOMDocumentFragment** aFragment)
if (endOffset > startOffset)
{
nsCOMPtr<nsIDOMCharacterData> cutNode;
nsCOMPtr<nsIDOMCharacterData> endNode;
rv = SplitDataNode(charData, startOffset, endOffset,
getter_AddRefs(cutNode),
getter_AddRefs(endNode));
if (retval) {
nsAutoString cutValue;
rv = charData->SubstringData(startOffset, endOffset - startOffset,
cutValue);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMNode> clone;
rv = charData->CloneNode(PR_FALSE, getter_AddRefs(clone));
NS_ENSURE_SUCCESS(rv, rv);
clone->SetNodeValue(cutValue);
nodeToResult = clone;
}
rv = charData->DeleteData(startOffset, endOffset - startOffset);
NS_ENSURE_SUCCESS(rv, rv);
nodeToResult = cutNode;
}
handled = PR_TRUE;
@ -1315,8 +1305,7 @@ nsresult nsRange::CutContents(nsIDOMDocumentFragment** aFragment)
if (dataLength >= (PRUint32)startOffset)
{
nsCOMPtr<nsIDOMCharacterData> cutNode;
rv = SplitDataNode(charData, startOffset, dataLength,
getter_AddRefs(cutNode), nsnull);
rv = SplitDataNode(charData, startOffset, getter_AddRefs(cutNode));
NS_ENSURE_SUCCESS(rv, rv);
nodeToResult = cutNode;
}
@ -1334,8 +1323,8 @@ nsresult nsRange::CutContents(nsIDOMDocumentFragment** aFragment)
/* The Range spec clearly states clones get cut and original nodes
remain behind, so use PR_FALSE as the last parameter.
*/
rv = SplitDataNode(charData, endOffset, endOffset,
getter_AddRefs(cutNode), nsnull, PR_FALSE);
rv = SplitDataNode(charData, endOffset, getter_AddRefs(cutNode),
PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
nodeToResult = cutNode;
}

View File

@ -317,6 +317,8 @@ _TEST_FILES = test_bug5141.html \
file_bug498897.html \
file_bug498897.html^headers^ \
file_bug498897.css \
test_bug493881.js \
test_bug493881.html \
$(NULL)
# Disabled; see bug 492181
# test_plugin_freezing.html

View File

@ -15,20 +15,20 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=417255
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=417255">Mozilla Bug 417255</a>
<p id="display" style="width:800px"></p>
<div id="display" style="width:800px"></div>
<p><span id="s1" style="border:2px dotted red;"><span class="spacer" style="width:100px"></span>
<div><span id="s1" style="border:2px dotted red;"><span class="spacer" style="width:100px"></span>
<div style="width:500px; height:100px; background:yellow;"></div>
<span class="spacer" style="width:200px"></span></span>
<span class="spacer" style="width:200px"></span></span></div>
<p><span id="s2" style="border:2px dotted red;"><span class="spacer" style="width:100px"></span>
<div><span id="s2" style="border:2px dotted red;"><span class="spacer" style="width:100px"></span>
<div style="width:150px; height:100px; background:yellow;"></div>
<span class="spacer" style="width:200px"></span></span>
<span class="spacer" style="width:200px"></span></span></div>
<!-- test nested spans around the IB split -->
<p><span id="s3" style="border:2px dotted red;"><span><span class="spacer" style="width:100px"></span>
<div><span id="s3" style="border:2px dotted red;"><span><span class="spacer" style="width:100px"></span>
<div style="width:500px; height:100px; background:yellow;"></div>
<span class="spacer" style="width:200px"></span></span></span>
<span class="spacer" style="width:200px"></span></span></span></div>
<div id="content" style="display: none">

View File

@ -111,9 +111,29 @@ function testDocument2() {
ok(c1.isEqualNode(e1), "Wrong cloning or extracting!");
}
function testSurroundContents() {
var div = document.createElement('div');
document.body.appendChild(div);
div.innerHTML = '<div>hello</div>world';
var innerDiv = div.firstChild;
var hello = innerDiv.firstChild;
var range = document.createRange();
range.setStart(hello, 0);
range.setEnd(hello, 5);
range.surroundContents(document.createElement('code'));
is(innerDiv.childNodes.length, 3, "Wrong childNodes count");
is(innerDiv.childNodes[0].nodeName, "#text", "Wrong node name (1)");
is(innerDiv.childNodes[0].textContent, "", "Wrong textContent (1)");
is(innerDiv.childNodes[1].nodeName, "CODE", "Wrong node name (2)");
is(innerDiv.childNodes[1].textContent, "hello", "Wrong textContent (2)");
is(innerDiv.childNodes[2].nodeName, "#text", "Wrong node name (3)");
is(innerDiv.childNodes[2].textContent, "", "Wrong textContent (3)");
}
function runTest() {
testDocument1();
testDocument2();
testSurroundContents();
SimpleTest.finish();
}

View File

@ -0,0 +1,32 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=493881
-->
<head>
<title>Test for Bug 493881</title>
<script type="text/javascript" src="/MochiKit/packed.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="test_bug493881.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<style type="text/css">
</style>
</head>
<body>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=493881"
target="_blank" >Mozilla Bug 493881</a>
<p id="display"></p>
<a id="nonvisitedlink" href="http://www.example.com/">Non-visited link</a>
<a id="visitedlink" href="">Visited link</a>
<p id="plaintext">some text</p>
<pre id="test">
</pre>
</body>
</html>

View File

@ -0,0 +1,72 @@
/**
* Test for Bug 493881: Changes to legacy HTML color properties before the BODY is loaded
* should be ignored. Additionally, after BODY loads, setting any of these properties to undefined
* should cause them to be returned as the string "undefined".
*/
SimpleTest.waitForExplicitFinish();
var legacyProps = ["fgColor", "bgColor", "linkColor", "vlinkColor", "alinkColor"];
var testColors = ["blue", "silver", "green", "orange", "red"];
var rgbTestColors = ["rgb(255, 0, 0)", "rgb(192, 192, 192)", "rgb(0, 128, 0)", "rgb(255, 165, 0)", "rgb(255, 0, 0)"];
var idPropList = [ {id: "plaintext", prop: "color"},
{id: "plaintext", prop: "background-color"},
{id: "nonvisitedlink", prop: "color"},
{id: "visitedlink", prop: "color"} ];
var initialValues = [];
function setAndTestProperty(prop, color) {
var initial = document[prop];
document[prop] = color;
is(document[prop], initial, "document[" + prop + "] not ignored before body");
return initial;
}
/**
* Attempt to set legacy color properties before BODY exists, and verify that such
* attempts are ignored.
*/
for (var i = 0; i < legacyProps.length; i++) {
initialValues[i] = setAndTestProperty(legacyProps[i], testColors[i]);
}
/**
* After BODY loads, run some more tests.
*/
addLoadEvent( function() {
// Verify that the legacy color properties still have their original values.
for (var i = 0; i < legacyProps.length; i++) {
is(document[legacyProps[i]], initialValues[i], "document[" + legacyProps[i] + "] altered after body load");
}
// Verify that legacy color properties applied before BODY are really ignored when rendering.
// Save current computed style colors for later use.
for (i = 0; i < idPropList.length; i++) {
var style = window.getComputedStyle(document.getElementById(idPropList[i].id), null);
var color = style.getPropertyValue(idPropList[i].prop);
idPropList[i].initialComputedColor = color;
isnot(color, rgbTestColors[i], "element rendered using before-body style");
}
// XXX: Can't get links to visually activate via script events, so can't verify
// that the alinkColor property was not applied.
// Verify that setting legacy color props to undefined after BODY loads will cause them
// to be read as the string "undefined".
for (var i = 0; i < legacyProps.length; i++) {
document[legacyProps[i]] = undefined;
is(document[legacyProps[i]], "undefined",
"Unexpected value of " + legacyProps[i] + " after setting to undefined");
}
// Verify that setting legacy color props to undefined did not affect rendering
// (computed styles).
for (i = 0; i < idPropList.length; i++) {
var style = window.getComputedStyle(document.getElementById(idPropList[i].id), null);
var color = style.getPropertyValue(idPropList[i].prop);
is(color, idPropList[i].initialComputedColor,
"element's style changed by setting legacy prop to undefined");
}
// Mark the test as finished.
setTimeout(SimpleTest.finish, 0);
});

View File

@ -49,4 +49,8 @@ EXPORTS = \
nsICanvasElement.h \
$(NULL)
XPIDLSRCS = \
nsICanvasGLPrivate.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,53 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is canvas 3D.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Vladimir Vukicevic <vladimir@pobox.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
/* These are private interface that's used to identify
* specific concrete classes so we know what we can cast.
*/
[scriptable, uuid(eba2aa03-ae19-46e2-bad7-6b966037e22c)]
interface nsICanvasGLBuffer : nsISupports
{
};
[scriptable, uuid(27310aab-1988-43e8-882e-6293c8c9df60)]
interface nsICanvasGLTexture : nsISupports
{
};

View File

@ -74,6 +74,36 @@ CPPSRCS = \
nsCanvasRenderingContext2D.cpp \
$(NULL)
# Canvas 3D Pieces
ifdef MOZ_ENABLE_CANVAS3D
CPPSRCS += \
nsCanvasRenderingContextGL.cpp \
nsCanvasRenderingContextGLWeb20.cpp \
glwrap.cpp \
nsGLPbuffer.cpp \
nsGLPbufferOSMesa.cpp \
$(NULL)
ifdef MOZ_X11
EXTRA_DSO_LIBS += X11
CPPSRCS += nsGLPbufferGLX.cpp
DEFINES += -DUSE_GLX
endif
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
CPPSRCS += nsGLPbufferWGL.cpp
DEFINES += -DUSE_WGL
endif
ifneq (,$(filter $(MOZ_WIDGET_TOOLKIT),mac cocoa))
CPPSRCS += nsGLPbufferCGL.cpp
DEFINES += -DUSE_CGL
endif
endif
# we don't want the shared lib, but we want to force the creation of a static lib.
FORCE_STATIC_LIB = 1

View File

@ -0,0 +1,390 @@
#ifndef _NATIVEJSCONTEXT_H_
#define _NATIVEJSCONTEXT_H_
class JSObjectHelper;
class NativeJSContext {
public:
NativeJSContext() {
error = gXPConnect->GetCurrentNativeCallContext(&ncc);
if (NS_FAILED(error))
return;
if (!ncc) {
error = NS_ERROR_FAILURE;
return;
}
ctx = nsnull;
error = ncc->GetJSContext(&ctx);
if (NS_FAILED(error))
return;
JS_BeginRequest(ctx);
ncc->GetArgc(&argc);
ncc->GetArgvPtr(&argv);
}
~NativeJSContext() {
JS_EndRequest(ctx);
}
PRBool CheckArray (JSObject *obj, jsuint *sz) {
if (obj &&
::JS_IsArrayObject(ctx, obj) &&
::JS_GetArrayLength(ctx, obj, sz))
return PR_TRUE;
return PR_FALSE;
}
PRBool CheckArray (jsval val, jsuint *sz) {
if (!JSVAL_IS_NULL(val) &&
JSVAL_IS_OBJECT(val) &&
::JS_IsArrayObject(ctx, JSVAL_TO_OBJECT(val)) &&
::JS_GetArrayLength(ctx, JSVAL_TO_OBJECT(val), sz))
return PR_TRUE;
return PR_FALSE;
}
PRBool AddGCRoot (void *aPtr, const char *aName) {
return JS_AddNamedRootRT(gScriptRuntime, aPtr, aName);
}
void ReleaseGCRoot (void *aPtr) {
JS_RemoveRootRT(gScriptRuntime, aPtr);
}
void SetRetVal (PRInt32 val) {
if (INT_FITS_IN_JSVAL(val))
SetRetValAsJSVal(INT_TO_JSVAL(val));
else
SetRetVal((double) val);
}
void SetRetVal (PRUint32 val) {
if (INT_FITS_IN_JSVAL(val))
SetRetValAsJSVal(INT_TO_JSVAL((int) val));
else
SetRetVal((double) val);
}
void SetRetVal (double val) {
jsval *vp;
ncc->GetRetValPtr(&vp);
JS_NewDoubleValue(ctx, val, vp);
}
void SetBoolRetVal (PRBool val) {
if (val)
SetRetValAsJSVal(JSVAL_TRUE);
else
SetRetValAsJSVal(JSVAL_FALSE);
}
void SetRetVal (PRInt32 *vp, PRUint32 len) {
nsAutoArrayPtr<jsval> jsvector(new jsval[len]);
if (!JS_EnterLocalRootScope(ctx))
return; // XXX ???
for (PRUint32 i = 0; i < len; i++) {
if (INT_FITS_IN_JSVAL(vp[i])) {
jsvector[i] = INT_TO_JSVAL(vp[i]);
} else {
JS_NewDoubleValue(ctx, vp[i], &jsvector[i]);
}
}
JSObject *jsarr = JS_NewArrayObject(ctx, len, jsvector.get());
SetRetVal(jsarr);
JS_LeaveLocalRootScope(ctx);
}
void SetRetVal (PRUint32 *vp, PRUint32 len) {
nsAutoArrayPtr<jsval> jsvector(new jsval[len]);
if (!JS_EnterLocalRootScope(ctx))
return; // XXX ???
for (PRUint32 i = 0; i < len; i++) {
JS_NewNumberValue(ctx, vp[i], &jsvector[i]);
}
JSObject *jsarr = JS_NewArrayObject(ctx, len, jsvector.get());
SetRetVal(jsarr);
JS_LeaveLocalRootScope(ctx);
}
void SetRetVal (double *dp, PRUint32 len) {
nsAutoArrayPtr<jsval> jsvector(new jsval[len]);
if (!JS_EnterLocalRootScope(ctx))
return; // XXX ???
for (PRUint32 i = 0; i < len; i++)
JS_NewDoubleValue(ctx, (jsdouble) dp[i], &jsvector[i]);
JSObject *jsarr = JS_NewArrayObject(ctx, len, jsvector.get());
SetRetVal(jsarr);
JS_LeaveLocalRootScope(ctx);
}
void SetRetVal (float *fp, PRUint32 len) {
nsAutoArrayPtr<jsval> jsvector(new jsval[len]);
if (!JS_EnterLocalRootScope(ctx))
return; // XXX ???
for (PRUint32 i = 0; i < len; i++)
JS_NewDoubleValue(ctx, (jsdouble) fp[i], &jsvector[i]);
JSObject *jsarr = JS_NewArrayObject(ctx, len, jsvector.get());
SetRetVal(jsarr);
JS_LeaveLocalRootScope(ctx);
}
void SetRetValAsJSVal (jsval val) {
jsval *vp;
ncc->GetRetValPtr(&vp);
*vp = val;
ncc->SetReturnValueWasSet(PR_TRUE);
}
void SetRetVal (JSObject *obj) {
SetRetValAsJSVal(OBJECT_TO_JSVAL(obj));
}
void SetRetVal (JSObjectHelper& objh);
nsAXPCNativeCallContext *ncc;
nsresult error;
JSContext *ctx;
PRUint32 argc;
jsval *argv;
public:
// static JS helpers
static inline PRBool JSValToFloatArray (JSContext *ctx, jsval val,
jsuint cnt, float *array)
{
JSObject *arrayObj;
jsuint arrayLen;
jsval jv;
jsdouble dv;
if (!::JS_ValueToObject(ctx, val, &arrayObj) ||
arrayObj == NULL ||
!::JS_IsArrayObject(ctx, arrayObj) ||
!::JS_GetArrayLength(ctx, arrayObj, &arrayLen) ||
(arrayLen < cnt))
return PR_FALSE;
for (jsuint i = 0; i < cnt; i++) {
::JS_GetElement(ctx, arrayObj, i, &jv);
if (!::JS_ValueToNumber(ctx, jv, &dv))
return PR_FALSE;
array[i] = (float) dv;
}
return PR_TRUE;
}
static inline PRBool JSValToDoubleArray (JSContext *ctx, jsval val,
jsuint cnt, double *array)
{
JSObject *arrayObj;
jsuint arrayLen;
jsval jv;
jsdouble dv;
if (!::JS_ValueToObject(ctx, val, &arrayObj) ||
arrayObj == NULL ||
!::JS_IsArrayObject(ctx, arrayObj) ||
!::JS_GetArrayLength(ctx, arrayObj, &arrayLen) ||
(arrayLen < cnt))
return PR_FALSE;
for (jsuint i = 0; i < cnt; i++) {
::JS_GetElement(ctx, arrayObj, i, &jv);
if (!::JS_ValueToNumber(ctx, jv, &dv))
return PR_FALSE;
array[i] = dv;
}
return PR_TRUE;
}
static inline PRBool JSValToJSArrayAndLength (JSContext *ctx, jsval val,
JSObject **outObj, jsuint *outLen)
{
JSObject *obj = nsnull;
jsuint len;
if (!::JS_ValueToObject(ctx, val, &obj) ||
obj == NULL ||
!::JS_IsArrayObject(ctx, obj) ||
!::JS_GetArrayLength(ctx, obj, &len))
{
return PR_FALSE;
}
*outObj = obj;
*outLen = len;
return PR_TRUE;
}
template<class T>
static nsresult JSValToSpecificInterface(JSContext *ctx, jsval val, T **out)
{
if (JSVAL_IS_NULL(val)) {
*out = nsnull;
return NS_OK;
}
if (!JSVAL_IS_OBJECT(val))
return NS_ERROR_DOM_SYNTAX_ERR;
nsCOMPtr<nsISupports> isup;
nsresult rv = gXPConnect->WrapJS(ctx, JSVAL_TO_OBJECT(val),
NS_GET_IID(nsISupports),
getter_AddRefs(isup));
if (NS_FAILED(rv))
return NS_ERROR_DOM_SYNTAX_ERR;
nsCOMPtr<T> obj = do_QueryInterface(isup);
if (!obj)
return NS_ERROR_DOM_SYNTAX_ERR;
NS_ADDREF(*out = obj.get());
return NS_OK;
}
static inline JSObject *ArrayToJSArray (JSContext *ctx,
const PRInt32 *vals,
const PRUint32 len)
{
// XXX handle ints that are too big to fit
nsAutoArrayPtr<jsval> jsvector(new jsval[len]);
for (PRUint32 i = 0; i < len; i++)
jsvector[i] = INT_TO_JSVAL(vals[i]);
return JS_NewArrayObject(ctx, len, jsvector);
}
static inline JSObject *ArrayToJSArray (JSContext *ctx,
const PRUint32 *vals,
const PRUint32 len)
{
// XXX handle ints that are too big to fit
nsAutoArrayPtr<jsval> jsvector(new jsval[len]);
for (PRUint32 i = 0; i < len; i++)
jsvector[i] = INT_TO_JSVAL(vals[i]);
return JS_NewArrayObject(ctx, len, jsvector);
}
};
class JSObjectHelper {
friend class NativeJSContext;
public:
JSObjectHelper(NativeJSContext *jsctx)
: mCtx (jsctx)
{
mObject = JS_NewObject(mCtx->ctx, NULL, NULL, NULL);
if (!mObject)
return;
if (!mCtx->AddGCRoot(&mObject, "JSObjectHelperCanvas3D"))
mObject = nsnull;
}
~JSObjectHelper() {
if (mObject && mCtx)
mCtx->ReleaseGCRoot(&mObject);
}
PRBool DefineProperty(const char *name, PRInt32 val) {
// XXX handle too big ints
if (!JS_DefineProperty(mCtx->ctx, mObject, name, INT_TO_JSVAL(val), NULL, NULL, JSPROP_ENUMERATE))
return PR_FALSE;
return PR_TRUE;
}
PRBool DefineProperty(const char *name, PRUint32 val) {
// XXX handle too big ints
if (!JS_DefineProperty(mCtx->ctx, mObject, name, INT_TO_JSVAL((int)val), NULL, NULL, JSPROP_ENUMERATE))
return PR_FALSE;
return PR_TRUE;
}
PRBool DefineProperty(const char *name, double val) {
jsval dv;
if (!JS_NewDoubleValue(mCtx->ctx, val, &dv))
return PR_FALSE;
if (!JS_DefineProperty(mCtx->ctx, mObject, name, dv, NULL, NULL, JSPROP_ENUMERATE))
return PR_FALSE;
return PR_TRUE;
}
PRBool DefineProperty(const char *name, JSObject *val) {
if (!JS_DefineProperty(mCtx->ctx, mObject, name, OBJECT_TO_JSVAL(val), NULL, NULL, JSPROP_ENUMERATE))
return PR_FALSE;
return PR_TRUE;
}
// Blah. We can't name this DefineProperty also because PRBool is the same as PRInt32
PRBool DefineBoolProperty(const char *name, PRBool val) {
if (!JS_DefineProperty(mCtx->ctx, mObject, name, val ? JS_TRUE : JS_FALSE, NULL, NULL, JSPROP_ENUMERATE))
return PR_FALSE;
return PR_TRUE;
}
// We can't use ns*Substring, because we don't have internal linkage
#if 0
PRBool DefineProperty(const char *name, const nsCSubstring& val) {
JSString *jsstr = JS_NewStringCopyN(mCtx->ctx, val.BeginReading(), val.Length());
if (!jsstr ||
!JS_DefineProperty(mCtx->ctx, mObject, name, STRING_TO_JSVAL(jsstr), NULL, NULL, JSPROP_ENUMERATE))
return PR_FALSE;
return PR_TRUE;
}
PRBool DefineProperty(const char *name, const nsSubstring& val) {
JSString *jsstr = JS_NewUCStringCopyN(mCtx->ctx, val.BeginReading(), val.Length());
if (!jsstr ||
!JS_DefineProperty(mCtx->ctx, mObject, name, STRING_TO_JSVAL(jsstr), NULL, NULL, JSPROP_ENUMERATE))
return PR_FALSE;
return PR_TRUE;
}
#endif
PRBool DefineProperty(const char *name, const char *val, PRUint32 len) {
JSString *jsstr = JS_NewStringCopyN(mCtx->ctx, val, len);
if (!jsstr ||
!JS_DefineProperty(mCtx->ctx, mObject, name, STRING_TO_JSVAL(jsstr), NULL, NULL, JSPROP_ENUMERATE))
return PR_FALSE;
return PR_TRUE;
}
JSObject *Object() {
return mObject;
}
protected:
NativeJSContext *mCtx;
JSObject *mObject;
};
inline void
NativeJSContext::SetRetVal(JSObjectHelper& objh) {
SetRetValAsJSVal(OBJECT_TO_JSVAL(objh.mObject));
}
#endif

View File

@ -0,0 +1,298 @@
#ifdef C3D_STANDALONE_BUILD
#include "c3d-standalone.h"
#endif
#include <string.h>
#include <stdio.h>
#include "prlink.h"
#include "glwrap.h"
#define MAX_SYMBOL_LENGTH 128
#define MAX_SYMBOL_NAMES 5
#ifdef MOZ_X11
#include <GL/glx.h>
#endif
bool
LibrarySymbolLoader::OpenLibrary(const char *library)
{
PRLibSpec lspec;
lspec.type = PR_LibSpec_Pathname;
lspec.value.pathname = library;
mLibrary = PR_LoadLibraryWithFlags(lspec, PR_LD_LAZY | PR_LD_LOCAL);
if (!mLibrary)
return false;
return true;
}
PRFuncPtr
LibrarySymbolLoader::LookupSymbol(const char *sym, bool tryplatform)
{
PRFuncPtr res = 0;
// try finding it in the library directly, if we have one
if (mLibrary) {
res = PR_FindFunctionSymbol(mLibrary, sym);
}
// try finding it in the process
if (!res) {
PRLibrary *leakedLibRef;
res = PR_FindFunctionSymbolAndLibrary(sym, &leakedLibRef);
}
// no? then try looking it up via the lookup symbol
if (!res && tryplatform && mLookupFunc) {
res = mLookupFunc (sym);
}
return res;
}
bool
LibrarySymbolLoader::LoadSymbols(SymLoadStruct *firstStruct, bool tryplatform, const char *prefix)
{
char sbuf[MAX_SYMBOL_LENGTH * 2];
SymLoadStruct *ss = firstStruct;
while (ss->symPointer) {
*ss->symPointer = 0;
for (int i = 0; i < MAX_SYMBOL_NAMES; i++) {
if (ss->symNames[i] == NULL)
break;
const char *s = ss->symNames[i];
if (prefix && *prefix != 0) {
strcpy(sbuf, prefix);
strcat(sbuf, ss->symNames[i]);
s = sbuf;
}
PRFuncPtr p = LookupSymbol(s, tryplatform);
if (p) {
*ss->symPointer = p;
break;
}
}
if (*ss->symPointer == 0) {
fprintf (stderr, "Can't find symbol '%s'\n", ss->symNames[0]);
return false;
}
ss++;
}
return true;
}
bool
OSMesaWrap::Init()
{
if (fCreateContextExt)
return true;
SymLoadStruct symbols[] = {
{ (PRFuncPtr*) &fCreateContextExt, { "OSMesaCreateContextExt", NULL } },
{ (PRFuncPtr*) &fMakeCurrent, { "OSMesaMakeCurrent", NULL } },
{ (PRFuncPtr*) &fPixelStore, { "OSMesaPixelStore", NULL } },
{ (PRFuncPtr*) &fDestroyContext, { "OSMesaDestroyContext", NULL } },
{ (PRFuncPtr*) &fGetCurrentContext, { "OSMesaGetCurrentContext", NULL } },
{ (PRFuncPtr*) &fMakeCurrent, { "OSMesaMakeCurrent", NULL } },
{ (PRFuncPtr*) &fGetProcAddress, { "OSMesaGetProcAddress", NULL } },
{ NULL, { NULL } }
};
return LoadSymbols(&symbols[0]);
}
bool
GLES20Wrap::Init(NativeGLMode mode)
{
if (mode & TRY_NATIVE_GL) {
if (InitNative())
return true;
}
if (mode & TRY_SOFTWARE_GL) {
if (InitSoftware())
return true;
}
return false;
}
bool
GLES20Wrap::InitNative()
{
return InitWithPrefix("gl", true);
}
bool
GLES20Wrap::InitSoftware()
{
return InitWithPrefix("mgl", true);
}
/*
* XXX - we should really know the ARB/EXT variants of these
* instead of only handling the symbol if it's exposed directly.
*/
bool
GLES20Wrap::InitWithPrefix(const char *prefix, bool trygl)
{
if (ok)
return true;
SymLoadStruct symbols[] = {
{ (PRFuncPtr*) &fActiveTexture, { "ActiveTexture", "ActiveTextureARB", NULL } },
{ (PRFuncPtr*) &fAttachShader, { "AttachShader", "AttachShaderARB", NULL } },
{ (PRFuncPtr*) &fBindAttribLocation, { "BindAttribLocation", "BindAttribLocationARB", NULL } },
{ (PRFuncPtr*) &fBindBuffer, { "BindBuffer", "BindBufferARB", NULL } },
{ (PRFuncPtr*) &fBindTexture, { "BindTexture", "BindTextureARB", NULL } },
{ (PRFuncPtr*) &fBlendColor, { "BlendColor", NULL } },
{ (PRFuncPtr*) &fBlendEquation, { "BlendEquation", NULL } },
{ (PRFuncPtr*) &fBlendEquationSeparate, { "BlendEquationSeparate", "BlendEquationSeparateEXT", NULL } },
{ (PRFuncPtr*) &fBlendFunc, { "BlendFunc", NULL } },
{ (PRFuncPtr*) &fBlendFuncSeparate, { "BlendFuncSeparate", "BlendFuncSeparateEXT", NULL } },
{ (PRFuncPtr*) &fBufferData, { "BufferData", NULL } },
{ (PRFuncPtr*) &fBufferSubData, { "BufferSubData", NULL } },
{ (PRFuncPtr*) &fClear, { "Clear", NULL } },
{ (PRFuncPtr*) &fClearColor, { "ClearColor", NULL } },
{ (PRFuncPtr*) &fClearDepth, { "ClearDepth", NULL } },
{ (PRFuncPtr*) &fClearStencil, { "ClearStencil", NULL } },
{ (PRFuncPtr*) &fColorMask, { "ColorMask", NULL } },
{ (PRFuncPtr*) &fCreateProgram, { "CreateProgram", "CreateProgramARB", NULL } },
{ (PRFuncPtr*) &fCreateShader, { "CreateShader", "CreateShaderARB", NULL } },
{ (PRFuncPtr*) &fCullFace, { "CullFace", NULL } },
{ (PRFuncPtr*) &fDeleteBuffers, { "DeleteBuffers", "DeleteBuffersARB", NULL } },
{ (PRFuncPtr*) &fDeleteTextures, { "DeleteTextures", "DeleteTexturesARB", NULL } },
{ (PRFuncPtr*) &fDeleteProgram, { "DeleteProgram", "DeleteProgramARB", NULL } },
{ (PRFuncPtr*) &fDeleteShader, { "DeleteShader", "DeleteShaderARB", NULL } },
{ (PRFuncPtr*) &fDetachShader, { "DetachShader", "DetachShaderARB", NULL } },
{ (PRFuncPtr*) &fDepthFunc, { "DepthFunc", NULL } },
{ (PRFuncPtr*) &fDepthMask, { "DepthMask", NULL } },
{ (PRFuncPtr*) &fDepthRange, { "DepthRange", NULL } },
{ (PRFuncPtr*) &fDisable, { "Disable", NULL } },
{ (PRFuncPtr*) &fDisableVertexAttribArray, { "DisableVertexAttribArray", "DisableVertexAttribArrayARB", NULL } },
{ (PRFuncPtr*) &fDrawArrays, { "DrawArrays", NULL } },
{ (PRFuncPtr*) &fDrawElements, { "DrawElements", NULL } },
{ (PRFuncPtr*) &fEnable, { "Enable", NULL } },
{ (PRFuncPtr*) &fEnableVertexAttribArray, { "EnableVertexAttribArray", "EnableVertexAttribArrayARB", NULL } },
{ (PRFuncPtr*) &fFinish, { "Finish", NULL } },
{ (PRFuncPtr*) &fFlush, { "Flush", NULL } },
{ (PRFuncPtr*) &fFrontFace, { "FrontFace", NULL } },
{ (PRFuncPtr*) &fGetActiveAttrib, { "GetActiveAttrib", "GetActiveAttribARB", NULL } },
{ (PRFuncPtr*) &fGetActiveUniform, { "GetActiveUniform", "GetActiveUniformARB", NULL } },
{ (PRFuncPtr*) &fGetAttachedShaders, { "GetAttachedShaders", "GetAttachedShadersARB", NULL } },
{ (PRFuncPtr*) &fGetAttribLocation, { "GetAttribLocation", "GetAttribLocationARB", NULL } },
{ (PRFuncPtr*) &fGetIntegerv, { "GetIntegerv", NULL } },
{ (PRFuncPtr*) &fGetDoublev, { "GetDoublev", NULL } },
{ (PRFuncPtr*) &fGetFloatv, { "GetFloatv", NULL } },
{ (PRFuncPtr*) &fGetBooleanv, { "GetBooleanv", NULL } },
{ (PRFuncPtr*) &fGetBufferParameteriv, { "GetBufferParameteriv", "GetBufferParameterivARB", NULL } },
{ (PRFuncPtr*) &fGenBuffers, { "GenBuffers", "GenBuffersARB", NULL } },
{ (PRFuncPtr*) &fGenTextures, { "GenTextures", NULL } },
{ (PRFuncPtr*) &fGetError, { "GetError", NULL } },
{ (PRFuncPtr*) &fGetProgramiv, { "GetProgramiv", "GetProgramivARB", NULL } },
{ (PRFuncPtr*) &fGetProgramInfoLog, { "GetProgramInfoLog", "GetProgramInfoLogARB", NULL } },
{ (PRFuncPtr*) &fTexParameteri, { "TexParameteri", NULL } },
{ (PRFuncPtr*) &fTexParameterf, { "TexParameterf", NULL } },
{ (PRFuncPtr*) &fGetTexParameteriv, { "GetTexParameteriv", NULL } },
{ (PRFuncPtr*) &fGetUniformfv, { "GetUniformfv", "GetUniformfvARB", NULL } },
{ (PRFuncPtr*) &fGetUniformiv, { "GetUniformiv", "GetUniformivARB", NULL } },
{ (PRFuncPtr*) &fGetUniformLocation, { "GetUniformLocation", "GetUniformLocationARB", NULL } },
{ (PRFuncPtr*) &fGetVertexAttribdv, { "GetVertexAttribdv", "GetVertexAttribdvARB", NULL } },
{ (PRFuncPtr*) &fGetVertexAttribfv, { "GetVertexAttribfv", "GetVertexAttribfvARB", NULL } },
{ (PRFuncPtr*) &fGetVertexAttribiv, { "GetVertexAttribiv", "GetVertexAttribivARB", NULL } },
{ (PRFuncPtr*) &fHint, { "Hint", NULL } },
{ (PRFuncPtr*) &fIsBuffer, { "IsBuffer", "IsBufferARB", NULL } },
{ (PRFuncPtr*) &fIsEnabled, { "IsEnabled", NULL } },
{ (PRFuncPtr*) &fIsProgram, { "IsProgram", "IsProgramARB", NULL } },
{ (PRFuncPtr*) &fIsShader, { "IsShader", "IsShaderARB", NULL } },
{ (PRFuncPtr*) &fIsTexture, { "IsTexture", "IsTextureARB", NULL } },
{ (PRFuncPtr*) &fLineWidth, { "LineWidth", NULL } },
{ (PRFuncPtr*) &fLinkProgram, { "LinkProgram", "LinkProgramARB", NULL } },
{ (PRFuncPtr*) &fPixelStorei, { "PixelStorei", NULL } },
{ (PRFuncPtr*) &fPolygonOffset, { "PolygonOffset", NULL } },
{ (PRFuncPtr*) &fReadPixels, { "ReadPixels", NULL } },
{ (PRFuncPtr*) &fSampleCoverage, { "SampleCoverage", NULL } },
{ (PRFuncPtr*) &fScissor, { "Scissor", NULL } },
{ (PRFuncPtr*) &fStencilFunc, { "StencilFunc", NULL } },
{ (PRFuncPtr*) &fStencilFuncSeparate, { "StencilFuncSeparate", "StencilFuncSeparateEXT", NULL } },
{ (PRFuncPtr*) &fStencilMask, { "StencilMask", NULL } },
{ (PRFuncPtr*) &fStencilMaskSeparate, { "StencilMaskSeparate", "StencilMaskSeparateEXT", NULL } },
{ (PRFuncPtr*) &fStencilOp, { "StencilOp", NULL } },
{ (PRFuncPtr*) &fStencilOpSeparate, { "StencilOpSeparate", "StencilOpSeparateEXT", NULL } },
{ (PRFuncPtr*) &fTexImage2D, { "TexImage2D", NULL } },
{ (PRFuncPtr*) &fTexSubImage2D, { "TexSubImage2D", NULL } },
{ (PRFuncPtr*) &fUniform1f, { "Uniform1f", NULL } },
{ (PRFuncPtr*) &fUniform1fv, { "Uniform1fv", NULL } },
{ (PRFuncPtr*) &fUniform1i, { "Uniform1i", NULL } },
{ (PRFuncPtr*) &fUniform1iv, { "Uniform1iv", NULL } },
{ (PRFuncPtr*) &fUniform2f, { "Uniform2f", NULL } },
{ (PRFuncPtr*) &fUniform2fv, { "Uniform2fv", NULL } },
{ (PRFuncPtr*) &fUniform2i, { "Uniform2i", NULL } },
{ (PRFuncPtr*) &fUniform2iv, { "Uniform2iv", NULL } },
{ (PRFuncPtr*) &fUniform3f, { "Uniform3f", NULL } },
{ (PRFuncPtr*) &fUniform3fv, { "Uniform3fv", NULL } },
{ (PRFuncPtr*) &fUniform3i, { "Uniform3i", NULL } },
{ (PRFuncPtr*) &fUniform3iv, { "Uniform3iv", NULL } },
{ (PRFuncPtr*) &fUniform4f, { "Uniform4f", NULL } },
{ (PRFuncPtr*) &fUniform4fv, { "Uniform4fv", NULL } },
{ (PRFuncPtr*) &fUniform4i, { "Uniform4i", NULL } },
{ (PRFuncPtr*) &fUniform4iv, { "Uniform4iv", NULL } },
{ (PRFuncPtr*) &fUniformMatrix2fv, { "UniformMatrix2fv", NULL } },
{ (PRFuncPtr*) &fUniformMatrix3fv, { "UniformMatrix3fv", NULL } },
{ (PRFuncPtr*) &fUniformMatrix4fv, { "UniformMatrix4fv", NULL } },
{ (PRFuncPtr*) &fUseProgram, { "UseProgram", NULL } },
{ (PRFuncPtr*) &fValidateProgram, { "ValidateProgram", NULL } },
{ (PRFuncPtr*) &fVertexAttribPointer, { "VertexAttribPointer", NULL } },
{ (PRFuncPtr*) &fVertexAttrib1f, { "VertexAttrib1f", NULL } },
{ (PRFuncPtr*) &fVertexAttrib2f, { "VertexAttrib2f", NULL } },
{ (PRFuncPtr*) &fVertexAttrib3f, { "VertexAttrib3f", NULL } },
{ (PRFuncPtr*) &fVertexAttrib4f, { "VertexAttrib4f", NULL } },
{ (PRFuncPtr*) &fVertexAttrib1fv, { "VertexAttrib1fv", NULL } },
{ (PRFuncPtr*) &fVertexAttrib2fv, { "VertexAttrib2fv", NULL } },
{ (PRFuncPtr*) &fVertexAttrib3fv, { "VertexAttrib3fv", NULL } },
{ (PRFuncPtr*) &fVertexAttrib4fv, { "VertexAttrib4fv", NULL } },
{ (PRFuncPtr*) &fViewport, { "Viewport", NULL } },
{ (PRFuncPtr*) &fCompileShader, { "CompileShader", NULL } },
{ (PRFuncPtr*) &fCopyTexImage2D, { "CopyTexImage2D", NULL } },
{ (PRFuncPtr*) &fCopyTexSubImage2D, { "CopyTexSubImage2D", NULL } },
{ (PRFuncPtr*) &fGetShaderiv, { "GetShaderiv", NULL } },
{ (PRFuncPtr*) &fGetShaderInfoLog, { "GetShaderInfoLog", NULL } },
{ (PRFuncPtr*) &fGetShaderSource, { "GetShaderSource", NULL } },
{ (PRFuncPtr*) &fShaderSource, { "ShaderSource", NULL } },
{ (PRFuncPtr*) &fVertexAttribPointer, { "VertexAttribPointer", NULL } },
{ (PRFuncPtr*) &fBindFramebuffer, { "BindFramebuffer", "BindFramebufferEXT", NULL } },
{ (PRFuncPtr*) &fBindRenderbuffer, { "BindRenderbuffer", "BindRenderbufferEXT", NULL } },
{ (PRFuncPtr*) &fCheckFramebufferStatus, { "CheckFramebufferStatus", "CheckFramebufferStatusEXT", NULL } },
{ (PRFuncPtr*) &fDeleteFramebuffers, { "DeleteFramebuffers", "DeleteFramebuffersEXT", NULL } },
{ (PRFuncPtr*) &fDeleteRenderbuffers, { "DeleteRenderbuffers", "DeleteRenderbuffersEXT", NULL } },
{ (PRFuncPtr*) &fFramebufferRenderbuffer, { "FramebufferRenderbuffer", "FramebufferRenderbufferEXT", NULL } },
{ (PRFuncPtr*) &fFramebufferTexture2D, { "FramebufferTexture2D", "FramebufferTexture2DEXT", NULL } },
{ (PRFuncPtr*) &fGenerateMipmap, { "GenerateMipmap", "GenerateMipmapEXT", NULL } },
{ (PRFuncPtr*) &fGenFramebuffers, { "GenFramebuffers", "GenFramebuffersEXT", NULL } },
{ (PRFuncPtr*) &fGenRenderbuffers, { "GenRenderbuffers", "GenRenderbuffersEXT", NULL } },
{ (PRFuncPtr*) &fGetFramebufferAttachmentParameteriv, { "GetFramebufferAttachmentParameteriv", "GetFramebufferAttachmentParameterivEXT", NULL } },
{ (PRFuncPtr*) &fGetRenderbufferParameteriv, { "GetRenderbufferParameteriv", "GetRenderbufferParameterivEXT", NULL } },
{ (PRFuncPtr*) &fIsFramebuffer, { "IsFramebuffer", "IsFramebufferEXT", NULL } },
{ (PRFuncPtr*) &fIsRenderbuffer, { "IsRenderbuffer", "IsRenderbufferEXT", NULL } },
{ (PRFuncPtr*) &fRenderbufferStorage, { "RenderbufferStorage", "RenderbufferStorageEXT", NULL } },
{ NULL, { NULL } },
};
ok = LoadSymbols(&symbols[0], trygl, prefix);
return ok;
}

388
content/canvas/src/glwrap.h Normal file
View File

@ -0,0 +1,388 @@
#ifndef GLWRAP_H_
#define GLWRAP_H_
#ifdef WIN32
#include <windows.h>
#endif
#include "localgl.h"
#include "prlink.h"
#ifndef GLAPIENTRY
#ifdef XP_WIN
#define GLAPIENTRY __stdcall
#else
#define GLAPIENTRY
#endif
#define GLAPI
#endif
class LibrarySymbolLoader
{
public:
bool OpenLibrary(const char *library);
typedef PRFuncPtr (GLAPIENTRY * PlatformLookupFunction) (const char *);
void SetLookupFunc(PlatformLookupFunction plf) {
mLookupFunc = plf;
}
enum {
MAX_SYMBOL_NAMES = 5,
MAX_SYMBOL_LENGTH = 128
};
typedef struct {
PRFuncPtr *symPointer;
const char *symNames[MAX_SYMBOL_NAMES];
} SymLoadStruct;
PRFuncPtr LookupSymbol(const char *symname, bool tryplatform = false);
bool LoadSymbols(SymLoadStruct *firstStruct, bool tryplatform = false, const char *prefix = NULL);
protected:
LibrarySymbolLoader() {
mLibrary = NULL;
mLookupFunc = NULL;
}
PRLibrary *mLibrary;
PlatformLookupFunction mLookupFunc;
};
typedef void *PrivateOSMesaContext;
class OSMesaWrap
: public LibrarySymbolLoader
{
public:
OSMesaWrap() : fCreateContextExt(0) { }
bool Init();
protected:
//
// the wrapped functions
//
public:
typedef PrivateOSMesaContext (GLAPIENTRY * PFNOSMESACREATECONTEXTEXT) (GLenum, GLint, GLint, GLint, PrivateOSMesaContext);
typedef void (GLAPIENTRY * PFNOSMESADESTROYCONTEXT) (PrivateOSMesaContext);
typedef GLboolean (GLAPIENTRY * PFNOSMESAMAKECURRENT) (PrivateOSMesaContext, void *, GLenum, GLsizei, GLsizei);
typedef PrivateOSMesaContext (GLAPIENTRY * PFNOSMESAGETCURRENTCONTEXT) (void);
typedef void (GLAPIENTRY * PFNOSMESAPIXELSTORE) (GLint, GLint);
typedef PRFuncPtr (GLAPIENTRY * PFNOSMESAGETPROCADDRESS) (const char*);
PFNOSMESACREATECONTEXTEXT fCreateContextExt;
PFNOSMESADESTROYCONTEXT fDestroyContext;
PFNOSMESAMAKECURRENT fMakeCurrent;
PFNOSMESAGETCURRENTCONTEXT fGetCurrentContext;
PFNOSMESAPIXELSTORE fPixelStore;
PFNOSMESAGETPROCADDRESS fGetProcAddress;
};
class GLES20Wrap
: public LibrarySymbolLoader
{
public:
enum NativeGLMode {
TRY_NATIVE_GL = 1 << 0,
TRY_SOFTWARE_GL = 1 << 1
};
GLES20Wrap() : ok(false) { }
bool Init(NativeGLMode mode);
protected:
bool ok;
bool InitNative();
bool InitSoftware();
bool InitWithPrefix(const char *prefix, bool trygl );
//
// the wrapped functions
//
public:
/* One would think that this would live in some nice perl-or-python-or-js script somewhere and would be autogenerated;
* one would be wrong.
*/
typedef void (GLAPIENTRY * PFNGLACTIVETEXTUREPROC) (GLenum texture);
PFNGLACTIVETEXTUREPROC fActiveTexture;
typedef void (GLAPIENTRY * PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
PFNGLATTACHSHADERPROC fAttachShader;
typedef void (GLAPIENTRY * PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar* name);
PFNGLBINDATTRIBLOCATIONPROC fBindAttribLocation;
typedef void (GLAPIENTRY * PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
PFNGLBINDBUFFERPROC fBindBuffer;
typedef void (GLAPIENTRY * PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture);
PFNGLBINDTEXTUREPROC fBindTexture;
typedef void (GLAPIENTRY * PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
PFNGLBLENDCOLORPROC fBlendColor;
typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONPROC) (GLenum mode);
PFNGLBLENDEQUATIONPROC fBlendEquation;
typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum, GLenum);
PFNGLBLENDEQUATIONSEPARATEPROC fBlendEquationSeparate;
typedef void (GLAPIENTRY * PFNGLBLENDFUNCPROC) (GLenum, GLenum);
PFNGLBLENDFUNCPROC fBlendFunc;
typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
PFNGLBLENDFUNCSEPARATEPROC fBlendFuncSeparate;
typedef void (GLAPIENTRY * PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
PFNGLBUFFERDATAPROC fBufferData;
typedef void (GLAPIENTRY * PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
PFNGLBUFFERSUBDATAPROC fBufferSubData;
typedef void (GLAPIENTRY * PFNGLCLEARPROC) (GLbitfield);
PFNGLCLEARPROC fClear;
typedef void (GLAPIENTRY * PFNGLCLEARCOLORPROC) (GLclampf, GLclampf, GLclampf, GLclampf);
PFNGLCLEARCOLORPROC fClearColor;
typedef void (GLAPIENTRY * PFNGLCLEARDEPTHPROC) (GLclampd);
PFNGLCLEARDEPTHPROC fClearDepth;
typedef void (GLAPIENTRY * PFNGLCLEARSTENCILPROC) (GLint);
PFNGLCLEARSTENCILPROC fClearStencil;
typedef void (GLAPIENTRY * PFNGLCOLORMASKPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
PFNGLCOLORMASKPROC fColorMask;
typedef GLuint (GLAPIENTRY * PFNGLCREATEPROGRAMPROC) (void);
PFNGLCREATEPROGRAMPROC fCreateProgram;
typedef GLuint (GLAPIENTRY * PFNGLCREATESHADERPROC) (GLenum type);
PFNGLCREATESHADERPROC fCreateShader;
typedef void (GLAPIENTRY * PFNGLCULLFACEPROC) (GLenum mode);
PFNGLCULLFACEPROC fCullFace;
typedef void (GLAPIENTRY * PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint* buffers);
PFNGLDELETEBUFFERSPROC fDeleteBuffers;
typedef void (GLAPIENTRY * PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint* textures);
PFNGLDELETETEXTURESPROC fDeleteTextures;
typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMPROC) (GLuint program);
PFNGLDELETEPROGRAMPROC fDeleteProgram;
typedef void (GLAPIENTRY * PFNGLDELETESHADERPROC) (GLuint shader);
PFNGLDELETESHADERPROC fDeleteShader;
typedef void (GLAPIENTRY * PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader);
PFNGLDETACHSHADERPROC fDetachShader;
typedef void (GLAPIENTRY * PFNGLDEPTHFUNCPROC) (GLenum);
PFNGLDEPTHFUNCPROC fDepthFunc;
typedef void (GLAPIENTRY * PFNGLDEPTHMASKPROC) (GLboolean);
PFNGLDEPTHMASKPROC fDepthMask;
typedef void (GLAPIENTRY * PFNGLDEPTHRANGEPROC) (GLclampd, GLclampd);
PFNGLDEPTHRANGEPROC fDepthRange;
typedef void (GLAPIENTRY * PFNGLDISABLEPROC) (GLenum);
PFNGLDISABLEPROC fDisable;
typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint);
PFNGLDISABLEVERTEXATTRIBARRAYPROC fDisableVertexAttribArray;
typedef void (GLAPIENTRY * PFNGLDRAWARRAYSPROC) (GLenum mode, GLint first, GLsizei count);
PFNGLDRAWARRAYSPROC fDrawArrays;
typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
PFNGLDRAWELEMENTSPROC fDrawElements;
typedef void (GLAPIENTRY * PFNGLENABLEPROC) (GLenum);
PFNGLENABLEPROC fEnable;
typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint);
PFNGLENABLEVERTEXATTRIBARRAYPROC fEnableVertexAttribArray;
typedef void (GLAPIENTRY * PFNGLFINISHPROC) (void);
PFNGLFINISHPROC fFinish;
typedef void (GLAPIENTRY * PFNGLFLUSHPROC) (void);
PFNGLFLUSHPROC fFlush;
typedef void (GLAPIENTRY * PFNGLFRONTFACEPROC) (GLenum);
PFNGLFRONTFACEPROC fFrontFace;
typedef void (GLAPIENTRY * PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
PFNGLGETACTIVEATTRIBPROC fGetActiveAttrib;
typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
PFNGLGETACTIVEUNIFORMPROC fGetActiveUniform;
typedef void (GLAPIENTRY * PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders);
PFNGLGETATTACHEDSHADERSPROC fGetAttachedShaders;
typedef GLint (GLAPIENTRY * PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar* name);
PFNGLGETATTRIBLOCATIONPROC fGetAttribLocation;
typedef void (GLAPIENTRY * PFNGLGETINTEGERVPROC) (GLenum pname, GLint *params);
PFNGLGETINTEGERVPROC fGetIntegerv;
typedef void (GLAPIENTRY * PFNGLGETDOUBLEVPROC) (GLenum pname, GLdouble *params);
PFNGLGETDOUBLEVPROC fGetDoublev;
typedef void (GLAPIENTRY * PFNGLGETFLOATVPROC) (GLenum pname, GLfloat *params);
PFNGLGETFLOATVPROC fGetFloatv;
typedef void (GLAPIENTRY * PFNGLGETBOOLEANBPROC) (GLenum pname, GLboolean *params);
PFNGLGETBOOLEANBPROC fGetBooleanv;
typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params);
PFNGLGETBUFFERPARAMETERIVPROC fGetBufferParameteriv;
typedef void (GLAPIENTRY * PFNGLGENBUFFERSPROC) (GLsizei n, GLuint* buffers);
PFNGLGENBUFFERSPROC fGenBuffers;
typedef void (GLAPIENTRY * PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures);
PFNGLGENTEXTURESPROC fGenTextures;
typedef void (GLAPIENTRY * PFNGLGENERATEMIPMAPPROC) (GLenum target);
PFNGLGENERATEMIPMAPPROC fGenerateMipmap;
typedef GLenum (GLAPIENTRY * PFNGLGETERRORPROC) (void);
PFNGLGETERRORPROC fGetError;
typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint* param);
PFNGLGETPROGRAMIVPROC fGetProgramiv;
typedef void (GLAPIENTRY * PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog);
PFNGLGETPROGRAMINFOLOGPROC fGetProgramInfoLog;
typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
PFNGLTEXPARAMETERIPROC fTexParameteri;
typedef void (GLAPIENTRY * PFNGLTEXPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat param);
PFNGLTEXPARAMETERFPROC fTexParameterf;
typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
PFNGLTEXPARAMETERIVPROC fGetTexParameteriv;
typedef void (GLAPIENTRY * PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat* params);
PFNGLGETUNIFORMFVPROC fGetUniformfv;
typedef void (GLAPIENTRY * PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint* params);
PFNGLGETUNIFORMIVPROC fGetUniformiv;
typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMLOCATIONPROC) (GLint programObj, const GLchar* name);
PFNGLGETUNIFORMLOCATIONPROC fGetUniformLocation;
typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVPROC) (GLuint, GLenum, GLdouble*);
PFNGLGETVERTEXATTRIBDVPROC fGetVertexAttribdv;
typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVPROC) (GLuint, GLenum, GLfloat*);
PFNGLGETVERTEXATTRIBFVPROC fGetVertexAttribfv;
typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVPROC) (GLuint, GLenum, GLint*);
PFNGLGETVERTEXATTRIBIVPROC fGetVertexAttribiv;
typedef void (GLAPIENTRY * PFNGLHINTPROC) (GLenum target, GLenum mode);
PFNGLHINTPROC fHint;
typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERPROC) (GLuint buffer);
PFNGLISBUFFERPROC fIsBuffer;
typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDPROC) (GLenum cap);
PFNGLISENABLEDPROC fIsEnabled;
typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMPROC) (GLuint program);
PFNGLISPROGRAMPROC fIsProgram;
typedef GLboolean (GLAPIENTRY * PFNGLISSHADERPROC) (GLuint shader);
PFNGLISSHADERPROC fIsShader;
typedef GLboolean (GLAPIENTRY * PFNGLISTEXTUREPROC) (GLuint texture);
PFNGLISTEXTUREPROC fIsTexture;
typedef void (GLAPIENTRY * PFNGLLINEWIDTHPROC) (GLfloat width);
PFNGLLINEWIDTHPROC fLineWidth;
typedef void (GLAPIENTRY * PFNGLLINKPROGRAMPROC) (GLuint program);
PFNGLLINKPROGRAMPROC fLinkProgram;
typedef void (GLAPIENTRY * PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param);
PFNGLPIXELSTOREIPROC fPixelStorei;
typedef void (GLAPIENTRY * PFNGLPOLYGONOFFSETPROC) (GLfloat factor, GLfloat bias);
PFNGLPOLYGONOFFSETPROC fPolygonOffset;
typedef void (GLAPIENTRY * PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);
PFNGLREADPIXELSPROC fReadPixels;
typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert);
PFNGLSAMPLECOVERAGEPROC fSampleCoverage;
typedef void (GLAPIENTRY * PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
PFNGLSCISSORPROC fScissor;
typedef void (GLAPIENTRY * PFNGLSTENCILFUNCPROC) (GLenum func, GLint ref, GLuint mask);
PFNGLSTENCILFUNCPROC fStencilFunc;
typedef void (GLAPIENTRY * PFNGLSTENCILFUNCSEPARATEPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
PFNGLSTENCILFUNCSEPARATEPROC fStencilFuncSeparate;
typedef void (GLAPIENTRY * PFNGLSTENCILMASKPROC) (GLuint mask);
PFNGLSTENCILMASKPROC fStencilMask;
typedef void (GLAPIENTRY * PFNGLSTENCILMASKSEPARATEPROC) (GLenum, GLuint);
PFNGLSTENCILMASKSEPARATEPROC fStencilMaskSeparate;
typedef void (GLAPIENTRY * PFNGLSTENCILOPPROC) (GLenum fail, GLenum zfail, GLenum zpass);
PFNGLSTENCILOPPROC fStencilOp;
typedef void (GLAPIENTRY * PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
PFNGLSTENCILOPSEPARATEPROC fStencilOpSeparate;
typedef void (GLAPIENTRY * PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
PFNGLTEXIMAGE2DPROC fTexImage2D;
typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels);
PFNGLTEXSUBIMAGE2DPROC fTexSubImage2D;
typedef void (GLAPIENTRY * PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0);
PFNGLUNIFORM1FPROC fUniform1f;
typedef void (GLAPIENTRY * PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat* value);
PFNGLUNIFORM1FVPROC fUniform1fv;
typedef void (GLAPIENTRY * PFNGLUNIFORM1IPROC) (GLint location, GLint v0);
PFNGLUNIFORM1IPROC fUniform1i;
typedef void (GLAPIENTRY * PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint* value);
PFNGLUNIFORM1IVPROC fUniform1iv;
typedef void (GLAPIENTRY * PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1);
PFNGLUNIFORM2FPROC fUniform2f;
typedef void (GLAPIENTRY * PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat* value);
PFNGLUNIFORM2FVPROC fUniform2fv;
typedef void (GLAPIENTRY * PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1);
PFNGLUNIFORM2IPROC fUniform2i;
typedef void (GLAPIENTRY * PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint* value);
PFNGLUNIFORM2IVPROC fUniform2iv;
typedef void (GLAPIENTRY * PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
PFNGLUNIFORM3FPROC fUniform3f;
typedef void (GLAPIENTRY * PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat* value);
PFNGLUNIFORM3FVPROC fUniform3fv;
typedef void (GLAPIENTRY * PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2);
PFNGLUNIFORM3IPROC fUniform3i;
typedef void (GLAPIENTRY * PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint* value);
PFNGLUNIFORM3IVPROC fUniform3iv;
typedef void (GLAPIENTRY * PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
PFNGLUNIFORM4FPROC fUniform4f;
typedef void (GLAPIENTRY * PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat* value);
PFNGLUNIFORM4FVPROC fUniform4fv;
typedef void (GLAPIENTRY * PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
PFNGLUNIFORM4IPROC fUniform4i;
typedef void (GLAPIENTRY * PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint* value);
PFNGLUNIFORM4IVPROC fUniform4iv;
typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
PFNGLUNIFORMMATRIX2FVPROC fUniformMatrix2fv;
typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
PFNGLUNIFORMMATRIX3FVPROC fUniformMatrix3fv;
typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
PFNGLUNIFORMMATRIX4FVPROC fUniformMatrix4fv;
typedef void (GLAPIENTRY * PFNGLUSEPROGRAMPROC) (GLuint program);
PFNGLUSEPROGRAMPROC fUseProgram;
typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMPROC) (GLuint program);
PFNGLVALIDATEPROGRAMPROC fValidateProgram;
typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer);
PFNGLVERTEXATTRIBPOINTERPROC fVertexAttribPointer;
typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x);
PFNGLVERTEXATTRIB1FPROC fVertexAttrib1f;
typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y);
PFNGLVERTEXATTRIB2FPROC fVertexAttrib2f;
typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
PFNGLVERTEXATTRIB3FPROC fVertexAttrib3f;
typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
PFNGLVERTEXATTRIB4FPROC fVertexAttrib4f;
typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat* v);
PFNGLVERTEXATTRIB1FVPROC fVertexAttrib1fv;
typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat* v);
PFNGLVERTEXATTRIB2FVPROC fVertexAttrib2fv;
typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat* v);
PFNGLVERTEXATTRIB3FVPROC fVertexAttrib3fv;
typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat* v);
PFNGLVERTEXATTRIB4FVPROC fVertexAttrib4fv;
typedef void (GLAPIENTRY * PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
PFNGLVIEWPORTPROC fViewport;
typedef void (GLAPIENTRY * PFNGLCOMPILESHADERPROC) (GLuint shader);
PFNGLCOMPILESHADERPROC fCompileShader;
typedef void (GLAPIENTRY * PFNGLCOPYTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
PFNGLCOPYTEXIMAGE2DPROC fCopyTexImage2D;
typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
PFNGLCOPYTEXSUBIMAGE2DPROC fCopyTexSubImage2D;
typedef void (GLAPIENTRY * PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint* param);
PFNGLGETSHADERIVPROC fGetShaderiv;
typedef void (GLAPIENTRY * PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog);
PFNGLGETSHADERINFOLOGPROC fGetShaderInfoLog;
typedef void (GLAPIENTRY * PFNGLGETSHADERSOURCEPROC) (GLint obj, GLsizei maxLength, GLsizei* length, GLchar* source);
PFNGLGETSHADERSOURCEPROC fGetShaderSource;
typedef void (GLAPIENTRY * PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar** strings, const GLint* lengths);
PFNGLSHADERSOURCEPROC fShaderSource;
typedef void (GLAPIENTRY * PFNGLBINDFRAMEBUFFER) (GLenum target, GLuint framebuffer);
PFNGLBINDFRAMEBUFFER fBindFramebuffer;
typedef void (GLAPIENTRY * PFNGLBINDRENDERBUFFER) (GLenum target, GLuint renderbuffer);
PFNGLBINDRENDERBUFFER fBindRenderbuffer;
typedef GLenum (GLAPIENTRY * PFNGLCHECKFRAMEBUFFERSTATUS) (GLenum target);
PFNGLCHECKFRAMEBUFFERSTATUS fCheckFramebufferStatus;
typedef void (GLAPIENTRY * PFNGLDELETEFRAMEBUFFERS) (GLsizei n, const GLuint* ids);
PFNGLDELETEFRAMEBUFFERS fDeleteFramebuffers;
typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERS) (GLsizei n, const GLuint* ids);
PFNGLDELETERENDERBUFFERS fDeleteRenderbuffers;
typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERRENDERBUFFER) (GLenum target, GLenum attachmentPoint, GLenum renderbufferTarget, GLuint renderbuffer);
PFNGLFRAMEBUFFERRENDERBUFFER fFramebufferRenderbuffer;
typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2D) (GLenum target, GLenum attachmentPoint, GLenum textureTarget, GLuint texture, GLint level);
PFNGLFRAMEBUFFERTEXTURE2D fFramebufferTexture2D;
typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIV) (GLenum target, GLenum attachment, GLenum pname, GLint* value);
PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIV fGetFramebufferAttachmentParameteriv;
typedef void (GLAPIENTRY * PFNGLGETRENDERBUFFERPARAMETERIV) (GLenum target, GLenum pname, GLint* value);
PFNGLGETRENDERBUFFERPARAMETERIV fGetRenderbufferParameteriv;
typedef void (GLAPIENTRY * PFNGLGENFRAMEBUFFERS) (GLsizei n, GLuint* ids);
PFNGLGENFRAMEBUFFERS fGenFramebuffers;
typedef void (GLAPIENTRY * PFNGLGENRENDERBUFFERS) (GLsizei n, GLuint* ids);
PFNGLGENRENDERBUFFERS fGenRenderbuffers;
typedef GLboolean (GLAPIENTRY * PFNGLISFRAMEBUFFER) (GLuint framebuffer);
PFNGLISFRAMEBUFFER fIsFramebuffer;
typedef GLboolean (GLAPIENTRY * PFNGLISRENDERBUFFER) (GLuint renderbuffer);
PFNGLISRENDERBUFFER fIsRenderbuffer;
typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGE) (GLenum target, GLenum internalFormat, GLsizei width, GLsizei height);
PFNGLRENDERBUFFERSTORAGE fRenderbufferStorage;
};
#endif

3051
content/canvas/src/localgl.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -2938,9 +2938,7 @@ nsCanvasRenderingContext2D::DrawImage()
gfxMatrix matrix;
nsRefPtr<gfxPattern> pattern;
nsRefPtr<gfxPath> path;
#ifdef WINCE
nsRefPtr<gfxASurface> currentSurface;
#endif
nsLayoutUtils::SurfaceFromElementResult res =
nsLayoutUtils::SurfaceFromElement(imgElt);
if (!res.mSurface)
@ -3026,29 +3024,30 @@ nsCanvasRenderingContext2D::DrawImage()
matrix.Translate(gfxPoint(sx, sy));
matrix.Scale(sw/dw, sh/dh);
#ifdef WINCE
currentSurface = getter_AddRefs(mThebes->CurrentSurface());
/* cairo doesn't have consistent semantics for drawing a surface onto
* itself. Specifically, pixman will not preserve the contents when doing
* the copy. So to get the desired semantics a temporary copy would be needed.
* Instead we optimize opaque self copies here */
if (currentSurface == imgsurf) {
if (imgsurf->GetType() == gfxASurface::SurfaceTypeImage) {
gfxImageSurface *surf = static_cast<gfxImageSurface*>(imgsurf.get());
gfxContext::GraphicsOperator op = mThebes->CurrentOperator();
PRBool opaque, unscaled;
{
nsRefPtr<gfxASurface> csurf = mThebes->CurrentSurface();
if (csurf == imgsurf) {
if (imgsurf->GetType() == gfxASurface::SurfaceTypeImage) {
gfxImageSurface *surf = static_cast<gfxImageSurface*>(imgsurf.get());
gfxContext::GraphicsOperator op = mThebes->CurrentOperator();
PRBool opaque, unscaled;
opaque = surf->Format() == gfxASurface::ImageFormatARGB32 &&
(op == gfxContext::OPERATOR_SOURCE);
opaque |= surf->Format() == gfxASurface::ImageFormatRGB24 &&
(op == gfxContext::OPERATOR_SOURCE || op == gfxContext::OPERATOR_OVER);
opaque = surf->Format() == gfxASurface::ImageFormatARGB32 &&
(op == gfxContext::OPERATOR_SOURCE);
opaque |= surf->Format() == gfxASurface::ImageFormatRGB24 &&
(op == gfxContext::OPERATOR_SOURCE || op == gfxContext::OPERATOR_OVER);
unscaled = sw == dw && sh == dh;
unscaled = sw == dw && sh == dh;
if (opaque && unscaled) {
bitblt(surf, sx, sy, sw, sh, dx, dy);
rv = NS_OK;
goto FINISH;
if (opaque && unscaled) {
bitblt(surf, sx, sy, sw, sh, dx, dy);
rv = NS_OK;
goto FINISH;
}
}
}
}
@ -3247,22 +3246,6 @@ nsCanvasRenderingContext2D::ConvertJSValToXPCObject(nsISupports** aSupports, REF
return JS_FALSE;
}
/* Check that the rect [x,y,w,h] is a valid subrect of [0,0,realWidth,realHeight]
* without overflowing any integers and the like.
*/
PRBool
CheckSaneSubrectSize (PRInt32 x, PRInt32 y, PRInt32 w, PRInt32 h, PRInt32 realWidth, PRInt32 realHeight)
{
if (w <= 0 || h <= 0 || x < 0 || y < 0)
return PR_FALSE;
if (x >= realWidth || w > (realWidth - x) ||
y >= realHeight || h > (realHeight - y))
return PR_FALSE;
return PR_TRUE;
}
static void
FlushLayoutForTree(nsIDOMWindow* aWindow)
{
@ -3765,13 +3748,16 @@ nsCanvasRenderingContext2D::CreateImageData()
JSAutoRequest ar(ctx);
int32 w, h;
if (!JS_ConvertArguments (ctx, argc, argv, "jj", &w, &h))
int32 width, height;
if (!JS_ConvertArguments (ctx, argc, argv, "jj", &width, &height))
return NS_ERROR_DOM_SYNTAX_ERR;
if (w <= 0 || h <= 0)
if (width <= 0 || height <= 0)
return NS_ERROR_DOM_INDEX_SIZE_ERR;
PRUint32 w = (PRUint32) width;
PRUint32 h = (PRUint32) height;
// check for overflow when calculating len
PRUint32 len0 = w * h;
if (len0 / w != (PRUint32) h)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,425 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Vladimir Vukicevic <vladimir@pobox.com> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef _NSCANVASRENDERINGCONTEXTGL_H_
#define _NSCANVASRENDERINGCONTEXTGL_H_
#ifdef C3D_STANDALONE_BUILD
#include "c3d-standalone.h"
#endif
#include "nsICanvasRenderingContextGL.h"
#include <stdlib.h>
#include <stdarg.h>
#include "prmem.h"
#include "nsStringGlue.h"
#include "nsICanvasRenderingContextGLBuffer.h"
#include "nsICanvasRenderingContextInternal.h"
#include "nsIDOMHTMLCanvasElement.h"
#include "nsICanvasGLPrivate.h"
#include "nsIScriptSecurityManager.h"
#include "nsISecurityCheckedComponent.h"
#include "nsWeakReference.h"
#include "imgIRequest.h"
#include "imgIContainer.h"
#include "gfxIImageFrame.h"
#include "nsIDOMHTMLCanvasElement.h"
#include "nsICanvasElement.h"
#include "nsIDOMHTMLImageElement.h"
#include "nsIImageLoadingContent.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIImage.h"
#include "nsDOMError.h"
#include "nsIJSRuntimeService.h"
#include "nsIServiceManager.h"
#include "nsIConsoleService.h"
#include "nsDOMError.h"
#include "nsServiceManagerUtils.h"
#include "nsIXPConnect.h"
#include "jsapi.h"
#include "gfxContext.h"
#include "nsGLPbuffer.h"
extern nsIXPConnect *gXPConnect;
extern JSRuntime *gScriptRuntime;
extern nsIJSRuntimeService *gJSRuntimeService;
class nsICanvasRenderingContextGL;
class nsCanvasRenderingContextGLES11;
class nsCanvasRenderingContextGLWeb20;
class CanvasGLBuffer;
class CanvasGLTexture;
class nsCanvasRenderingContextGLPrivate :
public nsICanvasRenderingContextInternal,
public nsSupportsWeakReference
{
friend class nsGLPbuffer;
friend class CanvasGLBuffer;
friend class CanvasGLTexture;
public:
nsCanvasRenderingContextGLPrivate();
virtual ~nsCanvasRenderingContextGLPrivate();
virtual nsICanvasRenderingContextGL *GetSelf() = 0;
virtual PRBool ValidateGL() { return PR_TRUE; }
void MakeContextCurrent();
static void LostCurrentContext(void *closure);
// nsICanvasRenderingContextInternal
NS_IMETHOD SetCanvasElement(nsICanvasElement* aParentCanvas);
NS_IMETHOD SetDimensions(PRInt32 width, PRInt32 height);
NS_IMETHOD Render(gfxContext *ctx, gfxPattern::GraphicsFilter f);
NS_IMETHOD GetInputStream(const char* aMimeType,
const PRUnichar* aEncoderOptions,
nsIInputStream **aStream);
NS_IMETHOD GetThebesSurface(gfxASurface **surface);
NS_IMETHOD SetIsOpaque(PRBool b) { return NS_OK; };
protected:
PRBool SafeToCreateCanvas3DContext(nsICanvasElement *canvasElement);
nsresult DoSwapBuffers();
// thebes helpers
nsresult ImageSurfaceFromElement(nsIDOMElement *imgElt,
gfxImageSurface **aSurface,
nsIPrincipal **prinOut,
PRBool *forceWriteOnlyOut,
PRBool *surfaceNeedsReleaseInsteadOfDelete);
void DoDrawImageSecurityCheck(nsIPrincipal* element_uri, PRBool forceWriteOnly);
GLES20Wrap *gl;
nsGLPbuffer *mGLPbuffer;
PRInt32 mWidth, mHeight;
nsICanvasElement* mCanvasElement;
PRPackedBool mPrefWireframe;
void LogMessage (const nsCString& errorString) {
nsCOMPtr<nsIConsoleService> console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
if (!console)
return;
console->LogStringMessage(NS_ConvertUTF8toUTF16(errorString).get());
fprintf(stderr, "%s\n", errorString.get());
}
void LogMessagef (const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
char buf[256];
nsCOMPtr<nsIConsoleService> console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
if (console) {
vsnprintf(buf, 256, fmt, ap);
console->LogStringMessage(NS_ConvertUTF8toUTF16(nsDependentCString(buf)).get());
fprintf(stderr, "%s\n", buf);
}
va_end(ap);
}
};
class SimpleBuffer {
public:
SimpleBuffer()
: type(GL_FLOAT), data(nsnull), length(0), capacity(0), sizePerVertex(0)
{ }
SimpleBuffer(PRUint32 typeParam,
PRUint32 sizeParam,
JSContext *ctx,
JSObject *arrayObj,
jsuint arrayLen)
: type(GL_FLOAT), data(nsnull), length(0), capacity(0), sizePerVertex(0)
{
InitFromJSArray(typeParam, sizeParam, ctx, arrayObj, arrayLen);
}
PRBool InitFromJSArray(PRUint32 typeParam,
PRUint32 sizeParam,
JSContext *ctx,
JSObject *arrayObj,
jsuint arrayLen);
~SimpleBuffer() {
Release();
}
inline PRBool Valid() {
return data != nsnull;
}
inline PRUint32 ElementSize() {
if (type == GL_FLOAT) return sizeof(float);
if (type == GL_SHORT) return sizeof(short);
if (type == GL_UNSIGNED_SHORT) return sizeof(unsigned short);
if (type == GL_BYTE) return 1;
if (type == GL_UNSIGNED_BYTE) return 1;
if (type == GL_INT) return sizeof(int);
if (type == GL_UNSIGNED_INT) return sizeof(unsigned int);
if (type == GL_DOUBLE) return sizeof(double);
return 0;
}
void Clear() {
Release();
}
void Set(PRUint32 t, PRUint32 spv, PRUint32 count, void* vals) {
Prepare(t, spv, count);
if (count)
memcpy(data, vals, count*ElementSize());
}
void Prepare(PRUint32 t, PRUint32 spv, PRUint32 count) {
if (count == 0) {
Release();
} else {
type = t;
EnsureCapacity(PR_FALSE, count*ElementSize());
length = count;
sizePerVertex = spv;
}
}
void Release() {
if (data)
PR_Free(data);
length = 0;
capacity = 0;
data = nsnull;
}
void EnsureCapacity(PRBool preserve, PRUint32 cap) {
if (capacity >= cap)
return;
void* newdata = PR_Malloc(cap);
if (preserve && length)
memcpy(newdata, data, length*ElementSize());
PR_Free(data);
data = newdata;
capacity = cap;
}
PRUint32 type;
void* data;
PRUint32 length; // # of elements
PRUint32 capacity; // bytes!
PRUint32 sizePerVertex; // OpenGL "size" param; num coordinates per vertex
};
class CanvasGLTexture :
public nsICanvasRenderingContextGLTexture,
public nsICanvasGLTexture
{
friend class nsCanvasRenderingContextGLES11;
friend class nsCanvasRenderingContextGLWeb20;
public:
CanvasGLTexture(nsCanvasRenderingContextGLPrivate *owner);
~CanvasGLTexture();
NS_DECL_ISUPPORTS
NS_DECL_NSICANVASRENDERINGCONTEXTGLTEXTURE
nsresult Init();
nsresult Dispose();
protected:
PRBool mDisposed;
nsCOMPtr<nsIWeakReference> mOwnerContext;
GLES20Wrap *gl;
PRUint32 mWidth;
PRUint32 mHeight;
};
class CanvasGLBuffer :
public nsICanvasRenderingContextGLBuffer,
public nsISecurityCheckedComponent,
public nsICanvasGLBuffer
{
friend class nsCanvasRenderingContextGLES11;
friend class nsCanvasRenderingContextGLWeb20;
public:
CanvasGLBuffer(nsCanvasRenderingContextGLPrivate *owner);
~CanvasGLBuffer();
// Init can be called multiple times to reinitialize this
// buffer object
nsresult Init (PRUint32 usage,
PRUint32 size,
PRUint32 type,
JSContext *ctx,
JSObject *arrayObj,
jsuint arrayLen);
SimpleBuffer& GetSimpleBuffer() { return mSimpleBuffer; }
PRBool UpdateBuffer (PRUint32 offset, SimpleBuffer& sbuffer)
{
PRUint32 len = GetSimpleBuffer().capacity;
PRUint32 sbuflen = sbuffer.capacity;
if (offset < 0 || offset > len || sbuflen > len || offset > len - sbuflen)
return false;
memcpy(((char*)(GetSimpleBuffer().data)) + offset, sbuffer.data, sbuflen);
mMaxUShortComputed = false;
return true;
}
GLushort MaxUShortValue()
{
if (!mMaxUShortComputed) {
GLushort *data = (GLushort*)GetSimpleBuffer().data;
PRUint32 i, len;
GLushort max = 0;
len = GetSimpleBuffer().capacity / sizeof(GLushort);
for (i=0; i<len; ++i)
if (data[i] > max)
max = data[i];
mMaxUShort = max;
mMaxUShortComputed = true;
}
return mMaxUShort;
}
NS_DECL_ISUPPORTS
NS_DECL_NSICANVASRENDERINGCONTEXTGLBUFFER
NS_DECL_NSISECURITYCHECKEDCOMPONENT
PRUint32 Size() { return mSize; }
PRUint32 Length() { return mLength; }
PRUint32 Type() { return mType; }
protected:
CanvasGLBuffer() { }
nsCOMPtr<nsIWeakReference> mOwnerContext;
GLES20Wrap *gl;
PRBool mDisposed;
PRUint32 mLength;
PRUint32 mSize;
PRUint32 mType;
PRUint32 mUsage;
SimpleBuffer mSimpleBuffer;
GLuint mBufferID;
GLushort mMaxUShort;
PRBool mMaxUShortComputed;
};
class CanvasGLThebes {
public:
static gfxImageSurface *CreateImageSurface (const gfxIntSize &isize,
gfxASurface::gfxImageFormat fmt);
static gfxContext *CreateContext (gfxASurface *surf);
static gfxPattern *CreatePattern (gfxASurface *surf);
};
/* Helper macros for when we're just wrapping a gl method, so that
* we can avoid having to type this 500 times. Note that these MUST
* NOT BE USED if we need to check any of the parameters.
*/
#define GL_SAME_METHOD_0(glname, name) \
NS_IMETHODIMP NSGL_CONTEXT_NAME::name() { \
MakeContextCurrent(); gl->f##glname(); return NS_OK; \
}
#define GL_SAME_METHOD_1(glname, name, t1) \
NS_IMETHODIMP NSGL_CONTEXT_NAME::name(t1 a1) { \
MakeContextCurrent(); gl->f##glname(a1); return NS_OK; \
}
#define GL_SAME_METHOD_2(glname, name, t1, t2) \
NS_IMETHODIMP NSGL_CONTEXT_NAME::name(t1 a1, t2 a2) { \
MakeContextCurrent(); gl->f##glname(a1,a2); return NS_OK; \
}
#define GL_SAME_METHOD_3(glname, name, t1, t2, t3) \
NS_IMETHODIMP NSGL_CONTEXT_NAME::name(t1 a1, t2 a2, t3 a3) { \
MakeContextCurrent(); gl->f##glname(a1,a2,a3); return NS_OK; \
}
#define GL_SAME_METHOD_4(glname, name, t1, t2, t3, t4) \
NS_IMETHODIMP NSGL_CONTEXT_NAME::name(t1 a1, t2 a2, t3 a3, t4 a4) { \
MakeContextCurrent(); gl->f##glname(a1,a2,a3,a4); return NS_OK; \
}
#define GL_SAME_METHOD_5(glname, name, t1, t2, t3, t4, t5) \
NS_IMETHODIMP NSGL_CONTEXT_NAME::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) { \
MakeContextCurrent(); gl->f##glname(a1,a2,a3,a4,a5); return NS_OK; \
}
#define GL_SAME_METHOD_6(glname, name, t1, t2, t3, t4, t5, t6) \
NS_IMETHODIMP NSGL_CONTEXT_NAME::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) { \
MakeContextCurrent(); gl->f##glname(a1,a2,a3,a4,a5,a6); return NS_OK; \
}
#endif /* _NSCANVASRENDERINGCONTEXTGL_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,147 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Vladimir Vukicevic <vladimir@pobox.com> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <stdarg.h>
#include "nsCanvasRenderingContextGL.h"
#include "nsGLPbuffer.h"
#if 0
#include <xmmintrin.h>
#endif
void *nsGLPbuffer::sCurrentContextToken = nsnull;
void
nsGLPbuffer::LogMessage (const nsCString& errorString)
{
if (mPriv)
mPriv->LogMessage(errorString);
else
fprintf(stderr, "nsGLPbuffer: %s\n", errorString.get());
}
void
nsGLPbuffer::LogMessagef (const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
char buf[256];
vsnprintf(buf, 256, fmt, ap);
if (mPriv)
mPriv->LogMessage(nsDependentCString(buf));
else
fprintf(stderr, "nsGLPbuffer: %s\n", buf);
va_end(ap);
}
static void
premultiply_slow(unsigned char *src, unsigned int len)
{
int a,t;
for (unsigned int i=0; i<len; i+=4) {
a = src[i+3];
t = src[i]*a+0x80;
src[i] = ((t>>8) + t) >> 8;
t = src[i+1]*a+0x80;
src[i+1] = ((t>>8) + t) >> 8;
t = src[i+2]*a+0x80;
src[i+2] = ((t>>8) + t) >> 8;
}
}
#if 0
static void
premultiply_sse2(__m128i* block, __m128i* block_end)
{
__m128i xmm0080, xmm0101, xmmAlpha, data, dataLo, dataHi, alphaLo, alphaHi;
while (block < block_end) {
xmm0080 = _mm_set1_epi16(0x0080);
xmm0101 = _mm_set1_epi16(0x0101);
xmmAlpha = _mm_set_epi32(0x00ff0000, 0x00000000, 0x00ff0000, 0x00000000);
data = _mm_loadu_si128(block);
dataLo = _mm_unpacklo_epi8 (data, _mm_setzero_si128 ());
dataHi = _mm_unpackhi_epi8 (data, _mm_setzero_si128 ());
alphaLo = _mm_shufflelo_epi16 (dataLo, _MM_SHUFFLE(3, 3, 3, 3));
alphaHi = _mm_shufflelo_epi16 (dataHi, _MM_SHUFFLE(3, 3, 3, 3));
alphaLo = _mm_shufflehi_epi16 (alphaLo, _MM_SHUFFLE(3, 3, 3, 3));
alphaHi = _mm_shufflehi_epi16 (alphaHi, _MM_SHUFFLE(3, 3, 3, 3));
alphaLo = _mm_or_si128(alphaLo, xmmAlpha);
alphaHi = _mm_or_si128(alphaHi, xmmAlpha);
dataLo = _mm_shufflelo_epi16 (dataLo, _MM_SHUFFLE(3, 2, 1, 0));
dataLo = _mm_shufflehi_epi16 (dataLo, _MM_SHUFFLE(3, 2, 1, 0));
dataHi = _mm_shufflelo_epi16 (dataHi, _MM_SHUFFLE(3, 2, 1, 0));
dataHi = _mm_shufflehi_epi16 (dataHi, _MM_SHUFFLE(3, 2, 1, 0));
dataLo = _mm_mullo_epi16(dataLo, alphaLo);
dataHi = _mm_mullo_epi16(dataHi, alphaHi);
dataLo = _mm_adds_epu16(dataLo, xmm0080);
dataHi = _mm_adds_epu16(dataHi, xmm0080);
dataLo = _mm_mulhi_epu16(dataLo, xmm0101);
dataHi = _mm_mulhi_epu16(dataHi, xmm0101);
data = _mm_packus_epi16 (dataLo, dataHi);
_mm_storeu_si128(block, data);
++block;
}
}
#endif
void
nsGLPbuffer::Premultiply(unsigned char *src, unsigned int len)
{
#if 0
if (can_sse2) {
premultiply_sse2((__m128i*)src, (__m128i*)(src+len));
return;
}
#endif
premultiply_slow(src, len);
}

View File

@ -0,0 +1,218 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Vladimir Vukicevic <vladimir@pobox.com> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef NSGLPBUFFER_H_
#define NSGLPBUFFER_H_
#ifdef C3D_STANDALONE_BUILD
#include "c3d-standalone.h"
#endif
#include "nsStringGlue.h"
#include "gfxASurface.h"
#include "gfxImageSurface.h"
#ifdef XP_WIN
#include "gfxWindowsSurface.h"
#endif
#if defined(XP_UNIX) && defined(MOZ_X11)
#include "GL/glx.h"
#endif
#ifdef XP_MACOSX
#include "gfxQuartzImageSurface.h"
#include <OpenGL/CGLTypes.h>
#endif
#include "glwrap.h"
class nsCanvasRenderingContextGLPrivate;
class nsGLPbuffer {
public:
nsGLPbuffer() : mWidth(0), mHeight(0), mPriv(0) { }
virtual ~nsGLPbuffer() { }
virtual PRBool Init(nsCanvasRenderingContextGLPrivate *priv) = 0;
virtual PRBool Resize(PRInt32 width, PRInt32 height) = 0;
virtual void Destroy() = 0;
virtual void MakeContextCurrent() = 0;
virtual void SwapBuffers() = 0;
virtual gfxASurface* ThebesSurface() = 0;
PRInt32 Width() { return mWidth; }
PRInt32 Height() { return mHeight; }
GLES20Wrap *GL() { return &mGLWrap; }
protected:
PRInt32 mWidth, mHeight;
GLES20Wrap mGLWrap;
static void *sCurrentContextToken;
nsCanvasRenderingContextGLPrivate *mPriv;
void Premultiply(unsigned char *src, unsigned int len);
void LogMessage (const nsCString& errorString);
void LogMessagef (const char *fmt, ...);
};
class nsGLPbufferOSMESA :
public nsGLPbuffer
{
public:
nsGLPbufferOSMESA();
virtual ~nsGLPbufferOSMESA();
virtual PRBool Init(nsCanvasRenderingContextGLPrivate *priv);
virtual PRBool Resize(PRInt32 width, PRInt32 height);
virtual void Destroy();
virtual void MakeContextCurrent();
virtual void SwapBuffers();
virtual gfxASurface* ThebesSurface();
protected:
nsRefPtr<gfxImageSurface> mThebesSurface;
PrivateOSMesaContext mMesaContext;
};
#ifdef XP_MACOSX
class nsGLPbufferCGL :
public nsGLPbuffer
{
public:
nsGLPbufferCGL();
virtual ~nsGLPbufferCGL();
virtual PRBool Init(nsCanvasRenderingContextGLPrivate *priv);
virtual PRBool Resize(PRInt32 width, PRInt32 height);
virtual void Destroy();
virtual void MakeContextCurrent();
virtual void SwapBuffers();
virtual gfxASurface* ThebesSurface();
CGLPixelFormatObj GetCGLPixelFormat() { return mPixelFormat; }
CGLContextObj GetCGLContext() { return mContext; }
CGLPBufferObj GetCGLPbuffer() { return mPbuffer; }
protected:
CGLPixelFormatObj mPixelFormat;
CGLContextObj mContext;
CGLPBufferObj mPbuffer;
PRBool mImageNeedsUpdate;
nsRefPtr<gfxImageSurface> mThebesSurface;
nsRefPtr<gfxQuartzImageSurface> mQuartzSurface;
typedef void (GLAPIENTRY * PFNGLFLUSHPROC) (void);
PFNGLFLUSHPROC fFlush;
};
#endif
#if defined(XP_UNIX) && defined(MOZ_X11)
class nsGLPbufferGLX :
public nsGLPbuffer
{
public:
nsGLPbufferGLX();
virtual ~nsGLPbufferGLX();
virtual PRBool Init(nsCanvasRenderingContextGLPrivate *priv);
virtual PRBool Resize(PRInt32 width, PRInt32 height);
virtual void Destroy();
virtual void MakeContextCurrent();
virtual void SwapBuffers();
virtual gfxASurface* ThebesSurface();
protected:
nsRefPtr<gfxImageSurface> mThebesSurface;
Display *mDisplay;
GLXFBConfig mFBConfig;
GLXPbuffer mPbuffer;
GLXContext mPbufferContext;
};
#endif
#ifdef XP_WIN
class nsGLPbufferWGL :
public nsGLPbuffer
{
public:
nsGLPbufferWGL();
virtual ~nsGLPbufferWGL();
virtual PRBool Init(nsCanvasRenderingContextGLPrivate *priv);
virtual PRBool Resize(PRInt32 width, PRInt32 height);
virtual void Destroy();
virtual void MakeContextCurrent();
virtual void SwapBuffers();
virtual gfxASurface* ThebesSurface();
protected:
// this is the crap that we need to get the gl entry points
HWND mGlewWindow;
HDC mGlewDC;
HANDLE mGlewWglContext;
// and this is the actual stuff that we need to render
HANDLE mPbuffer;
HDC mPbufferDC;
HANDLE mPbufferContext;
nsRefPtr<gfxImageSurface> mThebesSurface;
nsRefPtr<gfxWindowsSurface> mWindowsSurface;
};
#endif
#endif /* NSGLPBUFFER_H_ */

View File

@ -0,0 +1,249 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Vladimir Vukicevic <vladimir@pobox.com> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <OpenGL/OpenGL.h>
#include "nsICanvasRenderingContextGL.h"
#include "nsIPrefService.h"
#include "nsGLPbuffer.h"
#include "nsCanvasRenderingContextGL.h"
#include "gfxContext.h"
static PRUint32 gActiveBuffers = 0;
nsGLPbufferCGL::nsGLPbufferCGL()
: mContext(nsnull), mPbuffer(nsnull), fFlush(nsnull)
{
gActiveBuffers++;
fprintf (stderr, "nsGLPbuffer: gActiveBuffers: %d\n", gActiveBuffers);
}
PRBool
nsGLPbufferCGL::Init(nsCanvasRenderingContextGLPrivate *priv)
{
mPriv = priv;
nsresult rv;
nsCOMPtr<nsIPrefService> prefService = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, PR_FALSE);
nsCOMPtr<nsIPrefBranch> prefBranch;
rv = prefService->GetBranch("extensions.canvas3d.", getter_AddRefs(prefBranch));
NS_ENSURE_SUCCESS(rv, PR_FALSE);
PRInt32 prefAntialiasing;
rv = prefBranch->GetIntPref("antialiasing", &prefAntialiasing);
if (NS_FAILED(rv))
prefAntialiasing = 0;
CGLPixelFormatAttribute attrib[] = {
kCGLPFAAccelerated,
kCGLPFAMinimumPolicy,
kCGLPFAPBuffer,
kCGLPFAColorSize, (CGLPixelFormatAttribute) 24,
kCGLPFAAlphaSize, (CGLPixelFormatAttribute) 8,
kCGLPFADepthSize, (CGLPixelFormatAttribute) 8,
(CGLPixelFormatAttribute) 0
};
#if 0
if (false && prefAntialiasing > 0) {
attrib[12] = AGL_SAMPLE_BUFFERS_ARB;
attrib[13] = 1;
attrib[14] = AGL_SAMPLES_ARB;
attrib[15] = 1 << prefAntialiasing;
}
#endif
CGLError err;
GLint npix;
err = CGLChoosePixelFormat(attrib, &mPixelFormat, &npix);
if (err) {
fprintf (stderr, "CGLChoosePixelFormat failed: %d\n", err);
return PR_FALSE;
}
// we need a context for glewInit
Resize(2, 2);
MakeContextCurrent();
if (!mGLWrap.OpenLibrary("/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib")) {
LogMessage(NS_LITERAL_CSTRING("Canvas 3D: Failed to open LibGL.dylib (tried system OpenGL.framework)"));
return PR_FALSE;
}
if (!mGLWrap.Init(GLES20Wrap::TRY_NATIVE_GL)) {
LogMessage(NS_LITERAL_CSTRING("Canvas 3D: GLWrap init failed"));
return PR_FALSE;
}
fFlush = (PFNGLFLUSHPROC) mGLWrap.LookupSymbol("glFlush", true);
return PR_TRUE;
}
PRBool
nsGLPbufferCGL::Resize(PRInt32 width, PRInt32 height)
{
if (mWidth == width &&
mHeight == height)
{
return PR_TRUE;
}
Destroy();
mThebesSurface = nsnull;
mQuartzSurface = nsnull;
CGLError err;
err = CGLCreateContext(mPixelFormat, NULL, &mContext);
if (err) {
fprintf (stderr, "CGLCreateContext failed: %d\n", err);
return PR_FALSE;
}
err = CGLCreatePBuffer(width, height, GL_TEXTURE_RECTANGLE_EXT, GL_RGBA, 0, &mPbuffer);
if (err) {
fprintf (stderr, "CGLCreatePBuffer failed: %d\n", err);
return PR_FALSE;
}
GLint screen;
err = CGLGetVirtualScreen(mContext, &screen);
if (err) {
fprintf (stderr, "CGLGetVirtualScreen failed: %d\n", err);
return PR_FALSE;
}
err = CGLSetPBuffer(mContext, mPbuffer, 0, 0, screen);
if (err) {
fprintf (stderr, "CGLSetPBuffer failed: %d\n", err);
return PR_FALSE;
}
mWidth = width;
mHeight = height;
return PR_TRUE;
}
void
nsGLPbufferCGL::Destroy()
{
sCurrentContextToken = nsnull;
mThebesSurface = nsnull;
if (mContext) {
CGLDestroyContext(mContext);
mContext = nsnull;
}
if (mPbuffer) {
CGLDestroyPBuffer(mPbuffer);
mPbuffer = nsnull;
}
}
nsGLPbufferCGL::~nsGLPbufferCGL()
{
Destroy();
if (mPixelFormat) {
CGLDestroyPixelFormat(mPixelFormat);
mPixelFormat = nsnull;
}
gActiveBuffers--;
fprintf (stderr, "nsGLPbuffer: gActiveBuffers: %d\n", gActiveBuffers);
fflush (stderr);
}
void
nsGLPbufferCGL::MakeContextCurrent()
{
CGLError err = CGLSetCurrentContext (mContext);
if (err) {
fprintf (stderr, "CGLSetCurrentContext failed: %d\n", err);
}
}
void
nsGLPbufferCGL::SwapBuffers()
{
MakeContextCurrent();
// oddly, CGLFlushDrawable() doesn't seem to work, even though it should be calling
// glFlush first.
if (fFlush)
fFlush();
mImageNeedsUpdate = PR_TRUE;
}
gfxASurface*
nsGLPbufferCGL::ThebesSurface()
{
if (!mThebesSurface) {
mThebesSurface = CanvasGLThebes::CreateImageSurface(gfxIntSize(mWidth, mHeight), gfxASurface::ImageFormatARGB32);
if (mThebesSurface->CairoStatus() != 0) {
fprintf (stderr, "image surface failed\n");
return nsnull;
}
mQuartzSurface = new gfxQuartzImageSurface(mThebesSurface);
mImageNeedsUpdate = PR_TRUE;
}
if (mImageNeedsUpdate) {
MakeContextCurrent();
mGLWrap.fReadPixels (0, 0, mWidth, mHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, mThebesSurface->Data());
mQuartzSurface->Flush();
mImageNeedsUpdate = PR_FALSE;
}
return mQuartzSurface;
}

View File

@ -0,0 +1,338 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Vladimir Vukicevic <vladimir@pobox.com> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
// this must be first, else windows.h breaks us
#include "nsICanvasRenderingContextGL.h"
#include "nsIPrefService.h"
#include "nsGLPbuffer.h"
#include "nsCanvasRenderingContextGL.h"
#include "gfxContext.h"
#if defined(MOZ_WIDGET_GTK2) && defined(MOZ_X11)
#include <gdk/gdkx.h>
#endif
static PRUint32 gActiveBuffers = 0;
class GLXWrap
: public LibrarySymbolLoader
{
public:
GLXWrap() : fCreateNewContext(0) { }
bool Init();
protected:
//
// the wrapped functions
//
public:
typedef PRFuncPtr (* PFNGLXGETPROCADDRESS) (const GLubyte *procName);
PFNGLXGETPROCADDRESS fGetProcAddress;
typedef GLXContext (* PFNGLXCREATENEWCONTEXTPROC) (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
PFNGLXCREATENEWCONTEXTPROC fCreateNewContext;
typedef XVisualInfo* (* PFNGLXCHOOSEVISUALPROC) (Display *dpy, int scrnum, int *attrib);
PFNGLXCHOOSEVISUALPROC fChooseVisual;
typedef GLXContext (* PFNGLXCREATECONTEXTPROC) (Display *dpy, XVisualInfo *visinfo, GLXContext share_list, Bool direct);
PFNGLXCREATECONTEXTPROC fCreateContext;
typedef GLXPbuffer (* PFNGLXCREATEPBUFFERPROC) (Display *dpy, GLXFBConfig config, const int *attrib_list);
PFNGLXCREATEPBUFFERPROC fCreatePbuffer;
typedef void (* PFNGLXDESTROYCONTEXTPROC) (Display *dpy, GLXContext ctx);
PFNGLXDESTROYCONTEXTPROC fDestroyContext;
typedef void (* PFNGLXDESTROYPBUFFERPROC) (Display *dpy, GLXPbuffer pbuf);
PFNGLXDESTROYPBUFFERPROC fDestroyPbuffer;
typedef GLXFBConfig* (* PFNGLXCHOOSEFBCONFIGPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements);
PFNGLXCHOOSEFBCONFIGPROC fChooseFBConfig;
typedef Bool (* PFNGLXMAKECONTEXTCURRENTPROC) (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
PFNGLXMAKECONTEXTCURRENTPROC fMakeContextCurrent;
typedef GLXContext (* PFNGLXGETCURRENTCONTEXTPROC) ( void );
PFNGLXGETCURRENTCONTEXTPROC fGetCurrentContext;
typedef const char* (* PFNGLXQUERYEXTENSIONSSTRING) (Display *dpy, int screen);
PFNGLXQUERYEXTENSIONSSTRING fQueryExtensionsString;
typedef const char* (* PFNGLXQUERYSERVERSTRING) (Display *dpy, int screen, int name);
PFNGLXQUERYSERVERSTRING fQueryServerString;
};
bool
GLXWrap::Init()
{
if (fCreateNewContext)
return true;
SymLoadStruct symbols[] = {
{ (PRFuncPtr*) &fGetProcAddress, { "glXGetProcAddress", "glXGetProcAddressARB", NULL } },
{ (PRFuncPtr*) &fCreateNewContext, { "glXCreateNewContext", NULL } },
{ (PRFuncPtr*) &fCreateContext, { "glXCreateContext", NULL } },
{ (PRFuncPtr*) &fChooseVisual, { "glXChooseVisual", NULL } },
{ (PRFuncPtr*) &fCreatePbuffer, { "glXCreatePbuffer", NULL } },
{ (PRFuncPtr*) &fDestroyContext, { "glXDestroyContext", NULL } },
{ (PRFuncPtr*) &fDestroyPbuffer, { "glXDestroyPbuffer", NULL } },
{ (PRFuncPtr*) &fChooseFBConfig, { "glXChooseFBConfig", NULL } },
{ (PRFuncPtr*) &fMakeContextCurrent, { "glXMakeContextCurrent", NULL } },
{ (PRFuncPtr*) &fGetCurrentContext, { "glXGetCurrentContext", NULL } },
{ (PRFuncPtr*) &fQueryExtensionsString, { "glXQueryExtensionsString", NULL } },
{ (PRFuncPtr*) &fQueryServerString, { "glXQueryServerString", NULL } },
{ NULL, { NULL } }
};
return LoadSymbols(&symbols[0]);
}
static GLXWrap gGLXWrap;
nsGLPbufferGLX::nsGLPbufferGLX()
: mDisplay(nsnull), mFBConfig(0), mPbuffer(0), mPbufferContext(0)
{
gActiveBuffers++;
fprintf (stderr, "nsGLPbufferGLX: gActiveBuffers: %d\n", gActiveBuffers);
}
PRBool
nsGLPbufferGLX::Init(nsCanvasRenderingContextGLPrivate *priv)
{
nsresult rv;
const char *s;
if (!gGLXWrap.OpenLibrary("libGL.so.1")) {
LogMessage(NS_LITERAL_CSTRING("Canvas 3D: Couldn't find libGL.so.1"));
return PR_FALSE;
}
if (!gGLXWrap.Init()) {
LogMessage(NS_LITERAL_CSTRING("Canvas 3D: gGLXWrap.Init() failed"));
return PR_FALSE;
}
#if defined(MOZ_WIDGET_GTK2) && defined(MOZ_X11)
mDisplay = gdk_x11_get_default_xdisplay();
#else
mDisplay = XOpenDisplay(NULL);
#endif
if (!mDisplay) {
LogMessage(NS_LITERAL_CSTRING("Canvas 3D: XOpenDisplay failed"));
return PR_FALSE;
}
// Make sure that everyone agrees that pbuffers are supported
s = gGLXWrap.fQueryExtensionsString(mDisplay, DefaultScreen(mDisplay));
if (strstr(s, "GLX_SGIX_pbuffer") == NULL) {
LogMessage(NS_LITERAL_CSTRING("Canvas 3D: GLX_SGIX_pbuffer not supported"));
return PR_FALSE;
}
s = gGLXWrap.fQueryServerString(mDisplay, DefaultScreen(mDisplay), GLX_EXTENSIONS);
if (strstr(s, "GLX_SGIX_pbuffer") == NULL) {
LogMessage(NS_LITERAL_CSTRING("Canvas 3D: GLX_SGIX_pbuffer not supported by server"));
return PR_FALSE;
}
mPriv = priv;
nsCOMPtr<nsIPrefService> prefService = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, PR_FALSE);
nsCOMPtr<nsIPrefBranch> prefBranch;
rv = prefService->GetBranch("extensions.canvas3d.", getter_AddRefs(prefBranch));
NS_ENSURE_SUCCESS(rv, PR_FALSE);
PRInt32 prefAntialiasing;
rv = prefBranch->GetIntPref("antialiasing", &prefAntialiasing);
if (NS_FAILED(rv))
prefAntialiasing = 0;
int attrib[] = { GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
GLX_ALPHA_SIZE, 1,
GLX_DEPTH_SIZE, 1,
GLX_SAMPLE_BUFFERS, 1,
GLX_SAMPLES, 1 << prefAntialiasing,
None };
if (prefAntialiasing <= 0)
attrib[16] = 0;
int num;
GLXFBConfig *configs = gGLXWrap.fChooseFBConfig(mDisplay, DefaultScreen(mDisplay),
attrib, &num);
fprintf(stderr, "CANVAS3D FBCONFIG: %d %p\n", num, (void*) configs);
if (!configs) {
LogMessage(NS_LITERAL_CSTRING("Canvas 3D: No GLXFBConfig found"));
return PR_FALSE;
}
// choose first matching config;
mFBConfig = *configs;
XFree(configs);
mPbufferContext = gGLXWrap.fCreateNewContext(mDisplay, mFBConfig, GLX_RGBA_TYPE,
nsnull, True);
PRInt64 t1 = PR_Now();
Resize(2, 2);
MakeContextCurrent();
PRInt64 t2 = PR_Now();
fprintf (stderr, "nsGLPbufferGLX::Init!\n");
if (!mGLWrap.OpenLibrary("libGL.so.1")) {
LogMessage(NS_LITERAL_CSTRING("Canvas 3D: GLWrap init failed, couldn't find libGL.so.1"));
return PR_FALSE;
}
mGLWrap.SetLookupFunc((LibrarySymbolLoader::PlatformLookupFunction) gGLXWrap.fGetProcAddress);
if (!mGLWrap.Init(GLES20Wrap::TRY_NATIVE_GL)) {
LogMessage(NS_LITERAL_CSTRING("Canvas 3D: GLWrap init failed"));
return PR_FALSE;
}
PRInt64 t3 = PR_Now();
fprintf (stderr, "nsGLPbufferGLX:: Initialization took t2-t1: %f t3-t2: %f\n",
((double)(t2-t1))/1000.0, ((double)(t3-t2))/1000.0);
fflush (stderr);
return PR_TRUE;
}
PRBool
nsGLPbufferGLX::Resize(PRInt32 width, PRInt32 height)
{
if (mWidth == width &&
mHeight == height)
{
return PR_TRUE;
}
Destroy();
mThebesSurface = CanvasGLThebes::CreateImageSurface(gfxIntSize(width, height), gfxASurface::ImageFormatARGB32);
if (mThebesSurface->CairoStatus() != 0) {
fprintf (stderr, "image surface failed\n");
return PR_FALSE;
}
// clear the surface
memset (mThebesSurface->Data(),
0,
height * mThebesSurface->Stride());
int attrib[] = { GLX_PBUFFER_WIDTH, width,
GLX_PBUFFER_HEIGHT, height,
None };
mPbuffer = gGLXWrap.fCreatePbuffer(mDisplay, mFBConfig, attrib);
gGLXWrap.fMakeContextCurrent(mDisplay, mPbuffer, mPbuffer, mPbufferContext);
mWidth = width;
mHeight = height;
fprintf (stderr, "Resize: %d %d\n", width, height);
return PR_TRUE;
}
void
nsGLPbufferGLX::Destroy()
{
sCurrentContextToken = nsnull;
mThebesSurface = nsnull;
if (mPbuffer) {
gGLXWrap.fDestroyPbuffer(mDisplay, mPbuffer);
mPbuffer = nsnull;
}
}
nsGLPbufferGLX::~nsGLPbufferGLX()
{
MakeContextCurrent();
#ifndef GL_FRAMEBUFFER
#define GL_FRAMEBUFFER 0x8D40
#endif
// workaround for segfault on glXDestroyContext
mGLWrap.fBindFramebuffer(GL_FRAMEBUFFER, 0);
Destroy();
if (mPbuffer)
gGLXWrap.fDestroyPbuffer(mDisplay, mPbuffer);
if (mPbufferContext)
gGLXWrap.fDestroyContext(mDisplay, mPbufferContext);
#if !(defined(MOZ_WIDGET_GTK2) && defined(MOZ_X11))
if (mDisplay)
XCloseDisplay(mDisplay);
#endif
gActiveBuffers--;
fprintf (stderr, "nsGLPbufferGLX: gActiveBuffers: %d\n", gActiveBuffers);
fflush (stderr);
}
void
nsGLPbufferGLX::MakeContextCurrent()
{
if (gGLXWrap.fGetCurrentContext() != mPbufferContext)
gGLXWrap.fMakeContextCurrent(mDisplay, mPbuffer, mPbuffer, mPbufferContext);
}
void
nsGLPbufferGLX::SwapBuffers()
{
MakeContextCurrent();
mGLWrap.fReadPixels (0, 0, mWidth, mHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, mThebesSurface->Data());
unsigned int len = mWidth*mHeight*4;
unsigned char *src = mThebesSurface->Data();
// Premultiply the image
// XXX don't do this if we're known opaque
Premultiply(src, len);
}
gfxASurface*
nsGLPbufferGLX::ThebesSurface()
{
return mThebesSurface;
}

View File

@ -0,0 +1,249 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Vladimir Vukicevic <vladimir@pobox.com> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
// this must be first, else windows.h breaks us
#include "nsICanvasRenderingContextGL.h"
#include "nsDirectoryServiceUtils.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsIPrefService.h"
#include "nsGLPbuffer.h"
#include "nsCanvasRenderingContextGL.h"
#include "gfxContext.h"
#include "glwrap.h"
#if 0
#include <GL/osmesa.h>
#else
#define OSMESA_RGBA GL_RGBA
#define OSMESA_BGRA 0x1
#define OSMESA_ARGB 0x2
#define OSMESA_Y_UP 0x11
#endif
static OSMesaWrap gMesaWrap;
static PRUint32 gActiveBuffers = 0;
nsGLPbufferOSMESA::nsGLPbufferOSMESA()
: mMesaContext(nsnull)
{
gActiveBuffers++;
fprintf (stderr, "nsGLPbufferOSMESA: gActiveBuffers: %d\n", gActiveBuffers);
}
PRBool
nsGLPbufferOSMESA::Init(nsCanvasRenderingContextGLPrivate *priv)
{
mPriv = priv;
nsresult rv;
nsCOMPtr<nsIPrefService> prefService = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, PR_FALSE);
nsCOMPtr<nsIPrefBranch> prefBranch;
rv = prefService->GetBranch("extensions.canvas3d.", getter_AddRefs(prefBranch));
NS_ENSURE_SUCCESS(rv, PR_FALSE);
nsCString osmesalib;
rv = prefBranch->GetCharPref("osmesalib", getter_Copies(osmesalib));
if (NS_FAILED(rv)) {
osmesalib.Truncate();
// try our default; build it from the profile dir
nsCOMPtr<nsIFile> libfile;
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(libfile));
if (NS_FAILED(rv)) {
fprintf (stderr, "NS_GetSpecialDirectory failed?\n");
return rv;
}
// XXX this makes assumptions about the ID of this extension
rv |= libfile->Append(NS_LITERAL_STRING("extensions"));
rv |= libfile->Append(NS_LITERAL_STRING("canvas3d@mozilla.com"));
rv |= libfile->Append(NS_LITERAL_STRING("platform"));
#if defined(XP_WIN)
rv |= libfile->Append(NS_LITERAL_STRING("WINNT"));
rv |= libfile->Append(NS_LITERAL_STRING("osmesa32.dll"));
#elif defined(XP_MACOSX)
rv |= libfile->Append(NS_LITERAL_STRING("Darwin"));
rv |= libfile->Append(NS_LITERAL_STRING("libOSMesa.7.dylib"));
#elif defined(XP_UNIX)
rv |= libfile->Append(NS_LITERAL_STRING("Linux"));
rv |= libfile->Append(NS_LITERAL_STRING("libOSMesa.so.7"));
#else
#warning No default osmesa library path available
LogMessage(NS_LITERAL_STRING("Canvas 3D: No default OSMesa lib path available -- please set the extensions.canvas3d.osmesalib pref to the full path to the OSMesa shared library"));
rv = NS_ERROR_FAILURE;
#endif
if (NS_FAILED(rv))
return PR_FALSE;
PRBool exists = PR_FALSE;
rv = libfile->Exists(&exists);
if (NS_FAILED(rv) || !exists) {
LogMessage(NS_LITERAL_CSTRING("Canvas 3D: Couldn't find OSMesa lib -- either default or extension.canvas3d.osmesalib path is incorrect"));
return PR_FALSE;
}
// I'm told by the comments in nsIFile that I'm not supposed to do this. Noted.
rv = libfile->GetNativeTarget(osmesalib);
if (NS_FAILED(rv)) {
LogMessage(NS_LITERAL_CSTRING("Canvas 3D: Couldn't find OSMesa lib"));
return PR_FALSE;
}
}
if (!gMesaWrap.OpenLibrary(osmesalib.get())) {
LogMessage(NS_LITERAL_CSTRING("Canvas 3D: Couldn't open OSMesa lib -- either default or extension.canvas3d.osmesalib path is incorrect, or not a valid shared library"));
return PR_FALSE;
}
if (!gMesaWrap.Init())
return PR_FALSE;
PRInt32 prefAntialiasing;
rv = prefBranch->GetIntPref("antialiasing", &prefAntialiasing);
if (NS_FAILED(rv))
prefAntialiasing = 0;
Resize (2, 2);
if (!mGLWrap.OpenLibrary(osmesalib.get())) {
LogMessage(NS_LITERAL_CSTRING("Canvas 3D: Couldn't open OSMesa lib [1]"));
return PR_FALSE;
}
mGLWrap.SetLookupFunc((LibrarySymbolLoader::PlatformLookupFunction) gMesaWrap.fGetProcAddress);
if (!mGLWrap.Init(GLES20Wrap::TRY_SOFTWARE_GL)) {
LogMessage(NS_LITERAL_CSTRING("Canvas 3D: GLWrap init failed"));
return PR_FALSE;
}
return PR_TRUE;
}
PRBool
nsGLPbufferOSMESA::Resize(PRInt32 width, PRInt32 height)
{
if (mWidth == width &&
mHeight == height)
{
return PR_TRUE;
}
Destroy();
mThebesSurface = CanvasGLThebes::CreateImageSurface(gfxIntSize(width, height),
gfxASurface::ImageFormatARGB32);
if (mThebesSurface->CairoStatus() != 0) {
fprintf (stderr, "image surface failed\n");
return PR_FALSE;
}
mMesaContext = gMesaWrap.fCreateContextExt (OSMESA_BGRA, 16, 0, 0, NULL);
if (!mMesaContext) {
fprintf (stderr, "OSMesaCreateContextExt failed!\n");
return PR_FALSE;
}
fprintf (stderr, "Surface: %p\n", mThebesSurface->Data());
if (!gMesaWrap.fMakeCurrent (mMesaContext, mThebesSurface->Data(), GL_UNSIGNED_BYTE, width, height))
{
fprintf (stderr, "OSMesaMakeCurrent failed!\n");
return PR_FALSE;
}
gMesaWrap.fPixelStore (OSMESA_Y_UP, 1);
mWidth = width;
mHeight = height;
fprintf (stderr, "Resize: %d %d\n", width, height);
return PR_TRUE;
}
void
nsGLPbufferOSMESA::Destroy()
{
if (mMesaContext) {
gMesaWrap.fDestroyContext (mMesaContext);
mMesaContext = 0;
}
sCurrentContextToken = nsnull;
mThebesSurface = nsnull;
}
nsGLPbufferOSMESA::~nsGLPbufferOSMESA()
{
Destroy();
gActiveBuffers--;
fprintf (stderr, "nsGLPbufferOSMESA: gActiveBuffers: %d\n", gActiveBuffers);
fflush (stderr);
}
void
nsGLPbufferOSMESA::MakeContextCurrent()
{
if (gMesaWrap.fGetCurrentContext() == mMesaContext)
return;
gMesaWrap.fMakeCurrent (mMesaContext, mThebesSurface->Data(), GL_UNSIGNED_BYTE, mWidth, mHeight);
}
void
nsGLPbufferOSMESA::SwapBuffers()
{
// Nothing; we're already rendering to an image
}
gfxASurface*
nsGLPbufferOSMESA::ThebesSurface()
{
return mThebesSurface;
}

View File

@ -0,0 +1,423 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Vladimir Vukicevic <vladimir@pobox.com> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
// this must be first, else windows.h breaks us
#include "nsICanvasRenderingContextGL.h"
#include "nsIPrefService.h"
#include "nsGLPbuffer.h"
#include "nsCanvasRenderingContextGL.h"
#include "gfxContext.h"
static PRUint32 gActiveBuffers = 0;
class WGLWrap
: public LibrarySymbolLoader
{
public:
WGLWrap() : fCreatePbuffer(0) { }
bool Init();
public:
typedef HANDLE (WINAPI * PFNWGLCREATEPBUFFERPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int* piAttribList);
PFNWGLCREATEPBUFFERPROC fCreatePbuffer;
typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERPROC) (HANDLE hPbuffer);
PFNWGLDESTROYPBUFFERPROC fDestroyPbuffer;
typedef HDC (WINAPI * PFNWGLGETPBUFFERDCPROC) (HANDLE hPbuffer);
PFNWGLGETPBUFFERDCPROC fGetPbufferDC;
typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATPROC) (HDC hdc, const int* piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
PFNWGLCHOOSEPIXELFORMATPROC fChoosePixelFormat;
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int* piAttributes, int *piValues);
PFNWGLGETPIXELFORMATATTRIBIVPROC fGetPixelFormatAttribiv;
};
bool
WGLWrap::Init()
{
if (fCreatePbuffer)
return true;
SymLoadStruct symbols[] = {
{ (PRFuncPtr*) &fCreatePbuffer, { "wglCreatePbufferARB", "wglCreatePbufferEXT", NULL } },
{ (PRFuncPtr*) &fDestroyPbuffer, { "wglDestroyPbufferARB", "wglDestroyPbufferEXT", NULL } },
{ (PRFuncPtr*) &fGetPbufferDC, { "wglGetPbufferDCARB", "wglGetPbufferDCEXT", NULL } },
{ (PRFuncPtr*) &fChoosePixelFormat, { "wglChoosePixelFormatARB", "wglChoosePixelFormatEXT", NULL } },
{ (PRFuncPtr*) &fGetPixelFormatAttribiv, { "wglGetPixelFormatAttribivARB", "wglGetPixelFormatAttribivEXT", NULL } },
{ NULL, { NULL } }
};
return LoadSymbols(&symbols[0], true);
}
static WGLWrap gWGLWrap;
nsGLPbufferWGL::nsGLPbufferWGL()
: mGlewWindow(nsnull), mGlewDC(nsnull), mGlewWglContext(nsnull),
mPbuffer(nsnull), mPbufferDC(nsnull), mPbufferContext(nsnull)
{
gActiveBuffers++;
fprintf (stderr, "nsGLPbufferWGL: gActiveBuffers: %d\n", gActiveBuffers);
}
PRBool
nsGLPbufferWGL::Init(nsCanvasRenderingContextGLPrivate *priv)
{
// XXX lookup SYSTEM32 path!
char *opengl32 = "C:\\WINDOWS\\SYSTEM32\\OPENGL32.DLL";
if (!gWGLWrap.OpenLibrary(opengl32))
return PR_FALSE;
gWGLWrap.SetLookupFunc((LibrarySymbolLoader::PlatformLookupFunction) wglGetProcAddress);
mPriv = priv;
WNDCLASS wc;
PIXELFORMATDESCRIPTOR pfd;
if (!GetClassInfo(GetModuleHandle(NULL), "GLEW", &wc)) {
ZeroMemory(&wc, sizeof(WNDCLASS));
wc.hInstance = GetModuleHandle(NULL);
wc.lpfnWndProc = DefWindowProc;
wc.lpszClassName = "GLEW";
if (!RegisterClass(&wc)) {
LogMessage(NS_LITERAL_CSTRING("Canvas 3D: RegisterClass failed"));
return PR_FALSE;
}
}
// create window
mGlewWindow = CreateWindow("GLEW", "GLEW", 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, NULL, NULL, GetModuleHandle(NULL), NULL);
if (!mGlewWindow) {
LogMessage(NS_LITERAL_CSTRING("Canvas 3D: CreateWindow failed"));
return PR_FALSE;
}
// get the device context
mGlewDC = GetDC(mGlewWindow);
if (!mGlewDC) {
LogMessage(NS_LITERAL_CSTRING("Canvas 3D: GetDC failed"));
return PR_FALSE;
}
// find default pixel format
ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR));
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
int pixelformat = ChoosePixelFormat(mGlewDC, &pfd);
// set the pixel format for the dc
if (!SetPixelFormat(mGlewDC, pixelformat, &pfd)) {
LogMessage(NS_LITERAL_CSTRING("Canvas 3D: SetPixelFormat failed"));
return PR_FALSE;
}
// create rendering context
mGlewWglContext = wglCreateContext(mGlewDC);
if (!mGlewWglContext) {
LogMessage(NS_LITERAL_CSTRING("Canvas 3D: wglCreateContext failed"));
return PR_FALSE;
}
if (!wglMakeCurrent(mGlewDC, (HGLRC) mGlewWglContext)) {
LogMessage(NS_LITERAL_CSTRING("Canvas 3D: wglMakeCurrent failed"));
return PR_FALSE;
}
// grab all the wgl extension pieces that we couldn't grab before
// we had a context
if (!gWGLWrap.Init())
return PR_FALSE;
// XXX look up system32 dir
if (!mGLWrap.OpenLibrary(opengl32)) {
LogMessage(NS_LITERAL_CSTRING("Canvas 3D: Failed to open opengl32.dll (only looked in c:\\windows\\system32, fixme)"));
return PR_FALSE;
}
mGLWrap.SetLookupFunc((LibrarySymbolLoader::PlatformLookupFunction) wglGetProcAddress);
if (!mGLWrap.Init(GLES20Wrap::TRY_NATIVE_GL)) {
LogMessage(NS_LITERAL_CSTRING("Canvas 3D: GLWrap init failed"));
return PR_FALSE;
}
return PR_TRUE;
}
PRBool
nsGLPbufferWGL::Resize(PRInt32 width, PRInt32 height)
{
if (mWidth == width &&
mHeight == height)
{
return PR_TRUE;
}
Destroy();
nsresult rv;
nsCOMPtr<nsIPrefService> prefService = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, PR_FALSE);
nsCOMPtr<nsIPrefBranch> prefBranch;
rv = prefService->GetBranch("extensions.canvas3d.", getter_AddRefs(prefBranch));
NS_ENSURE_SUCCESS(rv, PR_FALSE);
PRInt32 prefAntialiasing;
rv = prefBranch->GetIntPref("antialiasing", &prefAntialiasing);
if (NS_FAILED(rv))
prefAntialiasing = 0;
mThebesSurface = CanvasGLThebes::CreateImageSurface(gfxIntSize(width, height), gfxASurface::ImageFormatARGB32);
if (mThebesSurface->CairoStatus() != 0) {
fprintf (stderr, "image surface failed\n");
return PR_FALSE;
}
// clear the surface
memset (mThebesSurface->Data(),
0,
height * mThebesSurface->Stride());
if (!wglMakeCurrent(mGlewDC, (HGLRC) mGlewWglContext)) {
fprintf (stderr, "Error: %d\n", GetLastError());
LogMessage(NS_LITERAL_CSTRING("Canvas 3D: wglMakeCurrent failed"));
return PR_FALSE;
}
PRBool ignoreAA = PR_FALSE;
int attribs[] = {
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
WGL_DRAW_TO_PBUFFER_ARB, GL_TRUE,
WGL_DOUBLE_BUFFER_ARB, GL_FALSE,
WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
WGL_COLOR_BITS_ARB, 32,
WGL_RED_BITS_ARB, 8,
WGL_GREEN_BITS_ARB, 8,
WGL_BLUE_BITS_ARB, 8,
WGL_ALPHA_BITS_ARB, 8,
0, 0,
0, 0,
0
};
float fattribs[] = { 0.0f };
// ATI's OpenGL impl seems to have a problem with calling
// wglChoosePixelFormatARB with NULL/0 to obtain the number of
// matching formats; so just allocate room for a lot.
#define MAX_NUM_FORMATS 256
UINT numFormats = MAX_NUM_FORMATS;
nsAutoArrayPtr<int> formats = new int[numFormats];
//fprintf (stderr, "EXT: %p ARB: %p rest: %s\n", wglewGetContext()->__wglewChoosePixelFormatEXT, wglewGetContext()->__wglewChoosePixelFormatARB, wglGetExtensionsStringARB(mGlewDC));
TRY_FIND_AGAIN:
if (ignoreAA) {
attribs[18] = 0;
} else if (prefAntialiasing > 0) {
attribs[18] = WGL_SAMPLE_BUFFERS_ARB;
attribs[19] = 1;
attribs[20] = WGL_SAMPLES_ARB;
attribs[21] = 1 << prefAntialiasing;
}
if (!gWGLWrap.fChoosePixelFormat(mGlewDC,
attribs,
NULL,
numFormats,
formats,
&numFormats) ||
numFormats == 0)
{
if (!ignoreAA) {
ignoreAA = PR_TRUE;
goto TRY_FIND_AGAIN;
}
LogMessage(NS_LITERAL_CSTRING("Canvas 3D: wglChoosePixelFormat failed (or couldn't find any matching formats)."));
ReleaseDC(NULL, mGlewDC);
return PR_FALSE;
}
int chosenFormat = -1;
int question,answer;
for (int priority = 6; priority > 0; priority--) {
//fprintf (stderr, "---- priority: %d\n", priority);
for (UINT i = 0; i < numFormats; i++) {
int fmt = formats[i];
#define CHECK_ATTRIB(q, test) \
question = (q); \
if (!gWGLWrap.fGetPixelFormatAttribiv(mGlewDC, fmt, 0, 1, &question, &answer)) { \
/*fprintf (stderr, "check for %d failed\n", q);*/ \
continue; \
} \
/*fprintf (stderr, #q " -> %d\n", answer);*/ \
if (test) { \
continue; \
}
//fprintf (stderr, "Format %d:\n", fmt);
switch (priority) {
case 6:
CHECK_ATTRIB(WGL_ACCUM_BITS_ARB, answer != 0)
case 5:
CHECK_ATTRIB(WGL_STENCIL_BITS_ARB, answer != 0)
// XXX we only pick 2xAA here, should let user choose
case 4:
CHECK_ATTRIB(WGL_SAMPLE_BUFFERS_ARB, answer != (prefAntialiasing != 0))
case 3:
CHECK_ATTRIB(WGL_SAMPLES_ARB, answer != (prefAntialiasing ? (1 << prefAntialiasing) : 0))
case 2:
CHECK_ATTRIB(WGL_DEPTH_BITS_ARB, answer < 8)
case 1:
CHECK_ATTRIB(WGL_COLOR_BITS_ARB, answer != 32)
default:
chosenFormat = fmt;
}
#undef CHECK_ATTRIB
}
if (chosenFormat != -1)
break;
}
if (chosenFormat == -1) {
LogMessage(NS_LITERAL_CSTRING("Canvas 3D: Couldn't find a suitable pixel format!"));
return PR_FALSE;
}
// ok, we now have a pixel format
fprintf (stderr, "***** Chose pixel format: %d\n", chosenFormat);
int pbattribs = 0;
mPbuffer = gWGLWrap.fCreatePbuffer(mGlewDC, chosenFormat, width, height, &pbattribs);
if (!mPbuffer) {
LogMessage(NS_LITERAL_CSTRING("Canvas 3D: Failed to create pbuffer"));
return PR_FALSE;
}
mPbufferDC = gWGLWrap.fGetPbufferDC(mPbuffer);
mPbufferContext = wglCreateContext(mPbufferDC);
mWindowsSurface = new gfxWindowsSurface(gfxIntSize(width, height), gfxASurface::ImageFormatARGB32);
if (mWindowsSurface && mWindowsSurface->CairoStatus() == 0)
mThebesSurface = mWindowsSurface->GetImageSurface();
mWidth = width;
mHeight = height;
fprintf (stderr, "Resize: %d %d\n", width, height);
return PR_TRUE;
}
void
nsGLPbufferWGL::Destroy()
{
sCurrentContextToken = nsnull;
mThebesSurface = nsnull;
if (mPbuffer) {
wglDeleteContext((HGLRC) mPbufferContext);
gWGLWrap.fDestroyPbuffer(mPbuffer);
mPbuffer = nsnull;
}
}
nsGLPbufferWGL::~nsGLPbufferWGL()
{
Destroy();
if (mGlewWglContext) {
wglDeleteContext((HGLRC) mGlewWglContext);
mGlewWglContext = nsnull;
}
if (mGlewWindow) {
DestroyWindow(mGlewWindow);
mGlewWindow = nsnull;
}
gActiveBuffers--;
fprintf (stderr, "nsGLPbufferWGL: gActiveBuffers: %d\n", gActiveBuffers);
fflush (stderr);
}
void
nsGLPbufferWGL::MakeContextCurrent()
{
if (sCurrentContextToken == mPbufferContext)
return;
wglMakeCurrent (mPbufferDC, (HGLRC) mPbufferContext);
sCurrentContextToken = mPbufferContext;
}
void
nsGLPbufferWGL::SwapBuffers()
{
MakeContextCurrent();
mGLWrap.fReadPixels (0, 0, mWidth, mHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, mThebesSurface->Data());
// premultiply the image
int len = mWidth*mHeight*4;
unsigned char *src = mThebesSurface->Data();
Premultiply(src, len);
}
gfxASurface*
nsGLPbufferWGL::ThebesSurface()
{
return mThebesSurface;
}

View File

@ -100,7 +100,7 @@ nsresult
NS_NewDOMSVGZoomEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsGUIEvent* aEvent);
#endif // MOZ_SVG
nsresult
NS_NewDOMXULCommandEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsXULCommandEvent* aEvent);
NS_NewDOMXULCommandEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsInputEvent* aEvent);
nsresult
NS_NewDOMCommandEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, nsCommandEvent* aEvent);
nsresult

View File

@ -184,9 +184,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMEvent)
static_cast<nsDragEvent*>(tmp->mEvent)->dataTransfer = nsnull;
static_cast<nsMouseEvent_base*>(tmp->mEvent)->relatedTarget = nsnull;
break;
case NS_XUL_COMMAND_EVENT:
static_cast<nsXULCommandEvent*>(tmp->mEvent)->sourceEvent = nsnull;
break;
case NS_MUTATION_EVENT:
static_cast<nsMutationEvent*>(tmp->mEvent)->mRelatedNode = nsnull;
break;
@ -220,11 +217,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMEvent)
cb.NoteXPCOMChild(
static_cast<nsMouseEvent_base*>(tmp->mEvent)->relatedTarget);
break;
case NS_XUL_COMMAND_EVENT:
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEvent->sourceEvent");
cb.NoteXPCOMChild(
static_cast<nsXULCommandEvent*>(tmp->mEvent)->sourceEvent);
break;
case NS_MUTATION_EVENT:
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEvent->mRelatedNode");
cb.NoteXPCOMChild(
@ -588,7 +580,7 @@ nsDOMEvent::SetEventType(const nsAString& aEventTypeArg)
mEvent->message = NS_UI_FOCUSOUT;
else if (atom == nsGkAtoms::oninput)
mEvent->message = NS_FORM_INPUT;
} else if (mEvent->eventStructType == NS_XUL_COMMAND_EVENT) {
} else if (mEvent->eventStructType == NS_INPUT_EVENT) {
if (atom == nsGkAtoms::oncommand)
mEvent->message = NS_XUL_COMMAND;
}
@ -958,16 +950,6 @@ NS_METHOD nsDOMEvent::DuplicatePrivateData()
break;
}
#endif // MOZ_SVG
case NS_XUL_COMMAND_EVENT:
{
newEvent = new nsXULCommandEvent(PR_FALSE, msg, nsnull);
NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
isInputEvent = PR_TRUE;
newEvent->eventStructType = NS_XUL_COMMAND_EVENT;
static_cast<nsXULCommandEvent*>(newEvent)->sourceEvent =
static_cast<nsXULCommandEvent*>(mEvent)->sourceEvent;
break;
}
case NS_SIMPLE_GESTURE_EVENT:
{
nsSimpleGestureEvent* oldSimpleGestureEvent = static_cast<nsSimpleGestureEvent*>(mEvent);
@ -1130,6 +1112,9 @@ nsDOMEvent::GetEventPopupControlState(nsEvent *aEvent)
if (::PopupAllowedForEvent("change"))
abuse = openControlled;
break;
case NS_XUL_COMMAND:
abuse = openControlled;
break;
}
}
break;
@ -1211,10 +1196,6 @@ nsDOMEvent::GetEventPopupControlState(nsEvent *aEvent)
}
}
break;
case NS_XUL_COMMAND_EVENT :
if (nsEventStateManager::IsHandlingUserInput()) {
abuse = openControlled;
}
}
return abuse;

View File

@ -196,6 +196,15 @@ nsDOMMouseEvent::GetRelatedTarget(nsIDOMEventTarget** aRelatedTarget)
}
if (relatedTarget) {
nsCOMPtr<nsIContent> content = do_QueryInterface(relatedTarget);
if (content && content->IsInNativeAnonymousSubtree() &&
!nsContentUtils::CanAccessNativeAnon()) {
relatedTarget = content->FindFirstNonNativeAnonymous();
if (!relatedTarget) {
return NS_OK;
}
}
CallQueryInterface(relatedTarget, aRelatedTarget);
}
return NS_OK;

View File

@ -40,9 +40,9 @@
#include "nsContentUtils.h"
nsDOMXULCommandEvent::nsDOMXULCommandEvent(nsPresContext* aPresContext,
nsXULCommandEvent* aEvent)
nsInputEvent* aEvent)
: nsDOMUIEvent(aPresContext,
aEvent ? aEvent : new nsXULCommandEvent(PR_FALSE, 0, nsnull))
aEvent ? aEvent : new nsInputEvent(PR_FALSE, 0, nsnull))
{
if (aEvent) {
mEventIsInternal = PR_FALSE;
@ -53,19 +53,22 @@ nsDOMXULCommandEvent::nsDOMXULCommandEvent(nsPresContext* aPresContext,
}
}
nsDOMXULCommandEvent::~nsDOMXULCommandEvent()
{
if (mEventIsInternal) {
nsXULCommandEvent* command = static_cast<nsXULCommandEvent*>(mEvent);
delete command;
mEvent = nsnull;
}
}
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMXULCommandEvent)
NS_IMPL_ADDREF_INHERITED(nsDOMXULCommandEvent, nsDOMUIEvent)
NS_IMPL_RELEASE_INHERITED(nsDOMXULCommandEvent, nsDOMUIEvent)
NS_INTERFACE_MAP_BEGIN(nsDOMXULCommandEvent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMXULCommandEvent,
nsDOMUIEvent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mSourceEvent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMXULCommandEvent,
nsDOMUIEvent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mSourceEvent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMXULCommandEvent)
NS_INTERFACE_MAP_ENTRY(nsIDOMXULCommandEvent)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(XULCommandEvent)
NS_INTERFACE_MAP_END_INHERITING(nsDOMUIEvent)
@ -106,7 +109,7 @@ NS_IMETHODIMP
nsDOMXULCommandEvent::GetSourceEvent(nsIDOMEvent** aSourceEvent)
{
NS_ENSURE_ARG_POINTER(aSourceEvent);
NS_IF_ADDREF(*aSourceEvent = Event()->sourceEvent);
NS_IF_ADDREF(*aSourceEvent = mSourceEvent);
return NS_OK;
}
@ -123,12 +126,12 @@ nsDOMXULCommandEvent::InitCommandEvent(const nsAString& aType,
aView, aDetail);
NS_ENSURE_SUCCESS(rv, rv);
nsXULCommandEvent *event = Event();
nsInputEvent *event = Event();
event->isControl = aCtrlKey;
event->isAlt = aAltKey;
event->isShift = aShiftKey;
event->isMeta = aMetaKey;
event->sourceEvent = aSourceEvent;
mSourceEvent = aSourceEvent;
return NS_OK;
}
@ -136,7 +139,7 @@ nsDOMXULCommandEvent::InitCommandEvent(const nsAString& aType,
nsresult NS_NewDOMXULCommandEvent(nsIDOMEvent** aInstancePtrResult,
nsPresContext* aPresContext,
nsXULCommandEvent *aEvent)
nsInputEvent *aEvent)
{
nsDOMXULCommandEvent* it = new nsDOMXULCommandEvent(aPresContext, aEvent);
if (nsnull == it) {

View File

@ -48,20 +48,22 @@ class nsDOMXULCommandEvent : public nsDOMUIEvent,
public nsIDOMXULCommandEvent
{
public:
nsDOMXULCommandEvent(nsPresContext* aPresContext, nsXULCommandEvent* aEvent);
virtual ~nsDOMXULCommandEvent();
nsDOMXULCommandEvent(nsPresContext* aPresContext, nsInputEvent* aEvent);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMXULCommandEvent, nsDOMUIEvent)
NS_DECL_NSIDOMXULCOMMANDEVENT
// Forward our inherited virtual methods to the base class
NS_FORWARD_TO_NSDOMUIEVENT
private:
protected:
// Convenience accessor for the event
nsXULCommandEvent* Event() {
return static_cast<nsXULCommandEvent*>(mEvent);
nsInputEvent* Event() {
return static_cast<nsInputEvent*>(mEvent);
}
nsCOMPtr<nsIDOMEvent> mSourceEvent;
};
#endif // nsDOMXULCommandEvent_h_

View File

@ -650,10 +650,6 @@ nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
static_cast<nsGUIEvent*>(aEvent));
#endif // MOZ_SVG
case NS_XUL_COMMAND_EVENT:
return NS_NewDOMXULCommandEvent(aDOMEvent, aPresContext,
static_cast<nsXULCommandEvent*>
(aEvent));
case NS_COMMAND_EVENT:
return NS_NewDOMCommandEvent(aDOMEvent, aPresContext,
static_cast<nsCommandEvent*>(aEvent));

View File

@ -51,7 +51,6 @@
#include "nsIDOMLoadListener.h"
#include "nsIDOMTextListener.h"
#include "nsIDOMCompositionListener.h"
#include "nsIDOMXULListener.h"
#include "nsIDOMUIListener.h"
#include "nsITextControlFrame.h"
#ifdef MOZ_SVG
@ -244,17 +243,6 @@ static const EventDispatchData sLoadEvents[] = {
{ NS_BEFORE_PAGE_UNLOAD, HANDLER(&nsIDOMLoadListener::BeforeUnload) }
};
static const EventDispatchData sXULEvents[] = {
{ NS_XUL_POPUP_SHOWING, HANDLER(&nsIDOMXULListener::PopupShowing) },
{ NS_XUL_POPUP_SHOWN, HANDLER(&nsIDOMXULListener::PopupShown) },
{ NS_XUL_POPUP_HIDING, HANDLER(&nsIDOMXULListener::PopupHiding) },
{ NS_XUL_POPUP_HIDDEN, HANDLER(&nsIDOMXULListener::PopupHidden) },
{ NS_XUL_CLOSE, HANDLER(&nsIDOMXULListener::Close) },
{ NS_XUL_COMMAND, HANDLER(&nsIDOMXULListener::Command) },
{ NS_XUL_BROADCAST, HANDLER(&nsIDOMXULListener::Broadcast) },
{ NS_XUL_COMMAND_UPDATE, HANDLER(&nsIDOMXULListener::CommandUpdate) }
};
static const EventDispatchData sUIEvents[] = {
{ NS_UI_ACTIVATE, HANDLER(&nsIDOMUIListener::Activate) },
{ NS_UI_FOCUSIN, HANDLER(&nsIDOMUIListener::FocusIn) },
@ -280,7 +268,6 @@ static const EventTypeData sEventTypes[] = {
IMPL_EVENTTYPEDATA(Form),
IMPL_EVENTTYPEDATA(Text),
IMPL_EVENTTYPEDATA(Composition),
IMPL_EVENTTYPEDATA(XUL),
IMPL_EVENTTYPEDATA(UI)
};
@ -288,8 +275,6 @@ static const EventTypeData sEventTypes[] = {
nsIDOMEventGroup* gSystemEventGroup = nsnull;
nsIDOMEventGroup* gDOM2EventGroup = nsnull;
nsDataHashtable<nsISupportsHashKey, PRUint32>* gEventIdTable = nsnull;
PRUint32 nsEventListenerManager::mInstanceCount = 0;
PRUint32 nsEventListenerManager::sCreatedCount = 0;
@ -309,8 +294,6 @@ nsEventListenerManager::~nsEventListenerManager()
if(mInstanceCount == 0) {
NS_IF_RELEASE(gSystemEventGroup);
NS_IF_RELEASE(gDOM2EventGroup);
delete gEventIdTable;
gEventIdTable = nsnull;
}
}

View File

@ -356,6 +356,12 @@ nsXMLEventsManager::CharacterDataChanged(nsIDocument* aDocument,
nsIContent* aContent,
CharacterDataChangeInfo* aInfo) {}
void
nsXMLEventsManager::AttributeWillChange(nsIDocument* aDocument,
nsIContent* aContent,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aModType) {}
void
nsXMLEventsManager::AttributeChanged(nsIDocument* aDocument,
nsIContent* aContent,
PRInt32 aNameSpaceID,

View File

@ -78,7 +78,7 @@ public:
// nsGenericElement
virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
PRBool aNotify);
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent = PR_TRUE);
// nsIContent
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
@ -185,10 +185,11 @@ nsHTMLOptGroupElement::InsertChildAt(nsIContent* aKid,
}
nsresult
nsHTMLOptGroupElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
nsHTMLOptGroupElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent)
{
NS_ASSERTION(aMutationEvent, "Someone tried to inhibit mutation events on optgroup child removal.");
nsSafeOptionListMutation safeMutation(GetSelect(), this, nsnull, aIndex);
nsresult rv = nsGenericHTMLElement::RemoveChildAt(aIndex, aNotify);
nsresult rv = nsGenericHTMLElement::RemoveChildAt(aIndex, aNotify, aMutationEvent);
if (NS_FAILED(rv)) {
safeMutation.MutationFailed();
}

View File

@ -208,10 +208,11 @@ nsHTMLSelectElement::InsertChildAt(nsIContent* aKid,
}
nsresult
nsHTMLSelectElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
nsHTMLSelectElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent)
{
NS_ASSERTION(aMutationEvent, "Someone tried to inhibit mutations on select child removal.");
nsSafeOptionListMutation safeMutation(this, this, nsnull, aIndex);
nsresult rv = nsGenericHTMLFormElement::RemoveChildAt(aIndex, aNotify);
nsresult rv = nsGenericHTMLFormElement::RemoveChildAt(aIndex, aNotify, aMutationEvent);
if (NS_FAILED(rv)) {
safeMutation.MutationFailed();
}

View File

@ -271,7 +271,7 @@ public:
virtual PRBool IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex);
virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
PRBool aNotify);
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent = PR_TRUE);
// Overriden nsIFormControl methods
NS_IMETHOD_(PRInt32) GetType() const { return NS_FORM_SELECT; }

View File

@ -1,11 +0,0 @@
<html>
<body>
<s>
<form>a</form>
<iframe></iframe>
<script src=a></script>
<form></form>
<table>
<optgroup>
</body>
</html>

View File

@ -1,14 +0,0 @@
<html>
<body>
<s>
<form>a</form>
<iframe></iframe>
</s>
<form></form>
<form>
<select>
<optgroup></optgroup>
</select>
</form>
</body>
</html>

View File

@ -1,4 +0,0 @@
<table>
<th>head</th>
<optgroup></optgroup>
</table>

View File

@ -1,8 +0,0 @@
<form>
<select>
<optgroup></optgroup>
</select>
</form>
<table>
<th>head</th>
</table>

View File

@ -1,16 +0,0 @@
<html>
<head>
<link rel="stylesheet" type="text/css"
href="bug448564_forms.css">
</link>
</head>
<body>
<form>
<table>
<optgroup></optgroup>
</table>
<input type="button" value="button"></input>
</form>
<b>asdf</b>
</body>
</html>

View File

@ -1,17 +0,0 @@
<html>
<head>
<link rel="stylesheet" type="text/css"
href="bug448564_forms.css">
</link>
</head>
<body>
<form>
<select>
<optgroup></optgroup>
</select>
<table></table>
<input type="button" value="button"></input>
</form>
<b>asdf</b>
</body>
</html>

View File

@ -1,10 +1,4 @@
== bug448564-1_malformed.html bug448564-1_well-formed.html
== bug448564-1_malformed.html bug448564-1_ideal.html
== bug448564-2_malformed.html bug448564-2_well-formed.html
== bug448564-3_malformed.html bug448564-3_well-formed.html
== bug448564-4a.html bug448564-4b.html
== bug448564-5_malformed.html bug448564-5_well-formed.html

View File

@ -76,6 +76,7 @@ REQUIRES = xpcom \
plugin \
txtsvc \
uriloader \
html5 \
$(NULL)
CPPSRCS = \

View File

@ -211,8 +211,6 @@ public:
NS_IMETHOD IsEnabled(PRInt32 aTag, PRBool* aReturn);
NS_IMETHOD_(PRBool) IsFormOnStack();
virtual nsresult ProcessMETATag(nsIContent* aContent);
#ifdef DEBUG
// nsIDebugDumpContent
NS_IMETHOD DumpContentModel();
@ -2955,33 +2953,6 @@ HTMLContentSink::ProcessLINKTag(const nsIParserNode& aNode)
return result;
}
/*
* Extends nsContentSink::ProcessMETATag to grab the 'viewport' meta tag. This
* information is ignored by the generic content sink because it only stores
* http-equiv meta tags.
*
* Initially implemented for bug #436083
*/
nsresult
HTMLContentSink::ProcessMETATag(nsIContent *aContent) {
/* Call the superclass method. */
nsContentSink::ProcessMETATag(aContent);
nsresult rv = NS_OK;
/* Look for the viewport meta tag. If we find it, process it and put the
* data into the document header. */
if (aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
nsGkAtoms::viewport, eIgnoreCase)) {
nsAutoString value;
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::content, value);
rv = nsContentUtils::ProcessViewportInfo(mDocument, value);
}
return rv;
}
#ifdef DEBUG
void
HTMLContentSink::ForceReflow()

View File

@ -141,6 +141,7 @@
#include "nsRange.h"
#include "mozAutoDocUpdate.h"
#include "nsCCUncollectableMarker.h"
#include "nsHtml5Module.h"
#include "prprf.h"
#define NS_MAX_DOCUMENT_WRITE_DEPTH 20
@ -654,6 +655,11 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
PRBool aReset,
nsIContentSink* aSink)
{
PRBool loadAsHtml5 = nsHtml5Module::Enabled;
if (aSink) {
loadAsHtml5 = PR_FALSE;
}
nsCAutoString contentType;
aChannel->GetContentType(contentType);
@ -663,6 +669,11 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
mIsRegularHTML = PR_FALSE;
mCompatMode = eCompatibility_FullStandards;
loadAsHtml5 = PR_FALSE;
}
if (!(contentType.Equals("text/html") && aCommand && !nsCRT::strcmp(aCommand, "view"))) {
loadAsHtml5 = PR_FALSE;
}
#ifdef DEBUG
else {
@ -709,8 +720,12 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
}
if (needsParser) {
mParser = do_CreateInstance(kCParserCID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
if (loadAsHtml5) {
mParser = nsHtml5Module::NewHtml5Parser();
} else {
mParser = do_CreateInstance(kCParserCID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
}
}
PRInt32 textType = GET_BIDI_OPTION_TEXTTYPE(GetBidiOptions());
@ -925,9 +940,10 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
// create the content sink
nsCOMPtr<nsIContentSink> sink;
if (aSink)
if (aSink) {
NS_ASSERTION((!loadAsHtml5), "Panic: We are loading as HTML5 and someone tries to set an external sink!");
sink = aSink;
else {
} else {
if (IsXHTML()) {
nsCOMPtr<nsIXMLContentSink> xmlsink;
rv = NS_NewXMLContentSink(getter_AddRefs(xmlsink), this, uri,
@ -935,12 +951,17 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
sink = xmlsink;
} else {
nsCOMPtr<nsIHTMLContentSink> htmlsink;
if (loadAsHtml5) {
nsHtml5Module::Initialize(mParser, this, uri, docShell, aChannel);
sink = mParser->GetContentSink();
} else {
nsCOMPtr<nsIHTMLContentSink> htmlsink;
rv = NS_NewHTMLContentSink(getter_AddRefs(htmlsink), this, uri,
docShell, aChannel);
rv = NS_NewHTMLContentSink(getter_AddRefs(htmlsink), this, uri,
docShell, aChannel);
sink = htmlsink;
sink = htmlsink;
}
}
NS_ENSURE_SUCCESS(rv, rv);
@ -1784,6 +1805,8 @@ nsHTMLDocument::OpenCommon(const nsACString& aContentType, PRBool aReplace)
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
}
PRBool loadAsHtml5 = nsHtml5Module::Enabled;
nsresult rv = NS_OK;
// If we already have a parser we ignore the document.open call.
@ -1935,7 +1958,12 @@ nsHTMLDocument::OpenCommon(const nsACString& aContentType, PRBool aReplace)
// resetting the document.
mSecurityInfo = securityInfo;
mParser = do_CreateInstance(kCParserCID, &rv);
if (loadAsHtml5) {
mParser = nsHtml5Module::NewHtml5Parser();
rv = NS_OK;
} else {
mParser = do_CreateInstance(kCParserCID, &rv);
}
// This will be propagated to the parser when someone actually calls write()
mContentType = aContentType;
@ -1943,18 +1971,22 @@ nsHTMLDocument::OpenCommon(const nsACString& aContentType, PRBool aReplace)
mWriteState = eDocumentOpened;
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIHTMLContentSink> sink;
if (loadAsHtml5) {
nsHtml5Module::Initialize(mParser, this, uri, shell, channel);
} else {
nsCOMPtr<nsIHTMLContentSink> sink;
rv = NS_NewHTMLContentSink(getter_AddRefs(sink), this, uri, shell,
channel);
if (NS_FAILED(rv)) {
// Don't use a parser without a content sink.
mParser = nsnull;
mWriteState = eNotWriting;
return rv;
rv = NS_NewHTMLContentSink(getter_AddRefs(sink), this, uri, shell,
channel);
if (NS_FAILED(rv)) {
// Don't use a parser without a content sink.
mParser = nsnull;
mWriteState = eNotWriting;
return rv;
}
mParser->SetContentSink(sink);
}
mParser->SetContentSink(sink);
}
// Prepare the docshell and the document viewer for the impending

View File

@ -0,0 +1,52 @@
#
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is
# Netscape Communications Corporation.
# Portions created by the Initial Developer are Copyright (C) 1998
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the terms of
# either of the GNU General Public License Version 2 or later (the "GPL"),
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = public src
# ifdef ENABLE_TESTS
# DIRS += test
# endif
include $(topsrcdir)/config/rules.mk

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,484 @@
/*
* Copyright (c) 2007 Henri Sivonen
* Copyright (c) 2008-2009 Mozilla Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package nu.validator.htmlparser.impl;
import nu.validator.htmlparser.annotation.IdType;
import nu.validator.htmlparser.annotation.Local;
import nu.validator.htmlparser.annotation.NsUri;
import nu.validator.htmlparser.annotation.Prefix;
import nu.validator.htmlparser.annotation.QName;
import nu.validator.htmlparser.common.XmlViolationPolicy;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
/**
* Be careful with this class. QName is the name in from HTML tokenization.
* Otherwise, please refer to the interface doc.
*
* @version $Id: AttributesImpl.java 206 2008-03-20 14:09:29Z hsivonen $
* @author hsivonen
*/
public final class HtmlAttributes implements Attributes {
// [NOCPP[
private static final AttributeName[] EMPTY_ATTRIBUTENAMES = new AttributeName[0];
private static final String[] EMPTY_STRINGS = new String[0];
// ]NOCPP]
public static final HtmlAttributes EMPTY_ATTRIBUTES = new HtmlAttributes(
AttributeName.HTML);
private int mode;
private int length;
private AttributeName[] names;
private String[] values; // XXX perhaps make this @NoLength?
// [NOCPP[
private String idValue;
private int xmlnsLength;
private AttributeName[] xmlnsNames;
private String[] xmlnsValues;
// ]NOCPP]
public HtmlAttributes(int mode) {
this.mode = mode;
this.length = 0;
this.names = new AttributeName[5]; // covers 98.3% of elements
// according to
// Hixie
this.values = new String[5];
// [NOCPP[
this.idValue = null;
this.xmlnsLength = 0;
this.xmlnsNames = HtmlAttributes.EMPTY_ATTRIBUTENAMES;
this.xmlnsValues = HtmlAttributes.EMPTY_STRINGS;
// ]NOCPP]
}
/*
public HtmlAttributes(HtmlAttributes other) {
this.mode = other.mode;
this.length = other.length;
this.names = new AttributeName[other.length];
this.values = new String[other.length];
// [NOCPP[
this.idValue = other.idValue;
this.xmlnsLength = other.xmlnsLength;
this.xmlnsNames = new AttributeName[other.xmlnsLength];
this.xmlnsValues = new String[other.xmlnsLength];
// ]NOCPP]
}
*/
void destructor() {
clear(0);
Portability.releaseArray(names);
Portability.releaseArray(values);
}
/**
* Only use with a static argument
*
* @param name
* @return
*/
public int getIndex(AttributeName name) {
for (int i = 0; i < length; i++) {
if (names[i] == name) {
return i;
}
}
return -1;
}
// [NOCPP[
public int getIndex(String qName) {
for (int i = 0; i < length; i++) {
if (names[i].getQName(mode).equals(qName)) {
return i;
}
}
return -1;
}
public int getIndex(String uri, String localName) {
for (int i = 0; i < length; i++) {
if (names[i].getLocal(mode).equals(localName)
&& names[i].getUri(mode).equals(uri)) {
return i;
}
}
return -1;
}
public @IdType String getType(String qName) {
int index = getIndex(qName);
if (index == -1) {
return null;
} else {
return getType(index);
}
}
public @IdType String getType(String uri, String localName) {
int index = getIndex(uri, localName);
if (index == -1) {
return null;
} else {
return getType(index);
}
}
public String getValue(String qName) {
int index = getIndex(qName);
if (index == -1) {
return null;
} else {
return getValue(index);
}
}
public String getValue(String uri, String localName) {
int index = getIndex(uri, localName);
if (index == -1) {
return null;
} else {
return getValue(index);
}
}
// ]NOCPP]
public int getLength() {
return length;
}
public @Local String getLocalName(int index) {
if (index < length && index >= 0) {
return names[index].getLocal(mode);
} else {
return null;
}
}
// [NOCPP[
public @QName String getQName(int index) {
if (index < length && index >= 0) {
return names[index].getQName(mode);
} else {
return null;
}
}
public @IdType String getType(int index) {
if (index < length && index >= 0) {
return names[index].getType(mode);
} else {
return null;
}
}
// ]NOCPP]
public AttributeName getAttributeName(int index) {
if (index < length && index >= 0) {
return names[index];
} else {
return null;
}
}
public @NsUri String getURI(int index) {
if (index < length && index >= 0) {
return names[index].getUri(mode);
} else {
return null;
}
}
public @Prefix String getPrefix(int index) {
if (index < length && index >= 0) {
return names[index].getPrefix(mode);
} else {
return null;
}
}
public String getValue(int index) {
if (index < length && index >= 0) {
return values[index];
} else {
return null;
}
}
/**
* Only use with static argument.
*
* @see org.xml.sax.Attributes#getValue(java.lang.String)
*/
public String getValue(AttributeName name) {
int index = getIndex(name);
if (index == -1) {
return null;
} else {
return getValue(index);
}
}
// [NOCPP[
public String getId() {
return idValue;
}
public int getXmlnsLength() {
return xmlnsLength;
}
public @Local String getXmlnsLocalName(int index) {
if (index < xmlnsLength && index >= 0) {
return xmlnsNames[index].getLocal(mode);
} else {
return null;
}
}
public @NsUri String getXmlnsURI(int index) {
if (index < xmlnsLength && index >= 0) {
return xmlnsNames[index].getUri(mode);
} else {
return null;
}
}
public String getXmlnsValue(int index) {
if (index < xmlnsLength && index >= 0) {
return xmlnsValues[index];
} else {
return null;
}
}
public int getXmlnsIndex(AttributeName name) {
for (int i = 0; i < xmlnsLength; i++) {
if (xmlnsNames[i] == name) {
return i;
}
}
return -1;
}
public String getXmlnsValue(AttributeName name) {
int index = getXmlnsIndex(name);
if (index == -1) {
return null;
} else {
return getXmlnsValue(index);
}
}
public AttributeName getXmlnsAttributeName(int index) {
if (index < xmlnsLength && index >= 0) {
return xmlnsNames[index];
} else {
return null;
}
}
// ]NOCPP]
void addAttribute(AttributeName name, String value
// [NOCPP[
, XmlViolationPolicy xmlnsPolicy
// ]NOCPP]
) throws SAXException {
// [NOCPP[
if (name == AttributeName.ID) {
idValue = value;
}
if (name.isXmlns()) {
if (xmlnsNames.length == xmlnsLength) {
int newLen = xmlnsLength == 0 ? 2 : xmlnsLength << 1;
AttributeName[] newNames = new AttributeName[newLen];
System.arraycopy(xmlnsNames, 0, newNames, 0, xmlnsNames.length);
xmlnsNames = newNames;
String[] newValues = new String[newLen];
System.arraycopy(xmlnsValues, 0, newValues, 0, xmlnsValues.length);
xmlnsValues = newValues;
}
xmlnsNames[xmlnsLength] = name;
xmlnsValues[xmlnsLength] = value;
xmlnsLength++;
switch (xmlnsPolicy) {
case FATAL:
// this is ugly
throw new SAXException("Saw an xmlns attribute.");
case ALTER_INFOSET:
return;
case ALLOW:
// fall through
}
}
// ]NOCPP]
if (names.length == length) {
int newLen = length << 1; // The first growth covers virtually
// 100% of elements according to
// Hixie
AttributeName[] newNames = new AttributeName[newLen];
System.arraycopy(names, 0, newNames, 0, names.length);
Portability.releaseArray(names);
names = newNames;
String[] newValues = new String[newLen];
System.arraycopy(values, 0, newValues, 0, values.length);
Portability.releaseArray(values);
values = newValues;
}
names[length] = name;
values[length] = value;
length++;
}
void clear(int m) {
for (int i = 0; i < length; i++) {
names[i].release();
names[i] = null;
Portability.releaseString(values[i]);
values[i] = null;
}
length = 0;
mode = m;
// [NOCPP[
idValue = null;
for (int i = 0; i < xmlnsLength; i++) {
xmlnsNames[i] = null;
xmlnsValues[i] = null;
}
xmlnsLength = 0;
// ]NOCPP]
}
/**
* This is used in C++ to release special <code>isindex</code>
* attribute values whose ownership is not transferred.
*/
void releaseValue(int i) {
Portability.releaseString(values[i]);
}
/**
* This is only used for <code>AttributeName</code> ownership transfer
* in the isindex case to avoid freeing custom names twice in C++.
*/
void clearWithoutReleasingContents() {
for (int i = 0; i < length; i++) {
names[i] = null;
values[i] = null;
}
length = 0;
}
boolean contains(AttributeName name) {
for (int i = 0; i < length; i++) {
if (name.equalsAnother(names[i])) {
return true;
}
}
// [NOCPP[
for (int i = 0; i < xmlnsLength; i++) {
if (name.equalsAnother(xmlnsNames[i])) {
return true;
}
}
// ]NOCPP]
return false;
}
public void adjustForMath() {
mode = AttributeName.MATHML;
}
public void adjustForSvg() {
mode = AttributeName.SVG;
}
// [NOCPP[
void processNonNcNames(TreeBuilder<?> treeBuilder, XmlViolationPolicy namePolicy) throws SAXException {
for (int i = 0; i < length; i++) {
AttributeName attName = names[i];
if (!attName.isNcName(mode)) {
String name = attName.getLocal(mode);
switch (namePolicy) {
case ALTER_INFOSET:
names[i] = AttributeName.create(NCName.escapeName(name));
// fall through
case ALLOW:
if (attName != AttributeName.XML_LANG) {
treeBuilder.warn("Attribute \u201C" + name + "\u201D is not serializable as XML 1.0.");
}
break;
case FATAL:
treeBuilder.fatal("Attribute \u201C" + name + "\u201D is not serializable as XML 1.0.");
break;
}
}
}
}
public void merge(HtmlAttributes attributes) throws SAXException {
int len = attributes.getLength();
for (int i = 0; i < len; i++) {
AttributeName name = attributes.getAttributeName(i);
if (!contains(name)) {
addAttribute(name, attributes.getValue(i), XmlViolationPolicy.ALLOW);
}
}
}
// ]NOCPP]
}

Some files were not shown because too many files have changed in this diff Show More