| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 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 <atlbase.h> | 5 #include <atlbase.h> |
| 6 #include <atlcom.h> | 6 #include <atlcom.h> |
| 7 #include <limits.h> | 7 #include <limits.h> |
| 8 #include <oleacc.h> | 8 #include <oleacc.h> |
| 9 #include <stdint.h> | 9 #include <stdint.h> |
| 10 | 10 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 // a COM interface. Because COM objects are reference counted and clients | 26 // a COM interface. Because COM objects are reference counted and clients |
| 27 // are completely untrusted, it's important to always first check that our | 27 // are completely untrusted, it's important to always first check that our |
| 28 // object is still valid, and then check that all pointer arguments are | 28 // object is still valid, and then check that all pointer arguments are |
| 29 // not NULL. | 29 // not NULL. |
| 30 // | 30 // |
| 31 | 31 |
| 32 #define COM_OBJECT_VALIDATE() \ | 32 #define COM_OBJECT_VALIDATE() \ |
| 33 if (!delegate_) \ | 33 if (!delegate_) \ |
| 34 return E_FAIL; | 34 return E_FAIL; |
| 35 #define COM_OBJECT_VALIDATE_1_ARG(arg) \ | 35 #define COM_OBJECT_VALIDATE_1_ARG(arg) \ |
| 36 if (!delegate_) return E_FAIL; \ | 36 if (!delegate_) \ |
| 37 if (!arg) return E_INVALIDARG | 37 return E_FAIL; \ |
| 38 if (!arg) \ |
| 39 return E_INVALIDARG; |
| 38 #define COM_OBJECT_VALIDATE_2_ARGS(arg1, arg2) \ | 40 #define COM_OBJECT_VALIDATE_2_ARGS(arg1, arg2) \ |
| 39 if (!delegate_) return E_FAIL; \ | 41 if (!delegate_) \ |
| 40 if (!arg1) return E_INVALIDARG; \ | 42 return E_FAIL; \ |
| 41 if (!arg2) return E_INVALIDARG | 43 if (!arg1) \ |
| 44 return E_INVALIDARG; \ |
| 45 if (!arg2) \ |
| 46 return E_INVALIDARG; |
| 42 #define COM_OBJECT_VALIDATE_3_ARGS(arg1, arg2, arg3) \ | 47 #define COM_OBJECT_VALIDATE_3_ARGS(arg1, arg2, arg3) \ |
| 43 if (!delegate_) return E_FAIL; \ | 48 if (!delegate_) \ |
| 44 if (!arg1) return E_INVALIDARG; \ | 49 return E_FAIL; \ |
| 45 if (!arg2) return E_INVALIDARG; \ | 50 if (!arg1) \ |
| 46 if (!arg3) return E_INVALIDARG | 51 return E_INVALIDARG; \ |
| 52 if (!arg2) \ |
| 53 return E_INVALIDARG; \ |
| 54 if (!arg3) \ |
| 55 return E_INVALIDARG; |
| 47 #define COM_OBJECT_VALIDATE_4_ARGS(arg1, arg2, arg3, arg4) \ | 56 #define COM_OBJECT_VALIDATE_4_ARGS(arg1, arg2, arg3, arg4) \ |
| 48 if (!delegate_) return E_FAIL; \ | 57 if (!delegate_) \ |
| 49 if (!arg1) return E_INVALIDARG; \ | 58 return E_FAIL; \ |
| 50 if (!arg2) return E_INVALIDARG; \ | 59 if (!arg1) \ |
| 51 if (!arg3) return E_INVALIDARG; \ | 60 return E_INVALIDARG; \ |
| 52 if (!arg4) return E_INVALIDARG | 61 if (!arg2) \ |
| 53 #define COM_OBJECT_VALIDATE_VAR_ID(var_id) \ | 62 return E_INVALIDARG; \ |
| 54 if (!delegate_) return E_FAIL; \ | 63 if (!arg3) \ |
| 55 if (!IsValidId(var_id)) return E_INVALIDARG | 64 return E_INVALIDARG; \ |
| 56 #define COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, arg) \ | 65 if (!arg4) \ |
| 57 if (!delegate_) return E_FAIL; \ | 66 return E_INVALIDARG; |
| 58 if (!IsValidId(var_id)) return E_INVALIDARG; \ | 67 #define COM_OBJECT_VALIDATE_VAR_ID_AND_GET_TARGET(var_id, target) \ |
| 59 if (!arg) return E_INVALIDARG | 68 if (!delegate_) \ |
| 60 #define COM_OBJECT_VALIDATE_VAR_ID_2_ARGS(var_id, arg1, arg2) \ | 69 return E_FAIL; \ |
| 61 if (!delegate_) return E_FAIL; \ | 70 target = GetTargetFromChildID(var_id); \ |
| 62 if (!IsValidId(var_id)) return E_INVALIDARG; \ | 71 if (!target) \ |
| 63 if (!arg1) return E_INVALIDARG; \ | 72 return E_INVALIDARG; \ |
| 64 if (!arg2) return E_INVALIDARG | 73 if (!target->delegate_) \ |
| 65 #define COM_OBJECT_VALIDATE_VAR_ID_3_ARGS(var_id, arg1, arg2, arg3) \ | 74 return E_INVALIDARG; |
| 66 if (!delegate_) return E_FAIL; \ | 75 #define COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, arg, target) \ |
| 67 if (!IsValidId(var_id)) return E_INVALIDARG; \ | 76 if (!delegate_) \ |
| 68 if (!arg1) return E_INVALIDARG; \ | 77 return E_FAIL; \ |
| 69 if (!arg2) return E_INVALIDARG; \ | 78 if (!arg) \ |
| 70 if (!arg3) return E_INVALIDARG | 79 return E_INVALIDARG; \ |
| 71 #define COM_OBJECT_VALIDATE_VAR_ID_4_ARGS(var_id, arg1, arg2, arg3, arg4) \ | 80 target = GetTargetFromChildID(var_id); \ |
| 72 if (!delegate_) return E_FAIL; \ | 81 if (!target) \ |
| 73 if (!IsValidId(var_id)) return E_INVALIDARG; \ | 82 return E_INVALIDARG; \ |
| 74 if (!arg1) return E_INVALIDARG; \ | 83 if (!target->delegate_) \ |
| 75 if (!arg2) return E_INVALIDARG; \ | 84 return E_INVALIDARG; |
| 76 if (!arg3) return E_INVALIDARG; \ | 85 #define COM_OBJECT_VALIDATE_VAR_ID_2_ARGS_AND_GET_TARGET(var_id, arg1, arg2, \ |
| 77 if (!arg4) return E_INVALIDARG | 86 target) \ |
| 87 if (!delegate_) \ |
| 88 return E_FAIL; \ |
| 89 if (!arg1) \ |
| 90 return E_INVALIDARG; \ |
| 91 if (!arg2) \ |
| 92 return E_INVALIDARG; \ |
| 93 target = GetTargetFromChildID(var_id); \ |
| 94 if (!target) \ |
| 95 return E_INVALIDARG; \ |
| 96 if (!target->delegate_) \ |
| 97 return E_INVALIDARG; |
| 98 #define COM_OBJECT_VALIDATE_VAR_ID_3_ARGS_AND_GET_TARGET(var_id, arg1, arg2, \ |
| 99 arg3, target) \ |
| 100 if (!delegate_) \ |
| 101 return E_FAIL; \ |
| 102 if (!arg1) \ |
| 103 return E_INVALIDARG; \ |
| 104 if (!arg2) \ |
| 105 return E_INVALIDARG; \ |
| 106 if (!arg3) \ |
| 107 return E_INVALIDARG; \ |
| 108 target = GetTargetFromChildID(var_id); \ |
| 109 if (!target) \ |
| 110 return E_INVALIDARG; \ |
| 111 if (!target->delegate_) \ |
| 112 return E_INVALIDARG; |
| 113 #define COM_OBJECT_VALIDATE_VAR_ID_4_ARGS_AND_GET_TARGET(var_id, arg1, arg2, \ |
| 114 arg3, arg4, target) \ |
| 115 if (!delegate_) \ |
| 116 return E_FAIL; \ |
| 117 if (!arg1) \ |
| 118 return E_INVALIDARG; \ |
| 119 if (!arg2) \ |
| 120 return E_INVALIDARG; \ |
| 121 if (!arg3) \ |
| 122 return E_INVALIDARG; \ |
| 123 if (!arg4) \ |
| 124 return E_INVALIDARG; \ |
| 125 target = GetTargetFromChildID(var_id); \ |
| 126 if (!target) \ |
| 127 return E_INVALIDARG; \ |
| 128 if (!target->delegate_) \ |
| 129 return E_INVALIDARG; |
| 78 | 130 |
| 79 namespace ui { | 131 namespace ui { |
| 80 | 132 |
| 81 namespace { | 133 namespace { |
| 82 | 134 |
| 83 typedef base::hash_set<AXPlatformNodeWin*> AXPlatformNodeWinSet; | 135 typedef base::hash_set<AXPlatformNodeWin*> AXPlatformNodeWinSet; |
| 84 // Set of all AXPlatformNodeWin objects that were the target of an | 136 // Set of all AXPlatformNodeWin objects that were the target of an |
| 85 // alert event. | 137 // alert event. |
| 86 base::LazyInstance<AXPlatformNodeWinSet>::DestructorAtExit g_alert_targets = | 138 base::LazyInstance<AXPlatformNodeWinSet>::DestructorAtExit g_alert_targets = |
| 87 LAZY_INSTANCE_INITIALIZER; | 139 LAZY_INSTANCE_INITIALIZER; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 HRESULT hr = CComObject<AXPlatformNodeWin>::CreateInstance(&instance); | 173 HRESULT hr = CComObject<AXPlatformNodeWin>::CreateInstance(&instance); |
| 122 DCHECK(SUCCEEDED(hr)); | 174 DCHECK(SUCCEEDED(hr)); |
| 123 instance->Init(delegate); | 175 instance->Init(delegate); |
| 124 instance->AddRef(); | 176 instance->AddRef(); |
| 125 return instance; | 177 return instance; |
| 126 } | 178 } |
| 127 | 179 |
| 128 // static | 180 // static |
| 129 AXPlatformNode* AXPlatformNode::FromNativeViewAccessible( | 181 AXPlatformNode* AXPlatformNode::FromNativeViewAccessible( |
| 130 gfx::NativeViewAccessible accessible) { | 182 gfx::NativeViewAccessible accessible) { |
| 183 if (!accessible) |
| 184 return nullptr; |
| 131 base::win::ScopedComPtr<AXPlatformNodeWin> ax_platform_node; | 185 base::win::ScopedComPtr<AXPlatformNodeWin> ax_platform_node; |
| 132 accessible->QueryInterface(ax_platform_node.Receive()); | 186 accessible->QueryInterface(ax_platform_node.Receive()); |
| 133 return ax_platform_node.get(); | 187 return ax_platform_node.get(); |
| 134 } | 188 } |
| 135 | 189 |
| 136 // | 190 // |
| 137 // AXPlatformNodeWin | 191 // AXPlatformNodeWin |
| 138 // | 192 // |
| 139 | 193 |
| 140 AXPlatformNodeWin::AXPlatformNodeWin() { | 194 AXPlatformNodeWin::AXPlatformNodeWin() { |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 if (S_OK == result && child->vt == VT_I4 && child->lVal == CHILDID_SELF) { | 299 if (S_OK == result && child->vt == VT_I4 && child->lVal == CHILDID_SELF) { |
| 246 child->vt = VT_DISPATCH; | 300 child->vt = VT_DISPATCH; |
| 247 child->pdispVal = hit_child; | 301 child->pdispVal = hit_child; |
| 248 // Always increment ref when returning a reference to a COM object. | 302 // Always increment ref when returning a reference to a COM object. |
| 249 child->pdispVal->AddRef(); | 303 child->pdispVal->AddRef(); |
| 250 } | 304 } |
| 251 return result; | 305 return result; |
| 252 } | 306 } |
| 253 | 307 |
| 254 HRESULT AXPlatformNodeWin::accDoDefaultAction(VARIANT var_id) { | 308 HRESULT AXPlatformNodeWin::accDoDefaultAction(VARIANT var_id) { |
| 255 COM_OBJECT_VALIDATE_VAR_ID(var_id); | 309 AXPlatformNodeWin* target; |
| 310 COM_OBJECT_VALIDATE_VAR_ID_AND_GET_TARGET(var_id, target); |
| 256 AXActionData data; | 311 AXActionData data; |
| 257 data.action = ui::AX_ACTION_DO_DEFAULT; | 312 data.action = ui::AX_ACTION_DO_DEFAULT; |
| 258 if (delegate_->AccessibilityPerformAction(data)) | 313 |
| 314 if (target->delegate_->AccessibilityPerformAction(data)) |
| 259 return S_OK; | 315 return S_OK; |
| 260 return E_FAIL; | 316 return E_FAIL; |
| 261 } | 317 } |
| 262 | 318 |
| 263 STDMETHODIMP AXPlatformNodeWin::accLocation( | 319 STDMETHODIMP AXPlatformNodeWin::accLocation( |
| 264 LONG* x_left, LONG* y_top, LONG* width, LONG* height, VARIANT var_id) { | 320 LONG* x_left, LONG* y_top, LONG* width, LONG* height, VARIANT var_id) { |
| 265 COM_OBJECT_VALIDATE_VAR_ID_4_ARGS(var_id, x_left, y_top, width, height); | 321 AXPlatformNodeWin* target; |
| 266 gfx::Rect bounds = delegate_->GetScreenBoundsRect(); | 322 COM_OBJECT_VALIDATE_VAR_ID_4_ARGS_AND_GET_TARGET(var_id, x_left, y_top, width, |
| 323 height, target); |
| 324 |
| 325 gfx::Rect bounds = target->delegate_->GetScreenBoundsRect(); |
| 267 *x_left = bounds.x(); | 326 *x_left = bounds.x(); |
| 268 *y_top = bounds.y(); | 327 *y_top = bounds.y(); |
| 269 *width = bounds.width(); | 328 *width = bounds.width(); |
| 270 *height = bounds.height(); | 329 *height = bounds.height(); |
| 271 | 330 |
| 272 if (bounds.IsEmpty()) | 331 if (bounds.IsEmpty()) |
| 273 return S_FALSE; | 332 return S_FALSE; |
| 274 | 333 |
| 275 return S_OK; | 334 return S_OK; |
| 276 } | 335 } |
| 277 | 336 |
| 278 STDMETHODIMP AXPlatformNodeWin::accNavigate( | 337 STDMETHODIMP AXPlatformNodeWin::accNavigate( |
| 279 LONG nav_dir, VARIANT start, VARIANT* end) { | 338 LONG nav_dir, VARIANT start, VARIANT* end) { |
| 280 COM_OBJECT_VALIDATE_VAR_ID_1_ARG(start, end); | 339 AXPlatformNodeWin* target; |
| 340 COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(start, end, target); |
| 281 IAccessible* result = nullptr; | 341 IAccessible* result = nullptr; |
| 282 | 342 |
| 283 if ((nav_dir == NAVDIR_LASTCHILD || nav_dir == NAVDIR_FIRSTCHILD) && | 343 if ((nav_dir == NAVDIR_LASTCHILD || nav_dir == NAVDIR_FIRSTCHILD) && |
| 284 start.lVal != CHILDID_SELF) { | 344 start.lVal != CHILDID_SELF) { |
| 285 // MSAA states that navigating to first/last child can only be from self. | 345 // MSAA states that navigating to first/last child can only be from self. |
| 286 return E_INVALIDARG; | 346 return E_INVALIDARG; |
| 287 } | 347 } |
| 288 | 348 |
| 289 switch (nav_dir) { | 349 switch (nav_dir) { |
| 290 case NAVDIR_DOWN: | 350 case NAVDIR_DOWN: |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 330 end->vt = VT_DISPATCH; | 390 end->vt = VT_DISPATCH; |
| 331 end->pdispVal = result; | 391 end->pdispVal = result; |
| 332 // Always increment ref when returning a reference to a COM object. | 392 // Always increment ref when returning a reference to a COM object. |
| 333 end->pdispVal->AddRef(); | 393 end->pdispVal->AddRef(); |
| 334 | 394 |
| 335 return S_OK; | 395 return S_OK; |
| 336 } | 396 } |
| 337 | 397 |
| 338 STDMETHODIMP AXPlatformNodeWin::get_accChild(VARIANT var_child, | 398 STDMETHODIMP AXPlatformNodeWin::get_accChild(VARIANT var_child, |
| 339 IDispatch** disp_child) { | 399 IDispatch** disp_child) { |
| 340 COM_OBJECT_VALIDATE_1_ARG(disp_child); | 400 *disp_child = nullptr; |
| 341 LONG child_id = V_I4(&var_child); | 401 AXPlatformNodeWin* target; |
| 342 if (child_id == CHILDID_SELF) { | 402 COM_OBJECT_VALIDATE_VAR_ID_AND_GET_TARGET(var_child, target); |
| 343 *disp_child = this; | |
| 344 (*disp_child)->AddRef(); | |
| 345 return S_OK; | |
| 346 } | |
| 347 | 403 |
| 348 if (child_id >= 1 && child_id <= delegate_->GetChildCount()) { | 404 *disp_child = target; |
| 349 // Positive child ids are a 1-based child index, used by clients | 405 (*disp_child)->AddRef(); |
| 350 // that want to enumerate all immediate children. | 406 return S_OK; |
| 351 *disp_child = delegate_->ChildAtIndex(child_id - 1); | |
| 352 if (!(*disp_child)) | |
| 353 return E_INVALIDARG; | |
| 354 (*disp_child)->AddRef(); | |
| 355 return S_OK; | |
| 356 } | |
| 357 | |
| 358 if (child_id >= 0) | |
| 359 return E_INVALIDARG; | |
| 360 | |
| 361 // Negative child ids can be used to map to any descendant. | |
| 362 AXPlatformNodeWin* child = static_cast<AXPlatformNodeWin*>( | |
| 363 GetFromUniqueId(-child_id)); | |
| 364 if (child && !IsDescendant(child)) | |
| 365 child = nullptr; | |
| 366 | |
| 367 if (child) { | |
| 368 *disp_child = child; | |
| 369 (*disp_child)->AddRef(); | |
| 370 return S_OK; | |
| 371 } | |
| 372 | |
| 373 *disp_child = nullptr; | |
| 374 return E_INVALIDARG; | |
| 375 } | 407 } |
| 376 | 408 |
| 377 STDMETHODIMP AXPlatformNodeWin::get_accChildCount(LONG* child_count) { | 409 STDMETHODIMP AXPlatformNodeWin::get_accChildCount(LONG* child_count) { |
| 378 COM_OBJECT_VALIDATE_1_ARG(child_count); | 410 COM_OBJECT_VALIDATE_1_ARG(child_count); |
| 379 *child_count = delegate_->GetChildCount(); | 411 *child_count = delegate_->GetChildCount(); |
| 380 return S_OK; | 412 return S_OK; |
| 381 } | 413 } |
| 382 | 414 |
| 383 STDMETHODIMP AXPlatformNodeWin::get_accDefaultAction( | 415 STDMETHODIMP AXPlatformNodeWin::get_accDefaultAction( |
| 384 VARIANT var_id, BSTR* def_action) { | 416 VARIANT var_id, BSTR* def_action) { |
| 385 COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, def_action); | 417 AXPlatformNodeWin* target; |
| 418 COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, def_action, target); |
| 419 |
| 386 int action; | 420 int action; |
| 387 if (!GetIntAttribute(AX_ATTR_ACTION, &action)) { | 421 if (!target->GetIntAttribute(AX_ATTR_ACTION, &action)) { |
| 388 *def_action = nullptr; | 422 *def_action = nullptr; |
| 389 return S_FALSE; | 423 return S_FALSE; |
| 390 } | 424 } |
| 391 | 425 |
| 392 base::string16 action_verb = | 426 base::string16 action_verb = |
| 393 ActionToString(static_cast<AXSupportedAction>(action)); | 427 ActionToString(static_cast<AXSupportedAction>(action)); |
| 394 if (action_verb.empty()) { | 428 if (action_verb.empty()) { |
| 395 *def_action = nullptr; | 429 *def_action = nullptr; |
| 396 return S_FALSE; | 430 return S_FALSE; |
| 397 } | 431 } |
| 398 | 432 |
| 399 *def_action = SysAllocString(action_verb.c_str()); | 433 *def_action = SysAllocString(action_verb.c_str()); |
| 400 DCHECK(def_action); | 434 DCHECK(def_action); |
| 401 return S_OK; | 435 return S_OK; |
| 402 } | 436 } |
| 403 | 437 |
| 404 STDMETHODIMP AXPlatformNodeWin::get_accDescription( | 438 STDMETHODIMP AXPlatformNodeWin::get_accDescription( |
| 405 VARIANT var_id, BSTR* desc) { | 439 VARIANT var_id, BSTR* desc) { |
| 406 COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, desc); | 440 AXPlatformNodeWin* target; |
| 407 return GetStringAttributeAsBstr(ui::AX_ATTR_DESCRIPTION, desc); | 441 COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, desc, target); |
| 442 |
| 443 return target->GetStringAttributeAsBstr(ui::AX_ATTR_DESCRIPTION, desc); |
| 408 } | 444 } |
| 409 | 445 |
| 410 STDMETHODIMP AXPlatformNodeWin::get_accFocus(VARIANT* focus_child) { | 446 STDMETHODIMP AXPlatformNodeWin::get_accFocus(VARIANT* focus_child) { |
| 411 COM_OBJECT_VALIDATE_1_ARG(focus_child); | 447 COM_OBJECT_VALIDATE_1_ARG(focus_child); |
| 412 gfx::NativeViewAccessible focus_accessible = delegate_->GetFocus(); | 448 gfx::NativeViewAccessible focus_accessible = delegate_->GetFocus(); |
| 413 if (focus_accessible == this) { | 449 if (focus_accessible == this) { |
| 414 focus_child->vt = VT_I4; | 450 focus_child->vt = VT_I4; |
| 415 focus_child->lVal = CHILDID_SELF; | 451 focus_child->lVal = CHILDID_SELF; |
| 416 } else if (focus_accessible) { | 452 } else if (focus_accessible) { |
| 417 focus_child->vt = VT_DISPATCH; | 453 focus_child->vt = VT_DISPATCH; |
| 418 focus_child->pdispVal = focus_accessible; | 454 focus_child->pdispVal = focus_accessible; |
| 419 focus_child->pdispVal->AddRef(); | 455 focus_child->pdispVal->AddRef(); |
| 420 return S_OK; | 456 return S_OK; |
| 421 } else { | 457 } else { |
| 422 focus_child->vt = VT_EMPTY; | 458 focus_child->vt = VT_EMPTY; |
| 423 } | 459 } |
| 424 | 460 |
| 425 return S_OK; | 461 return S_OK; |
| 426 } | 462 } |
| 427 | 463 |
| 428 STDMETHODIMP AXPlatformNodeWin::get_accKeyboardShortcut( | 464 STDMETHODIMP AXPlatformNodeWin::get_accKeyboardShortcut( |
| 429 VARIANT var_id, BSTR* acc_key) { | 465 VARIANT var_id, BSTR* acc_key) { |
| 430 COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, acc_key); | 466 AXPlatformNodeWin* target; |
| 431 return GetStringAttributeAsBstr(ui::AX_ATTR_SHORTCUT, acc_key); | 467 COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, acc_key, target); |
| 468 |
| 469 return target->GetStringAttributeAsBstr(ui::AX_ATTR_SHORTCUT, acc_key); |
| 432 } | 470 } |
| 433 | 471 |
| 434 STDMETHODIMP AXPlatformNodeWin::get_accName( | 472 STDMETHODIMP AXPlatformNodeWin::get_accName( |
| 435 VARIANT var_id, BSTR* name) { | 473 VARIANT var_id, BSTR* name) { |
| 436 COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, name); | 474 AXPlatformNodeWin* target; |
| 437 return GetStringAttributeAsBstr(ui::AX_ATTR_NAME, name); | 475 COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, name, target); |
| 476 |
| 477 return target->GetStringAttributeAsBstr(ui::AX_ATTR_NAME, name); |
| 438 } | 478 } |
| 439 | 479 |
| 440 STDMETHODIMP AXPlatformNodeWin::get_accParent( | 480 STDMETHODIMP AXPlatformNodeWin::get_accParent( |
| 441 IDispatch** disp_parent) { | 481 IDispatch** disp_parent) { |
| 442 COM_OBJECT_VALIDATE_1_ARG(disp_parent); | 482 COM_OBJECT_VALIDATE_1_ARG(disp_parent); |
| 443 *disp_parent = GetParent(); | 483 *disp_parent = GetParent(); |
| 444 if (*disp_parent) { | 484 if (*disp_parent) { |
| 445 (*disp_parent)->AddRef(); | 485 (*disp_parent)->AddRef(); |
| 446 return S_OK; | 486 return S_OK; |
| 447 } | 487 } |
| 448 | 488 |
| 449 return S_FALSE; | 489 return S_FALSE; |
| 450 } | 490 } |
| 451 | 491 |
| 452 STDMETHODIMP AXPlatformNodeWin::get_accRole( | 492 STDMETHODIMP AXPlatformNodeWin::get_accRole( |
| 453 VARIANT var_id, VARIANT* role) { | 493 VARIANT var_id, VARIANT* role) { |
| 454 COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, role); | 494 AXPlatformNodeWin* target; |
| 495 COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, role, target); |
| 455 role->vt = VT_I4; | 496 role->vt = VT_I4; |
| 456 role->lVal = MSAARole(); | 497 role->lVal = target->MSAARole(); |
| 457 return S_OK; | 498 return S_OK; |
| 458 } | 499 } |
| 459 | 500 |
| 460 STDMETHODIMP AXPlatformNodeWin::get_accState( | 501 STDMETHODIMP AXPlatformNodeWin::get_accState( |
| 461 VARIANT var_id, VARIANT* state) { | 502 VARIANT var_id, VARIANT* state) { |
| 462 COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, state); | 503 AXPlatformNodeWin* target; |
| 504 COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, state, target); |
| 463 state->vt = VT_I4; | 505 state->vt = VT_I4; |
| 464 state->lVal = MSAAState(); | 506 state->lVal = target->MSAAState(); |
| 465 return S_OK; | 507 return S_OK; |
| 466 } | 508 } |
| 467 | 509 |
| 468 STDMETHODIMP AXPlatformNodeWin::get_accHelp( | 510 STDMETHODIMP AXPlatformNodeWin::get_accHelp( |
| 469 VARIANT var_id, BSTR* help) { | 511 VARIANT var_id, BSTR* help) { |
| 470 COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, help); | |
| 471 return S_FALSE; | 512 return S_FALSE; |
| 472 } | 513 } |
| 473 | 514 |
| 474 STDMETHODIMP AXPlatformNodeWin::get_accValue(VARIANT var_id, BSTR* value) { | 515 STDMETHODIMP AXPlatformNodeWin::get_accValue(VARIANT var_id, BSTR* value) { |
| 475 COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, value); | 516 AXPlatformNodeWin* target; |
| 476 return GetStringAttributeAsBstr(ui::AX_ATTR_VALUE, value); | 517 COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, value, target); |
| 518 return target->GetStringAttributeAsBstr(ui::AX_ATTR_VALUE, value); |
| 477 } | 519 } |
| 478 | 520 |
| 479 STDMETHODIMP AXPlatformNodeWin::put_accValue(VARIANT var_id, | 521 STDMETHODIMP AXPlatformNodeWin::put_accValue(VARIANT var_id, |
| 480 BSTR new_value) { | 522 BSTR new_value) { |
| 523 AXPlatformNodeWin* target; |
| 524 COM_OBJECT_VALIDATE_VAR_ID_AND_GET_TARGET(var_id, target); |
| 525 |
| 481 AXActionData data; | 526 AXActionData data; |
| 482 data.action = ui::AX_ACTION_SET_VALUE; | 527 data.action = ui::AX_ACTION_SET_VALUE; |
| 483 data.value = new_value; | 528 data.value = new_value; |
| 484 COM_OBJECT_VALIDATE_VAR_ID(var_id); | 529 if (target->delegate_->AccessibilityPerformAction(data)) |
| 485 if (delegate_->AccessibilityPerformAction(data)) | |
| 486 return S_OK; | 530 return S_OK; |
| 487 return E_FAIL; | 531 return E_FAIL; |
| 488 } | 532 } |
| 489 | 533 |
| 490 // IAccessible functions not supported. | 534 // IAccessible functions not supported. |
| 491 | 535 |
| 492 STDMETHODIMP AXPlatformNodeWin::get_accSelection(VARIANT* selected) { | 536 STDMETHODIMP AXPlatformNodeWin::get_accSelection(VARIANT* selected) { |
| 493 COM_OBJECT_VALIDATE_1_ARG(selected); | 537 COM_OBJECT_VALIDATE_1_ARG(selected); |
| 494 if (selected) | 538 if (selected) |
| 495 selected->vt = VT_EMPTY; | 539 selected->vt = VT_EMPTY; |
| 496 return E_NOTIMPL; | 540 return E_NOTIMPL; |
| 497 } | 541 } |
| 498 | 542 |
| 499 STDMETHODIMP AXPlatformNodeWin::accSelect( | 543 STDMETHODIMP AXPlatformNodeWin::accSelect( |
| 500 LONG flagsSelect, VARIANT var_id) { | 544 LONG flagsSelect, VARIANT var_id) { |
| 501 COM_OBJECT_VALIDATE_VAR_ID(var_id); | |
| 502 return E_NOTIMPL; | 545 return E_NOTIMPL; |
| 503 } | 546 } |
| 504 | 547 |
| 505 STDMETHODIMP AXPlatformNodeWin::get_accHelpTopic( | 548 STDMETHODIMP AXPlatformNodeWin::get_accHelpTopic( |
| 506 BSTR* help_file, VARIANT var_id, LONG* topic_id) { | 549 BSTR* help_file, VARIANT var_id, LONG* topic_id) { |
| 507 COM_OBJECT_VALIDATE_VAR_ID_2_ARGS(var_id, help_file, topic_id); | 550 AXPlatformNodeWin* target; |
| 551 COM_OBJECT_VALIDATE_VAR_ID_2_ARGS_AND_GET_TARGET(var_id, help_file, topic_id, |
| 552 target); |
| 508 if (help_file) { | 553 if (help_file) { |
| 509 *help_file = nullptr; | 554 *help_file = nullptr; |
| 510 } | 555 } |
| 511 if (topic_id) { | 556 if (topic_id) { |
| 512 *topic_id = static_cast<LONG>(-1); | 557 *topic_id = static_cast<LONG>(-1); |
| 513 } | 558 } |
| 514 return E_NOTIMPL; | 559 return E_NOTIMPL; |
| 515 } | 560 } |
| 516 | 561 |
| 517 STDMETHODIMP AXPlatformNodeWin::put_accName( | 562 STDMETHODIMP AXPlatformNodeWin::put_accName( |
| 518 VARIANT var_id, BSTR put_name) { | 563 VARIANT var_id, BSTR put_name) { |
| 519 COM_OBJECT_VALIDATE_VAR_ID(var_id); | |
| 520 // Deprecated. | 564 // Deprecated. |
| 521 return E_NOTIMPL; | 565 return E_NOTIMPL; |
| 522 } | 566 } |
| 523 | 567 |
| 524 // | 568 // |
| 525 // IAccessible2 implementation. | 569 // IAccessible2 implementation. |
| 526 // | 570 // |
| 527 | 571 |
| 528 STDMETHODIMP AXPlatformNodeWin::role(LONG* role) { | 572 STDMETHODIMP AXPlatformNodeWin::role(LONG* role) { |
| 529 COM_OBJECT_VALIDATE_1_ARG(role); | 573 COM_OBJECT_VALIDATE_1_ARG(role); |
| (...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 967 return QueryInterface(riid, object); | 1011 return QueryInterface(riid, object); |
| 968 } | 1012 } |
| 969 | 1013 |
| 970 *object = nullptr; | 1014 *object = nullptr; |
| 971 return E_FAIL; | 1015 return E_FAIL; |
| 972 } | 1016 } |
| 973 | 1017 |
| 974 // | 1018 // |
| 975 // Private member functions. | 1019 // Private member functions. |
| 976 // | 1020 // |
| 977 | |
| 978 bool AXPlatformNodeWin::IsValidId(const VARIANT& child) const { | |
| 979 // Since we have a separate IAccessible COM object for each node, we only | |
| 980 // support the CHILDID_SELF id. | |
| 981 return (VT_I4 == child.vt) && (CHILDID_SELF == child.lVal); | |
| 982 } | |
| 983 | |
| 984 int AXPlatformNodeWin::MSAARole() { | 1021 int AXPlatformNodeWin::MSAARole() { |
| 985 switch (GetData().role) { | 1022 switch (GetData().role) { |
| 986 case ui::AX_ROLE_ALERT: | 1023 case ui::AX_ROLE_ALERT: |
| 987 return ROLE_SYSTEM_ALERT; | 1024 return ROLE_SYSTEM_ALERT; |
| 988 case ui::AX_ROLE_APPLICATION: | 1025 case ui::AX_ROLE_APPLICATION: |
| 989 return ROLE_SYSTEM_APPLICATION; | 1026 return ROLE_SYSTEM_APPLICATION; |
| 990 case ui::AX_ROLE_BUTTON_DROP_DOWN: | 1027 case ui::AX_ROLE_BUTTON_DROP_DOWN: |
| 991 return ROLE_SYSTEM_BUTTONDROPDOWN; | 1028 return ROLE_SYSTEM_BUTTONDROPDOWN; |
| 992 case ui::AX_ROLE_POP_UP_BUTTON: | 1029 case ui::AX_ROLE_POP_UP_BUTTON: |
| 993 return ROLE_SYSTEM_BUTTONMENU; | 1030 return ROLE_SYSTEM_BUTTONMENU; |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1199 LONG start_offset, | 1236 LONG start_offset, |
| 1200 ui::TextBoundaryDirection direction) { | 1237 ui::TextBoundaryDirection direction) { |
| 1201 HandleSpecialTextOffset(&start_offset); | 1238 HandleSpecialTextOffset(&start_offset); |
| 1202 ui::TextBoundaryType boundary = IA2TextBoundaryToTextBoundary(ia2_boundary); | 1239 ui::TextBoundaryType boundary = IA2TextBoundaryToTextBoundary(ia2_boundary); |
| 1203 std::vector<int32_t> line_breaks; | 1240 std::vector<int32_t> line_breaks; |
| 1204 return static_cast<LONG>(ui::FindAccessibleTextBoundary( | 1241 return static_cast<LONG>(ui::FindAccessibleTextBoundary( |
| 1205 text, line_breaks, boundary, start_offset, direction, | 1242 text, line_breaks, boundary, start_offset, direction, |
| 1206 AX_TEXT_AFFINITY_DOWNSTREAM)); | 1243 AX_TEXT_AFFINITY_DOWNSTREAM)); |
| 1207 } | 1244 } |
| 1208 | 1245 |
| 1246 AXPlatformNodeWin* AXPlatformNodeWin::GetTargetFromChildID( |
| 1247 const VARIANT& var_id) { |
| 1248 LONG child_id = V_I4(&var_id); |
| 1249 if (child_id == CHILDID_SELF) { |
| 1250 return this; |
| 1251 } |
| 1252 |
| 1253 if (child_id >= 1 && child_id <= delegate_->GetChildCount()) { |
| 1254 // Positive child ids are a 1-based child index, used by clients |
| 1255 // that want to enumerate all immediate children. |
| 1256 AXPlatformNodeBase* base = |
| 1257 FromNativeViewAccessible(delegate_->ChildAtIndex(child_id - 1)); |
| 1258 return static_cast<AXPlatformNodeWin*>(base); |
| 1259 } |
| 1260 |
| 1261 if (child_id >= 0) |
| 1262 return nullptr; |
| 1263 |
| 1264 // Negative child ids can be used to map to any descendant. |
| 1265 AXPlatformNode* node = GetFromUniqueId(-child_id); |
| 1266 if (!node) |
| 1267 return nullptr; |
| 1268 |
| 1269 AXPlatformNodeBase* base = |
| 1270 FromNativeViewAccessible(node->GetNativeViewAccessible()); |
| 1271 if (base && !IsDescendant(base)) |
| 1272 base = nullptr; |
| 1273 |
| 1274 return static_cast<AXPlatformNodeWin*>(base); |
| 1275 } |
| 1276 |
| 1209 } // namespace ui | 1277 } // namespace ui |
| OLD | NEW |