Bug 154327, cache newly created objects in MAI. This is for the Mozilla Accessiblity on Unix/Linux. It will not be included in the Default build of Mozilla.

This commit is contained in:
bolian.yin%sun.com 2002-08-22 02:52:04 +00:00
Родитель dd6037ac4b
Коммит 1ea72021f0
18 изменённых файлов: 603 добавлений и 1000 удалений

Просмотреть файл

@ -51,6 +51,7 @@ EXPORT_LIBRARY = 1
REQUIRES = xpcom \
string \
dom \
necko \
accessibility
# Add you C source file here
@ -67,11 +68,23 @@ CPPSRCS = \
nsMaiTopLevel.cpp \
nsMaiWidget.cpp \
nsMaiInterfaceComponent.cpp \
nsMaiInterfaceAction.cpp \
nsMaiInterfaceValue.cpp \
nsMaiInterfaceSelection.cpp \
nsMaiInterfaceHypertext.cpp \
nsMaiInterfaceTable.cpp \
nsMaiInterfaceText.cpp \
nsMaiInterfaceEditableText.cpp \
nsMaiHyperlink.cpp \
$(NULL)
EXTRA_DSO_LDOPTS += $(MOZ_GTK2_LIBS) \
-L.. -lwidget_gtk2
# Add you header files need to be exported here
EXPORTS = \
$(NULL)
include $(topsrcdir)/config/rules.mk
CFLAGS += $(MOZ_GTK2_CFLAGS)

Просмотреть файл

