Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / ui / accessibility / platform / ax_platform_node_auralinux.cc
blob722280a97784ca0da65ad42f4fa3ca48db91269c
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/accessibility/platform/ax_platform_node_auralinux.h"
7 #include "base/command_line.h"
8 #include "base/strings/sys_string_conversions.h"
9 #include "base/task_runner.h"
10 #include "ui/accessibility/ax_node_data.h"
11 #include "ui/accessibility/platform/atk_util_auralinux.h"
12 #include "ui/accessibility/platform/ax_platform_node_delegate.h"
15 // ax_platform_node_auralinux AtkObject definition and implementation.
18 G_BEGIN_DECLS
20 #define AX_PLATFORM_NODE_AURALINUX_TYPE (ax_platform_node_auralinux_get_type())
21 #define AX_PLATFORM_NODE_AURALINUX(obj) \
22 (G_TYPE_CHECK_INSTANCE_CAST( \
23 (obj), AX_PLATFORM_NODE_AURALINUX_TYPE, AXPlatformNodeAuraLinuxObject))
24 #define AX_PLATFORM_NODE_AURALINUX_CLASS(klass) \
25 (G_TYPE_CHECK_CLASS_CAST( \
26 (klass), AX_PLATFORM_NODE_AURALINUX_TYPE, AXPlatformNodeAuraLinuxClass))
27 #define IS_AX_PLATFORM_NODE_AURALINUX(obj) \
28 (G_TYPE_CHECK_INSTANCE_TYPE((obj), AX_PLATFORM_NODE_AURALINUX_TYPE))
29 #define IS_AX_PLATFORM_NODE_AURALINUX_CLASS(klass) \
30 (G_TYPE_CHECK_CLASS_TYPE((klass), AX_PLATFORM_NODE_AURALINUX_TYPE))
31 #define AX_PLATFORM_NODE_AURALINUX_GET_CLASS(obj) \
32 (G_TYPE_INSTANCE_GET_CLASS( \
33 (obj), AX_PLATFORM_NODE_AURALINUX_TYPE, AXPlatformNodeAuraLinuxClass))
35 typedef struct _AXPlatformNodeAuraLinuxObject AXPlatformNodeAuraLinuxObject;
36 typedef struct _AXPlatformNodeAuraLinuxClass AXPlatformNodeAuraLinuxClass;
38 struct _AXPlatformNodeAuraLinuxObject {
39 AtkObject parent;
40 ui::AXPlatformNodeAuraLinux* m_object;
43 struct _AXPlatformNodeAuraLinuxClass {
44 AtkObjectClass parent_class;
47 GType ax_platform_node_auralinux_get_type();
49 static gpointer ax_platform_node_auralinux_parent_class = nullptr;
51 static ui::AXPlatformNodeAuraLinux* ToAXPlatformNodeAuraLinux(
52 AXPlatformNodeAuraLinuxObject* atk_object) {
53 if (!atk_object)
54 return nullptr;
56 return atk_object->m_object;
59 static ui::AXPlatformNodeAuraLinux* AtkObjectToAXPlatformNodeAuraLinux(
60 AtkObject* atk_object) {
61 if (!atk_object)
62 return nullptr;
64 if (IS_AX_PLATFORM_NODE_AURALINUX(atk_object))
65 return ToAXPlatformNodeAuraLinux(AX_PLATFORM_NODE_AURALINUX(atk_object));
67 return nullptr;
70 static const gchar* ax_platform_node_auralinux_get_name(AtkObject* atk_object) {
71 ui::AXPlatformNodeAuraLinux* obj =
72 AtkObjectToAXPlatformNodeAuraLinux(atk_object);
73 if (!obj)
74 return nullptr;
76 return obj->GetStringAttribute(ui::AX_ATTR_NAME).c_str();
79 static const gchar* ax_platform_node_auralinux_get_description(
80 AtkObject* atk_object) {
81 ui::AXPlatformNodeAuraLinux* obj =
82 AtkObjectToAXPlatformNodeAuraLinux(atk_object);
83 if (!obj)
84 return nullptr;
86 return obj->GetStringAttribute(
87 ui::AX_ATTR_DESCRIPTION).c_str();
90 static gint ax_platform_node_auralinux_get_index_in_parent(
91 AtkObject* atk_object) {
92 ui::AXPlatformNodeAuraLinux* obj =
93 AtkObjectToAXPlatformNodeAuraLinux(atk_object);
95 if (!obj || !obj->GetParent())
96 return -1;
98 AtkObject* obj_parent = obj->GetParent();
100 unsigned child_count = atk_object_get_n_accessible_children(obj_parent);
101 for (unsigned index = 0; index < child_count; index++) {
102 AtkObject* child = atk_object_ref_accessible_child(obj_parent, index);
103 bool atk_object_found = child == atk_object;
104 g_object_unref(child);
105 if (atk_object_found)
106 return index;
109 return obj->GetIndexInParent();
112 static AtkObject* ax_platform_node_auralinux_get_parent(AtkObject* atk_object) {
113 ui::AXPlatformNodeAuraLinux* obj =
114 AtkObjectToAXPlatformNodeAuraLinux(atk_object);
115 if (!obj)
116 return nullptr;
118 return obj->GetParent();
121 static gint ax_platform_node_auralinux_get_n_children(AtkObject* atk_object) {
122 ui::AXPlatformNodeAuraLinux* obj =
123 AtkObjectToAXPlatformNodeAuraLinux(atk_object);
124 if (!obj)
125 return 0;
127 return obj->GetChildCount();
130 static AtkObject* ax_platform_node_auralinux_ref_child(
131 AtkObject* atk_object, gint index) {
132 ui::AXPlatformNodeAuraLinux* obj =
133 AtkObjectToAXPlatformNodeAuraLinux(atk_object);
134 if (!obj)
135 return nullptr;
137 AtkObject* result = obj->ChildAtIndex(index);
138 if (result)
139 g_object_ref(result);
140 return result;
143 static AtkRelationSet* ax_platform_node_auralinux_ref_relation_set(
144 AtkObject* atk_object) {
145 ui::AXPlatformNodeAuraLinux* obj =
146 AtkObjectToAXPlatformNodeAuraLinux(atk_object);
147 AtkRelationSet* atk_relation_set =
148 ATK_OBJECT_CLASS(ax_platform_node_auralinux_parent_class)->
149 ref_relation_set(atk_object);
151 if (!obj)
152 return atk_relation_set;
154 obj->GetAtkRelations(atk_relation_set);
155 return atk_relation_set;
158 static AtkAttributeSet* ax_platform_node_auralinux_get_attributes(
159 AtkObject* atk_object) {
160 return NULL;
163 static AtkRole ax_platform_node_auralinux_get_role(AtkObject* atk_object) {
164 ui::AXPlatformNodeAuraLinux* obj =
165 AtkObjectToAXPlatformNodeAuraLinux(atk_object);
166 if (!obj)
167 return ATK_ROLE_INVALID;
168 return obj->GetAtkRole();
171 static AtkStateSet* ax_platform_node_auralinux_ref_state_set(
172 AtkObject* atk_object) {
173 ui::AXPlatformNodeAuraLinux* obj =
174 AtkObjectToAXPlatformNodeAuraLinux(atk_object);
175 if (!obj)
176 return NULL;
178 AtkStateSet* atk_state_set =
179 ATK_OBJECT_CLASS(ax_platform_node_auralinux_parent_class)->
180 ref_state_set(atk_object);
182 obj->GetAtkState(atk_state_set);
183 return atk_state_set;
187 // AtkComponent interface
190 static gfx::Point FindAtkObjectParentCoords(AtkObject* atk_object) {
191 if (!atk_object)
192 return gfx::Point(0, 0);
194 if (atk_object_get_role(atk_object) == ATK_ROLE_WINDOW) {
195 int x, y;
196 atk_component_get_extents(ATK_COMPONENT(atk_object),
197 &x, &y, nullptr, nullptr, ATK_XY_WINDOW);
198 gfx::Point window_coords(x, y);
199 return window_coords;
201 atk_object = atk_object_get_parent(atk_object);
203 return FindAtkObjectParentCoords(atk_object);
206 static void ax_platform_node_auralinux_get_extents(AtkComponent* atk_component,
207 gint* x, gint* y,
208 gint* width, gint* height,
209 AtkCoordType coord_type) {
210 g_return_if_fail(ATK_IS_COMPONENT(atk_component));
212 if (x)
213 *x = 0;
214 if (y)
215 *y = 0;
216 if (width)
217 *width = 0;
218 if (height)
219 *height = 0;
221 AtkObject* atk_object = ATK_OBJECT(atk_component);
222 ui::AXPlatformNodeAuraLinux* obj =
223 AtkObjectToAXPlatformNodeAuraLinux(atk_object);
224 if (!obj)
225 return;
227 obj->GetExtents(x, y, width, height, coord_type);
230 static void ax_platform_node_auralinux_get_position(AtkComponent* atk_component,
231 gint* x, gint* y,
232 AtkCoordType coord_type) {
233 g_return_if_fail(ATK_IS_COMPONENT(atk_component));
235 if (x)
236 *x = 0;
237 if (y)
238 *y = 0;
240 AtkObject* atk_object = ATK_OBJECT(atk_component);
241 ui::AXPlatformNodeAuraLinux* obj =
242 AtkObjectToAXPlatformNodeAuraLinux(atk_object);
243 if (!obj)
244 return;
246 obj->GetPosition(x, y, coord_type);
249 static void ax_platform_node_auralinux_get_size(AtkComponent* atk_component,
250 gint* width, gint* height) {
251 g_return_if_fail(ATK_IS_COMPONENT(atk_component));
253 if (width)
254 *width = 0;
255 if (height)
256 *height = 0;
258 AtkObject* atk_object = ATK_OBJECT(atk_component);
259 ui::AXPlatformNodeAuraLinux* obj =
260 AtkObjectToAXPlatformNodeAuraLinux(atk_object);
261 if (!obj)
262 return;
264 obj->GetSize(width, height);
267 void ax_component_interface_base_init(AtkComponentIface* iface) {
268 iface->get_extents = ax_platform_node_auralinux_get_extents;
269 iface->get_position = ax_platform_node_auralinux_get_position;
270 iface->get_size = ax_platform_node_auralinux_get_size;
273 static const GInterfaceInfo ComponentInfo = {
274 reinterpret_cast<GInterfaceInitFunc>(ax_component_interface_base_init), 0, 0
278 // The rest of the AXPlatformNodeAuraLinux code, not specific to one
279 // of the Atk* interfaces.
282 static void ax_platform_node_auralinux_init(AtkObject* atk_object,
283 gpointer data) {
284 if (ATK_OBJECT_CLASS(ax_platform_node_auralinux_parent_class)->initialize) {
285 ATK_OBJECT_CLASS(ax_platform_node_auralinux_parent_class)->initialize(
286 atk_object, data);
289 AX_PLATFORM_NODE_AURALINUX(atk_object)->m_object =
290 reinterpret_cast<ui::AXPlatformNodeAuraLinux*>(data);
293 static void ax_platform_node_auralinux_finalize(GObject* atk_object) {
294 G_OBJECT_CLASS(ax_platform_node_auralinux_parent_class)->finalize(atk_object);
297 static void ax_platform_node_auralinux_class_init(AtkObjectClass* klass) {
298 GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
299 ax_platform_node_auralinux_parent_class = g_type_class_peek_parent(klass);
301 gobject_class->finalize = ax_platform_node_auralinux_finalize;
302 klass->initialize = ax_platform_node_auralinux_init;
303 klass->get_name = ax_platform_node_auralinux_get_name;
304 klass->get_description = ax_platform_node_auralinux_get_description;
305 klass->get_parent = ax_platform_node_auralinux_get_parent;
306 klass->get_n_children = ax_platform_node_auralinux_get_n_children;
307 klass->ref_child = ax_platform_node_auralinux_ref_child;
308 klass->get_role = ax_platform_node_auralinux_get_role;
309 klass->ref_state_set = ax_platform_node_auralinux_ref_state_set;
310 klass->get_index_in_parent = ax_platform_node_auralinux_get_index_in_parent;
311 klass->ref_relation_set = ax_platform_node_auralinux_ref_relation_set;
312 klass->get_attributes = ax_platform_node_auralinux_get_attributes;
315 GType ax_platform_node_auralinux_get_type() {
316 static volatile gsize type_volatile = 0;
318 if (g_once_init_enter(&type_volatile)) {
319 static const GTypeInfo tinfo = {
320 sizeof(AXPlatformNodeAuraLinuxClass),
321 (GBaseInitFunc) 0,
322 (GBaseFinalizeFunc) 0,
323 (GClassInitFunc) ax_platform_node_auralinux_class_init,
324 (GClassFinalizeFunc) 0,
325 0, /* class data */
326 sizeof(AXPlatformNodeAuraLinuxObject), /* instance size */
327 0, /* nb preallocs */
328 (GInstanceInitFunc) 0,
329 0 /* value table */
332 GType type = g_type_register_static(
333 ATK_TYPE_OBJECT, "AXPlatformNodeAuraLinux", &tinfo, GTypeFlags(0));
334 g_type_add_interface_static(type, ATK_TYPE_COMPONENT, &ComponentInfo);
335 g_once_init_leave(&type_volatile, type);
338 return type_volatile;
341 AXPlatformNodeAuraLinuxObject* ax_platform_node_auralinux_new(
342 ui::AXPlatformNodeAuraLinux* obj) {
343 #if !GLIB_CHECK_VERSION(2, 36, 0)
344 static bool first_time = true;
345 if (first_time) {
346 g_type_init();
347 first_time = false;
349 #endif
351 GType type = AX_PLATFORM_NODE_AURALINUX_TYPE;
352 AtkObject* atk_object = static_cast<AtkObject*>(g_object_new(type, 0));
353 atk_object_initialize(atk_object, obj);
354 return AX_PLATFORM_NODE_AURALINUX(atk_object);
357 void ax_platform_node_auralinux_detach(
358 AXPlatformNodeAuraLinuxObject* atk_object) {
359 atk_object->m_object = nullptr;
362 G_END_DECLS
365 // AXPlatformNodeAuraLinux implementation.
368 namespace ui {
370 // static
371 AXPlatformNode* AXPlatformNode::Create(AXPlatformNodeDelegate* delegate) {
372 AXPlatformNodeAuraLinux* node = new AXPlatformNodeAuraLinux();
373 node->Init(delegate);
374 return node;
377 // static
378 AXPlatformNode* AXPlatformNodeAuraLinux::application_ = nullptr;
380 // static
381 void AXPlatformNodeAuraLinux::SetApplication(AXPlatformNode* application) {
382 application_ = application;
385 // static
386 void AXPlatformNodeAuraLinux::StaticInitialize(
387 scoped_refptr<base::TaskRunner> init_task_runner) {
388 AtkUtilAuraLinux::GetInstance()->Initialize(init_task_runner);
391 AtkRole AXPlatformNodeAuraLinux::GetAtkRole() {
392 switch (GetData().role) {
393 case ui::AX_ROLE_ALERT:
394 return ATK_ROLE_ALERT;
395 case ui::AX_ROLE_APPLICATION:
396 return ATK_ROLE_APPLICATION;
397 case ui::AX_ROLE_BUTTON:
398 return ATK_ROLE_PUSH_BUTTON;
399 case ui::AX_ROLE_CHECK_BOX:
400 return ATK_ROLE_CHECK_BOX;
401 case ui::AX_ROLE_COMBO_BOX:
402 return ATK_ROLE_COMBO_BOX;
403 case ui::AX_ROLE_DIALOG:
404 return ATK_ROLE_DIALOG;
405 case ui::AX_ROLE_GROUP:
406 return ATK_ROLE_PANEL;
407 case ui::AX_ROLE_IMAGE:
408 return ATK_ROLE_IMAGE;
409 case ui::AX_ROLE_MENU_ITEM:
410 return ATK_ROLE_MENU_ITEM;
411 case ui::AX_ROLE_SCROLL_BAR:
412 return ATK_ROLE_SCROLL_BAR;
413 case ui::AX_ROLE_SLIDER:
414 return ATK_ROLE_SLIDER;
415 case ui::AX_ROLE_SPLITTER:
416 return ATK_ROLE_SEPARATOR;
417 case ui::AX_ROLE_STATIC_TEXT:
418 return ATK_ROLE_TEXT;
419 case ui::AX_ROLE_TAB:
420 return ATK_ROLE_PAGE_TAB;
421 case ui::AX_ROLE_TAB_LIST:
422 return ATK_ROLE_PAGE_TAB_LIST;
423 case ui::AX_ROLE_TEXT_FIELD:
424 return ATK_ROLE_ENTRY;
425 case ui::AX_ROLE_TOOLBAR:
426 return ATK_ROLE_TOOL_BAR;
427 case ui::AX_ROLE_WINDOW:
428 return ATK_ROLE_WINDOW;
429 default:
430 return ATK_ROLE_UNKNOWN;
434 void AXPlatformNodeAuraLinux::GetAtkState(AtkStateSet* atk_state_set) {
435 uint32 state = GetData().state;
437 if (state & (1 << ui::AX_STATE_CHECKED))
438 atk_state_set_add_state(atk_state_set, ATK_STATE_CHECKED);
439 if (state & (1 << ui::AX_STATE_DEFAULT))
440 atk_state_set_add_state(atk_state_set, ATK_STATE_DEFAULT);
441 if (state & (1 << ui::AX_STATE_EDITABLE))
442 atk_state_set_add_state(atk_state_set, ATK_STATE_EDITABLE);
443 if (state & (1 << ui::AX_STATE_ENABLED))
444 atk_state_set_add_state(atk_state_set, ATK_STATE_ENABLED);
445 if (state & (1 << ui::AX_STATE_EXPANDED))
446 atk_state_set_add_state(atk_state_set, ATK_STATE_EXPANDED);
447 if (state & (1 << ui::AX_STATE_FOCUSABLE))
448 atk_state_set_add_state(atk_state_set, ATK_STATE_FOCUSABLE);
449 if (state & (1 << ui::AX_STATE_FOCUSED))
450 atk_state_set_add_state(atk_state_set, ATK_STATE_FOCUSED);
451 if (state & (1 << ui::AX_STATE_PRESSED))
452 atk_state_set_add_state(atk_state_set, ATK_STATE_PRESSED);
453 if (state & (1 << ui::AX_STATE_SELECTABLE))
454 atk_state_set_add_state(atk_state_set, ATK_STATE_SELECTABLE);
455 if (state & (1 << ui::AX_STATE_SELECTED))
456 atk_state_set_add_state(atk_state_set, ATK_STATE_SELECTED);
459 void AXPlatformNodeAuraLinux::GetAtkRelations(AtkRelationSet* atk_relation_set)
463 AXPlatformNodeAuraLinux::AXPlatformNodeAuraLinux()
464 : atk_object_(nullptr) {
467 AXPlatformNodeAuraLinux::~AXPlatformNodeAuraLinux() {
468 g_object_unref(atk_object_);
471 void AXPlatformNodeAuraLinux::Init(AXPlatformNodeDelegate* delegate) {
472 // Initialize ATK.
473 AXPlatformNodeBase::Init(delegate);
474 atk_object_ = ATK_OBJECT(ax_platform_node_auralinux_new(this));
477 void AXPlatformNodeAuraLinux::Destroy() {
478 delegate_ = nullptr;
479 delete this;
482 gfx::NativeViewAccessible AXPlatformNodeAuraLinux::GetNativeViewAccessible() {
483 return atk_object_;
486 void AXPlatformNodeAuraLinux::NotifyAccessibilityEvent(ui::AXEvent event_type) {
489 int AXPlatformNodeAuraLinux::GetIndexInParent() {
490 return 0;
493 void AXPlatformNodeAuraLinux::SetExtentsRelativeToAtkCoordinateType(
494 gint* x, gint* y, gint* width, gint* height, AtkCoordType coord_type) {
495 gfx::Rect extents = GetBoundsInScreen();
497 if (x)
498 *x = extents.x();
499 if (y)
500 *y = extents.y();
501 if (width)
502 *width = extents.width();
503 if (height)
504 *height = extents.height();
506 if (coord_type == ATK_XY_WINDOW) {
507 if (AtkObject* atk_object = GetParent()) {
508 gfx::Point window_coords = FindAtkObjectParentCoords(atk_object);
509 if (x)
510 *x -= window_coords.x();
511 if (y)
512 *y -= window_coords.y();
517 void AXPlatformNodeAuraLinux::GetExtents(gint* x, gint* y,
518 gint* width, gint* height,
519 AtkCoordType coord_type) {
520 SetExtentsRelativeToAtkCoordinateType(x, y,
521 width, height,
522 coord_type);
525 void AXPlatformNodeAuraLinux::GetPosition(gint* x, gint* y,
526 AtkCoordType coord_type) {
527 SetExtentsRelativeToAtkCoordinateType(x, y,
528 nullptr,nullptr,
529 coord_type);
532 void AXPlatformNodeAuraLinux::GetSize(gint* width, gint* height) {
533 gfx::Rect rect_size = GetData().location;
534 if (width)
535 *width = rect_size.width();
536 if (height)
537 *height = rect_size.height();
540 } // namespace ui