Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Side by Side Diff: content/browser/accessibility/browser_accessibility_gtk.cc

Issue 21148002: Implement AtkComponent and AtkValue interfaces. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix clang compile error Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « content/browser/accessibility/browser_accessibility_gtk.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/accessibility/browser_accessibility_gtk.h" 5 #include "content/browser/accessibility/browser_accessibility_gtk.h"
6 6
7 #include <gtk/gtk.h> 7 #include <gtk/gtk.h>
8 8
9 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h"
10 #include "content/browser/accessibility/browser_accessibility_manager_gtk.h" 10 #include "content/browser/accessibility/browser_accessibility_manager_gtk.h"
11 #include "content/common/accessibility_messages.h" 11 #include "content/common/accessibility_messages.h"
12 12
13 namespace content { 13 namespace content {
14 14
15 // The maximum length of an autogenerated unique type name string,
16 // generated from the 16-bit interface mask from an AtkObject.
17 // 30 is enough for the prefix "WAIType" + 5 hex chars (max) */
18 static const int kWAITypeNameLen = 30;
19
20 static gpointer browser_accessibility_parent_class = NULL; 15 static gpointer browser_accessibility_parent_class = NULL;
21 16
22 static BrowserAccessibilityGtk* ToBrowserAccessibilityGtk( 17 static BrowserAccessibilityGtk* ToBrowserAccessibilityGtk(
23 BrowserAccessibilityAtk* atk_object) { 18 BrowserAccessibilityAtk* atk_object) {
24 if (!atk_object) 19 if (!atk_object)
25 return NULL; 20 return NULL;
26 21
27 return atk_object->m_object; 22 return atk_object->m_object;
28 } 23 }
29 24
25 //
26 // AtkComponent interface.
27 //
28
29 static BrowserAccessibilityGtk* ToBrowserAccessibilityGtk(
30 AtkComponent* atk_object) {
31 if (!IS_BROWSER_ACCESSIBILITY(atk_object))
32 return NULL;
33
34 return ToBrowserAccessibilityGtk(BROWSER_ACCESSIBILITY(atk_object));
35 }
36
37 static AtkObject* browser_accessibility_accessible_at_point(
38 AtkComponent* component, gint x, gint y, AtkCoordType coord_type) {
39 BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(component);
40 if (!obj)
41 return NULL;
42
43 gfx::Point point(x, y);
44 if (!obj->GetGlobalBoundsRect().Contains(point))
45 return NULL;
46
47 BrowserAccessibility* result = obj->BrowserAccessibilityForPoint(point);
48 if (!result)
49 return NULL;
50
51 AtkObject* atk_result = result->ToBrowserAccessibilityGtk()->GetAtkObject();
52 g_object_ref(atk_result);
53 return atk_result;
54 }
55
56 static void browser_accessibility_get_extents(
57 AtkComponent* component, gint* x, gint* y, gint* width, gint* height,
58 AtkCoordType coord_type) {
59 BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(component);
60 if (!obj)
61 return;
62
63 gfx::Rect bounds = obj->GetGlobalBoundsRect();
64 *x = bounds.x();
65 *y = bounds.y();
66 *width = bounds.width();
67 *height = bounds.height();
68 }
69
70 static gboolean browser_accessibility_grab_focus(AtkComponent* component) {
71 BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(component);
72 if (!obj)
73 return false;
74
75 obj->manager()->SetFocus(obj, true);
76 return true;
77 }
78
79 static void ComponentInterfaceInit(AtkComponentIface* iface) {
80 iface->ref_accessible_at_point = browser_accessibility_accessible_at_point;
81 iface->get_extents = browser_accessibility_get_extents;
82 iface->grab_focus = browser_accessibility_grab_focus;
83 }
84
85 static const GInterfaceInfo ComponentInfo = {
86 reinterpret_cast<GInterfaceInitFunc>(ComponentInterfaceInit), 0, 0
87 };
88
89 //
90 // AtkValue interface.
91 //
92
93 static BrowserAccessibilityGtk* ToBrowserAccessibilityGtk(
94 AtkValue* atk_object) {
95 if (!IS_BROWSER_ACCESSIBILITY(atk_object))
96 return NULL;
97
98 return ToBrowserAccessibilityGtk(BROWSER_ACCESSIBILITY(atk_object));
99 }
100
101 static void browser_accessibility_get_current_value(
102 AtkValue* atk_object, GValue* value) {
103 BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(atk_object);
104 if (!obj)
105 return;
106
107 float float_val;
108 if (obj->GetFloatAttribute(AccessibilityNodeData::ATTR_VALUE_FOR_RANGE,
109 &float_val)) {
110 memset(value, 0, sizeof(*value));
111 g_value_init(value, G_TYPE_FLOAT);
112 g_value_set_float(value, float_val);
113 }
114 }
115
116 static void browser_accessibility_get_minimum_value(
117 AtkValue* atk_object, GValue* value) {
118 BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(atk_object);
119 if (!obj)
120 return;
121
122 float float_val;
123 if (obj->GetFloatAttribute(AccessibilityNodeData::ATTR_MIN_VALUE_FOR_RANGE,
124 &float_val)) {
125 memset(value, 0, sizeof(*value));
126 g_value_init(value, G_TYPE_FLOAT);
127 g_value_set_float(value, float_val);
128 }
129 }
130
131 static void browser_accessibility_get_maximum_value(
132 AtkValue* atk_object, GValue* value) {
133 BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(atk_object);
134 if (!obj)
135 return;
136
137 float float_val;
138 if (obj->GetFloatAttribute(AccessibilityNodeData::ATTR_MAX_VALUE_FOR_RANGE,
139 &float_val)) {
140 memset(value, 0, sizeof(*value));
141 g_value_init(value, G_TYPE_FLOAT);
142 g_value_set_float(value, float_val);
143 }
144 }
145
146 static void browser_accessibility_get_minimum_increment(
147 AtkValue* atk_object, GValue* value) {
148 // TODO(dmazzoni): get the correct value from an <input type=range>.
149 memset(value, 0, sizeof(*value));
150 g_value_init(value, G_TYPE_FLOAT);
151 g_value_set_float(value, 1.0);
152 }
153
154 static void ValueInterfaceInit(AtkValueIface* iface) {
155 iface->get_current_value = browser_accessibility_get_current_value;
156 iface->get_minimum_value = browser_accessibility_get_minimum_value;
157 iface->get_maximum_value = browser_accessibility_get_maximum_value;
158 iface->get_minimum_increment = browser_accessibility_get_minimum_increment;
159 }
160
161 static const GInterfaceInfo ValueInfo = {
162 reinterpret_cast<GInterfaceInitFunc>(ValueInterfaceInit), 0, 0
163 };
164
165 //
166 // AtkObject interface
167 //
168
30 static BrowserAccessibilityGtk* ToBrowserAccessibilityGtk( 169 static BrowserAccessibilityGtk* ToBrowserAccessibilityGtk(
31 AtkObject* atk_object) { 170 AtkObject* atk_object) {
32 if (!IS_BROWSER_ACCESSIBILITY(atk_object)) 171 if (!IS_BROWSER_ACCESSIBILITY(atk_object))
33 return NULL; 172 return NULL;
34 173
35 return ToBrowserAccessibilityGtk(BROWSER_ACCESSIBILITY(atk_object)); 174 return ToBrowserAccessibilityGtk(BROWSER_ACCESSIBILITY(atk_object));
36 } 175 }
37 176
38 static const gchar* browser_accessibility_get_name(AtkObject* atk_object) { 177 static const gchar* browser_accessibility_get_name(AtkObject* atk_object) {
39 BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(atk_object); 178 BrowserAccessibilityGtk* obj = ToBrowserAccessibilityGtk(atk_object);
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 } 258 }
120 259
121 static AtkRelationSet* browser_accessibility_ref_relation_set( 260 static AtkRelationSet* browser_accessibility_ref_relation_set(
122 AtkObject* atk_object) { 261 AtkObject* atk_object) {
123 AtkRelationSet* relation_set = 262 AtkRelationSet* relation_set =
124 ATK_OBJECT_CLASS(browser_accessibility_parent_class) 263 ATK_OBJECT_CLASS(browser_accessibility_parent_class)
125 ->ref_relation_set(atk_object); 264 ->ref_relation_set(atk_object);
126 return relation_set; 265 return relation_set;
127 } 266 }
128 267
268 //
269 // The rest of the BrowserAccessibilityGtk code, not specific to one
270 // of the Atk* interfaces.
271 //
272
129 static void browser_accessibility_init(AtkObject* atk_object, gpointer data) { 273 static void browser_accessibility_init(AtkObject* atk_object, gpointer data) {
130 if (ATK_OBJECT_CLASS(browser_accessibility_parent_class)->initialize) { 274 if (ATK_OBJECT_CLASS(browser_accessibility_parent_class)->initialize) {
131 ATK_OBJECT_CLASS(browser_accessibility_parent_class)->initialize( 275 ATK_OBJECT_CLASS(browser_accessibility_parent_class)->initialize(
132 atk_object, data); 276 atk_object, data);
133 } 277 }
134 278
135 BROWSER_ACCESSIBILITY(atk_object)->m_object = 279 BROWSER_ACCESSIBILITY(atk_object)->m_object =
136 reinterpret_cast<BrowserAccessibilityGtk*>(data); 280 reinterpret_cast<BrowserAccessibilityGtk*>(data);
137 } 281 }
138 282
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 }; 320 };
177 321
178 GType type = g_type_register_static( 322 GType type = g_type_register_static(
179 ATK_TYPE_OBJECT, "BrowserAccessibility", &tinfo, GTypeFlags(0)); 323 ATK_TYPE_OBJECT, "BrowserAccessibility", &tinfo, GTypeFlags(0));
180 g_once_init_leave(&type_volatile, type); 324 g_once_init_leave(&type_volatile, type);
181 } 325 }
182 326
183 return type_volatile; 327 return type_volatile;
184 } 328 }
185 329
186 static guint16 GetInterfaceMaskFromObject(BrowserAccessibilityGtk* obj) { 330 static const char* GetUniqueAccessibilityTypeName(int interface_mask)
187 return 0;
188 }
189
190 static const char* GetUniqueAccessibilityTypeName(guint16 interface_mask)
191 { 331 {
192 static char name[kWAITypeNameLen + 1]; 332 // 20 characters is enough for "Chrome%x" with any integer value.
193 333 static char name[20];
194 sprintf(name, "WAIType%x", interface_mask); 334 snprintf(name, sizeof(name), "Chrome%x", interface_mask);
195 name[kWAITypeNameLen] = '\0';
196
197 return name; 335 return name;
198 } 336 }
199 337
200 static const GInterfaceInfo AtkInterfacesInitFunctions[] = { 338 enum AtkInterfaces {
339 ATK_ACTION_INTERFACE,
340 ATK_COMPONENT_INTERFACE,
341 ATK_DOCUMENT_INTERFACE,
342 ATK_EDITABLE_TEXT_INTERFACE,
343 ATK_HYPERLINK_INTERFACE,
344 ATK_HYPERTEXT_INTERFACE,
345 ATK_IMAGE_INTERFACE,
346 ATK_SELECTION_INTERFACE,
347 ATK_TABLE_INTERFACE,
348 ATK_TEXT_INTERFACE,
349 ATK_VALUE_INTERFACE,
201 }; 350 };
202 351
203 enum WAIType { 352 static int GetInterfaceMaskFromObject(BrowserAccessibilityGtk* obj) {
204 WAI_ACTION, 353 int interface_mask = 0;
205 WAI_SELECTION,
206 WAI_EDITABLE_TEXT,
207 WAI_TEXT,
208 WAI_COMPONENT,
209 WAI_IMAGE,
210 WAI_TABLE,
211 WAI_HYPERTEXT,
212 WAI_HYPERLINK,
213 WAI_DOCUMENT,
214 WAI_VALUE,
215 };
216 354
217 static GType GetAtkInterfaceTypeFromWAIType(WAIType type) { 355 // Component interface is always supported.
218 switch (type) { 356 interface_mask |= 1 << ATK_COMPONENT_INTERFACE;
219 case WAI_ACTION: 357
220 return ATK_TYPE_ACTION; 358 int role = obj->role();
221 case WAI_SELECTION: 359 if (role == AccessibilityNodeData::ROLE_PROGRESS_INDICATOR ||
222 return ATK_TYPE_SELECTION; 360 role == AccessibilityNodeData::ROLE_SCROLLBAR ||
223 case WAI_EDITABLE_TEXT: 361 role == AccessibilityNodeData::ROLE_SLIDER) {
224 return ATK_TYPE_EDITABLE_TEXT; 362 interface_mask |= 1 << ATK_VALUE_INTERFACE;
225 case WAI_TEXT:
226 return ATK_TYPE_TEXT;
227 case WAI_COMPONENT:
228 return ATK_TYPE_COMPONENT;
229 case WAI_IMAGE:
230 return ATK_TYPE_IMAGE;
231 case WAI_TABLE:
232 return ATK_TYPE_TABLE;
233 case WAI_HYPERTEXT:
234 return ATK_TYPE_HYPERTEXT;
235 case WAI_HYPERLINK:
236 return ATK_TYPE_HYPERLINK_IMPL;
237 case WAI_DOCUMENT:
238 return ATK_TYPE_DOCUMENT;
239 case WAI_VALUE:
240 return ATK_TYPE_VALUE;
241 } 363 }
242 364
243 return G_TYPE_INVALID; 365 return interface_mask;
244 } 366 }
245 367
246 static GType GetAccessibilityTypeFromObject(BrowserAccessibilityGtk* obj) { 368 static GType GetAccessibilityTypeFromObject(BrowserAccessibilityGtk* obj) {
247 static const GTypeInfo type_info = { 369 static const GTypeInfo type_info = {
248 sizeof(BrowserAccessibilityAtkClass), 370 sizeof(BrowserAccessibilityAtkClass),
249 (GBaseInitFunc) 0, 371 (GBaseInitFunc) 0,
250 (GBaseFinalizeFunc) 0, 372 (GBaseFinalizeFunc) 0,
251 (GClassInitFunc) 0, 373 (GClassInitFunc) 0,
252 (GClassFinalizeFunc) 0, 374 (GClassFinalizeFunc) 0,
253 0, /* class data */ 375 0, /* class data */
254 sizeof(BrowserAccessibilityAtk), /* instance size */ 376 sizeof(BrowserAccessibilityAtk), /* instance size */
255 0, /* nb preallocs */ 377 0, /* nb preallocs */
256 (GInstanceInitFunc) 0, 378 (GInstanceInitFunc) 0,
257 0 /* value table */ 379 0 /* value table */
258 }; 380 };
259 381
260 guint16 interface_mask = GetInterfaceMaskFromObject(obj); 382 int interface_mask = GetInterfaceMaskFromObject(obj);
261 const char* atk_type_name = GetUniqueAccessibilityTypeName(interface_mask); 383 const char* atk_type_name = GetUniqueAccessibilityTypeName(interface_mask);
262 GType type = g_type_from_name(atk_type_name); 384 GType type = g_type_from_name(atk_type_name);
263 if (type) 385 if (type)
264 return type; 386 return type;
265 387
266 type = g_type_register_static(BROWSER_ACCESSIBILITY_TYPE, 388 type = g_type_register_static(BROWSER_ACCESSIBILITY_TYPE,
267 atk_type_name, 389 atk_type_name,
268 &type_info, 390 &type_info,
269 GTypeFlags(0)); 391 GTypeFlags(0));
270 for (guint i = 0; i < G_N_ELEMENTS(AtkInterfacesInitFunctions); i++) { 392 if (interface_mask & (1 << ATK_COMPONENT_INTERFACE))
271 if (interface_mask & (1 << i)) { 393 g_type_add_interface_static(type, ATK_TYPE_COMPONENT, &ComponentInfo);
272 g_type_add_interface_static( 394 if (interface_mask & (1 << ATK_VALUE_INTERFACE))
273 type, 395 g_type_add_interface_static(type, ATK_TYPE_VALUE, &ValueInfo);
274 GetAtkInterfaceTypeFromWAIType(static_cast<WAIType>(i)),
275 &AtkInterfacesInitFunctions[i]);
276 }
277 }
278 396
279 return type; 397 return type;
280 } 398 }
281 399
282 BrowserAccessibilityAtk* browser_accessibility_new( 400 BrowserAccessibilityAtk* browser_accessibility_new(
283 BrowserAccessibilityGtk* obj) { 401 BrowserAccessibilityGtk* obj) {
284 GType type = GetAccessibilityTypeFromObject(obj); 402 GType type = GetAccessibilityTypeFromObject(obj);
285 AtkObject* atk_object = static_cast<AtkObject*>(g_object_new(type, 0)); 403 AtkObject* atk_object = static_cast<AtkObject*>(g_object_new(type, 0));
286 404
287 atk_object_initialize(atk_object, obj); 405 atk_object_initialize(atk_object, obj);
288 406
289 return BROWSER_ACCESSIBILITY(atk_object); 407 return BROWSER_ACCESSIBILITY(atk_object);
290 } 408 }
291 409
292 void browser_accessibility_detach(BrowserAccessibilityAtk* atk_object) { 410 void browser_accessibility_detach(BrowserAccessibilityAtk* atk_object) {
293 atk_object->m_object = NULL; 411 atk_object->m_object = NULL;
294 } 412 }
295 413
296 // static 414 // static
297 BrowserAccessibility* BrowserAccessibility::Create() { 415 BrowserAccessibility* BrowserAccessibility::Create() {
298 return new BrowserAccessibilityGtk(); 416 return new BrowserAccessibilityGtk();
299 } 417 }
300 418
301 BrowserAccessibilityGtk* BrowserAccessibility::ToBrowserAccessibilityGtk() { 419 BrowserAccessibilityGtk* BrowserAccessibility::ToBrowserAccessibilityGtk() {
302 return static_cast<BrowserAccessibilityGtk*>(this); 420 return static_cast<BrowserAccessibilityGtk*>(this);
303 } 421 }
304 422
305 BrowserAccessibilityGtk::BrowserAccessibilityGtk() { 423 BrowserAccessibilityGtk::BrowserAccessibilityGtk()
306 atk_object_ = ATK_OBJECT(browser_accessibility_new(this)); 424 : atk_object_(NULL) {
307 } 425 }
308 426
309 BrowserAccessibilityGtk::~BrowserAccessibilityGtk() { 427 BrowserAccessibilityGtk::~BrowserAccessibilityGtk() {
310 browser_accessibility_detach(BROWSER_ACCESSIBILITY(atk_object_)); 428 browser_accessibility_detach(BROWSER_ACCESSIBILITY(atk_object_));
311 g_object_unref(atk_object_); 429 if (atk_object_)
430 g_object_unref(atk_object_);
312 } 431 }
313 432
314 AtkObject* BrowserAccessibilityGtk::GetAtkObject() const { 433 AtkObject* BrowserAccessibilityGtk::GetAtkObject() const {
315 if (!G_IS_OBJECT(atk_object_)) 434 if (!G_IS_OBJECT(atk_object_))
316 return NULL; 435 return NULL;
317 return atk_object_; 436 return atk_object_;
318 } 437 }
319 438
320 void BrowserAccessibilityGtk::PreInitialize() { 439 void BrowserAccessibilityGtk::PreInitialize() {
321 BrowserAccessibility::PreInitialize(); 440 BrowserAccessibility::PreInitialize();
322 InitRoleAndState(); 441 InitRoleAndState();
323 442
324 if (this->parent()) { 443 if (atk_object_) {
325 atk_object_set_parent( 444 // If the object's role changes and that causes its
326 atk_object_, 445 // interface mask to change, we need to create a new
327 this->parent()->ToBrowserAccessibilityGtk()->GetAtkObject()); 446 // AtkObject for it.
447 int interface_mask = GetInterfaceMaskFromObject(this);
448 if (interface_mask != interface_mask_) {
449 g_object_unref(atk_object_);
450 atk_object_ = NULL;
451 }
452 }
453
454 if (!atk_object_) {
455 interface_mask_ = GetInterfaceMaskFromObject(this);
456 atk_object_ = ATK_OBJECT(browser_accessibility_new(this));
457 if (this->parent()) {
458 atk_object_set_parent(
459 atk_object_,
460 this->parent()->ToBrowserAccessibilityGtk()->GetAtkObject());
461 }
328 } 462 }
329 } 463 }
330 464
331 bool BrowserAccessibilityGtk::IsNative() const { 465 bool BrowserAccessibilityGtk::IsNative() const {
332 return true; 466 return true;
333 } 467 }
334 468
335 void BrowserAccessibilityGtk::InitRoleAndState() { 469 void BrowserAccessibilityGtk::InitRoleAndState() {
336 atk_acc_name_ = UTF16ToUTF8(name()); 470 atk_acc_name_ = UTF16ToUTF8(name());
337 471
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 case AccessibilityNodeData::ROLE_WEBCORE_LINK: 510 case AccessibilityNodeData::ROLE_WEBCORE_LINK:
377 atk_role_ = ATK_ROLE_LINK; 511 atk_role_ = ATK_ROLE_LINK;
378 break; 512 break;
379 default: 513 default:
380 atk_role_ = ATK_ROLE_UNKNOWN; 514 atk_role_ = ATK_ROLE_UNKNOWN;
381 break; 515 break;
382 } 516 }
383 } 517 }
384 518
385 } // namespace content 519 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/accessibility/browser_accessibility_gtk.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698