@ -49,6 +49,7 @@ MaiAppRoot::MaiAppRoot()
/* for mai root, mAccessible is always NULL */
mTopLevelList = NULL;
mMaiCache = new MaiCache();
NS_ASSERTION(mMaiCache, "Fail to create MaiCache");
}
MaiAppRoot::~MaiAppRoot()
@ -69,9 +70,13 @@ MaiAppRoot::~MaiAppRoot()
g_object_unref(maiTopLevel->GetAtkObject());
}
g_list_free(tmp_list2);
mTopLevelList = NULL;
}
if (mMaiCache)
if (mMaiCache) {
delete mMaiCache;
mMaiCache = NULL;
}
}
#ifdef MAI_LOGGING
@ -81,20 +86,24 @@ MaiAppRoot::DumpMaiObjectInfo(int aDepth)
--aDepth;
if (aDepth < 0)
return;
g_print("<<<<<Begin of MaiObject: this=0x%x, aDepth=%d, type=%s\n",
g_print("MaiAppRoot: this=0x%x, aDepth=%d, type=%s\n",
(unsigned int)this, aDepth, "MaiAppRoot");
gint nChild = GetChildCount();
g_print("== %d toplevel children\n", nChild);
g_print("#child=%d<br>\n", nChild);
g_print("Iface num: 1=component, 2=action, 3=value, 4=editabletext,"
"5=hyperlink, 6=hypertext, 7=selection, 8=table, 9=text\n");
g_print("<ul>\n");
MaiObject *maiChild;
for (int childIndex = 0; childIndex < nChild; childIndex++) {
maiChild = RefChild(childIndex);
if (maiChild) {
g_print(" <li>");
maiChild->DumpMaiObjectInfo(aDepth);
}
}
g_print(">>>>>End of MaiObject: this=0x%x, type=%s\n",
g_print("</ul>\n");
g_print("End of MaiAppRoot: this=0x%x, type=%s\n<br>",
(unsigned int)this, "MaiAppRoot");
}
#endif
@ -111,17 +120,20 @@ gboolean
MaiAppRoot::AddMaiTopLevel(MaiTopLevel *aTopLevel)
{
g_return_val_if_fail(aTopLevel != NULL, FALSE);
MAI_LOG_DEBUG(("MaiAppRoot: add MaiTopLevel = 0x%x", (guint)aTopLevel));
/* if the nsIAccessible with the same UniqueID is already added,
* we only add atk object ref of the one in list, not really
* add the new mai object. They are think to be same (??)
* we only increase the count of this item in the list.
* They are same.
*/
TopLevelItem *item = FindTopLevelItem(aTopLevel->GetNSAccessible());
if (!item) {
MAI_LOG_DEBUG(("MaiAppRoot: new item created\n"));
item = new TopLevelItem();
item->ref = 1;
NS_ASSERTION(item, "Fail to create TopLevelItem");
item->ref = 0;
item->maiTopLevel = aTopLevel;
mTopLevelList = g_list_append(mTopLevelList, item);
@ -132,6 +144,8 @@ MaiAppRoot::AddMaiTopLevel(MaiTopLevel *aTopLevel)
}
}
item->ref++;
MAI_LOG_DEBUG(("MaiAppRoot: item ref = %d\n", item->ref));
return TRUE;
}
@ -139,14 +153,18 @@ gboolean
MaiAppRoot::RemoveMaiTopLevel(MaiTopLevel *aTopLevel)
{
g_return_val_if_fail(aTopLevel != NULL, TRUE);
MAI_LOG_DEBUG(("MaiAppRoot: remove MaiTopLevel = 0x%x", (guint)aTopLevel));
TopLevelItem *item = FindTopLevelItem(aTopLevel->GetNSAccessible());
if (!item)
return FALSE;
item->ref--;
MAI_LOG_DEBUG(("MaiAppRoot: item ref = %d\n", item->ref));
if (item->ref == 0) {
mTopLevelList = g_list_remove(mTopLevelList, item);
g_object_unref(item->maiTopLevel->GetAtkObject());
delete item;
MAI_LOG_DEBUG(("MaiAppRoot: Toplevel deleted\n"));
}
return TRUE;
}
@ -185,7 +203,8 @@ MaiAppRoot::FindTopLevelItem(nsIAccessible *aTopLevel)
while (tmp_list) {
item = (TopLevelItem*)tmp_list->data;
tmp_list = tmp_list->next;
if (item->maiTopLevel->GetNSAccessibleUniqueID() ==
if (item && item->maiTopLevel &&
item->maiTopLevel->GetNSAccessibleUniqueID() ==
::GetNSAccessibleUniqueID(aTopLevel))
return item;
}

Просмотреть файл

@ -84,11 +84,11 @@ public:
MaiCache *GetCache(void);
public:
/* virtual functions for MaiObject */
virtual AtkObject *GetAtkObject(void);
virtual void Initialize(void);
virtual void Finalize(void);
/* virtual functions for MaiObject */
virtual gchar *GetName(void);
virtual gchar *GetDescription(void);
virtual MaiObject *GetParent(void);

Просмотреть файл

@ -53,15 +53,17 @@ MaiCache::MaiCache()
MaiCache::~MaiCache()
{
AtkObject *tmpAtkObj = NULL;
for (int index = 0; index < MAI_CACHE_SIZE; index++) {
if (mCache[index].maiObject && mCache[index].uid != 0) {
MAI_LOG_DEBUG(("de-caching : maiObj=0x%x, uid=%x\n",
tmpAtkObj = mCache[index].maiObject->GetAtkObject();
MAI_LOG_DEBUG(("Mai Cache: de-caching, maiAtkObj=0x%x, ref=%d\
maiObj=0x%x, uid=%x\n", (guint)tmpAtkObj,
G_OBJECT(tmpAtkObj)->ref_count,
(guint)mCache[index].maiObject, mCache[index].uid));
g_object_unref(mCache[index].maiObject->GetAtkObject());
g_object_unref(tmpAtkObj);
mCache[index].uid = 0;
mCache[index].maiObject = NULL;
}
}
}
@ -76,7 +78,7 @@ MaiCache::Add(MaiObject *aMaiObj)
// different nsIAccessible object can have the same ID,
// but we deem them equal for accessible user.
if (Fetch(aMaiObj)) {
MAI_LOG_DEBUG(("**Object is already in Cache: aMaiObj=0x%x, uid=%x\n",
MAI_LOG_DEBUG(("Mai Cache: already in Cache: aMaiObj=0x%x, uid=%x\n",
(guint)aMaiObj, aMaiObj->GetNSAccessibleUniqueID()));
return TRUE;
}
@ -84,20 +86,32 @@ MaiCache::Add(MaiObject *aMaiObj)
/* try to find a vacant place */
while (counter < MAI_CACHE_SIZE) {
counter++;
mCacheIndex = (mCacheIndex++) % MAI_CACHE_SIZE;
mCacheIndex = (++mCacheIndex) % MAI_CACHE_SIZE;
if ((mCache[mCacheIndex].maiObject == NULL) &&
(mCache[mCacheIndex].uid == 0))
break;
}
/* if fail to find a vacant place, remove the old */
AtkObject *tmpAtkObj = NULL;
if (counter >= MAI_CACHE_SIZE) {
g_object_unref(mCache[mCacheIndex].maiObject->GetAtkObject());
mCacheIndex = (++mCacheIndex) % MAI_CACHE_SIZE;
tmpAtkObj = mCache[mCacheIndex].maiObject->GetAtkObject();
MAI_LOG_DEBUG(("Mai Cache: de-caching, maiAtkObj=0x%x, ref=%d \
maiObj=0x%x, uid=%x\n", (guint)tmpAtkObj,
G_OBJECT(tmpAtkObj)->ref_count,
(guint)mCache[mCacheIndex].maiObject,
(guint)mCache[mCacheIndex].uid));
MAI_LOG_DEBUG(("Mai Cache: added in %d, replace", mCacheIndex));
g_object_unref(tmpAtkObj);
}
else
MAI_LOG_DEBUG(("Mai Cache: added in %d, vacant", mCacheIndex));
g_object_ref(aMaiObj->GetAtkObject());
mCache[mCacheIndex].uid = aMaiObj->GetNSAccessibleUniqueID();
mCache[mCacheIndex].maiObject = aMaiObj;
MAI_LOG_DEBUG(("Add in Cache: aMaiObj=0x%x, uid=%x\n",
MAI_LOG_DEBUG(("Mai Cache: Add in Cache, aMaiObj=0x%x, uid=%x\n",
(guint)aMaiObj, mCache[mCacheIndex].uid));
return TRUE;

Просмотреть файл

@ -64,7 +64,7 @@ public:
MaiObject *Fetch(AtkObject *aAtkObj);
private:
enum { MAI_CACHE_SIZE = 100 };
enum { MAI_CACHE_SIZE = 10 };
MaiCacheItem mCache [MAI_CACHE_SIZE];
gint mCacheIndex;
};

Просмотреть файл

@ -101,7 +101,7 @@ MaiInterfaceAction::GetActionCount()
PRUint8 num = 0;
nsresult rv = accessible->GetAccNumActions(&num);
return (NS_FAILED(rv)) ? 0 : gint(num);
return (NS_FAILED(rv)) ? 0 : NS_STATIC_CAST(gint, num);
}
const gchar *

Просмотреть файл

@ -1,236 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim:expandtab:shiftwidth=4:tabstop=4:
*/
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 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 Sun Microsystems, Inc.
* Portions created by Sun Microsystems are Copyright (C) 2002 Sun
* Microsystems, Inc. All Rights Reserved.
*
* Original Author: Bolian Yin (bolian.yin@sun.com)
*
* Contributor(s):
*
* 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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsMaiInterfaceComponent.h"
/* helpers */
static MaiInterfaceComponent *getComponent(AtkComponent *aIface);
G_BEGIN_DECLS
/* component interface callbacks */
static void interfaceInitCB(AtkComponentIface *aIface);
static AtkObject *refAccessibleAtPointCB(AtkComponent *aComponent,
gint aAccX, gint aAccY,
AtkCoordType aCoordType);
static void getExtentsCB(AtkComponent *aComponent,
gint *aAccX, gint *aAccY,
gint *aAccWidth, gint *aAccHeight,
AtkCoordType aCoordType);
/* the "contains", "get_position", "get_size" can take advantage of
* "get_extents", there is no need to implement them now.
*/
static gboolean grabFocusCB(AtkComponent *aComponent);
/* what are missing now for atk component */
/* ==================================================
* add_focus_handler
* remove_focus_handler
* set_extents
* set_position
* set_size
* get_layer
* get_mdi_zorder
* ==================================================
*/
G_END_DECLS
MaiInterfaceComponent::MaiInterfaceComponent(MaiWidget *aMaiWidget):
MaiInterface(aMaiWidget)
{
}
MaiInterfaceComponent::~MaiInterfaceComponent()
{
}
MaiInterfaceType
MaiInterfaceComponent::GetType()
{
return MAI_INTERFACE_COMPONENT;
}
const GInterfaceInfo *
MaiInterfaceComponent::GetInterfaceInfo()
{
static const GInterfaceInfo atk_if_component_info = {
(GInterfaceInitFunc)interfaceInitCB,
(GInterfaceFinalizeFunc) NULL,
NULL
};
return &atk_if_component_info;
}
MaiObject *
MaiInterfaceComponent::RefAccessibleAtPoint(gint aAccX, gint aAccY,
AtkCoordType aCoordType)
{
nsIAccessible *accessible = GetNSAccessible();
g_return_val_if_fail(accessible != NULL, NULL);
// or ATK_XY_SCREEN what is definition this in nsIAccessible?
if (aCoordType == ATK_XY_WINDOW) {
/* deal with the coord type */
}
nsCOMPtr<nsIAccessible> pointAcc;
nsresult rv = accessible->AccGetAt(aAccX, aAccY, getter_AddRefs(pointAcc));
if (NS_FAILED(rv))
return NULL;
/* ??? when to free ??? */
MaiWidget *maiWidget = new MaiWidget(pointAcc);
return maiWidget;
}
void
MaiInterfaceComponent::GetExtents(gint *aAccX,
gint *aAccY,
gint *aAccWidth,
gint *aAccHeight,
AtkCoordType aCoordType)
{
nsIAccessible *accessible = GetNSAccessible();
g_return_if_fail(accessible != NULL);
PRInt32 nsAccX, nsAccY, nsAccWidth, nsAccHeight;
nsresult rv = accessible->AccGetBounds(&nsAccX, &nsAccY,
&nsAccWidth, &nsAccHeight);
if (NS_FAILED(rv))
return;
// or ATK_XY_SCREEN what is definition this in nsIAccessible?
if (aCoordType == ATK_XY_WINDOW) {
/* deal with the coord type */
}
*aAccX = nsAccX;
*aAccY = nsAccY;
*aAccWidth = nsAccWidth;
*aAccHeight = nsAccHeight;
}
gboolean
MaiInterfaceComponent::GrabFocus()
{
nsIAccessible *accessible = GetNSAccessible();
g_return_val_if_fail(accessible != NULL, FALSE);
nsresult rv = accessible->AccTakeFocus();
return (NS_FAILED(rv)) ? FALSE : TRUE;
}
/* static functions */
/* do general checking for callbacks functions
* return the MaiInterfaceComponent extracted from atk component
*/
MaiInterfaceComponent *
getComponent(AtkComponent *aComponent)
{
g_return_val_if_fail(MAI_IS_ATK_WIDGET(aComponent), NULL);
MaiWidget *maiWidget = (MaiWidget*)(MAI_ATK_OBJECT(aComponent)->maiObject);
g_return_val_if_fail(maiWidget != NULL, NULL);
g_return_val_if_fail(maiWidget->GetAtkObject() == (AtkObject*)aComponent,
NULL);
MaiInterfaceComponent *maiInterfaceComponent = (MaiInterfaceComponent*)
maiWidget->GetMaiInterface(MAI_INTERFACE_COMPONENT);
return maiInterfaceComponent;
}
void
interfaceInitCB(AtkComponentIface *aIface)
{
g_return_if_fail(aIface != NULL);
/*
* Use default implementation in atk for contains, get_position,
* and get_size
*/
aIface->ref_accessible_at_point = refAccessibleAtPointCB;
aIface->get_extents = getExtentsCB;
aIface->grab_focus = grabFocusCB;
}
AtkObject *
refAccessibleAtPointCB(AtkComponent *aComponent,
gint aAccX, gint aAccY,
AtkCoordType aCoordType)
{
MaiInterfaceComponent *maiInterfaceComponent = getComponent(aComponent);
if (!maiInterfaceComponent)
return NULL;
MaiObject *maiObj =
maiInterfaceComponent->RefAccessibleAtPoint(aAccX, aAccY, aCoordType);
if (!maiObj)
return NULL;
AtkObject *atkObj = maiObj->GetAtkObject();
if (!atkObj)
return NULL;
g_object_ref(atkObj);
return atkObj;
}
void
getExtentsCB(AtkComponent *aComponent,
gint *aAccX,
gint *aAccY,
gint *aAccWidth,
gint *aAccHeight,
AtkCoordType aCoordType)
{
MaiInterfaceComponent *maiInterfaceComponent = getComponent(aComponent);
if (maiInterfaceComponent)
maiInterfaceComponent->GetExtents(aAccX, aAccY, aAccWidth, aAccHeight,
aCoordType);
}
gboolean
grabFocusCB(AtkComponent *aComponent)
{
MaiInterfaceComponent *maiInterfaceComponent = getComponent(aComponent);
if (!maiInterfaceComponent)
return FALSE;
return maiInterfaceComponent->GrabFocus();
}

Просмотреть файл

@ -1,294 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim:expandtab:shiftwidth=4:tabstop=4:
*/
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 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 Sun Microsystems, Inc.
* Portions created by Sun Microsystems are Copyright (C) 2002 Sun
* Microsystems, Inc. All Rights Reserved.
*
* Original Author: Bolian Yin (bolian.yin@sun.com)
*
* Contributor(s):
*
* 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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsString.h"
#include "nsIAccessibleEditableText.h"
#include "nsMaiInterfaceEditableText.h"
/* helpers */
static MaiInterfaceEditableText *getEditableText(AtkEditableText *aIface);
G_BEGIN_DECLS
static void interfaceInitCB(AtkEditableTextIface *aIface);
/* editabletext interface callbacks */
static gboolean setRunAttributesCB(AtkEditableText *aText,
AtkAttributeSet *aAttribSet,
gint aStartOffset,
gint aEndOffset);
static void setTextContentsCB(AtkEditableText *aText, const gchar *aString);
static void insertTextCB(AtkEditableText *aText,
const gchar *aString, gint aLength, gint *aPosition);
static void copyTextCB(AtkEditableText *aText, gint aStartPos, gint aEndPos);
static void cutTextCB(AtkEditableText *aText, gint aStartPos, gint aEndPos);
static void deleteTextCB(AtkEditableText *aText, gint aStartPos, gint aEndPos);
static void pasteTextCB(AtkEditableText *aText, gint aPosition);
G_END_DECLS
MaiInterfaceEditableText::MaiInterfaceEditableText(MaiWidget *aMaiWidget):
MaiInterface(aMaiWidget)
{
}
MaiInterfaceEditableText::~MaiInterfaceEditableText()
{
}
MaiInterfaceType
MaiInterfaceEditableText::GetType()
{
return MAI_INTERFACE_EDITABLE_TEXT;
}
const GInterfaceInfo *
MaiInterfaceEditableText::GetInterfaceInfo()
{
static const GInterfaceInfo atk_if_editabletext_info = {
(GInterfaceInitFunc)interfaceInitCB,
(GInterfaceFinalizeFunc) NULL,
NULL
};
return &atk_if_editabletext_info;
}
#define MAI_IFACE_RETURN_VAL_IF_FAIL(accessIface, value) \
nsCOMPtr<nsIAccessibleEditableText> \
accessIface(do_QueryInterface(GetNSAccessible())); \
if (!(accessIface)) \
return (value)
#define MAI_IFACE_RETURN_IF_FAIL(accessIface) \
nsCOMPtr<nsIAccessibleEditableText> \
accessIface(do_QueryInterface(GetNSAccessible())); \
if (!(accessIface)) \
return
gboolean
MaiInterfaceEditableText::SetRunAttributes(AtkAttributeSet *aAttribSet,
gint aStartOffset, gint aEndOffset)
{
MAI_IFACE_RETURN_VAL_IF_FAIL(accessIface, FALSE);
nsCOMPtr<nsISupports> attrSet;
/* how to insert attributes into nsISupports ??? */
nsresult rv = accessIface->SetAttributes(aStartOffset, aEndOffset,
attrSet);
return NS_FAILED(rv) ? FALSE : TRUE;
}
void
MaiInterfaceEditableText::SetTextContents(const gchar *aString)
{
MAI_IFACE_RETURN_IF_FAIL(accessIface);
NS_ConvertUTF8toUCS2 strContent(aString);
nsresult rv = accessIface->SetTextContents(strContent);
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
"MaiInterfaceEditableText::SetTextContents, failed\n");
}
void
MaiInterfaceEditableText::InsertText(const gchar *aString, gint aLength,
gint *aPosition)
{
MAI_IFACE_RETURN_IF_FAIL(accessIface);
NS_ConvertUTF8toUCS2 strContent(aString);
/////////////////////////////////////////////////////////////////////
// interface changed in nsIAccessibleEditabelText.idl ???
//
// PRInt32 pos = *aPosition;
// nsresult rv = accessIface->InsertText(strContent, aLength, &pos);
// *aPosition = pos;
/////////////////////////////////////////////////////////////////////
nsresult rv = accessIface->InsertText(strContent, *aPosition);
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
"MaiInterfaceEditableText::InsertText, failed\n");
}
void
MaiInterfaceEditableText::CopyText(gint aStartPos, gint aEndPos)
{
MAI_IFACE_RETURN_IF_FAIL(accessIface);
nsresult rv = accessIface->CopyText(aStartPos, aEndPos);
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
"MaiInterfaceEditableText::CopyText, failed\n");
}
void
MaiInterfaceEditableText::CutText(gint aStartPos, gint aEndPos)
{
MAI_IFACE_RETURN_IF_FAIL(accessIface);
nsresult rv = accessIface->CutText(aStartPos, aEndPos);
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
"MaiInterfaceEditableText::CutText, failed\n");
}
void
MaiInterfaceEditableText::DeleteText(gint aStartPos, gint aEndPos)
{
MAI_IFACE_RETURN_IF_FAIL(accessIface);
nsresult rv = accessIface->DeleteText(aStartPos, aEndPos);
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
"MaiInterfaceEditableText::DeleteText, failed\n");
}
void
MaiInterfaceEditableText::PasteText(gint aPosition)
{
MAI_IFACE_RETURN_IF_FAIL(accessIface);
nsresult rv = accessIface->PasteText(aPosition);
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
"MaiInterfaceEditableText::PasteText, failed\n");
}
/* statics */
/* do general checking for callbacks functions
* return the MaiInterfaceEditableText extracted from atk editabletext
*/
MaiInterfaceEditableText *
getEditableText(AtkEditableText *aEditable)
{
g_return_val_if_fail(MAI_IS_ATK_WIDGET(aEditable), NULL);
MaiWidget *maiWidget =
NS_STATIC_CAST(MaiWidget*, (MAI_ATK_OBJECT(aEditable)->maiObject));
g_return_val_if_fail(maiWidget != NULL, NULL);
g_return_val_if_fail(maiWidget->GetAtkObject() == (AtkObject*)aEditable,
NULL);
MaiInterfaceEditableText *ifaceEditableText =
NS_STATIC_CAST(MaiInterfaceEditableText*,
maiWidget->GetMaiInterface(MAI_INTERFACE_EDITABLE_TEXT));
return ifaceEditableText;
}
void
interfaceInitCB(AtkEditableTextIface *aIface)
{
g_return_if_fail(aIface != NULL);
aIface->set_run_attributes = setRunAttributesCB;
aIface->set_text_contents = setTextContentsCB;
aIface->insert_text = insertTextCB;
aIface->copy_text = copyTextCB;
aIface->cut_text = cutTextCB;
aIface->delete_text = deleteTextCB;
aIface->paste_text = pasteTextCB;
}
/* static, callbacks for atkeditabletext virutal functions */
gboolean
setRunAttributesCB(AtkEditableText *aText, AtkAttributeSet *aAttribSet,
gint aStartOffset, gint aEndOffset)
{
MaiInterfaceEditableText *maiIfaceEditableText = getEditableText(aText);
if (!maiIfaceEditableText)
return FALSE;
return maiIfaceEditableText->SetRunAttributes(aAttribSet,
aStartOffset, aEndOffset);
}
void
setTextContentsCB(AtkEditableText *aText, const gchar *aString)
{
MaiInterfaceEditableText *maiIfaceEditableText = getEditableText(aText);
if (!maiIfaceEditableText)
return;
maiIfaceEditableText->SetTextContents(aString);
}
void
insertTextCB(AtkEditableText *aText,
const gchar *aString, gint aLength, gint *aPosition)
{
MaiInterfaceEditableText *maiIfaceEditableText = getEditableText(aText);
if (!maiIfaceEditableText)
return;
maiIfaceEditableText->InsertText(aString, aLength, aPosition);
}
void
copyTextCB(AtkEditableText *aText, gint aStartPos, gint aEndPos)
{
MaiInterfaceEditableText *maiIfaceEditableText = getEditableText(aText);
if (!maiIfaceEditableText)
return;
maiIfaceEditableText->CopyText(aStartPos, aEndPos);
}
void
cutTextCB(AtkEditableText *aText, gint aStartPos, gint aEndPos)
{
MaiInterfaceEditableText *maiIfaceEditableText = getEditableText(aText);
if (!maiIfaceEditableText)
return;
maiIfaceEditableText->CutText(aStartPos, aEndPos);
}
void
deleteTextCB(AtkEditableText *aText, gint aStartPos, gint aEndPos)
{
MaiInterfaceEditableText *maiIfaceEditableText = getEditableText(aText);
if (!maiIfaceEditableText)
return;
maiIfaceEditableText->DeleteText(aStartPos, aEndPos);
}
void
pasteTextCB(AtkEditableText *aText, gint aPosition)
{
MaiInterfaceEditableText *maiIfaceEditableText = getEditableText(aText);
if (!maiIfaceEditableText)
return;
maiIfaceEditableText->PasteText(aPosition);
}

