blob: 0a1cf53c39d1a086a0fa56f6f64de46e22a276f7 [file] [log] [blame]
// Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/accessibility/browser_accessibility_auralinux.h"
#include <stdint.h>
#include <string.h>
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/accessibility/browser_accessibility_manager_auralinux.h"
#include "content/common/accessibility_messages.h"
#include "ui/accessibility/ax_text_utils.h"
namespace content {
static gpointer browser_accessibility_parent_class = NULL;
static BrowserAccessibilityAuraLinux* ToBrowserAccessibilityAuraLinux(
BrowserAccessibilityAtk* atk_object) {
if (!atk_object)
return NULL;
return atk_object->m_object;
}
const BrowserAccessibilityAuraLinux* ToBrowserAccessibilityAuraLinux(
const BrowserAccessibility* obj) {
DCHECK(!obj || obj->IsNative());
return static_cast<const BrowserAccessibilityAuraLinux*>(obj);
}
BrowserAccessibilityAuraLinux* ToBrowserAccessibilityAuraLinux(
BrowserAccessibility* obj) {
DCHECK(!obj || obj->IsNative());
return static_cast<BrowserAccessibilityAuraLinux*>(obj);
}
//
// AtkAction interface.
//
static BrowserAccessibilityAuraLinux* ToBrowserAccessibilityAuraLinux(
AtkAction* atk_action) {
if (!IS_BROWSER_ACCESSIBILITY(atk_action))
return NULL;
return ToBrowserAccessibilityAuraLinux(BROWSER_ACCESSIBILITY(atk_action));
}
static gboolean browser_accessibility_do_action(AtkAction* atk_action,
gint index) {
g_return_val_if_fail(ATK_IS_ACTION(atk_action), FALSE);
g_return_val_if_fail(!index, FALSE);
BrowserAccessibilityAuraLinux* obj =
ToBrowserAccessibilityAuraLinux(atk_action);
if (!obj)
return FALSE;
obj->manager()->DoDefaultAction(*obj);
return TRUE;
}
static gint browser_accessibility_get_n_actions(AtkAction* atk_action) {
g_return_val_if_fail(ATK_IS_ACTION(atk_action), 0);
BrowserAccessibilityAuraLinux* obj =
ToBrowserAccessibilityAuraLinux(atk_action);
if (!obj)
return 0;
return 1;
}
static const gchar* browser_accessibility_get_description(AtkAction* atk_action,
gint) {
g_return_val_if_fail(ATK_IS_ACTION(atk_action), 0);
BrowserAccessibilityAuraLinux* obj =
ToBrowserAccessibilityAuraLinux(atk_action);
if (!obj)
return 0;
return 0;
}
static const gchar* browser_accessibility_get_name(AtkAction* atk_action,
gint index) {
g_return_val_if_fail(ATK_IS_ACTION(atk_action), 0);
g_return_val_if_fail(!index, 0);
BrowserAccessibilityAuraLinux* obj =
ToBrowserAccessibilityAuraLinux(atk_action);
if (!obj)
return nullptr;
int action;
if (!obj->GetIntAttribute(ui::AX_ATTR_ACTION, &action))
return nullptr;
base::string16 action_verb =
ui::ActionToUnlocalizedString(static_cast<ui::AXSupportedAction>(action));
return base::UTF16ToUTF8(action_verb).c_str();
}
static const gchar* browser_accessibility_get_keybinding(AtkAction* atk_action,
gint index) {
g_return_val_if_fail(ATK_IS_ACTION(atk_action), 0);
g_return_val_if_fail(!index, 0);
BrowserAccessibilityAuraLinux* obj =
ToBrowserAccessibilityAuraLinux(atk_action);
if (!obj)
return 0;
return obj->GetStringAttribute(ui::AX_ATTR_ACCESS_KEY).c_str();
}
static void ActionInterfaceInit(AtkActionIface* iface) {
iface->do_action = browser_accessibility_do_action;
iface->get_n_actions = browser_accessibility_get_n_actions;
iface->get_description = browser_accessibility_get_description;
iface->get_name = browser_accessibility_get_name;
iface->get_keybinding = browser_accessibility_get_keybinding;
}
static const GInterfaceInfo ActionInfo = {
reinterpret_cast<GInterfaceInitFunc>(ActionInterfaceInit), 0, 0};
//
// AtkComponent interface.
//
static BrowserAccessibilityAuraLinux* ToBrowserAccessibilityAuraLinux(
AtkComponent* atk_component) {
if (!IS_BROWSER_ACCESSIBILITY(atk_component))
return NULL;
return ToBrowserAccessibilityAuraLinux(BROWSER_ACCESSIBILITY(atk_component));
}
static AtkObject* browser_accessibility_accessible_at_point(
AtkComponent* atk_component,
gint x,
gint y,
AtkCoordType coord_type) {
g_return_val_if_fail(ATK_IS_COMPONENT(atk_component), 0);
BrowserAccessibilityAuraLinux* obj =
ToBrowserAccessibilityAuraLinux(atk_component);
if (!obj)
return NULL;
gfx::Point point(x, y);
BrowserAccessibility* result = obj->manager()->CachingAsyncHitTest(point);
if (!result)
return NULL;
AtkObject* atk_result =
ToBrowserAccessibilityAuraLinux(result)->GetAtkObject();
g_object_ref(atk_result);
return atk_result;
}
static void browser_accessibility_get_extents(AtkComponent* atk_component,
gint* x,
gint* y,
gint* width,
gint* height,
AtkCoordType coord_type) {
g_return_if_fail(ATK_IS_COMPONENT(atk_component));
BrowserAccessibilityAuraLinux* obj =
ToBrowserAccessibilityAuraLinux(atk_component);
if (!obj)
return;
gfx::Rect bounds = obj->GetScreenBoundsRect();
if (x)
*x = bounds.x();
if (y)
*y = bounds.y();
if (width)
*width = bounds.width();
if (height)
*height = bounds.height();
}
static gboolean browser_accessibility_grab_focus(AtkComponent* atk_component) {
g_return_val_if_fail(ATK_IS_COMPONENT(atk_component), FALSE);
BrowserAccessibilityAuraLinux* obj =
ToBrowserAccessibilityAuraLinux(atk_component);
if (!obj)
return false;
obj->manager()->SetFocus(*obj);
return true;
}
static void ComponentInterfaceInit(AtkComponentIface* iface) {
iface->ref_accessible_at_point = browser_accessibility_accessible_at_point;
iface->get_extents = browser_accessibility_get_extents;
iface->grab_focus = browser_accessibility_grab_focus;
}
static const GInterfaceInfo ComponentInfo = {
reinterpret_cast<GInterfaceInitFunc>(ComponentInterfaceInit),
0,
0};
//
// AtkDocument interface.
//
static BrowserAccessibilityAuraLinux* ToBrowserAccessibilityAuraLinux(
AtkDocument* atk_doc) {
if (!IS_BROWSER_ACCESSIBILITY(atk_doc))
return NULL;
return ToBrowserAccessibilityAuraLinux(BROWSER_ACCESSIBILITY(atk_doc));
}
static const gchar* GetDocumentAttributeValue(
BrowserAccessibilityAuraLinux* obj,
const gchar* attribute) {
if (!g_ascii_strcasecmp(attribute, "DocType"))
return obj->manager()->GetTreeData().doctype.c_str();
else if (!g_ascii_strcasecmp(attribute, "MimeType"))
return obj->manager()->GetTreeData().mimetype.c_str();
else if (!g_ascii_strcasecmp(attribute, "Title"))
return obj->manager()->GetTreeData().title.c_str();
else if (!g_ascii_strcasecmp(attribute, "URI"))
return obj->manager()->GetTreeData().url.c_str();
return 0;
}
AtkAttributeSet* SetAtkAttributeSet(AtkAttributeSet* attribute_set,
const char* name,
const char* value) {
AtkAttribute* attribute =
static_cast<AtkAttribute*>(g_malloc(sizeof(AtkAttribute)));
attribute->name = g_strdup(name);
attribute->value = g_strdup(value);
attribute_set = g_slist_prepend(attribute_set, attribute);
return attribute_set;
}
static const gchar* browser_accessibility_get_attribute_value(
AtkDocument* atk_doc,
const gchar* attribute) {
g_return_val_if_fail(ATK_IS_DOCUMENT(atk_doc), 0);
BrowserAccessibilityAuraLinux* obj = ToBrowserAccessibilityAuraLinux(atk_doc);
if (!obj)
return 0;
return GetDocumentAttributeValue(obj, attribute);
}
static AtkAttributeSet* browser_accessibility_get_attributes(
AtkDocument* atk_doc) {
g_return_val_if_fail(ATK_IS_DOCUMENT(atk_doc), 0);
BrowserAccessibilityAuraLinux* obj = ToBrowserAccessibilityAuraLinux(atk_doc);
if (!obj)
return 0;
AtkAttributeSet* attribute_set = 0;
const gchar* doc_attributes[] = {"DocType", "MimeType", "Title", "URI"};
const gchar* value = 0;
for (unsigned i = 0; i < G_N_ELEMENTS(doc_attributes); i++) {
value = GetDocumentAttributeValue(obj, doc_attributes[i]);
if (value)
attribute_set =
SetAtkAttributeSet(attribute_set, doc_attributes[i], value);
}
return attribute_set;
}
static void DocumentInterfaceInit(AtkDocumentIface* iface) {
iface->get_document_attribute_value =
browser_accessibility_get_attribute_value;
iface->get_document_attributes = browser_accessibility_get_attributes;
}
static const GInterfaceInfo DocumentInfo = {
reinterpret_cast<GInterfaceInitFunc>(DocumentInterfaceInit), 0, 0};
//
// AtkImage interface.
//
static BrowserAccessibilityAuraLinux* ToBrowserAccessibilityAuraLinux(
AtkImage* atk_img) {
if (!IS_BROWSER_ACCESSIBILITY(atk_img))
return NULL;
return ToBrowserAccessibilityAuraLinux(BROWSER_ACCESSIBILITY(atk_img));
}
void GetImagePositionSize(BrowserAccessibilityAuraLinux* obj,
gint* x,
gint* y,
gint* width,
gint* height) {
gfx::Rect img_pos_size = obj->GetScreenBoundsRect();
if (x)
*x = img_pos_size.x();
if (y)
*y = img_pos_size.y();
if (width)
*width = img_pos_size.width();
if (height)
*height = img_pos_size.height();
}
static void browser_accessibility_get_image_position(AtkImage* atk_img,
gint* x,
gint* y,
AtkCoordType coordType) {
g_return_if_fail(ATK_IMAGE(atk_img));
BrowserAccessibilityAuraLinux* obj = ToBrowserAccessibilityAuraLinux(atk_img);
if (!obj)
return;
GetImagePositionSize(obj, x, y, nullptr, nullptr);
}
static const gchar* browser_accessibility_get_image_description(
AtkImage* atk_img) {
g_return_val_if_fail(ATK_IMAGE(atk_img), 0);
BrowserAccessibilityAuraLinux* obj = ToBrowserAccessibilityAuraLinux(atk_img);
if (!obj)
return 0;
return obj->GetStringAttribute(ui::AX_ATTR_DESCRIPTION).c_str();
}
static void browser_accessibility_get_image_size(AtkImage* atk_img,
gint* width,
gint* height) {
g_return_if_fail(ATK_IMAGE(atk_img));
BrowserAccessibilityAuraLinux* obj = ToBrowserAccessibilityAuraLinux(atk_img);
if (!obj)
return;
GetImagePositionSize(obj, nullptr, nullptr, width, height);
}
void ImageInterfaceInit(AtkImageIface* iface) {
iface->get_image_position = browser_accessibility_get_image_position;
iface->get_image_description = browser_accessibility_get_image_description;
iface->get_image_size = browser_accessibility_get_image_size;
}
static const GInterfaceInfo ImageInfo = {
reinterpret_cast<GInterfaceInitFunc>(ImageInterfaceInit), 0, 0};
//
// AtkValue interface.
//
static BrowserAccessibilityAuraLinux* ToBrowserAccessibilityAuraLinux(
AtkValue* atk_object) {
if (!IS_BROWSER_ACCESSIBILITY(atk_object))
return NULL;
return ToBrowserAccessibilityAuraLinux(BROWSER_ACCESSIBILITY(atk_object));
}
static float GetStepAttribute(BrowserAccessibilityAuraLinux* obj) {
// TODO(shreeram.k): Get Correct value of Step attribute.
return 1.0;
}
static void browser_accessibility_get_current_value(AtkValue* atk_value,
GValue* value) {
g_return_if_fail(ATK_VALUE(atk_value));
BrowserAccessibilityAuraLinux* obj =
ToBrowserAccessibilityAuraLinux(atk_value);
if (!obj)
return;
float float_val;
if (obj->GetFloatAttribute(ui::AX_ATTR_VALUE_FOR_RANGE, &float_val)) {
memset(value, 0, sizeof(*value));
g_value_init(value, G_TYPE_FLOAT);
g_value_set_float(value, float_val);
}
}
static void browser_accessibility_get_minimum_value(AtkValue* atk_value,
GValue* value) {
g_return_if_fail(ATK_VALUE(atk_value));
BrowserAccessibilityAuraLinux* obj =
ToBrowserAccessibilityAuraLinux(atk_value);
if (!obj)
return;
float float_val;
if (obj->GetFloatAttribute(ui::AX_ATTR_MIN_VALUE_FOR_RANGE, &float_val)) {
memset(value, 0, sizeof(*value));
g_value_init(value, G_TYPE_FLOAT);
g_value_set_float(value, float_val);
}
}
static void browser_accessibility_get_maximum_value(AtkValue* atk_value,
GValue* value) {
g_return_if_fail(ATK_VALUE(atk_value));
BrowserAccessibilityAuraLinux* obj =
ToBrowserAccessibilityAuraLinux(atk_value);
if (!obj)
return;
float float_val;
if (obj->GetFloatAttribute(ui::AX_ATTR_MAX_VALUE_FOR_RANGE, &float_val)) {
memset(value, 0, sizeof(*value));
g_value_init(value, G_TYPE_FLOAT);
g_value_set_float(value, float_val);
}
}
static void browser_accessibility_get_minimum_increment(AtkValue* atk_value,
GValue* gValue) {
g_return_if_fail(ATK_VALUE(atk_value));
memset(gValue, 0, sizeof(GValue));
g_value_init(gValue, G_TYPE_FLOAT);
BrowserAccessibilityAuraLinux* obj =
ToBrowserAccessibilityAuraLinux(atk_value);
if (!obj)
return;
g_value_set_float(gValue, GetStepAttribute(obj));
}
static void ValueInterfaceInit(AtkValueIface* iface) {
iface->get_current_value = browser_accessibility_get_current_value;
iface->get_minimum_value = browser_accessibility_get_minimum_value;
iface->get_maximum_value = browser_accessibility_get_maximum_value;
iface->get_minimum_increment = browser_accessibility_get_minimum_increment;
}
static const GInterfaceInfo ValueInfo = {
reinterpret_cast<GInterfaceInitFunc>(ValueInterfaceInit),
0,
0};
//
// AtkObject interface
//
static BrowserAccessibilityAuraLinux* ToBrowserAccessibilityAuraLinux(
AtkObject* atk_object) {
if (!IS_BROWSER_ACCESSIBILITY(atk_object))
return NULL;
return ToBrowserAccessibilityAuraLinux(BROWSER_ACCESSIBILITY(atk_object));
}
static const gchar* browser_accessibility_get_name(AtkObject* atk_object) {
BrowserAccessibilityAuraLinux* obj =
ToBrowserAccessibilityAuraLinux(atk_object);
if (!obj)
return NULL;
return obj->GetStringAttribute(ui::AX_ATTR_NAME).c_str();
}
static const gchar* browser_accessibility_get_description(
AtkObject* atk_object) {
BrowserAccessibilityAuraLinux* obj =
ToBrowserAccessibilityAuraLinux(atk_object);
if (!obj)
return NULL;
return obj->GetStringAttribute(ui::AX_ATTR_DESCRIPTION).c_str();
}
static AtkObject* browser_accessibility_get_parent(AtkObject* atk_object) {
BrowserAccessibilityAuraLinux* obj =
ToBrowserAccessibilityAuraLinux(atk_object);
if (!obj)
return NULL;
if (obj->PlatformGetParent())
return ToBrowserAccessibilityAuraLinux(obj->PlatformGetParent())
->GetAtkObject();
BrowserAccessibilityManagerAuraLinux* manager =
static_cast<BrowserAccessibilityManagerAuraLinux*>(obj->manager());
return manager->parent_object();
}
static gint browser_accessibility_get_n_children(AtkObject* atk_object) {
BrowserAccessibilityAuraLinux* obj =
ToBrowserAccessibilityAuraLinux(atk_object);
if (!obj)
return 0;
return obj->PlatformChildCount();
}
static AtkObject* browser_accessibility_ref_child(AtkObject* atk_object,
gint index) {
BrowserAccessibilityAuraLinux* obj =
ToBrowserAccessibilityAuraLinux(atk_object);
if (!obj)
return NULL;
if (index < 0 || index >= static_cast<gint>(obj->PlatformChildCount()))
return NULL;
AtkObject* result = ToBrowserAccessibilityAuraLinux(
obj->InternalGetChild(index))->GetAtkObject();
g_object_ref(result);
return result;
}
static gint browser_accessibility_get_index_in_parent(AtkObject* atk_object) {
BrowserAccessibilityAuraLinux* obj =
ToBrowserAccessibilityAuraLinux(atk_object);
if (!obj)
return 0;
return obj->GetIndexInParent();
}
static AtkAttributeSet* browser_accessibility_get_attributes(
AtkObject* atk_object) {
return NULL;
}
static AtkRole browser_accessibility_get_role(AtkObject* atk_object) {
BrowserAccessibilityAuraLinux* obj =
ToBrowserAccessibilityAuraLinux(atk_object);
if (!obj)
return ATK_ROLE_INVALID;
return obj->atk_role();
}
static AtkStateSet* browser_accessibility_ref_state_set(AtkObject* atk_object) {
BrowserAccessibilityAuraLinux* obj =
ToBrowserAccessibilityAuraLinux(atk_object);
if (!obj)
return NULL;
AtkStateSet* state_set = ATK_OBJECT_CLASS(browser_accessibility_parent_class)
->ref_state_set(atk_object);
int32_t state = obj->GetState();
if (state & (1 << ui::AX_STATE_FOCUSABLE))
atk_state_set_add_state(state_set, ATK_STATE_FOCUSABLE);
if (obj->manager()->GetFocus() == obj)
atk_state_set_add_state(state_set, ATK_STATE_FOCUSED);
if (!(state & (1 << ui::AX_STATE_DISABLED)))
atk_state_set_add_state(state_set, ATK_STATE_ENABLED);
return state_set;
}
static AtkRelationSet* browser_accessibility_ref_relation_set(
AtkObject* atk_object) {
AtkRelationSet* relation_set =
ATK_OBJECT_CLASS(browser_accessibility_parent_class)
->ref_relation_set(atk_object);
return relation_set;
}
//
// The rest of the BrowserAccessibilityAuraLinux code, not specific to one
// of the Atk* interfaces.
//
static void browser_accessibility_init(AtkObject* atk_object, gpointer data) {
if (ATK_OBJECT_CLASS(browser_accessibility_parent_class)->initialize) {
ATK_OBJECT_CLASS(browser_accessibility_parent_class)
->initialize(atk_object, data);
}
BROWSER_ACCESSIBILITY(atk_object)->m_object =
reinterpret_cast<BrowserAccessibilityAuraLinux*>(data);
}
static void browser_accessibility_finalize(GObject* atk_object) {
G_OBJECT_CLASS(browser_accessibility_parent_class)->finalize(atk_object);
}
static void browser_accessibility_class_init(AtkObjectClass* klass) {
GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
browser_accessibility_parent_class = g_type_class_peek_parent(klass);
gobject_class->finalize = browser_accessibility_finalize;
klass->initialize = browser_accessibility_init;
klass->get_name = browser_accessibility_get_name;
klass->get_description = browser_accessibility_get_description;
klass->get_parent = browser_accessibility_get_parent;
klass->get_n_children = browser_accessibility_get_n_children;
klass->ref_child = browser_accessibility_ref_child;
klass->get_role = browser_accessibility_get_role;
klass->ref_state_set = browser_accessibility_ref_state_set;
klass->get_index_in_parent = browser_accessibility_get_index_in_parent;
klass->get_attributes = browser_accessibility_get_attributes;
klass->ref_relation_set = browser_accessibility_ref_relation_set;
}
GType browser_accessibility_get_type() {
static volatile gsize type_volatile = 0;
#if !GLIB_CHECK_VERSION(2, 36, 0)
g_type_init();
#endif
if (g_once_init_enter(&type_volatile)) {
static const GTypeInfo tinfo = {
sizeof(BrowserAccessibilityAtkClass),
(GBaseInitFunc)0,
(GBaseFinalizeFunc)0,
(GClassInitFunc)browser_accessibility_class_init,
(GClassFinalizeFunc)0,
0, /* class data */
sizeof(BrowserAccessibilityAtk), /* instance size */
0, /* nb preallocs */
(GInstanceInitFunc)0,
0 /* value table */
};
GType type = g_type_register_static(ATK_TYPE_OBJECT, "BrowserAccessibility",
&tinfo, GTypeFlags(0));
g_once_init_leave(&type_volatile, type);
}
return type_volatile;
}
static const char* GetUniqueAccessibilityTypeName(int interface_mask) {
// 20 characters is enough for "Chrome%x" with any integer value.
static char name[20];
snprintf(name, sizeof(name), "Chrome%x", interface_mask);
return name;
}
enum AtkInterfaces {
ATK_ACTION_INTERFACE,
ATK_COMPONENT_INTERFACE,
ATK_DOCUMENT_INTERFACE,
ATK_EDITABLE_TEXT_INTERFACE,
ATK_HYPERLINK_INTERFACE,
ATK_HYPERTEXT_INTERFACE,
ATK_IMAGE_INTERFACE,
ATK_SELECTION_INTERFACE,
ATK_TABLE_INTERFACE,
ATK_TEXT_INTERFACE,
ATK_VALUE_INTERFACE,
};
static int GetInterfaceMaskFromObject(BrowserAccessibilityAuraLinux* obj) {
int interface_mask = 0;
// Component interface is always supported.
interface_mask |= 1 << ATK_COMPONENT_INTERFACE;
// Action interface is basic one. It just relays on executing default action
// for each object.
interface_mask |= 1 << ATK_ACTION_INTERFACE;
// Value Interface
int role = obj->GetRole();
if (role == ui::AX_ROLE_PROGRESS_INDICATOR ||
role == ui::AX_ROLE_SCROLL_BAR || role == ui::AX_ROLE_SLIDER) {
interface_mask |= 1 << ATK_VALUE_INTERFACE;
}
// Document Interface
if (role == ui::AX_ROLE_DOCUMENT || role == ui::AX_ROLE_ROOT_WEB_AREA ||
role == ui::AX_ROLE_WEB_AREA)
interface_mask |= 1 << ATK_DOCUMENT_INTERFACE;
// Image Interface
if (role == ui::AX_ROLE_IMAGE || role == ui::AX_ROLE_IMAGE_MAP)
interface_mask |= 1 << ATK_IMAGE_INTERFACE;
return interface_mask;
}
static GType GetAccessibilityTypeFromObject(
BrowserAccessibilityAuraLinux* obj) {
static const GTypeInfo type_info = {
sizeof(BrowserAccessibilityAtkClass),
(GBaseInitFunc)0,
(GBaseFinalizeFunc)0,
(GClassInitFunc)0,
(GClassFinalizeFunc)0,
0, /* class data */
sizeof(BrowserAccessibilityAtk), /* instance size */
0, /* nb preallocs */
(GInstanceInitFunc)0,
0 /* value table */
};
int interface_mask = GetInterfaceMaskFromObject(obj);
const char* atk_type_name = GetUniqueAccessibilityTypeName(interface_mask);
GType type = g_type_from_name(atk_type_name);
if (type)
return type;
type = g_type_register_static(BROWSER_ACCESSIBILITY_TYPE, atk_type_name,
&type_info, GTypeFlags(0));
if (interface_mask & (1 << ATK_ACTION_INTERFACE))
g_type_add_interface_static(type, ATK_TYPE_ACTION, &ActionInfo);
if (interface_mask & (1 << ATK_COMPONENT_INTERFACE))
g_type_add_interface_static(type, ATK_TYPE_COMPONENT, &ComponentInfo);
if (interface_mask & (1 << ATK_DOCUMENT_INTERFACE))
g_type_add_interface_static(type, ATK_TYPE_DOCUMENT, &DocumentInfo);
if (interface_mask & (1 << ATK_IMAGE_INTERFACE))
g_type_add_interface_static(type, ATK_TYPE_IMAGE, &ImageInfo);
if (interface_mask & (1 << ATK_VALUE_INTERFACE))
g_type_add_interface_static(type, ATK_TYPE_VALUE, &ValueInfo);
return type;
}
BrowserAccessibilityAtk* browser_accessibility_new(
BrowserAccessibilityAuraLinux* obj) {
#if !GLIB_CHECK_VERSION(2, 36, 0)
static bool first_time = true;
if (first_time) {
g_type_init();
first_time = false;
}
#endif
GType type = GetAccessibilityTypeFromObject(obj);
AtkObject* atk_object = static_cast<AtkObject*>(g_object_new(type, 0));
atk_object_initialize(atk_object, obj);
return BROWSER_ACCESSIBILITY(atk_object);
}
void browser_accessibility_detach(BrowserAccessibilityAtk* atk_object) {
atk_object->m_object = NULL;
}
// static
BrowserAccessibility* BrowserAccessibility::Create() {
return new BrowserAccessibilityAuraLinux();
}
BrowserAccessibilityAuraLinux::BrowserAccessibilityAuraLinux()
: atk_object_(NULL) {
}
BrowserAccessibilityAuraLinux::~BrowserAccessibilityAuraLinux() {
browser_accessibility_detach(BROWSER_ACCESSIBILITY(atk_object_));
if (atk_object_)
g_object_unref(atk_object_);
}
AtkObject* BrowserAccessibilityAuraLinux::GetAtkObject() const {
if (!G_IS_OBJECT(atk_object_))
return NULL;
return atk_object_;
}
void BrowserAccessibilityAuraLinux::OnDataChanged() {
BrowserAccessibility::OnDataChanged();
InitRoleAndState();
if (atk_object_) {
// If the object's role changes and that causes its
// interface mask to change, we need to create a new
// AtkObject for it.
int interface_mask = GetInterfaceMaskFromObject(this);
if (interface_mask != interface_mask_) {
g_object_unref(atk_object_);
atk_object_ = NULL;
}
}
if (!atk_object_) {
interface_mask_ = GetInterfaceMaskFromObject(this);
atk_object_ = ATK_OBJECT(browser_accessibility_new(this));
if (this->PlatformGetParent()) {
atk_object_set_parent(atk_object_, ToBrowserAccessibilityAuraLinux(
this->PlatformGetParent())
->GetAtkObject());
}
}
}
bool BrowserAccessibilityAuraLinux::IsNative() const {
return true;
}
void BrowserAccessibilityAuraLinux::InitRoleAndState() {
switch (GetRole()) {
case ui::AX_ROLE_DOCUMENT:
case ui::AX_ROLE_ROOT_WEB_AREA:
case ui::AX_ROLE_WEB_AREA:
atk_role_ = ATK_ROLE_DOCUMENT_WEB;
break;
case ui::AX_ROLE_ALERT:
case ui::AX_ROLE_ALERT_DIALOG:
atk_role_ = ATK_ROLE_ALERT;
break;
case ui::AX_ROLE_APPLICATION:
atk_role_ = ATK_ROLE_APPLICATION;
break;
case ui::AX_ROLE_BUTTON:
atk_role_ = ATK_ROLE_PUSH_BUTTON;
break;
case ui::AX_ROLE_AUDIO:
#if defined(ATK_CHECK_VERSION)
#if ATK_CHECK_VERSION(2, 12, 0)
atk_role_ = ATK_ROLE_AUDIO;
#else
atk_role_ = ATK_ROLE_SECTION;
#endif
#else
atk_role_ = ATK_ROLE_SECTION;
#endif
break;
case ui::AX_ROLE_CANVAS:
atk_role_ = ATK_ROLE_CANVAS;
break;
case ui::AX_ROLE_CAPTION:
atk_role_ = ATK_ROLE_CAPTION;
break;
case ui::AX_ROLE_CHECK_BOX:
atk_role_ = ATK_ROLE_CHECK_BOX;
break;
case ui::AX_ROLE_COLOR_WELL:
atk_role_ = ATK_ROLE_COLOR_CHOOSER;
break;
case ui::AX_ROLE_COLUMN_HEADER:
atk_role_ = ATK_ROLE_COLUMN_HEADER;
break;
case ui::AX_ROLE_COMBO_BOX:
atk_role_ = ATK_ROLE_COMBO_BOX;
break;
case ui::AX_ROLE_DATE:
case ui::AX_ROLE_DATE_TIME:
atk_role_ = ATK_ROLE_DATE_EDITOR;
break;
case ui::AX_ROLE_DIALOG:
atk_role_ = ATK_ROLE_DIALOG;
break;
case ui::AX_ROLE_DIV:
case ui::AX_ROLE_GROUP:
atk_role_ = ATK_ROLE_SECTION;
break;
case ui::AX_ROLE_FORM:
atk_role_ = ATK_ROLE_FORM;
break;
case ui::AX_ROLE_IMAGE:
atk_role_ = ATK_ROLE_IMAGE;
break;
case ui::AX_ROLE_IMAGE_MAP:
atk_role_ = ATK_ROLE_IMAGE_MAP;
break;
case ui::AX_ROLE_LABEL_TEXT:
atk_role_ = ATK_ROLE_LABEL;
break;
case ui::AX_ROLE_LINK:
atk_role_ = ATK_ROLE_LINK;
break;
case ui::AX_ROLE_LIST:
atk_role_ = ATK_ROLE_LIST;
break;
case ui::AX_ROLE_LIST_BOX:
atk_role_ = ATK_ROLE_LIST_BOX;
break;
case ui::AX_ROLE_LIST_ITEM:
atk_role_ = ATK_ROLE_LIST_ITEM;
break;
case ui::AX_ROLE_MENU:
atk_role_ = ATK_ROLE_MENU;
break;
case ui::AX_ROLE_MENU_BAR:
atk_role_ = ATK_ROLE_MENU_BAR;
break;
case ui::AX_ROLE_MENU_ITEM:
atk_role_ = ATK_ROLE_MENU_ITEM;
break;
case ui::AX_ROLE_MENU_ITEM_CHECK_BOX:
atk_role_ = ATK_ROLE_CHECK_MENU_ITEM;
break;
case ui::AX_ROLE_MENU_ITEM_RADIO:
atk_role_ = ATK_ROLE_RADIO_MENU_ITEM;
break;
case ui::AX_ROLE_METER:
atk_role_ = ATK_ROLE_PROGRESS_BAR;
break;
case ui::AX_ROLE_PARAGRAPH:
atk_role_ = ATK_ROLE_PARAGRAPH;
break;
case ui::AX_ROLE_RADIO_BUTTON:
atk_role_ = ATK_ROLE_RADIO_BUTTON;
break;
case ui::AX_ROLE_ROW_HEADER:
atk_role_ = ATK_ROLE_ROW_HEADER;
break;
case ui::AX_ROLE_SCROLL_BAR:
atk_role_ = ATK_ROLE_SCROLL_BAR;
break;
case ui::AX_ROLE_SLIDER:
atk_role_ = ATK_ROLE_SLIDER;
break;
case ui::AX_ROLE_SPIN_BUTTON:
atk_role_ = ATK_ROLE_SPIN_BUTTON;
break;
case ui::AX_ROLE_SPLITTER:
atk_role_ = ATK_ROLE_SEPARATOR;
break;
case ui::AX_ROLE_STATIC_TEXT:
atk_role_ = ATK_ROLE_TEXT;
break;
case ui::AX_ROLE_STATUS:
atk_role_ = ATK_ROLE_STATUSBAR;
break;
case ui::AX_ROLE_TAB:
atk_role_ = ATK_ROLE_PAGE_TAB;
break;
case ui::AX_ROLE_TABLE:
atk_role_ = ATK_ROLE_TABLE;
break;
case ui::AX_ROLE_TAB_LIST:
atk_role_ = ATK_ROLE_PAGE_TAB_LIST;
break;
case ui::AX_ROLE_TOGGLE_BUTTON:
atk_role_ = ATK_ROLE_TOGGLE_BUTTON;
break;
case ui::AX_ROLE_TOOLBAR:
atk_role_ = ATK_ROLE_TOOL_BAR;
break;
case ui::AX_ROLE_TOOLTIP:
atk_role_ = ATK_ROLE_TOOL_TIP;
break;
case ui::AX_ROLE_TEXT_FIELD:
atk_role_ = ATK_ROLE_ENTRY;
break;
case ui::AX_ROLE_TREE:
atk_role_ = ATK_ROLE_TREE;
break;
case ui::AX_ROLE_TREE_ITEM:
atk_role_ = ATK_ROLE_TREE_ITEM;
break;
case ui::AX_ROLE_VIDEO:
#if defined(ATK_CHECK_VERSION)
#if ATK_CHECK_VERSION(2, 12, 0)
atk_role_ = ATK_ROLE_VIDEO;
#else
atk_role_ = ATK_ROLE_SECTION;
#endif
#else
atk_role_ = ATK_ROLE_SECTION;
#endif
break;
default:
atk_role_ = ATK_ROLE_UNKNOWN;
break;
}
}
} // namespace content