2007-03-22 10:30:00 -07:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
|
|
/* vim:expandtab:shiftwidth=4:tabstop=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
|
|
|
|
* Sun Microsystems, Inc.
|
|
|
|
* Portions created by the Initial Developer are Copyright (C) 2002
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
|
|
|
* Bolian Yin (bolian.yin@sun.com)
|
|
|
|
* 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
|
|
|
|
* 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 "nsAccessibleWrap.h"
|
2010-04-26 23:52:03 -07:00
|
|
|
|
|
|
|
#include "nsAccUtils.h"
|
2009-08-21 05:33:31 -07:00
|
|
|
#include "nsApplicationAccessibleWrap.h"
|
2007-06-17 22:47:33 -07:00
|
|
|
#include "nsRootAccessible.h"
|
|
|
|
#include "nsDocAccessibleWrap.h"
|
|
|
|
#include "nsIAccessibleValue.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
#include "nsString.h"
|
2007-06-01 20:01:38 -07:00
|
|
|
#include "nsAutoPtr.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
#include "prprf.h"
|
|
|
|
#include "nsRoleMap.h"
|
2010-04-26 23:52:03 -07:00
|
|
|
#include "nsRelUtils.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
#include "nsStateMap.h"
|
|
|
|
|
|
|
|
#include "nsMaiInterfaceComponent.h"
|
|
|
|
#include "nsMaiInterfaceAction.h"
|
|
|
|
#include "nsMaiInterfaceText.h"
|
|
|
|
#include "nsMaiInterfaceEditableText.h"
|
|
|
|
#include "nsMaiInterfaceSelection.h"
|
|
|
|
#include "nsMaiInterfaceValue.h"
|
|
|
|
#include "nsMaiInterfaceHypertext.h"
|
|
|
|
#include "nsMaiInterfaceHyperlinkImpl.h"
|
|
|
|
#include "nsMaiInterfaceTable.h"
|
|
|
|
#include "nsXPCOMStrings.h"
|
|
|
|
#include "nsComponentManagerUtils.h"
|
|
|
|
#include "nsMaiInterfaceDocument.h"
|
|
|
|
#include "nsMaiInterfaceImage.h"
|
|
|
|
|
2009-08-21 05:33:31 -07:00
|
|
|
//defined in nsApplicationAccessibleWrap.cpp
|
|
|
|
extern "C" GType g_atk_hyperlink_impl_type;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
/* MaiAtkObject */
|
|
|
|
|
|
|
|
enum {
|
|
|
|
ACTIVATE,
|
|
|
|
CREATE,
|
|
|
|
DEACTIVATE,
|
|
|
|
DESTROY,
|
|
|
|
MAXIMIZE,
|
|
|
|
MINIMIZE,
|
|
|
|
RESIZE,
|
|
|
|
RESTORE,
|
|
|
|
LAST_SIGNAL
|
|
|
|
};
|
|
|
|
|
|
|
|
enum MaiInterfaceType {
|
|
|
|
MAI_INTERFACE_COMPONENT, /* 0 */
|
|
|
|
MAI_INTERFACE_ACTION,
|
|
|
|
MAI_INTERFACE_VALUE,
|
|
|
|
MAI_INTERFACE_EDITABLE_TEXT,
|
|
|
|
MAI_INTERFACE_HYPERTEXT,
|
|
|
|
MAI_INTERFACE_HYPERLINK_IMPL,
|
|
|
|
MAI_INTERFACE_SELECTION,
|
|
|
|
MAI_INTERFACE_TABLE,
|
|
|
|
MAI_INTERFACE_TEXT,
|
|
|
|
MAI_INTERFACE_DOCUMENT,
|
|
|
|
MAI_INTERFACE_IMAGE /* 10 */
|
|
|
|
};
|
|
|
|
|
|
|
|
static GType GetAtkTypeForMai(MaiInterfaceType type)
|
|
|
|
{
|
|
|
|
switch (type) {
|
|
|
|
case MAI_INTERFACE_COMPONENT:
|
|
|
|
return ATK_TYPE_COMPONENT;
|
|
|
|
case MAI_INTERFACE_ACTION:
|
|
|
|
return ATK_TYPE_ACTION;
|
|
|
|
case MAI_INTERFACE_VALUE:
|
|
|
|
return ATK_TYPE_VALUE;
|
|
|
|
case MAI_INTERFACE_EDITABLE_TEXT:
|
|
|
|
return ATK_TYPE_EDITABLE_TEXT;
|
|
|
|
case MAI_INTERFACE_HYPERTEXT:
|
|
|
|
return ATK_TYPE_HYPERTEXT;
|
|
|
|
case MAI_INTERFACE_HYPERLINK_IMPL:
|
|
|
|
return g_atk_hyperlink_impl_type;
|
|
|
|
case MAI_INTERFACE_SELECTION:
|
|
|
|
return ATK_TYPE_SELECTION;
|
|
|
|
case MAI_INTERFACE_TABLE:
|
|
|
|
return ATK_TYPE_TABLE;
|
|
|
|
case MAI_INTERFACE_TEXT:
|
|
|
|
return ATK_TYPE_TEXT;
|
|
|
|
case MAI_INTERFACE_DOCUMENT:
|
|
|
|
return ATK_TYPE_DOCUMENT;
|
|
|
|
case MAI_INTERFACE_IMAGE:
|
|
|
|
return ATK_TYPE_IMAGE;
|
|
|
|
}
|
|
|
|
return G_TYPE_INVALID;
|
|
|
|
}
|
|
|
|
|
2007-09-18 14:40:04 -07:00
|
|
|
static const char* kNonUserInputEvent = ":system";
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
static const GInterfaceInfo atk_if_infos[] = {
|
|
|
|
{(GInterfaceInitFunc)componentInterfaceInitCB,
|
|
|
|
(GInterfaceFinalizeFunc) NULL, NULL},
|
|
|
|
{(GInterfaceInitFunc)actionInterfaceInitCB,
|
|
|
|
(GInterfaceFinalizeFunc) NULL, NULL},
|
|
|
|
{(GInterfaceInitFunc)valueInterfaceInitCB,
|
|
|
|
(GInterfaceFinalizeFunc) NULL, NULL},
|
|
|
|
{(GInterfaceInitFunc)editableTextInterfaceInitCB,
|
|
|
|
(GInterfaceFinalizeFunc) NULL, NULL},
|
|
|
|
{(GInterfaceInitFunc)hypertextInterfaceInitCB,
|
|
|
|
(GInterfaceFinalizeFunc) NULL, NULL},
|
|
|
|
{(GInterfaceInitFunc)hyperlinkImplInterfaceInitCB,
|
|
|
|
(GInterfaceFinalizeFunc) NULL, NULL},
|
|
|
|
{(GInterfaceInitFunc)selectionInterfaceInitCB,
|
|
|
|
(GInterfaceFinalizeFunc) NULL, NULL},
|
|
|
|
{(GInterfaceInitFunc)tableInterfaceInitCB,
|
|
|
|
(GInterfaceFinalizeFunc) NULL, NULL},
|
|
|
|
{(GInterfaceInitFunc)textInterfaceInitCB,
|
|
|
|
(GInterfaceFinalizeFunc) NULL, NULL},
|
|
|
|
{(GInterfaceInitFunc)documentInterfaceInitCB,
|
|
|
|
(GInterfaceFinalizeFunc) NULL, NULL},
|
|
|
|
{(GInterfaceInitFunc)imageInterfaceInitCB,
|
|
|
|
(GInterfaceFinalizeFunc) NULL, NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This MaiAtkObject is a thin wrapper, in the MAI namespace, for AtkObject
|
|
|
|
*/
|
|
|
|
struct MaiAtkObject
|
|
|
|
{
|
|
|
|
AtkObject parent;
|
|
|
|
/*
|
|
|
|
* The nsAccessibleWrap whose properties and features are exported
|
|
|
|
* via this object instance.
|
|
|
|
*/
|
|
|
|
nsAccessibleWrap *accWrap;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct MaiAtkObjectClass
|
|
|
|
{
|
|
|
|
AtkObjectClass parent_class;
|
|
|
|
};
|
|
|
|
|
|
|
|
static guint mai_atk_object_signals [LAST_SIGNAL] = { 0, };
|
|
|
|
|
|
|
|
#ifdef MAI_LOGGING
|
|
|
|
PRInt32 sMaiAtkObjCreated = 0;
|
|
|
|
PRInt32 sMaiAtkObjDeleted = 0;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
G_BEGIN_DECLS
|
|
|
|
/* callbacks for MaiAtkObject */
|
|
|
|
static void classInitCB(AtkObjectClass *aClass);
|
|
|
|
static void initializeCB(AtkObject *aAtkObj, gpointer aData);
|
|
|
|
static void finalizeCB(GObject *aObj);
|
|
|
|
|
|
|
|
/* callbacks for AtkObject virtual functions */
|
|
|
|
static const gchar* getNameCB (AtkObject *aAtkObj);
|
|
|
|
/* getDescriptionCB is also used by image interface */
|
|
|
|
const gchar* getDescriptionCB (AtkObject *aAtkObj);
|
|
|
|
static AtkRole getRoleCB(AtkObject *aAtkObj);
|
|
|
|
static AtkAttributeSet* getAttributesCB(AtkObject *aAtkObj);
|
|
|
|
static AtkObject* getParentCB(AtkObject *aAtkObj);
|
|
|
|
static gint getChildCountCB(AtkObject *aAtkObj);
|
|
|
|
static AtkObject* refChildCB(AtkObject *aAtkObj, gint aChildIndex);
|
|
|
|
static gint getIndexInParentCB(AtkObject *aAtkObj);
|
|
|
|
static AtkStateSet* refStateSetCB(AtkObject *aAtkObj);
|
|
|
|
static AtkRelationSet* refRelationSetCB(AtkObject *aAtkObj);
|
|
|
|
|
|
|
|
/* the missing atkobject virtual functions */
|
|
|
|
/*
|
|
|
|
static AtkLayer getLayerCB(AtkObject *aAtkObj);
|
|
|
|
static gint getMdiZorderCB(AtkObject *aAtkObj);
|
|
|
|
static void SetNameCB(AtkObject *aAtkObj,
|
|
|
|
const gchar *name);
|
|
|
|
static void SetDescriptionCB(AtkObject *aAtkObj,
|
|
|
|
const gchar *description);
|
|
|
|
static void SetParentCB(AtkObject *aAtkObj,
|
|
|
|
AtkObject *parent);
|
|
|
|
static void SetRoleCB(AtkObject *aAtkObj,
|
|
|
|
AtkRole role);
|
|
|
|
static guint ConnectPropertyChangeHandlerCB(
|
|
|
|
AtkObject *aObj,
|
|
|
|
AtkPropertyChangeHandler *handler);
|
|
|
|
static void RemovePropertyChangeHandlerCB(
|
|
|
|
AtkObject *aAtkObj,
|
|
|
|
guint handler_id);
|
|
|
|
static void InitializeCB(AtkObject *aAtkObj,
|
|
|
|
gpointer data);
|
|
|
|
static void ChildrenChangedCB(AtkObject *aAtkObj,
|
|
|
|
guint change_index,
|
|
|
|
gpointer changed_child);
|
|
|
|
static void FocusEventCB(AtkObject *aAtkObj,
|
|
|
|
gboolean focus_in);
|
|
|
|
static void PropertyChangeCB(AtkObject *aAtkObj,
|
|
|
|
AtkPropertyValues *values);
|
|
|
|
static void StateChangeCB(AtkObject *aAtkObj,
|
|
|
|
const gchar *name,
|
|
|
|
gboolean state_set);
|
|
|
|
static void VisibleDataChangedCB(AtkObject *aAtkObj);
|
|
|
|
*/
|
|
|
|
G_END_DECLS
|
|
|
|
|
|
|
|
static GType GetMaiAtkType(PRUint16 interfacesBits);
|
|
|
|
static const char * GetUniqueMaiAtkTypeName(PRUint16 interfacesBits);
|
|
|
|
|
|
|
|
static gpointer parent_class = NULL;
|
|
|
|
|
2007-05-28 23:41:14 -07:00
|
|
|
static GQuark quark_mai_hyperlink = 0;
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
GType
|
|
|
|
mai_atk_object_get_type(void)
|
|
|
|
{
|
|
|
|
static GType type = 0;
|
|
|
|
|
|
|
|
if (!type) {
|
|
|
|
static const GTypeInfo tinfo = {
|
|
|
|
sizeof(MaiAtkObjectClass),
|
|
|
|
(GBaseInitFunc)NULL,
|
|
|
|
(GBaseFinalizeFunc)NULL,
|
|
|
|
(GClassInitFunc)classInitCB,
|
|
|
|
(GClassFinalizeFunc)NULL,
|
|
|
|
NULL, /* class data */
|
|
|
|
sizeof(MaiAtkObject), /* instance size */
|
|
|
|
0, /* nb preallocs */
|
|
|
|
(GInstanceInitFunc)NULL,
|
|
|
|
NULL /* value table */
|
|
|
|
};
|
|
|
|
|
|
|
|
type = g_type_register_static(ATK_TYPE_OBJECT,
|
|
|
|
"MaiAtkObject", &tinfo, GTypeFlags(0));
|
2007-05-28 23:41:14 -07:00
|
|
|
quark_mai_hyperlink = g_quark_from_static_string("MaiHyperlink");
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
return type;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef MAI_LOGGING
|
|
|
|
PRInt32 nsAccessibleWrap::mAccWrapCreated = 0;
|
|
|
|
PRInt32 nsAccessibleWrap::mAccWrapDeleted = 0;
|
|
|
|
#endif
|
|
|
|
|
2010-06-11 01:23:18 -07:00
|
|
|
nsAccessibleWrap::
|
|
|
|
nsAccessibleWrap(nsIContent *aContent, nsIWeakReference *aShell) :
|
|
|
|
nsAccessible(aContent, aShell), mAtkObject(nsnull)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
#ifdef MAI_LOGGING
|
|
|
|
++mAccWrapCreated;
|
|
|
|
#endif
|
|
|
|
MAI_LOG_DEBUG(("==nsAccessibleWrap creating: this=%p,total=%d left=%d\n",
|
|
|
|
(void*)this, mAccWrapCreated,
|
|
|
|
(mAccWrapCreated-mAccWrapDeleted)));
|
|
|
|
}
|
|
|
|
|
|
|
|
nsAccessibleWrap::~nsAccessibleWrap()
|
|
|
|
{
|
2008-01-21 21:29:40 -08:00
|
|
|
NS_ASSERTION(!mAtkObject, "ShutdownAtkObject() is not called");
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
#ifdef MAI_LOGGING
|
|
|
|
++mAccWrapDeleted;
|
|
|
|
#endif
|
|
|
|
MAI_LOG_DEBUG(("==nsAccessibleWrap deleting: this=%p,total=%d left=%d\n",
|
|
|
|
(void*)this, mAccWrapDeleted,
|
|
|
|
(mAccWrapCreated-mAccWrapDeleted)));
|
2007-05-28 23:41:14 -07:00
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2007-07-02 04:18:07 -07:00
|
|
|
void nsAccessibleWrap::ShutdownAtkObject()
|
2007-05-28 23:41:14 -07:00
|
|
|
{
|
2007-03-22 10:30:00 -07:00
|
|
|
if (mAtkObject) {
|
|
|
|
if (IS_MAI_OBJECT(mAtkObject)) {
|
|
|
|
MAI_ATK_OBJECT(mAtkObject)->accWrap = nsnull;
|
|
|
|
}
|
2007-05-28 23:41:14 -07:00
|
|
|
SetMaiHyperlink(nsnull);
|
2007-03-22 10:30:00 -07:00
|
|
|
g_object_unref(mAtkObject);
|
2007-05-28 23:41:14 -07:00
|
|
|
mAtkObject = nsnull;
|
|
|
|
}
|
2007-07-02 04:18:07 -07:00
|
|
|
}
|
|
|
|
|
2010-06-11 21:04:35 -07:00
|
|
|
void
|
2008-10-31 20:58:07 -07:00
|
|
|
nsAccessibleWrap::Shutdown()
|
2007-07-02 04:18:07 -07:00
|
|
|
{
|
|
|
|
ShutdownAtkObject();
|
2010-06-11 21:04:35 -07:00
|
|
|
nsAccessible::Shutdown();
|
2007-05-28 23:41:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
MaiHyperlink* nsAccessibleWrap::GetMaiHyperlink(PRBool aCreate /* = PR_TRUE */)
|
|
|
|
{
|
|
|
|
// make sure mAtkObject is created
|
|
|
|
GetAtkObject();
|
|
|
|
|
|
|
|
NS_ASSERTION(quark_mai_hyperlink, "quark_mai_hyperlink not initialized");
|
|
|
|
NS_ASSERTION(IS_MAI_OBJECT(mAtkObject), "Invalid AtkObject");
|
|
|
|
MaiHyperlink* maiHyperlink = nsnull;
|
|
|
|
if (quark_mai_hyperlink && IS_MAI_OBJECT(mAtkObject)) {
|
|
|
|
maiHyperlink = (MaiHyperlink*)g_object_get_qdata(G_OBJECT(mAtkObject),
|
|
|
|
quark_mai_hyperlink);
|
|
|
|
if (!maiHyperlink && aCreate) {
|
|
|
|
maiHyperlink = new MaiHyperlink(this);
|
|
|
|
SetMaiHyperlink(maiHyperlink);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return maiHyperlink;
|
|
|
|
}
|
|
|
|
|
|
|
|
void nsAccessibleWrap::SetMaiHyperlink(MaiHyperlink* aMaiHyperlink)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(quark_mai_hyperlink, "quark_mai_hyperlink not initialized");
|
|
|
|
NS_ASSERTION(IS_MAI_OBJECT(mAtkObject), "Invalid AtkObject");
|
|
|
|
if (quark_mai_hyperlink && IS_MAI_OBJECT(mAtkObject)) {
|
|
|
|
MaiHyperlink* maiHyperlink = GetMaiHyperlink(PR_FALSE);
|
|
|
|
if (!maiHyperlink && !aMaiHyperlink) {
|
|
|
|
return; // Never set and we're shutting down
|
|
|
|
}
|
|
|
|
if (maiHyperlink) {
|
|
|
|
delete maiHyperlink;
|
|
|
|
}
|
|
|
|
g_object_set_qdata(G_OBJECT(mAtkObject), quark_mai_hyperlink,
|
|
|
|
aMaiHyperlink);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsAccessibleWrap::GetNativeInterface(void **aOutAccessible)
|
|
|
|
{
|
|
|
|
*aOutAccessible = nsnull;
|
|
|
|
|
|
|
|
if (!mAtkObject) {
|
2008-10-17 03:10:43 -07:00
|
|
|
if (!mWeakShell || !nsAccUtils::IsEmbeddedObject(this)) {
|
2008-06-10 23:20:12 -07:00
|
|
|
// We don't create ATK objects for node which has been shutdown, or
|
|
|
|
// nsIAccessible plain text leaves
|
2007-06-04 01:37:33 -07:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
GType type = GetMaiAtkType(CreateMaiInterfaces());
|
|
|
|
NS_ENSURE_TRUE(type, NS_ERROR_FAILURE);
|
|
|
|
mAtkObject =
|
2007-07-08 00:08:04 -07:00
|
|
|
reinterpret_cast<AtkObject *>
|
|
|
|
(g_object_new(type, NULL));
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_ENSURE_TRUE(mAtkObject, NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
|
|
|
|
atk_object_initialize(mAtkObject, this);
|
|
|
|
mAtkObject->role = ATK_ROLE_INVALID;
|
|
|
|
mAtkObject->layer = ATK_LAYER_INVALID;
|
|
|
|
}
|
|
|
|
|
|
|
|
*aOutAccessible = mAtkObject;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
AtkObject *
|
|
|
|
nsAccessibleWrap::GetAtkObject(void)
|
|
|
|
{
|
|
|
|
void *atkObj = nsnull;
|
|
|
|
GetNativeInterface(&atkObj);
|
2007-07-08 00:08:04 -07:00
|
|
|
return static_cast<AtkObject *>(atkObj);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2007-06-08 02:09:24 -07:00
|
|
|
// Get AtkObject from nsIAccessible interface
|
|
|
|
/* static */
|
|
|
|
AtkObject *
|
|
|
|
nsAccessibleWrap::GetAtkObject(nsIAccessible * acc)
|
|
|
|
{
|
|
|
|
void *atkObjPtr = nsnull;
|
|
|
|
acc->GetNativeInterface(&atkObjPtr);
|
|
|
|
return atkObjPtr ? ATK_OBJECT(atkObjPtr) : nsnull;
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
/* private */
|
|
|
|
PRUint16
|
|
|
|
nsAccessibleWrap::CreateMaiInterfaces(void)
|
|
|
|
{
|
|
|
|
PRUint16 interfacesBits = 0;
|
|
|
|
|
|
|
|
// Add Interfaces for each nsIAccessible.ext interfaces
|
|
|
|
|
|
|
|
// the Component interface are supported by all nsIAccessible
|
|
|
|
interfacesBits |= 1 << MAI_INTERFACE_COMPONENT;
|
|
|
|
|
|
|
|
// Add Action interface if the action count is more than zero.
|
|
|
|
PRUint8 actionCount = 0;
|
|
|
|
nsresult rv = GetNumActions(&actionCount);
|
|
|
|
if (NS_SUCCEEDED(rv) && actionCount > 0) {
|
|
|
|
interfacesBits |= 1 << MAI_INTERFACE_ACTION;
|
|
|
|
}
|
|
|
|
|
|
|
|
//nsIAccessibleText
|
|
|
|
nsCOMPtr<nsIAccessibleText> accessInterfaceText;
|
|
|
|
QueryInterface(NS_GET_IID(nsIAccessibleText),
|
|
|
|
getter_AddRefs(accessInterfaceText));
|
|
|
|
if (accessInterfaceText) {
|
|
|
|
interfacesBits |= 1 << MAI_INTERFACE_TEXT;
|
|
|
|
}
|
|
|
|
|
|
|
|
//nsIAccessibleEditableText
|
|
|
|
nsCOMPtr<nsIAccessibleEditableText> accessInterfaceEditableText;
|
|
|
|
QueryInterface(NS_GET_IID(nsIAccessibleEditableText),
|
|
|
|
getter_AddRefs(accessInterfaceEditableText));
|
|
|
|
if (accessInterfaceEditableText) {
|
|
|
|
interfacesBits |= 1 << MAI_INTERFACE_EDITABLE_TEXT;
|
|
|
|
}
|
|
|
|
|
|
|
|
//nsIAccessibleValue
|
|
|
|
nsCOMPtr<nsIAccessibleValue> accessInterfaceValue;
|
|
|
|
QueryInterface(NS_GET_IID(nsIAccessibleValue),
|
|
|
|
getter_AddRefs(accessInterfaceValue));
|
|
|
|
if (accessInterfaceValue) {
|
|
|
|
interfacesBits |= 1 << MAI_INTERFACE_VALUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
//nsIAccessibleDocument
|
|
|
|
nsCOMPtr<nsIAccessibleDocument> accessInterfaceDocument;
|
|
|
|
QueryInterface(NS_GET_IID(nsIAccessibleDocument),
|
|
|
|
getter_AddRefs(accessInterfaceDocument));
|
|
|
|
if (accessInterfaceDocument) {
|
|
|
|
interfacesBits |= 1 << MAI_INTERFACE_DOCUMENT;
|
|
|
|
}
|
|
|
|
|
|
|
|
//nsIAccessibleImage
|
|
|
|
nsCOMPtr<nsIAccessibleImage> accessInterfaceImage;
|
|
|
|
QueryInterface(NS_GET_IID(nsIAccessibleImage),
|
|
|
|
getter_AddRefs(accessInterfaceImage));
|
|
|
|
if (accessInterfaceImage) {
|
|
|
|
interfacesBits |= 1 << MAI_INTERFACE_IMAGE;
|
|
|
|
}
|
|
|
|
|
2010-08-31 20:26:13 -07:00
|
|
|
// HyperLinkAccessible
|
|
|
|
if (IsHyperLink()) {
|
2007-08-03 19:15:52 -07:00
|
|
|
interfacesBits |= 1 << MAI_INTERFACE_HYPERLINK_IMPL;
|
|
|
|
}
|
|
|
|
|
2008-10-17 03:10:43 -07:00
|
|
|
if (!nsAccUtils::MustPrune(this)) { // These interfaces require children
|
2007-08-03 19:15:52 -07:00
|
|
|
//nsIAccessibleHypertext
|
|
|
|
nsCOMPtr<nsIAccessibleHyperText> accessInterfaceHypertext;
|
|
|
|
QueryInterface(NS_GET_IID(nsIAccessibleHyperText),
|
|
|
|
getter_AddRefs(accessInterfaceHypertext));
|
|
|
|
if (accessInterfaceHypertext) {
|
2007-08-06 23:10:31 -07:00
|
|
|
interfacesBits |= 1 << MAI_INTERFACE_HYPERTEXT;
|
2007-08-03 19:15:52 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//nsIAccessibleTable
|
|
|
|
nsCOMPtr<nsIAccessibleTable> accessInterfaceTable;
|
|
|
|
QueryInterface(NS_GET_IID(nsIAccessibleTable),
|
|
|
|
getter_AddRefs(accessInterfaceTable));
|
|
|
|
if (accessInterfaceTable) {
|
|
|
|
interfacesBits |= 1 << MAI_INTERFACE_TABLE;
|
|
|
|
}
|
|
|
|
|
|
|
|
//nsIAccessibleSelection
|
|
|
|
nsCOMPtr<nsIAccessibleSelectable> accessInterfaceSelection;
|
|
|
|
QueryInterface(NS_GET_IID(nsIAccessibleSelectable),
|
|
|
|
getter_AddRefs(accessInterfaceSelection));
|
|
|
|
if (accessInterfaceSelection) {
|
|
|
|
interfacesBits |= 1 << MAI_INTERFACE_SELECTION;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
return interfacesBits;
|
|
|
|
}
|
|
|
|
|
|
|
|
static GType
|
|
|
|
GetMaiAtkType(PRUint16 interfacesBits)
|
|
|
|
{
|
|
|
|
GType type;
|
|
|
|
static const GTypeInfo tinfo = {
|
|
|
|
sizeof(MaiAtkObjectClass),
|
|
|
|
(GBaseInitFunc) NULL,
|
|
|
|
(GBaseFinalizeFunc) NULL,
|
|
|
|
(GClassInitFunc) NULL,
|
|
|
|
(GClassFinalizeFunc) NULL,
|
|
|
|
NULL, /* class data */
|
|
|
|
sizeof(MaiAtkObject), /* instance size */
|
|
|
|
0, /* nb preallocs */
|
|
|
|
(GInstanceInitFunc) NULL,
|
|
|
|
NULL /* value table */
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The members we use to register GTypes are GetAtkTypeForMai
|
|
|
|
* and atk_if_infos, which are constant values to each MaiInterface
|
|
|
|
* So we can reuse the registered GType when having
|
|
|
|
* the same MaiInterface types.
|
|
|
|
*/
|
|
|
|
const char *atkTypeName = GetUniqueMaiAtkTypeName(interfacesBits);
|
|
|
|
type = g_type_from_name(atkTypeName);
|
|
|
|
if (type) {
|
|
|
|
return type;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* gobject limits the number of types that can directly derive from any
|
|
|
|
* given object type to 4095.
|
|
|
|
*/
|
|
|
|
static PRUint16 typeRegCount = 0;
|
|
|
|
if (typeRegCount++ >= 4095) {
|
|
|
|
return G_TYPE_INVALID;
|
|
|
|
}
|
|
|
|
type = g_type_register_static(MAI_TYPE_ATK_OBJECT,
|
|
|
|
atkTypeName,
|
|
|
|
&tinfo, GTypeFlags(0));
|
|
|
|
|
|
|
|
for (PRUint32 index = 0; index < NS_ARRAY_LENGTH(atk_if_infos); index++) {
|
|
|
|
if (interfacesBits & (1 << index)) {
|
|
|
|
g_type_add_interface_static(type,
|
|
|
|
GetAtkTypeForMai((MaiInterfaceType)index),
|
|
|
|
&atk_if_infos[index]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return type;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *
|
|
|
|
GetUniqueMaiAtkTypeName(PRUint16 interfacesBits)
|
|
|
|
{
|
|
|
|
#define MAI_ATK_TYPE_NAME_LEN (30) /* 10+sizeof(PRUint16)*8/4+1 < 30 */
|
|
|
|
|
|
|
|
static gchar namePrefix[] = "MaiAtkType"; /* size = 10 */
|
|
|
|
static gchar name[MAI_ATK_TYPE_NAME_LEN + 1];
|
|
|
|
|
|
|
|
PR_snprintf(name, MAI_ATK_TYPE_NAME_LEN, "%s%x", namePrefix,
|
|
|
|
interfacesBits);
|
|
|
|
name[MAI_ATK_TYPE_NAME_LEN] = '\0';
|
|
|
|
|
|
|
|
MAI_LOG_DEBUG(("MaiWidget::LastedTypeName=%s\n", name));
|
|
|
|
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRBool nsAccessibleWrap::IsValidObject()
|
|
|
|
{
|
|
|
|
// to ensure we are not shut down
|
2010-06-11 01:23:18 -07:00
|
|
|
return !IsDefunct();
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* static functions for ATK callbacks */
|
|
|
|
void
|
|
|
|
classInitCB(AtkObjectClass *aClass)
|
|
|
|
{
|
|
|
|
GObjectClass *gobject_class = G_OBJECT_CLASS(aClass);
|
|
|
|
|
|
|
|
parent_class = g_type_class_peek_parent(aClass);
|
|
|
|
|
|
|
|
aClass->get_name = getNameCB;
|
|
|
|
aClass->get_description = getDescriptionCB;
|
|
|
|
aClass->get_parent = getParentCB;
|
|
|
|
aClass->get_n_children = getChildCountCB;
|
|
|
|
aClass->ref_child = refChildCB;
|
|
|
|
aClass->get_index_in_parent = getIndexInParentCB;
|
|
|
|
aClass->get_role = getRoleCB;
|
|
|
|
aClass->get_attributes = getAttributesCB;
|
|
|
|
aClass->ref_state_set = refStateSetCB;
|
|
|
|
aClass->ref_relation_set = refRelationSetCB;
|
|
|
|
|
|
|
|
aClass->initialize = initializeCB;
|
|
|
|
|
|
|
|
gobject_class->finalize = finalizeCB;
|
|
|
|
|
|
|
|
mai_atk_object_signals [ACTIVATE] =
|
|
|
|
g_signal_new ("activate",
|
|
|
|
MAI_TYPE_ATK_OBJECT,
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0, /* default signal handler */
|
|
|
|
NULL, NULL,
|
|
|
|
g_cclosure_marshal_VOID__VOID,
|
|
|
|
G_TYPE_NONE, 0);
|
|
|
|
mai_atk_object_signals [CREATE] =
|
|
|
|
g_signal_new ("create",
|
|
|
|
MAI_TYPE_ATK_OBJECT,
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0, /* default signal handler */
|
|
|
|
NULL, NULL,
|
|
|
|
g_cclosure_marshal_VOID__VOID,
|
|
|
|
G_TYPE_NONE, 0);
|
|
|
|
mai_atk_object_signals [DEACTIVATE] =
|
|
|
|
g_signal_new ("deactivate",
|
|
|
|
MAI_TYPE_ATK_OBJECT,
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0, /* default signal handler */
|
|
|
|
NULL, NULL,
|
|
|
|
g_cclosure_marshal_VOID__VOID,
|
|
|
|
G_TYPE_NONE, 0);
|
|
|
|
mai_atk_object_signals [DESTROY] =
|
|
|
|
g_signal_new ("destroy",
|
|
|
|
MAI_TYPE_ATK_OBJECT,
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0, /* default signal handler */
|
|
|
|
NULL, NULL,
|
|
|
|
g_cclosure_marshal_VOID__VOID,
|
|
|
|
G_TYPE_NONE, 0);
|
|
|
|
mai_atk_object_signals [MAXIMIZE] =
|
|
|
|
g_signal_new ("maximize",
|
|
|
|
MAI_TYPE_ATK_OBJECT,
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0, /* default signal handler */
|
|
|
|
NULL, NULL,
|
|
|
|
g_cclosure_marshal_VOID__VOID,
|
|
|
|
G_TYPE_NONE, 0);
|
|
|
|
mai_atk_object_signals [MINIMIZE] =
|
|
|
|
g_signal_new ("minimize",
|
|
|
|
MAI_TYPE_ATK_OBJECT,
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0, /* default signal handler */
|
|
|
|
NULL, NULL,
|
|
|
|
g_cclosure_marshal_VOID__VOID,
|
|
|
|
G_TYPE_NONE, 0);
|
|
|
|
mai_atk_object_signals [RESIZE] =
|
|
|
|
g_signal_new ("resize",
|
|
|
|
MAI_TYPE_ATK_OBJECT,
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0, /* default signal handler */
|
|
|
|
NULL, NULL,
|
|
|
|
g_cclosure_marshal_VOID__VOID,
|
|
|
|
G_TYPE_NONE, 0);
|
|
|
|
mai_atk_object_signals [RESTORE] =
|
|
|
|
g_signal_new ("restore",
|
|
|
|
MAI_TYPE_ATK_OBJECT,
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0, /* default signal handler */
|
|
|
|
NULL, NULL,
|
|
|
|
g_cclosure_marshal_VOID__VOID,
|
|
|
|
G_TYPE_NONE, 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
initializeCB(AtkObject *aAtkObj, gpointer aData)
|
|
|
|
{
|
|
|
|
NS_ASSERTION((IS_MAI_OBJECT(aAtkObj)), "Invalid AtkObject");
|
|
|
|
NS_ASSERTION(aData, "Invalid Data to init AtkObject");
|
|
|
|
if (!aAtkObj || !aData)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* 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(aAtkObj, aData);
|
|
|
|
|
|
|
|
/* initialize object */
|
|
|
|
MAI_ATK_OBJECT(aAtkObj)->accWrap =
|
2007-07-08 00:08:04 -07:00
|
|
|
static_cast<nsAccessibleWrap*>(aData);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
#ifdef MAI_LOGGING
|
|
|
|
++sMaiAtkObjCreated;
|
|
|
|
#endif
|
|
|
|
MAI_LOG_DEBUG(("MaiAtkObj Create obj=%p for AccWrap=%p, all=%d, left=%d\n",
|
|
|
|
(void*)aAtkObj, (void*)aData, sMaiAtkObjCreated,
|
|
|
|
(sMaiAtkObjCreated-sMaiAtkObjDeleted)));
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
finalizeCB(GObject *aObj)
|
|
|
|
{
|
|
|
|
if (!IS_MAI_OBJECT(aObj))
|
|
|
|
return;
|
|
|
|
NS_ASSERTION(MAI_ATK_OBJECT(aObj)->accWrap == nsnull, "AccWrap NOT null");
|
|
|
|
|
|
|
|
#ifdef MAI_LOGGING
|
|
|
|
++sMaiAtkObjDeleted;
|
|
|
|
#endif
|
|
|
|
MAI_LOG_DEBUG(("MaiAtkObj Delete obj=%p, all=%d, left=%d\n",
|
|
|
|
(void*)aObj, sMaiAtkObjCreated,
|
|
|
|
(sMaiAtkObjCreated-sMaiAtkObjDeleted)));
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
}
|
|
|
|
|
|
|
|
const gchar *
|
|
|
|
getNameCB(AtkObject *aAtkObj)
|
|
|
|
{
|
2007-06-04 02:39:15 -07:00
|
|
|
nsAccessibleWrap *accWrap = GetAccessibleWrap(aAtkObj);
|
2007-06-08 02:09:24 -07:00
|
|
|
if (!accWrap) {
|
|
|
|
return nsnull;
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
/* nsIAccessible is responsible for the non-NULL name */
|
2007-06-08 02:09:24 -07:00
|
|
|
nsAutoString uniName;
|
2007-03-22 10:30:00 -07:00
|
|
|
nsresult rv = accWrap->GetName(uniName);
|
|
|
|
NS_ENSURE_SUCCESS(rv, nsnull);
|
|
|
|
|
2007-06-08 02:09:24 -07:00
|
|
|
NS_ConvertUTF8toUTF16 objName(aAtkObj->name);
|
|
|
|
if (!uniName.Equals(objName)) {
|
|
|
|
atk_object_set_name(aAtkObj,
|
|
|
|
NS_ConvertUTF16toUTF8(uniName).get());
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
return aAtkObj->name;
|
|
|
|
}
|
|
|
|
|
|
|
|
const gchar *
|
|
|
|
getDescriptionCB(AtkObject *aAtkObj)
|
|
|
|
{
|
2007-06-08 02:09:24 -07:00
|
|
|
nsAccessibleWrap *accWrap = GetAccessibleWrap(aAtkObj);
|
|
|
|
if (!accWrap) {
|
|
|
|
return nsnull;
|
2007-04-30 22:57:51 -07:00
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2007-06-08 02:09:24 -07:00
|
|
|
/* nsIAccessible is responsible for the non-NULL description */
|
|
|
|
nsAutoString uniDesc;
|
|
|
|
nsresult rv = accWrap->GetDescription(uniDesc);
|
|
|
|
NS_ENSURE_SUCCESS(rv, nsnull);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2007-06-08 02:09:24 -07:00
|
|
|
NS_ConvertUTF8toUTF16 objDesc(aAtkObj->description);
|
|
|
|
if (!uniDesc.Equals(objDesc)) {
|
|
|
|
atk_object_set_description(aAtkObj,
|
|
|
|
NS_ConvertUTF16toUTF8(uniDesc).get());
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
return aAtkObj->description;
|
|
|
|
}
|
|
|
|
|
|
|
|
AtkRole
|
|
|
|
getRoleCB(AtkObject *aAtkObj)
|
|
|
|
{
|
2007-06-08 02:09:24 -07:00
|
|
|
nsAccessibleWrap *accWrap = GetAccessibleWrap(aAtkObj);
|
|
|
|
if (!accWrap) {
|
|
|
|
return ATK_ROLE_INVALID;
|
2007-04-30 22:57:51 -07:00
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
#ifdef DEBUG_A11Y
|
2008-10-17 03:10:43 -07:00
|
|
|
NS_ASSERTION(nsAccUtils::IsTextInterfaceSupportCorrect(accWrap),
|
|
|
|
"Does not support nsIAccessibleText when it should");
|
2007-03-22 10:30:00 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
if (aAtkObj->role == ATK_ROLE_INVALID) {
|
|
|
|
PRUint32 accRole, atkRole;
|
2009-03-07 07:38:58 -08:00
|
|
|
nsresult rv = accWrap->GetRole(&accRole);
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_ENSURE_SUCCESS(rv, ATK_ROLE_INVALID);
|
|
|
|
|
|
|
|
atkRole = atkRoleMap[accRole]; // map to the actual value
|
|
|
|
NS_ASSERTION(atkRoleMap[nsIAccessibleRole::ROLE_LAST_ENTRY] ==
|
|
|
|
kROLE_ATK_LAST_ENTRY, "ATK role map skewed");
|
2007-07-08 00:08:04 -07:00
|
|
|
aAtkObj->role = static_cast<AtkRole>(atkRole);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
return aAtkObj->role;
|
|
|
|
}
|
|
|
|
|
2008-07-17 05:06:24 -07:00
|
|
|
AtkAttributeSet*
|
|
|
|
ConvertToAtkAttributeSet(nsIPersistentProperties* aAttributes)
|
|
|
|
{
|
|
|
|
if (!aAttributes)
|
|
|
|
return nsnull;
|
|
|
|
|
|
|
|
AtkAttributeSet *objAttributeSet = nsnull;
|
|
|
|
nsCOMPtr<nsISimpleEnumerator> propEnum;
|
|
|
|
nsresult rv = aAttributes->Enumerate(getter_AddRefs(propEnum));
|
|
|
|
NS_ENSURE_SUCCESS(rv, nsnull);
|
|
|
|
|
|
|
|
PRBool hasMore;
|
|
|
|
while (NS_SUCCEEDED(propEnum->HasMoreElements(&hasMore)) && hasMore) {
|
|
|
|
nsCOMPtr<nsISupports> sup;
|
|
|
|
rv = propEnum->GetNext(getter_AddRefs(sup));
|
|
|
|
NS_ENSURE_SUCCESS(rv, objAttributeSet);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPropertyElement> propElem(do_QueryInterface(sup));
|
|
|
|
NS_ENSURE_TRUE(propElem, objAttributeSet);
|
|
|
|
|
|
|
|
nsCAutoString name;
|
|
|
|
rv = propElem->GetKey(name);
|
|
|
|
NS_ENSURE_SUCCESS(rv, objAttributeSet);
|
|
|
|
|
|
|
|
nsAutoString value;
|
|
|
|
rv = propElem->GetValue(value);
|
|
|
|
NS_ENSURE_SUCCESS(rv, objAttributeSet);
|
|
|
|
|
|
|
|
AtkAttribute *objAttr = (AtkAttribute *)g_malloc(sizeof(AtkAttribute));
|
|
|
|
objAttr->name = g_strdup(name.get());
|
|
|
|
objAttr->value = g_strdup(NS_ConvertUTF16toUTF8(value).get());
|
|
|
|
objAttributeSet = g_slist_prepend(objAttributeSet, objAttr);
|
|
|
|
}
|
|
|
|
|
|
|
|
//libspi will free it
|
|
|
|
return objAttributeSet;
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
AtkAttributeSet *
|
|
|
|
GetAttributeSet(nsIAccessible* aAccessible)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIPersistentProperties> attributes;
|
|
|
|
aAccessible->GetAttributes(getter_AddRefs(attributes));
|
2008-07-17 05:06:24 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
if (attributes) {
|
2007-07-04 00:54:56 -07:00
|
|
|
// Deal with attributes that we only need to expose in ATK
|
2007-09-18 14:40:04 -07:00
|
|
|
PRUint32 state;
|
2008-11-03 19:37:46 -08:00
|
|
|
aAccessible->GetState(&state, nsnull);
|
2007-07-04 01:38:54 -07:00
|
|
|
if (state & nsIAccessibleStates::STATE_HASPOPUP) {
|
2007-07-04 00:54:56 -07:00
|
|
|
// There is no ATK state for haspopup, must use object attribute to expose the same info
|
|
|
|
nsAutoString oldValueUnused;
|
2007-07-04 01:24:23 -07:00
|
|
|
attributes->SetStringProperty(NS_LITERAL_CSTRING("haspopup"), NS_LITERAL_STRING("true"),
|
2007-07-04 00:54:56 -07:00
|
|
|
oldValueUnused);
|
|
|
|
}
|
|
|
|
|
2008-07-17 05:06:24 -07:00
|
|
|
return ConvertToAtkAttributeSet(attributes);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2008-07-17 05:06:24 -07:00
|
|
|
return nsnull;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
AtkAttributeSet *
|
|
|
|
getAttributesCB(AtkObject *aAtkObj)
|
|
|
|
{
|
2007-06-04 02:39:15 -07:00
|
|
|
nsAccessibleWrap *accWrap = GetAccessibleWrap(aAtkObj);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2007-06-08 02:09:24 -07:00
|
|
|
return accWrap ? GetAttributeSet(accWrap) : nsnull;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
AtkObject *
|
|
|
|
getParentCB(AtkObject *aAtkObj)
|
|
|
|
{
|
2007-06-08 02:09:24 -07:00
|
|
|
if (!aAtkObj->accessible_parent) {
|
|
|
|
nsAccessibleWrap *accWrap = GetAccessibleWrap(aAtkObj);
|
|
|
|
if (!accWrap) {
|
|
|
|
return nsnull;
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2010-08-15 04:29:02 -07:00
|
|
|
nsAccessible* accParent = accWrap->GetParent();
|
|
|
|
if (!accParent)
|
2007-06-08 02:09:24 -07:00
|
|
|
return nsnull;
|
2007-06-04 02:39:15 -07:00
|
|
|
|
2008-07-18 04:21:04 -07:00
|
|
|
AtkObject *parent = nsAccessibleWrap::GetAtkObject(accParent);
|
|
|
|
if (parent)
|
|
|
|
atk_object_set_parent(aAtkObj, parent);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
2007-06-04 02:39:15 -07:00
|
|
|
return aAtkObj->accessible_parent;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
gint
|
|
|
|
getChildCountCB(AtkObject *aAtkObj)
|
|
|
|
{
|
2007-06-04 02:39:15 -07:00
|
|
|
nsAccessibleWrap *accWrap = GetAccessibleWrap(aAtkObj);
|
2008-10-17 03:10:43 -07:00
|
|
|
if (!accWrap || nsAccUtils::MustPrune(accWrap)) {
|
2007-06-08 02:09:24 -07:00
|
|
|
return 0;
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2010-08-15 04:29:02 -07:00
|
|
|
return accWrap->GetEmbeddedChildCount();
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
AtkObject *
|
|
|
|
refChildCB(AtkObject *aAtkObj, gint aChildIndex)
|
|
|
|
{
|
|
|
|
// aChildIndex should not be less than zero
|
|
|
|
if (aChildIndex < 0) {
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
2007-06-04 02:39:15 -07:00
|
|
|
nsAccessibleWrap *accWrap = GetAccessibleWrap(aAtkObj);
|
2008-10-17 03:10:43 -07:00
|
|
|
if (!accWrap || nsAccUtils::MustPrune(accWrap)) {
|
2007-06-08 02:09:24 -07:00
|
|
|
return nsnull;
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2010-08-15 04:29:02 -07:00
|
|
|
nsAccessible* accChild = accWrap->GetEmbeddedChildAt(aChildIndex);
|
2007-08-06 23:10:31 -07:00
|
|
|
if (!accChild)
|
2007-03-22 10:30:00 -07:00
|
|
|
return nsnull;
|
|
|
|
|
2007-06-08 02:09:24 -07:00
|
|
|
AtkObject* childAtkObj = nsAccessibleWrap::GetAtkObject(accChild);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2007-06-08 02:09:24 -07:00
|
|
|
NS_ASSERTION(childAtkObj, "Fail to get AtkObj");
|
|
|
|
if (!childAtkObj)
|
2007-03-22 10:30:00 -07:00
|
|
|
return nsnull;
|
2010-01-05 22:56:56 -08:00
|
|
|
g_object_ref(childAtkObj);
|
2007-06-04 02:39:15 -07:00
|
|
|
|
|
|
|
//this will addref parent
|
|
|
|
atk_object_set_parent(childAtkObj, aAtkObj);
|
2007-03-22 10:30:00 -07:00
|
|
|
return childAtkObj;
|
|
|
|
}
|
|
|
|
|
|
|
|
gint
|
|
|
|
getIndexInParentCB(AtkObject *aAtkObj)
|
|
|
|
{
|
|
|
|
// We don't use nsIAccessible::GetIndexInParent() because
|
|
|
|
// for ATK we don't want to include text leaf nodes as children
|
2007-06-04 02:39:15 -07:00
|
|
|
nsAccessibleWrap *accWrap = GetAccessibleWrap(aAtkObj);
|
2007-06-08 02:09:24 -07:00
|
|
|
if (!accWrap) {
|
|
|
|
return -1;
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2010-05-18 07:03:56 -07:00
|
|
|
nsAccessible *parent = accWrap->GetParent();
|
2007-03-22 10:30:00 -07:00
|
|
|
if (!parent) {
|
|
|
|
return -1; // No parent
|
|
|
|
}
|
|
|
|
|
2010-08-15 04:29:02 -07:00
|
|
|
return parent->GetIndexOfEmbeddedChild(accWrap);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void TranslateStates(PRUint32 aState, const AtkStateMap *aStateMap,
|
|
|
|
AtkStateSet *aStateSet)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(aStateSet, "Can't pass in null state set");
|
|
|
|
|
|
|
|
// Convert every state to an entry in AtkStateMap
|
|
|
|
PRUint32 stateIndex = 0;
|
|
|
|
PRUint32 bitMask = 1;
|
|
|
|
while (aStateMap[stateIndex].stateMapEntryType != kNoSuchState) {
|
|
|
|
if (aStateMap[stateIndex].atkState) { // There's potentially an ATK state for this
|
|
|
|
PRBool isStateOn = (aState & bitMask) != 0;
|
|
|
|
if (aStateMap[stateIndex].stateMapEntryType == kMapOpposite) {
|
|
|
|
isStateOn = !isStateOn;
|
|
|
|
}
|
|
|
|
if (isStateOn) {
|
|
|
|
atk_state_set_add_state(aStateSet, aStateMap[stateIndex].atkState);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Map extended state
|
|
|
|
bitMask <<= 1;
|
|
|
|
++ stateIndex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
AtkStateSet *
|
|
|
|
refStateSetCB(AtkObject *aAtkObj)
|
|
|
|
{
|
|
|
|
AtkStateSet *state_set = nsnull;
|
|
|
|
state_set = ATK_OBJECT_CLASS(parent_class)->ref_state_set(aAtkObj);
|
|
|
|
|
2007-06-08 02:09:24 -07:00
|
|
|
nsAccessibleWrap *accWrap = GetAccessibleWrap(aAtkObj);
|
|
|
|
if (!accWrap) {
|
2007-05-10 22:51:46 -07:00
|
|
|
TranslateStates(nsIAccessibleStates::EXT_STATE_DEFUNCT,
|
|
|
|
gAtkStateMapExt, state_set);
|
|
|
|
return state_set;
|
2007-04-30 22:57:51 -07:00
|
|
|
}
|
2007-05-10 22:51:46 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
// Map states
|
2007-04-02 08:56:24 -07:00
|
|
|
PRUint32 accState = 0, accExtState = 0;
|
2008-11-03 19:37:46 -08:00
|
|
|
nsresult rv = accWrap->GetState(&accState, &accExtState);
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_ENSURE_SUCCESS(rv, state_set);
|
|
|
|
|
2007-04-02 08:56:24 -07:00
|
|
|
TranslateStates(accState, gAtkStateMap, state_set);
|
2007-03-22 10:30:00 -07:00
|
|
|
TranslateStates(accExtState, gAtkStateMapExt, state_set);
|
|
|
|
|
|
|
|
return state_set;
|
|
|
|
}
|
|
|
|
|
|
|
|
AtkRelationSet *
|
|
|
|
refRelationSetCB(AtkObject *aAtkObj)
|
|
|
|
{
|
|
|
|
AtkRelationSet *relation_set = nsnull;
|
|
|
|
relation_set = ATK_OBJECT_CLASS(parent_class)->ref_relation_set(aAtkObj);
|
|
|
|
|
2007-06-04 02:39:15 -07:00
|
|
|
nsAccessibleWrap *accWrap = GetAccessibleWrap(aAtkObj);
|
2007-06-08 02:09:24 -07:00
|
|
|
if (!accWrap) {
|
|
|
|
return relation_set;
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
AtkRelation* relation;
|
|
|
|
|
2007-05-19 19:41:33 -07:00
|
|
|
PRUint32 relationType[] = {nsIAccessibleRelation::RELATION_LABELLED_BY,
|
|
|
|
nsIAccessibleRelation::RELATION_LABEL_FOR,
|
|
|
|
nsIAccessibleRelation::RELATION_NODE_CHILD_OF,
|
|
|
|
nsIAccessibleRelation::RELATION_CONTROLLED_BY,
|
|
|
|
nsIAccessibleRelation::RELATION_CONTROLLER_FOR,
|
|
|
|
nsIAccessibleRelation::RELATION_EMBEDS,
|
|
|
|
nsIAccessibleRelation::RELATION_FLOWS_TO,
|
|
|
|
nsIAccessibleRelation::RELATION_FLOWS_FROM,
|
|
|
|
nsIAccessibleRelation::RELATION_DESCRIBED_BY,
|
|
|
|
nsIAccessibleRelation::RELATION_DESCRIPTION_FOR,
|
2007-03-22 10:30:00 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(relationType); i++) {
|
2007-07-08 00:08:04 -07:00
|
|
|
relation = atk_relation_set_get_relation_by_type(relation_set, static_cast<AtkRelationType>(relationType[i]));
|
2007-03-22 10:30:00 -07:00
|
|
|
if (relation) {
|
|
|
|
atk_relation_set_remove(relation_set, relation);
|
|
|
|
}
|
|
|
|
|
2009-02-10 02:03:30 -08:00
|
|
|
nsCOMPtr<nsIAccessibleRelation> geckoRelation;
|
|
|
|
nsresult rv = accWrap->GetRelationByType(relationType[i],
|
|
|
|
getter_AddRefs(geckoRelation));
|
|
|
|
if (NS_SUCCEEDED(rv) && geckoRelation) {
|
|
|
|
PRUint32 targetsCount = 0;
|
|
|
|
geckoRelation->GetTargetsCount(&targetsCount);
|
|
|
|
if (targetsCount) {
|
|
|
|
AtkObject** accessible_array = new AtkObject*[targetsCount];
|
|
|
|
for (PRUint32 index = 0; index < targetsCount; index++) {
|
|
|
|
nsCOMPtr<nsIAccessible> geckoTarget;
|
|
|
|
geckoRelation->GetTarget(index, getter_AddRefs(geckoTarget));
|
|
|
|
accessible_array[index] =
|
|
|
|
nsAccessibleWrap::GetAtkObject(geckoTarget);
|
|
|
|
}
|
|
|
|
|
|
|
|
relation = atk_relation_new(accessible_array, targetsCount,
|
|
|
|
static_cast<AtkRelationType>(relationType[i]));
|
|
|
|
atk_relation_set_add(relation_set, relation);
|
|
|
|
g_object_unref(relation);
|
|
|
|
|
|
|
|
delete [] accessible_array;
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return relation_set;
|
|
|
|
}
|
|
|
|
|
2007-06-08 02:09:24 -07:00
|
|
|
// Check if aAtkObj is a valid MaiAtkObject, and return the nsAccessibleWrap
|
|
|
|
// for it.
|
|
|
|
nsAccessibleWrap *GetAccessibleWrap(AtkObject *aAtkObj)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2007-06-08 02:09:24 -07:00
|
|
|
NS_ENSURE_TRUE(IS_MAI_OBJECT(aAtkObj), nsnull);
|
|
|
|
nsAccessibleWrap *tmpAccWrap = MAI_ATK_OBJECT(aAtkObj)->accWrap;
|
2007-05-10 22:51:46 -07:00
|
|
|
|
|
|
|
// Check if AccessibleWrap was deconstructed
|
|
|
|
if (tmpAccWrap == nsnull) {
|
2007-06-08 02:09:24 -07:00
|
|
|
return nsnull;
|
2007-05-10 22:51:46 -07:00
|
|
|
}
|
|
|
|
|
2007-06-08 02:09:24 -07:00
|
|
|
NS_ENSURE_TRUE(tmpAccWrap->GetAtkObject() == aAtkObj, nsnull);
|
|
|
|
|
2010-03-18 11:49:39 -07:00
|
|
|
nsApplicationAccessible *applicationAcc =
|
2007-06-01 20:01:38 -07:00
|
|
|
nsAccessNode::GetApplicationAccessible();
|
|
|
|
nsAccessibleWrap* tmpAppAccWrap =
|
2010-03-18 11:49:39 -07:00
|
|
|
static_cast<nsAccessibleWrap*>(applicationAcc);
|
2007-06-01 20:01:38 -07:00
|
|
|
|
|
|
|
if (tmpAppAccWrap != tmpAccWrap && !tmpAccWrap->IsValidObject())
|
2007-06-08 02:09:24 -07:00
|
|
|
return nsnull;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
return tmpAccWrap;
|
|
|
|
}
|
2007-04-15 19:21:49 -07:00
|
|
|
|
2009-06-18 00:37:38 -07:00
|
|
|
nsresult
|
2010-08-24 19:08:28 -07:00
|
|
|
nsAccessibleWrap::HandleAccEvent(AccEvent* aEvent)
|
2007-04-15 19:21:49 -07:00
|
|
|
{
|
2010-01-18 20:23:44 -08:00
|
|
|
nsresult rv = nsAccessible::HandleAccEvent(aEvent);
|
2007-04-15 19:21:49 -07:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2008-06-15 23:16:18 -07:00
|
|
|
return FirePlatformEvent(aEvent);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2010-08-24 19:08:28 -07:00
|
|
|
nsAccessibleWrap::FirePlatformEvent(AccEvent* aEvent)
|
2008-06-15 23:16:18 -07:00
|
|
|
{
|
2010-06-11 21:04:24 -07:00
|
|
|
nsAccessible *accessible = aEvent->GetAccessible();
|
2007-06-04 02:39:15 -07:00
|
|
|
NS_ENSURE_TRUE(accessible, NS_ERROR_FAILURE);
|
|
|
|
|
2010-01-18 20:23:44 -08:00
|
|
|
PRUint32 type = aEvent->GetEventType();
|
2007-04-15 19:21:49 -07:00
|
|
|
|
2007-06-08 02:09:24 -07:00
|
|
|
AtkObject *atkObj = nsAccessibleWrap::GetAtkObject(accessible);
|
|
|
|
|
2007-06-06 19:47:30 -07:00
|
|
|
// We don't create ATK objects for nsIAccessible plain text leaves,
|
|
|
|
// just return NS_OK in such case
|
|
|
|
if (!atkObj) {
|
2009-09-09 02:03:14 -07:00
|
|
|
NS_ASSERTION(type == nsIAccessibleEvent::EVENT_SHOW ||
|
|
|
|
type == nsIAccessibleEvent::EVENT_HIDE,
|
2007-06-06 19:47:30 -07:00
|
|
|
"Event other than SHOW and HIDE fired for plain text leaves");
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2007-06-17 22:47:33 -07:00
|
|
|
nsAccessibleWrap *accWrap = GetAccessibleWrap(atkObj);
|
2007-06-21 02:16:32 -07:00
|
|
|
if (!accWrap) {
|
|
|
|
return NS_OK; // Node is shut down
|
|
|
|
}
|
2007-06-17 22:47:33 -07:00
|
|
|
|
2007-04-15 19:21:49 -07:00
|
|
|
switch (type) {
|
|
|
|
case nsIAccessibleEvent::EVENT_STATE_CHANGE:
|
2007-04-20 00:29:08 -07:00
|
|
|
return FireAtkStateChangeEvent(aEvent, atkObj);
|
|
|
|
|
2007-08-10 18:44:44 -07:00
|
|
|
case nsIAccessibleEvent::EVENT_TEXT_REMOVED:
|
|
|
|
case nsIAccessibleEvent::EVENT_TEXT_INSERTED:
|
2007-04-20 00:29:08 -07:00
|
|
|
return FireAtkTextChangedEvent(aEvent, atkObj);
|
|
|
|
|
2007-06-17 22:47:33 -07:00
|
|
|
case nsIAccessibleEvent::EVENT_FOCUS:
|
|
|
|
{
|
|
|
|
MAI_LOG_DEBUG(("\n\nReceived: EVENT_FOCUS\n"));
|
|
|
|
nsRefPtr<nsRootAccessible> rootAccWrap = accWrap->GetRootAccessible();
|
|
|
|
if (rootAccWrap && rootAccWrap->mActivated) {
|
|
|
|
atk_focus_tracker_notify(atkObj);
|
2007-06-25 01:28:22 -07:00
|
|
|
// Fire state change event for focus
|
2010-08-24 19:08:28 -07:00
|
|
|
nsRefPtr<AccEvent> stateChangeEvent =
|
|
|
|
new AccStateChangeEvent(accessible,
|
|
|
|
nsIAccessibleStates::STATE_FOCUSED,
|
|
|
|
PR_FALSE, PR_TRUE);
|
2007-06-25 01:28:22 -07:00
|
|
|
return FireAtkStateChangeEvent(stateChangeEvent, atkObj);
|
2007-06-17 22:47:33 -07:00
|
|
|
}
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case nsIAccessibleEvent::EVENT_VALUE_CHANGE:
|
|
|
|
{
|
|
|
|
MAI_LOG_DEBUG(("\n\nReceived: EVENT_VALUE_CHANGE\n"));
|
2010-06-11 21:04:24 -07:00
|
|
|
nsCOMPtr<nsIAccessibleValue> value(do_QueryObject(accessible));
|
2007-06-17 22:47:33 -07:00
|
|
|
if (value) { // Make sure this is a numeric value
|
|
|
|
// Don't fire for MSAA string value changes (e.g. text editing)
|
|
|
|
// ATK values are always numeric
|
|
|
|
g_object_notify( (GObject*)atkObj, "accessible-value" );
|
|
|
|
}
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case nsIAccessibleEvent::EVENT_SELECTION_CHANGED:
|
|
|
|
MAI_LOG_DEBUG(("\n\nReceived: EVENT_SELECTION_CHANGED\n"));
|
|
|
|
g_signal_emit_by_name(atkObj, "selection_changed");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED:
|
|
|
|
MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_SELECTION_CHANGED\n"));
|
|
|
|
g_signal_emit_by_name(atkObj, "text_selection_changed");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED:
|
2007-06-22 02:27:22 -07:00
|
|
|
{
|
2007-06-17 22:47:33 -07:00
|
|
|
MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_CARET_MOVED\n"));
|
2007-06-22 02:27:22 -07:00
|
|
|
|
2010-08-24 19:08:28 -07:00
|
|
|
AccCaretMoveEvent* caretMoveEvent = downcast_accEvent(aEvent);
|
2007-06-22 02:27:22 -07:00
|
|
|
NS_ASSERTION(caretMoveEvent, "Event needs event data");
|
|
|
|
if (!caretMoveEvent)
|
2007-06-17 22:47:33 -07:00
|
|
|
break;
|
|
|
|
|
2010-06-14 23:16:16 -07:00
|
|
|
PRInt32 caretOffset = caretMoveEvent->GetCaretOffset();
|
2007-06-22 02:27:22 -07:00
|
|
|
|
2007-06-24 19:33:18 -07:00
|
|
|
MAI_LOG_DEBUG(("\n\nCaret postion: %d", caretOffset));
|
2007-06-17 22:47:33 -07:00
|
|
|
g_signal_emit_by_name(atkObj,
|
|
|
|
"text_caret_moved",
|
|
|
|
// Curent caret position
|
2007-06-24 19:33:18 -07:00
|
|
|
caretOffset);
|
2007-06-22 02:27:22 -07:00
|
|
|
} break;
|
2007-06-17 22:47:33 -07:00
|
|
|
|
2008-07-17 05:06:24 -07:00
|
|
|
case nsIAccessibleEvent::EVENT_TEXT_ATTRIBUTE_CHANGED:
|
|
|
|
MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_ATTRIBUTE_CHANGED\n"));
|
|
|
|
|
|
|
|
g_signal_emit_by_name(atkObj,
|
|
|
|
"text-attributes-changed");
|
|
|
|
break;
|
|
|
|
|
2007-06-17 22:47:33 -07:00
|
|
|
case nsIAccessibleEvent::EVENT_TABLE_MODEL_CHANGED:
|
|
|
|
MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_MODEL_CHANGED\n"));
|
|
|
|
g_signal_emit_by_name(atkObj, "model_changed");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case nsIAccessibleEvent::EVENT_TABLE_ROW_INSERT:
|
2008-01-17 19:09:10 -08:00
|
|
|
{
|
2007-06-17 22:47:33 -07:00
|
|
|
MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_ROW_INSERT\n"));
|
2010-08-24 19:08:28 -07:00
|
|
|
AccTableChangeEvent* tableEvent = downcast_accEvent(aEvent);
|
2008-01-17 18:56:38 -08:00
|
|
|
NS_ENSURE_TRUE(tableEvent, NS_ERROR_FAILURE);
|
2007-06-17 22:47:33 -07:00
|
|
|
|
2010-06-14 23:16:16 -07:00
|
|
|
PRInt32 rowIndex = tableEvent->GetIndex();
|
|
|
|
PRInt32 numRows = tableEvent->GetCount();
|
2007-06-17 22:47:33 -07:00
|
|
|
|
|
|
|
g_signal_emit_by_name(atkObj,
|
|
|
|
"row_inserted",
|
|
|
|
// After which the rows are inserted
|
2008-01-17 18:56:38 -08:00
|
|
|
rowIndex,
|
2007-06-17 22:47:33 -07:00
|
|
|
// The number of the inserted
|
2008-01-17 18:56:38 -08:00
|
|
|
numRows);
|
2008-01-17 19:09:10 -08:00
|
|
|
} break;
|
2007-06-17 22:47:33 -07:00
|
|
|
|
|
|
|
case nsIAccessibleEvent::EVENT_TABLE_ROW_DELETE:
|
2008-01-17 19:09:10 -08:00
|
|
|
{
|
2007-06-17 22:47:33 -07:00
|
|
|
MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_ROW_DELETE\n"));
|
2010-08-24 19:08:28 -07:00
|
|
|
AccTableChangeEvent* tableEvent = downcast_accEvent(aEvent);
|
2008-01-17 18:56:38 -08:00
|
|
|
NS_ENSURE_TRUE(tableEvent, NS_ERROR_FAILURE);
|
2007-06-17 22:47:33 -07:00
|
|
|
|
2010-06-14 23:16:16 -07:00
|
|
|
PRInt32 rowIndex = tableEvent->GetIndex();
|
|
|
|
PRInt32 numRows = tableEvent->GetCount();
|
2007-06-17 22:47:33 -07:00
|
|
|
|
|
|
|
g_signal_emit_by_name(atkObj,
|
|
|
|
"row_deleted",
|
|
|
|
// After which the rows are deleted
|
2008-01-17 18:56:38 -08:00
|
|
|
rowIndex,
|
2007-06-17 22:47:33 -07:00
|
|
|
// The number of the deleted
|
2008-01-17 18:56:38 -08:00
|
|
|
numRows);
|
2008-01-17 19:09:10 -08:00
|
|
|
} break;
|
2007-06-17 22:47:33 -07:00
|
|
|
|
|
|
|
case nsIAccessibleEvent::EVENT_TABLE_ROW_REORDER:
|
2008-01-17 19:09:10 -08:00
|
|
|
{
|
2007-06-17 22:47:33 -07:00
|
|
|
MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_ROW_REORDER\n"));
|
|
|
|
g_signal_emit_by_name(atkObj, "row_reordered");
|
|
|
|
break;
|
2008-01-17 19:09:10 -08:00
|
|
|
}
|
2007-06-17 22:47:33 -07:00
|
|
|
|
|
|
|
case nsIAccessibleEvent::EVENT_TABLE_COLUMN_INSERT:
|
2008-01-17 19:09:10 -08:00
|
|
|
{
|
2007-06-17 22:47:33 -07:00
|
|
|
MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_COLUMN_INSERT\n"));
|
2010-08-24 19:08:28 -07:00
|
|
|
AccTableChangeEvent* tableEvent = downcast_accEvent(aEvent);
|
2008-01-17 18:56:38 -08:00
|
|
|
NS_ENSURE_TRUE(tableEvent, NS_ERROR_FAILURE);
|
2007-06-17 22:47:33 -07:00
|
|
|
|
2010-06-14 23:16:16 -07:00
|
|
|
PRInt32 colIndex = tableEvent->GetIndex();
|
|
|
|
PRInt32 numCols = tableEvent->GetCount();
|
2007-06-17 22:47:33 -07:00
|
|
|
|
|
|
|
g_signal_emit_by_name(atkObj,
|
|
|
|
"column_inserted",
|
|
|
|
// After which the columns are inserted
|
2008-01-17 18:56:38 -08:00
|
|
|
colIndex,
|
2007-06-17 22:47:33 -07:00
|
|
|
// The number of the inserted
|
2008-01-17 18:56:38 -08:00
|
|
|
numCols);
|
2008-01-17 19:09:10 -08:00
|
|
|
} break;
|
2007-06-17 22:47:33 -07:00
|
|
|
|
|
|
|
case nsIAccessibleEvent::EVENT_TABLE_COLUMN_DELETE:
|
2008-01-17 19:09:10 -08:00
|
|
|
{
|
2007-06-17 22:47:33 -07:00
|
|
|
MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_COLUMN_DELETE\n"));
|
2010-08-24 19:08:28 -07:00
|
|
|
AccTableChangeEvent* tableEvent = downcast_accEvent(aEvent);
|
2008-01-17 18:56:38 -08:00
|
|
|
NS_ENSURE_TRUE(tableEvent, NS_ERROR_FAILURE);
|
2007-06-17 22:47:33 -07:00
|
|
|
|
2010-06-14 23:16:16 -07:00
|
|
|
PRInt32 colIndex = tableEvent->GetIndex();
|
|
|
|
PRInt32 numCols = tableEvent->GetCount();
|
2007-06-17 22:47:33 -07:00
|
|
|
|
|
|
|
g_signal_emit_by_name(atkObj,
|
|
|
|
"column_deleted",
|
|
|
|
// After which the columns are deleted
|
2008-01-17 18:56:38 -08:00
|
|
|
colIndex,
|
2007-06-17 22:47:33 -07:00
|
|
|
// The number of the deleted
|
2008-01-17 18:56:38 -08:00
|
|
|
numCols);
|
2008-01-17 19:09:10 -08:00
|
|
|
} break;
|
2007-06-17 22:47:33 -07:00
|
|
|
|
|
|
|
case nsIAccessibleEvent::EVENT_TABLE_COLUMN_REORDER:
|
|
|
|
MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_COLUMN_REORDER\n"));
|
|
|
|
g_signal_emit_by_name(atkObj, "column_reordered");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case nsIAccessibleEvent::EVENT_SECTION_CHANGED:
|
|
|
|
MAI_LOG_DEBUG(("\n\nReceived: EVENT_SECTION_CHANGED\n"));
|
|
|
|
g_signal_emit_by_name(atkObj, "visible_data_changed");
|
|
|
|
break;
|
|
|
|
|
2009-09-09 02:03:14 -07:00
|
|
|
case nsIAccessibleEvent::EVENT_SHOW:
|
2007-06-29 19:49:32 -07:00
|
|
|
return FireAtkShowHideEvent(aEvent, atkObj, PR_TRUE);
|
|
|
|
|
2009-09-09 02:03:14 -07:00
|
|
|
case nsIAccessibleEvent::EVENT_HIDE:
|
2007-06-29 19:49:32 -07:00
|
|
|
return FireAtkShowHideEvent(aEvent, atkObj, PR_FALSE);
|
2007-06-17 22:47:33 -07:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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 nsIAccessibleEvent::EVENT_MENU_START:
|
|
|
|
MAI_LOG_DEBUG(("\n\nReceived: EVENT_MENU_START\n"));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case nsIAccessibleEvent::EVENT_MENU_END:
|
|
|
|
MAI_LOG_DEBUG(("\n\nReceived: EVENT_MENU_END\n"));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case nsIAccessibleEvent::EVENT_WINDOW_ACTIVATE:
|
|
|
|
{
|
|
|
|
MAI_LOG_DEBUG(("\n\nReceived: EVENT_WINDOW_ACTIVATED\n"));
|
2008-07-03 00:10:16 -07:00
|
|
|
nsRootAccessible *rootAcc =
|
2010-06-11 21:04:24 -07:00
|
|
|
static_cast<nsRootAccessible *>(accessible);
|
2008-07-03 00:10:16 -07:00
|
|
|
rootAcc->mActivated = PR_TRUE;
|
2007-06-17 22:47:33 -07:00
|
|
|
guint id = g_signal_lookup ("activate", MAI_TYPE_ATK_OBJECT);
|
|
|
|
g_signal_emit(atkObj, id, 0);
|
2008-07-03 00:10:16 -07:00
|
|
|
|
|
|
|
// Always fire a current focus event after activation.
|
|
|
|
rootAcc->FireCurrentFocusEvent();
|
2007-06-17 22:47:33 -07:00
|
|
|
} break;
|
|
|
|
|
|
|
|
case nsIAccessibleEvent::EVENT_WINDOW_DEACTIVATE:
|
|
|
|
{
|
|
|
|
MAI_LOG_DEBUG(("\n\nReceived: EVENT_WINDOW_DEACTIVATED\n"));
|
2008-07-03 00:10:16 -07:00
|
|
|
nsRootAccessible *rootAcc =
|
2010-06-11 21:04:24 -07:00
|
|
|
static_cast<nsRootAccessible *>(accessible);
|
2008-07-03 00:10:16 -07:00
|
|
|
rootAcc->mActivated = PR_FALSE;
|
2007-06-17 22:47:33 -07:00
|
|
|
guint id = g_signal_lookup ("deactivate", MAI_TYPE_ATK_OBJECT);
|
|
|
|
g_signal_emit(atkObj, id, 0);
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE:
|
|
|
|
{
|
|
|
|
MAI_LOG_DEBUG(("\n\nReceived: EVENT_DOCUMENT_LOAD_COMPLETE\n"));
|
|
|
|
g_signal_emit_by_name (atkObj, "load_complete");
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD:
|
|
|
|
{
|
|
|
|
MAI_LOG_DEBUG(("\n\nReceived: EVENT_DOCUMENT_RELOAD\n"));
|
|
|
|
g_signal_emit_by_name (atkObj, "reload");
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED:
|
|
|
|
{
|
|
|
|
MAI_LOG_DEBUG(("\n\nReceived: EVENT_DOCUMENT_LOAD_STOPPED\n"));
|
|
|
|
g_signal_emit_by_name (atkObj, "load_stopped");
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case nsIAccessibleEvent::EVENT_MENUPOPUP_START:
|
2007-06-29 19:49:32 -07:00
|
|
|
MAI_LOG_DEBUG(("\n\nReceived: EVENT_MENUPOPUP_START\n"));
|
|
|
|
atk_focus_tracker_notify(atkObj); // fire extra focus event
|
2007-06-17 22:47:33 -07:00
|
|
|
atk_object_notify_state_change(atkObj, ATK_STATE_VISIBLE, PR_TRUE);
|
|
|
|
atk_object_notify_state_change(atkObj, ATK_STATE_SHOWING, PR_TRUE);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case nsIAccessibleEvent::EVENT_MENUPOPUP_END:
|
2007-06-29 19:49:32 -07:00
|
|
|
MAI_LOG_DEBUG(("\n\nReceived: EVENT_MENUPOPUP_END\n"));
|
2007-06-17 22:47:33 -07:00
|
|
|
atk_object_notify_state_change(atkObj, ATK_STATE_VISIBLE, PR_FALSE);
|
|
|
|
atk_object_notify_state_change(atkObj, ATK_STATE_SHOWING, PR_FALSE);
|
2007-06-29 19:49:32 -07:00
|
|
|
break;
|
2007-04-20 00:29:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2007-04-15 19:21:49 -07:00
|
|
|
|
2007-04-20 00:29:08 -07:00
|
|
|
nsresult
|
2010-08-24 19:08:28 -07:00
|
|
|
nsAccessibleWrap::FireAtkStateChangeEvent(AccEvent* aEvent,
|
2007-04-20 00:29:08 -07:00
|
|
|
AtkObject *aObject)
|
|
|
|
{
|
|
|
|
MAI_LOG_DEBUG(("\n\nReceived: EVENT_STATE_CHANGE\n"));
|
|
|
|
|
2010-08-24 19:08:28 -07:00
|
|
|
AccStateChangeEvent* event = downcast_accEvent(aEvent);
|
2007-04-20 00:29:08 -07:00
|
|
|
NS_ENSURE_TRUE(event, NS_ERROR_FAILURE);
|
2007-04-15 19:21:49 -07:00
|
|
|
|
2010-06-14 23:16:16 -07:00
|
|
|
PRUint32 state = event->GetState();
|
|
|
|
PRBool isExtra = event->IsExtraState();
|
|
|
|
PRBool isEnabled = event->IsStateEnabled();
|
2007-04-15 19:21:49 -07:00
|
|
|
|
2007-04-20 00:29:08 -07:00
|
|
|
PRInt32 stateIndex = AtkStateMap::GetStateIndexFor(state);
|
|
|
|
if (stateIndex >= 0) {
|
|
|
|
const AtkStateMap *atkStateMap = isExtra ? gAtkStateMapExt : gAtkStateMap;
|
|
|
|
NS_ASSERTION(atkStateMap[stateIndex].stateMapEntryType != kNoSuchState,
|
|
|
|
"No such state");
|
2007-04-15 19:21:49 -07:00
|
|
|
|
2007-04-20 00:29:08 -07:00
|
|
|
if (atkStateMap[stateIndex].atkState != kNone) {
|
|
|
|
NS_ASSERTION(atkStateMap[stateIndex].stateMapEntryType != kNoStateChange,
|
|
|
|
"State changes should not fired for this state");
|
2007-04-15 19:21:49 -07:00
|
|
|
|
2007-04-20 00:29:08 -07:00
|
|
|
if (atkStateMap[stateIndex].stateMapEntryType == kMapOpposite)
|
|
|
|
isEnabled = !isEnabled;
|
2007-04-15 19:21:49 -07:00
|
|
|
|
2007-04-20 00:29:08 -07:00
|
|
|
// Fire state change for first state if there is one to map
|
|
|
|
atk_object_notify_state_change(aObject,
|
|
|
|
atkStateMap[stateIndex].atkState,
|
|
|
|
isEnabled);
|
2007-04-15 19:21:49 -07:00
|
|
|
}
|
2007-04-20 00:29:08 -07:00
|
|
|
}
|
2007-04-16 23:52:52 -07:00
|
|
|
|
2007-04-20 00:29:08 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2007-04-16 23:52:52 -07:00
|
|
|
|
2007-04-20 00:29:08 -07:00
|
|
|
nsresult
|
2010-08-24 19:08:28 -07:00
|
|
|
nsAccessibleWrap::FireAtkTextChangedEvent(AccEvent* aEvent,
|
2007-04-20 00:29:08 -07:00
|
|
|
AtkObject *aObject)
|
|
|
|
{
|
2007-08-10 18:44:44 -07:00
|
|
|
MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_REMOVED/INSERTED\n"));
|
2007-04-16 23:52:52 -07:00
|
|
|
|
2010-08-24 19:08:28 -07:00
|
|
|
AccTextChangeEvent* event = downcast_accEvent(aEvent);
|
2007-04-20 00:29:08 -07:00
|
|
|
NS_ENSURE_TRUE(event, NS_ERROR_FAILURE);
|
2007-04-16 23:52:52 -07:00
|
|
|
|
2010-06-14 23:16:16 -07:00
|
|
|
PRInt32 start = event->GetStartOffset();
|
|
|
|
PRUint32 length = event->GetLength();
|
|
|
|
PRBool isInserted = event->IsTextInserted();
|
2007-04-20 00:29:08 -07:00
|
|
|
|
2010-04-26 23:52:03 -07:00
|
|
|
PRBool isFromUserInput = aEvent->IsFromUserInput();
|
2007-09-18 14:40:04 -07:00
|
|
|
|
|
|
|
char *signal_name = g_strconcat(isInserted ? "text_changed::insert" : "text_changed::delete",
|
|
|
|
isFromUserInput ? "" : kNonUserInputEvent, NULL);
|
|
|
|
g_signal_emit_by_name(aObject, signal_name, start, length);
|
|
|
|
g_free (signal_name);
|
2007-04-20 00:29:08 -07:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2007-06-29 19:49:32 -07:00
|
|
|
nsresult
|
2010-08-24 19:08:28 -07:00
|
|
|
nsAccessibleWrap::FireAtkShowHideEvent(AccEvent* aEvent,
|
2007-06-29 19:49:32 -07:00
|
|
|
AtkObject *aObject, PRBool aIsAdded)
|
|
|
|
{
|
|
|
|
if (aIsAdded)
|
2007-08-10 18:44:44 -07:00
|
|
|
MAI_LOG_DEBUG(("\n\nReceived: Show event\n"));
|
2007-06-29 19:49:32 -07:00
|
|
|
else
|
2007-08-10 18:44:44 -07:00
|
|
|
MAI_LOG_DEBUG(("\n\nReceived: Hide event\n"));
|
2007-06-29 19:49:32 -07:00
|
|
|
|
2008-01-29 13:41:58 -08:00
|
|
|
PRInt32 indexInParent = getIndexInParentCB(aObject);
|
|
|
|
AtkObject *parentObject = getParentCB(aObject);
|
2007-06-29 19:49:32 -07:00
|
|
|
NS_ENSURE_STATE(parentObject);
|
|
|
|
|
2010-04-26 23:52:03 -07:00
|
|
|
PRBool isFromUserInput = aEvent->IsFromUserInput();
|
2007-09-18 14:40:04 -07:00
|
|
|
char *signal_name = g_strconcat(aIsAdded ? "children_changed::add" : "children_changed::remove",
|
|
|
|
isFromUserInput ? "" : kNonUserInputEvent, NULL);
|
|
|
|
g_signal_emit_by_name(parentObject, signal_name, indexInParent, aObject, NULL);
|
|
|
|
g_free(signal_name);
|
2007-06-29 19:49:32 -07:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|