1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim:expandtab:shiftwidth=4:tabstop=4:
4 /* ***** BEGIN LICENSE BLOCK *****
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
17 * The Original Code is mozilla.org code.
19 * The Initial Developer of the Original Code is
20 * Sun Microsystems, Inc.
21 * Portions created by the Initial Developer are Copyright (C) 2002
22 * the Initial Developer. All Rights Reserved.
25 * Bolian Yin (bolian.yin@sun.com)
26 * John Sun (john.sun@sun.com)
28 * Alternatively, the contents of this file may be used under the terms of
29 * either the GNU General Public License Version 2 or later (the "GPL"), or
30 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
31 * in which case the provisions of the GPL or the LGPL are applicable instead
32 * of those above. If you wish to allow use of your version of this file only
33 * under the terms of either the GPL or the LGPL, and not to allow others to
34 * use your version of this file under the terms of the MPL, indicate your
35 * decision by deleting the provisions above and replace them with the notice
36 * and other provisions required by the GPL or the LGPL. If you do not delete
37 * the provisions above, a recipient may use your version of this file under
38 * the terms of any one of the MPL, the GPL or the LGPL.
40 * ***** END LICENSE BLOCK ***** */
42 #include "nsAccessibleWrap.h"
44 #include "nsAccUtils.h"
45 #include "nsApplicationAccessibleWrap.h"
46 #include "nsRootAccessible.h"
47 #include "nsDocAccessibleWrap.h"
48 #include "nsIAccessibleValue.h"
50 #include "nsAutoPtr.h"
52 #include "nsRoleMap.h"
53 #include "nsRelUtils.h"
54 #include "nsStateMap.h"
56 #include "nsMaiInterfaceComponent.h"
57 #include "nsMaiInterfaceAction.h"
58 #include "nsMaiInterfaceText.h"
59 #include "nsMaiInterfaceEditableText.h"
60 #include "nsMaiInterfaceSelection.h"
61 #include "nsMaiInterfaceValue.h"
62 #include "nsMaiInterfaceHypertext.h"
63 #include "nsMaiInterfaceHyperlinkImpl.h"
64 #include "nsMaiInterfaceTable.h"
65 #include "nsXPCOMStrings.h"
66 #include "nsComponentManagerUtils.h"
67 #include "nsMaiInterfaceDocument.h"
68 #include "nsMaiInterfaceImage.h"
70 //defined in nsApplicationAccessibleWrap.cpp
71 extern "C" GType g_atk_hyperlink_impl_type
;
87 enum MaiInterfaceType
{
88 MAI_INTERFACE_COMPONENT
, /* 0 */
91 MAI_INTERFACE_EDITABLE_TEXT
,
92 MAI_INTERFACE_HYPERTEXT
,
93 MAI_INTERFACE_HYPERLINK_IMPL
,
94 MAI_INTERFACE_SELECTION
,
97 MAI_INTERFACE_DOCUMENT
,
98 MAI_INTERFACE_IMAGE
/* 10 */
101 static GType
GetAtkTypeForMai(MaiInterfaceType type
)
104 case MAI_INTERFACE_COMPONENT
:
105 return ATK_TYPE_COMPONENT
;
106 case MAI_INTERFACE_ACTION
:
107 return ATK_TYPE_ACTION
;
108 case MAI_INTERFACE_VALUE
:
109 return ATK_TYPE_VALUE
;
110 case MAI_INTERFACE_EDITABLE_TEXT
:
111 return ATK_TYPE_EDITABLE_TEXT
;
112 case MAI_INTERFACE_HYPERTEXT
:
113 return ATK_TYPE_HYPERTEXT
;
114 case MAI_INTERFACE_HYPERLINK_IMPL
:
115 return g_atk_hyperlink_impl_type
;
116 case MAI_INTERFACE_SELECTION
:
117 return ATK_TYPE_SELECTION
;
118 case MAI_INTERFACE_TABLE
:
119 return ATK_TYPE_TABLE
;
120 case MAI_INTERFACE_TEXT
:
121 return ATK_TYPE_TEXT
;
122 case MAI_INTERFACE_DOCUMENT
:
123 return ATK_TYPE_DOCUMENT
;
124 case MAI_INTERFACE_IMAGE
:
125 return ATK_TYPE_IMAGE
;
127 return G_TYPE_INVALID
;
130 static const char* kNonUserInputEvent
= ":system";
132 static const GInterfaceInfo atk_if_infos
[] = {
133 {(GInterfaceInitFunc
)componentInterfaceInitCB
,
134 (GInterfaceFinalizeFunc
) NULL
, NULL
},
135 {(GInterfaceInitFunc
)actionInterfaceInitCB
,
136 (GInterfaceFinalizeFunc
) NULL
, NULL
},
137 {(GInterfaceInitFunc
)valueInterfaceInitCB
,
138 (GInterfaceFinalizeFunc
) NULL
, NULL
},
139 {(GInterfaceInitFunc
)editableTextInterfaceInitCB
,
140 (GInterfaceFinalizeFunc
) NULL
, NULL
},
141 {(GInterfaceInitFunc
)hypertextInterfaceInitCB
,
142 (GInterfaceFinalizeFunc
) NULL
, NULL
},
143 {(GInterfaceInitFunc
)hyperlinkImplInterfaceInitCB
,
144 (GInterfaceFinalizeFunc
) NULL
, NULL
},
145 {(GInterfaceInitFunc
)selectionInterfaceInitCB
,
146 (GInterfaceFinalizeFunc
) NULL
, NULL
},
147 {(GInterfaceInitFunc
)tableInterfaceInitCB
,
148 (GInterfaceFinalizeFunc
) NULL
, NULL
},
149 {(GInterfaceInitFunc
)textInterfaceInitCB
,
150 (GInterfaceFinalizeFunc
) NULL
, NULL
},
151 {(GInterfaceInitFunc
)documentInterfaceInitCB
,
152 (GInterfaceFinalizeFunc
) NULL
, NULL
},
153 {(GInterfaceInitFunc
)imageInterfaceInitCB
,
154 (GInterfaceFinalizeFunc
) NULL
, NULL
}
158 * This MaiAtkObject is a thin wrapper, in the MAI namespace, for AtkObject
164 * The nsAccessibleWrap whose properties and features are exported
165 * via this object instance.
167 nsAccessibleWrap
*accWrap
;
170 struct MaiAtkObjectClass
172 AtkObjectClass parent_class
;
175 static guint mai_atk_object_signals
[LAST_SIGNAL
] = { 0, };
178 PRInt32 sMaiAtkObjCreated
= 0;
179 PRInt32 sMaiAtkObjDeleted
= 0;
183 /* callbacks for MaiAtkObject */
184 static void classInitCB(AtkObjectClass
*aClass
);
185 static void initializeCB(AtkObject
*aAtkObj
, gpointer aData
);
186 static void finalizeCB(GObject
*aObj
);
188 /* callbacks for AtkObject virtual functions */
189 static const gchar
* getNameCB (AtkObject
*aAtkObj
);
190 /* getDescriptionCB is also used by image interface */
191 const gchar
* getDescriptionCB (AtkObject
*aAtkObj
);
192 static AtkRole
getRoleCB(AtkObject
*aAtkObj
);
193 static AtkAttributeSet
* getAttributesCB(AtkObject
*aAtkObj
);
194 static AtkObject
* getParentCB(AtkObject
*aAtkObj
);
195 static gint
getChildCountCB(AtkObject
*aAtkObj
);
196 static AtkObject
* refChildCB(AtkObject
*aAtkObj
, gint aChildIndex
);
197 static gint
getIndexInParentCB(AtkObject
*aAtkObj
);
198 static AtkStateSet
* refStateSetCB(AtkObject
*aAtkObj
);
199 static AtkRelationSet
* refRelationSetCB(AtkObject
*aAtkObj
);
201 /* the missing atkobject virtual functions */
203 static AtkLayer getLayerCB(AtkObject *aAtkObj);
204 static gint getMdiZorderCB(AtkObject *aAtkObj);
205 static void SetNameCB(AtkObject *aAtkObj,
207 static void SetDescriptionCB(AtkObject *aAtkObj,
208 const gchar *description);
209 static void SetParentCB(AtkObject *aAtkObj,
211 static void SetRoleCB(AtkObject *aAtkObj,
213 static guint ConnectPropertyChangeHandlerCB(
215 AtkPropertyChangeHandler *handler);
216 static void RemovePropertyChangeHandlerCB(
219 static void InitializeCB(AtkObject *aAtkObj,
221 static void ChildrenChangedCB(AtkObject *aAtkObj,
223 gpointer changed_child);
224 static void FocusEventCB(AtkObject *aAtkObj,
226 static void PropertyChangeCB(AtkObject *aAtkObj,
227 AtkPropertyValues *values);
228 static void StateChangeCB(AtkObject *aAtkObj,
231 static void VisibleDataChangedCB(AtkObject *aAtkObj);
235 static GType
GetMaiAtkType(PRUint16 interfacesBits
);
236 static const char * GetUniqueMaiAtkTypeName(PRUint16 interfacesBits
);
238 static gpointer parent_class
= NULL
;
240 static GQuark quark_mai_hyperlink
= 0;
243 mai_atk_object_get_type(void)
245 static GType type
= 0;
248 static const GTypeInfo tinfo
= {
249 sizeof(MaiAtkObjectClass
),
251 (GBaseFinalizeFunc
)NULL
,
252 (GClassInitFunc
)classInitCB
,
253 (GClassFinalizeFunc
)NULL
,
254 NULL
, /* class data */
255 sizeof(MaiAtkObject
), /* instance size */
256 0, /* nb preallocs */
257 (GInstanceInitFunc
)NULL
,
258 NULL
/* value table */
261 type
= g_type_register_static(ATK_TYPE_OBJECT
,
262 "MaiAtkObject", &tinfo
, GTypeFlags(0));
263 quark_mai_hyperlink
= g_quark_from_static_string("MaiHyperlink");
269 PRInt32
nsAccessibleWrap::mAccWrapCreated
= 0;
270 PRInt32
nsAccessibleWrap::mAccWrapDeleted
= 0;
274 nsAccessibleWrap(nsIContent
*aContent
, nsIWeakReference
*aShell
) :
275 nsAccessible(aContent
, aShell
), mAtkObject(nsnull
)
280 MAI_LOG_DEBUG(("==nsAccessibleWrap creating: this=%p,total=%d left=%d\n",
281 (void*)this, mAccWrapCreated
,
282 (mAccWrapCreated
-mAccWrapDeleted
)));
285 nsAccessibleWrap::~nsAccessibleWrap()
287 NS_ASSERTION(!mAtkObject
, "ShutdownAtkObject() is not called");
292 MAI_LOG_DEBUG(("==nsAccessibleWrap deleting: this=%p,total=%d left=%d\n",
293 (void*)this, mAccWrapDeleted
,
294 (mAccWrapCreated
-mAccWrapDeleted
)));
297 void nsAccessibleWrap::ShutdownAtkObject()
300 if (IS_MAI_OBJECT(mAtkObject
)) {
301 MAI_ATK_OBJECT(mAtkObject
)->accWrap
= nsnull
;
303 SetMaiHyperlink(nsnull
);
304 g_object_unref(mAtkObject
);
310 nsAccessibleWrap::Shutdown()
313 nsAccessible::Shutdown();
316 MaiHyperlink
* nsAccessibleWrap::GetMaiHyperlink(PRBool aCreate
/* = PR_TRUE */)
318 // make sure mAtkObject is created
321 NS_ASSERTION(quark_mai_hyperlink
, "quark_mai_hyperlink not initialized");
322 NS_ASSERTION(IS_MAI_OBJECT(mAtkObject
), "Invalid AtkObject");
323 MaiHyperlink
* maiHyperlink
= nsnull
;
324 if (quark_mai_hyperlink
&& IS_MAI_OBJECT(mAtkObject
)) {
325 maiHyperlink
= (MaiHyperlink
*)g_object_get_qdata(G_OBJECT(mAtkObject
),
326 quark_mai_hyperlink
);
327 if (!maiHyperlink
&& aCreate
) {
328 maiHyperlink
= new MaiHyperlink(this);
329 SetMaiHyperlink(maiHyperlink
);
335 void nsAccessibleWrap::SetMaiHyperlink(MaiHyperlink
* aMaiHyperlink
)
337 NS_ASSERTION(quark_mai_hyperlink
, "quark_mai_hyperlink not initialized");
338 NS_ASSERTION(IS_MAI_OBJECT(mAtkObject
), "Invalid AtkObject");
339 if (quark_mai_hyperlink
&& IS_MAI_OBJECT(mAtkObject
)) {
340 MaiHyperlink
* maiHyperlink
= GetMaiHyperlink(PR_FALSE
);
341 if (!maiHyperlink
&& !aMaiHyperlink
) {
342 return; // Never set and we're shutting down
347 g_object_set_qdata(G_OBJECT(mAtkObject
), quark_mai_hyperlink
,
352 NS_IMETHODIMP
nsAccessibleWrap::GetNativeInterface(void **aOutAccessible
)
354 *aOutAccessible
= nsnull
;
357 if (!mWeakShell
|| !nsAccUtils::IsEmbeddedObject(this)) {
358 // We don't create ATK objects for node which has been shutdown, or
359 // nsIAccessible plain text leaves
360 return NS_ERROR_FAILURE
;
363 GType type
= GetMaiAtkType(CreateMaiInterfaces());
364 NS_ENSURE_TRUE(type
, NS_ERROR_FAILURE
);
366 reinterpret_cast<AtkObject
*>
367 (g_object_new(type
, NULL
));
368 NS_ENSURE_TRUE(mAtkObject
, NS_ERROR_OUT_OF_MEMORY
);
370 atk_object_initialize(mAtkObject
, this);
371 mAtkObject
->role
= ATK_ROLE_INVALID
;
372 mAtkObject
->layer
= ATK_LAYER_INVALID
;
375 *aOutAccessible
= mAtkObject
;
380 nsAccessibleWrap::GetAtkObject(void)
382 void *atkObj
= nsnull
;
383 GetNativeInterface(&atkObj
);
384 return static_cast<AtkObject
*>(atkObj
);
387 // Get AtkObject from nsIAccessible interface
390 nsAccessibleWrap::GetAtkObject(nsIAccessible
* acc
)
392 void *atkObjPtr
= nsnull
;
393 acc
->GetNativeInterface(&atkObjPtr
);
394 return atkObjPtr
? ATK_OBJECT(atkObjPtr
) : nsnull
;
399 nsAccessibleWrap::CreateMaiInterfaces(void)
401 PRUint16 interfacesBits
= 0;
403 // Add Interfaces for each nsIAccessible.ext interfaces
405 // the Component interface are supported by all nsIAccessible
406 interfacesBits
|= 1 << MAI_INTERFACE_COMPONENT
;
408 // Add Action interface if the action count is more than zero.
409 PRUint8 actionCount
= 0;
410 nsresult rv
= GetNumActions(&actionCount
);
411 if (NS_SUCCEEDED(rv
) && actionCount
> 0) {
412 interfacesBits
|= 1 << MAI_INTERFACE_ACTION
;
416 nsCOMPtr
<nsIAccessibleText
> accessInterfaceText
;
417 QueryInterface(NS_GET_IID(nsIAccessibleText
),
418 getter_AddRefs(accessInterfaceText
));
419 if (accessInterfaceText
) {
420 interfacesBits
|= 1 << MAI_INTERFACE_TEXT
;
423 //nsIAccessibleEditableText
424 nsCOMPtr
<nsIAccessibleEditableText
> accessInterfaceEditableText
;
425 QueryInterface(NS_GET_IID(nsIAccessibleEditableText
),
426 getter_AddRefs(accessInterfaceEditableText
));
427 if (accessInterfaceEditableText
) {
428 interfacesBits
|= 1 << MAI_INTERFACE_EDITABLE_TEXT
;
432 nsCOMPtr
<nsIAccessibleValue
> accessInterfaceValue
;
433 QueryInterface(NS_GET_IID(nsIAccessibleValue
),
434 getter_AddRefs(accessInterfaceValue
));
435 if (accessInterfaceValue
) {
436 interfacesBits
|= 1 << MAI_INTERFACE_VALUE
;
439 //nsIAccessibleDocument
440 nsCOMPtr
<nsIAccessibleDocument
> accessInterfaceDocument
;
441 QueryInterface(NS_GET_IID(nsIAccessibleDocument
),
442 getter_AddRefs(accessInterfaceDocument
));
443 if (accessInterfaceDocument
) {
444 interfacesBits
|= 1 << MAI_INTERFACE_DOCUMENT
;
448 nsCOMPtr
<nsIAccessibleImage
> accessInterfaceImage
;
449 QueryInterface(NS_GET_IID(nsIAccessibleImage
),
450 getter_AddRefs(accessInterfaceImage
));
451 if (accessInterfaceImage
) {
452 interfacesBits
|= 1 << MAI_INTERFACE_IMAGE
;
455 //nsIAccessibleHyperLink
456 nsCOMPtr
<nsIAccessibleHyperLink
> accessInterfaceHyperlink
;
457 QueryInterface(NS_GET_IID(nsIAccessibleHyperLink
),
458 getter_AddRefs(accessInterfaceHyperlink
));
459 if (accessInterfaceHyperlink
) {
460 interfacesBits
|= 1 << MAI_INTERFACE_HYPERLINK_IMPL
;
463 if (!nsAccUtils::MustPrune(this)) { // These interfaces require children
464 //nsIAccessibleHypertext
465 nsCOMPtr
<nsIAccessibleHyperText
> accessInterfaceHypertext
;
466 QueryInterface(NS_GET_IID(nsIAccessibleHyperText
),
467 getter_AddRefs(accessInterfaceHypertext
));
468 if (accessInterfaceHypertext
) {
469 interfacesBits
|= 1 << MAI_INTERFACE_HYPERTEXT
;
473 nsCOMPtr
<nsIAccessibleTable
> accessInterfaceTable
;
474 QueryInterface(NS_GET_IID(nsIAccessibleTable
),
475 getter_AddRefs(accessInterfaceTable
));
476 if (accessInterfaceTable
) {
477 interfacesBits
|= 1 << MAI_INTERFACE_TABLE
;
480 //nsIAccessibleSelection
481 nsCOMPtr
<nsIAccessibleSelectable
> accessInterfaceSelection
;
482 QueryInterface(NS_GET_IID(nsIAccessibleSelectable
),
483 getter_AddRefs(accessInterfaceSelection
));
484 if (accessInterfaceSelection
) {
485 interfacesBits
|= 1 << MAI_INTERFACE_SELECTION
;
489 return interfacesBits
;
493 GetMaiAtkType(PRUint16 interfacesBits
)
496 static const GTypeInfo tinfo
= {
497 sizeof(MaiAtkObjectClass
),
498 (GBaseInitFunc
) NULL
,
499 (GBaseFinalizeFunc
) NULL
,
500 (GClassInitFunc
) NULL
,
501 (GClassFinalizeFunc
) NULL
,
502 NULL
, /* class data */
503 sizeof(MaiAtkObject
), /* instance size */
504 0, /* nb preallocs */
505 (GInstanceInitFunc
) NULL
,
506 NULL
/* value table */
510 * The members we use to register GTypes are GetAtkTypeForMai
511 * and atk_if_infos, which are constant values to each MaiInterface
512 * So we can reuse the registered GType when having
513 * the same MaiInterface types.
515 const char *atkTypeName
= GetUniqueMaiAtkTypeName(interfacesBits
);
516 type
= g_type_from_name(atkTypeName
);
522 * gobject limits the number of types that can directly derive from any
523 * given object type to 4095.
525 static PRUint16 typeRegCount
= 0;
526 if (typeRegCount
++ >= 4095) {
527 return G_TYPE_INVALID
;
529 type
= g_type_register_static(MAI_TYPE_ATK_OBJECT
,
531 &tinfo
, GTypeFlags(0));
533 for (PRUint32 index
= 0; index
< NS_ARRAY_LENGTH(atk_if_infos
); index
++) {
534 if (interfacesBits
& (1 << index
)) {
535 g_type_add_interface_static(type
,
536 GetAtkTypeForMai((MaiInterfaceType
)index
),
537 &atk_if_infos
[index
]);
545 GetUniqueMaiAtkTypeName(PRUint16 interfacesBits
)
547 #define MAI_ATK_TYPE_NAME_LEN (30) /* 10+sizeof(PRUint16)*8/4+1 < 30 */
549 static gchar namePrefix
[] = "MaiAtkType"; /* size = 10 */
550 static gchar name
[MAI_ATK_TYPE_NAME_LEN
+ 1];
552 PR_snprintf(name
, MAI_ATK_TYPE_NAME_LEN
, "%s%x", namePrefix
,
554 name
[MAI_ATK_TYPE_NAME_LEN
] = '\0';
556 MAI_LOG_DEBUG(("MaiWidget::LastedTypeName=%s\n", name
));
561 PRBool
nsAccessibleWrap::IsValidObject()
563 // to ensure we are not shut down
567 /* static functions for ATK callbacks */
569 classInitCB(AtkObjectClass
*aClass
)
571 GObjectClass
*gobject_class
= G_OBJECT_CLASS(aClass
);
573 parent_class
= g_type_class_peek_parent(aClass
);
575 aClass
->get_name
= getNameCB
;
576 aClass
->get_description
= getDescriptionCB
;
577 aClass
->get_parent
= getParentCB
;
578 aClass
->get_n_children
= getChildCountCB
;
579 aClass
->ref_child
= refChildCB
;
580 aClass
->get_index_in_parent
= getIndexInParentCB
;
581 aClass
->get_role
= getRoleCB
;
582 aClass
->get_attributes
= getAttributesCB
;
583 aClass
->ref_state_set
= refStateSetCB
;
584 aClass
->ref_relation_set
= refRelationSetCB
;
586 aClass
->initialize
= initializeCB
;
588 gobject_class
->finalize
= finalizeCB
;
590 mai_atk_object_signals
[ACTIVATE
] =
591 g_signal_new ("activate",
594 0, /* default signal handler */
596 g_cclosure_marshal_VOID__VOID
,
598 mai_atk_object_signals
[CREATE
] =
599 g_signal_new ("create",
602 0, /* default signal handler */
604 g_cclosure_marshal_VOID__VOID
,
606 mai_atk_object_signals
[DEACTIVATE
] =
607 g_signal_new ("deactivate",
610 0, /* default signal handler */
612 g_cclosure_marshal_VOID__VOID
,
614 mai_atk_object_signals
[DESTROY
] =
615 g_signal_new ("destroy",
618 0, /* default signal handler */
620 g_cclosure_marshal_VOID__VOID
,
622 mai_atk_object_signals
[MAXIMIZE
] =
623 g_signal_new ("maximize",
626 0, /* default signal handler */
628 g_cclosure_marshal_VOID__VOID
,
630 mai_atk_object_signals
[MINIMIZE
] =
631 g_signal_new ("minimize",
634 0, /* default signal handler */
636 g_cclosure_marshal_VOID__VOID
,
638 mai_atk_object_signals
[RESIZE
] =
639 g_signal_new ("resize",
642 0, /* default signal handler */
644 g_cclosure_marshal_VOID__VOID
,
646 mai_atk_object_signals
[RESTORE
] =
647 g_signal_new ("restore",
650 0, /* default signal handler */
652 g_cclosure_marshal_VOID__VOID
,
658 initializeCB(AtkObject
*aAtkObj
, gpointer aData
)
660 NS_ASSERTION((IS_MAI_OBJECT(aAtkObj
)), "Invalid AtkObject");
661 NS_ASSERTION(aData
, "Invalid Data to init AtkObject");
662 if (!aAtkObj
|| !aData
)
665 /* call parent init function */
666 /* AtkObjectClass has not a "initialize" function now,
670 if (ATK_OBJECT_CLASS(parent_class
)->initialize
)
671 ATK_OBJECT_CLASS(parent_class
)->initialize(aAtkObj
, aData
);
673 /* initialize object */
674 MAI_ATK_OBJECT(aAtkObj
)->accWrap
=
675 static_cast<nsAccessibleWrap
*>(aData
);
680 MAI_LOG_DEBUG(("MaiAtkObj Create obj=%p for AccWrap=%p, all=%d, left=%d\n",
681 (void*)aAtkObj
, (void*)aData
, sMaiAtkObjCreated
,
682 (sMaiAtkObjCreated
-sMaiAtkObjDeleted
)));
686 finalizeCB(GObject
*aObj
)
688 if (!IS_MAI_OBJECT(aObj
))
690 NS_ASSERTION(MAI_ATK_OBJECT(aObj
)->accWrap
== nsnull
, "AccWrap NOT null");
695 MAI_LOG_DEBUG(("MaiAtkObj Delete obj=%p, all=%d, left=%d\n",
696 (void*)aObj
, sMaiAtkObjCreated
,
697 (sMaiAtkObjCreated
-sMaiAtkObjDeleted
)));
699 // call parent finalize function
700 // finalize of GObjectClass will unref the accessible parent if has
701 if (G_OBJECT_CLASS (parent_class
)->finalize
)
702 G_OBJECT_CLASS (parent_class
)->finalize(aObj
);
706 getNameCB(AtkObject
*aAtkObj
)
708 nsAccessibleWrap
*accWrap
= GetAccessibleWrap(aAtkObj
);
713 /* nsIAccessible is responsible for the non-NULL name */
714 nsAutoString uniName
;
715 nsresult rv
= accWrap
->GetName(uniName
);
716 NS_ENSURE_SUCCESS(rv
, nsnull
);
718 NS_ConvertUTF8toUTF16
objName(aAtkObj
->name
);
719 if (!uniName
.Equals(objName
)) {
720 atk_object_set_name(aAtkObj
,
721 NS_ConvertUTF16toUTF8(uniName
).get());
723 return aAtkObj
->name
;
727 getDescriptionCB(AtkObject
*aAtkObj
)
729 nsAccessibleWrap
*accWrap
= GetAccessibleWrap(aAtkObj
);
734 /* nsIAccessible is responsible for the non-NULL description */
735 nsAutoString uniDesc
;
736 nsresult rv
= accWrap
->GetDescription(uniDesc
);
737 NS_ENSURE_SUCCESS(rv
, nsnull
);
739 NS_ConvertUTF8toUTF16
objDesc(aAtkObj
->description
);
740 if (!uniDesc
.Equals(objDesc
)) {
741 atk_object_set_description(aAtkObj
,
742 NS_ConvertUTF16toUTF8(uniDesc
).get());
744 return aAtkObj
->description
;
748 getRoleCB(AtkObject
*aAtkObj
)
750 nsAccessibleWrap
*accWrap
= GetAccessibleWrap(aAtkObj
);
752 return ATK_ROLE_INVALID
;
756 NS_ASSERTION(nsAccUtils::IsTextInterfaceSupportCorrect(accWrap
),
757 "Does not support nsIAccessibleText when it should");
760 if (aAtkObj
->role
== ATK_ROLE_INVALID
) {
761 PRUint32 accRole
, atkRole
;
762 nsresult rv
= accWrap
->GetRole(&accRole
);
763 NS_ENSURE_SUCCESS(rv
, ATK_ROLE_INVALID
);
765 atkRole
= atkRoleMap
[accRole
]; // map to the actual value
766 NS_ASSERTION(atkRoleMap
[nsIAccessibleRole::ROLE_LAST_ENTRY
] ==
767 kROLE_ATK_LAST_ENTRY
, "ATK role map skewed");
768 aAtkObj
->role
= static_cast<AtkRole
>(atkRole
);
770 return aAtkObj
->role
;
774 ConvertToAtkAttributeSet(nsIPersistentProperties
* aAttributes
)
779 AtkAttributeSet
*objAttributeSet
= nsnull
;
780 nsCOMPtr
<nsISimpleEnumerator
> propEnum
;
781 nsresult rv
= aAttributes
->Enumerate(getter_AddRefs(propEnum
));
782 NS_ENSURE_SUCCESS(rv
, nsnull
);
785 while (NS_SUCCEEDED(propEnum
->HasMoreElements(&hasMore
)) && hasMore
) {
786 nsCOMPtr
<nsISupports
> sup
;
787 rv
= propEnum
->GetNext(getter_AddRefs(sup
));
788 NS_ENSURE_SUCCESS(rv
, objAttributeSet
);
790 nsCOMPtr
<nsIPropertyElement
> propElem(do_QueryInterface(sup
));
791 NS_ENSURE_TRUE(propElem
, objAttributeSet
);
794 rv
= propElem
->GetKey(name
);
795 NS_ENSURE_SUCCESS(rv
, objAttributeSet
);
798 rv
= propElem
->GetValue(value
);
799 NS_ENSURE_SUCCESS(rv
, objAttributeSet
);
801 AtkAttribute
*objAttr
= (AtkAttribute
*)g_malloc(sizeof(AtkAttribute
));
802 objAttr
->name
= g_strdup(name
.get());
803 objAttr
->value
= g_strdup(NS_ConvertUTF16toUTF8(value
).get());
804 objAttributeSet
= g_slist_prepend(objAttributeSet
, objAttr
);
807 //libspi will free it
808 return objAttributeSet
;
812 GetAttributeSet(nsIAccessible
* aAccessible
)
814 nsCOMPtr
<nsIPersistentProperties
> attributes
;
815 aAccessible
->GetAttributes(getter_AddRefs(attributes
));
818 // Deal with attributes that we only need to expose in ATK
820 aAccessible
->GetState(&state
, nsnull
);
821 if (state
& nsIAccessibleStates::STATE_HASPOPUP
) {
822 // There is no ATK state for haspopup, must use object attribute to expose the same info
823 nsAutoString oldValueUnused
;
824 attributes
->SetStringProperty(NS_LITERAL_CSTRING("haspopup"), NS_LITERAL_STRING("true"),
828 return ConvertToAtkAttributeSet(attributes
);
835 getAttributesCB(AtkObject
*aAtkObj
)
837 nsAccessibleWrap
*accWrap
= GetAccessibleWrap(aAtkObj
);
839 return accWrap
? GetAttributeSet(accWrap
) : nsnull
;
843 getParentCB(AtkObject
*aAtkObj
)
845 if (!aAtkObj
->accessible_parent
) {
846 nsAccessibleWrap
*accWrap
= GetAccessibleWrap(aAtkObj
);
851 nsAccessible
* accParent
= accWrap
->GetParent();
855 AtkObject
*parent
= nsAccessibleWrap::GetAtkObject(accParent
);
857 atk_object_set_parent(aAtkObj
, parent
);
859 return aAtkObj
->accessible_parent
;
863 getChildCountCB(AtkObject
*aAtkObj
)
865 nsAccessibleWrap
*accWrap
= GetAccessibleWrap(aAtkObj
);
866 if (!accWrap
|| nsAccUtils::MustPrune(accWrap
)) {
870 return accWrap
->GetEmbeddedChildCount();
874 refChildCB(AtkObject
*aAtkObj
, gint aChildIndex
)
876 // aChildIndex should not be less than zero
877 if (aChildIndex
< 0) {
881 nsAccessibleWrap
*accWrap
= GetAccessibleWrap(aAtkObj
);
882 if (!accWrap
|| nsAccUtils::MustPrune(accWrap
)) {
886 nsAccessible
* accChild
= accWrap
->GetEmbeddedChildAt(aChildIndex
);
890 AtkObject
* childAtkObj
= nsAccessibleWrap::GetAtkObject(accChild
);
892 NS_ASSERTION(childAtkObj
, "Fail to get AtkObj");
895 g_object_ref(childAtkObj
);
897 //this will addref parent
898 atk_object_set_parent(childAtkObj
, aAtkObj
);
903 getIndexInParentCB(AtkObject
*aAtkObj
)
905 // We don't use nsIAccessible::GetIndexInParent() because
906 // for ATK we don't want to include text leaf nodes as children
907 nsAccessibleWrap
*accWrap
= GetAccessibleWrap(aAtkObj
);
912 nsAccessible
*parent
= accWrap
->GetParent();
914 return -1; // No parent
917 return parent
->GetIndexOfEmbeddedChild(accWrap
);
920 static void TranslateStates(PRUint32 aState
, const AtkStateMap
*aStateMap
,
921 AtkStateSet
*aStateSet
)
923 NS_ASSERTION(aStateSet
, "Can't pass in null state set");
925 // Convert every state to an entry in AtkStateMap
926 PRUint32 stateIndex
= 0;
927 PRUint32 bitMask
= 1;
928 while (aStateMap
[stateIndex
].stateMapEntryType
!= kNoSuchState
) {
929 if (aStateMap
[stateIndex
].atkState
) { // There's potentially an ATK state for this
930 PRBool isStateOn
= (aState
& bitMask
) != 0;
931 if (aStateMap
[stateIndex
].stateMapEntryType
== kMapOpposite
) {
932 isStateOn
= !isStateOn
;
935 atk_state_set_add_state(aStateSet
, aStateMap
[stateIndex
].atkState
);
938 // Map extended state
945 refStateSetCB(AtkObject
*aAtkObj
)
947 AtkStateSet
*state_set
= nsnull
;
948 state_set
= ATK_OBJECT_CLASS(parent_class
)->ref_state_set(aAtkObj
);
950 nsAccessibleWrap
*accWrap
= GetAccessibleWrap(aAtkObj
);
952 TranslateStates(nsIAccessibleStates::EXT_STATE_DEFUNCT
,
953 gAtkStateMapExt
, state_set
);
958 PRUint32 accState
= 0, accExtState
= 0;
959 nsresult rv
= accWrap
->GetState(&accState
, &accExtState
);
960 NS_ENSURE_SUCCESS(rv
, state_set
);
962 TranslateStates(accState
, gAtkStateMap
, state_set
);
963 TranslateStates(accExtState
, gAtkStateMapExt
, state_set
);
969 refRelationSetCB(AtkObject
*aAtkObj
)
971 AtkRelationSet
*relation_set
= nsnull
;
972 relation_set
= ATK_OBJECT_CLASS(parent_class
)->ref_relation_set(aAtkObj
);
974 nsAccessibleWrap
*accWrap
= GetAccessibleWrap(aAtkObj
);
979 AtkRelation
* relation
;
981 PRUint32 relationType
[] = {nsIAccessibleRelation::RELATION_LABELLED_BY
,
982 nsIAccessibleRelation::RELATION_LABEL_FOR
,
983 nsIAccessibleRelation::RELATION_NODE_CHILD_OF
,
984 nsIAccessibleRelation::RELATION_CONTROLLED_BY
,
985 nsIAccessibleRelation::RELATION_CONTROLLER_FOR
,
986 nsIAccessibleRelation::RELATION_EMBEDS
,
987 nsIAccessibleRelation::RELATION_FLOWS_TO
,
988 nsIAccessibleRelation::RELATION_FLOWS_FROM
,
989 nsIAccessibleRelation::RELATION_DESCRIBED_BY
,
990 nsIAccessibleRelation::RELATION_DESCRIPTION_FOR
,
993 for (PRUint32 i
= 0; i
< NS_ARRAY_LENGTH(relationType
); i
++) {
994 relation
= atk_relation_set_get_relation_by_type(relation_set
, static_cast<AtkRelationType
>(relationType
[i
]));
996 atk_relation_set_remove(relation_set
, relation
);
999 nsCOMPtr
<nsIAccessibleRelation
> geckoRelation
;
1000 nsresult rv
= accWrap
->GetRelationByType(relationType
[i
],
1001 getter_AddRefs(geckoRelation
));
1002 if (NS_SUCCEEDED(rv
) && geckoRelation
) {
1003 PRUint32 targetsCount
= 0;
1004 geckoRelation
->GetTargetsCount(&targetsCount
);
1006 AtkObject
** accessible_array
= new AtkObject
*[targetsCount
];
1007 for (PRUint32 index
= 0; index
< targetsCount
; index
++) {
1008 nsCOMPtr
<nsIAccessible
> geckoTarget
;
1009 geckoRelation
->GetTarget(index
, getter_AddRefs(geckoTarget
));
1010 accessible_array
[index
] =
1011 nsAccessibleWrap::GetAtkObject(geckoTarget
);
1014 relation
= atk_relation_new(accessible_array
, targetsCount
,
1015 static_cast<AtkRelationType
>(relationType
[i
]));
1016 atk_relation_set_add(relation_set
, relation
);
1017 g_object_unref(relation
);
1019 delete [] accessible_array
;
1024 return relation_set
;
1027 // Check if aAtkObj is a valid MaiAtkObject, and return the nsAccessibleWrap
1029 nsAccessibleWrap
*GetAccessibleWrap(AtkObject
*aAtkObj
)
1031 NS_ENSURE_TRUE(IS_MAI_OBJECT(aAtkObj
), nsnull
);
1032 nsAccessibleWrap
*tmpAccWrap
= MAI_ATK_OBJECT(aAtkObj
)->accWrap
;
1034 // Check if AccessibleWrap was deconstructed
1035 if (tmpAccWrap
== nsnull
) {
1039 NS_ENSURE_TRUE(tmpAccWrap
->GetAtkObject() == aAtkObj
, nsnull
);
1041 nsApplicationAccessible
*applicationAcc
=
1042 nsAccessNode::GetApplicationAccessible();
1043 nsAccessibleWrap
* tmpAppAccWrap
=
1044 static_cast<nsAccessibleWrap
*>(applicationAcc
);
1046 if (tmpAppAccWrap
!= tmpAccWrap
&& !tmpAccWrap
->IsValidObject())
1053 nsAccessibleWrap::HandleAccEvent(AccEvent
* aEvent
)
1055 nsresult rv
= nsAccessible::HandleAccEvent(aEvent
);
1056 NS_ENSURE_SUCCESS(rv
, rv
);
1058 return FirePlatformEvent(aEvent
);
1062 nsAccessibleWrap::FirePlatformEvent(AccEvent
* aEvent
)
1064 nsAccessible
*accessible
= aEvent
->GetAccessible();
1065 NS_ENSURE_TRUE(accessible
, NS_ERROR_FAILURE
);
1067 PRUint32 type
= aEvent
->GetEventType();
1069 AtkObject
*atkObj
= nsAccessibleWrap::GetAtkObject(accessible
);
1071 // We don't create ATK objects for nsIAccessible plain text leaves,
1072 // just return NS_OK in such case
1074 NS_ASSERTION(type
== nsIAccessibleEvent::EVENT_SHOW
||
1075 type
== nsIAccessibleEvent::EVENT_HIDE
,
1076 "Event other than SHOW and HIDE fired for plain text leaves");
1080 nsAccessibleWrap
*accWrap
= GetAccessibleWrap(atkObj
);
1082 return NS_OK
; // Node is shut down
1086 case nsIAccessibleEvent::EVENT_STATE_CHANGE
:
1087 return FireAtkStateChangeEvent(aEvent
, atkObj
);
1089 case nsIAccessibleEvent::EVENT_TEXT_REMOVED
:
1090 case nsIAccessibleEvent::EVENT_TEXT_INSERTED
:
1091 return FireAtkTextChangedEvent(aEvent
, atkObj
);
1093 case nsIAccessibleEvent::EVENT_FOCUS
:
1095 MAI_LOG_DEBUG(("\n\nReceived: EVENT_FOCUS\n"));
1096 nsRefPtr
<nsRootAccessible
> rootAccWrap
= accWrap
->GetRootAccessible();
1097 if (rootAccWrap
&& rootAccWrap
->mActivated
) {
1098 atk_focus_tracker_notify(atkObj
);
1099 // Fire state change event for focus
1100 nsRefPtr
<AccEvent
> stateChangeEvent
=
1101 new AccStateChangeEvent(accessible
,
1102 nsIAccessibleStates::STATE_FOCUSED
,
1104 return FireAtkStateChangeEvent(stateChangeEvent
, atkObj
);
1108 case nsIAccessibleEvent::EVENT_VALUE_CHANGE
:
1110 MAI_LOG_DEBUG(("\n\nReceived: EVENT_VALUE_CHANGE\n"));
1111 nsCOMPtr
<nsIAccessibleValue
> value(do_QueryObject(accessible
));
1112 if (value
) { // Make sure this is a numeric value
1113 // Don't fire for MSAA string value changes (e.g. text editing)
1114 // ATK values are always numeric
1115 g_object_notify( (GObject
*)atkObj
, "accessible-value" );
1119 case nsIAccessibleEvent::EVENT_SELECTION_CHANGED
:
1120 MAI_LOG_DEBUG(("\n\nReceived: EVENT_SELECTION_CHANGED\n"));
1121 g_signal_emit_by_name(atkObj
, "selection_changed");
1124 case nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED
:
1125 MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_SELECTION_CHANGED\n"));
1126 g_signal_emit_by_name(atkObj
, "text_selection_changed");
1129 case nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED
:
1131 MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_CARET_MOVED\n"));
1133 AccCaretMoveEvent
* caretMoveEvent
= downcast_accEvent(aEvent
);
1134 NS_ASSERTION(caretMoveEvent
, "Event needs event data");
1135 if (!caretMoveEvent
)
1138 PRInt32 caretOffset
= caretMoveEvent
->GetCaretOffset();
1140 MAI_LOG_DEBUG(("\n\nCaret postion: %d", caretOffset
));
1141 g_signal_emit_by_name(atkObj
,
1143 // Curent caret position
1147 case nsIAccessibleEvent::EVENT_TEXT_ATTRIBUTE_CHANGED
:
1148 MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_ATTRIBUTE_CHANGED\n"));
1150 g_signal_emit_by_name(atkObj
,
1151 "text-attributes-changed");
1154 case nsIAccessibleEvent::EVENT_TABLE_MODEL_CHANGED
:
1155 MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_MODEL_CHANGED\n"));
1156 g_signal_emit_by_name(atkObj
, "model_changed");
1159 case nsIAccessibleEvent::EVENT_TABLE_ROW_INSERT
:
1161 MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_ROW_INSERT\n"));
1162 AccTableChangeEvent
* tableEvent
= downcast_accEvent(aEvent
);
1163 NS_ENSURE_TRUE(tableEvent
, NS_ERROR_FAILURE
);
1165 PRInt32 rowIndex
= tableEvent
->GetIndex();
1166 PRInt32 numRows
= tableEvent
->GetCount();
1168 g_signal_emit_by_name(atkObj
,
1170 // After which the rows are inserted
1172 // The number of the inserted
1176 case nsIAccessibleEvent::EVENT_TABLE_ROW_DELETE
:
1178 MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_ROW_DELETE\n"));
1179 AccTableChangeEvent
* tableEvent
= downcast_accEvent(aEvent
);
1180 NS_ENSURE_TRUE(tableEvent
, NS_ERROR_FAILURE
);
1182 PRInt32 rowIndex
= tableEvent
->GetIndex();
1183 PRInt32 numRows
= tableEvent
->GetCount();
1185 g_signal_emit_by_name(atkObj
,
1187 // After which the rows are deleted
1189 // The number of the deleted
1193 case nsIAccessibleEvent::EVENT_TABLE_ROW_REORDER
:
1195 MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_ROW_REORDER\n"));
1196 g_signal_emit_by_name(atkObj
, "row_reordered");
1200 case nsIAccessibleEvent::EVENT_TABLE_COLUMN_INSERT
:
1202 MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_COLUMN_INSERT\n"));
1203 AccTableChangeEvent
* tableEvent
= downcast_accEvent(aEvent
);
1204 NS_ENSURE_TRUE(tableEvent
, NS_ERROR_FAILURE
);
1206 PRInt32 colIndex
= tableEvent
->GetIndex();
1207 PRInt32 numCols
= tableEvent
->GetCount();
1209 g_signal_emit_by_name(atkObj
,
1211 // After which the columns are inserted
1213 // The number of the inserted
1217 case nsIAccessibleEvent::EVENT_TABLE_COLUMN_DELETE
:
1219 MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_COLUMN_DELETE\n"));
1220 AccTableChangeEvent
* tableEvent
= downcast_accEvent(aEvent
);
1221 NS_ENSURE_TRUE(tableEvent
, NS_ERROR_FAILURE
);
1223 PRInt32 colIndex
= tableEvent
->GetIndex();
1224 PRInt32 numCols
= tableEvent
->GetCount();
1226 g_signal_emit_by_name(atkObj
,
1228 // After which the columns are deleted
1230 // The number of the deleted
1234 case nsIAccessibleEvent::EVENT_TABLE_COLUMN_REORDER
:
1235 MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_COLUMN_REORDER\n"));
1236 g_signal_emit_by_name(atkObj
, "column_reordered");
1239 case nsIAccessibleEvent::EVENT_SECTION_CHANGED
:
1240 MAI_LOG_DEBUG(("\n\nReceived: EVENT_SECTION_CHANGED\n"));
1241 g_signal_emit_by_name(atkObj
, "visible_data_changed");
1244 case nsIAccessibleEvent::EVENT_SHOW
:
1245 return FireAtkShowHideEvent(aEvent
, atkObj
, PR_TRUE
);
1247 case nsIAccessibleEvent::EVENT_HIDE
:
1248 return FireAtkShowHideEvent(aEvent
, atkObj
, PR_FALSE
);
1251 * Because dealing with menu is very different between nsIAccessible
1252 * and ATK, and the menu activity is important, specially transfer the
1253 * following two event.
1254 * Need more verification by AT test.
1256 case nsIAccessibleEvent::EVENT_MENU_START
:
1257 MAI_LOG_DEBUG(("\n\nReceived: EVENT_MENU_START\n"));
1260 case nsIAccessibleEvent::EVENT_MENU_END
:
1261 MAI_LOG_DEBUG(("\n\nReceived: EVENT_MENU_END\n"));
1264 case nsIAccessibleEvent::EVENT_WINDOW_ACTIVATE
:
1266 MAI_LOG_DEBUG(("\n\nReceived: EVENT_WINDOW_ACTIVATED\n"));
1267 nsRootAccessible
*rootAcc
=
1268 static_cast<nsRootAccessible
*>(accessible
);
1269 rootAcc
->mActivated
= PR_TRUE
;
1270 guint id
= g_signal_lookup ("activate", MAI_TYPE_ATK_OBJECT
);
1271 g_signal_emit(atkObj
, id
, 0);
1273 // Always fire a current focus event after activation.
1274 rootAcc
->FireCurrentFocusEvent();
1277 case nsIAccessibleEvent::EVENT_WINDOW_DEACTIVATE
:
1279 MAI_LOG_DEBUG(("\n\nReceived: EVENT_WINDOW_DEACTIVATED\n"));
1280 nsRootAccessible
*rootAcc
=
1281 static_cast<nsRootAccessible
*>(accessible
);
1282 rootAcc
->mActivated
= PR_FALSE
;
1283 guint id
= g_signal_lookup ("deactivate", MAI_TYPE_ATK_OBJECT
);
1284 g_signal_emit(atkObj
, id
, 0);
1287 case nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE
:
1289 MAI_LOG_DEBUG(("\n\nReceived: EVENT_DOCUMENT_LOAD_COMPLETE\n"));
1290 g_signal_emit_by_name (atkObj
, "load_complete");
1293 case nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD
:
1295 MAI_LOG_DEBUG(("\n\nReceived: EVENT_DOCUMENT_RELOAD\n"));
1296 g_signal_emit_by_name (atkObj
, "reload");
1299 case nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED
:
1301 MAI_LOG_DEBUG(("\n\nReceived: EVENT_DOCUMENT_LOAD_STOPPED\n"));
1302 g_signal_emit_by_name (atkObj
, "load_stopped");
1305 case nsIAccessibleEvent::EVENT_MENUPOPUP_START
:
1306 MAI_LOG_DEBUG(("\n\nReceived: EVENT_MENUPOPUP_START\n"));
1307 atk_focus_tracker_notify(atkObj
); // fire extra focus event
1308 atk_object_notify_state_change(atkObj
, ATK_STATE_VISIBLE
, PR_TRUE
);
1309 atk_object_notify_state_change(atkObj
, ATK_STATE_SHOWING
, PR_TRUE
);
1312 case nsIAccessibleEvent::EVENT_MENUPOPUP_END
:
1313 MAI_LOG_DEBUG(("\n\nReceived: EVENT_MENUPOPUP_END\n"));
1314 atk_object_notify_state_change(atkObj
, ATK_STATE_VISIBLE
, PR_FALSE
);
1315 atk_object_notify_state_change(atkObj
, ATK_STATE_SHOWING
, PR_FALSE
);
1323 nsAccessibleWrap::FireAtkStateChangeEvent(AccEvent
* aEvent
,
1326 MAI_LOG_DEBUG(("\n\nReceived: EVENT_STATE_CHANGE\n"));
1328 AccStateChangeEvent
* event
= downcast_accEvent(aEvent
);
1329 NS_ENSURE_TRUE(event
, NS_ERROR_FAILURE
);
1331 PRUint32 state
= event
->GetState();
1332 PRBool isExtra
= event
->IsExtraState();
1333 PRBool isEnabled
= event
->IsStateEnabled();
1335 PRInt32 stateIndex
= AtkStateMap::GetStateIndexFor(state
);
1336 if (stateIndex
>= 0) {
1337 const AtkStateMap
*atkStateMap
= isExtra
? gAtkStateMapExt
: gAtkStateMap
;
1338 NS_ASSERTION(atkStateMap
[stateIndex
].stateMapEntryType
!= kNoSuchState
,
1341 if (atkStateMap
[stateIndex
].atkState
!= kNone
) {
1342 NS_ASSERTION(atkStateMap
[stateIndex
].stateMapEntryType
!= kNoStateChange
,
1343 "State changes should not fired for this state");
1345 if (atkStateMap
[stateIndex
].stateMapEntryType
== kMapOpposite
)
1346 isEnabled
= !isEnabled
;
1348 // Fire state change for first state if there is one to map
1349 atk_object_notify_state_change(aObject
,
1350 atkStateMap
[stateIndex
].atkState
,
1359 nsAccessibleWrap::FireAtkTextChangedEvent(AccEvent
* aEvent
,
1362 MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_REMOVED/INSERTED\n"));
1364 AccTextChangeEvent
* event
= downcast_accEvent(aEvent
);
1365 NS_ENSURE_TRUE(event
, NS_ERROR_FAILURE
);
1367 PRInt32 start
= event
->GetStartOffset();
1368 PRUint32 length
= event
->GetLength();
1369 PRBool isInserted
= event
->IsTextInserted();
1371 PRBool isFromUserInput
= aEvent
->IsFromUserInput();
1373 char *signal_name
= g_strconcat(isInserted
? "text_changed::insert" : "text_changed::delete",
1374 isFromUserInput
? "" : kNonUserInputEvent
, NULL
);
1375 g_signal_emit_by_name(aObject
, signal_name
, start
, length
);
1376 g_free (signal_name
);
1382 nsAccessibleWrap::FireAtkShowHideEvent(AccEvent
* aEvent
,
1383 AtkObject
*aObject
, PRBool aIsAdded
)
1386 MAI_LOG_DEBUG(("\n\nReceived: Show event\n"));
1388 MAI_LOG_DEBUG(("\n\nReceived: Hide event\n"));
1390 PRInt32 indexInParent
= getIndexInParentCB(aObject
);
1391 AtkObject
*parentObject
= getParentCB(aObject
);
1392 NS_ENSURE_STATE(parentObject
);
1394 PRBool isFromUserInput
= aEvent
->IsFromUserInput();
1395 char *signal_name
= g_strconcat(aIsAdded
? "children_changed::add" : "children_changed::remove",
1396 isFromUserInput
? "" : kNonUserInputEvent
, NULL
);
1397 g_signal_emit_by_name(parentObject
, signal_name
, indexInParent
, aObject
, NULL
);
1398 g_free(signal_name
);