AtkStateSet * refStateSetCB(AtkObject *aAtkObj) { AtkStateSet *state_set = nsnull; state_set = ATK_OBJECT_CLASS(parent_class)->ref_state_set(aAtkObj); AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj); if (!accWrap) { TranslateStates(states::DEFUNCT, state_set); return state_set; } // Map states TranslateStates(accWrap->State(), state_set); return state_set; }
STDMETHODIMP ia2Accessible::scrollToPoint(enum IA2CoordinateType aCoordType, long aX, long aY) { AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; uint32_t geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ? nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE : nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE; MOZ_ASSERT(!acc->IsProxy()); acc->ScrollToPoint(geckoCoordType, aX, aY); return S_OK; }
STDMETHODIMP ia2Accessible::get_locale(IA2Locale* aLocale) { if (!aLocale) return E_INVALIDARG; // Language codes consist of a primary code and a possibly empty series of // subcodes: language-code = primary-code ( "-" subcode )* // Two-letter primary codes are reserved for [ISO639] language abbreviations. // Any two-letter subcode is understood to be a [ISO3166] country code. AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; nsAutoString lang; acc->Language(lang); // If primary code consists from two letters then expose it as language. int32_t offset = lang.FindChar('-', 0); if (offset == -1) { if (lang.Length() == 2) { aLocale->language = ::SysAllocString(lang.get()); return S_OK; } } else if (offset == 2) { aLocale->language = ::SysAllocStringLen(lang.get(), 2); // If the first subcode consists from two letters then expose it as // country. offset = lang.FindChar('-', 3); if (offset == -1) { if (lang.Length() == 5) { aLocale->country = ::SysAllocString(lang.get() + 3); return S_OK; } } else if (offset == 5) { aLocale->country = ::SysAllocStringLen(lang.get() + 3, 2); } } // Expose as a string if primary code or subcode cannot point to language or // country abbreviations or if there are more than one subcode. aLocale->variant = ::SysAllocString(lang.get()); return S_OK; }
// set methods static gboolean addTextSelectionCB(AtkText *aText, gint aStartOffset, gint aEndOffset) { AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText)); if (!accWrap) return FALSE; HyperTextAccessible* text = accWrap->AsHyperText(); if (!text || !text->IsTextRole()) return false; nsresult rv = text->AddSelection(aStartOffset, aEndOffset); return NS_SUCCEEDED(rv) ? TRUE : FALSE; }
void a11y::ProxyDestroyed(ProxyAccessible* aProxy) { AccessibleWrap* wrapper = reinterpret_cast<AccessibleWrap*>(aProxy->GetWrapper()); MOZ_ASSERT(wrapper); if (!wrapper) return; if (aProxy->IsDoc() && nsWinUtils::IsWindowEmulationStarted()) { aProxy->AsDoc()->SetEmulatedWindowHandle(nullptr); } wrapper->Shutdown(); aProxy->SetWrapper(0); wrapper->Release(); }
STDMETHODIMP ia2AccessibleComponent::get_foreground(IA2Color* aForeground) { A11Y_TRYBLOCK_BEGIN AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; nsIFrame* frame = acc->GetFrame(); if (frame) *aForeground = frame->StyleColor()->mColor; return S_OK; A11Y_TRYBLOCK_END }
const gchar* getNameCB(AtkObject* aAtkObj) { nsAutoString name; AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj); if (accWrap) accWrap->Name(name); else if (ProxyAccessible* proxy = GetProxy(aAtkObj)) proxy->Name(name); else return nullptr; // XXX Firing an event from here does not seem right MaybeFireNameChange(aAtkObj, name); return aAtkObj->name; }
static AtkObject* refAtCB(AtkTable* aTable, gint aRowIdx, gint aColIdx) { AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable)); if (!accWrap || aRowIdx < 0 || aColIdx < 0) return nullptr; Accessible* cell = accWrap->AsTable()->CellAt(aRowIdx, aColIdx); if (!cell) return nullptr; AtkObject* cellAtkObj = AccessibleWrap::GetAtkObject(cell); if (cellAtkObj) g_object_ref(cellAtkObj); return cellAtkObj; }
void a11y::ProxyDestroyed(ProxyAccessible* aProxy) { AccessibleWrap* wrapper = reinterpret_cast<AccessibleWrap*>(aProxy->GetWrapper()); // If aProxy is a document that was created, but // RecvPDocAccessibleConstructor failed then aProxy->GetWrapper() will be // null. if (!wrapper) { return; } wrapper->Shutdown(); aProxy->SetWrapper(0); wrapper->Release(); }
static AtkObject* refSelectionCB(AtkSelection *aSelection, gint i) { AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aSelection)); if (!accWrap || !accWrap->IsSelect()) return nullptr; Accessible* selectedItem = accWrap->GetSelectedItem(i); if (!selectedItem) return nullptr; AtkObject* atkObj = AccessibleWrap::GetAtkObject(selectedItem); if (atkObj) g_object_ref(atkObj); return atkObj; }
STDMETHODIMP ia2Accessible::get_states(AccessibleStates* aStates) { if (!aStates) return E_INVALIDARG; *aStates = 0; // XXX: bug 344674 should come with better approach that we have here. AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); if (acc->IsDefunct()) { *aStates = IA2_STATE_DEFUNCT; return S_OK; } uint64_t state; MOZ_ASSERT(!acc->IsProxy()); state = acc->State(); if (state & states::INVALID) *aStates |= IA2_STATE_INVALID_ENTRY; if (state & states::REQUIRED) *aStates |= IA2_STATE_REQUIRED; // The following IA2 states are not supported by Gecko // IA2_STATE_ARMED // IA2_STATE_MANAGES_DESCENDANTS // IA2_STATE_ICONIFIED // IA2_STATE_INVALID // This is not a state, it is the absence of a state if (state & states::ACTIVE) *aStates |= IA2_STATE_ACTIVE; if (state & states::DEFUNCT) *aStates |= IA2_STATE_DEFUNCT; if (state & states::EDITABLE) *aStates |= IA2_STATE_EDITABLE; if (state & states::HORIZONTAL) *aStates |= IA2_STATE_HORIZONTAL; if (state & states::MODAL) *aStates |= IA2_STATE_MODAL; if (state & states::MULTI_LINE) *aStates |= IA2_STATE_MULTI_LINE; if (state & states::OPAQUE1) *aStates |= IA2_STATE_OPAQUE; if (state & states::SELECTABLE_TEXT) *aStates |= IA2_STATE_SELECTABLE_TEXT; if (state & states::SINGLE_LINE) *aStates |= IA2_STATE_SINGLE_LINE; if (state & states::STALE) *aStates |= IA2_STATE_STALE; if (state & states::SUPPORTS_AUTOCOMPLETION) *aStates |= IA2_STATE_SUPPORTS_AUTOCOMPLETION; if (state & states::TRANSIENT) *aStates |= IA2_STATE_TRANSIENT; if (state & states::VERTICAL) *aStates |= IA2_STATE_VERTICAL; if (state & states::CHECKED) *aStates |= IA2_STATE_CHECKABLE; if (state & states::PINNED) *aStates |= IA2_STATE_PINNED; return S_OK; }
AtkRelationSet * refRelationSetCB(AtkObject *aAtkObj) { AtkRelationSet* relation_set = ATK_OBJECT_CLASS(parent_class)->ref_relation_set(aAtkObj); AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj); if (!accWrap) return relation_set; PRUint32 relationTypes[] = { 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, }; for (PRUint32 i = 0; i < ArrayLength(relationTypes); i++) { AtkRelationType atkType = static_cast<AtkRelationType>(relationTypes[i]); AtkRelation* atkRelation = atk_relation_set_get_relation_by_type(relation_set, atkType); if (atkRelation) atk_relation_set_remove(relation_set, atkRelation); Relation rel(accWrap->RelationByType(relationTypes[i])); nsTArray<AtkObject*> targets; Accessible* tempAcc = nsnull; while ((tempAcc = rel.Next())) targets.AppendElement(AccessibleWrap::GetAtkObject(tempAcc)); if (targets.Length()) { atkRelation = atk_relation_new(targets.Elements(), targets.Length(), atkType); atk_relation_set_add(relation_set, atkRelation); g_object_unref(atkRelation); } } return relation_set; }
const gchar * getDocumentAttributeValueCB(AtkDocument *aDocument, const gchar *aAttrName) { ProxyAccessible* proxy = nullptr; DocAccessible* document = nullptr; AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aDocument)); if (accWrap) { if (!accWrap->IsDoc()) { return nullptr; } document = accWrap->AsDoc(); } else { proxy = GetProxy(ATK_OBJECT(aDocument)); if (!proxy) { return nullptr; } } nsAutoString attrValue; if (!strcasecmp(aAttrName, kDocTypeName)) { if (document) { document->DocType(attrValue); } else { proxy->DocType(attrValue); } } else if (!strcasecmp(aAttrName, kDocUrlName)) { if (document) { document->URL(attrValue); } else { proxy->URL(attrValue); } } else if (!strcasecmp(aAttrName, kMimeTypeName)) { if (document) { document->MimeType(attrValue); } else { proxy->MimeType(attrValue); } } else { return nullptr; } return attrValue.IsEmpty() ? nullptr : AccessibleWrap::ReturnString(attrValue); }
static AtkAttributeSet* getDefaultAttributesCB(AtkText *aText) { AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText)); if (!accWrap) return nullptr; HyperTextAccessible* text = accWrap->AsHyperText(); if (!text || !text->IsTextRole()) return nullptr; nsCOMPtr<nsIPersistentProperties> attributes; nsresult rv = text->GetDefaultTextAttributes(getter_AddRefs(attributes)); if (NS_FAILED(rv)) return nullptr; return ConvertToAtkAttributeSet(attributes); }
STDMETHODIMP ia2Accessible::get_attributes(BSTR* aAttributes) { if (!aAttributes) return E_INVALIDARG; *aAttributes = nullptr; AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; // The format is name:value;name:value; with \ for escaping these // characters ":;=,\". if (!acc->IsProxy()) { nsCOMPtr<nsIPersistentProperties> attributes = acc->Attributes(); return ConvertToIA2Attributes(attributes, aAttributes); } MOZ_ASSERT(!acc->IsProxy()); return E_UNEXPECTED; }
static gboolean setTextSelectionCB(AtkText *aText, gint aSelectionNum, gint aStartOffset, gint aEndOffset) { AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText)); if (accWrap) { HyperTextAccessible* text = accWrap->AsHyperText(); if (!text || !text->IsTextRole()) { return FALSE; } return text->SetSelectionBoundsAt(aSelectionNum, aStartOffset, aEndOffset); } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) { return proxy->SetSelectionBoundsAt(aSelectionNum, aStartOffset, aEndOffset); } return FALSE; }
static void insertTextCB(AtkEditableText *aText, const gchar *aString, gint aLength, gint *aPosition) { AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText)); if (!accWrap) return; HyperTextAccessible* text = accWrap->AsHyperText(); if (!text || !text->IsTextRole()) return; NS_ConvertUTF8toUTF16 strContent(aString, aLength); text->InsertText(strContent, *aPosition); MAI_LOG_DEBUG(("EditableText: insert aString=%s, aLength=%d, aPosition=%d", aString, aLength, *aPosition)); }
static gint getColumnCountCB(AtkTable *aTable) { AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable)); if (!accWrap) return -1; nsCOMPtr<nsIAccessibleTable> accTable; accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable), getter_AddRefs(accTable)); NS_ENSURE_TRUE(accTable, -1); PRInt32 count; nsresult rv = accTable->GetColumnCount(&count); NS_ENSURE_SUCCESS(rv, -1); return static_cast<gint>(count); }
static gint getRowAtIndexCB(AtkTable *aTable, gint aIndex) { AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable)); if (!accWrap) return -1; nsCOMPtr<nsIAccessibleTable> accTable; accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable), getter_AddRefs(accTable)); NS_ENSURE_TRUE(accTable, -1); PRInt32 row; nsresult rv = accTable->GetRowIndexAt(aIndex, &row); NS_ENSURE_SUCCESS(rv, -1); return static_cast<gint>(row); }
static const gchar* getRowDescriptionCB(AtkTable *aTable, gint aRow) { AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable)); if (!accWrap) return nsnull; nsCOMPtr<nsIAccessibleTable> accTable; accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable), getter_AddRefs(accTable)); NS_ENSURE_TRUE(accTable, nsnull); nsAutoString autoStr; nsresult rv = accTable->GetRowDescription(aRow, autoStr); NS_ENSURE_SUCCESS(rv, nsnull); return AccessibleWrap::ReturnString(autoStr); }
static gboolean removeTextSelectionCB(AtkText *aText, gint aSelectionNum) { AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText)); if (accWrap) { HyperTextAccessible* text = accWrap->AsHyperText(); if (!text || !text->IsTextRole()) { return FALSE; } return text->RemoveFromSelection(aSelectionNum); } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) { return proxy->RemoveFromSelection(aSelectionNum); } return FALSE; }
STDMETHODIMP ia2Accessible::get_nRelations(long* aNRelations) { if (!aNRelations) return E_INVALIDARG; *aNRelations = 0; AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; MOZ_ASSERT(!acc->IsProxy()); for (uint32_t idx = 0; idx < ArrayLength(sRelationTypePairs); idx++) { if (sRelationTypePairs[idx].second == IA2_RELATION_NULL) continue; Relation rel = acc->RelationByType(sRelationTypePairs[idx].first); if (rel.Next()) (*aNRelations)++; } return S_OK; }
// Check if aAtkObj is a valid MaiAtkObject, and return the AccessibleWrap // for it. AccessibleWrap* GetAccessibleWrap(AtkObject* aAtkObj) { NS_ENSURE_TRUE(IS_MAI_OBJECT(aAtkObj), nsnull); AccessibleWrap* accWrap = MAI_ATK_OBJECT(aAtkObj)->accWrap; // Check if the accessible was deconstructed. if (!accWrap) return nsnull; NS_ENSURE_TRUE(accWrap->GetAtkObject() == aAtkObj, nsnull); AccessibleWrap* appAccWrap = nsAccessNode::GetApplicationAccessible(); if (appAccWrap != accWrap && !accWrap->IsValidObject()) return nsnull; return accWrap; }
AtkObject * getParentCB(AtkObject *aAtkObj) { if (!aAtkObj->accessible_parent) { AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj); if (!accWrap) return nsnull; Accessible* accParent = accWrap->Parent(); if (!accParent) return nsnull; AtkObject* parent = AccessibleWrap::GetAtkObject(accParent); if (parent) atk_object_set_parent(aAtkObj, parent); } return aAtkObj->accessible_parent; }
STDMETHODIMP ia2AccessibleValue::QueryInterface(REFIID iid, void** ppv) { *ppv = NULL; if (IID_IAccessibleValue == iid) { AccessibleWrap* valueAcc = static_cast<AccessibleWrap*>(this); if (valueAcc->HasNumericValue()) { *ppv = static_cast<IAccessibleValue*>(this); valueAcc->AddRef(); return S_OK; } return E_NOINTERFACE; } return E_NOINTERFACE; }
const gchar * getDescriptionCB(AtkObject *aAtkObj) { AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj); if (!accWrap || accWrap->IsDefunct()) return nsnull; /* nsIAccessible is responsible for the non-NULL description */ nsAutoString uniDesc; accWrap->Description(uniDesc); NS_ConvertUTF8toUTF16 objDesc(aAtkObj->description); if (!uniDesc.Equals(objDesc)) atk_object_set_description(aAtkObj, NS_ConvertUTF16toUTF8(uniDesc).get()); return aAtkObj->description; }
static gint getCaretOffsetCB(AtkText *aText) { AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText)); if (accWrap) { HyperTextAccessible* text = accWrap->AsHyperText(); if (!text || !text->IsTextRole()) { return 0; } return static_cast<gint>(text->CaretOffset()); } if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) { return static_cast<gint>(proxy->CaretOffset()); } return 0; }
static gint getTextSelectionCountCB(AtkText *aText) { AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText)); if (accWrap) { HyperTextAccessible* text = accWrap->AsHyperText(); if (!text || !text->IsTextRole()) { return 0; } return text->SelectionCount(); } if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) { return proxy->SelectionCount(); } return 0; }
void a11y::ProxyTextChangeEvent(ProxyAccessible* aText, const nsString& aStr, int32_t aStart, uint32_t aLen, bool aInsert, bool) { AccessibleWrap* wrapper = WrapperFor(aText); MOZ_ASSERT(wrapper); if (!wrapper) { return; } auto text = static_cast<HyperTextAccessibleWrap*>(wrapper->AsHyperText()); if (text) { ia2AccessibleText::UpdateTextChangeData(text, aInsert, aStr, aStart, aLen); } uint32_t eventType = aInsert ? nsIAccessibleEvent::EVENT_TEXT_INSERTED : nsIAccessibleEvent::EVENT_TEXT_REMOVED; AccessibleWrap::FireWinEvent(wrapper, eventType); }
STDMETHODIMP ia2Accessible::get_indexInParent(long* aIndexInParent) { if (!aIndexInParent) return E_INVALIDARG; *aIndexInParent = -1; AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; MOZ_ASSERT(!acc->IsProxy()); *aIndexInParent = acc->IndexInParent(); if (*aIndexInParent == -1) return S_FALSE; return S_OK; }