Просмотреть файл

@ -1,273 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim:expandtab:shiftwidth=4:tabstop=4:
*/
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 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 Sun Microsystems, Inc.
* Portions created by Sun Microsystems are Copyright (C) 2002 Sun
* Microsystems, Inc. All Rights Reserved.
*
* Original Author: Silvia Zhao (silvia.zhao@sun.com)
*
* Contributor(s):
*
* 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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsMaiInterfaceSelection.h"
#include "nsIAccessibleSelectable.h"
/* helpers */
static MaiInterfaceSelection *getSelection(AtkSelection *aIface);
G_BEGIN_DECLS
/* selection interface callbacks */
static void interfaceInitCB(AtkSelectionIface *aIface);
static gboolean addSelectionCB(AtkSelection *aSelection,
gint i);
static gboolean clearSelectionCB(AtkSelection *aSelection);
static AtkObject *refSelectionCB(AtkSelection *aSelection,
gint i);
static gint getSelectionCountCB(AtkSelection *aSelection);
static gboolean isChildSelectedCB(AtkSelection *aSelection,
gint i);
static gboolean removeSelectionCB(AtkSelection *aSelection,
gint i);
static gboolean selectAllSelectionCB(AtkSelection *aSelection);
G_END_DECLS
MaiInterfaceSelection::MaiInterfaceSelection(MaiWidget *aMaiWidget):
MaiInterface(aMaiWidget)
{
}
MaiInterfaceSelection::~MaiInterfaceSelection()
{
}
MaiInterfaceType
MaiInterfaceSelection::GetType()
{
return MAI_INTERFACE_SELECTION;
}
const GInterfaceInfo *
MaiInterfaceSelection::GetInterfaceInfo()
{
static const GInterfaceInfo atk_if_selection_info = {
(GInterfaceInitFunc) interfaceInitCB,
(GInterfaceFinalizeFunc) NULL,
NULL
};
return &atk_if_selection_info;
}
#define MAI_IFACE_RETURN_VAL_IF_FAIL(accessIface, retvalue) \
nsIAccessible *tmpAccess = GetNSAccessible(); \
nsCOMPtr<nsIAccessibleSelectable> \
accessIface(do_QueryInterface(tmpAccess)); \
if (!(accessIface)) \
return (retvalue)
/*interface virtual functions*/
gboolean
MaiInterfaceSelection::AddSelection(gint i)
{
MAI_IFACE_RETURN_VAL_IF_FAIL(accessInterfaceSelectable, FALSE);
return NS_SUCCEEDED(accessInterfaceSelectable->AddSelection(i)) != 0;
}
gboolean
MaiInterfaceSelection::ClearSelection()
{
MAI_IFACE_RETURN_VAL_IF_FAIL(accessInterfaceSelectable, FALSE);
return NS_SUCCEEDED(accessInterfaceSelectable->ClearSelection()) != 0;
}
MaiObject *
MaiInterfaceSelection::RefSelection(gint i)
{
MAI_IFACE_RETURN_VAL_IF_FAIL(accessInterfaceSelectable, NULL);
nsCOMPtr<nsIAccessible> aSelection;
nsresult rv =
accessInterfaceSelectable->RefSelection(i, getter_AddRefs(aSelection));
MaiWidget *maiWidget;
if (NS_SUCCEEDED(rv))
maiWidget = new MaiWidget(aSelection);
return (maiWidget != NULL) ? maiWidget : NULL;
}
gint
MaiInterfaceSelection::GetSelectionCount()
{
MAI_IFACE_RETURN_VAL_IF_FAIL(accessInterfaceSelectable, 0);
PRInt32 num = 0;
nsresult rv = accessInterfaceSelectable->GetSelectionCount(&num);
return (NS_FAILED(rv)) ? -1 : num;
}
gboolean
MaiInterfaceSelection::IsChildSelected(gint i)
{
MAI_IFACE_RETURN_VAL_IF_FAIL(accessInterfaceSelectable, FALSE);
PRBool result = FALSE;
nsresult rv = accessInterfaceSelectable->IsChildSelected(i, &result);
return (NS_FAILED(rv)) ? FALSE : result;
}
gboolean
MaiInterfaceSelection::RemoveSelection(gint i)
{
MAI_IFACE_RETURN_VAL_IF_FAIL(accessInterfaceSelectable, FALSE);
nsresult rv = accessInterfaceSelectable->RemoveSelection(i);
return (NS_FAILED(rv)) ? FALSE : TRUE;
}
gboolean
MaiInterfaceSelection::SelectAllSelection()
{
MAI_IFACE_RETURN_VAL_IF_FAIL(accessInterfaceSelectable, FALSE);
PRBool result = FALSE;
nsresult rv = accessInterfaceSelectable->SelectAllSelection(&result);
return (NS_FAILED(rv)) ? FALSE : result;
}
/* static functions */
/* do general checking for callbacks functions
* return the MaiInterfaceSelection extracted from atk selection
*/
MaiInterfaceSelection *
getSelection(AtkSelection *aSelection)
{
MAI_CHECK_ATK_OBJECT_RETURN_VAL_IF_FAIL(aSelection, NULL);
g_return_val_if_fail(MAI_IS_ATK_WIDGET(aSelection), NULL);
MaiWidget *maiWidget = (MaiWidget*)(MAI_ATK_OBJECT(aSelection)->maiObject);
MaiInterfaceSelection *maiInterfaceSelection = (MaiInterfaceSelection*)
maiWidget->GetMaiInterface(MAI_INTERFACE_SELECTION);
return maiInterfaceSelection;
}
void
interfaceInitCB(AtkSelectionIface *aIface)
{
g_return_if_fail(aIface != NULL);
aIface->add_selection = addSelectionCB;
aIface->clear_selection = clearSelectionCB;
aIface->ref_selection = refSelectionCB;
aIface->get_selection_count = getSelectionCountCB;
aIface->is_child_selected = isChildSelectedCB;
aIface->remove_selection = removeSelectionCB;
aIface->select_all_selection = selectAllSelectionCB;
}
gboolean
addSelectionCB(AtkSelection *aSelection, gint i)
{
MaiInterfaceSelection *maiInterfaceSelection = getSelection(aSelection);
return (maiInterfaceSelection) ? maiInterfaceSelection->AddSelection(i) :
FALSE;
}
gboolean
clearSelectionCB(AtkSelection *aSelection)
{
MaiInterfaceSelection *maiInterfaceSelection = getSelection(aSelection);
return (maiInterfaceSelection) ? maiInterfaceSelection->ClearSelection() :
FALSE;
}
AtkObject *
refSelectionCB(AtkSelection *aSelection, gint i)
{
MaiInterfaceSelection *maiInterfaceSelection = getSelection(aSelection);
if (!maiInterfaceSelection)
return NULL;
MaiObject *maiObj =
maiInterfaceSelection->RefSelection(i);
if (!maiObj)
return NULL;
AtkObject *atkObj = maiObj->GetAtkObject();
if (!atkObj)
return NULL;
g_object_ref(atkObj);
return atkObj;
}
gint
getSelectionCountCB(AtkSelection *aSelection)
{
MaiInterfaceSelection *maiInterfaceSelection = getSelection(aSelection);
return (maiInterfaceSelection) ?
maiInterfaceSelection->GetSelectionCount() : -1;
}
gboolean
isChildSelectedCB(AtkSelection *aSelection, gint i)
{
MaiInterfaceSelection *maiInterfaceSelection = getSelection(aSelection);
return (maiInterfaceSelection) ?
maiInterfaceSelection->IsChildSelected(i) : FALSE;
}
gboolean
removeSelectionCB(AtkSelection *aSelection, gint i)
{
MaiInterfaceSelection *maiInterfaceSelection = getSelection(aSelection);
return (maiInterfaceSelection) ?
maiInterfaceSelection->RemoveSelection(i) : FALSE;
}
gboolean
selectAllSelectionCB(AtkSelection *aSelection)
{
MaiInterfaceSelection *maiInterfaceSelection = getSelection(aSelection);
return (maiInterfaceSelection) ?
maiInterfaceSelection->SelectAllSelection() : FALSE;
}

