Chromium Code Reviews
|
| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "content/browser/accessibility/browser_accessibility_gtk.h" | |
| 6 | |
| 7 #include "base/utf_string_conversions.h" | |
| 8 #include "content/browser/accessibility/browser_accessibility_manager_gtk.h" | |
| 9 #include "content/common/accessibility_messages.h" | |
| 10 | |
| 11 #include <gtk/gtk.h> | |
| 12 | |
| 13 using webkit_glue::WebAccessibility; | |
| 14 | |
| 15 static gpointer browser_accessibility_parent_class = NULL; | |
| 16 | |
| 17 static BrowserAccessibilityGtk* toBrowserAccessibilityGtk( | |
| 18 BrowserAccessibilityAtk* atk_object) { | |
| 19 if (!atk_object) | |
| 20 return NULL; | |
| 21 | |
| 22 return atk_object->m_object; | |
| 23 } | |
| 24 | |
| 25 static BrowserAccessibilityGtk* toBrowserAccessibilityGtk( | |
| 26 AtkObject* atk_object) { | |
| 27 if (!IS_BROWSER_ACCESSIBILITY(atk_object)) | |
| 28 return NULL; | |
| 29 | |
| 30 return toBrowserAccessibilityGtk(BROWSER_ACCESSIBILITY(atk_object)); | |
| 31 } | |
| 32 | |
| 33 static const gchar* browser_accessibility_get_name(AtkObject* atk_object) { | |
| 34 BrowserAccessibilityGtk* obj = toBrowserAccessibilityGtk(atk_object); | |
| 35 return obj->atk_acc_name().c_str(); | |
| 36 } | |
| 37 | |
| 38 static const gchar* browser_accessibility_get_description( | |
| 39 AtkObject* atk_object) { | |
| 40 BrowserAccessibilityGtk* obj = toBrowserAccessibilityGtk(atk_object); | |
| 41 string16 description; | |
| 42 obj->GetStringAttribute(WebAccessibility::ATTR_DESCRIPTION, &description); | |
| 43 return UTF16ToUTF8(description).c_str(); | |
| 44 } | |
| 45 | |
| 46 static AtkObject* browser_accessibility_get_parent(AtkObject* atk_object) { | |
| 47 BrowserAccessibilityGtk* obj = toBrowserAccessibilityGtk(atk_object); | |
| 48 if (obj->parent()) | |
| 49 return obj->parent()->toBrowserAccessibilityGtk()->GetAtkObject(); | |
| 50 else | |
| 51 return gtk_widget_get_accessible(obj->manager()->GetParentView()); | |
| 52 } | |
| 53 | |
| 54 static gint browser_accessibility_get_n_children(AtkObject* atk_object) { | |
| 55 BrowserAccessibilityGtk* obj = toBrowserAccessibilityGtk(atk_object); | |
| 56 return obj->children().size(); | |
| 57 } | |
| 58 | |
| 59 static AtkObject* browser_accessibility_ref_child( | |
| 60 AtkObject* atk_object, gint index) { | |
| 61 BrowserAccessibilityGtk* obj = toBrowserAccessibilityGtk(atk_object); | |
| 62 AtkObject* result = | |
| 63 obj->children()[index]->toBrowserAccessibilityGtk()->GetAtkObject(); | |
| 64 g_object_ref(result); | |
| 65 return result; | |
| 66 } | |
| 67 | |
| 68 static gint browser_accessibility_get_index_in_parent(AtkObject* atk_object) { | |
| 69 BrowserAccessibilityGtk* obj = toBrowserAccessibilityGtk(atk_object); | |
| 70 return obj->index_in_parent(); | |
| 71 } | |
| 72 | |
| 73 static AtkAttributeSet* browser_accessibility_get_attributes( | |
| 74 AtkObject* atk_object) { | |
| 75 return NULL; | |
| 76 } | |
| 77 | |
| 78 static AtkRole browser_accessibility_get_role(AtkObject* atk_object) { | |
| 79 BrowserAccessibilityGtk* obj = toBrowserAccessibilityGtk(atk_object); | |
| 80 return obj->atk_role(); | |
| 81 } | |
| 82 | |
| 83 static AtkStateSet* browser_accessibility_ref_state_set(AtkObject* atk_object) { | |
| 84 BrowserAccessibilityGtk* obj = toBrowserAccessibilityGtk(atk_object); | |
| 85 AtkStateSet* state_set = ATK_OBJECT_CLASS(browser_accessibility_parent_class) | |
| 86 ->ref_state_set(atk_object); | |
|
Evan Stade
2012/05/02 00:03:30
-> at end of previous line
dmazzoni
2012/05/02 06:27:33
Done.
| |
| 87 int32 state = obj->state(); | |
| 88 | |
| 89 if ((state >> WebAccessibility::STATE_FOCUSABLE) & 1) | |
| 90 atk_state_set_add_state(state_set, ATK_STATE_FOCUSABLE); | |
| 91 if (obj->manager()->GetFocus(NULL) == obj) | |
| 92 atk_state_set_add_state(state_set, ATK_STATE_FOCUSED); | |
| 93 | |
| 94 return state_set; | |
| 95 } | |
| 96 | |
| 97 static AtkRelationSet* browser_accessibility_ref_relation_set( | |
| 98 AtkObject* atk_object) { | |
| 99 AtkRelationSet* relation_set = | |
| 100 ATK_OBJECT_CLASS(browser_accessibility_parent_class) | |
| 101 ->ref_relation_set(atk_object); | |
| 102 return relation_set; | |
| 103 } | |
| 104 | |
| 105 static void browser_accessibility_init(AtkObject* atk_object, gpointer data) { | |
| 106 if (ATK_OBJECT_CLASS(browser_accessibility_parent_class)->initialize) { | |
| 107 ATK_OBJECT_CLASS(browser_accessibility_parent_class)->initialize( | |
| 108 atk_object, data); | |
| 109 } | |
| 110 | |
| 111 BROWSER_ACCESSIBILITY(atk_object)->m_object = | |
| 112 reinterpret_cast<BrowserAccessibilityGtk*>(data); | |
| 113 } | |
| 114 | |
| 115 static void browser_accessibility_finalize(GObject* atk_object) { | |
| 116 G_OBJECT_CLASS(browser_accessibility_parent_class)->finalize(atk_object); | |
| 117 } | |
| 118 | |
| 119 static void browser_accessibility_class_init(AtkObjectClass* klass) { | |
| 120 GObjectClass* gobject_class = G_OBJECT_CLASS(klass); | |
| 121 browser_accessibility_parent_class = g_type_class_peek_parent(klass); | |
| 122 | |
| 123 gobject_class->finalize = browser_accessibility_finalize; | |
| 124 klass->initialize = browser_accessibility_init; | |
| 125 klass->get_name = browser_accessibility_get_name; | |
| 126 klass->get_description = browser_accessibility_get_description; | |
| 127 klass->get_parent = browser_accessibility_get_parent; | |
| 128 klass->get_n_children = browser_accessibility_get_n_children; | |
| 129 klass->ref_child = browser_accessibility_ref_child; | |
| 130 klass->get_role = browser_accessibility_get_role; | |
| 131 klass->ref_state_set = browser_accessibility_ref_state_set; | |
| 132 klass->get_index_in_parent = browser_accessibility_get_index_in_parent; | |
| 133 klass->get_attributes = browser_accessibility_get_attributes; | |
| 134 klass->ref_relation_set = browser_accessibility_ref_relation_set; | |
| 135 } | |
| 136 | |
| 137 GType browser_accessibility_get_type() { | |
| 138 static volatile gsize type_volatile = 0; | |
| 139 | |
| 140 if (g_once_init_enter(&type_volatile)) { | |
| 141 static const GTypeInfo tinfo = { | |
| 142 sizeof(BrowserAccessibilityAtkClass), | |
| 143 (GBaseInitFunc) 0, | |
| 144 (GBaseFinalizeFunc) 0, | |
| 145 (GClassInitFunc) browser_accessibility_class_init, | |
| 146 (GClassFinalizeFunc) 0, | |
| 147 0, /* class data */ | |
| 148 sizeof(BrowserAccessibilityAtk), /* instance size */ | |
| 149 0, /* nb preallocs */ | |
| 150 (GInstanceInitFunc) 0, | |
| 151 0 /* value table */ | |
| 152 }; | |
| 153 | |
| 154 GType type = g_type_register_static( | |
| 155 ATK_TYPE_OBJECT, "BrowserAccessibility", &tinfo, GTypeFlags(0)); | |
| 156 g_once_init_leave(&type_volatile, type); | |
| 157 } | |
| 158 | |
| 159 return type_volatile; | |
| 160 } | |
| 161 | |
| 162 static guint16 GetInterfaceMaskFromObject(BrowserAccessibilityGtk* obj) { | |
| 163 return 0; | |
| 164 } | |
| 165 | |
| 166 static const char* GetUniqueAccessibilityTypeName(guint16 interface_mask) | |
| 167 { | |
| 168 #define WAI_TYPE_NAME_LEN (30) /* Enough for prefix + 5 hex chars (max) */ | |
|
Evan Stade
2012/05/02 00:03:30
you can ask someone else if you like, but I don't
dmazzoni
2012/05/02 06:27:33
Done. Moved to top and made a static const int.
| |
| 169 static char name[WAI_TYPE_NAME_LEN + 1]; | |
| 170 | |
| 171 sprintf(name, "WAIType%x", interface_mask); | |
| 172 name[WAI_TYPE_NAME_LEN] = '\0'; | |
| 173 | |
| 174 return name; | |
| 175 } | |
| 176 | |
| 177 static const GInterfaceInfo AtkInterfacesInitFunctions[] = { | |
| 178 }; | |
| 179 | |
| 180 enum WAIType { | |
| 181 WAI_ACTION, | |
| 182 WAI_SELECTION, | |
| 183 WAI_EDITABLE_TEXT, | |
| 184 WAI_TEXT, | |
| 185 WAI_COMPONENT, | |
| 186 WAI_IMAGE, | |
| 187 WAI_TABLE, | |
| 188 WAI_HYPERTEXT, | |
| 189 WAI_HYPERLINK, | |
| 190 WAI_DOCUMENT, | |
| 191 WAI_VALUE, | |
| 192 }; | |
| 193 | |
| 194 static GType GetAtkInterfaceTypeFromWAIType(WAIType type) { | |
| 195 switch (type) { | |
| 196 case WAI_ACTION: | |
| 197 return ATK_TYPE_ACTION; | |
| 198 case WAI_SELECTION: | |
| 199 return ATK_TYPE_SELECTION; | |
| 200 case WAI_EDITABLE_TEXT: | |
| 201 return ATK_TYPE_EDITABLE_TEXT; | |
| 202 case WAI_TEXT: | |
| 203 return ATK_TYPE_TEXT; | |
| 204 case WAI_COMPONENT: | |
| 205 return ATK_TYPE_COMPONENT; | |
| 206 case WAI_IMAGE: | |
| 207 return ATK_TYPE_IMAGE; | |
| 208 case WAI_TABLE: | |
| 209 return ATK_TYPE_TABLE; | |
| 210 case WAI_HYPERTEXT: | |
| 211 return ATK_TYPE_HYPERTEXT; | |
| 212 case WAI_HYPERLINK: | |
| 213 return ATK_TYPE_HYPERLINK_IMPL; | |
| 214 case WAI_DOCUMENT: | |
| 215 return ATK_TYPE_DOCUMENT; | |
| 216 case WAI_VALUE: | |
| 217 return ATK_TYPE_VALUE; | |
| 218 } | |
| 219 | |
| 220 return G_TYPE_INVALID; | |
| 221 } | |
| 222 | |
| 223 static GType GetAccessibilityTypeFromObject(BrowserAccessibilityGtk* obj) { | |
| 224 static const GTypeInfo type_info = { | |
| 225 sizeof(BrowserAccessibilityAtkClass), | |
| 226 (GBaseInitFunc) 0, | |
| 227 (GBaseFinalizeFunc) 0, | |
| 228 (GClassInitFunc) 0, | |
| 229 (GClassFinalizeFunc) 0, | |
| 230 0, /* class data */ | |
| 231 sizeof(BrowserAccessibilityAtk), /* instance size */ | |
| 232 0, /* nb preallocs */ | |
| 233 (GInstanceInitFunc) 0, | |
| 234 0 /* value table */ | |
| 235 }; | |
| 236 | |
| 237 guint16 interface_mask = GetInterfaceMaskFromObject(obj); | |
| 238 const char* atk_type_name = GetUniqueAccessibilityTypeName(interface_mask); | |
| 239 GType type = g_type_from_name(atk_type_name); | |
| 240 if (type) | |
| 241 return type; | |
| 242 | |
| 243 type = g_type_register_static(BROWSER_ACCESSIBILITY_TYPE, | |
| 244 atk_type_name, | |
| 245 &type_info, | |
| 246 GTypeFlags(0)); | |
| 247 for (guint i = 0; i < G_N_ELEMENTS(AtkInterfacesInitFunctions); i++) { | |
| 248 if (interface_mask & (1 << i)) { | |
| 249 g_type_add_interface_static( | |
| 250 type, | |
| 251 GetAtkInterfaceTypeFromWAIType(static_cast<WAIType>(i)), | |
| 252 &AtkInterfacesInitFunctions[i]); | |
| 253 } | |
| 254 } | |
| 255 | |
| 256 return type; | |
| 257 } | |
| 258 | |
| 259 BrowserAccessibilityAtk* browser_accessibility_new( | |
| 260 BrowserAccessibilityGtk* obj) { | |
| 261 GType type = GetAccessibilityTypeFromObject(obj); | |
| 262 AtkObject* atk_object = static_cast<AtkObject*>(g_object_new(type, 0)); | |
| 263 | |
| 264 atk_object_initialize(atk_object, obj); | |
| 265 | |
| 266 return BROWSER_ACCESSIBILITY(atk_object); | |
| 267 } | |
| 268 | |
| 269 void browser_accessibility_detach(BrowserAccessibilityAtk* atk_object) { | |
| 270 } | |
| 271 | |
| 272 // static | |
| 273 BrowserAccessibility* BrowserAccessibility::Create() { | |
| 274 return new BrowserAccessibilityGtk(); | |
| 275 } | |
| 276 | |
| 277 BrowserAccessibilityGtk* BrowserAccessibility::toBrowserAccessibilityGtk() { | |
| 278 return static_cast<BrowserAccessibilityGtk*>(this); | |
| 279 } | |
| 280 | |
| 281 BrowserAccessibilityGtk::BrowserAccessibilityGtk() { | |
| 282 atk_object_ = ATK_OBJECT(browser_accessibility_new(this)); | |
| 283 } | |
| 284 | |
| 285 BrowserAccessibilityGtk::~BrowserAccessibilityGtk() { | |
| 286 browser_accessibility_detach(BROWSER_ACCESSIBILITY(atk_object_)); | |
| 287 } | |
| 288 | |
| 289 AtkObject* BrowserAccessibilityGtk::GetAtkObject() const { | |
| 290 if (!G_IS_OBJECT(atk_object_)) | |
| 291 return NULL; | |
| 292 return atk_object_; | |
| 293 } | |
| 294 | |
| 295 void BrowserAccessibilityGtk::PreInitialize() { | |
| 296 BrowserAccessibility::PreInitialize(); | |
| 297 InitRoleAndState(); | |
| 298 | |
| 299 if (this->parent()) { | |
| 300 atk_object_set_parent( | |
| 301 atk_object_, | |
| 302 this->parent()->toBrowserAccessibilityGtk()->GetAtkObject()); | |
| 303 } | |
| 304 } | |
| 305 | |
| 306 void BrowserAccessibilityGtk::InitRoleAndState() { | |
| 307 atk_acc_name_ = UTF16ToUTF8(name()).c_str(); | |
| 308 | |
| 309 switch(role_) { | |
| 310 case WebAccessibility::ROLE_BUTTON: | |
| 311 atk_role_ = ATK_ROLE_PUSH_BUTTON; | |
| 312 break; | |
| 313 case WebAccessibility::ROLE_CHECKBOX: | |
| 314 atk_role_ = ATK_ROLE_CHECK_BOX; | |
| 315 break; | |
| 316 case WebAccessibility::ROLE_COMBO_BOX: | |
| 317 atk_role_ = ATK_ROLE_COMBO_BOX; | |
| 318 break; | |
| 319 case WebAccessibility::ROLE_LINK: | |
| 320 atk_role_ = ATK_ROLE_LINK; | |
| 321 break; | |
| 322 case WebAccessibility::ROLE_RADIO_BUTTON: | |
| 323 atk_role_ = ATK_ROLE_RADIO_BUTTON; | |
| 324 break; | |
| 325 case WebAccessibility::ROLE_TEXTAREA: | |
| 326 atk_role_ = ATK_ROLE_ENTRY; | |
| 327 break; | |
| 328 case WebAccessibility::ROLE_TEXT_FIELD: | |
| 329 atk_role_ = ATK_ROLE_ENTRY; | |
| 330 break; | |
| 331 case WebAccessibility::ROLE_WEBCORE_LINK: | |
| 332 atk_role_ = ATK_ROLE_LINK; | |
| 333 break; | |
| 334 default: | |
| 335 atk_role_ = ATK_ROLE_UNKNOWN; | |
| 336 break; | |
| 337 } | |
| 338 } | |
| OLD | NEW |