OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "chrome/browser/browser_accessibility.h" | 5 #include "chrome/browser/browser_accessibility.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "chrome/browser/browser_accessibility_manager.h" | 8 #include "chrome/browser/browser_accessibility_manager.h" |
9 | 9 |
10 using webkit_glue::WebAccessibility; | 10 using webkit_glue::WebAccessibility; |
11 | 11 |
12 BrowserAccessibility::BrowserAccessibility() | 12 HRESULT BrowserAccessibility::Initialize(int iaccessible_id, int routing_id, |
13 : iaccessible_id_(-1), | 13 int process_id, HWND parent_hwnd) { |
14 instance_active_(true) { | 14 if (!parent_hwnd || iaccessible_id < 0) |
| 15 return E_INVALIDARG; |
| 16 |
| 17 iaccessible_id_ = iaccessible_id; |
| 18 routing_id_ = routing_id; |
| 19 process_id_ = process_id; |
| 20 parent_hwnd_ = parent_hwnd; |
| 21 |
| 22 // Mark instance as active. |
| 23 instance_active_ = true; |
| 24 |
| 25 // Treat child ids intitially as referring to direct children of the object. |
| 26 direct_descendant_ = true; |
| 27 |
| 28 return S_OK; |
15 } | 29 } |
16 | 30 |
17 HRESULT BrowserAccessibility::accDoDefaultAction(VARIANT var_id) { | 31 HRESULT BrowserAccessibility::accDoDefaultAction(VARIANT var_id) { |
18 if (!instance_active()) { | 32 if (!instance_active()) { |
19 // Instance no longer active, fail gracefully. | 33 // Instance no longer active, fail gracefully. |
20 // TODO(klink): Once we have MSAA events, change these fails for having | 34 // TODO(klink): Once we have MSAA events, change these fails to having |
21 // BrowserAccessibilityManager firing the right event. | 35 // BrowserAccessibilityManager firing the right event. |
22 return E_FAIL; | 36 return E_FAIL; |
23 } | 37 } |
24 | 38 |
25 if (var_id.vt != VT_I4) | 39 if (var_id.vt != VT_I4) |
26 return E_INVALIDARG; | 40 return E_INVALIDARG; |
27 | 41 |
28 if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_DODEFAULTACTION, | 42 if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_DODEFAULTACTION, |
29 var_id, NULL, NULL)) { | 43 var_id, NULL, NULL)) { |
30 return E_FAIL; | 44 return E_FAIL; |
31 } | 45 } |
32 | 46 |
33 if (!response().return_code) | 47 if (!response().return_code) |
34 return S_FALSE; | 48 return S_FALSE; |
35 | 49 |
36 return S_OK; | 50 return S_OK; |
37 } | 51 } |
38 | 52 |
39 STDMETHODIMP BrowserAccessibility::accHitTest(LONG x_left, LONG y_top, | 53 STDMETHODIMP BrowserAccessibility::accHitTest(LONG x_left, LONG y_top, |
40 VARIANT* child) { | 54 VARIANT* child) { |
41 if (!instance_active()) { | 55 if (!instance_active()) { |
42 // Instance no longer active, fail gracefully. | 56 // Instance no longer active, fail gracefully. |
43 return E_FAIL; | 57 return E_FAIL; |
44 } | 58 } |
45 | 59 |
46 if (!child) | 60 if (!child) |
47 return E_INVALIDARG; | 61 return E_INVALIDARG; |
48 | 62 |
49 if (!parent_hwnd()) { | 63 if (!parent_hwnd_) { |
50 // Parent HWND needed for coordinate conversion. | 64 // Parent HWND needed for coordinate conversion. |
51 return E_FAIL; | 65 return E_FAIL; |
52 } | 66 } |
53 | 67 |
54 // Convert coordinates to test from screen into client window coordinates, to | 68 // Convert coordinates to test from screen into client window coordinates, to |
55 // maintain sandbox functionality on renderer side. | 69 // maintain sandbox functionality on renderer side. |
56 POINT p = {x_left, y_top}; | 70 POINT p = {x_left, y_top}; |
57 ::ScreenToClient(parent_hwnd(), &p); | 71 ::ScreenToClient(parent_hwnd_, &p); |
58 | 72 |
59 if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_HITTEST, | 73 if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_HITTEST, |
60 EmptyVariant(), p.x, p.y)) { | 74 EmptyVariant(), p.x, p.y)) { |
61 return E_FAIL; | 75 return E_FAIL; |
62 } | 76 } |
63 | 77 |
64 if (!response().return_code) { | 78 if (!response().return_code) { |
65 // The point is outside of the object's boundaries. | 79 // The point is outside of the object's boundaries. |
66 child->vt = VT_EMPTY; | 80 child->vt = VT_EMPTY; |
67 return S_FALSE; | 81 return S_FALSE; |
(...skipping 18 matching lines...) Expand all Loading... |
86 | 100 |
87 STDMETHODIMP BrowserAccessibility::accLocation(LONG* x_left, LONG* y_top, | 101 STDMETHODIMP BrowserAccessibility::accLocation(LONG* x_left, LONG* y_top, |
88 LONG* width, LONG* height, | 102 LONG* width, LONG* height, |
89 VARIANT var_id) { | 103 VARIANT var_id) { |
90 if (!instance_active()) { | 104 if (!instance_active()) { |
91 // Instance no longer active, fail gracefully. | 105 // Instance no longer active, fail gracefully. |
92 return E_FAIL; | 106 return E_FAIL; |
93 } | 107 } |
94 | 108 |
95 if (var_id.vt != VT_I4 || !x_left || !y_top || !width || !height || | 109 if (var_id.vt != VT_I4 || !x_left || !y_top || !width || !height || |
96 !parent_hwnd()) { | 110 !parent_hwnd_) { |
97 return E_INVALIDARG; | 111 return E_INVALIDARG; |
98 } | 112 } |
99 | 113 |
100 if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_LOCATION, var_id, | 114 if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_LOCATION, var_id, |
101 NULL, NULL)) { | 115 NULL, NULL)) { |
102 return E_FAIL; | 116 return E_FAIL; |
103 } | 117 } |
104 | 118 |
105 POINT top_left = {0, 0}; | 119 POINT top_left = {0, 0}; |
106 | 120 |
107 // Find the top left corner of the containing window in screen coords, and | 121 // Find the top left corner of the containing window in screen coords, and |
108 // adjust the output position by this amount. | 122 // adjust the output position by this amount. |
109 ::ClientToScreen(parent_hwnd(), &top_left); | 123 ::ClientToScreen(parent_hwnd_, &top_left); |
110 | 124 |
111 *x_left = response().output_long1 + top_left.x; | 125 *x_left = response().output_long1 + top_left.x; |
112 *y_top = response().output_long2 + top_left.y; | 126 *y_top = response().output_long2 + top_left.y; |
113 | 127 |
114 *width = response().output_long3; | 128 *width = response().output_long3; |
115 *height = response().output_long4; | 129 *height = response().output_long4; |
116 | 130 |
117 return S_OK; | 131 return S_OK; |
118 } | 132 } |
119 | 133 |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 DCHECK(*name); | 400 DCHECK(*name); |
387 return S_OK; | 401 return S_OK; |
388 } | 402 } |
389 | 403 |
390 STDMETHODIMP BrowserAccessibility::get_accParent(IDispatch** disp_parent) { | 404 STDMETHODIMP BrowserAccessibility::get_accParent(IDispatch** disp_parent) { |
391 if (!instance_active()) { | 405 if (!instance_active()) { |
392 // Instance no longer active, fail gracefully. | 406 // Instance no longer active, fail gracefully. |
393 return E_FAIL; | 407 return E_FAIL; |
394 } | 408 } |
395 | 409 |
396 if (!disp_parent || !parent_hwnd()) | 410 if (!disp_parent || !parent_hwnd_) |
397 return E_INVALIDARG; | 411 return E_INVALIDARG; |
398 | 412 |
399 // Root node's parent is the containing HWND's IAccessible. | 413 // Root node's parent is the containing HWND's IAccessible. |
400 if (iaccessible_id() == 0) { | 414 if (iaccessible_id_ == 0) { |
401 // For an object that has no parent (e.g. root), point the accessible parent | 415 // For an object that has no parent (e.g. root), point the accessible parent |
402 // to the default implementation. | 416 // to the default implementation. |
403 HRESULT hr = | 417 HRESULT hr = |
404 ::CreateStdAccessibleObject(parent_hwnd(), OBJID_WINDOW, | 418 ::CreateStdAccessibleObject(parent_hwnd_, OBJID_WINDOW, |
405 IID_IAccessible, | 419 IID_IAccessible, |
406 reinterpret_cast<void**>(disp_parent)); | 420 reinterpret_cast<void**>(disp_parent)); |
407 | 421 |
408 if (!SUCCEEDED(hr)) { | 422 if (!SUCCEEDED(hr)) { |
409 *disp_parent = NULL; | 423 *disp_parent = NULL; |
410 return S_FALSE; | 424 return S_FALSE; |
411 } | 425 } |
412 return S_OK; | 426 return S_OK; |
413 } | 427 } |
414 | 428 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 // No string found. | 505 // No string found. |
492 return S_FALSE; | 506 return S_FALSE; |
493 } | 507 } |
494 | 508 |
495 *value = CComBSTR(response().output_string.c_str()).Detach(); | 509 *value = CComBSTR(response().output_string.c_str()).Detach(); |
496 | 510 |
497 DCHECK(*value); | 511 DCHECK(*value); |
498 return S_OK; | 512 return S_OK; |
499 } | 513 } |
500 | 514 |
501 STDMETHODIMP BrowserAccessibility::accSelect(LONG flags_select, | |
502 VARIANT var_id) { | |
503 return E_NOTIMPL; | |
504 } | |
505 | |
506 STDMETHODIMP BrowserAccessibility::get_accHelpTopic(BSTR* help_file, | 515 STDMETHODIMP BrowserAccessibility::get_accHelpTopic(BSTR* help_file, |
507 VARIANT var_id, | 516 VARIANT var_id, |
508 LONG* topic_id) { | 517 LONG* topic_id) { |
509 if (help_file) { | 518 if (help_file) |
510 *help_file = NULL; | 519 *help_file = NULL; |
511 } | 520 |
512 if (topic_id) { | 521 if (topic_id) |
513 *topic_id = static_cast<LONG>(-1); | 522 *topic_id = static_cast<LONG>(-1); |
514 } | 523 |
515 return E_NOTIMPL; | 524 return E_NOTIMPL; |
516 } | 525 } |
517 | 526 |
518 STDMETHODIMP BrowserAccessibility::get_accSelection(VARIANT* selected) { | 527 STDMETHODIMP BrowserAccessibility::get_accSelection(VARIANT* selected) { |
519 if (selected) | 528 if (selected) |
520 selected->vt = VT_EMPTY; | 529 selected->vt = VT_EMPTY; |
521 | 530 |
522 return E_NOTIMPL; | 531 return E_NOTIMPL; |
523 } | 532 } |
524 | 533 |
525 STDMETHODIMP BrowserAccessibility::put_accName(VARIANT var_id, BSTR put_name) { | |
526 return E_NOTIMPL; | |
527 } | |
528 | |
529 STDMETHODIMP BrowserAccessibility::put_accValue(VARIANT var_id, BSTR put_val) { | |
530 return E_NOTIMPL; | |
531 } | |
532 | |
533 STDMETHODIMP BrowserAccessibility::CreateInstance(REFIID iid, | 534 STDMETHODIMP BrowserAccessibility::CreateInstance(REFIID iid, |
534 int iaccessible_id, | 535 int iaccessible_id, |
535 void** interface_ptr) { | 536 void** interface_ptr) { |
536 return BrowserAccessibilityManager::GetInstance()-> | 537 return BrowserAccessibilityManager::GetInstance()-> |
537 CreateAccessibilityInstance(iid, iaccessible_id, instance_id(), | 538 CreateAccessibilityInstance(iid, iaccessible_id, routing_id_, |
538 interface_ptr); | 539 process_id_, parent_hwnd_, interface_ptr); |
539 } | 540 } |
540 | 541 |
541 bool BrowserAccessibility::RequestAccessibilityInfo(int iaccessible_func_id, | 542 bool BrowserAccessibility::RequestAccessibilityInfo(int iaccessible_func_id, |
542 VARIANT var_id, LONG input1, | 543 VARIANT var_id, LONG input1, |
543 LONG input2) { | 544 LONG input2) { |
544 return BrowserAccessibilityManager::GetInstance()->RequestAccessibilityInfo( | 545 // Create and populate IPC message structure, for retrieval of accessibility |
545 iaccessible_id(), instance_id(), iaccessible_func_id, var_id.lVal, input1, | 546 // information from the renderer. |
546 input2); | 547 WebAccessibility::InParams in_params; |
| 548 in_params.object_id = iaccessible_id_; |
| 549 in_params.function_id = iaccessible_func_id; |
| 550 in_params.child_id = var_id.lVal; |
| 551 in_params.direct_descendant = direct_descendant(); |
| 552 in_params.input_long1 = input1; |
| 553 in_params.input_long2 = input2; |
| 554 |
| 555 if (!direct_descendant()) |
| 556 set_direct_descendant(true); |
| 557 |
| 558 return BrowserAccessibilityManager::GetInstance()-> |
| 559 RequestAccessibilityInfo(&in_params, routing_id_, process_id_); |
547 } | 560 } |
548 | 561 |
549 const WebAccessibility::OutParams& BrowserAccessibility::response() { | 562 const WebAccessibility::OutParams& BrowserAccessibility::response() { |
550 return BrowserAccessibilityManager::GetInstance()->response(); | 563 return BrowserAccessibilityManager::GetInstance()->response(); |
551 } | 564 } |
552 | 565 |
553 HWND BrowserAccessibility::parent_hwnd() { | |
554 return BrowserAccessibilityManager::GetInstance()->parent_hwnd(instance_id()); | |
555 } | |
556 | |
557 long BrowserAccessibility::MSAARole(long browser_accessibility_role) { | 566 long BrowserAccessibility::MSAARole(long browser_accessibility_role) { |
558 switch (browser_accessibility_role) { | 567 switch (browser_accessibility_role) { |
559 case WebAccessibility::ROLE_PUSHBUTTON : | 568 case WebAccessibility::ROLE_PUSHBUTTON : |
560 return ROLE_SYSTEM_PUSHBUTTON; | 569 return ROLE_SYSTEM_PUSHBUTTON; |
561 case WebAccessibility::ROLE_RADIOBUTTON : | 570 case WebAccessibility::ROLE_RADIOBUTTON : |
562 return ROLE_SYSTEM_RADIOBUTTON; | 571 return ROLE_SYSTEM_RADIOBUTTON; |
563 case WebAccessibility::ROLE_CHECKBUTTON : | 572 case WebAccessibility::ROLE_CHECKBUTTON : |
564 return ROLE_SYSTEM_CHECKBUTTON; | 573 return ROLE_SYSTEM_CHECKBUTTON; |
565 case WebAccessibility::ROLE_SLIDER : | 574 case WebAccessibility::ROLE_SLIDER : |
566 return ROLE_SYSTEM_SLIDER; | 575 return ROLE_SYSTEM_SLIDER; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
634 state |= STATE_SYSTEM_FOCUSED; | 643 state |= STATE_SYSTEM_FOCUSED; |
635 | 644 |
636 if ((browser_accessibility_state >> WebAccessibility::STATE_TRAVERSED) & 1) | 645 if ((browser_accessibility_state >> WebAccessibility::STATE_TRAVERSED) & 1) |
637 state |= STATE_SYSTEM_TRAVERSED; | 646 state |= STATE_SYSTEM_TRAVERSED; |
638 | 647 |
639 if ((browser_accessibility_state >> WebAccessibility::STATE_FOCUSABLE) & 1) | 648 if ((browser_accessibility_state >> WebAccessibility::STATE_FOCUSABLE) & 1) |
640 state |= STATE_SYSTEM_FOCUSABLE; | 649 state |= STATE_SYSTEM_FOCUSABLE; |
641 | 650 |
642 return state; | 651 return state; |
643 } | 652 } |
OLD | NEW |