Просмотреть файл

@ -168,9 +168,7 @@ MaiInterfaceTable::RefAt(gint aRow, gint aColumn)
if (NS_FAILED(rv) || !cell)
return NULL;
/* ??? when the new one get freed? */
MaiWidget *maiObj = new MaiWidget(cell);
return maiObj;
return MaiWidget::CreateAndCache(cell);
}
gint
@ -267,9 +265,7 @@ MaiInterfaceTable::GetCaption()
if (NS_FAILED(rv) || !caption)
return NULL;
/* ??? when the new one get freed? */
MaiWidget *maiObj = new MaiWidget(caption);
return maiObj;
return MaiWidget::CreateAndCache(caption);
}
const gchar*
@ -301,9 +297,8 @@ MaiInterfaceTable::GetColumnHeader(gint aColumn)
nsCOMPtr<nsIAccessible> accHeader(do_QueryInterface(header));
if (!accHeader)
return NULL;
/* ??? when the new one get freed? */
MaiWidget *maiObj = new MaiWidget(accHeader);
return maiObj;
return MaiWidget::CreateAndCache(accHeader);
}
const gchar*
@ -335,9 +330,8 @@ MaiInterfaceTable::GetRowHeader(gint aRow)
nsCOMPtr<nsIAccessible> accHeader(do_QueryInterface(header));
if (!accHeader)
return NULL;
/* ??? when the new one get freed? */
MaiWidget *maiObj = new MaiWidget(accHeader);
return maiObj;
return MaiWidget::CreateAndCache(accHeader);
}
MaiWidget*
@ -350,13 +344,51 @@ MaiInterfaceTable::GetSummary()
gint
MaiInterfaceTable::GetSelectedColumns(gint **aSelected)
{
return 0;
MAI_IFACE_RETURN_VAL_IF_FAIL(accessIface, NULL);
PRUint32 size = 0;
PRInt32 *columns = NULL;
nsresult rv = accessIface->GetSelectedColumns(&size, &columns);
if (NS_FAILED(rv) || (size == 0) || !columns) {
*aSelected = NULL;
return 0;
}
gint *atkColumns = g_new(gint, size);
NS_ASSERTION(atkColumns, "Fail to get memory for columns");
//copy
for (int index = 0; index < size; ++index)
atkColumns[index] = NS_STATIC_CAST(gint, columns[index]);
nsMemory::Free(columns);
*aSelected = atkColumns;
return size;
}
gint
MaiInterfaceTable::GetSelectedRows(gint **aSelected)
{
return 0;
MAI_IFACE_RETURN_VAL_IF_FAIL(accessIface, NULL);
PRUint32 size = 0;
PRInt32 *rows = NULL;
nsresult rv = accessIface->GetSelectedRows(&size, &rows);
if (NS_FAILED(rv) || (size == 0) || !rows) {
*aSelected = NULL;
return 0;
}
gint *atkRows = g_new(gint, size);
NS_ASSERTION(atkRows, "Fail to get memory for rows");
//copy
for (int index = 0; index < size; ++index)
atkRows[index] = NS_STATIC_CAST(gint, rows[index]);
nsMemory::Free(rows);
*aSelected = atkRows;
return size;
}
gboolean

Просмотреть файл

@ -141,6 +141,10 @@ MaiInterfaceText::GetText(gint aStartOffset, gint aEndOffset)
{
MAI_IFACE_RETURN_VAL_IF_FAIL(accessIface, NULL);
//currently nsIAccessibleText does not know the meaning of -1
//after fixing that, remove this
if (aEndOffset < 0 )
aEndOffset = 1024;
nsAutoString autoStr;
nsresult rv = accessIface->GetText(aStartOffset, aEndOffset, autoStr);
if (NS_FAILED(rv))

Просмотреть файл

@ -23,7 +23,7 @@
*
* Original Author: Bolian Yin (bolian.yin@sun.com)
*
* Contributor(s):
* Contributor(s): John Sun (john.sun@sun.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
@ -61,14 +61,17 @@ static AtkObject* getParentCB(AtkObject *aObj);
static gint getChildCountCB(AtkObject *aObj);
static AtkObject* refChildCB(AtkObject *aObj, gint aChildIndex);
static gint getIndexInParentCB(AtkObject *aObj);
//static AtkRelationSet* refRelationSetCB(AtkObject *aObj);
/* implemented by MaiWidget */
//static AtkStateSet* refStateSetCB(AtkObject *aObj);
//static AtkRole getRoleCB(AtkObject *aObj);
//static AtkRelationSet* refRelationSetCB(AtkObject *aObj);
//static AtkLayer getLayerCB(AtkObject *aObj);
//static gint getMdiZorderCB(AtkObject *aObj);
/* the missing atkobject virtual functions */
/*
static AtkStateSet* refStateSetCB(AtkObject *aObj);
static void SetNameCB(AtkObject *aObj,
const gchar *name);
static void SetDescriptionCB(AtkObject *aObj,
@ -140,8 +143,8 @@ MaiObject::MaiObject(nsIAccessible *aAcc)
MaiObject::~MaiObject()
{
/* mAccessible will get released here automatically */
mMaiAtkObject = NULL;
NS_ASSERTION((mMaiAtkObject == NULL),
"Cannot Del MaiObject: alive atk object");
#ifdef MAI_LOGGING
num_deleted_mai_object++;
@ -160,7 +163,7 @@ MaiObject::GetNSAccessible(void)
/* for those get functions who have a related memeber vairable in AtkObject
* (see atkobject.h), save a copy of the value in atkobject, return them
* when available, get a new one and save if not.
* when available, create one and save if not.
*
* virtual functions that fall into this scope:
* GetName x
@ -253,6 +256,11 @@ MaiObject::Initialize(void)
void
MaiObject::Finalize(void)
{
//here we know that the action is originated from the MaiAtkObject,
//and the MaiAtkObject itself will be destroyed.
//Mark MaiAtkObject to nil
mMaiAtkObject = NULL;
delete this;
}
@ -283,7 +291,7 @@ classInitCB(AtkObjectClass *aClass)
aClass->get_n_children = getChildCountCB;
aClass->ref_child = refChildCB;
aClass->get_index_in_parent = getIndexInParentCB;
// aClass->ref_state_set = refStateSetCB;
aClass->initialize = initializeCB;
gobject_class->finalize = finalizeCB;
@ -312,10 +320,17 @@ void
finalizeCB(GObject *aObj)
{
MAI_CHECK_ATK_OBJECT_RETURN_IF_FAIL(aObj);
MaiObject *maiObject = MAI_ATK_OBJECT(aObj)->maiObject;
MAI_LOG_DEBUG(("====release MaiAtkObject=0x%x, MaiObject=0x%x\n",
(guint)aObj, (guint)maiObject));
maiObject->Finalize();
/* call parent finalize function */
// never call MaiObject later
MAI_ATK_OBJECT(aObj)->maiObject = NULL;
// call parent finalize function
// finalize of GObjectClass will unref the accessible parent if has
if (G_OBJECT_CLASS (parent_class)->finalize)
G_OBJECT_CLASS (parent_class)->finalize(aObj);
}
@ -375,6 +390,7 @@ refChildCB(AtkObject *aObj, gint aChildIndex)
if (childAtkObj) {
g_object_ref(childAtkObj);
if (!childAtkObj->accessible_parent)
//this will addref parent
atk_object_set_parent(childAtkObj, aObj);
}
return childAtkObj;
@ -393,7 +409,8 @@ getIndexInParentCB(AtkObject *aObj)
The following nsIAccessible states aren't translated, just ignored.
STATE_MIXED: For a three-state check box.
STATE_READONLY: The object is designated read-only.
STATE_HOTTRACKED: Its appearance has changed to indicate mouse over it.
STATE_HOTTRACKED: Means its appearance has changed to indicate mouse
over it.
STATE_DEFAULT: Represents the default button in a window.
STATE_FLOATING: Not supported yet.
STATE_MARQUEED: Indicate scrolling or moving text or graphics.
@ -402,7 +419,7 @@ The following nsIAccessible states aren't translated, just ignored.
STATE_MOVEABLE:
STATE_SELFVOICING: The object has self-TTS.
STATE_LINKED: The object is formatted as a hyperlink.
STATE_TRAVERSE: The object is a hyperlink that has been visited by a user.
STATE_TRAVERSE: The object is a hyperlink that has been visited.
STATE_EXTSELECTABLE: Indicates that an object extends its selectioin.
STATE_ALERT_LOW: Not supported yet.
STATE_ALERT_MEDIUM: Not supported yet.
@ -421,14 +438,12 @@ Returned AtkStatusSet never contain the following AtkStates.
rectangular region
ATK_STATE_STALE: The index associated with this object has changed since
the user accessed the object
*******************************************************************************/
******************************************************************************/
AtkStateSet*
MaiObject::TranslateStates(PRUint32 aAccState)
void
MaiObject::TranslateStates(PRUint32 aAccState, AtkStateSet *state_set)
{
AtkStateSet *state_set;
state_set = atk_state_set_new (); // state_set contains ATK_STATE_INVALID
g_return_if_fail(state_set);
if (aAccState & nsIAccessible::STATE_SELECTED)
atk_state_set_add_state (state_set, ATK_STATE_SELECTED);
@ -508,5 +523,4 @@ MaiObject::TranslateStates(PRUint32 aAccState)
if (aAccState & nsIAccessible::STATE_VERTICAL)
atk_state_set_add_state (state_set, ATK_STATE_VERTICAL);
return state_set;
}

Просмотреть файл

@ -131,7 +131,8 @@ public:
public:
virtual AtkObject *GetAtkObject(void) = 0;
virtual nsIAccessible *GetNSAccessible(void);
static AtkStateSet* TranslateStates(PRUint32 aAccState);
static void TranslateStates(PRUint32 aAccState,
AtkStateSet *state_set);
/* virtual functions called by callbacks */
virtual void Initialize(void);

Просмотреть файл

@ -23,7 +23,7 @@
*
* Original Author: Bolian Yin (bolian.yin@sun.com)
*
* Contributor(s):
* Contributor(s): John Sun (john.sun@sun.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
@ -40,6 +40,8 @@
* ***** END LICENSE BLOCK ***** */
#include "nsCOMPtr.h"
#include "nsMaiUtil.h"
#include "nsMaiCache.h"
#include "nsMaiTopLevel.h"
#include "nsIAccessibleEventReceiver.h"
#include "nsAccessibleEventData.h"
@ -47,7 +49,7 @@
/*
* Must keep sychronization with
* enumerate AtkProperty in mozilla/accessible/src/base/nsRootAccessible.h
*/
*/
static char * pAtkPropertyNameArray[PROP_LAST] = {
0,
"accessible_name",
@ -130,7 +132,7 @@ MaiTopLevel::HandleEvent(PRUint32 aEvent, nsIAccessible *aAccessible,
}
atk_object_notify_state_change(ATK_OBJECT(pMaiObject->GetAtkObject()),
atkState, pAtkStateChange->enable);
atkState, pAtkStateChange->enable);
break;
/*
@ -157,11 +159,13 @@ MaiTopLevel::HandleEvent(PRUint32 aEvent, nsIAccessible *aAccessible,
if (pAtkPropChange->oldvalue)
aOldMaiObj = CreateMaiObjectFor(NS_REINTERPRET_CAST
(nsIAccessible *, pAtkPropChange->oldvalue));
(nsIAccessible *,
pAtkPropChange->oldvalue));
if (pAtkPropChange->newvalue)
aNewMaiObj = CreateMaiObjectFor(NS_REINTERPRET_CAST
(nsIAccessible *, pAtkPropChange->newvalue));
(nsIAccessible *,
pAtkPropChange->newvalue));
if (!aOldMaiObj || !aNewMaiObj )
return NS_ERROR_FAILURE;
@ -180,10 +184,11 @@ MaiTopLevel::HandleEvent(PRUint32 aEvent, nsIAccessible *aAccessible,
case PROP_TABLE_ROW_DESCRIPTION:
g_value_init(&values.new_value, G_TYPE_INT);
g_value_set_int(&values.new_value,
*NS_REINTERPRET_CAST(gint *, pAtkPropChange->newvalue));
*NS_REINTERPRET_CAST(gint *,
pAtkPropChange->newvalue));
break;
//Perhaps need divide more in the future according to result of test
//Perhaps need more cases in the future
default:
g_value_init (&values.old_value, G_TYPE_POINTER);
g_value_set_pointer (&values.old_value, pAtkPropChange->oldvalue);
@ -192,8 +197,9 @@ MaiTopLevel::HandleEvent(PRUint32 aEvent, nsIAccessible *aAccessible,
}
g_signal_emit_by_name(ATK_OBJECT(pMaiObject->GetAtkObject()),
g_strconcat("property_change::", values.property_name),
&values, NULL);
g_strconcat("property_change::",
values.property_name),
&values, NULL);
break;
@ -212,16 +218,17 @@ MaiTopLevel::HandleEvent(PRUint32 aEvent, nsIAccessible *aAccessible,
pAtkTextChange = NS_REINTERPRET_CAST(AtkTextChange *, aEventData);
g_signal_emit_by_name (ATK_OBJECT(pMaiObject->GetAtkObject()),
pAtkTextChange->add ? "text_changed:insert":"text_changed::delete",
pAtkTextChange->start,
pAtkTextChange->length);
pAtkTextChange->add ? \
"text_changed:insert":"text_changed::delete",
pAtkTextChange->start,
pAtkTextChange->length);
break;
case nsIAccessibleEventListener::EVENT_ATK_TEXT_SELECTION_CHANGE:
MAI_LOG_DEBUG(("Receiving event EVENT_ATK_TEXT_SELECTION_CHANGE\n\n"));
g_signal_emit_by_name(ATK_OBJECT(pMaiObject->GetAtkObject()),
"text_selection_changed");
"text_selection_changed");
break;
case nsIAccessibleEventListener::EVENT_ATK_TEXT_CARET_MOVE:
@ -320,7 +327,7 @@ MaiTopLevel::HandleEvent(PRUint32 aEvent, nsIAccessible *aAccessible,
"visible_data_changed");
break;
// Is a superclass of ATK event children_changed
// Is a superclass of ATK event children_changed
case nsIAccessibleEventListener::EVENT_REORDER:
AtkChildrenChange *pAtkChildrenChange;
@ -334,25 +341,22 @@ MaiTopLevel::HandleEvent(PRUint32 aEvent, nsIAccessible *aAccessible,
MaiObject *aChildMaiObject;
aChildMaiObject = CreateMaiObjectFor(pAtkChildrenChange->child);
if (!aChildMaiObject)
g_signal_emit_by_name (ATK_OBJECT(pMaiObject->GetAtkObject()),
pAtkChildrenChange->add ?
"children_changed::add" : "children_changed::remove",
pAtkChildrenChange->index,
ATK_OBJECT(aChildMaiObject->GetAtkObject()),
NULL);
g_signal_emit_by_name (ATK_OBJECT(pMaiObject->GetAtkObject()),
pAtkChildrenChange->add ? \
"children_changed::add" : \
"children_changed::remove",
pAtkChildrenChange->index,
ATK_OBJECT(aChildMaiObject->GetAtkObject()),
NULL);
// Don't need for the MAI cache machanism
// g_object_unref(G_OBJECT(aChildMaiObject->GetAtkObject()));
break;
/*
* Because the dealing with menu is very different between nsIAccessible
* and ATK, and the menu activity is important, specially transfer the
* following two event.
* Need more verification by AT test.
*/
/*
* Because dealing with menu is very different between nsIAccessible
* and ATK, and the menu activity is important, specially transfer the
* following two event.
* Need more verification by AT test.
*/
case nsIAccessibleEventListener::EVENT_MENUSTART:
MAI_LOG_DEBUG(("Receiving event EVENT_MENUSTART\n\n"));
atk_focus_tracker_notify(ATK_OBJECT(pMaiObject->GetAtkObject()));
@ -375,6 +379,52 @@ MaiTopLevel::HandleEvent(PRUint32 aEvent, nsIAccessible *aAccessible,
return NS_OK;
}
/******************************************************************
* MaiObject *
* MaiTopLevel::CreateMaiObjectFor(nsIAccessible* aAccessible)
*
******************************************************************/
MaiObject *
MaiTopLevel::CreateMaiObjectFor(nsIAccessible *aAccessible)
{
return MaiWidget::CreateAndCache(aAccessible);
}
/*static*/
//////////////////////////////////////////////////////////////////////
// See the comments in
// MaiWidget::CreateAndCache(nsIAccessible *aAcc);
/////////////////////////////////////////////////////////////////////
MaiTopLevel *
MaiTopLevel::CreateAndCache(nsIAccessible *aAcc)
{
if (!aAcc)
return NULL;
MaiCache *maiCache = mai_get_cache();
if (!maiCache)
return NULL;
MaiTopLevel *retWidget =
NS_STATIC_CAST(MaiTopLevel*, maiCache->Fetch(aAcc));
//there is a maiWidget in cache for the nsIAccessible already.
if (retWidget) {
MAI_LOG_DEBUG(("MaiTopLevel::CreateAndCache, already added\n"));
return retWidget;
}
//create one, and cache it.
retWidget = new MaiTopLevel(aAcc);
NS_ASSERTION(retWidget, "Fail to create mai object");
MAI_LOG_DEBUG(("MaiTopLevel::CreateAndCache, new one created\n"));
maiCache->Add(retWidget);
//cache should have add ref, release ours
g_object_unref(retWidget->GetAtkObject());
return retWidget;
}
/* static */
AtkStateType
MaiTopLevel::TranslateAState(PRUint32 aAccState)
@ -392,7 +442,7 @@ MaiTopLevel::TranslateAState(PRUint32 aAccState)
return ATK_STATE_EXPANDED;
case nsIAccessible::STATE_COLLAPSED:
return ATK_STATE_EXPANDABLE;
// The control can't accept input at this time
// The control can't accept input at this time
case nsIAccessible::STATE_BUSY:
return ATK_STATE_BUSY;
case nsIAccessible::STATE_FOCUSABLE:
@ -405,7 +455,7 @@ MaiTopLevel::TranslateAState(PRUint32 aAccState)
return ATK_STATE_MULTISELECTABLE;
#if 0
// The following two state need to deal specially
// The following two state need to deal specially
case nsIAccessible::STATE_INVISIBLE:
return !ATK_STATE_VISIBLE;
@ -413,18 +463,19 @@ MaiTopLevel::TranslateAState(PRUint32 aAccState)
return !ATK_STATE_ENABLED;
#endif
// The following state is
// Extended state flags (for now non-MSAA, for Java and Gnome/ATK support)
// This is only the states that there isn't already a mapping for in MSAA
// See www.accessmozilla.org/article.php?sid=11 for information on the
// mappings between accessibility API state
// The following state is
// Extended state flags (for non-MSAA, for Java and Gnome/ATK support)
// They are only the states that are not already mapped in MSAA
// See www.accessmozilla.org/article.php?sid=11 for information on the
// mappings between accessibility API state
case nsIAccessible::STATE_ACTIVE:
return ATK_STATE_ACTIVE;
case nsIAccessible::STATE_EXPANDABLE:
return ATK_STATE_EXPANDABLE;
#if 0
// Need change definitions in nsIAccessible.idl to avoid duplicate value
// Need change definitions in nsIAccessible.idl to avoid
// duplicate value
case nsIAccessible::STATE_MODAL:
return ATK_STATE_MODAL;
#endif
@ -446,22 +497,3 @@ MaiTopLevel::TranslateAState(PRUint32 aAccState)
return ATK_STATE_INVALID;
}
}
/******************************************************************
* MaiObject *
* MaiTopLevel::CreateMaiObjectFor(nsIAccessible* aAccessible)
*
******************************************************************/
MaiObject *
MaiTopLevel::CreateMaiObjectFor(nsIAccessible *aAccessible)
{
MaiObject *newMaiObject = NULL;
newMaiObject = new MaiWidget(aAccessible);
return newMaiObject;
}
/* virtual functions to ATK callbacks */
/* not implemented yet */

Просмотреть файл

@ -61,7 +61,7 @@ public:
// nsIAccessibleEventListener
NS_DECL_NSIACCESSIBLEEVENTLISTENER
/* virtual functions called by callbacks */
static MaiTopLevel *CreateAndCache(nsIAccessible *aAcc);
private:
MaiObject *CreateMaiObjectFor(nsIAccessible* aAccessible);

Просмотреть файл

@ -65,6 +65,10 @@ static gboolean mai_remove_toplevel_accessible(nsIAccessible *toplevel);
/* Misc */
static void _listener_info_destroy(gpointer data);
static guint add_listener (GSignalEmissionHook listener,
const gchar *object_type,
const gchar *signal,
const gchar *hook_data);
static GHashTable *listener_list = NULL;
static gint listener_idx = 1;
@ -142,45 +146,29 @@ static guint
mai_util_add_global_event_listener(GSignalEmissionHook listener,
const gchar *event_type)
{
GType type;
guint signal_id;
guint rc = 0;
gchar **split_string;
gint rc = 0;
split_string = g_strsplit(event_type, ":", 3);
split_string = g_strsplit (event_type, ":", 3);
type = g_type_from_name(split_string[1]);
if (type > 0) {
signal_id = g_signal_lookup(split_string[2], type);
if (signal_id > 0) {
MaiUtilListenerInfo *listener_info;
if (split_string) {
if (!strcmp ("window", split_string[0])) {
/* ???
static gboolean initialized = FALSE;
rc = listener_idx;
listener_info = (MaiUtilListenerInfo *)
g_malloc(sizeof(MaiUtilListenerInfo));
listener_info->key = listener_idx;
listener_info->hook_id =
g_signal_add_emission_hook(signal_id, 0, listener,
g_strdup(event_type),
(GDestroyNotify) g_free);
listener_info->signal_id = signal_id;
g_hash_table_insert(listener_list, &(listener_info->key),
listener_info);
listener_idx++;
if (!initialized) {
do_window_event_initialization ();
initialized = TRUE;
}
rc = add_listener (listener, "MaiWindow",
split_string[1], event_type);
*/
}
else {
g_warning("Invalid signal type %s\n", split_string[2]);
rc = add_listener (listener, split_string[1], split_string[2],
event_type);
}
}
else {
g_warning("Invalid object type %s\n", split_string[1]);
}
if (split_string != NULL)
g_strfreev(split_string);
return rc;
}
@ -226,7 +214,7 @@ mai_util_remove_global_event_listener(guint remove_listener)
}
}
static AtkObject *
AtkObject *
mai_util_get_root(void)
{
static AtkObject *gRootAtkObject = NULL;
@ -237,24 +225,65 @@ mai_util_get_root(void)
return gRootAtkObject;
}
static G_CONST_RETURN gchar *
G_CONST_RETURN gchar *
mai_util_get_toolkit_name(void)
{
return MAI_NAME;
}
static G_CONST_RETURN gchar *
G_CONST_RETURN gchar *
mai_util_get_toolkit_version(void)
{
return MAI_VERSION;
}
static void
void
_listener_info_destroy(gpointer data)
{
free(data);
}
guint
add_listener (GSignalEmissionHook listener,
const gchar *object_type,
const gchar *signal,
const gchar *hook_data)
{
GType type;
guint signal_id;
gint rc = 0;
type = g_type_from_name(object_type);
if (type) {
signal_id = g_signal_lookup(signal, type);
if (signal_id > 0) {
MaiUtilListenerInfo *listener_info;
rc = listener_idx;
listener_info = (MaiUtilListenerInfo *)
g_malloc(sizeof(MaiUtilListenerInfo));
listener_info->key = listener_idx;
listener_info->hook_id =
g_signal_add_emission_hook(signal_id, 0, listener,
g_strdup(hook_data),
(GDestroyNotify)g_free);
listener_info->signal_id = signal_id;
g_hash_table_insert(listener_list, &(listener_info->key),
listener_info);
listener_idx++;
}
else {
g_warning("Invalid signal type %s\n", signal);
}
}
else {
g_warning("Invalid object type %s\n", object_type);
}
return rc;
}
gboolean
mai_init(void)
{
@ -314,10 +343,14 @@ static MaiAppRoot *gRootAccessible = NULL;
MaiAppRoot *
mai_get_root(void)
{
if (gRootAccessible || (gRootAccessible = new MaiAppRoot()))
return gRootAccessible;
return NULL;
if (!mai_initialized) {
return NULL;
}
if (!gRootAccessible) {
gRootAccessible = new MaiAppRoot();
NS_ASSERTION(gRootAccessible, "Fail to create MaiAppRoot");
}
return gRootAccessible;
}
void
@ -334,6 +367,9 @@ mai_delete_root(void)
MaiCache *
mai_get_cache(void)
{
if (!mai_initialized) {
return NULL;
}
MaiAppRoot *root = mai_get_root();
if (root)
return root->GetCache();
@ -345,6 +381,7 @@ mai_add_toplevel_accessible(nsIAccessible *toplevel)
{
g_return_val_if_fail(toplevel != NULL, TRUE);
#if 1
MaiAppRoot *root;
root = mai_get_root();
if (!root)
@ -356,6 +393,23 @@ mai_add_toplevel_accessible(nsIAccessible *toplevel)
/* root will add ref for itself use */
g_object_unref(mai_top_level->GetAtkObject());
return res;
#endif
#if 0
MaiAppRoot *root;
root = mai_get_root();
if (!root)
return FALSE;
MaiTopLevel *mai_top_level =
NS_STATIC_CAST(MaiTopLevel*, MaiTopLevel::CreateAndCache(toplevel));
g_return_val_if_fail(mai_top_level != NULL, PR_FALSE);
gboolean res = root->AddMaiTopLevel(mai_top_level);
return res;
#endif
}
gboolean

Просмотреть файл

@ -41,12 +41,40 @@
#include "nsCOMPtr.h"
#include "nsIAccessibleAction.h"
#include "nsIAccessibleText.h"
#include "nsIAccessibleEditableText.h"
#include "nsIAccessibleTable.h"
#include "nsIAccessibleSelectable.h"
#include "nsIAccessibleHyperText.h"
#include "nsIAccessibleValue.h"
#include "nsMaiWidget.h"
#include "nsMaiAppRoot.h"
#include "nsMaiInterfaceComponent.h"
#include "nsMaiInterfaceAction.h"
#include "nsMaiInterfaceText.h"
#include "nsMaiInterfaceEditableText.h"
#include "nsMaiInterfaceTable.h"
#include "nsMaiInterfaceSelection.h"
#include "nsMaiInterfaceHypertext.h"
#include "nsMaiInterfaceValue.h"
#include "nsMaiUtil.h"
G_BEGIN_DECLS
void classInitCB(AtkObjectClass *aClass);
void initializeCB(AtkObject *aObj, gpointer aData);
void finalizeCB(GObject *aObj);
/* more callbacks for atkobject */
static AtkStateSet* refStateSetCB(AtkObject *aObj);
static AtkRole getRoleCB(AtkObject *aObj);
G_END_DECLS
static gpointer parent_class = NULL;
GType
mai_atk_widget_get_type(void)
{
@ -57,7 +85,7 @@ mai_atk_widget_get_type(void)
sizeof(MaiAtkWidgetClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) NULL,
(GClassInitFunc) classInitCB,
(GClassFinalizeFunc) NULL,
NULL, /* class data */
sizeof(MaiAtkWidget), /* instance size */
@ -99,30 +127,29 @@ MaiWidget::DumpMaiObjectInfo(gint aDepth)
--aDepth;
if (aDepth < 0)
return;
g_print("<<<<<Begin of MaiObject: this=0x%x, aDepth=%d, type=%s\n",
g_print("%s: this=0x%x, aDepth=%d, type=%s", GetName(),
(unsigned int)this, aDepth, "MaiWidget");
g_print("NSAccessible UniqueID=%x\n", GetNSAccessibleUniqueID());
g_print("Interfaces Supported:");
g_print(", UID=%x", GetNSAccessibleUniqueID());
g_print(", Iface");
for (int ifaces = 0; ifaces < MAI_INTERFACE_NUM; ifaces++) {
if (mMaiInterface[ifaces])
g_print(" : %d", ifaces);
}
g_print("\n");
gint nChild = GetChildCount();
gint nIndexInParent = GetIndexInParent();
g_print("== Name: %s, IndexInParent=%d, ChildNum=%d \n",
GetName(),nIndexInParent, nChild);
g_print(", IndexInParent=%d, #child=%d\n", nIndexInParent, nChild);
g_print("<ul>\n");
MaiObject *maiChild;
for (int index = 0; index < nChild; index++) {
maiChild = RefChild(index);
if (maiChild) {
g_print("<li>");
maiChild->DumpMaiObjectInfo(aDepth);
}
}
g_print(">>>>>End of MaiObject: this=0x%x, type=%s\n",
(unsigned int)this, "MaiWidget");
g_print("</ul>\n");
//the interface info
}
@ -140,6 +167,55 @@ MaiWidget::GetMaiInterface(MaiInterfaceType aIfaceType)
return mMaiInterface[aIfaceType];
}
/*static*/
//////////////////////////////////////////////////////////////////////
// MaiWidget *
// MaiWidget::CreateAndCache(nsIAccessible *aAcc);
//
// A helper to create a new MaiWidget and cache it.
//-------------------------------------------------------------------
// This Method gets a cached MaiWidget for the nsIAccessible, create one
// if needed and cache it. Only when create a new MaiWidget, |aAcc| will
// be addrefed.
//
// **Note**
// The returned cached MaiWidget object is NOT guaranteed to be there when
// you fetch it next time. Accordingly, DO NOT keep the returned pointer
// and use it later. Typically, you pass the result of this method to a
// callback.
// If it is really needed to keep the result for later use, please use
// g_object_ref(maiWidget->GetAtkObject());
// to ensure the |maiWidget| pointer is still valid, even when the MaiWidget
// is removed from the cache. And when you do not need it, you have to use:
// g_object_unref(maiWidget->GetAtkObject());
// to release your reference.
////////////////////////////////////////////////////////////////////////
MaiWidget *
MaiWidget::CreateAndCache(nsIAccessible *aAcc)
{
if (!aAcc)
return NULL;
MaiCache *maiCache = mai_get_cache();
if (!maiCache)
return NULL;
MaiWidget *retWidget = NS_STATIC_CAST(MaiWidget*, maiCache->Fetch(aAcc));
//there is a maiWidget in cache for the nsIAccessible already.
if (retWidget)
return retWidget;
//create one, and cache it.
retWidget = new MaiWidget(aAcc);
NS_ASSERTION(retWidget, "Fail to create mai object");
maiCache->Add(retWidget);
//cache should have add ref, release ours
g_object_unref(retWidget->GetAtkObject());
return retWidget;
}
GType
MaiWidget::GetMaiAtkType(void)
{
@ -157,13 +233,13 @@ MaiWidget::GetMaiAtkType(void)
NULL /* value table */
};
if (mMaiInterfaceCount == 0)
return MAI_TYPE_ATK_WIDGET;
type = g_type_register_static(MAI_TYPE_ATK_WIDGET,
MaiWidget::GetUniqueMaiAtkTypeName(),
&tinfo, GTypeFlags(0));
if (mMaiInterfaceCount == 0)
return MAI_TYPE_ATK_WIDGET;
for (int index = 0; index < MAI_INTERFACE_NUM; index++) {
if (!mMaiInterface[index])
continue;
@ -193,37 +269,79 @@ MaiWidget::CreateMaiInterfaces(void)
{
g_return_if_fail(mAccessible != NULL);
// the Component interface are supported by all nsIAccessible
// the Component and interface are supported by all nsIAccessible
// Add Interfaces for each nsIAccessible.ext interfaces
MaiInterfaceComponent *maiInterfaceComponent =
new MaiInterfaceComponent(this);
NS_ASSERTION(maiInterfaceComponent, "Fail to add component interface");
AddMaiInterface(maiInterfaceComponent);
/*
nsCOMPtr<nsIAccessibleAction>
accessInterfaceAction(do_QueryInterface(mAccessible));
if (accessInterfaceAction) {
MaiInterfaceAction *maiInterfaceAction = new MaiInterfaceAction(this);
AddMaiInterface(maiInterfaceAction);
MaiInterfaceAction *maiInterfaceAction = new MaiInterfaceAction(this);
NS_ASSERTION(maiInterfaceAction, "Fail to add Action interface");
AddMaiInterface(maiInterfaceAction);
//nsIAccessibleText
nsCOMPtr<nsIAccessibleText>
accessInterfaceText(do_QueryInterface(mAccessible));
if (accessInterfaceText) {
MaiInterfaceText *maiInterfaceText = new MaiInterfaceText(this);
NS_ASSERTION(maiInterfaceText, "Fail to add text interface");
AddMaiInterface(maiInterfaceText);
}
*/
/*
// all the other interfaces follow here
nsIAccessibleAction.idl
nsIAccessibleEditableText.idl
nsIAccessibleHyperLink.idl
nsIAccessibleHyperText.idl
nsIAccessibleSelection.idl
nsIAccessibleTable.idl
nsIAccessibleText.idl
nsIAccessibleValue.idl
//nsIAccessibleEditableText
nsCOMPtr<nsIAccessibleEditableText>
accessInterfaceEditableText(do_QueryInterface(mAccessible));
if (accessInterfaceEditableText) {
MaiInterfaceEditableText *maiInterfaceEditableText =
new MaiInterfaceEditableText(this);
NS_ASSERTION(maiInterfaceEditableText,
"Fail to add editabletext interface");
AddMaiInterface(maiInterfaceEditableText);
}
*/
//nsIAccessibleTable
nsCOMPtr<nsIAccessibleTable>
accessInterfaceTable(do_QueryInterface(mAccessible));
if (accessInterfaceTable) {
MaiInterfaceTable *maiInterfaceTable = new MaiInterfaceTable(this);
NS_ASSERTION(maiInterfaceTable, "Fail to add table interface");
AddMaiInterface(maiInterfaceTable);
}
//nsIAccessibleSelection
nsCOMPtr<nsIAccessibleSelectable>
accessInterfaceSelection(do_QueryInterface(mAccessible));
if (accessInterfaceSelection) {
MaiInterfaceSelection *maiInterfaceSelection =
new MaiInterfaceSelection(this);
NS_ASSERTION(maiInterfaceSelection, "Fail to add selection interface");
AddMaiInterface(maiInterfaceSelection);
}
//nsIAccessibleHypertext
nsCOMPtr<nsIAccessibleHyperText>
accessInterfaceHypertext(do_QueryInterface(mAccessible));
if (accessInterfaceHypertext) {
MaiInterfaceHypertext *maiInterfaceHypertext =
new MaiInterfaceHypertext(this);
NS_ASSERTION(maiInterfaceHypertext, "Fail to add hypertext interface");
AddMaiInterface(maiInterfaceHypertext);
}
//nsIAccessibleValue
nsCOMPtr<nsIAccessibleValue>
accessInterfaceValue(do_QueryInterface(mAccessible));
if (accessInterfaceValue) {
MaiInterfaceValue *maiInterfaceValue =
new MaiInterfaceValue(this);
NS_ASSERTION(maiInterfaceValue, "Fail to add value interface");
AddMaiInterface(maiInterfaceValue);
}
}
/* virtual functions */
/* virtual functions of MaiObject*/
AtkObject *
MaiWidget::GetAtkObject(void)
@ -245,6 +363,8 @@ MaiWidget::GetAtkObject(void)
atk_object_initialize(ATK_OBJECT(mMaiAtkObject), this);
ATK_OBJECT(mMaiAtkObject)->role = ATK_ROLE_INVALID;
ATK_OBJECT(mMaiAtkObject)->layer = ATK_LAYER_INVALID;
MAI_LOG_DEBUG(("MaiWidget: Create MaiAtkObject=0x%x for MaiWidget 0x%x\n",
(guint)mMaiAtkObject, (guint)this));
return ATK_OBJECT(mMaiAtkObject);
}
@ -269,10 +389,8 @@ MaiWidget::GetParent(void)
if (NS_FAILED(rv) || !accParent)
return NULL;
/* create a new mai parent */
/* ??? when the new one get freed? */
MaiWidget *maiParent = new MaiWidget(accParent);
return maiParent;
/* create a maiWidget for parent */
return CreateAndCache(accParent);
}
gint
@ -300,7 +418,7 @@ MaiWidget::RefChild(gint aChildIndex)
if (maiCache) {
uid = GetChildUniqueID(aChildIndex);
if (uid > 0 && (maiChild = maiCache->Fetch(uid))) {
g_print("got child 0x%x from cache\n", (guint)maiChild);
MAI_LOG_DEBUG(("got child 0x%x from cache\n", (guint)maiChild));
return maiChild;
}
}
@ -328,15 +446,9 @@ MaiWidget::RefChild(gint aChildIndex)
if (maiCache)
maiChild = maiCache->Fetch(uid);
// not cached, create a new one
// not cached, create one
if (!maiChild) {
maiChild = new MaiWidget(accChild);
g_return_val_if_fail(maiChild != NULL, NULL);
if (maiCache) {
maiCache->Add(maiChild);
//cache should have add ref, release ours
g_object_unref(maiChild->GetAtkObject());
}
maiChild = CreateAndCache(accChild);
}
// update children uid list
SetChildUniqueID(aChildIndex, uid);
@ -362,6 +474,24 @@ MaiWidget::GetIndexInParent()
return -1;
}
PRUint32
MaiWidget::RefStateSet()
{
g_return_val_if_fail(mAccessible != NULL, 0);
PRUint32 accState;
nsresult rv = mAccessible->GetAccState(&accState);
return (NS_FAILED(rv)) ? 0 : accState;
}
PRUint32
MaiWidget::GetRole()
{
g_return_val_if_fail(mAccessible != NULL, 0);
PRUint32 accRole;
nsresult rv = mAccessible->GetAccRole(&accRole);
return (NS_FAILED(rv)) ? 0 : accRole;
}
/* static functions */
gchar *
@ -395,9 +525,99 @@ MaiWidget::GetChildUniqueID(gint aChildIndex)
void
MaiWidget::SetChildUniqueID(gint aChildIndex, guint aChildUid)
{
//If the key already exists in the GHashTable its current value is
//replaced with the new value.
//If the key already exists in the GHashTable,
//the old value is replaced.
g_hash_table_insert(mChildren,
NS_REINTERPRET_CAST(void*, aChildIndex),
NS_REINTERPRET_CAST(void*, aChildUid));
}
void
classInitCB(AtkObjectClass *aClass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS(aClass);
parent_class = g_type_class_peek_parent(aClass);
aClass->ref_state_set = refStateSetCB;
aClass->get_role = getRoleCB;
// aClass->initialize = initializeCB;
// gobject_class->finalize = finalizeCB;
}
void
initializeCB(AtkObject *aObj, gpointer aData)
{
g_return_if_fail(MAI_IS_ATK_WIDGET(aObj));
g_return_if_fail(aData != NULL);
/* call parent init function */
/* AtkObjectClass has not a "initialize" function now,
* maybe it has later
*/
if (ATK_OBJECT_CLASS(parent_class)->initialize)
ATK_OBJECT_CLASS(parent_class)->initialize(aObj, aData);
}
#define MAI_ATK_WIDGET_RETURN_VAL_IF_FAIL(obj, val) \
do {\
g_return_val_if_fail(MAI_IS_ATK_WIDGET(obj), val);\
MaiObject * tmpMaiObjectIn = MAI_ATK_OBJECT(obj)->maiObject; \
g_return_val_if_fail(tmpMaiObjectIn != NULL, val);\
g_return_val_if_fail(tmpMaiObjectIn->GetAtkObject() == obj, val); \
} while (0)
#define MAI_ATK_WIDGET_RETURN_IF_FAIL(obj) \
do {\
g_return_if_fail(MAI_IS_ATK_WIDGET(obj));\
MaiObject * tmpMaiObjectIn = MAI_ATK_OBJECT(obj)->maiObject; \
g_return_if_fail(tmpMaiObjectIn != NULL);\
g_return_if_fail(tmpMaiObjectIn->GetAtkObject() == obj); \
} while (0)
void
finalizeCB(GObject *aObj)
{
// MAI_ATK_WIDGET_RETURN_IF_FAIL(aObj);
// call parent finalize function
// finalize of GObjectClass will unref the accessible parent if has
if (G_OBJECT_CLASS (parent_class)->finalize)
G_OBJECT_CLASS (parent_class)->finalize(aObj);
}
AtkStateSet *
refStateSetCB(AtkObject *aObj)
{
MAI_ATK_WIDGET_RETURN_VAL_IF_FAIL(aObj, NULL);
AtkStateSet *state_set;
state_set = ATK_OBJECT_CLASS (parent_class)->ref_state_set (aObj);
MaiWidget *maiWidget = NS_STATIC_CAST(MaiWidget*,
MAI_ATK_OBJECT(aObj)->maiObject);
PRUint32 accState = maiWidget->RefStateSet();
if (accState != 0)
MaiObject::TranslateStates(accState, state_set);
return state_set;
}
AtkRole
getRoleCB(AtkObject *aObj)
{
MAI_ATK_WIDGET_RETURN_VAL_IF_FAIL(aObj, ATK_ROLE_INVALID);
if (aObj->role != ATK_ROLE_INVALID)
return aObj->role;
MaiWidget *maiWidget = NS_STATIC_CAST(MaiWidget*,
MAI_ATK_OBJECT(aObj)->maiObject);
AtkRole atkRole = NS_STATIC_CAST(AtkRole, maiWidget->GetRole());
aObj->role = atkRole;
return atkRole;
}

Просмотреть файл

@ -91,7 +91,7 @@ public:
virtual guint GetNSAccessibleUniqueID();
MaiInterface *GetMaiInterface(MaiInterfaceType aInterfacefaceType);
AtkRole GetAtkRole();
static MaiWidget *CreateAndCache(nsIAccessible *aAcc);
public:
/* callbacks and their virtual functions */
@ -101,6 +101,9 @@ public:
virtual gint GetChildCount(void);
virtual MaiObject *RefChild(gint aChildIndex);
virtual gint GetIndexInParent();
/* new ones */
virtual PRUint32 RefStateSet();
virtual PRUint32 GetRole();
private:
/* Interfaces */