зеркало из https://github.com/mozilla/gecko-dev.git
Merge changes from mozilla-central to electrolysis
This commit is contained in:
Коммит
e527ef540e
|
@ -73,11 +73,5 @@ XPIDLSRCS = \
|
|||
nsIXBLAccessible.idl \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_XUL
|
||||
XPIDLSRCS += \
|
||||
nsIAccessibleTreeCache.idl \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
@ -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)
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -178,7 +178,7 @@ enum eStateMapEntryID
|
|||
eARIAReadonly,
|
||||
eARIAReadonlyOrEditable,
|
||||
eARIARequired,
|
||||
eARIASelected
|
||||
eARIASelectable
|
||||
};
|
||||
|
||||
class nsStateMapEntry
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();"/>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -641,9 +641,7 @@ msvcr80.dll
|
|||
#else
|
||||
mozcrt19.dll
|
||||
#endif
|
||||
xpicleanup.exe
|
||||
#else
|
||||
xpicleanup
|
||||
#endif
|
||||
xpicleanup@BIN_SUFFIX@
|
||||
chrome.manifest
|
||||
install.rdf
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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@
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
24
configure.in
24
configure.in
|
@ -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 ========================================================
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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, \
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -84,6 +84,7 @@ REQUIRES = xpcom \
|
|||
shistory \
|
||||
editor \
|
||||
windowwatcher \
|
||||
html5 \
|
||||
$(NULL)
|
||||
|
||||
ifdef ACCESSIBILITY
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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">
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
|
@ -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);
|
||||
});
|
|
@ -49,4 +49,8 @@ EXPORTS = \
|
|||
nsICanvasElement.h \
|
||||
$(NULL)
|
||||
|
||||
XPIDLSRCS = \
|
||||
nsICanvasGLPrivate.idl \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -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
|
||||
{
|
||||
};
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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)
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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_ */
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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);
|
||||
}
|
|
@ -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_ */
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
<html>
|
||||
<body>
|
||||
<s>
|
||||
<form>a</form>
|
||||
<iframe></iframe>
|
||||
<script src=a></script>
|
||||
<form></form>
|
||||
<table>
|
||||
<optgroup>
|
||||
</body>
|
||||
</html>
|
|
@ -1,14 +0,0 @@
|
|||
<html>
|
||||
<body>
|
||||
<s>
|
||||
<form>a</form>
|
||||
<iframe></iframe>
|
||||
</s>
|
||||
<form></form>
|
||||
<form>
|
||||
<select>
|
||||
<optgroup></optgroup>
|
||||
</select>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -1,4 +0,0 @@
|
|||
<table>
|
||||
<th>head</th>
|
||||
<optgroup></optgroup>
|
||||
</table>
|
|
@ -1,8 +0,0 @@
|
|||
<form>
|
||||
<select>
|
||||
<optgroup></optgroup>
|
||||
</select>
|
||||
</form>
|
||||
<table>
|
||||
<th>head</th>
|
||||
</table>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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
|
||||
|
|
|
@ -76,6 +76,7 @@ REQUIRES = xpcom \
|
|||
plugin \
|
||||
txtsvc \
|
||||
uriloader \
|
||||
html5 \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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]
|
||||
|
||||
}
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче