diff options
26 files changed, 5506 insertions, 1173 deletions
diff --git a/chrome/browser/browser_accessibility.cc b/chrome/browser/browser_accessibility.cc index f6cd32f..e282263 100644 --- a/chrome/browser/browser_accessibility.cc +++ b/chrome/browser/browser_accessibility.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -9,134 +9,159 @@ using webkit_glue::WebAccessibility; -HRESULT BrowserAccessibility::Initialize(int iaccessible_id, int routing_id, - int process_id, HWND parent_hwnd) { - // Check input parameters. Root id is 1000, to avoid conflicts with the ids - // used by MSAA. - if (!parent_hwnd || iaccessible_id < 1000) - return E_INVALIDARG; +BrowserAccessibility::BrowserAccessibility() + : manager_(NULL), + parent_(NULL), + child_id_(-1), + index_in_parent_(-1), + renderer_id_(-1), + instance_active_(false) { +} + +BrowserAccessibility::~BrowserAccessibility() { + InactivateTree(); +} - iaccessible_id_ = iaccessible_id; - routing_id_ = routing_id; - process_id_ = process_id; - parent_hwnd_ = parent_hwnd; +void BrowserAccessibility::Initialize( + BrowserAccessibilityManager* manager, + BrowserAccessibility* parent, + LONG child_id, + LONG index_in_parent, + const webkit_glue::WebAccessibility& src) { + manager_ = manager; + parent_ = parent; + child_id_ = child_id; + index_in_parent_ = index_in_parent; + + renderer_id_ = src.id; + name_ = src.name; + value_ = src.value; + action_ = src.action; + description_ = src.description; + help_ = src.help; + shortcut_ = src.shortcut; + role_ = MSAARole(src.role); + state_ = MSAAState(src.state); + location_ = src.location; - // Mark instance as active. instance_active_ = true; - return S_OK; + + // Focused is a dynamic state, only one node will be focused at a time. + state_ &= ~STATE_SYSTEM_FOCUSED; } -HRESULT BrowserAccessibility::accDoDefaultAction(VARIANT var_id) { - if (!instance_active()) { - // Instance no longer active, fail gracefully. - // TODO(ctguil): Once we have MSAA events, change these fails to having - // BrowserAccessibilityManager firing the right event. - return E_FAIL; - } +void BrowserAccessibility::AddChild(BrowserAccessibility* child) { + children_.push_back(child); +} - if (var_id.vt != VT_I4) - return E_INVALIDARG; +void BrowserAccessibility::InactivateTree() { + // Mark this object as inactive, so calls to all COM methods will return + // failure. + instance_active_ = false; + + // Now we can safely call InactivateTree on our children and remove + // references to them, so that as much of the tree as possible will be + // destroyed now - however, nodes that still have references to them + // might stick around a while until all clients have released them. + for (std::vector<BrowserAccessibility*>::iterator iter = + children_.begin(); + iter != children_.end(); ++iter) { + (*iter)->InactivateTree(); + (*iter)->Release(); + } + children_.clear(); +} - if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_DODEFAULTACTION, - var_id, NULL, NULL)) { - return E_FAIL; +bool BrowserAccessibility::IsDescendantOf(BrowserAccessibility* ancestor) { + if (this == ancestor) { + return true; + } else if (parent_) { + return parent_->IsDescendantOf(ancestor); } - if (response().return_code == WebAccessibility::RETURNCODE_FALSE) - return S_FALSE; + return false; +} - return S_OK; +BrowserAccessibility* BrowserAccessibility::GetPreviousSibling() { + if (parent_ && index_in_parent_ > 0) + return parent_->children_[index_in_parent_ - 1]; + + return NULL; } -STDMETHODIMP BrowserAccessibility::accHitTest(LONG x_left, LONG y_top, - VARIANT* child) { - if (!instance_active()) { - // Instance no longer active, fail gracefully. - return E_FAIL; +BrowserAccessibility* BrowserAccessibility::GetNextSibling() { + if (parent_ && + index_in_parent_ < static_cast<int>(parent_->children_.size() - 1)) { + return parent_->children_[index_in_parent_ + 1]; } - if (!child) - return E_INVALIDARG; + return NULL; +} - if (!parent_hwnd_) { - // Parent HWND needed for coordinate conversion. - return E_FAIL; - } +BrowserAccessibility* BrowserAccessibility::NewReference() { + AddRef(); + return this; +} - // Convert coordinates to test from screen into client window coordinates, to - // maintain sandbox functionality on renderer side. - POINT p = {x_left, y_top}; - ::ScreenToClient(parent_hwnd_, &p); +// +// IAccessible methods. +// - if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_HITTEST, - ChildSelfVariant(), p.x, p.y)) { +HRESULT BrowserAccessibility::accDoDefaultAction(VARIANT var_id) { + if (!instance_active_) { + // Instance no longer active, fail gracefully. return E_FAIL; } - if (response().return_code == WebAccessibility::RETURNCODE_FALSE) { - // The point is outside of the object's boundaries. - child->vt = VT_EMPTY; - return S_FALSE; - } + return E_NOTIMPL; +} - if (response().output_long1 == -1) { - if (CreateInstance(IID_IAccessible, response().object_id, - reinterpret_cast<void**>(&child->pdispVal)) == S_OK) { - child->vt = VT_DISPATCH; - // Increment the reference count for the retrieved interface. - child->pdispVal->AddRef(); - } else { - return E_NOINTERFACE; - } - } else { - child->vt = VT_I4; - child->lVal = response().output_long1; +STDMETHODIMP BrowserAccessibility::accHitTest(LONG x_left, LONG y_top, + VARIANT* child) { + if (!instance_active_) { + // Instance no longer active, fail gracefully. + return E_FAIL; } - return S_OK; + if (!child) + return E_INVALIDARG; + + return E_NOTIMPL; } STDMETHODIMP BrowserAccessibility::accLocation(LONG* x_left, LONG* y_top, LONG* width, LONG* height, VARIANT var_id) { - if (!instance_active()) { + if (!instance_active_) { // Instance no longer active, fail gracefully. return E_FAIL; } - if (var_id.vt != VT_I4 || !x_left || !y_top || !width || !height || - !parent_hwnd_) { + if (!x_left || !y_top || !width || !height) return E_INVALIDARG; - } - - if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_LOCATION, var_id, - NULL, NULL)) { - return E_FAIL; - } - POINT top_left = {0, 0}; + BrowserAccessibility* target = GetTargetFromChildID(var_id); + if (!target) + return E_INVALIDARG; // Find the top left corner of the containing window in screen coords, and // adjust the output position by this amount. - ::ClientToScreen(parent_hwnd_, &top_left); - - *x_left = response().output_long1 + top_left.x; - *y_top = response().output_long2 + top_left.y; + HWND parent_hwnd = manager_->GetParentHWND(); + POINT top_left = {0, 0}; + ::ClientToScreen(parent_hwnd, &top_left); - *width = response().output_long3; - *height = response().output_long4; + *x_left = target->location_.x + top_left.x; + *y_top = target->location_.y + top_left.y; + *width = target->location_.width; + *height = target->location_.height; return S_OK; } -STDMETHODIMP BrowserAccessibility::accNavigate(LONG nav_dir, VARIANT start, - VARIANT* end) { - if (!instance_active()) { - // Instance no longer active, fail gracefully. - return E_FAIL; - } - - if (start.vt != VT_I4 || !end) +STDMETHODIMP BrowserAccessibility::accNavigate( + LONG nav_dir, VARIANT start, VARIANT* end) { + BrowserAccessibility* target = GetTargetFromChildID(start); + if (!target) return E_INVALIDARG; if ((nav_dir == NAVDIR_LASTCHILD || nav_dir == NAVDIR_FIRSTCHILD) && @@ -145,80 +170,62 @@ STDMETHODIMP BrowserAccessibility::accNavigate(LONG nav_dir, VARIANT start, return E_INVALIDARG; } - if (nav_dir == NAVDIR_DOWN || nav_dir == NAVDIR_UP || - nav_dir == NAVDIR_LEFT || nav_dir == NAVDIR_RIGHT) { - // Directions not implemented, matching Mozilla and IE. - return E_INVALIDARG; - } - - if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_NAVIGATE, start, - nav_dir, NULL)) { - return E_FAIL; - } - - if (response().return_code == WebAccessibility::RETURNCODE_FALSE) { - // No screen element was found in the specified direction. + BrowserAccessibility* result; + switch (nav_dir) { + case NAVDIR_DOWN: + case NAVDIR_UP: + case NAVDIR_LEFT: + case NAVDIR_RIGHT: + // These directions are not implemented, matching Mozilla and IE. + return E_NOTIMPL; + case NAVDIR_FIRSTCHILD: + if (target->children_.size() > 0) + result = target->children_[0]; + break; + case NAVDIR_LASTCHILD: + if (target->children_.size() > 0) + result = target->children_[target->children_.size() - 1]; + break; + case NAVDIR_NEXT: + result = target->GetNextSibling(); + break; + case NAVDIR_PREVIOUS: + result = target->GetPreviousSibling(); + break; + } + + if (!result) { end->vt = VT_EMPTY; return S_FALSE; } - if (response().output_long1 == -1) { - if (CreateInstance(IID_IAccessible, response().object_id, - reinterpret_cast<void**>(&end->pdispVal)) == S_OK) { - end->vt = VT_DISPATCH; - // Increment the reference count for the retrieved interface. - end->pdispVal->AddRef(); - } else { - return E_NOINTERFACE; - } - } else { - end->vt = VT_I4; - end->lVal = response().output_long1; - } - + end->vt = VT_DISPATCH; + end->pdispVal = result->NewReference(); return S_OK; } STDMETHODIMP BrowserAccessibility::get_accChild(VARIANT var_child, IDispatch** disp_child) { - if (!instance_active()) { + if (!instance_active_) { // Instance no longer active, fail gracefully. return E_FAIL; } - if (var_child.vt != VT_I4 || !disp_child) + if (!disp_child) return E_INVALIDARG; - // If var_child is the parent, remain with the same IDispatch. - if (var_child.lVal == CHILDID_SELF && iaccessible_id_ != 1000) - return S_OK; - - if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_GETCHILD, var_child, - NULL, NULL)) { - return E_FAIL; - } + *disp_child = NULL; - // TODO(ctguil): Figure out when the return code would be false - if (response().return_code == WebAccessibility::RETURNCODE_FALSE) { - // When at a leaf, children are handled by the parent object. - *disp_child = NULL; - return S_FALSE; - } + BrowserAccessibility* target = GetTargetFromChildID(var_child); + if (!target) + return E_INVALIDARG; - // Retrieve the IUnknown interface for the parent view, and assign the - // IDispatch returned. - if (CreateInstance(IID_IAccessible, response().object_id, - reinterpret_cast<void**>(disp_child)) == S_OK) { - // Increment the reference count for the retrieved interface. - (*disp_child)->AddRef(); - return S_OK; - } else { - return E_NOINTERFACE; - } + (*disp_child) = target->NewReference(); + return S_OK; } STDMETHODIMP BrowserAccessibility::get_accChildCount(LONG* child_count) { - if (!instance_active()) { + if (!instance_active_) { // Instance no longer active, fail gracefully. return E_FAIL; } @@ -226,36 +233,29 @@ STDMETHODIMP BrowserAccessibility::get_accChildCount(LONG* child_count) { if (!child_count) return E_INVALIDARG; - if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_CHILDCOUNT, - ChildSelfVariant(), NULL, NULL)) { - return E_FAIL; - } - - *child_count = response().output_long1; + *child_count = children_.size(); return S_OK; } STDMETHODIMP BrowserAccessibility::get_accDefaultAction(VARIANT var_id, BSTR* def_action) { - if (!instance_active()) { + if (!instance_active_) { // Instance no longer active, fail gracefully. return E_FAIL; } - if (var_id.vt != VT_I4 || !def_action) + if (!def_action) return E_INVALIDARG; - if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_DEFAULTACTION, - var_id, NULL, NULL)) { - return E_FAIL; - } + BrowserAccessibility* target = GetTargetFromChildID(var_id); + if (!target) + return E_INVALIDARG; - if (response().return_code == WebAccessibility::RETURNCODE_FALSE) { - // No string found. + // Return false if the string is empty. + if (target->action_.size() == 0) return S_FALSE; - } - *def_action = SysAllocString(response().output_string.c_str()); + *def_action = SysAllocString(target->action_.c_str()); DCHECK(*def_action); return S_OK; @@ -263,32 +263,30 @@ STDMETHODIMP BrowserAccessibility::get_accDefaultAction(VARIANT var_id, STDMETHODIMP BrowserAccessibility::get_accDescription(VARIANT var_id, BSTR* desc) { - if (!instance_active()) { + if (!instance_active_) { // Instance no longer active, fail gracefully. return E_FAIL; } - if (var_id.vt != VT_I4 || !desc) + if (!desc) return E_INVALIDARG; - if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_DESCRIPTION, var_id, - NULL, NULL)) { - return E_FAIL; - } + BrowserAccessibility* target = GetTargetFromChildID(var_id); + if (!target) + return E_INVALIDARG; - if (response().return_code == WebAccessibility::RETURNCODE_FALSE) { - // No string found. + // Return false if the string is empty. + if (target->description_.size() == 0) return S_FALSE; - } - *desc = SysAllocString(response().output_string.c_str()); + *desc = SysAllocString(target->description_.c_str()); DCHECK(*desc); return S_OK; } STDMETHODIMP BrowserAccessibility::get_accFocus(VARIANT* focus_child) { - if (!instance_active()) { + if (!instance_active_) { // Instance no longer active, fail gracefully. return E_FAIL; } @@ -296,55 +294,38 @@ STDMETHODIMP BrowserAccessibility::get_accFocus(VARIANT* focus_child) { if (!focus_child) return E_INVALIDARG; - if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_GETFOCUSEDCHILD, - ChildSelfVariant(), NULL, NULL)) { - return E_FAIL; - } - - if (response().return_code == WebAccessibility::RETURNCODE_FALSE) { - // The window that contains this object is not the active window. + BrowserAccessibility* focus = manager_->GetFocus(this); + if (focus == this) { + focus_child->vt = VT_I4; + focus_child->lVal = CHILDID_SELF; + } else if (focus == NULL) { focus_child->vt = VT_EMPTY; - return S_FALSE; - } - - if (response().output_long1 == -1) { - if (CreateInstance(IID_IAccessible, response().object_id, - reinterpret_cast<void**>(&focus_child->pdispVal)) == S_OK) { - focus_child->vt = VT_DISPATCH; - // Increment the reference count for the retrieved interface. - focus_child->pdispVal->AddRef(); - } else { - return E_NOINTERFACE; - } } else { - focus_child->vt = VT_I4; - focus_child->lVal = response().output_long1; + focus_child->vt = VT_DISPATCH; + focus_child->pdispVal = focus->NewReference(); } return S_OK; } STDMETHODIMP BrowserAccessibility::get_accHelp(VARIANT var_id, BSTR* help) { - if (!instance_active()) { + if (!instance_active_) { // Instance no longer active, fail gracefully. return E_FAIL; } - if (var_id.vt != VT_I4 || !help) + if (!help) return E_INVALIDARG; - if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_HELPTEXT, var_id, - NULL, NULL)) { - return E_FAIL; - } + BrowserAccessibility* target = GetTargetFromChildID(var_id); + if (!target) + return E_INVALIDARG; - if (response().return_code == WebAccessibility::RETURNCODE_FALSE || - response().output_string.empty()) { - // No string found. + // Return false if the string is empty. + if (target->help_.size() == 0) return S_FALSE; - } - *help = SysAllocString(response().output_string.c_str()); + *help = SysAllocString(target->help_.c_str()); DCHECK(*help); return S_OK; @@ -352,162 +333,126 @@ STDMETHODIMP BrowserAccessibility::get_accHelp(VARIANT var_id, BSTR* help) { STDMETHODIMP BrowserAccessibility::get_accKeyboardShortcut(VARIANT var_id, BSTR* acc_key) { - if (!instance_active()) { + if (!instance_active_) { // Instance no longer active, fail gracefully. return E_FAIL; } - if (var_id.vt != VT_I4 || !acc_key) + if (!acc_key) return E_INVALIDARG; - if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_KEYBOARDSHORTCUT, - var_id, NULL, NULL)) { - return E_FAIL; - } + BrowserAccessibility* target = GetTargetFromChildID(var_id); + if (!target) + return E_INVALIDARG; - if (response().return_code == WebAccessibility::RETURNCODE_FALSE) { - // No string found. + // Return false if the string is empty. + if (target->shortcut_.size() == 0) return S_FALSE; - } - *acc_key = SysAllocString(response().output_string.c_str()); + *acc_key = SysAllocString(target->shortcut_.c_str()); DCHECK(*acc_key); return S_OK; } STDMETHODIMP BrowserAccessibility::get_accName(VARIANT var_id, BSTR* name) { - if (!instance_active()) { + if (!instance_active_) { // Instance no longer active, fail gracefully. return E_FAIL; } - if (var_id.vt != VT_I4 || !name) + if (!name) return E_INVALIDARG; - if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_NAME, var_id, NULL, - NULL)) { - return E_FAIL; - } + BrowserAccessibility* target = GetTargetFromChildID(var_id); + if (!target) + return E_INVALIDARG; - if (response().return_code == WebAccessibility::RETURNCODE_FALSE) { - // No string found. + // Return false if the string is empty. + if (target->name_.size() == 0) return S_FALSE; - } - *name = SysAllocString(response().output_string.c_str()); + *name = SysAllocString(target->name_.c_str()); DCHECK(*name); return S_OK; } STDMETHODIMP BrowserAccessibility::get_accParent(IDispatch** disp_parent) { - if (!instance_active()) { + if (!instance_active_) { // Instance no longer active, fail gracefully. return E_FAIL; } - if (!disp_parent || !parent_hwnd_) + if (!disp_parent) return E_INVALIDARG; - // Root node's parent is the containing HWND's IAccessible. - if (iaccessible_id_ == 1000) { - // For an object that has no parent (e.g. root), point the accessible parent - // to the default implementation. - HRESULT hr = - ::CreateStdAccessibleObject(parent_hwnd_, OBJID_WINDOW, - IID_IAccessible, - reinterpret_cast<void**>(disp_parent)); - - if (!SUCCEEDED(hr)) { - *disp_parent = NULL; - return S_FALSE; - } - return S_OK; - } - - if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_GETPARENT, - ChildSelfVariant(), NULL, NULL)) { - return E_FAIL; + IAccessible* parent = parent_; + if (parent == NULL) { + // This happens if we're the root of the tree; + // return the IAccessible for the window. + parent = manager_->GetParentWindowIAccessible(); } - if (response().return_code == WebAccessibility::RETURNCODE_FALSE) { - // No parent exists for this object. - return S_FALSE; - } - - // Retrieve the IUnknown interface for the parent view, and assign the - // IDispatch returned. - if (CreateInstance(IID_IAccessible, response().object_id, - reinterpret_cast<void**>(disp_parent)) == S_OK) { - // Increment the reference count for the retrieved interface. - (*disp_parent)->AddRef(); - return S_OK; - } else { - return E_NOINTERFACE; - } + parent->AddRef(); + *disp_parent = parent; + return S_OK; } STDMETHODIMP BrowserAccessibility::get_accRole(VARIANT var_id, VARIANT* role) { - if (!instance_active()) { + if (!instance_active_) { // Instance no longer active, fail gracefully. return E_FAIL; } - if (var_id.vt != VT_I4 || !role) + if (!role) return E_INVALIDARG; - if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_ROLE, var_id, NULL, - NULL)) { - return E_FAIL; - } + BrowserAccessibility* target = GetTargetFromChildID(var_id); + if (!target) + return E_INVALIDARG; role->vt = VT_I4; - role->lVal = MSAARole(response().output_long1); + role->lVal = target->role_; return S_OK; } STDMETHODIMP BrowserAccessibility::get_accState(VARIANT var_id, VARIANT* state) { - if (!instance_active()) { + if (!instance_active_) { // Instance no longer active, fail gracefully. return E_FAIL; } - if (var_id.vt != VT_I4 || !state) + if (!state) return E_INVALIDARG; - if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_STATE, var_id, NULL, - NULL)) { - return E_FAIL; - } + BrowserAccessibility* target = GetTargetFromChildID(var_id); + if (!target) + return E_INVALIDARG; state->vt = VT_I4; - state->lVal = MSAAState(response().output_long1); + state->lVal = target->state_; + if (manager_->GetFocus(NULL) == this) + state->lVal |= STATE_SYSTEM_FOCUSED; + return S_OK; } STDMETHODIMP BrowserAccessibility::get_accValue(VARIANT var_id, BSTR* value) { - if (!instance_active()) { + if (!instance_active_) { // Instance no longer active, fail gracefully. return E_FAIL; } - if (var_id.vt != VT_I4 || !value) + if (!value) return E_INVALIDARG; - if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_VALUE, var_id, NULL, - NULL)) { - return E_FAIL; - } - - if (response().return_code == WebAccessibility::RETURNCODE_FALSE || - response().output_string.empty()) { - // No string found. - return S_FALSE; - } + BrowserAccessibility* target = GetTargetFromChildID(var_id); + if (!target) + return E_INVALIDARG; - *value = SysAllocString(response().output_string.c_str()); + *value = SysAllocString(target->value_.c_str()); DCHECK(*value); return S_OK; @@ -516,54 +461,136 @@ STDMETHODIMP BrowserAccessibility::get_accValue(VARIANT var_id, BSTR* value) { STDMETHODIMP BrowserAccessibility::get_accHelpTopic(BSTR* help_file, VARIANT var_id, LONG* topic_id) { - if (help_file) - *help_file = NULL; + return E_NOTIMPL; +} - if (topic_id) - *topic_id = static_cast<LONG>(-1); +STDMETHODIMP BrowserAccessibility::get_accSelection(VARIANT* selected) { + if (!instance_active_) { + // Instance no longer active, fail gracefully. + return E_FAIL; + } return E_NOTIMPL; } -STDMETHODIMP BrowserAccessibility::get_accSelection(VARIANT* selected) { - if (selected) - selected->vt = VT_EMPTY; +STDMETHODIMP BrowserAccessibility::accSelect(LONG flags_sel, VARIANT var_id) { + if (!instance_active_) { + // Instance no longer active, fail gracefully. + return E_FAIL; + } return E_NOTIMPL; } -STDMETHODIMP BrowserAccessibility::CreateInstance(REFIID iid, - int iaccessible_id, - void** interface_ptr) { - return BrowserAccessibilityManager::GetInstance()-> - CreateAccessibilityInstance(iid, iaccessible_id, routing_id_, - process_id_, parent_hwnd_, interface_ptr); +// +// IAccessible2 methods. +// + +STDMETHODIMP BrowserAccessibility::role(LONG* role) { + if (!instance_active_) { + // Instance no longer active, fail gracefully. + return E_FAIL; + } + + if (!role) + return E_INVALIDARG; + + *role = role_; + + return S_OK; +} + +STDMETHODIMP BrowserAccessibility::get_states(AccessibleStates* states) { + if (!instance_active_) { + // Instance no longer active, fail gracefully. + return E_FAIL; + } + + if (!states) + return E_INVALIDARG; + + *states = state_; + + return S_OK; +} + +STDMETHODIMP BrowserAccessibility::get_uniqueID(LONG* unique_id) { + if (!instance_active_) { + // Instance no longer active, fail gracefully. + return E_FAIL; + } + + if (!unique_id) + return E_INVALIDARG; + + *unique_id = child_id_; + return S_OK; +} + +STDMETHODIMP BrowserAccessibility::get_windowHandle(HWND* window_handle) { + if (!instance_active_) { + // Instance no longer active, fail gracefully. + return E_FAIL; + } + + if (!window_handle) + return E_INVALIDARG; + + *window_handle = manager_->GetParentHWND(); + return S_OK; +} + +STDMETHODIMP BrowserAccessibility::get_indexInParent(LONG* index_in_parent) { + if (!instance_active_) { + // Instance no longer active, fail gracefully. + return E_FAIL; + } + + if (!index_in_parent) + return E_INVALIDARG; + + *index_in_parent = index_in_parent_; + return S_OK; } -bool BrowserAccessibility::RequestAccessibilityInfo(int iaccessible_func_id, - VARIANT var_id, LONG input1, - LONG input2) { - DCHECK(V_VT(&var_id) == VT_I4); +// +// IServiceProvider methods. +// + +STDMETHODIMP BrowserAccessibility::QueryService( + REFGUID guidService, REFIID riid, void** object) { + if (!instance_active_) { + // Instance no longer active, fail gracefully. + return E_FAIL; + } - // Create and populate IPC message structure, for retrieval of accessibility - // information from the renderer. - WebAccessibility::InParams in_params; - in_params.object_id = iaccessible_id_; - in_params.function_id = iaccessible_func_id; - in_params.child_id = V_I4(&var_id); - in_params.input_long1 = input1; - in_params.input_long2 = input2; + if (guidService == IID_IAccessible || guidService == IID_IAccessible2) + return QueryInterface(riid, object); - return BrowserAccessibilityManager::GetInstance()-> - RequestAccessibilityInfo(&in_params, routing_id_, process_id_) && - response().return_code != WebAccessibility::RETURNCODE_FAIL; + *object = NULL; + return E_FAIL; } -const WebAccessibility::OutParams& BrowserAccessibility::response() { - return BrowserAccessibilityManager::GetInstance()->response(); +// +// Private methods. +// + +BrowserAccessibility* BrowserAccessibility::GetTargetFromChildID( + const VARIANT& var_id) { + if (var_id.vt != VT_I4) + return NULL; + + LONG child_id = var_id.lVal; + if (child_id == CHILDID_SELF) + return this; + + if (child_id >= 1 && child_id <= static_cast<LONG>(children_.size())) + return children_[child_id - 1]; + + return manager_->GetFromChildID(child_id); } -long BrowserAccessibility::MSAARole(long browser_accessibility_role) { +LONG BrowserAccessibility::MSAARole(LONG browser_accessibility_role) { switch (browser_accessibility_role) { case WebAccessibility::ROLE_APPLICATION: return ROLE_SYSTEM_APPLICATION; @@ -631,8 +658,8 @@ long BrowserAccessibility::MSAARole(long browser_accessibility_role) { } } -long BrowserAccessibility::MSAAState(long browser_accessibility_state) { - long state = 0; +LONG BrowserAccessibility::MSAAState(LONG browser_accessibility_state) { + LONG state = 0; if ((browser_accessibility_state >> WebAccessibility::STATE_CHECKED) & 1) state |= STATE_SYSTEM_CHECKED; diff --git a/chrome/browser/browser_accessibility.h b/chrome/browser/browser_accessibility.h index ecf746e..767ede2 100644 --- a/chrome/browser/browser_accessibility.h +++ b/chrome/browser/browser_accessibility.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -7,9 +7,13 @@ #include <atlbase.h> #include <atlcom.h> - #include <oleacc.h> +#include <vector> + +#include "base/scoped_comptr_win.h" +#include "chrome/browser/browser_accessibility_manager.h" +#include "ia2_api_all.h" // Generated #include "webkit/glue/webaccessibility.h" using webkit_glue::WebAccessibility; @@ -25,29 +29,58 @@ using webkit_glue::WebAccessibility; //////////////////////////////////////////////////////////////////////////////// class ATL_NO_VTABLE BrowserAccessibility : public CComObjectRootEx<CComMultiThreadModel>, - public IDispatchImpl<IAccessible, &IID_IAccessible, &LIBID_Accessibility> { + public IDispatchImpl<IAccessible2, &IID_IAccessible2, + &LIBID_IAccessible2Lib>, + public IServiceProvider { public: BEGIN_COM_MAP(BrowserAccessibility) - COM_INTERFACE_ENTRY2(IDispatch, IAccessible) - COM_INTERFACE_ENTRY(IAccessible) + COM_INTERFACE_ENTRY2(IDispatch, IAccessible2) + COM_INTERFACE_ENTRY2(IAccessible, IAccessible2) + COM_INTERFACE_ENTRY(IAccessible2) + COM_INTERFACE_ENTRY(IServiceProvider) END_COM_MAP() - BrowserAccessibility() - : iaccessible_id_(-1), - routing_id_(-1), - process_id_(-1), - parent_hwnd_(NULL), - instance_active_(false) { - } + BrowserAccessibility(); + + virtual ~BrowserAccessibility(); + + // Initialize this object and mark it as active. + void Initialize(BrowserAccessibilityManager* manager, + BrowserAccessibility* parent, + LONG child_id, + LONG index_in_parent, + const webkit_glue::WebAccessibility& src); + + // Add a child of this object. + void AddChild(BrowserAccessibility* child); + + // Mark this object as inactive, and remove references to all children. + // When no other clients hold any references to this object it will be + // deleted, and in the meantime, calls to any methods will return E_FAIL. + void InactivateTree(); + + // Return true if this object is equal to or a descendant of |ancestor|. + bool IsDescendantOf(BrowserAccessibility* ancestor); + + // Return the previous sibling of this object, or NULL if it's the first + // child of its parent. + BrowserAccessibility* GetPreviousSibling(); + + // Return the next sibling of this object, or NULL if it's the last child + // of its parent. + BrowserAccessibility* GetNextSibling(); - ~BrowserAccessibility() {} + // Accessors + LONG child_id() { return child_id_; } - HRESULT Initialize(int iaccessible_id, - int routing_id, - int process_id, - HWND parent_hwnd); + // Add one to the reference count and return the same object. Always + // use this method when returning a BrowserAccessibility object as + // an output parameter to a COM interface, never use it otherwise. + BrowserAccessibility* NewReference(); - // Supported IAccessible methods. + // + // IAccessible methods. + // // Performs the default action on a given object. STDMETHODIMP accDoDefaultAction(VARIANT var_id); @@ -101,8 +134,8 @@ class ATL_NO_VTABLE BrowserAccessibility // Returns the value associated with the object. STDMETHODIMP get_accValue(VARIANT var_id, BSTR* value); - // Non-supported (by WebKit) IAccessible methods. - STDMETHODIMP accSelect(LONG flags_sel, VARIANT var_id) { return E_NOTIMPL; } + // Make an object take focus or extend the selection. + STDMETHODIMP accSelect(LONG flags_sel, VARIANT var_id); STDMETHODIMP get_accHelpTopic(BSTR* help_file, VARIANT var_id, @@ -110,77 +143,143 @@ class ATL_NO_VTABLE BrowserAccessibility STDMETHODIMP get_accSelection(VARIANT* selected); - // Deprecated functions, not implemented here. - STDMETHODIMP put_accName(VARIANT var_id, BSTR put_name) { return E_NOTIMPL; } - STDMETHODIMP put_accValue(VARIANT var_id, BSTR put_val) { return E_NOTIMPL; } + // Deprecated methods, not implemented. + STDMETHODIMP put_accName(VARIANT var_id, BSTR put_name) { + return E_NOTIMPL; + } + STDMETHODIMP put_accValue(VARIANT var_id, BSTR put_val) { + return E_NOTIMPL; + } - // Accessors/mutators. - HWND parent_hwnd() const { return parent_hwnd_;} + // + // IAccessible2 methods. + // - // Modify/retrieve the state (active/inactive) of this instance. - void set_instance_active(bool instance_active) { - instance_active_ = instance_active; - } - int instance_active() const { return instance_active_; } + // Returns role from a longer list of possible roles. + STDMETHODIMP role(LONG* role); - int routing_id() const { return routing_id_; } + // Returns the state bitmask from a larger set of possible states. + STDMETHODIMP get_states(AccessibleStates* states); - private: - // Creates a VARIANT that will reference the current accessibility - // object, not a child accessibility object. - VARIANT ChildSelfVariant() const { - VARIANT var; - V_VT(&var) = VT_I4; - V_I4(&var) = CHILDID_SELF; - return var; - } + // Get the unique ID of this object so that the client knows if it's + // been encountered previously. + STDMETHODIMP get_uniqueID(LONG* unique_id); - // Wrapper functions, calling through to singleton instance of - // BrowserAccessibilityManager. + // Get the window handle of the enclosing window. + STDMETHODIMP get_windowHandle(HWND* window_handle); - // Creates an instance of BrowserAccessibility, initializes it and sets the - // [iaccessible_id] and [parent_id]. - STDMETHODIMP CreateInstance(REFIID iid, - int iaccessible_id, - void** interface_ptr); + // Get this object's index in its parent object. + STDMETHODIMP get_indexInParent(LONG* index_in_parent); - // Composes and sends a message for requesting needed accessibility - // information. Unused LONG input parameters should be NULL, and the VARIANT - // an empty, valid instance. - bool RequestAccessibilityInfo(int iaccessible_func_id, - VARIANT var_id, - LONG input1, LONG input2); + // IAccessible2 methods not implemented. + STDMETHODIMP get_extendedRole(BSTR* extended_role) { + return E_NOTIMPL; + } + STDMETHODIMP get_nRelations(LONG* n_relations) { + return E_NOTIMPL; + } + STDMETHODIMP get_relation(LONG relation_index, + IAccessibleRelation** relation) { + return E_NOTIMPL; + } + STDMETHODIMP get_relations(LONG max_relations, + IAccessibleRelation** relations, + LONG *n_relations) { + return E_NOTIMPL; + } + STDMETHODIMP scrollTo(enum IA2ScrollType scroll_type) { + return E_NOTIMPL; + } + STDMETHODIMP scrollToPoint(enum IA2CoordinateType coordinate_type, + LONG x, + LONG y) { + return E_NOTIMPL; + } + STDMETHODIMP get_groupPosition(LONG* group_level, + LONG* similar_items_in_group, + LONG* position_in_group) { + return E_NOTIMPL; + } + STDMETHODIMP get_localizedExtendedRole(BSTR* localized_extended_role) { + return E_NOTIMPL; + } + STDMETHODIMP get_nExtendedStates(LONG* n_extended_states) { + return E_NOTIMPL; + } + STDMETHODIMP get_extendedStates(LONG max_extended_states, + BSTR** extended_states, + LONG* n_extended_states) { + return E_NOTIMPL; + } + STDMETHODIMP get_localizedExtendedStates(LONG max_localized_extended_states, + BSTR** localized_extended_states, + LONG* n_localized_extended_states) { + return E_NOTIMPL; + } + STDMETHODIMP get_locale(IA2Locale* locale) { + return E_NOTIMPL; + } + STDMETHODIMP get_attributes(BSTR* attributes) { + return E_NOTIMPL; + } + + // + // IServiceProvider methods. + // - // Accessors. - const WebAccessibility::OutParams& response(); + STDMETHODIMP QueryService(REFGUID guidService, REFIID riid, void** object); + + private: + // Many MSAA methods take a var_id parameter indicating that the operation + // should be performed on a particular child ID, rather than this object. + // This method tries to figure out the target object from |var_id| and + // returns a pointer to the target object if it exists, otherwise NULL. + // Does not return a new reference. + BrowserAccessibility* GetTargetFromChildID(const VARIANT& var_id); // Returns a conversion from the BrowserAccessibilityRole (as defined in // webkit/glue/webaccessibility.h) to an MSAA role. - long MSAARole(long browser_accessibility_role); + LONG MSAARole(LONG browser_accessibility_role); // Returns a conversion from the BrowserAccessibilityState (as defined in // webkit/glue/webaccessibility.h) to MSAA states set. - long MSAAState(long browser_accessibility_state); - - // Id to uniquely distinguish this instance in the render-side caching, - // mapping it to the correct IAccessible on that side. Initialized to -1. - int iaccessible_id_; - - // The unique ids of this IAccessible instance. Used to help - // BrowserAccessibilityManager instance retrieve the correct member - // variables for this process. - int routing_id_; - int process_id_; - - HWND parent_hwnd_; - - // The instance should only be active if there is a non-terminated - // RenderProcessHost associated with it. The BrowserAccessibilityManager keeps - // track of this state, and sets it to false to disable all calls into the - // renderer from this instance of BroweserAccessibility, and have all - // IAccessible functions return E_FAIL. + LONG MSAAState(LONG browser_accessibility_state); + + // The manager of this tree of accessibility objects; needed for + // global operations like focus tracking. + BrowserAccessibilityManager* manager_; + // The parent of this object, may be NULL if we're the root object. + BrowserAccessibility* parent_; + // The ID of this object; globally unique within the browser process. + LONG child_id_; + // The index of this within its parent object. + LONG index_in_parent_; + // The ID of this object in the renderer process. + int32 renderer_id_; + + // The children of this object. + std::vector<BrowserAccessibility*> children_; + + // Accessibility metadata from the renderer, used to respond to MSAA + // events. + string16 name_; + string16 value_; + string16 action_; + string16 description_; + string16 help_; + string16 shortcut_; + LONG role_; + LONG state_; + WebKit::WebRect location_; + + // COM objects are reference-counted. When we're done with this object + // and it's removed from our accessibility tree, a client may still be + // holding onto a pointer to this object, so we mark it as inactive + // so that calls to any of this object's methods immediately return + // failure. bool instance_active_; DISALLOW_COPY_AND_ASSIGN(BrowserAccessibility); }; + #endif // CHROME_BROWSER_BROWSER_ACCESSIBILITY_H_ diff --git a/chrome/browser/browser_accessibility_manager.cc b/chrome/browser/browser_accessibility_manager.cc index cd53e72..8e37719 100644 --- a/chrome/browser/browser_accessibility_manager.cc +++ b/chrome/browser/browser_accessibility_manager.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -8,161 +8,130 @@ #include "chrome/browser/browser_accessibility.h" #include "chrome/browser/renderer_host/render_process_host.h" #include "chrome/browser/renderer_host/render_view_host.h" -#include "chrome/common/notification_service.h" #include "chrome/common/render_messages.h" using webkit_glue::WebAccessibility; -// The time in ms after which we give up and return an error when processing an -// accessibility message and no response has been received from the renderer. -static const int kAccessibilityMessageTimeOut = 10000; - -// static -BrowserAccessibilityManager* BrowserAccessibilityManager::GetInstance() { - return Singleton<BrowserAccessibilityManager>::get(); +// Factory method to create an instance of BrowserAccessibility +BrowserAccessibility* BrowserAccessibilityFactory::Create() { + CComObject<BrowserAccessibility>* instance; + HRESULT hr = CComObject<BrowserAccessibility>::CreateInstance(&instance); + DCHECK(SUCCEEDED(hr)); + return instance->NewReference(); } -BrowserAccessibilityManager::BrowserAccessibilityManager() { - registrar_.Add(this, NotificationType::RENDERER_PROCESS_TERMINATED, - NotificationService::AllSources()); +// static +// Start child IDs at -1 and decrement each time, because clients use +// child IDs of 1, 2, 3, ... to access the children of an object by +// index, so we use negative IDs to clearly distinguish between indices +// and unique IDs. +LONG BrowserAccessibilityManager::next_child_id_ = -1; + +BrowserAccessibilityManager::BrowserAccessibilityManager( + HWND parent_hwnd, + const webkit_glue::WebAccessibility& src, + BrowserAccessibilityFactory* factory) + : parent_hwnd_(parent_hwnd), + factory_(factory) { + HRESULT hr = ::CreateStdAccessibleObject( + parent_hwnd_, OBJID_WINDOW, IID_IAccessible, + reinterpret_cast<void **>(&window_iaccessible_)); + DCHECK(SUCCEEDED(hr)); + root_ = CreateAccessibilityTree(NULL, src, 0); + if (!focus_) + focus_ = root_; } BrowserAccessibilityManager::~BrowserAccessibilityManager() { - // Clear hashmap. - render_process_host_map_.clear(); + // Clients could still hold references to some nodes of the tree, so + // calling Inactivate will make sure that as many nodes as possible are + // released now, and remaining nodes are marked as inactive so that + // calls to any methods on them will return E_FAIL; + root_->InactivateTree(); + root_->Release(); } -STDMETHODIMP BrowserAccessibilityManager::CreateAccessibilityInstance( - REFIID iid, int acc_obj_id, int routing_id, int process_id, - HWND parent_hwnd, void** interface_ptr) { - if (IID_IUnknown == iid || IID_IDispatch == iid || IID_IAccessible == iid) { - CComObject<BrowserAccessibility>* instance = NULL; - - HRESULT hr = CComObject<BrowserAccessibility>::CreateInstance(&instance); - DCHECK(SUCCEEDED(hr)); - - if (!instance) - return E_FAIL; - - ScopedComPtr<IAccessible> accessibility_instance(instance); - - // Set class member variables. - instance->Initialize(acc_obj_id, routing_id, process_id, parent_hwnd); - - // Retrieve the RenderViewHost connected to this request. - RenderViewHost* rvh = RenderViewHost::FromID(process_id, routing_id); - - // Update cache with RenderProcessHost/BrowserAccessibility pair. - if (rvh && rvh->process()) { - render_process_host_map_.insert(MapEntry(rvh->process()->id(), instance)); - } else { - // No RenderProcess active for this instance. - return E_FAIL; - } - - // All is well, assign the temp instance to the output pointer. - *interface_ptr = accessibility_instance.Detach(); - return S_OK; - } - // No supported interface found, return error. - *interface_ptr = NULL; - return E_NOINTERFACE; +BrowserAccessibility* BrowserAccessibilityManager::GetRoot() { + return root_; } -bool BrowserAccessibilityManager::RequestAccessibilityInfo( - WebAccessibility::InParams* in, int routing_id, int process_id) { - // Create and populate IPC message structure, for retrieval of accessibility - // information from the renderer. - WebAccessibility::InParams in_params; - in_params.object_id = in->object_id; - in_params.function_id = in->function_id; - in_params.child_id = in->child_id; - in_params.input_long1 = in->input_long1; - in_params.input_long2 = in->input_long2; - - // Retrieve the RenderViewHost connected to this request. - RenderViewHost* rvh = RenderViewHost::FromID(process_id, routing_id); - - // Send accessibility information retrieval message to the renderer. - bool success = false; - if (rvh && rvh->process() && rvh->process()->HasConnection()) { - IPC::SyncMessage* msg = - new ViewMsg_GetAccessibilityInfo(routing_id, in_params, &out_params_); - // Necessary for the send to keep the UI responsive. - msg->EnableMessagePumping(); - success = rvh->process()->SendWithTimeout(msg, - kAccessibilityMessageTimeOut); +BrowserAccessibility* BrowserAccessibilityManager::GetFromChildID( + LONG child_id) { + base::hash_map<LONG, BrowserAccessibility*>::iterator iter = + child_id_map_.find(child_id); + if (iter != child_id_map_.end()) { + return iter->second; + } else { + return NULL; } - return success; } -bool BrowserAccessibilityManager::ChangeAccessibilityFocus(int acc_obj_id, - int process_id, - int routing_id) { - BrowserAccessibility* browser_acc = - GetBrowserAccessibility(process_id, routing_id); - if (browser_acc) { - // Notify Access Technology that there was a change in keyboard focus. - ::NotifyWinEvent(EVENT_OBJECT_FOCUS, browser_acc->parent_hwnd(), - OBJID_CLIENT, static_cast<LONG>(acc_obj_id)); - return true; - } - return false; +IAccessible* BrowserAccessibilityManager::GetParentWindowIAccessible() { + return window_iaccessible_; } -bool BrowserAccessibilityManager::OnAccessibilityObjectStateChange( - int acc_obj_id, int process_id, int routing_id) { - BrowserAccessibility* browser_acc = - GetBrowserAccessibility(process_id, routing_id); - if (browser_acc) { - // Notify Access Technology that there was a change in state. - ::NotifyWinEvent(EVENT_OBJECT_STATECHANGE, browser_acc->parent_hwnd(), - OBJID_CLIENT, static_cast<LONG>(acc_obj_id)); - return true; - } - return false; +HWND BrowserAccessibilityManager::GetParentHWND() { + return parent_hwnd_; } -const WebAccessibility::OutParams& BrowserAccessibilityManager::response() { - return out_params_; +BrowserAccessibility* BrowserAccessibilityManager::GetFocus( + BrowserAccessibility* root) { + if (focus_ && (!root || focus_->IsDescendantOf(root))) + return focus_; + + return NULL; } -BrowserAccessibility* BrowserAccessibilityManager::GetBrowserAccessibility( - int process_id, int routing_id) { - // Retrieve the BrowserAccessibility connected to the requester's id. There - // could be multiple BrowserAccessibility connected to the given |process_id|, - // but they all have the same parent HWND, so using the first hit is fine. - RenderProcessHostMap::iterator it = - render_process_host_map_.lower_bound(process_id); +void BrowserAccessibilityManager::OnAccessibilityFocusChange(int renderer_id) { + base::hash_map<int, LONG>::iterator iter = + renderer_id_to_child_id_map_.find(renderer_id); + if (iter == renderer_id_to_child_id_map_.end()) + return; + + LONG child_id = iter->second; + base::hash_map<LONG, BrowserAccessibility*>::iterator uniq_iter = + child_id_map_.find(child_id); + if (uniq_iter != child_id_map_.end()) + focus_ = uniq_iter->second; + ::NotifyWinEvent(EVENT_OBJECT_FOCUS, parent_hwnd_, OBJID_CLIENT, child_id); +} - RenderProcessHostMap::iterator end_of_matching_objects = - render_process_host_map_.upper_bound(process_id); +void BrowserAccessibilityManager::OnAccessibilityObjectStateChange( + int renderer_id) { + base::hash_map<int, LONG>::iterator iter = + renderer_id_to_child_id_map_.find(renderer_id); + if (iter == renderer_id_to_child_id_map_.end()) + return; - for (; it != end_of_matching_objects; ++it) { - if (it->second && it->second->routing_id() == routing_id) - return it->second; - } - return NULL; + LONG child_id = iter->second; + ::NotifyWinEvent(EVENT_OBJECT_FOCUS, parent_hwnd_, OBJID_CLIENT, child_id); } -void BrowserAccessibilityManager::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - DCHECK(type == NotificationType::RENDERER_PROCESS_TERMINATED); - RenderProcessHost* rph = Source<RenderProcessHost>(source).ptr(); - DCHECK(rph); - - RenderProcessHostMap::iterator it = - render_process_host_map_.lower_bound(rph->id()); - - RenderProcessHostMap::iterator end_of_matching_objects = - render_process_host_map_.upper_bound(rph->id()); - - for (; it != end_of_matching_objects; ++it) { - if (it->second) { - // Set all matching BrowserAccessibility instances to inactive state. - // TODO(klink): Do more active memory cleanup as well. - it->second->set_instance_active(false); - } +BrowserAccessibility* BrowserAccessibilityManager::CreateAccessibilityTree( + BrowserAccessibility* parent, + const webkit_glue::WebAccessibility& src, + int index_in_parent) { + BrowserAccessibility* instance = factory_->Create(); + + // Get the next child ID, and wrap around when we get near the end + // of a 32-bit integer range. It's okay to wrap around; we just want + // to avoid it as long as possible because clients may cache the ID of + // an object for a while to determine if they've seen it before. + LONG child_id = next_child_id_; + next_child_id_--; + if (next_child_id_ == -2000000000) + next_child_id_ = -1; + + instance->Initialize(this, parent, child_id, index_in_parent, src); + child_id_map_[child_id] = instance; + renderer_id_to_child_id_map_[src.id] = child_id; + if ((src.state >> WebAccessibility::STATE_FOCUSED) & 1) + focus_ = instance; + for (int i = 0; i < static_cast<int>(src.children.size()); ++i) { + BrowserAccessibility* child = CreateAccessibilityTree( + instance, src.children[i], i); + instance->AddChild(child); } + + return instance; } diff --git a/chrome/browser/browser_accessibility_manager.h b/chrome/browser/browser_accessibility_manager.h index 4850242..1db8100 100644 --- a/chrome/browser/browser_accessibility_manager.h +++ b/chrome/browser/browser_accessibility_manager.h @@ -1,104 +1,102 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_BROWSER_BROWSER_ACCESSIBILITY_MANAGER_H_ #define CHROME_BROWSER_BROWSER_ACCESSIBILITY_MANAGER_H_ +#include <atlbase.h> +#include <atlcom.h> +#include <oleacc.h> + #include <map> -#include "base/singleton.h" -#include "chrome/common/notification_registrar.h" +#include "base/hash_tables.h" +#include "base/scoped_comptr_win.h" +#include "base/scoped_ptr.h" #include "webkit/glue/webaccessibility.h" class BrowserAccessibility; class RenderProcessHost; class RenderWidgetHost; -using webkit_glue::WebAccessibility; - -//////////////////////////////////////////////////////////////////////////////// -// -// BrowserAccessibilityManager -// -// Used to manage instance creation and memory handling for browser side -// accessibility. A singleton class. It implements NotificationObserver to -// ensure that a termination of a renderer process gets propagated to the -// active BrowserAccessibility instances calling into it. Each such instance -// will upon such an event be set to an inactive state, failing calls from the -// assistive technology gracefully. -//////////////////////////////////////////////////////////////////////////////// -class BrowserAccessibilityManager : public NotificationObserver { +class BrowserAccessibilityFactory { + public: + virtual ~BrowserAccessibilityFactory() {} + + // Create an instance of BrowserAccessibility and return a new + // reference to it. + virtual BrowserAccessibility* Create(); +}; + +// Manages a tree of BrowserAccessibility objects. +class BrowserAccessibilityManager { public: - // Gets the singleton BrowserAccessibilityManager object. The first time this - // method is called, a CacheManagerHost object is constructed and returned. - // Subsequent calls will return the same object. - static BrowserAccessibilityManager* GetInstance(); - - // Creates an instance of BrowserAccessibility, initializes it and sets the - // |acc_obj_id|, which is used for IPC communication, and |instance_id|, - // which is used to identify the mapping between accessibility instance and - // RenderProcess. - STDMETHODIMP CreateAccessibilityInstance(REFIID iid, - int acc_obj_id, - int routing_id, - int process_id, - HWND parent_hwnd, - void** interface_ptr); - - // Composes and sends a message for requesting needed accessibility - // information. - bool RequestAccessibilityInfo(WebAccessibility::InParams* in, - int routing_id, - int process_id); - - // Notifies assistive technology that renderer focus changed, through the - // platform-specific channels. - bool ChangeAccessibilityFocus(int acc_obj_id, int process_id, int routing_id); - - // Notifies assistive technology that an object's state changed, through the - // platform-specific channels. - bool OnAccessibilityObjectStateChange(int acc_obj_id, - int process_id, - int routing_id); - - // Wrapper function, for cleaner code. - const WebAccessibility::OutParams& response(); - - // NotificationObserver implementation. - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - - protected: - // This class is a singleton. Do not instantiate directly. - BrowserAccessibilityManager(); - friend struct DefaultSingletonTraits<BrowserAccessibilityManager>; - - ~BrowserAccessibilityManager(); + BrowserAccessibilityManager( + HWND parent_hwnd, + const webkit_glue::WebAccessibility& src, + BrowserAccessibilityFactory* factory = new BrowserAccessibilityFactory()); + + virtual ~BrowserAccessibilityManager(); + + // Return a pointer to the root of the tree, does not make a new reference. + BrowserAccessibility* GetRoot(); + + // Return a pointer to the object corresponding to the given child_id, + // does not make a new reference. + BrowserAccessibility* GetFromChildID(LONG child_id); + + // Get a the default IAccessible for the parent window, does not make a + // new reference. + IAccessible* GetParentWindowIAccessible(); + + // Get the parent window. + HWND GetParentHWND(); + + // Return the object that has focus, if it's a descandant of the + // given root (inclusive). Does not make a new reference. + BrowserAccessibility* GetFocus(BrowserAccessibility* root); + + // Called when the renderer process has notified us of a focus or state + // change. Send a notification to MSAA clients of the change. + void OnAccessibilityFocusChange(int acc_obj_id); + void OnAccessibilityObjectStateChange(int acc_obj_id); private: - // Retrieves the BrowserAccessibility instance connected to the - // RenderProcessHost identified by the process/routing id pair. - BrowserAccessibility* GetBrowserAccessibility(int process_id, int routing_id); + // Recursively build a tree of BrowserAccessibility objects from + // the WebAccessibility tree received from the renderer process. + BrowserAccessibility* CreateAccessibilityTree( + BrowserAccessibility* parent, + const webkit_glue::WebAccessibility& src, + int index_in_parent); - // Multi-map from process id (key) to active BrowserAccessibility instances - // for that RenderProcessHost. - typedef std::multimap<int, BrowserAccessibility*> RenderProcessHostMap; - typedef std::pair<int, BrowserAccessibility*> MapEntry; + // The parent window. + HWND parent_hwnd_; - NotificationRegistrar registrar_; + // Factory to create BrowserAccessibility objects (for dependency injection). + scoped_ptr<BrowserAccessibilityFactory> factory_; - // Mapping to track which RenderProcessHosts ids are active. If a - // RenderProcessHost is found to be terminated, its id (key) should be removed - // from this mapping, and the connected BrowserAccessibility ids/instances - // invalidated. - RenderProcessHostMap render_process_host_map_; + // A default IAccessible instance for the parent window. + ScopedComPtr<IAccessible> window_iaccessible_; - // Structure passed by reference to hold response parameters from the - // renderer. - WebAccessibility::OutParams out_params_; + // The root of the tree of IAccessible objects and the element that + // currently has focus, if any. + BrowserAccessibility* root_; + BrowserAccessibility* focus_; + + // A mapping from the IDs of objects in the renderer, to the child IDs + // we use internally here. + base::hash_map<int, LONG> renderer_id_to_child_id_map_; + + // A mapping from child IDs to BrowserAccessibility objects. + base::hash_map<LONG, BrowserAccessibility*> child_id_map_; + + // The next child ID to use; static so that they're global to the process. + // Screen readers cache these IDs to see if they've seen the same object + // before so we should avoid reusing them within the same project. + static LONG next_child_id_; DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityManager); }; + #endif // CHROME_BROWSER_BROWSER_ACCESSIBILITY_MANAGER_H_ diff --git a/chrome/browser/browser_accessibility_unittest.cc b/chrome/browser/browser_accessibility_unittest.cc new file mode 100644 index 0000000..f2429ea --- /dev/null +++ b/chrome/browser/browser_accessibility_unittest.cc @@ -0,0 +1,109 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/scoped_ptr.h" +#include "chrome/browser/browser_accessibility_manager.h" +#include "chrome/browser/browser_accessibility.h" +#include "testing/gtest/include/gtest/gtest.h" + +using webkit_glue::WebAccessibility; + +// Subclass of BrowserAccessibility that counts the number of instances. +class CountedBrowserAccessibility : public BrowserAccessibility { + public: + CountedBrowserAccessibility() { global_obj_count_++; } + virtual ~CountedBrowserAccessibility() { global_obj_count_--; } + static int global_obj_count_; +}; + +int CountedBrowserAccessibility::global_obj_count_ = 0; + +// Factory that creates a CountedBrowserAccessibility. +class CountedBrowserAccessibilityFactory : public BrowserAccessibilityFactory { + public: + virtual ~CountedBrowserAccessibilityFactory() {} + virtual BrowserAccessibility* Create() { + CComObject<CountedBrowserAccessibility>* instance; + HRESULT hr = CComObject<CountedBrowserAccessibility>::CreateInstance( + &instance); + DCHECK(SUCCEEDED(hr)); + return instance->NewReference(); + } +}; + +// Test that BrowserAccessibilityManager correctly releases the tree of +// BrowserAccessibility instances upon delete. +TEST(BrowserAccessibilityTest, TestNoLeaks) { + // ATL needs a pointer to a COM module. + CComModule module; + _pAtlModule = &module; + // Make sure COM is initialized for this thread; it's safe to call twice. + ::CoInitialize(NULL); + + // Create WebAccessibility objects for a simple document tree, + // representing the accessibility information used to initialize + // BrowserAccessibilityManager. + WebAccessibility button; + button.id = 2; + button.name = L"Button"; + button.role = WebAccessibility::ROLE_PUSHBUTTON; + button.state = 0; + + WebAccessibility checkbox; + checkbox.id = 3; + checkbox.name = L"Checkbox"; + checkbox.role = WebAccessibility::ROLE_CHECKBUTTON; + checkbox.state = 0; + + WebAccessibility root; + root.id = 1; + root.name = L"Document"; + root.role = WebAccessibility::ROLE_DOCUMENT; + root.state = 0; + root.children.push_back(button); + root.children.push_back(checkbox); + + // Construct a BrowserAccessibilityManager with this WebAccessibility tree + // and a factory for an instance-counting BrowserAccessibility, and ensure + // that exactly 3 instances were created. Note that the manager takes + // ownership of the factory. + CountedBrowserAccessibility::global_obj_count_ = 0; + BrowserAccessibilityManager* manager = + new BrowserAccessibilityManager( + GetDesktopWindow(), root, new CountedBrowserAccessibilityFactory()); + ASSERT_EQ(3, CountedBrowserAccessibility::global_obj_count_); + + // Delete the manager and test that all 3 instances are deleted. + delete manager; + ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_); + + // Construct a manager again, and this time use the IAccessible interface + // to get new references to two of the three nodes in the tree. + manager = new BrowserAccessibilityManager( + GetDesktopWindow(), root, new CountedBrowserAccessibilityFactory()); + ASSERT_EQ(3, CountedBrowserAccessibility::global_obj_count_); + BrowserAccessibility* root_accessible = manager->GetRoot(); + IDispatch* root_iaccessible = NULL; + IDispatch* child1_iaccessible = NULL; + VARIANT var_child; + var_child.vt = VT_I4; + var_child.lVal = CHILDID_SELF; + HRESULT hr = root_accessible->get_accChild(var_child, &root_iaccessible); + ASSERT_EQ(S_OK, hr); + var_child.lVal = 1; + hr = root_accessible->get_accChild(var_child, &child1_iaccessible); + ASSERT_EQ(S_OK, hr); + + // Now delete the manager, and only one of the three nodes in the tree + // should be released. + delete manager; + ASSERT_EQ(2, CountedBrowserAccessibility::global_obj_count_); + + // Release each of our references and make sure that each one results in + // the instance being deleted as its reference count hits zero. + root_iaccessible->Release(); + ASSERT_EQ(1, CountedBrowserAccessibility::global_obj_count_); + child1_iaccessible->Release(); + ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_); +} diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index ab436ec..a763388 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -676,6 +676,10 @@ bool RenderViewHost::SuddenTerminationAllowed() const { return sudden_termination_allowed_ || process()->sudden_termination_allowed(); } +void RenderViewHost::RequestAccessibilityTree() { + Send(new ViewMsg_GetAccessibilityTree(routing_id())); +} + /////////////////////////////////////////////////////////////////////////////// // RenderViewHost, IPC message handlers: @@ -828,6 +832,7 @@ void RenderViewHost::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER(ViewHostMsg_PageContents, OnPageContents) IPC_MESSAGE_HANDLER(ViewHostMsg_PageTranslated, OnPageTranslated) IPC_MESSAGE_HANDLER(ViewHostMsg_ContentBlocked, OnContentBlocked) + IPC_MESSAGE_HANDLER(ViewHostMsg_AccessibilityTree, OnAccessibilityTree) // Have the super handle all other messages. IPC_MESSAGE_UNHANDLED(RenderWidgetHost::OnMessageReceived(msg)) IPC_END_MESSAGE_MAP_EX() @@ -1826,21 +1831,16 @@ void RenderViewHost::OnExtensionPostMessage( } void RenderViewHost::OnAccessibilityFocusChange(int acc_obj_id) { -#if defined(OS_WIN) - BrowserAccessibilityManager::GetInstance()->ChangeAccessibilityFocus( - acc_obj_id, process()->id(), routing_id()); -#else - // TODO(port): accessibility not yet implemented. See http://crbug.com/8288. -#endif + view()->OnAccessibilityFocusChange(acc_obj_id); } void RenderViewHost::OnAccessibilityObjectStateChange(int acc_obj_id) { -#if defined(OS_WIN) - BrowserAccessibilityManager::GetInstance()->OnAccessibilityObjectStateChange( - acc_obj_id, process()->id(), routing_id()); -#else - // TODO(port): accessibility not yet implemented. See http://crbug.com/8288. -#endif + view()->OnAccessibilityObjectStateChange(acc_obj_id); +} + +void RenderViewHost::OnAccessibilityTree( + const webkit_glue::WebAccessibility& tree) { + view()->UpdateAccessibilityTree(tree); } void RenderViewHost::OnCSSInserted() { diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h index 0fffedd..c5bec3c 100644 --- a/chrome/browser/renderer_host/render_view_host.h +++ b/chrome/browser/renderer_host/render_view_host.h @@ -22,6 +22,7 @@ #include "third_party/WebKit/WebKit/chromium/public/WebPopupType.h" #include "third_party/WebKit/WebKit/chromium/public/WebTextDirection.h" #include "webkit/glue/password_form_dom_manager.h" +#include "webkit/glue/webaccessibility.h" #include "webkit/glue/window_open_disposition.h" class FilePath; @@ -464,6 +465,9 @@ class RenderViewHost : public RenderWidgetHost { // changed. void EnablePreferredSizeChangedMode(); + // Requests a snapshot of an accessible DOM tree from the renderer. + void RequestAccessibilityTree(); + protected: // RenderWidgetHost protected overrides. virtual bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event, @@ -625,6 +629,7 @@ class RenderViewHost : public RenderWidgetHost { void OnExtensionPostMessage(int port_id, const std::string& message); void OnAccessibilityFocusChange(int acc_obj_id); void OnAccessibilityObjectStateChange(int acc_obj_id); + void OnAccessibilityTree(const webkit_glue::WebAccessibility& tree); void OnCSSInserted(); void OnPageContents(const GURL& url, int32 page_id, diff --git a/chrome/browser/renderer_host/render_widget_host_view.h b/chrome/browser/renderer_host/render_widget_host_view.h index 6e5e28e..3a285c1 100644 --- a/chrome/browser/renderer_host/render_widget_host_view.h +++ b/chrome/browser/renderer_host/render_widget_host_view.h @@ -15,6 +15,7 @@ #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/WebKit/WebKit/chromium/public/WebPopupType.h" #include "webkit/glue/plugins/webplugin.h" +#include "webkit/glue/webaccessibility.h" namespace gfx { class Rect; @@ -235,6 +236,11 @@ class RenderWidgetHostView { // widget associated with this RenderWidgetHostView. virtual bool ContainsNativeView(gfx::NativeView native_view) const = 0; + virtual void UpdateAccessibilityTree( + const webkit_glue::WebAccessibility& tree) { } + virtual void OnAccessibilityFocusChange(int acc_obj_id) { } + virtual void OnAccessibilityObjectStateChange(int acc_obj_id) { } + protected: // Interface class only, do not construct. RenderWidgetHostView() : popup_type_(WebKit::WebPopupTypeNone) {} diff --git a/chrome/browser/renderer_host/render_widget_host_view_win.cc b/chrome/browser/renderer_host/render_widget_host_view_win.cc index 3fede8e..5696df1 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_win.cc +++ b/chrome/browser/renderer_host/render_widget_host_view_win.cc @@ -13,6 +13,7 @@ #include "base/process_util.h" #include "base/thread.h" #include "base/win_util.h" +#include "chrome/browser/browser_accessibility.h" #include "chrome/browser/browser_accessibility_manager.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_trial.h" @@ -26,6 +27,7 @@ #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/native_web_keyboard_event.h" +#include "chrome/common/notification_service.h" #include "chrome/common/plugin_messages.h" #include "chrome/common/render_messages.h" #include "gfx/canvas.h" @@ -285,6 +287,9 @@ RenderWidgetHostViewWin::RenderWidgetHostViewWin(RenderWidgetHost* widget) renderer_accessible_ = CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableRendererAccessibility); + registrar_.Add(this, + NotificationType::RENDERER_PROCESS_TERMINATED, + NotificationService::AllSources()); } RenderWidgetHostViewWin::~RenderWidgetHostViewWin() { @@ -1472,40 +1477,64 @@ LRESULT RenderWidgetHostViewWin::OnMouseActivate(UINT, WPARAM, LPARAM, return MA_ACTIVATE; } +void RenderWidgetHostViewWin::UpdateAccessibilityTree( + const webkit_glue::WebAccessibility& tree) { + browser_accessibility_manager_.reset( + new BrowserAccessibilityManager(m_hWnd, tree)); +} + +void RenderWidgetHostViewWin::OnAccessibilityFocusChange(int acc_obj_id) { + if (browser_accessibility_manager_.get()) { + browser_accessibility_manager_->OnAccessibilityFocusChange(acc_obj_id); + } +} + +void RenderWidgetHostViewWin::OnAccessibilityObjectStateChange(int acc_obj_id) { + if (browser_accessibility_manager_.get()) { + browser_accessibility_manager_->OnAccessibilityObjectStateChange( + acc_obj_id); + } +} + +void RenderWidgetHostViewWin::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + DCHECK(type == NotificationType::RENDERER_PROCESS_TERMINATED); + + // Get the RenderProcessHost that posted this notification, and exit + // if it's not the one associated with this host view. + RenderProcessHost* render_process_host = + Source<RenderProcessHost>(source).ptr(); + DCHECK(render_process_host); + if (!render_widget_host_ || + render_process_host != render_widget_host_->process()) + return; + + // If it was our RenderProcessHost that posted the notification, + // clear the BrowserAccessibilityManager, because the renderer is + // dead and any accessibility information we have is now stale. + browser_accessibility_manager_.reset(NULL); +} + LRESULT RenderWidgetHostViewWin::OnGetObject(UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled) { - LRESULT reference_result = static_cast<LRESULT>(0L); - // TODO(jcampan): http://b/issue?id=1432077 Disabling accessibility in the + // TODO(dmazzoni): http://crbug.com/25564 Disabling accessibility in the // renderer is a temporary work-around until that bug is fixed. - if (!renderer_accessible_) - return reference_result; - - // Accessibility readers will send an OBJID_CLIENT message. - if (OBJID_CLIENT == lparam) { - // If our MSAA DOM root is already created, reuse that pointer. Otherwise, - // create a new one. - if (!browser_accessibility_root_) { - // Create a new instance of IAccessible. Root id is 1000, to avoid - // conflicts with the ids used by MSAA. - BrowserAccessibilityManager::GetInstance()->CreateAccessibilityInstance( - IID_IAccessible, 1000, - render_widget_host_->routing_id(), - render_widget_host_->process()->id(), - m_hWnd, - reinterpret_cast<void **>(browser_accessibility_root_.Receive())); - - if (!browser_accessibility_root_) { - // No valid root found, return with failure. - return static_cast<LRESULT>(0L); - } - } + if (!renderer_accessible_) { + handled = false; + return static_cast<LRESULT>(0L); + } - // Create a reference to BrowserAccessibility which MSAA will marshall to - // the client. - reference_result = LresultFromObject(IID_IAccessible, wparam, - static_cast<IAccessible*>(browser_accessibility_root_)); + if (lparam == OBJID_CLIENT && browser_accessibility_manager_.get()) { + BrowserAccessibility* root = browser_accessibility_manager_->GetRoot(); + if (root) { + return LresultFromObject(IID_IAccessible, wparam, + static_cast<IAccessible*>(root->NewReference())); + } } - return reference_result; + + handled = false; + return static_cast<LRESULT>(0L); } void RenderWidgetHostViewWin::OnFinalMessage(HWND window) { diff --git a/chrome/browser/renderer_host/render_widget_host_view_win.h b/chrome/browser/renderer_host/render_widget_host_view_win.h index 09686ad..23716b9 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_win.h +++ b/chrome/browser/renderer_host/render_widget_host_view_win.h @@ -13,8 +13,10 @@ #include "base/scoped_comptr_win.h" #include "base/scoped_ptr.h" #include "base/task.h" +#include "chrome/browser/browser_accessibility_manager.h" #include "chrome/browser/ime_input.h" #include "chrome/browser/renderer_host/render_widget_host_view.h" +#include "chrome/common/notification_registrar.h" #include "webkit/glue/webcursor.h" namespace gfx { @@ -55,7 +57,8 @@ class RenderWidgetHostViewWin : public CWindowImpl<RenderWidgetHostViewWin, CWindow, RenderWidgetHostHWNDTraits>, - public RenderWidgetHostView { + public RenderWidgetHostView, + public NotificationObserver { public: // The view will associate itself with the given widget. explicit RenderWidgetHostViewWin(RenderWidgetHost* widget); @@ -141,6 +144,15 @@ class RenderWidgetHostViewWin virtual void SetBackground(const SkBitmap& background); virtual bool ContainsNativeView(gfx::NativeView native_view) const; virtual void SetVisuallyDeemphasized(bool deemphasized); + virtual void UpdateAccessibilityTree( + const webkit_glue::WebAccessibility& tree); + virtual void OnAccessibilityFocusChange(int acc_obj_id); + virtual void OnAccessibilityObjectStateChange(int acc_obj_id); + + // Implementation of NotificationObserver: + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); protected: // Windows Message Handlers @@ -296,7 +308,7 @@ class RenderWidgetHostViewWin // Instance of accessibility information for the root of the MSAA // tree representation of the WebKit render tree. - ScopedComPtr<IAccessible> browser_accessibility_root_; + scoped_ptr<BrowserAccessibilityManager> browser_accessibility_manager_; // The time at which this view started displaying white pixels as a result of // not having anything to paint (empty backing store from renderer). This @@ -315,6 +327,9 @@ class RenderWidgetHostViewWin // whenever we paint. bool visually_deemphasized_; + // Registrar so we can listen to RENDERER_PROCESS_TERMINATED events. + NotificationRegistrar registrar_; + DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewWin); }; diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index 1601823..1b5dcca 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -290,7 +290,8 @@ TabContents::TabContents(Profile* profile, is_showing_before_unload_dialog_(false), renderer_preferences_(), opener_dom_ui_type_(DOMUIFactory::kNoDOMUI), - language_state_(&controller_) { + language_state_(&controller_), + requested_accessibility_tree_(false) { ClearBlockedContentSettings(); renderer_preferences_util::UpdateFromSystemSettings( &renderer_preferences_, profile); @@ -348,6 +349,10 @@ TabContents::TabContents(Profile* profile, // Set-up the showing of the omnibox search infobar if applicable. if (OmniboxSearchHint::IsEnabled(profile)) omnibox_search_hint_.reset(new OmniboxSearchHint(this)); + + renderer_accessible_ = + CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableRendererAccessibility); } TabContents::~TabContents() { @@ -2126,6 +2131,10 @@ void TabContents::DidFailProvisionalLoadWithError( void TabContents::DocumentLoadedInFrame() { controller_.DocumentLoadedInFrame(); + if (renderer_accessible_ && !requested_accessibility_tree_) { + render_view_host()->RequestAccessibilityTree(); + requested_accessibility_tree_ = true; + } } void TabContents::OnContentBlocked(ContentSettingsType type) { @@ -2295,6 +2304,8 @@ void TabContents::DidNavigate(RenderViewHost* rvh, const ViewHostMsg_FrameNavigate_Params& params) { int extra_invalidate_flags = 0; + requested_accessibility_tree_ = false; + if (PageTransition::IsMainFrame(params.transition)) { bool was_bookmark_bar_visible = ShouldShowBookmarkBar(); bool was_extension_shelf_visible = IsExtensionShelfAlwaysVisible(); diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h index 68a8602..92a3223 100644 --- a/chrome/browser/tab_contents/tab_contents.h +++ b/chrome/browser/tab_contents/tab_contents.h @@ -1265,6 +1265,15 @@ class TabContents : public PageNavigator, // Maps each frame on this page to its geolocation content settings. GeolocationContentSettings geolocation_content_settings_; + // Whether the renderer is made accessible. + // TODO(dmazzoni): http://crbug.com/25564 This is a temporary work-around + // until that bug is fixed. + bool renderer_accessible_; + + // Keep track of if we've already requested the accessibility tree so + // we don't do it more than once. + bool requested_accessibility_tree_; + // --------------------------------------------------------------------------- DISALLOW_COPY_AND_ASSIGN(TabContents); diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 8f9c7c4..71de080 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -2785,6 +2785,7 @@ 'dependencies': [ '../gears/gears.gyp:gears', '../google_update/google_update.gyp:google_update', + '../third_party/iaccessible2/iaccessible2.gyp:iaccessible2', '../views/views.gyp:views', '<(allocator_target)', ], diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index dd470c4..1790467 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -594,6 +594,7 @@ 'browser/bookmarks/bookmark_model_test_utils.h', 'browser/bookmarks/bookmark_model_unittest.cc', 'browser/bookmarks/bookmark_utils_unittest.cc', + 'browser/browser_accessibility_unittest.cc', 'browser/browser_commands_unittest.cc', 'browser/browser_theme_pack_unittest.cc', 'browser/browser_theme_provider_unittest.cc', @@ -985,6 +986,7 @@ 'common/notification_service_unittest.cc', 'common/process_watcher_unittest.cc', 'common/property_bag_unittest.cc', + 'common/render_messages_unittest.cc', 'common/resource_dispatcher_unittest.cc', 'common/sandbox_mac_unittest.mm', 'common/thumbnail_score_unittest.cc', @@ -1134,6 +1136,7 @@ 'dependencies': [ 'chrome_dll_version', 'installer/installer.gyp:installer_util_strings', + '../third_party/iaccessible2/iaccessible2.gyp:iaccessible2', 'test_chrome_plugin', # run time dependency '<(allocator_target)', ], @@ -1185,6 +1188,7 @@ 'sources!': [ 'browser/bookmarks/bookmark_codec_unittest.cc', 'browser/bookmarks/bookmark_drag_data_unittest.cc', + 'browser/browser_accessibility_unittest.cc', 'browser/browser_unittest.cc', 'browser/chrome_plugin_unittest.cc', 'browser/extensions/extension_process_manager_unittest.cc', diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h index 3770fe2..7f6ce16 100644 --- a/chrome/common/render_messages.h +++ b/chrome/common/render_messages.h @@ -711,80 +711,6 @@ struct ParamTraits<FilterPolicy::Type> { }; template <> -struct ParamTraits<webkit_glue::WebAccessibility::InParams> { - typedef webkit_glue::WebAccessibility::InParams param_type; - static void Write(Message* m, const param_type& p) { - WriteParam(m, p.object_id); - WriteParam(m, p.function_id); - WriteParam(m, p.child_id); - WriteParam(m, p.input_long1); - WriteParam(m, p.input_long2); - } - static bool Read(const Message* m, void** iter, param_type* p) { - return - ReadParam(m, iter, &p->object_id) && - ReadParam(m, iter, &p->function_id) && - ReadParam(m, iter, &p->child_id) && - ReadParam(m, iter, &p->input_long1) && - ReadParam(m, iter, &p->input_long2); - } - static void Log(const param_type& p, std::wstring* l) { - l->append(L"("); - LogParam(p.object_id, l); - l->append(L", "); - LogParam(p.function_id, l); - l->append(L", "); - LogParam(p.child_id, l); - l->append(L", "); - LogParam(p.input_long1, l); - l->append(L", "); - LogParam(p.input_long2, l); - l->append(L")"); - } -}; - -template <> -struct ParamTraits<webkit_glue::WebAccessibility::OutParams> { - typedef webkit_glue::WebAccessibility::OutParams param_type; - static void Write(Message* m, const param_type& p) { - WriteParam(m, p.object_id); - WriteParam(m, p.output_long1); - WriteParam(m, p.output_long2); - WriteParam(m, p.output_long3); - WriteParam(m, p.output_long4); - WriteParam(m, p.output_string); - WriteParam(m, p.return_code); - } - static bool Read(const Message* m, void** iter, param_type* p) { - return - ReadParam(m, iter, &p->object_id) && - ReadParam(m, iter, &p->output_long1) && - ReadParam(m, iter, &p->output_long2) && - ReadParam(m, iter, &p->output_long3) && - ReadParam(m, iter, &p->output_long4) && - ReadParam(m, iter, &p->output_string) && - ReadParam(m, iter, &p->return_code); - } - static void Log(const param_type& p, std::wstring* l) { - l->append(L"("); - LogParam(p.object_id, l); - l->append(L", "); - LogParam(p.output_long1, l); - l->append(L", "); - LogParam(p.output_long2, l); - l->append(L", "); - LogParam(p.output_long3, l); - l->append(L", "); - LogParam(p.output_long4, l); - l->append(L", "); - LogParam(p.output_string, l); - l->append(L", "); - LogParam(p.return_code, l); - l->append(L")"); - } -}; - -template <> struct ParamTraits<ViewHostMsg_ImeControl> { typedef ViewHostMsg_ImeControl param_type; static void Write(Message* m, const param_type& p) { @@ -2668,8 +2594,73 @@ struct ParamTraits<WindowContainerType> { } }; -} // namespace IPC +template <> +struct ParamTraits<webkit_glue::WebAccessibility> { + typedef webkit_glue::WebAccessibility param_type; + static void Write(Message* m, const param_type& p) { + WriteParam(m, p.id); + WriteParam(m, p.name); + WriteParam(m, p.value); + WriteParam(m, p.action); + WriteParam(m, p.description); + WriteParam(m, p.help); + WriteParam(m, p.shortcut); + WriteParam(m, static_cast<int>(p.role)); + WriteParam(m, static_cast<int>(p.state)); + WriteParam(m, p.location); + WriteParam(m, p.children); + } + static bool Read(const Message* m, void** iter, param_type* p) { + bool ret = ReadParam(m, iter, &p->id); + ret = ret && ReadParam(m, iter, &p->name); + ret = ret && ReadParam(m, iter, &p->value); + ret = ret && ReadParam(m, iter, &p->action); + ret = ret && ReadParam(m, iter, &p->description); + ret = ret && ReadParam(m, iter, &p->help); + ret = ret && ReadParam(m, iter, &p->shortcut); + int role = -1; + ret = ret && ReadParam(m, iter, &role); + if (role >= webkit_glue::WebAccessibility::ROLE_NONE && + role < webkit_glue::WebAccessibility::NUM_ROLES) { + p->role = static_cast<webkit_glue::WebAccessibility::Role>(role); + } else { + p->role = webkit_glue::WebAccessibility::ROLE_NONE; + } + int state = 0; + ret = ret && ReadParam(m, iter, &state); + p->state = static_cast<webkit_glue::WebAccessibility::State>(state); + ret = ret && ReadParam(m, iter, &p->location); + ret = ret && ReadParam(m, iter, &p->children); + return ret; + } + static void Log(const param_type& p, std::wstring* l) { + l->append(L"("); + LogParam(p.id, l); + l->append(L", "); + LogParam(p.name, l); + l->append(L", "); + LogParam(p.value, l); + l->append(L", "); + LogParam(p.action, l); + l->append(L", "); + LogParam(p.description, l); + l->append(L", "); + LogParam(p.help, l); + l->append(L", "); + LogParam(p.shortcut, l); + l->append(L", "); + LogParam(static_cast<int>(p.role), l); + l->append(L", "); + LogParam(static_cast<int>(p.state), l); + l->append(L", "); + LogParam(p.location, l); + l->append(L", "); + LogParam(p.children, l); + l->append(L")"); + } +}; +} // namespace IPC #define MESSAGES_INTERNAL_FILE "chrome/common/render_messages_internal.h" #include "ipc/ipc_message_macros.h" diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index 763715a..076aab4 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -512,20 +512,6 @@ IPC_BEGIN_MESSAGES(View) // Used to instruct the RenderView to go into "view source" mode. IPC_MESSAGE_ROUTED0(ViewMsg_EnableViewSourceMode) - // Retreive information from the MSAA DOM subtree, for accessibility purposes. - IPC_SYNC_MESSAGE_ROUTED1_1(ViewMsg_GetAccessibilityInfo, - webkit_glue::WebAccessibility::InParams - /* input parameters */, - webkit_glue::WebAccessibility::OutParams - /* output parameters */) - - // Requests the renderer to clear cashed accessibility information. Takes an - // id to clear a specific hashmap entry, and a bool; true clears all, false - // does not. - IPC_MESSAGE_ROUTED2(ViewMsg_ClearAccessibilityInfo, - int /* accessibility object id */, - bool /* clear_all */) - // Get all savable resource links from current webpage, include main // frame and sub-frame. IPC_MESSAGE_ROUTED1(ViewMsg_GetAllSavableResourceLinksForCurrentPage, @@ -943,6 +929,9 @@ IPC_BEGIN_MESSAGES(View) // Notification that the list of extensions with web extents has been updated. IPC_MESSAGE_CONTROL1(ViewMsg_ExtensionExtentsUpdated, ViewMsg_ExtensionExtentsUpdated_Params) + + // Request a tree of Accessibility data from the render process. + IPC_MESSAGE_ROUTED0(ViewMsg_GetAccessibilityTree) IPC_END_MESSAGES(View) @@ -2344,4 +2333,9 @@ IPC_BEGIN_MESSAGES(ViewHost) int /* render_view_id */, int /* bridge_id */) + // Send the tree of accessibility data to the browser, where it's cached + // in order to respond to OS accessibility queries immediately. + IPC_MESSAGE_ROUTED1(ViewHostMsg_AccessibilityTree, + webkit_glue::WebAccessibility) + IPC_END_MESSAGES(ViewHost) diff --git a/chrome/common/render_messages_unittest.cc b/chrome/common/render_messages_unittest.cc new file mode 100644 index 0000000..0dc3be8 --- /dev/null +++ b/chrome/common/render_messages_unittest.cc @@ -0,0 +1,96 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/scoped_ptr.h" +#include "base/string16.h" +#include "base/values.h" +#include "chrome/common/render_messages.h" +#include "testing/gtest/include/gtest/gtest.h" + +TEST(RenderMessagesUnittest, WebAccessibility) { + // Test a simple case. + webkit_glue::WebAccessibility input; + input.id = 123; + input.name = ASCIIToUTF16("name"); + input.value = ASCIIToUTF16("value"); + input.action = ASCIIToUTF16("action"); + input.description = ASCIIToUTF16("description"); + input.help = ASCIIToUTF16("help"); + input.shortcut = ASCIIToUTF16("shortcut"); + input.role = webkit_glue::WebAccessibility::ROLE_CHECKBUTTON; + input.state = + (1 << webkit_glue::WebAccessibility::STATE_CHECKED) | + (1 << webkit_glue::WebAccessibility::STATE_FOCUSED); + input.location = WebKit::WebRect(11, 22, 333, 444); + + IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL); + IPC::WriteParam(&msg, input); + + webkit_glue::WebAccessibility output; + void* iter = NULL; + EXPECT_TRUE(IPC::ReadParam(&msg, &iter, &output)); + EXPECT_EQ(input.id, output.id); + EXPECT_EQ(input.name, output.name); + EXPECT_EQ(input.value, output.value); + EXPECT_EQ(input.action, output.action); + EXPECT_EQ(input.description, output.description); + EXPECT_EQ(input.help, output.help); + EXPECT_EQ(input.shortcut, output.shortcut); + EXPECT_EQ(input.role, output.role); + EXPECT_EQ(input.state, output.state); + EXPECT_EQ(input.location, output.location); + EXPECT_EQ(input.children.size(), output.children.size()); + + // Test a corrupt case. + IPC::Message bad_msg(1, 2, IPC::Message::PRIORITY_NORMAL); + bad_msg.WriteInt(99); + iter = NULL; + EXPECT_FALSE(IPC::ReadParam(&bad_msg, &iter, &output)); + + // Test a recursive case. + webkit_glue::WebAccessibility outer; + outer.id = 1000; + outer.name = ASCIIToUTF16("outer_name"); + outer.role = webkit_glue::WebAccessibility::ROLE_GROUPING; + outer.state = 0; + outer.location = WebKit::WebRect(0, 0, 1000, 1000); + webkit_glue::WebAccessibility inner1; + inner1.id = 1001; + inner1.name = ASCIIToUTF16("inner1_name"); + inner1.role = webkit_glue::WebAccessibility::ROLE_RADIOBUTTON; + inner1.state = + (1 << webkit_glue::WebAccessibility::STATE_CHECKED) | + (1 << webkit_glue::WebAccessibility::STATE_FOCUSED); + inner1.location = WebKit::WebRect(10, 10, 900, 400); + outer.children.push_back(inner1); + webkit_glue::WebAccessibility inner2; + inner2.id = 1002; + inner2.name = ASCIIToUTF16("inner2_name"); + inner2.role = webkit_glue::WebAccessibility::ROLE_RADIOBUTTON; + inner2.state = (1 << webkit_glue::WebAccessibility::STATE_CHECKED); + inner2.location = WebKit::WebRect(10, 500, 900, 400); + outer.children.push_back(inner2); + + IPC::Message msg2(1, 2, IPC::Message::PRIORITY_NORMAL); + IPC::WriteParam(&msg2, outer); + + void* iter2 = NULL; + EXPECT_TRUE(IPC::ReadParam(&msg2, &iter2, &output)); + EXPECT_EQ(outer.id, output.id); + EXPECT_EQ(outer.name, output.name); + EXPECT_EQ(outer.role, output.role); + EXPECT_EQ(outer.state, output.state); + EXPECT_EQ(outer.location, output.location); + EXPECT_EQ(outer.children.size(), output.children.size()); + EXPECT_EQ(inner1.id, output.children[0].id); + EXPECT_EQ(inner1.name, output.children[0].name); + EXPECT_EQ(inner1.role, output.children[0].role); + EXPECT_EQ(inner1.state, output.children[0].state); + EXPECT_EQ(inner1.location, output.children[0].location); + EXPECT_EQ(inner2.id, output.children[1].id); + EXPECT_EQ(inner2.name, output.children[1].name); + EXPECT_EQ(inner2.role, output.children[1].role); + EXPECT_EQ(inner2.state, output.children[1].state); + EXPECT_EQ(inner2.location, output.children[1].location); +} diff --git a/chrome/renderer/render_thread.h b/chrome/renderer/render_thread.h index 680668c..f2ea2c3 100644 --- a/chrome/renderer/render_thread.h +++ b/chrome/renderer/render_thread.h @@ -261,6 +261,8 @@ class RenderThread : public RenderThreadBase, void OnGpuChannelEstablished(const IPC::ChannelHandle& channel_handle); + void OnGetAccessibilityTree(); + // Gather usage statistics from the in-memory cache and inform our host. // These functions should be call periodically so that the host can make // decisions about how to allocation resources using current information. diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 9e23291..4671156 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -75,7 +75,6 @@ #include "skia/ext/image_operations.h" #include "third_party/cld/encodings/compact_lang_det/win/cld_unicodetext.h" #include "third_party/WebKit/WebKit/chromium/public/WebAccessibilityCache.h" -#include "third_party/WebKit/WebKit/chromium/public/WebAccessibilityObject.h" #include "third_party/WebKit/WebKit/chromium/public/WebCString.h" #include "third_party/WebKit/WebKit/chromium/public/WebDataSource.h" #include "third_party/WebKit/WebKit/chromium/public/WebDevToolsAgent.h" @@ -637,9 +636,6 @@ void RenderView::OnMessageReceived(const IPC::Message& message) { ViewMsg_GetSerializedHtmlDataForCurrentPageWithLocalLinks, OnGetSerializedHtmlDataForCurrentPageWithLocalLinks) IPC_MESSAGE_HANDLER(ViewMsg_GetApplicationInfo, OnGetApplicationInfo) - IPC_MESSAGE_HANDLER(ViewMsg_GetAccessibilityInfo, OnGetAccessibilityInfo) - IPC_MESSAGE_HANDLER(ViewMsg_ClearAccessibilityInfo, - OnClearAccessibilityInfo) IPC_MESSAGE_HANDLER(ViewMsg_ShouldClose, OnMsgShouldClose) IPC_MESSAGE_HANDLER(ViewMsg_ClosePage, OnClosePage) IPC_MESSAGE_HANDLER(ViewMsg_ThemeChanged, OnThemeChanged) @@ -685,6 +681,7 @@ void RenderView::OnMessageReceived(const IPC::Message& message) { OnCustomContextMenuAction) IPC_MESSAGE_HANDLER(ViewMsg_TranslatePage, OnTranslatePage) IPC_MESSAGE_HANDLER(ViewMsg_RevertTranslation, OnRevertTranslation) + IPC_MESSAGE_HANDLER(ViewMsg_GetAccessibilityTree, OnGetAccessibilityTree) // Have the super handle all other messages. IPC_MESSAGE_UNHANDLED(RenderWidget::OnMessageReceived(message)) @@ -1335,14 +1332,10 @@ void RenderView::UpdateURL(WebFrame* frame) { // we don't want the transition type to persist. Just clear it. navigation_state->set_transition_type(PageTransition::LINK); -#if defined(OS_WIN) if (accessibility_.get()) { - // Remove accessibility info cache. + accessibility_->clear(); accessibility_.reset(); } -#else - // TODO(port): accessibility not yet implemented. See http://crbug.com/8288. -#endif } // Tell the embedding application that the title of the active page has changed @@ -3929,46 +3922,16 @@ void RenderView::OnUpdateBrowserWindowId(int window_id) { browser_window_id_ = window_id; } -void RenderView::OnGetAccessibilityInfo( - const webkit_glue::WebAccessibility::InParams& in_params, - webkit_glue::WebAccessibility::OutParams* out_params) { -#if defined(OS_WIN) - if (!accessibility_.get()) { - // TODO(dglazkov): Once implemented for all ports, remove lazy - // instantiation of accessibility_. - accessibility_.reset(WebAccessibilityCache::create()); - accessibility_->initialize(webview()); - } - - out_params->return_code = - webkit_glue::WebAccessibility::GetAccObjInfo(accessibility_.get(), - in_params, - out_params); - -#else // defined(OS_WIN) - // TODO(port): accessibility not yet implemented - NOTIMPLEMENTED(); -#endif -} - -void RenderView::OnClearAccessibilityInfo(int acc_obj_id, bool clear_all) { -#if defined(OS_WIN) - if (!accessibility_.get()) { - // If accessibility is not activated, ignore clearing message. - return; - } - - if (clear_all) { +void RenderView::OnGetAccessibilityTree() { + if (accessibility_.get()) { accessibility_->clear(); - return; } + accessibility_.reset(WebAccessibilityCache::create()); + accessibility_->initialize(webview()); - accessibility_->remove(acc_obj_id); - -#else // defined(OS_WIN) - // TODO(port): accessibility not yet implemented - NOTIMPLEMENTED(); -#endif + WebAccessibilityObject src_tree = webview()->accessibilityObject(); + webkit_glue::WebAccessibility dst_tree(src_tree, accessibility_.get()); + Send(new ViewHostMsg_AccessibilityTree(routing_id_, dst_tree)); } void RenderView::OnGetAllSavableResourceLinksForCurrentPage( diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index bcf9f0a..57a8484 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -45,6 +45,7 @@ #include "gfx/rect.h" #include "third_party/skia/include/core/SkBitmap.h" #include "testing/gtest/include/gtest/gtest_prod.h" +#include "third_party/WebKit/WebKit/chromium/public/WebAccessibilityObject.h" #include "third_party/WebKit/WebKit/chromium/public/WebConsoleMessage.h" #include "third_party/WebKit/WebKit/chromium/public/WebContextMenuData.h" #include "third_party/WebKit/WebKit/chromium/public/WebFrameClient.h" @@ -496,6 +497,8 @@ class RenderView : public RenderWidget, // UserScript::DOCUMENT_IDLE. void OnUserScriptIdleTriggered(WebKit::WebFrame* frame); + void OnGetAccessibilityTree(); + #if defined(OS_MACOSX) // Helper routines for GPU plugin support. Used by the // WebPluginDelegateProxy, which has a pointer to the RenderView. @@ -729,10 +732,6 @@ class RenderView : public RenderWidget, void OnExecuteCode(const ViewMsg_ExecuteCode_Params& params); void ExecuteCodeImpl(WebKit::WebFrame* frame, const ViewMsg_ExecuteCode_Params& params); - void OnGetAccessibilityInfo( - const webkit_glue::WebAccessibility::InParams& in_params, - webkit_glue::WebAccessibility::OutParams* out_params); - void OnClearAccessibilityInfo(int acc_obj_id, bool clear_all); void OnExtensionMessageInvoke(const std::string& function_name, const ListValue& args, @@ -1063,11 +1062,10 @@ class RenderView : public RenderWidget, bool decrement_shared_popup_at_destruction_; // TODO(port): revisit once we have accessibility -#if defined(OS_WIN) + // Handles accessibility requests into the renderer side, as well as // maintains the cache and other features of the accessibility tree. scoped_ptr<WebKit::WebAccessibilityCache> accessibility_; -#endif // Resource message queue. Used to queue up resource IPCs if we need // to wait for an ACK from the browser before proceeding. diff --git a/third_party/iaccessible2/ia2_api_all.idl b/third_party/iaccessible2/ia2_api_all.idl new file mode 100644 index 0000000..5178012 --- /dev/null +++ b/third_party/iaccessible2/ia2_api_all.idl @@ -0,0 +1,4263 @@ +/************************************************************************* + * + * File Name (IA2CommonTypes.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) Linux Foundation 2007, 2009 + * Copyright (c) IBM Corp. 2006 + * Copyright (c) Sun Microsystems, Inc. 2000, 2006 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + ************************************************************************/ + +/** These constants control the scrolling of an object or substring into a window. + + This enum is used in IAccessible2::scrollTo and IAccessibleText::scrollSubstringTo. +*/ +enum IA2ScrollType { + + /** Scroll the top left corner of the object or substring such that the top left + corner (and as much as possible of the rest of the object or substring) is within + the top level window. In cases where the entire object or substring fits within + the top level window, the placement of the object or substring is dependent on + the application. For example, the object or substring may be scrolled to the + closest edge, the furthest edge, or midway between those two edges. In cases + where there is a hierarchy of nested scrollable controls, more than one control + may have to be scrolled. + */ + IA2_SCROLL_TYPE_TOP_LEFT, + + /** Scroll the bottom right corner of the object or substring such that the bottom right + corner (and as much as possible of the rest of the object or substring) is within + the top level window. In cases where the entire object or substring fits within + the top level window, the placement of the object or substring is dependent on + the application. For example, the object or substring may be scrolled to the + closest edge, the furthest edge, or midway between those two edges. In cases + where there is a hierarchy of nested scrollable controls, more than one control + may have to be scrolled. + */ + IA2_SCROLL_TYPE_BOTTOM_RIGHT, + + /** Scroll the top edge of the object or substring such that the top edge + (and as much as possible of the rest of the object or substring) is within the + top level window. In cases where the entire object or substring fits within + the top level window, the placement of the object or substring is dependent on + the application. For example, the object or substring may be scrolled to the + closest edge, the furthest edge, or midway between those two edges. In cases + where there is a hierarchy of nested scrollable controls, more than one control + may have to be scrolled. + */ + IA2_SCROLL_TYPE_TOP_EDGE, + + /** Scroll the bottom edge of the object or substring such that the bottom edge + (and as much as possible of the rest of the object or substring) is within the + top level window. In cases where the entire object or substring fits within + the top level window, the placement of the object or substring is dependent on + the application. For example, the object or substring may be scrolled to the + closest edge, the furthest edge, or midway between those two edges. In cases + where there is a hierarchy of nested scrollable controls, more than one control + may have to be scrolled. + */ + IA2_SCROLL_TYPE_BOTTOM_EDGE, + + /** Scroll the left edge of the object or substring such that the left edge + (and as much as possible of the rest of the object or substring) is within the + top level window. In cases where the entire object or substring fits within + the top level window, the placement of the object or substring is dependent on + the application. For example, the object or substring may be scrolled to the + closest edge, the furthest edge, or midway between those two edges. In cases + where there is a hierarchy of nested scrollable controls, more than one control + may have to be scrolled. + */ + IA2_SCROLL_TYPE_LEFT_EDGE, + + /** Scroll the right edge of the object or substring such that the right edge + (and as much as possible of the rest of the object or substring) is within the + top level window. In cases where the entire object or substring fits within + the top level window, the placement of the object or substring is dependent on + the application. For example, the object or substring may be scrolled to the + closest edge, the furthest edge, or midway between those two edges. In cases + where there is a hierarchy of nested scrollable controls, more than one control + may have to be scrolled. + */ + IA2_SCROLL_TYPE_RIGHT_EDGE, + + /** Scroll the object or substring such that as much as possible of the + object or substring is within the top level window. The placement of + the object is dependent on the application. For example, the object or + substring may be scrolled to to closest edge, the furthest edge, or midway + between those two edges. + */ + IA2_SCROLL_TYPE_ANYWHERE +}; + +/** These constants define which coordinate system a point is located in. + + This enum is used in IAccessible2::scrollToPoint, IAccessibleImage::imagePosition, + IAccessibleText::characterExtents, and IAccessibleText::offsetAtPoint, and + IAccessibleText::scrollSubstringToPoint. +*/ +enum IA2CoordinateType { + + /// The coordinates are relative to the screen. + IA2_COORDTYPE_SCREEN_RELATIVE, + + /** The coordinates are relative to the upper left corner of the bounding box + of the immediate parent. + */ + IA2_COORDTYPE_PARENT_RELATIVE + +}; + +/** Special offsets for use in IAccessibleText and IAccessibleEditableText methods + + Refer to @ref _specialOffsets + "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" + for more information. +*/ +enum IA2TextSpecialOffsets { + IA2_TEXT_OFFSET_LENGTH = -1, /**< This offset is equivalent to the length of the string. It eliminates + the need to call IAccessibleText::nCharacters. */ + IA2_TEXT_OFFSET_CARET = -2 /**< This offset signifies that the text related to the physical location + of the caret should be used. */ +}; + +/** These constants specify the kind of change made to a table. + + This enum is used in the IA2TableModelChange struct which in turn is used by + IAccessibleTable::modelChange and IAccessibleTable2::modelChange. +*/ +enum IA2TableModelChangeType { + IA2_TABLE_MODEL_CHANGE_INSERT, // = 0; + IA2_TABLE_MODEL_CHANGE_DELETE, + IA2_TABLE_MODEL_CHANGE_UPDATE +}; + +/** A structure defining the type of and extents of changes made to a table + + IAccessibleTable::modelChange and IAccessibleTable2::modelChange return this struct. + In the case of an insertion or change the row and column offsets define the boundaries + of the inserted or changed subtable after the operation. In the case of a deletion + the row and column offsets define the boundaries of the subtable being removed before + the removal. +*/ +typedef struct IA2TableModelChange { + enum IA2TableModelChangeType type; // insert, delete, update + long firstRow; ///< 0 based, inclusive + long lastRow; ///< 0 based, inclusive + long firstColumn; ///< 0 based, inclusive + long lastColumn; ///< 0 based, inclusive +} IA2TableModelChange; +/************************************************************************* + * + * File Name (AccessibleRelation.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) Linux Foundation 2007, 2009 + * Copyright (c) IBM Corp. 2006 + * Copyright (c) Sun Microsystems, Inc. 2000, 2006 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + ************************************************************************/ + +import "objidl.idl"; +import "oaidl.idl"; +import "oleacc.idl"; + +/** @defgroup grpRelations Relations + Use the following constants to compare against the BSTRs returned by + IAccessibleRelation::relationType. +*/ +///@{ + +/** Some attribute of this object is affected by a target object. */ +const WCHAR *const IA2_RELATION_CONTROLLED_BY = L"controlledBy"; + +/** This object is interactive and controls some attribute of a target object. */ +const WCHAR *const IA2_RELATION_CONTROLLER_FOR = L"controllerFor"; + +/** This object is described by the target object. */ +const WCHAR *const IA2_RELATION_DESCRIBED_BY = L"describedBy"; + +/** This object is describes the target object. */ +const WCHAR *const IA2_RELATION_DESCRIPTION_FOR = L"descriptionFor"; + +/** This object is embedded by a target object. */ +const WCHAR *const IA2_RELATION_EMBEDDED_BY = L"embeddedBy"; + +/** This object embeds a target object. This relation can be used on the + OBJID_CLIENT accessible for a top level window to show where the content + areas are. +*/ +const WCHAR *const IA2_RELATION_EMBEDS = L"embeds"; + +/** Content flows to this object from a target object. + This relation and IA2_RELATION_FLOWS_TO are useful to tie text and non-text + objects together in order to allow assistive technology to follow the + intended reading order. +*/ +const WCHAR *const IA2_RELATION_FLOWS_FROM = L"flowsFrom"; + +/** Content flows from this object to a target object. */ +const WCHAR *const IA2_RELATION_FLOWS_TO = L"flowsTo"; + +/** This object is label for a target object. */ +const WCHAR *const IA2_RELATION_LABEL_FOR = L"labelFor"; + +/** This object is labelled by a target object. Note that the double L spelling + which follows is preferred. Please use it instead. This single L version may + be removed in a later version. +*/ +const WCHAR *const IA2_RELATION_LABELED_BY = L"labelledBy"; + +/** This object is labelled by a target object. */ +const WCHAR *const IA2_RELATION_LABELLED_BY = L"labelledBy"; + +/** This object is a member of a group of one or more objects. When + there is more than one object in the group each member may have one and the + same target, e.g. a grouping object. It is also possible that each member has + multiple additional targets, e.g. one for every other member in the group. +*/ +const WCHAR *const IA2_RELATION_MEMBER_OF = L"memberOf"; + +/** This object is a child of a target object. */ +const WCHAR *const IA2_RELATION_NODE_CHILD_OF = L"nodeChildOf"; + +/** This object is a parent window of the target object. */ +const WCHAR *const IA2_RELATION_PARENT_WINDOW_OF = L"parentWindowOf"; + +/** This object is a transient component related to the target object. + When this object is activated the target object doesn't loose focus. +*/ +const WCHAR *const IA2_RELATION_POPUP_FOR = L"popupFor"; + +/** This object is a sub window of a target object. */ +const WCHAR *const IA2_RELATION_SUBWINDOW_OF = L"subwindowOf"; + +///@} + +/// This interface gives access to an object's set of relations. +[object, uuid(7CDF86EE-C3DA-496a-BDA4-281B336E1FDC)] +interface IAccessibleRelation : IUnknown +{ + /** @brief Returns the type of the relation. + @param [out] relationType + The strings returned are defined @ref grpRelations "in this section of the documentation". + @retval S_OK + */ + [propget] HRESULT relationType + ( + [out, retval] BSTR *relationType + ); + + /** @brief Returns a localized version of the relation type. + @param [out] localizedRelationType + @retval S_OK + */ + [propget] HRESULT localizedRelationType + ( + [out, retval] BSTR *localizedRelationType + ); + + /** @brief Returns the number of targets for this relation. + @param [out] nTargets + @retval S_OK + */ + [propget] HRESULT nTargets + ( + [out, retval] long *nTargets + ); + + /** @brief Returns one accessible relation target. + @param [in] targetIndex + 0 based index + @param [out] target + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + @retval E_INVALIDARG if bad [in] passed, [out] value is NULL + @note Use QueryInterface to get IAccessible2. + */ + [propget] HRESULT target + ( + [in] long targetIndex, + [out, retval] IUnknown **target + ); + + /** @brief Returns multiple accessible relation targets + @param [in] maxTargets + maximum size of the array allocated by the client + @param [out] targets + The array of target objects. Note that this array is to be allocated by the + client and freed when no longer needed. Refer to @ref _arrayConsideration + "Special Consideration when using Arrays" for more details. You will need to use + QueryInterface on the IUnknown to get the IAccessible2. + @param [out] nTargets + actual number of targets in the returned array (not more than maxTargets) + @retval S_OK + @retval S_FALSE if there is nothing to return, nTargets is set to 0 + */ + [propget] HRESULT targets + ( + [in] long maxTargets, + [out, size_is(maxTargets), length_is(*nTargets)] + IUnknown **targets, + [out, retval] long *nTargets + ); + +} +/************************************************************************* + * + * File Name (AccessibleAction.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) Linux Foundation 2007, 2008 + * Copyright (c) IBM Corp. 2006 + * Copyright (c) Sun Microsystems, Inc. 2000, 2006 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + ************************************************************************/ + +import "objidl.idl"; +import "oaidl.idl"; +import "oleacc.idl"; + +/** @brief This interface gives access to actions that can be executed + for accessible objects. + + Every accessible object that can be manipulated via the native GUI beyond the + methods available either in the MSAA IAccessible interface or in the set of + IAccessible2 interfaces (other than this IAccessibleAction interface) should + support the IAccessibleAction interface in order to provide Assistive Technology + access to all the actions that can be performed by the object. Each action can + be performed or queried for a name, description or associated key bindings. + Actions are needed more for ATs that assist the mobility impaired, such as + on-screen keyboards and voice command software. By providing actions directly, + the AT can present them to the user without the user having to perform the extra + steps to navigate a context menu. + + The first action should be equivalent to the MSAA default action. If there is + only one action, %IAccessibleAction should also be implemented. +*/ +[object, uuid(B70D9F59-3B5A-4dba-AB9E-22012F607DF5)] +interface IAccessibleAction : IUnknown +{ + + /** @brief Returns the number of accessible actions available in this object. + + If there are more than one, the first one is considered the + "default" action of the object. + @param [out] nActions + The returned value of the number of actions is zero if there are + no actions. + @retval S_OK + @note This method is missing a [propget] prefix in the IDL. The result is the + method is named nActions in generated C++ code instead of get_nActions. + */ + HRESULT nActions + ( + [out,retval] long* nActions + ); + + /** @brief Performs the specified Action on the object. + @param [in] actionIndex + 0 based index specifying the action to perform. If it lies outside + the valid range no action is performed. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT doAction + ( + [in] long actionIndex + ); + + /** @brief Returns a description of the specified action of the object. + @param [in] actionIndex + 0 based index specifying which action's description to return. + If it lies outside the valid range an empty string is returned. + @param [out] description + The returned value is a localized string of the specified action. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + @retval E_INVALIDARG if bad [in] passed, [out] value is NULL + */ + [propget] HRESULT description + ( + [in] long actionIndex, + [out, retval] BSTR *description + ); + + /** @brief Returns an array of BSTRs describing one or more key bindings, if + there are any, associated with the specified action. + + The returned strings are the localized human readable key sequences to be + used to activate each action, e.g. "Ctrl+Shift+D". Since these key + sequences are to be used when the object has focus, they are like + mnemonics (access keys), and not like shortcut (accelerator) keys. + + There is no need to implement this method for single action controls since + that would be redundant with the standard MSAA programming practice of + getting the mnemonic from get_accKeyboardShortcut. + + An AT such as an On Screen Keyboard might not expose these bindings but + provide alternative means of activation. + + Note: the client allocates and passes in an array of pointers. The server + allocates the BSTRs and passes back one or more pointers to these BSTRs into + the array of pointers allocated by the client. The client is responsible + for deallocating the BSTRs. + + @param [in] actionIndex + 0 based index specifying which action's key bindings should be returned. + @param [in] nMaxBindings + This parameter is ignored. Refer to @ref _arrayConsideration + "Special Consideration when using Arrays" for more details. + @param [out] keyBindings + An array of BSTRs, allocated by the server, one for each key binding. + Free it with CoTaskMemFree. + @param [out] nBindings + The number of key bindings returned; the size of the returned array. + @retval S_OK + @retval S_FALSE if there are no relations, [out] values are NULL and 0 respectively + @retval E_INVALIDARG if bad [in] passed, [out] values are NULL and 0 respectively + */ + [propget] HRESULT keyBinding + ( + [in] long actionIndex, + [in] long nMaxBindings, + [out, size_is(,nMaxBindings), length_is(,*nBindings)] BSTR **keyBindings, + [out, retval] long *nBindings + ); + + /** @brief Returns the non-localized name of specified action. + @param [in] actionIndex + 0 based index specifying which action's non-localized name should be returned. + @param [out] name + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + @retval E_INVALIDARG if bad [in] passed, [out] value is NULL + */ + [propget] HRESULT name + ( + [in] long actionIndex, + [out, retval] BSTR *name + ); + + /** @brief Returns the localized name of specified action. + @param [in] actionIndex + 0 based index specifying which action's localized name should be returned. + @param [out] localizedName + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + @retval E_INVALIDARG if bad [in] passed, [out] value is NULL + */ + [propget] HRESULT localizedName + ( + [in] long actionIndex, + [out, retval] BSTR *localizedName + ); + +} +/************************************************************************* + * + * File Name (AccessibleRole.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) Linux Foundation 2007, 2008 + * Copyright (c) IBM Corp. 2006 + * Copyright (c) Sun Microsystems, Inc. 2000, 2006 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02110-1301 USA + * + ************************************************************************/ + +import "objidl.idl"; + +/** Collection of roles + + This enumerator defines an extended set of accessible roles of objects implementing + the %IAccessible2 interface. These roles are in addition to the MSAA roles obtained + through the MSAA get_accRole method. Examples are 'footnote', 'heading', and + 'label'. You obtain an object's %IAccessible2 roles by calling IAccessible2::role. +*/ +enum IA2Role { + + /** Unknown role. The object contains some Accessible information, but its + role is not known. + */ + IA2_ROLE_UNKNOWN = 0, + + /** An object that can be drawn into and to manage events from the objects + drawn into it. Also refer to ::IA2_ROLE_FRAME, + ::IA2_ROLE_GLASS_PANE, and ::IA2_ROLE_LAYERED_PANE. + */ + IA2_ROLE_CANVAS = 0x401, + + /// A caption describing another object. + IA2_ROLE_CAPTION, + + /// Used for check buttons that are menu items. + IA2_ROLE_CHECK_MENU_ITEM, + + /// A specialized dialog that lets the user choose a color. + IA2_ROLE_COLOR_CHOOSER, + + /// A date editor. + IA2_ROLE_DATE_EDITOR, + + /** An iconified internal frame in an ::IA2_ROLE_DESKTOP_PANE. + Also refer to ::IA2_ROLE_INTERNAL_FRAME. + */ + IA2_ROLE_DESKTOP_ICON, + + /** A desktop pane. A pane that supports internal frames and iconified + versions of those internal frames. Also refer to ::IA2_ROLE_INTERNAL_FRAME. + */ + IA2_ROLE_DESKTOP_PANE, + + /** A directory pane. A pane that allows the user to navigate through + and select the contents of a directory. May be used by a file chooser. + Also refer to ::IA2_ROLE_FILE_CHOOSER. + */ + IA2_ROLE_DIRECTORY_PANE, + + /** An editable text object in a toolbar. + <BR><B>Note:</B> This role has been deprecated. The edit bar role was meant + for a text area in a tool bar. However, to detect a text area in a tool bar + the AT can query the parent. + */ + IA2_ROLE_EDITBAR, + + /// Embedded (OLE) object. + IA2_ROLE_EMBEDDED_OBJECT, + + /// Text that is used as an endnote (footnote at the end of a chapter or section). + IA2_ROLE_ENDNOTE, + + /** A file chooser. A specialized dialog that displays the files in the + directory and lets the user select a file, browse a different directory, + or specify a filename. May use the directory pane to show the contents of + a directory. + Also refer to ::IA2_ROLE_DIRECTORY_PANE. + */ + IA2_ROLE_FILE_CHOOSER, + + /** A font chooser. A font chooser is a component that lets the user pick + various attributes for fonts. + */ + IA2_ROLE_FONT_CHOOSER, + + /** Footer of a document page. + Also refer to ::IA2_ROLE_HEADER. + */ + IA2_ROLE_FOOTER, + + /// Text that is used as a footnote. Also refer to ::IA2_ROLE_ENDNOTE. + IA2_ROLE_FOOTNOTE, + + /** A container of form controls. An example of the use of this role is to + represent an HTML FORM tag. + */ + IA2_ROLE_FORM, + + /** Frame role. A top level window with a title bar, border, menu bar, etc. + It is often used as the primary window for an application. Also refer to + ::IA2_ROLE_CANVAS and the MSAA roles of dialog and window. + */ + IA2_ROLE_FRAME, + + /** A glass pane. A pane that is guaranteed to be painted on top of all panes + beneath it. Also refer to ::IA2_ROLE_CANVAS, ::IA2_ROLE_INTERNAL_FRAME, and + ::IA2_ROLE_ROOT_PANE. + */ + IA2_ROLE_GLASS_PANE, + + /** Header of a document page. + Also refer to ::IA2_ROLE_FOOTER. + */ + IA2_ROLE_HEADER, + + /// Heading. Use the IAccessible2::attributes heading-level attribute to determine the heading level. + IA2_ROLE_HEADING, + + /// A small fixed size picture, typically used to decorate components. + IA2_ROLE_ICON, + + /** An image map object. Usually a graphic with multiple hotspots, where + each hotspot can be activated resulting in the loading of another document + or section of a document. + */ + IA2_ROLE_IMAGE_MAP, + + /** An object which is used to allow input of characters not found on a keyboard, + such as the input of Chinese characters on a Western keyboard. + */ + IA2_ROLE_INPUT_METHOD_WINDOW, + + /** An internal frame. A frame-like object that is clipped by a desktop pane. + The desktop pane, internal frame, and desktop icon objects are often used to + create multiple document interfaces within an application. + Also refer to ::IA2_ROLE_DESKTOP_ICON, ::IA2_ROLE_DESKTOP_PANE, and ::IA2_ROLE_FRAME. + */ + IA2_ROLE_INTERNAL_FRAME, + + /// An object used to present an icon or short string in an interface. + IA2_ROLE_LABEL, + + /** A layered pane. A specialized pane that allows its children to be drawn + in layers, providing a form of stacking order. This is usually the pane that + holds the menu bar as well as the pane that contains most of the visual + components in a window. + Also refer to ::IA2_ROLE_CANVAS, ::IA2_ROLE_GLASS_PANE, and ::IA2_ROLE_ROOT_PANE. + */ + IA2_ROLE_LAYERED_PANE, + + /// An embedded note which is not visible until activated. + IA2_ROLE_NOTE, + + /** A specialized pane whose primary use is inside a dialog. + Also refer to MSAA's dialog role. + */ + IA2_ROLE_OPTION_PANE, + + /** An object representing a page of document content. It is used in documents + which are accessed by the user on a page by page basis. + */ + IA2_ROLE_PAGE, + + /// A paragraph of text. + IA2_ROLE_PARAGRAPH, + + /** A radio button that is a menu item. + Also refer to MSAA's button and menu item roles. + */ + IA2_ROLE_RADIO_MENU_ITEM, + + /** An object which is redundant with another object in the accessible hierarchy. + ATs typically ignore objects with this role. + */ + IA2_ROLE_REDUNDANT_OBJECT, + + /** A root pane. A specialized pane that has a glass pane and a layered pane + as its children. + Also refer to ::IA2_ROLE_GLASS_PANE and ::IA2_ROLE_LAYERED_PANE + */ + IA2_ROLE_ROOT_PANE, + + /** A ruler such as those used in word processors. + */ + IA2_ROLE_RULER, + + /** A scroll pane. An object that allows a user to incrementally view a large + amount of information. Its children can include scroll bars and a viewport. + Also refer to ::IA2_ROLE_VIEW_PORT and MSAA's scroll bar role. + */ + IA2_ROLE_SCROLL_PANE, + + /** A container of document content. An example of the use of this role is to + represent an HTML DIV tag. A section may be used as a region. A region is a + group of elements that together form a perceivable unit. A region does not + necessarily follow the logical structure of the content, but follows the + perceivable structure of the page. A region may have an attribute in the set + of IAccessible2::attributes which indicates that it is "live". A live region + is content that is likely to change in response to a timed change, a user + event, or some other programmed logic or event. + */ + IA2_ROLE_SECTION, + + /// Object with graphical representation used to represent content on draw pages. + IA2_ROLE_SHAPE, + + /** A split pane. A specialized panel that presents two other panels at the + same time. Between the two panels is a divider the user can manipulate to make + one panel larger and the other panel smaller. + */ + IA2_ROLE_SPLIT_PANE, + + /** An object that forms part of a menu system but which can be "undocked" + from or "torn off" the menu system to exist as a separate window. + */ + IA2_ROLE_TEAR_OFF_MENU, + + /// An object used as a terminal emulator. + IA2_ROLE_TERMINAL, + + /// Collection of objects that constitute a logical text entity. + IA2_ROLE_TEXT_FRAME, + + /** A toggle button. A specialized push button that can be checked or unchecked, + but does not provide a separate indicator for the current state. + Also refer to MSAA's roles of push button, check box, and radio button. + <BR><B>Note:</B> IA2_ROLE_TOGGLE_BUTTON should not be used. Instead, use MSAA's + ROLE_SYSTEM_PUSHBUTTON and STATE_SYSTEM_PRESSED. + */ + IA2_ROLE_TOGGLE_BUTTON, + + /** A viewport. An object usually used in a scroll pane. It represents the + portion of the entire data that the user can see. As the user manipulates + the scroll bars, the contents of the viewport can change. + Also refer to ::IA2_ROLE_SCROLL_PANE. + */ + IA2_ROLE_VIEW_PORT + +}; +/************************************************************************* + * + * File Name (AccessibleStates.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) Linux Foundation 2007, 2008 + * Copyright (c) IBM Corp. 2006 + * Copyright (c) Sun Microsystems, Inc. 2000, 2006 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02110-1301 USA + * + ************************************************************************/ + +import "objidl.idl"; + +typedef long AccessibleStates; + +/** %IAccessible2 specific state bit constants + + This enum defines the state bits returned by IAccessible2::states. The + %IAccessible2 state bits are in addition to those returned by MSAA. +*/ +enum IA2States { + +/** Indicates a window is currently the active window, or is an active subelement + within a container or table. + + This state can be used to indicate the current active item in a container, even + if the container itself is not currently active. In other words this would indicate + the item that will get focus if you tab to the container. + + This information is important for knowing what to report for trees and potentially + other containers in a virtual buffer. + + Also, see ::IA2_STATE_MANAGES_DESCENDANTS for more information. +*/ +IA2_STATE_ACTIVE = 0x1, + +/** Indicates that the object is armed. + + Used to indicate that the control is "pressed" and will be invoked when the + actuator, e.g. a mouse button, is "released". An AT which either monitors the + mouse or synthesizes mouse events might need to know that, and possibly a talking + interface would even let the user know about it. It could also potentially be + useful to on screen keyboards or test tools since the information does indicate + something about the state of the interface, for example, code operating asynchronously + might need to wait for the armed state to change before doing something else. + +*/ +IA2_STATE_ARMED = 0x2, + +/** Indicates the user interface object corresponding to this object no longer exists. */ +IA2_STATE_DEFUNCT = 0x4, + +/** Indicates the user can change the contents of this object. */ +IA2_STATE_EDITABLE = 0x8, + +/** Indicates the orientation of this object is horizontal. */ +IA2_STATE_HORIZONTAL = 0x10, + +/** Indicates this object is minimized and is represented only by an icon. */ +IA2_STATE_ICONIFIED = 0x20, + +/** Indicates an input validation failure. */ +IA2_STATE_INVALID_ENTRY = 0x40, + +/** Indicates that this object manages its children. + + Note: Due to the fact that MSAA's WinEvents don't allow the active child index + to be passed on the IA2_EVENT_ACTIVE_DESCENDANT_CHANGED event, the manages + descendants scheme can't be used. Instead the active child object has to fire + MSAA's EVENT_OBJECT_FOCUS. In a future release a new event mechanism may be + added to provide for event specific data to be passed with the event. At that + time the IA2_EVENT_ACTIVE_DECENDENT_CHANGED event and + IA2_STATE_MANAGES_DESCENDANTS state would be useful. +*/ +IA2_STATE_MANAGES_DESCENDANTS = 0x80, + +/** Indicates that an object is modal. + + Modal objects have the behavior that something must be done with the object + before the user can interact with an object in a different window. +*/ +IA2_STATE_MODAL = 0x100, + +/** Indicates this text object can contain multiple lines of text. */ +IA2_STATE_MULTI_LINE = 0x200, + +/** Indicates this object paints every pixel within its rectangular region. */ +IA2_STATE_OPAQUE = 0x400, + +/** Indicates that user interaction is required. + + An example of when this state is used is when a field in a form must be filled + before a form can be processed. +*/ +IA2_STATE_REQUIRED = 0x800, + +/** Indicates an object which supports text selection. + + Note: This is different than MSAA STATE_SYSTEM_SELECTABLE. +*/ +IA2_STATE_SELECTABLE_TEXT = 0x1000, + +/** Indicates that this text object can contain only a single line of text. */ +IA2_STATE_SINGLE_LINE = 0x2000, + +/** Indicates that the accessible object is stale. + + This state is used when the accessible object no longer accurately + represents the state of the object which it is representing such as when an + object is transient or when an object has been or is in the process of being + destroyed or when the object's index in its parent has changed. +*/ +IA2_STATE_STALE = 0x4000, + +/** Indicates that the object implements autocompletion. + + This state indicates that a text control will respond to the input of + one ore more characters and cause a sub-item to become selected. The + selection may also result in events fired on the parent object. +*/ +IA2_STATE_SUPPORTS_AUTOCOMPLETION = 0x8000, + +/** Indicates this object is transient. + + An object has this state when its parent object has the state ::IA2_STATE_MANAGES_DESCENDANTS. + For example, a list item object may be managed by its parent list object and may only + exist as long as the object is actually rendered. Similarly a table cell's accessible + object may exist only while the cell has focus. However, from the perspective of an + assistive technology a transient object behaves like a non-transient object. As a + result it is likely that this state is not of use to an assistive technology, but it + is provided in case an assistive technology determines that knowledge of the transient + nature of the object is useful and also for harmony with the Linux accessibility API. + + Also, see ::IA2_STATE_MANAGES_DESCENDANTS for more information. + */ +IA2_STATE_TRANSIENT = 0x10000, + +/** Indicates the orientation of this object is vertical. */ +IA2_STATE_VERTICAL = 0x20000 + +}; +/************************************************************************* + * + * File Name (Accessible2.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) Linux Foundation 2007, 2009 + * Copyright (c) IBM Corp. 2006 + * Copyright (c) Sun Microsystems, Inc. 2000, 2006 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + ************************************************************************/ + +/** @mainpage + + @section _interfaces Interfaces + IAccessible2\n + IAccessibleAction\n + IAccessibleApplication\n + IAccessibleComponent\n + IAccessibleHypertext\n + IAccessibleHyperlink\n + IAccessibleImage\n + IAccessibleRelation\n + IAccessibleTable [deprecated]\n + IAccessibleTable2\n + IAccessibleTableCell\n + IAccessibleText\n + IAccessibleEditableText\n + IAccessibleValue + + @section _structs Structs + IA2Locale\n + IA2TableModelChange\n + IA2TextSegment + + @section _enums Enums + ::IA2CoordinateType values define the requested coordinate type (screen or parent window).\n + ::IA2EventID values identify events.\n + ::IA2Role values defines roles which are in addition to the existing MSAA roles.\n + ::IA2ScrollType values define where to place an object or substring on the screen.\n + ::IA2States values define states which are in addition to the existing MSAA states.\n + ::IA2TableModelChangeType values describe the kinds of changes made to a table (insert, delete, update).\n + ::IA2TextBoundaryType values define the requested text unit (character, word, sentence, line, paragraph).\n + ::IA2TextSpecialOffsets values define special offsets for use in the text interfaces. + + @section _constants Constants + @ref grpRelations + + @section _misc Miscellaneous + @ref _licensePage "LGPL License"\n + @ref _generalInfo "General Information"\n + + @page _licensePage LGPL License + IAccessible2 IDL Specification + + Copyright (c) Linux Foundation 2007, 2008\n + Copyright (c) IBM Corp. 2006\n + Copyright (c) Sun Microsystems, Inc. 2000, 2006 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1, as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + You may also refer to http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html + + @page _generalInfo General Information + The following information is applicable to two or more interfaces. + + @ref _errors\n + @ref _memory\n + @ref _arrayConsideration\n + @ref _indexes\n + @ref _enums\n + @ref _specialOffsets\n + @ref _dicoveringInterfaces\n + @ref _changingInterfaces\n + @ref _applicationInfo\n + @ref _childIDs\n + @ref _variants\n + @ref _iaaction-iahyperlink\n + @ref _trademark + + @section _errors Error Handling + HRESULT values are defined by the Microsoft® Win32® API. For more information, refer to + <a href="http://msdn2.microsoft.com/en-us/library/bb401631.aspx">Interpreting HRESULT Values</a> + in MSDN®. + + Note that the S_FALSE return value is considered a non-error value and the + SUCCEEDED macro will return TRUE. S_FALSE is used when there is no failure + but there was nothing valid to return, e.g. in IAccessible2::attributes when + there are no attributes. When S_FALSE is returned [out] pointer types should + be NULL and [out] longs should generally be 0, but sometimes -1 is used such + as IAccessible2::indexInParent, IAccessibleText::caretOffset, and + IAccessibleHypertext::hyperlinkIndex. + + Note that for BSTR [out] variables common COM practice is that the server does + the SysAllocString and the client does the SysFreeString. Also note that when + NULL is returned there is no need for the client to call SysFreeString. Please + refer to the documentation for each method for more details regarding error handling. + + @section _memory Memory Management + The following memory management issues should be considered: + @li Although [out] BSTR variables are declared by the client, their space is + allocated by the server. They need to be freed with SysFreeString by the + client at end of life; the same is true when BSTRs are used in structs or + arrays which are passed to the server. + @li If there is no valid [out] BSTR to return, the server should return S_FALSE and + assign NULL to the output, e.g. *theOutBSTR = NULL;. + @li COM interfaces need to be referenced with AddRef when used and dereferenced + with Release at end of life. + @li Single [out] longs, HWNDs, booleans, and structs are declared by the caller + and passed by reference. The marshaller does all the memory management. + + The following articles may be helpful for understanding memory management issues: + @li An article by Don Box in a + <a href="http://www.microsoft.com/msj/1196/activex1196.aspx">Q & A section</a> + of the November 1996 edition of the Microsoft Systems Journal. + @li A posting to a CodeGuru forum, + <a href="http://www.codeguru.com/forum/showthread.php?t=364511">Windows SDK + String: What are the rules for BSTR allocation and deallocation?</a> + + @subsection _arrayConsideration Special Consideration when using Arrays + There are several methods which return arrays. It is considered a best practice + for the client to allocate and free the arrays. This can be done for + IAccessible2::relations and IAccessibleRelation::targets. However, due to the + coding of the IDL for the remaining methods which return arrays, the server must + allocate the array and the client must free the array when no longer needed. + These methods are IAccessible2::extendedStates, IAccessible2::localizedExtendedStates, + IAccessibleAction::keyBinding, IAccessibleTable::selectedChildren, + IAccessibleTable::selectedColumns, and IAccessibleTable::selectedRows. For those + methods, the server must allocate both the top level array and any storage + associated with it, e.g. for BSTRs. The client must use CoTaskMemFree to free + the array and any BSTRs must be freed with SysFreeString. + + Also, the IDL for those methods includes an extraneous [in] parameter for the + caller to specify the max size of the array. This parameter will be ignored by + the COM server. + + @section _indexes Zero and One Based Indexes + Unless otherwise specified all offsets and indexes are 0 based. + + @section _enums Enums + Note that enums start at 0. + + @section _specialOffsets Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods + IAccessibleText and IAccessibleEditableText can use one or more of the following + special offset values. They are defined in the ::IA2TextSpecialOffsets enum. + @li Using ::IA2_TEXT_OFFSET_LENGTH (-1) as an offset in any of the IAccessibleText or + IAccessibleEditableText methods is the same as specifying the length of the string. + @li Using ::IA2_TEXT_OFFSET_CARET (-2) as an offset for IAccessibleText::textBeforeOffset, + IAccessibleText::textAtOffset, and IAccessibleText::textAfterOffset indicates that the + text related to the physical location of the caret should be used. This is needed for + applications that consider the character offset of the end of one line (as reached by + pressing the End key) the same as the offset of the first character on the next line. + Since the same offset is associated with two different lines a special means is needed + to fetch text from the line where the caret is physically located. + + @section _dicoveringInterfaces Discovery of Interfaces + In general AT (Assistive Technology) should try IAccessible2 interfaces, followed by using + the MSAA (Microsoft® Active Accessibility®) interfaces. (In cases where the an application + is known to have custom interfaces which provide information not supplied by IAccessible2 + or MSAA, then those custom interfaces can be used.) The AT can then, by default, support + unknown IAccessible2/MSAA applications, without the application developers having to request + AT vendors for support on an individual application by application basis. + + When you have a reference to an IAccessible and require a reference to an IAccessible2 use + QueryService as follows: + @code + // pAcc is a reference to the accessible object's IAccessible interface. + IServiceProvider *pService = NULL; + hr = pAcc->QueryInterface(IID_IServiceProvider, (void **)&pService); + if(SUCCEEDED(hr)) { + IAccessible2 *pIA2 = NULL; + hr = pService->QueryService(IID_IAccessible, IID_IAccessible2, (void**)&pIA2); + if (SUCCEEDED(hr) && pIA2) { + // The control supports IAccessible2. + // pIA2 is the reference to the accessible object's IAccessible2 interface. + } + } + @endcode + + @section _changingInterfaces Changing between Accessible Interfaces + Note that developers must always implement MSAA's IAccessible and, if needed, some + of the interfaces in the set of IAccessible2 interfaces. Although the IAccessible2 + IDL is currently coded such that IAccessible2 is a subclass of MSAA's IAccessible, + none of MSAA's IAccessible methods are overridden or extended. In order to allow + future removal of the inheritance, Assistive Technologies (ATs) should not rely on + that inheritance. + + QueryService must be used to switch from a reference to an MSAA IAccessible interface + to another interface. This has been + <a href="http://www.accessinteropalliance.org/docs/Introducing_IAccessibleEx.doc"> + documented by Microsoft</a> and the pertinent facts have been extracted below: + + @par + Why use QueryService instead of just using QueryInterface to get IAccessibleEx + directly? The reason is that since MSAA 2.0, clients don't talk to a server's + IAccessible interface directly; instead they talk to an intermediate MSAA-provided + wrapper that calls through to the original IAccessible. This wrapper provides services + such as implementing IDispatch, supplying information from MSAA 2.0's Dynamic Annotation + service, and scaling locations when running on Windows Vista with DPI scaling enabled. + QueryService is the supported way to expose additional interfaces from an existing + IAccessible and was originally used by MSHTML to expose IHTMLElement objects corresponding + to IAccessibles. QueryService is often more convenient for servers to implement than + QueryInterface because it does not have the same requirements for preserving object + identity or symmetry/transitivity as QueryInterface, so QueryService allows servers to + easily implement the interface on the same object or a separate object. The latter is + often hard to do with QueryInterface unless the original object supports aggregation. + + Two related references in MSDN® are: + @li <a href="http://msdn.microsoft.com/en-us/library/ms696078(VS.85).aspx"> + "Using QueryService to expose a native object model interface for an IAccessible object"</a> + @li <a href="http://msdn.microsoft.com/en-us/library/ms528415.aspx#acc_obj"> + "Accessing the Internet Explorer Object Associated with an Accessible Object"</a> + + Based on this information from Microsoft, QueryService must be used to switch back and forth + between a reference to an MSAA IAccessible interface and any of the IAccessible2 interfaces. + + Regarding switching between any of the IAccessible2 interfaces, applications implementing + IAccessible2 should implement the IAccessible2 interfaces on a single object since ATs + will be using QueryInterface to switch between the IAccessilbe2 interfaces. Implementing + the IAccessible2 interfaces on separate objects would require the use of QueryService. + There is one exception, IAccessibleApplication can be implemented on a separate object so + its common code doesn't have to be included in each accessible object. ATs should use + QueryService to access IAccessibleApplication. + + @section _applicationInfo Access to Information about the Application + Servers implementing IAccessible2 should provide access to the IAccessibleApplication + interface via QueryService from any object so that ATs can easily determine specific + information about the application such as its name or version. + + @section _childIDs Child IDs + The IAccessible2 interfaces do not support child IDs, i.e. simple child elements. + Full accessible objects must be created for each object that supports IAccessible2. + Therefore MSAA's get_accChild should never return a child ID (other than CHILDID_SELF) + for an object that implements any of the IAccessible2 interfaces. + + Microsoft's UI Automation specification has the same limitation and this was resolved + in the UI Automation Express specification by adding IAccessibleEx::GetObjectForChild + and IAccessibleEx::GetIAccessiblePair. These methods allow mapping back and forth + between an IAccessibleEx and an {IAccessible, Child ID} pair. A future version of + IAccessible2 may include similar methods to map back and forth between an IAccessible2 + and an {IAccessible, Child ID} pair. + + @section _variants VARIANTs + Some methods return a VARIANT. Implementers need to make sure that the return type is + specified, i.e. VT_I4, VT_IDISPATCH, etc. The methods that return VARIANTs are + IAccessibleHyperlink::anchor, IAccessibleHyperlink::anchorTarget, IAccessibleValue::currentValue, + IAccessibleValue::maximumValue, IAccessibleValue::minimumValue. + + @section _iaaction-iahyperlink IAccessibleHyperlink as subclass of IAccessibleAction + In this version of the IDL, IAccessibleHyperlink is a subclass of IAccessibleAction. + However, there is no practical need for that inheritance and in some cases, such as + an image map of smart tags, it doesn't make sense because such an image map doesn't + have actionable objects; it's the secondary smart tags that are actionable. As a + result, implementations should not rely on the inheritance as it may be removed in + a later version of the IDL. + + @section _trademark Trademark Attribution + The names of actual companies and products mentioned herein may be the trademarks of + their respective owners. In particular, Active Accessibility, Microsoft, MSDN, and Win32 + are trademarks of the Microsoft group of companies in the U.S.A. and/or other countries. + +**/ + +import "objidl.idl"; +import "oaidl.idl"; +import "oleacc.idl"; + + + + +/** A structure defining the locale of an accessible object. + +IAccessible2::locale returns this struct. +*/ +typedef struct IA2Locale { + BSTR language; ///< ISO 639-1 Alpha-2 two character language code + BSTR country; ///< ISO 3166-1 Alpha-2 two character country code + BSTR variant; ///< Application specific variant of the locale +} IA2Locale; + +/** This interface must always be provided for objects that support some + portion of the collection of the %IAccessible2 interfaces. + + Please refer to @ref _changingInterfaces "Changing between Accessible Interfaces" + for special considerations related to use of the MSAA IAccessible interface and + the set of %IAccessible2 interfaces. + + */ +[object, uuid(E89F726E-C4F4-4c19-BB19-B647D7FA8478)] +interface IAccessible2 : IAccessible +{ + + /** @brief Returns the number of accessible relations for this object. + @param [out] nRelations + @retval S_OK + */ + [propget] HRESULT nRelations + ( + [out, retval] long *nRelations + ); + + /** @brief Returns one accessible relation for this object. + @param [in] relationIndex + 0 based + @param [out] relation + @retval S_OK + @retval E_INVALIDARG if bad [in] passed, [out] value is NULL + */ + [propget] HRESULT relation + ( + [in] long relationIndex, + [out, retval] IAccessibleRelation **relation + ); + + /** @brief Returns multiple accessible relations for this object. + @param [in] maxRelations + maximum size of the array allocated by the client + @param [out] relations + The array of accessible relation objects. Note that this array is to be + allocated by the client and freed when no longer needed. Refer to @ref + _arrayConsideration "Special Consideration when using Arrays" for more details. + @param [out] nRelations + actual number of relations in the returned array (not more than maxRelations) + @retval S_OK + @retval S_FALSE if there are no relations, nRelations is set to 0 + */ + [propget] HRESULT relations + ( + [in] long maxRelations, + [out, size_is(maxRelations), length_is(*nRelations)] + IAccessibleRelation **relations, + [out, retval] long *nRelations + ); + + /** @brief Returns the role of an %IAccessible2 object. + @param [out] role + The role of an %IAccessible2 object. + @retval S_OK + @note + @li For convenience MSAA roles are also passed through this method so the + AT doesn't have to also fetch roles through MSAA's get_accRole. + @li %IAccessible2 roles should not be passed through MSAA's get_accRole. + @li For compatibility with non IAccessible2 enabled ATs, IAccessible2 + applications should also add support to get_accRole to return the closest + MSAA role or ROLE_SYSTEM_CLIENT (the MSAA defined default role) if there + is not a good match. + @li This method is missing a [propget] prefix in the IDL. The result is the + method is named role in generated C++ code instead of get_role. + */ + HRESULT role + ( + [out, retval] long *role + ); + + /** @brief Makes an object visible on the screen. + @param [in] scrollType + Defines where the object should be placed on the screen. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT scrollTo + ( + [in] enum IA2ScrollType scrollType + ); + + /** @brief Moves the top left of an object to a specified location. + + @param [in] coordinateType + Specifies whether the coordinates are relative to the screen or the parent object. + @param [in] x + Defines the x coordinate. + @param [in] y + Defines the y coordinate. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT scrollToPoint + ( + [in] enum IA2CoordinateType coordinateType, + [in] long x, + [in] long y + ); + + /** @brief Returns grouping information. + + Used for tree items, list items, tab panel labels, radio buttons, etc. + Also used for collections of non-text objects. + + @param [out] groupLevel + 1 based, 0 indicates that this value is not applicable + @param [out] similarItemsInGroup + 1 based, 0 indicates that this value is not applicable + @param [out] positionInGroup + 1 based, 0 indicates that this value is not applicable. This is an index + into the objects in the current group, not an index into all the objects + at the same group level. + @retval S_OK if at least one value is valid + @retval S_FALSE if no values are valid + @note This method is meant to describe the nature of an object's containment + structure. This is normally not implemented on a combo box to describe the nature + of its contents. Normally an AT will get that information from its child list + object. However, in some cases when combo boxes are not able to be structured + such that the list is a child of the combo box, this method is implemented + on the combo box itself. ATs can use this interface if a child list is not found. + */ + [propget] HRESULT groupPosition + ( + [out] long *groupLevel, + [out] long *similarItemsInGroup, + [out, retval] long *positionInGroup + ); + + /** @brief Returns the bit strip containing any IAccessible2 states. + + The IAccessible2 states are in addition to the MSAA states and are defined in + the IA2States enum. + + @param [out] states + @retval S_OK + */ + [propget] HRESULT states + ( + [out, retval] AccessibleStates *states + ); + + /** @brief Returns the extended role. + + An extended role is a role which is dynamically generated by the application. + It is not predefined by the %IAccessible2 specification. + + @param [out] extendedRole + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + */ + [propget] HRESULT extendedRole + ( + [out, retval] BSTR *extendedRole + ); + + /** @brief Returns the localized extended role. + @param [out] localizedExtendedRole + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + */ + [propget] HRESULT localizedExtendedRole + ( + [out, retval] BSTR *localizedExtendedRole + ); + + /** @brief Returns the number of extended states. + @param [out] nExtendedStates + @retval S_OK + */ + [propget] HRESULT nExtendedStates + ( + [out, retval] long *nExtendedStates + ); + + /** @brief Returns the extended states (array of strings). + + An extended state is a state which is dynamically generated by the application. + It is not predefined by the %IAccessible2 specification. + + @param [in] maxExtendedStates + This parameter is ignored. Refer to @ref _arrayConsideration + "Special Consideration when using Arrays" for more details. + @param [out] extendedStates + This array is allocated by the server. Free it with CoTaskMemFree. + @param [out] nExtendedStates + The number of extended states returned; the size of the returned array. + @retval S_OK + @retval S_FALSE if there are no states, [out] values are NULL and 0 respectively + */ + [propget] HRESULT extendedStates + ( + [in] long maxExtendedStates, + [out, size_is(,maxExtendedStates), length_is(,*nExtendedStates)] BSTR **extendedStates, + [out, retval] long *nExtendedStates + ); + + /** @brief Returns the localized extended states (array of strings). + @param [in] maxLocalizedExtendedStates + This parameter is ignored. Refer to @ref _arrayConsideration + "Special Consideration when using Arrays" for more details. + @param [out] localizedExtendedStates + This array is allocated by the server. Free it with CoTaskMemFree. + @param [out] nLocalizedExtendedStates + The number of localized extended states returned; the size of the returned array. + @retval S_OK + @retval S_FALSE if there are no states, [out] values are NULL and 0 respectively + */ + [propget] HRESULT localizedExtendedStates + ( + [in] long maxLocalizedExtendedStates, + [out, size_is(,maxLocalizedExtendedStates), length_is(,*nLocalizedExtendedStates)] BSTR **localizedExtendedStates, + [out, retval] long *nLocalizedExtendedStates + ); + + /** @brief Returns the unique ID. + + The uniqueID is an identifier for this object, is unique within the + current window, and remains the same for the lifetime of the accessible + object. + + The uniqueID is not related to: + - the MSAA objectID which is used by the server to disambiguate between + IAccessibles per HWND or + - the MSAA childID which is used to disambiguate between children being + managed by an IAccessible. + + This value is provided so the AT can have access to a unique runtime persistent + identifier even when not handling an event for the object. + + An example of when this value is useful is if the AT wants to build a cache. + The AT could cache the uniqueIDs in addition to other data being cached. + When an event is fired the AT could map the uniqueID to its internal model. + Thus, if there's a REORDER/SHOW/HIDE event the AT knows which part of the + internal structure has been invalidated and can refetch just that part. + + This value can also be used by an AT to determine when the current control + has changed. If the role is the same for two controls that are adjacent in + the tab order, this can be used to detect the new control. + + Another use of this value by an AT is to identify when a grouping object has + changed, e.g. when moving from a radio button in one group to a radio button in a + different group. + + One means of implementing this would be to create a factory with a 32 bit number + generator and a reuse pool. The number generator would emit numbers starting + at 1. Each time an object's life cycle ended, its number would be saved into a + resuse pool. The number generator would be used whenever the reuse pool was empty. + + @param [out] uniqueID + @retval S_OK + */ + [propget] HRESULT uniqueID + ( + [out, retval] long *uniqueID + ); + + /** @brief Returns the window handle for the parent window which contains this object. + + This is the same window handle which will be passed for any events that occur on the + object, but is cached in the accessible object for use when it would be helpful to + access the window handle in cases where an event isn't fired on this object. + + A use case is when a screen reader is grabbing an entire web page on a page load. + Without the availability of windowHandle, the AT would have to get the window handle + by using WindowFromAccessibleObject on each IAccessible, which is slow because it's + implemented by oleacc.dll as a loop which crawls up the ancestor chain and looks for + a ROLE_WINDOW object, mapping that back to a window handle. + + @param [out] windowHandle + @retval S_OK + */ + [propget] HRESULT windowHandle + ( + [out, retval] HWND *windowHandle + ); + + /** @brief Returns the index of this object in its parent object. + @param [out] indexInParent + 0 based; -1 indicates there is no parent; the upper bound is the value + returned by the parent's IAccessible::get_accChildCount. + @retval S_OK + @retval S_FALSE if no parent, [out] value is -1 + */ + [propget] HRESULT indexInParent + ( + [out, retval] long *indexInParent + ); + + /** @brief Returns the IA2Locale of the accessible object. + @param [out] locale + @retval S_OK + */ + [propget] HRESULT locale + ( + [out, retval] IA2Locale *locale + ); + + /** @brief Returns the attributes specific to this %IAccessible2 object, such as a cell's formula. + @param [out] attributes + @retval S_OK + @retval S_FALSE returned if there is nothing to return, [out] value is NULL + */ + [propget] HRESULT attributes + ( + [out, retval] BSTR *attributes + ); + +} + +/************************************************************************* + * + * File Name (AccessibleComponent.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) Linux Foundation 2007, 2008 + * Copyright (c) IBM Corp. 2006 + * Copyright (c) Sun Microsystems, Inc. 2000, 2006 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02110-1301 USA + * + ************************************************************************/ + +import "objidl.idl"; +import "oaidl.idl"; +import "oleacc.idl"; + +/** A value specifying a color in ARGB format, where each 8 bit color component +specifies alpha, red, green, and blue respectively. The alpha value is optional. +*/ +typedef long IA2Color; + +/** @brief This interface is implemented by any object that can be rendered + on the screen. + + This interface provides the standard mechanism for an assistive technology + to retrieve information concerning the graphical representation of an object. + Coordinates used by the functions of this interface are specified in + different coordinate systems. Their scale is the same and is equal to + that of the screen coordinate system. In other words all coordinates + are measured in pixels. They differ in their respective origin: + <ul> + <li>The screen coordinate system has its origin in the upper left + corner of the current screen.</li> + <li>The origin of the parent coordinate system is the upper left corner + of the parent's bounding box. With no parent the screen coordinate + system is used instead.</li> + </ul> +*/ +[object, uuid(1546D4B0-4C98-4bda-89AE-9A64748BDDE4)] +interface IAccessibleComponent : IUnknown +{ + + /** @brief Returns the location of the upper left corner of the object's + bounding box relative to the immediate parent object. + + The coordinates of the bounding box are given relative to the parent's + coordinate system. The coordinates of the returned position are relative + to this object's parent or relative to the screen on which this object + is rendered if it has no parent. If the object is not on any screen + the returned position is (0,0). + + @param [out] x + @param [out] y + @retval S_OK + */ + [propget] HRESULT locationInParent + ( + [out] long *x, + [out, retval] long *y + ); + + /** @brief Returns the foreground color of this object. + @param [out] foreground + The returned color is the foreground color of this object or, if + that is not supported, the default foreground color. + @retval S_OK + */ + [propget] HRESULT foreground + ( + [out, retval] IA2Color *foreground + ); + + /** @brief Returns the background color of this object. + @param [out] background + The returned color is the background color of this object or, if + that is not supported, the default background color. + @retval S_OK + */ + [propget] HRESULT background + ( + [out, retval] IA2Color *background + ); +} +/************************************************************************* + * + * File Name (AccessibleValue) + * + * IAccessible2 IDL Specification + * + * Copyright (c) Linux Foundation 2007, 2008 + * Copyright (c) IBM Corp. 2006 + * Copyright (c) Sun Microsystems, Inc. 2000, 2006 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02110-1301 USA + * + ************************************************************************/ + +import "objidl.idl"; +import "oaidl.idl"; +import "oleacc.idl"; + +/** @brief This interface gives access to a single numerical value. + + The %IAccessibleValue interface represents a single numerical value and should + be implemented by any class that supports numerical value like progress bars + and spin boxes. This interface lets you access the value and its upper and + lower bounds. +*/ +[object, uuid(35855B5B-C566-4fd0-A7B1-E65465600394)] +interface IAccessibleValue : IUnknown +{ + + /** @brief Returns the value of this object as a number. + + The exact return type is implementation dependent. Typical types are long and + double. + @param [out] currentValue + Returns the current value represented by this object. See the section about + @ref _variants "VARIANTs" for additional information. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + */ + [propget] HRESULT currentValue + ( + [out, retval] VARIANT *currentValue + ); + + /** @brief Sets the value of this object to the given number. + + The argument is clipped to the valid interval whose upper and lower + bounds are returned by the methods IAccessibleValue::maximumValue and + IAccessibleValue::minimumValue, i.e. if it is lower than the minimum + value the new value will be the minimum and if it is greater than the + maximum then the new value will be the maximum. + + @param [out] value + The new value represented by this object. The set of admissible types for + this argument is implementation dependent. + @retval S_OK + */ + HRESULT setCurrentValue + ( + [in] VARIANT value + ); + + /** @brief Returns the maximal value that can be represented by this object. + + The type of the returned value is implementation dependent. It does not have + to be the same type as that returned by method IAccessibleValue::currentValue. + + @param [out] maximumValue + Returns the maximal value in an implementation dependent type. If this object + has no upper bound then an empty object is returned. See the section about + @ref _variants "VARIANTs" for additional information. + @retval S_OK + */ + [propget] HRESULT maximumValue + ( + [out, retval] VARIANT *maximumValue + ); + + /** @brief Returns the minimal value that can be represented by this object. + + The type of the returned value is implementation dependent. It does not have + to be the same type as that returned by method IAccessibleValue::currentValue. + + @param [out] minimumValue + Returns the minimal value in an implementation dependent type. If this object + has no lower bound then an empty object is returned. See the section about + @ref _variants "VARIANTs" for additional information. + @retval S_OK + */ + [propget] HRESULT minimumValue + ( + [out, retval] VARIANT *minimumValue + ); + +}; +/************************************************************************* + * + * File Name (AccessibleText.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) Linux Foundation 2007, 2008 + * Copyright (c) IBM Corp. 2006 + * Copyright (c) Sun Microsystems, Inc. 2000, 2006 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + ************************************************************************/ + +import "objidl.idl"; +import "oaidl.idl"; +import "oleacc.idl"; + + +/** A structure containing a substring and the start and end offsets in the enclosing string. + + IAccessibleText::newText and IAccessibleText::oldText return this struct. +*/ +typedef struct IA2TextSegment { + BSTR text; ///< A copy of a segment of text taken from an enclosing paragraph. + long start; ///< Index of the first character of the segment in the enclosing text. + long end; ///< Index of the character following the last character of the segment in the enclosing text. +} IA2TextSegment; + +/** This enum defines values which specify a text boundary type. + + IA2_TEXT_BOUNDARY_SENTENCE is optional. When a method doesn't implement this + method it must return S_FALSE. Typically this feature would not be implemented + by an application. However, if the application developer was not satisfied with + how screen readers have handled the reading of sentences this boundary type + could be implemented and screen readers could use the application's version of a + sentence rather than the screen reader's. + + The rest of the boundary types must be supported. + + This enum is used in IAccessibleText::textBeforeOffset, IAccessibleText::textAtOffset, + and IAccessibleText::textAfterOffset. +*/ + +enum IA2TextBoundaryType { + IA2_TEXT_BOUNDARY_CHAR, /**< Typically, a single character is returned. In some cases more than + one character is returned, for example, when a document contains field + data such as a field containing a date, time, or footnote reference. + In this case the caret can move over several characters in one movement + of the caret. Note that after the caret moves, the caret offset changes + by the number of characters in the field, e.g. by 8 characters in the + following date: 03/26/07. */ + IA2_TEXT_BOUNDARY_WORD, /**< The range provided matches the range observed when the application + processes the Ctrl + left arrow and Ctrl + right arrow key sequences. + Typically this is from the start of one word to the start of the next, but + various applications are inconsistent in the handling of the end of a line. */ + IA2_TEXT_BOUNDARY_SENTENCE, ///< Range is from start of one sentence to the start of another sentence. + IA2_TEXT_BOUNDARY_PARAGRAPH, ///< Range is from start of one paragraph to the start of another paragraph. + IA2_TEXT_BOUNDARY_LINE, /**< Range is from start of one line to the start of another line. This + often means that an end-of-line character will appear at the end of the + range. However in the case of some applications an end-of-line character + indicates the end of a paragraph and the lines composing the paragraph, + other than the last line, do not contain an end of line character. */ + IA2_TEXT_BOUNDARY_ALL ///< Using this value will cause all text to be returned. +}; + +/** @brief This interface gives read-only access to text. + + The %IAccessibleText interface should be implemented by all components + that present textual information on the display like buttons, + text entry fields, or text portions of the document window. The interface + provides access to the text's content, attributes, and spatial location. + However, text can not be modified with this interface. That is the task + of the IAccessibleEditableText interface. + + The text length, i.e. the number of characters in the text, is + returned by IAccessibleText::nCharacters. All methods that operate + on particular characters (e.g. IAccessibleText::textAtOffset) use character + indices from 0 to length-1. All methods that operate on character positions + (e.g. IAccessibleText::text) use indices from 0 to length. + + Please note that accessible text does not necessarily support selection. + In this case it should behave as if there where no selection. An empty + selection is used for example to express the current cursor position. + + Refer to @ref _specialOffsets + "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" + for information about special offsets that can be used in %IAccessibleText methods. + + E_FAIL is returned in the following cases + @li endOffset < startOffset + @li endoffset > length +*/ +[object, uuid(24FD2FFB-3AAD-4a08-8335-A3AD89C0FB4B)] +interface IAccessibleText : IUnknown +{ + + /** @brief Adds a text selection + @param [in] startOffset + Starting offset ( 0 based). + @param [in] endOffset + Offset of first character after new selection (0 based). + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT addSelection + ( + [in] long startOffset, + [in] long endOffset + ); + + /** @brief Returns text attributes. + @param [in] offset + Text offset (0 based) + @param [out] startOffset + The starting offset of the character range over which all text attributes match + those of offset. (0 based) + @param [out] endOffset + The offset of the first character past the character range over which all text + attributes match those of offset. (0 based) + @param [out] textAttributes + A string of attributes describing the text. The attributes are described in the + <a href="http://www.linuxfoundation.org/en/Accessibility/IAccessible2/TextAttributes"> + text attributes specification</a> on the %IAccessible2 web site. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] values are 0s and NULL respectively + @retval E_INVALIDARG if bad [in] passed, [out] values are 0s and NULL respectively + + */ + [propget] HRESULT attributes + ( + [in] long offset, + [out] long *startOffset, + [out] long *endOffset, + [out, retval] BSTR *textAttributes + ); + + /** @brief Returns the position of the caret. + + Returns the 0-based offset of the caret within the text. If the text is + implemented as a tree of text objects with embed characters in higher levels + representing substrings of child text objects and the caret is in one of the + child text objects, then the offset in the higher level text object would be + at the embed character representing child text object that contains the caret. + + For example, if the string "one two three" is implemented as a two text objects, + with a top level text object containing an embed character "one ? three" and a + child text object containing "two" and if the caret is in the descendant object + just before the 'o' in "two", then: + <ul> + <li>the caretOffset for the "one ? three" object would be 4, matching the embed character</li> + <li>the caretOffset for "two" would be 2, matching the "o"</li> + </ul> + The caret position/offset is that of the character logically following it, e.g. + to the right of it in a left to right language. + @param [out] offset + The returned offset is relative to the text represented by this object. + @retval S_OK + @retval S_FALSE if the caret is not currently active on this object, i.e. the + caret is located on some other object. The returned offset value will be -1. + @note S_FALSE (and an offset of -1) will not be returned if the caret is somewhere + in the text object or one of its descendants. + */ + [propget] HRESULT caretOffset + ( + [out, retval] long *offset + ); + + + /** @brief Returns the bounding box of the specified position. + + The virtual character after the last character of the represented + text, i.e. the one at position length is a special case. It represents the + current input position and will therefore typically be queried by AT more + often than other positions. Because it does not represent an existing character + its bounding box is defined in relation to preceding characters. It should be + roughly equivalent to the bounding box of some character when inserted at the + end of the text. Its height typically being the maximal height of all the + characters in the text or the height of the preceding character, its width being + at least one pixel so that the bounding box is not degenerate. + + Note that the index 'length' is not always valid. Whether it is or not is + implementation dependent. It typically is when text is editable or otherwise + when on the screen the caret can be placed behind the text. You can be sure + that the index is valid after you have received a ::IA2_EVENT_TEXT_CARET_MOVED + event for this index. + @param [in] offset + Index of the character for which to return its bounding box. The valid range + is 0..length. + @param [in] coordType + Specifies if the coordinates are relative to the screen or to the parent window. + @param [out] x + X coordinate of the top left corner of the bounding box of the referenced character. + @param [out] y + Y coordinate of the top left corner of the bounding box of the referenced character. + @param [out] width + Width of the bounding box of the referenced character. + @param [out] height + Height of the bounding box of the referenced character. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed, [out] values are 0s + */ + [propget] HRESULT characterExtents + ( + [in] long offset, + [in] enum IA2CoordinateType coordType, + [out] long *x, + [out] long *y, + [out] long *width, + [out, retval] long *height + ); + + + /** @brief Returns the number of active non-contiguous selections + @param [out] nSelections + @retval S_OK + */ + [propget] HRESULT nSelections + ( + [out, retval] long *nSelections + ); + + /** @brief Returns the text position for the specified screen position. + + Given a point return the zero-based index of the character under that + point. The same functionality could be achieved by using the bounding + boxes for each character as returned by IAccessibleText::characterExtents. + The method IAccessibleText::offsetAtPoint, however, can be implemented + more efficiently. + + @param [in] x + The position's x value for which to look up the index of the character that + is rendered on to the display at that point. + @param [in] y + The position's y value for which to look up the index of the character that + is rendered on to the display at that point. + @param [in] coordType + Screen coordinates or window coordinates. + @param [out] offset + Index of the character under the given point or -1 if the point + is invalid or there is no character under the point. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed, [out] value is 0 + */ + [propget] HRESULT offsetAtPoint + ( + [in] long x, + [in] long y, + [in] enum IA2CoordinateType coordType, + [out, retval] long *offset + ); + + /** @brief Returns the character offsets of Nth active text selection + @param [in] selectionIndex + Index of selection (0 based). + @param [out] startOffset + 0 based offset of first selected character + @param [out] endOffset + 0 based offset of one past the last selected character. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] values are 0s + @retval E_INVALIDARG if bad [in] passed, [out] values are 0s + */ + [propget] HRESULT selection + ( + [in] long selectionIndex, + [out] long *startOffset, + [out, retval] long *endOffset + ); + + /** @brief Returns the substring between the two given indices. + + The substring starts with the character at startOffset (inclusive) and up to + the character at endOffset (exclusive), if startOffset is less or equal + endOffste. If endOffset is lower than startOffset, the result is the same + as a call with the two arguments being exchanged. + + The whole text can be requested by passing the indices zero and + IAccessibleText::nCharacters. If both indices have the same value, an empty + string is returned. + @param [in] startOffset + Index of the first character to include in the returned string. The valid range + is 0..length. + @param [in] endOffset + Index of the last character to exclude in the returned string. The valid range + is 0..length. + @param [out] text + Returns the substring starting with the character at startOffset (inclusive) + and up to the character at endOffset (exclusive), if startOffset is less than + or equal to endOffset. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed, [out] value is NULL + @note The returned string may be longer than endOffset-startOffset bytes if text + contains multi-byte characters. + */ + [propget] HRESULT text + ( + [in] long startOffset, + [in] long endOffset, + [out, retval] BSTR *text + ); + + /** @brief Returns a text portion before the given position. + + Returns the substring of the specified text type that is located before the + given character and does not include it. The result of this method should be + same as a result for IAccessibleText::textAtOffset with a suitably decreased + index value. + + For example, if text type is ::IA2_TEXT_BOUNDARY_WORD, then the complete + word that is closest to and located before offset is returned. + + If the index is valid, but no suitable word (or other boundary type) is found, a + NULL pointer is returned. + + @param [in] offset + Index of the character for which to return the text part before it. The index + character will not be part of the returned string. The valid range is 0..length. + @param [in] boundaryType + The type of the text portion to return. See ::IA2TextBoundaryType for the + complete list. + @param [out] startOffset + 0 based offset of first character. + @param [out] endOffset + 0 based offset of one past the last character. + @param [out] text + Returns the requested text portion. This portion may be empty or invalid when + no appropriate text portion is found or text type is invalid. + @retval S_OK + @retval S_FALSE if the requested boundary type is not implemented, such as + ::IA2_TEXT_BOUNDARY_SENTENCE, or if there is nothing to return; + [out] values are 0s and NULL respectively + @retval E_INVALIDARG if bad [in] passed, [out] values are 0s and NULL respectively + */ + [propget] HRESULT textBeforeOffset + ( + [in] long offset, + [in] enum IA2TextBoundaryType boundaryType, + [out] long *startOffset, + [out] long *endOffset, + [out, retval] BSTR *text + ); + + /** @brief Returns a text portion after the given position. + + Returns the substring of the specified text type that is located after the + given character and does not include it. The result of this method should be + same as a result for IAccessibleText::textAtOffset with a suitably increased + index value. + + For example, if text type is ::IA2_TEXT_BOUNDARY_WORD, then the complete + word that is closest to and located after offset is returned. + + If the index is valid, but no suitable word (or other text type) is found, a + NULL pointer is returned. + + @param [in] offset + Index of the character for which to return the text part before it. The index + character will not be part of the returned string. The valid range is 0..length. + @param [in] boundaryType + The type of the text portion to return. See ::IA2TextBoundaryType for the complete + list. + @param [out] startOffset + 0 based offset of first character. + @param [out] endOffset + 0 based offset of one past the last character. + @param [out] text + Returns the requested text portion. This portion may be empty or invalid when + no appropriate text portion is found or text type is invalid. + @retval S_OK + @retval S_FALSE if the requested boundary type is not implemented, such as + ::IA2_TEXT_BOUNDARY_SENTENCE, or if there is nothing to return; + [out] values are 0s and NULL respectively + @retval E_INVALIDARG if bad [in] passed, [out] values are 0s and NULL respectively + */ + [propget] HRESULT textAfterOffset + ( + [in] long offset, + [in] enum IA2TextBoundaryType boundaryType, + [out] long *startOffset, + [out] long *endOffset, + [out, retval] BSTR *text + ); + + /** @brief Returns a text portion that spans the given position. + + Returns the substring of the specified text type at the specified offset. + + If the index is valid, but no suitable word (or other text type) is found, a + NULL pointer is returned. + + @param [in] offset + Index of the character for which to return the text part before it. The index + character will not be part of the returned string. The valid range is 0..length. + @param [in] boundaryType + The type of the text portion to return. See ::IA2TextBoundaryType for the complete + list. + @param [out] startOffset + 0 based offset of first character. + @param [out] endOffset + 0 based offset of one past the last character. + @param [out] text + Returns the requested text portion. This portion may be empty or invalid when + no appropriate text portion is found or text type is invalid. + @retval S_OK + @retval S_FALSE if the requested boundary type is not implemented, such as + ::IA2_TEXT_BOUNDARY_SENTENCE, or if there is nothing to return; + [out] values are 0s and NULL respectively + @retval E_INVALIDARG if bad [in] passed, [out] values are 0s and NULL respectively + */ + [propget] HRESULT textAtOffset + ( + [in] long offset, + [in] enum IA2TextBoundaryType boundaryType, + [out] long *startOffset, + [out] long *endOffset, + [out, retval] BSTR *text + ); + + /** @brief Unselects a range of text. + @param [in] selectionIndex + Index of selection to remove (0 based). + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT removeSelection + ( + [in] long selectionIndex + ); + + /** @brief Sets the position of the caret. + + The caret position/offset is that of the character logically following it, + e.g. to the right of it in a left to right language. + + Setting the caret position may or may not alter the current selection. A + change of the selection is notified to the accessibility event listeners with + an ::IA2_EVENT_TEXT_SELECTION_CHANGED event. + + When the new caret position differs from the old one (which, of course, is the + standard case) this is notified to the accessibility event listeners with an + ::IA2_EVENT_TEXT_CARET_MOVED event. + @param [in] offset + The new index of the caret. This caret is actually placed to the left side of + the character with that index. An index of 0 places the caret so that the next + insertion goes before the first character. An index of IAccessibleText::nCharacters + leads to insertion after the last character. + @retval S_OK + @retval E_FAIL if the caret cannot be set + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT setCaretOffset + ( + [in] long offset + ); + + /** @brief Changes the bounds of an existing selection. + @param [in] selectionIndex + Index of selection to change (0 based) + @param [in] startOffset + New starting offset (0 based) + @param [in] endOffset + New ending offset (0 based) - the offset of the character just past the last character of the selection. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT setSelection + ( + [in] long selectionIndex, + [in] long startOffset, + [in] long endOffset + ); + + /** @brief Returns total number of characters. + + Note that this may be different than the total number of bytes required to store the + text, if the text contains multi-byte characters. + @param [out] nCharacters + @retval S_OK + */ + [propget] HRESULT nCharacters + ( + [out, retval] long *nCharacters + ); + + /** @brief Makes a specific part of string visible on screen. + @param [in] startIndex + 0 based character offset. + @param [in] endIndex + 0 based character offset - the offset of the character just past the last character of the string. + @param [in] scrollType + Defines where the object should be placed on the screen. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT scrollSubstringTo + ( + [in] long startIndex, + [in] long endIndex, + [in] enum IA2ScrollType scrollType + ); + + /** @brief Moves the top left of a substring to a specified location. + + @param [in] startIndex + 0 based character offset. + @param [in] endIndex + 0 based character offset - the offset of the character just past the last character of the string. + @param [in] coordinateType + Specifies whether the coordinates are relative to the screen or the parent object. + @param [in] x + Defines the x coordinate. + @param [in] y + Defines the y coordinate. + @retval S_OK + @retval S_FALSE if the object is already at the specified location. + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT scrollSubstringToPoint + ( + [in] long startIndex, + [in] long endIndex, + [in] enum IA2CoordinateType coordinateType, + [in] long x, + [in] long y + ); + + /** @brief Returns any inserted text. + + Provided for use by the ::IA2_EVENT_TEXT_INSERTED and ::IA2_EVENT_TEXT_UPDATED + event handlers. + + This data is only guaranteed to be valid while the thread notifying the event + continues. Once the handler has returned, the validity of the data depends on + how the server manages the life cycle of its objects. Also, note that the server + may have different life cycle management strategies for controls depending on + whether or not a control manages its children. Lists, trees, and tables can have + a large number of children and thus it's possible that the child objects for those + controls would only be created as needed. Servers should document their life cycle + strategy as this will be of interest to assistive technology or script engines + accessing data out of process or from other threads. Servers only need to save the + last inserted block of text and a scope of the entire application is adequate. + + @param [out] newText + The text that was just inserted. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + */ + [propget] HRESULT newText + ( + [out, retval] IA2TextSegment *newText + ); + + /** @brief Returns any removed text. + + Provided for use by the IA2_EVENT_TEXT_REMOVED/UPDATED event handlers. + + This data is only guaranteed to be valid while the thread notifying the event + continues. Once the handler has returned, the validity of the data depends on + how the server manages the life cycle of its objects. Also, note that the server + may have different life cycle management strategies for controls depending on + whether or not a control manages its children. Lists, trees, and tables can have + a large number of children and thus it's possible that the child objects for those + controls would only be created as needed. Servers should document their life cycle + strategy as this will be of interest to assistive technology or script engines + accessing data out of process or from other threads. Servers only need to save the + last removed block of text and a scope of the entire application is adequate. + + @param [out] oldText + The text that was just removed. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + */ + [propget] HRESULT oldText + ( + [out, retval] IA2TextSegment *oldText + ); + +} +/************************************************************************* + * + * File Name (AccessibleEditableText.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) Linux Foundation 2007, 2008 + * Copyright (c) IBM Corp. 2006 + * Copyright (c) Sun Microsystems, Inc. 2000, 2006 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + ************************************************************************/ + +import "objidl.idl"; +import "oaidl.idl"; +import "oleacc.idl"; + + +/** @brief This interface provides clipboard capability to text objects. + + This interface is typically used in conjunction with the IAccessibleText + interface and complements that interface with the additional capability of + clipboard operations. Note that even a read only text object can support + the copy capability so this interface is not limited to editable objects. + + The substrings used with this interface are specified as follows: + If startOffset is less than endOffset, the substring starts with the + character at startOffset and ends with the character just before endOffset. + If endOffset is lower than startOffset, the result is the same as a call + with the two arguments exchanged. The whole text can be defined by passing + the indices zero and IAccessibleText::nCharacters. If both indices have the + same value, an empty string is defined. + + Refer to the @ref _specialOffsets + "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" + for information about a special offset constant that can be used in %IAccessibleEditableText methods. +*/ +[object, uuid(A59AA09A-7011-4b65-939D-32B1FB5547E3)] +interface IAccessibleEditableText : IUnknown +{ + + /** @brief Copies the text range into the clipboard. + + The specified text between the two given indices is copied into the + system clipboard. + + @param [in] startOffset + Start index of the text to moved into the clipboard. + The valid range is 0..length. + @param [in] endOffset + End index of the text to moved into the clipboard. + The valid range is 0..length. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT copyText + ( + [in] long startOffset, + [in] long endOffset + ); + + /** @brief Deletes a range of text. + + The text between and including the two given indices is deleted + from the text represented by this object. + + @param [in] startOffset + Start index of the text to be deleted. + The valid range is 0..length. + @param [in] endOffset + End index of the text to be deleted. + The valid range is 0..length. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT deleteText + ( + [in] long startOffset, + [in] long endOffset + ); + + /** @brief Inserts text at the specified position. + + The specified string is inserted at the given index into the text + represented by this object. + + @param [in] offset + Index at which to insert the text. + The valid range is 0..length. + @param [in] text + Text that is inserted. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT insertText + ( + [in] long offset, + [in] BSTR *text + ); + + /** @brief Deletes a range of text and copies it to the clipboard. + + The text between the two given indices is deleted from the text + represented by this object and copied to the clipboard. + + @param [in] startOffset + Start index of the text to be deleted. + The valid range is 0..length. + @param [in] endOffset + End index of the text to be deleted. + The valid range is 0..length. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT cutText + ( + [in] long startOffset, + [in] long endOffset + ); + + /** @brief Pastes text from the clipboard. + + The text in the system clipboard is pasted into the text represented + by this object at the given index. This method is similar to the + IAccessibleEditableText::insertText method. If the index is not valid + the system clipboard text is not inserted. + + @param [in] offset + Index at which to insert the text from the system clipboard into + the text represented by this object. + The valid range is 0..length. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT pasteText + ( + [in] long offset + ); + + /** @brief Replaces text. + + The text between the two given indices is replaced by the specified + replacement string. This method is equivalent to calling first + IAccessibleEditableText::deleteText with the two indices and then + calling IAccessibleEditableText::insertText with the replacement text + at the start index. + + @param [in] startOffset + Start index of the text to be replaced. + The valid range is 0..length. + @param [in] endOffset + Start index of the text to be replaced. + The valid range is 0..length. + @param [in] text + The Text that replaces the text between the given indices. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT replaceText + ( + [in] long startOffset, + [in] long endOffset, + [in] BSTR *text + ); + + /** @brief Replaces the attributes of a text range by the given set of attributes. + + Sets the attributes for the text between the two given indices. The old + attributes are replaced by the new list of attributes. + + @param [in] startOffset + Start index of the text whose attributes are modified. + The valid range is 0..length. + @param [in] endOffset + Start index of the text whose attributes are modified. + The valid range is 0..length. + @param [in] attributes + Set of attributes that replaces the old list of attributes of + the specified text portion. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT setAttributes + ( + [in] long startOffset, + [in] long endOffset, + [in] BSTR *attributes + ); +} + +/************************************************************************* + * + * File Name (AccessibleHyperlink.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) Linux Foundation 2007, 2008 + * Copyright (c) IBM Corp. 2006 + * Copyright (c) Sun Microsystems, Inc. 2000, 2006 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02110-1301 USA + * + ************************************************************************/ + +import "objidl.idl"; +import "oaidl.idl"; +import "oleacc.idl"; + + +/** @brief This interface represents hyperlinks. + + This interface represents a hyperlink associated with a single substring + of text or single non-text object. Non-text objects can have either a + single link or a collection of links such as when the non-text object is + an image map. + + Linked objects and anchors are implementation dependent. This interface is derived + from IAccessibleAction. IAccessibleAction::nActions is one greater than the + maximum value for the indices used with the methods of this interface. + + Furthermore, the object that implements this interface has to be connected + implicitly or explicitly with an object that implements IAccessibleText. + IAccessibleHyperlink::startIndex and IAccessibleHyperlink::endIndex are + indices with respect to the text exposed by IAccessibleText. + + This interface provides access to a single object which can have multiple actions. + An example is an image map which is an image with multiple links each of which is + associated with a separate non-overlapping area of the image. This interface could + also be applied to other kinds of objects with multiple actions such as "smart tags" + which are objects, typically strings, which have multiple actions such as + "Activate URI", "Bookmark URI", etc. + + An interesting use case is an image map where each area is associated with multiple + actions, e.g. an image map of smart tags. In this case you would have to implement + two levels of accessible hyperlinks. The first level hyperlinks would only implement + anchor and anchorTarget. The anchors would all reference the image object. The + anchorTargets would reference the second level accessible hyperlink objects. None + of the IAccessibleAction methods would be implemented on the first level hyperlink + objects. The second level hyperlink objects would implement the IAccessibleAction + methods. Their anchors would also reference the image object and their anchorTargets + would reference URLs or the objects that would be activated. + + This use case demonstrates that in some cases there is no need for IAccessibleHyperlink + to derive from IAccessibleAction. As a result it may be removed in a later version of + the IDL and it is suggested that implementations should not rely on the inheritance. + +*/ +[object, uuid(01C20F2B-3DD2-400f-949F-AD00BDAB1D41)] +interface IAccessibleHyperlink : IAccessibleAction +{ + + /** @brief Returns an object that represents the link anchor, as appropriate + for the link at the specified index. + @param [in] index + A 0 based index identifies the anchor when, as in the case of an image map, + there is more than one link represented by this object. The valid maximal + index is indicated by IAccessibleAction::nActions. + @param [out] anchor + This is an implementation dependent value. For example, for a text link this + method could return the substring of the containing string where the substring + is overridden with link behavior, and for an image link this method could return + an IUnknown VARIANT for IAccessibleImage. See the section about + @ref _variants "VARIANTs" for additional information. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + @retval E_INVALIDARG if bad [in] passed, [out] value is NULL + */ + [propget] HRESULT anchor + ( + [in] long index, + [out, retval] VARIANT *anchor + ); + + /** @brief Returns an object representing the target of the link, as appropriate + for the link at the specified index. + @param [in] index + A 0 based index identifies the anchor when, as in the case of an image map, + there is more than one link represented by this object. The valid maximal + index is indicated by IAccessibleAction::nActions. + @param [out] anchorTarget + This is an implementation dependent value. For example this method could + return a BSTR VARIANT of the URI. Alternatively this method could return an + IUnknown VARIANT of a COM interface representing a target object to be + activated when the link is activated. See the section about + @ref _variants "VARIANTs" for additional information. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + @retval E_INVALIDARG if bad [in] passed, [out] value is NULL + */ + [propget] HRESULT anchorTarget + ( + [in] long index, + [out, retval] VARIANT *anchorTarget + ); + + /** @brief Returns the 0 based character offset at which the textual representation of the hyperlink starts. + + The returned value is related to the IAccessibleText interface of the object that + owns this hyperlink. + @param [out] index + @retval S_OK + */ + [propget] HRESULT startIndex + ( + [out, retval] long *index + ); + + /** @brief Returns the 0 based character offset at which the textual representation of the hyperlink ends. + + The returned value is related to the IAccessibleText interface of the object that + owns this hyperlink. The character at the index is not part of the hypertext. + @param [out] index + @retval S_OK + */ + [propget] HRESULT endIndex + ( + [out, retval] long *index + ); + + /** @brief Returns whether the target object referenced by this link is still valid. + + This is a volatile state that may change without sending an appropriate event. + Returns TRUE if the referenced target is still valid and FALSE otherwise. + + This has also been used to indicate whether or not the URI of the anchorTarget + is malformed. + + Note: This method is not being used, is deprecated, and should not be implemented or + used. It is likely that this method will be removed in a later version of the IDL. + + @param [out] valid + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is FALSE + */ + [propget] HRESULT valid + ( + [out, retval] boolean *valid + ); +} +/************************************************************************* + * + * File Name (AccessibleHypertext.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) Linux Foundation 2007, 2008 + * Copyright (c) IBM Corp. 2006 + * Copyright (c) Sun Microsystems, Inc. 2000, 2006 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02110-1301 USA + * + ************************************************************************/ + +import "objidl.idl"; +import "oaidl.idl"; +import "oleacc.idl"; + + + +/** @brief This interface exposes information about hypertext in a document. + + The %IAccessibleHypertext interface is the main interface to expose + hyperlinks in a document, typically a text document, that are used + to reference other documents. A typical implementation is to implement + this interface on the smallest text object such as a paragraph of text. +*/ +[object, uuid(6B4F8BBF-F1F2-418a-B35E-A195BC4103B9)] +interface IAccessibleHypertext : IAccessibleText +{ + + /** @brief Returns the number of links and link groups contained within this hypertext + paragraph. + @param [out] hyperlinkCount + The number of links and link groups within this hypertext paragraph. + Returns 0 if there is no link. + @retval S_OK + */ + [propget] HRESULT nHyperlinks + ( + [out, retval] long *hyperlinkCount + ); + + /** @brief Returns the specified link. + + The returned IAccessibleHyperlink object encapsulates the hyperlink and + provides several kinds of information describing it. + @param [in] index + This 0 based index specifies the hyperlink to return. + @param [out] hyperlink + If the given index is valid, i.e. lies in the interval from 0 to the number + of links minus one, a reference to the specified hyperlink object is returned. + If the index is invalid then a NULL pointer is returned. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed, [out] value is NULL + */ + [propget] HRESULT hyperlink + ( + [in] long index, + [out, retval] IAccessibleHyperlink **hyperlink + ); + + /** @brief Returns the index of the hyperlink that is associated with this character index. + + This is the case when a link spans the given character index. + @param [in] charIndex + A 0 based index of the character for which to return the link index. If + IAccessibleText is used to represent the text containing the link, then the + character index is only valid if it is greater than or equal to zero and + lower than the number of characters in the text. + @param [out] hyperlinkIndex + Returns the 0 based index of the hyperlink that is associated with this + character index, or -1 if charIndex is not on a link. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is -1 + @retval E_INVALIDARG if bad [in] passed, [out] value is NULL + */ + [propget] HRESULT hyperlinkIndex + ( + [in] long charIndex, + [out, retval] long *hyperlinkIndex + ); + +} +/************************************************************************* + * + * File Name (AccessibleTable.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) Linux Foundation 2007, 2009 + * Copyright (c) IBM Corp. 2006 + * Copyright (c) Sun Microsystems, Inc. 2000, 2006 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + ************************************************************************/ + +import "objidl.idl"; +import "oaidl.idl"; +import "oleacc.idl"; + + + +/** @brief This interface gives access to a two-dimensional table. + + Typically all accessible objects that represent cells or cell-clusters of a table + will be at the same time children of the table. In this case IAccessible2::indexInParent + will return the child index which then can be used when calling IAccessibleTable::rowIndex + and IAccessibleTable::columnIndex. + + However, in some cases that kind of implementation will not be possible. When + the table cells are not direct children of a table, the object representing + the cell can define a "table-cell-index" object attribute identifying the 0 + based table cell index. This object attribute is obtained by parsing the + attribute string returned by IAccessible2::attributes. The "table-cell-index" + attribute can be used just like a child index of the typical case. ATs should + first test for the presence of the "table-cell-index" attribute and if it is not + present then IAccessible2::indexInParent can be used as in the typical case + where cells are direct children of the table. + + The range of valid coordinates for this interface are implementation dependent. + However, that range includes at least the intervals from the from the first row + or column with the index 0 up to the last (but not including) used row or column + as returned by IAccessibleTable::nRows and IAccessibleTable::nColumns. + + Note that newer implementations are now using IAccessibleTable2 and IAccessibleTableCell + rather than this interface. +*/ +[object, uuid(35AD8070-C20C-4fb4-B094-F4F7275DD469)] +interface IAccessibleTable : IUnknown +{ + + /** @brief Returns the accessible object at the specified row and column in + the table. This object could be an IAccessible or an IAccessible2. + @param [in] row + The 0 based row index for which to retrieve the cell. + @param [in] column + The 0 based column index for which to retrieve the cell. + @param [out] accessible + If both row and column index are valid then the corresponding accessible + object is returned that represents the requested cell regardless of whether + the cell is currently visible (on the screen). + @retval S_OK + @retval E_INVALIDARG if bad [in] passed, [out] value is NULL + */ + [propget] HRESULT accessibleAt + ( + [in] long row, + [in] long column, + [out, retval] IUnknown **accessible + ); + + /** @brief Returns the caption for the table. The returned object could be + an IAccessible or an IAccessible2. + @param [out] accessible + If the table has a caption then a reference to it is returned, else a NULL + pointer is returned. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + */ + [propget] HRESULT caption + ( + [out, retval] IUnknown **accessible + ); + + /** @brief Translates the given row and column indexes into the corresponding cell index. + @param [in] rowIndex + 0 based row index for the cell. + @param [in] columnIndex + 0 based column index for the cell. + @param [out] cellIndex + Returns the 0 based index of the cell at the specified row and column indexes. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed, [out] value is 0 + @note The returned value is not necessarily a child index of the immediate parent. + In cases where the table cells are not direct children of the table the index + is actually the cell index, i.e. conceptually it's an index into a one dimensional + array of cells laid out in row order. + */ + [propget] HRESULT childIndex + ( + [in] long rowIndex, + [in] long columnIndex, + [out, retval] long *cellIndex + ); + + /** @brief Returns the description text of the specified column in the table. + @param [in] column + The 0 based index of the column for which to retrieve the description. + @param [out] description + Returns the description text of the specified column in the table if such a + description exists. Otherwise a NULL pointer is returned. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + @retval E_INVALIDARG if bad [in] passed, [out] value is NULL + */ + [propget] HRESULT columnDescription + ( + [in] long column, + [out, retval] BSTR *description + ); + + /** @brief Returns the number of columns occupied by the accessible object + at the specified row and column in the table. + + The result is greater than 1 if the specified cell spans multiple columns. + @param [in] row + 0 based row index of the accessible for which to return the column extent. + @param [in] column + 0 based column index of the accessible for which to return the column extent. + @param [out] nColumnsSpanned + Returns the 1 based column extent of the specified cell. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed, [out] value is 0 + */ + [propget] HRESULT columnExtentAt + ( + [in] long row, + [in] long column, + [out, retval] long *nColumnsSpanned + ); + + /** @brief Returns the column headers as an %IAccessibleTable object. + + Content and size of the returned table are implementation dependent. + @param [out] accessibleTable + The column header + @param [out] startingRowIndex + The 0 based row index where the header starts, usually 0. + @retval S_OK + @retval S_FALSE if there is no header, [out] values are NULL and 0 respectively + */ + [propget] HRESULT columnHeader + ( + [out] IAccessibleTable **accessibleTable, + [out, retval] long *startingRowIndex + ); + + /** @brief Translates the given cell index into the corresponding column index. + @param [in] cellIndex + 0 based index of the cell in the parent or closest ancestor table. Typically this + is the value returned from IAccessible2::indexInParent, but in the case where the + table cells are not direct children of the table this is the cell index specified + by the "table-cell-index" object attribute obtained from parsing the attributes + string returned by calling IAccessible2::attributes on the cell object. + @param [out] columnIndex + Returns the 0 based column index of the cell of the specified child or the index of + the first column if the child spans multiple columns. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed, [out] value is 0 + */ + [propget] HRESULT columnIndex + ( + [in] long cellIndex, + [out, retval] long *columnIndex + ); + + /** @brief Returns the total number of columns in table + @param [out] columnCount + Number of columns in table (including columns outside the current viewport) + @retval S_OK + */ + [propget] HRESULT nColumns + ( + [out, retval] long *columnCount + ); + + /** @brief Returns the total number of rows in table + @param [out] rowCount + Number of rows in table (including rows outside the current viewport) + @retval S_OK + */ + [propget] HRESULT nRows + ( + [out, retval] long *rowCount + ); + + /** @brief Returns the total number of selected cells + @param [out] cellCount + Number of cells currently selected + @retval S_OK + */ + [propget] HRESULT nSelectedChildren + ( + [out, retval] long *cellCount + ); + + /** @brief Returns the total number of selected columns + @param [out] columnCount + Number of columns currently selected + @retval S_OK + */ + [propget] HRESULT nSelectedColumns + ( + [out, retval] long *columnCount + ); + + /** @brief Returns the total number of selected rows + @param [out] rowCount + Number of rows currently selected + @retval S_OK + */ + [propget] HRESULT nSelectedRows + ( + [out, retval] long *rowCount + ); + + /** @brief Returns the description text of the specified row in the table. + @param [in] row + The 0 based index of the row for which to retrieve the description. + @param [out] description + Returns the description text of the specified row in the table if such a + description exists. Otherwise a NULL pointer is returned. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + @retval E_INVALIDARG if bad [in] passed, [out] value is NULL + */ + [propget] HRESULT rowDescription + ( + [in] long row, + [out, retval] BSTR *description + ); + + /** @brief Returns the number of rows occupied by the accessible object + at the specified row and column in the table. + + The result is greater than 1 if the specified cell spans multiple rows. + @param [in] row + 0 based row index of the accessible for which to return the row extent. + @param [in] column + 0 based column index of the accessible for which to return the row extent. + @param [out] nRowsSpanned + Returns the row extent of the specified cell. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed, [out] value is 0 + */ + [propget] HRESULT rowExtentAt + ( + [in] long row, + [in] long column, + [out, retval] long *nRowsSpanned + ); + + /** @brief Returns the row headers as an %IAccessibleTable object. + + Content and size of the returned table are implementation dependent. + @param [out] accessibleTable + The row header. + @param [out] startingColumnIndex + The 0 based column index where the header starts, usually 0. + @retval S_OK + @retval S_FALSE if there is no header, [out] values are NULL and 0 respectively + */ + [propget] HRESULT rowHeader + ( + [out] IAccessibleTable **accessibleTable, + [out, retval] long *startingColumnIndex + ); + + /** @brief Translates the given cell index into a row index. + @param [in] cellIndex + 0 based index of the cell in the parent or closest ancestor table. Typically this + is the value returned from IAccessible2::indexInParent, but in the case where the + table cells are not direct children of the table this is the cell index specified + by the "table-cell-index" object attribute obtained from parsing the attributes + string returned by calling IAccessible2::attributes on the cell object. + @param [out] rowIndex + 0 based row index + @retval S_OK + @retval E_INVALIDARG if bad [in] passed, [out] value is 0 + */ + [propget] HRESULT rowIndex + ( + [in] long cellIndex, + [out, retval] long *rowIndex + ); + + /** @brief Returns a list of cell indexes currently selected (0 based). + @param [in] maxChildren + This parameter is ignored. Refer to @ref _arrayConsideration + "Special Consideration when using Arrays" for more details. + @param [out] children + An array of cell indexes of selected cells (each index is 0 based), + allocated by the server. Free it with CoTaskMemFree. + @param [out] nChildren + The number of cell indexes returned; the size of the returned array. + @retval S_OK + @retval S_FALSE if there are none, [out] values are NULL and 0 respectively + */ + [propget] HRESULT selectedChildren + ( + [in] long maxChildren, + [out, size_is(,maxChildren), length_is(,*nChildren)] long **children, + [out, retval] long *nChildren + ); + + /** @brief Returns a list of column indexes currently selected (0 based). + @param [in] maxColumns + This parameter is ignored. Refer to @ref _arrayConsideration + "Special Consideration when using Arrays" for more details. + @param [out] columns + An array of column indexes of selected columns (each index is 0 based), allocated + by the server. Free it with CoTaskMemFree. + @param [out] nColumns + The number of column indexes returned; the size of the returned array. + @retval S_OK + @retval S_FALSE if there are none, [out] values are NULL and 0 respectively + */ + [propget] HRESULT selectedColumns + ( + [in] long maxColumns, + [out, size_is(,maxColumns), length_is(,*nColumns)] long **columns, + [out, retval] long *nColumns + ); + + /** @brief Returns a list of row indexes currently selected (0 based). + @param [in] maxRows + This parameter is ignored. Refer to @ref _arrayConsideration + "Special Consideration when using Arrays" for more details. + @param [out] rows + An array of row indexes of selected rows (each index is 0 based), allocated + by the server. Free it with CoTaskMemFree. + @param [out] nRows + The number of row indexes returned; the size of the returned array. + @retval S_OK + @retval S_FALSE if there are none, [out] values are NULL and 0 respectively + */ + [propget] HRESULT selectedRows + ( + [in] long maxRows, + [out, size_is(,maxRows), length_is(,*nRows)] long **rows, + [out, retval] long *nRows + ); + + /** @brief Returns the summary description of the table. The returned object could be + an IAccessible or an IAccessible2. + @param [out] accessible + Returns a reference to an implementation dependent accessible object + representing the table's summary or a NULL pointer if the table + does not support a summary. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + */ + [propget] HRESULT summary + ( + [out, retval] IUnknown **accessible + ); + + /** @brief Returns a boolean value indicating whether the specified column is + completely selected. + @param [in] column + 0 based index of the column for which to determine whether it is selected. + @param [out] isSelected + Returns TRUE if the specified column is selected completely and FALSE otherwise. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed, [out] value is FALSE + */ + [propget] HRESULT isColumnSelected + ( + [in] long column, + [out, retval] boolean *isSelected + ); + + /** @brief Returns a boolean value indicating whether the specified row is completely + selected. + @param [in] row + 0 based index of the row for which to determine whether it is selected. + @param [out] isSelected + Returns TRUE if the specified row is selected completely and FALSE otherwise. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed, [out] value is FALSE + */ + [propget] HRESULT isRowSelected + ( + [in] long row, + [out, retval] boolean *isSelected + ); + + /** @brief Returns a boolean value indicating whether the specified cell is selected. + @param [in] row + 0 based index of the row for the cell to determine whether it is selected. + @param [in] column + 0 based index of the column for the cell to determine whether it is selected. + @param [out] isSelected + Returns TRUE if the specified cell is selected and FALSE otherwise. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed, [out] value is FALSE + */ + [propget] HRESULT isSelected + ( + [in] long row, + [in] long column, + [out, retval] boolean *isSelected + ); + + /** @brief Selects a row and unselects all previously selected rows. + @param [in] row + 0 based index of the row to be selected. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT selectRow + ( + [in] long row + ); + + /** @brief Selects a column and unselects all previously selected columns. + @param [in] column + 0 based index of the column to be selected. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT selectColumn + ( + [in] long column + ); + + /** @brief Unselects one row, leaving other selected rows selected (if any). + @param [in] row + 0 based index of the row to be unselected. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT unselectRow + ( + [in] long row + ); + + /** @brief Unselects one column, leaving other selected columns selected (if any). + @param [in] column + 0 based index of the column to be unselected. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT unselectColumn + ( + [in] long column + ); + + /** @brief Given a cell index, gets the row and column indexes and extents of a cell + and whether or not it is selected. + + This is a convenience function. It is not mandatory to implement it. + @param [in] index + 0 based index of this cell in the table. + @param [out] row + 0 based row index. + @param [out] column + 0 based column index. + @param [out] rowExtents + Number of cells spanned by this cell in this row. + @param [out] columnExtents + Number of cells spanned by this cell in this column. + @param [out] isSelected + Indicates if the specified cell is selected. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed, [out] values are 0s and FALSE respectively + */ + [propget] HRESULT rowColumnExtentsAtIndex + ( + [in] long index, + [out] long *row, + [out] long *column, + [out] long *rowExtents, + [out] long *columnExtents, + [out, retval] boolean *isSelected + ); + + /** @brief Returns the type and extents describing how a table changed. + + Provided for use by the IA2_EVENT_TABLE_MODEL_CHANGED event handler. + + This data is only guaranteed to be valid while the thread notifying the event + continues. Once the handler has returned, the validity of the data depends on + how the server manages the life cycle of its objects. Also, note that the server + may have different life cycle management strategies for controls depending on + whether or not a control manages its children. Lists, trees, and tables can have + a large number of children and thus it's possible that the child objects for those + controls would only be created as needed. Servers should document their life cycle + strategy as this will be of interest to assistive technology or script engines + accessing data out of process or from other threads. Servers only need to save the + most recent row and column values associated with the change and a scope of the + entire application is adequate. + + @param [out] modelChange + A struct of (type(insert, delete, update), firstRow, lastRow, firstColumn, lastColumn). + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + */ + [propget] HRESULT modelChange + ( + [out, retval] IA2TableModelChange *modelChange + ); + +} +/************************************************************************* + * + * File Name (AccessibleTable2.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) Linux Foundation 2007, 2009 + * Copyright (c) IBM Corp. 2006 + * Copyright (c) Sun Microsystems, Inc. 2000, 2006 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + ************************************************************************/ + +import "objidl.idl"; +import "oaidl.idl"; +import "oleacc.idl"; + + + +/** @brief This interface gives access to a two-dimensional table. + + Please also refer to the IAccessibleTableCell interface. + + If you want to support older applications you should also support the + IAccessibleTable inteface. +*/ +[object, uuid(6167f295-06f0-4cdd-a1fa-02e25153d869)] +interface IAccessibleTable2 : IUnknown +{ + + /** @brief Returns the accessible object at the specified row and column in + the table. This object could be an IAccessible or an IAccessible2. + @param [in] row + The 0 based row index for which to retrieve the cell. + @param [in] column + The 0 based column index for which to retrieve the cell. + @param [out] cell + If both row and column index are valid then the corresponding accessible + object is returned that represents the requested cell regardless of whether + the cell is currently visible (on the screen). + @retval S_OK + @retval E_INVALIDARG if bad [in] passed, [out] value is NULL + */ + [propget] HRESULT cellAt + ( + [in] long row, + [in] long column, + [out, retval] IUnknown **cell + ); + + /** @brief Returns the caption for the table. The returned object could be + an IAccessible or an IAccessible2. + @param [out] accessible + If the table has a caption then a reference to it is returned, else a NULL + pointer is returned. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + */ + [propget] HRESULT caption + ( + [out, retval] IUnknown **accessible + ); + + /** @brief Returns the description text of the specified column in the table. + @param [in] column + The 0 based index of the column for which to retrieve the description. + @param [out] description + Returns the description text of the specified column in the table if such a + description exists. Otherwise a NULL pointer is returned. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + @retval E_INVALIDARG if bad [in] passed, [out] value is NULL + */ + [propget] HRESULT columnDescription + ( + [in] long column, + [out, retval] BSTR *description + ); + + + /** @brief Returns the total number of columns in table + @param [out] columnCount + Number of columns in table (including columns outside the current viewport) + @retval S_OK + */ + [propget] HRESULT nColumns + ( + [out, retval] long *columnCount + ); + + /** @brief Returns the total number of rows in table + @param [out] rowCount + Number of rows in table (including rows outside the current viewport) + @retval S_OK + */ + [propget] HRESULT nRows + ( + [out, retval] long *rowCount + ); + + /** @brief Returns the total number of selected cells + @param [out] cellCount + Number of cells currently selected + @retval S_OK + */ + [propget] HRESULT nSelectedCells + ( + [out, retval] long *cellCount + ); + + /** @brief Returns the total number of selected columns + @param [out] columnCount + Number of columns currently selected + @retval S_OK + */ + [propget] HRESULT nSelectedColumns + ( + [out, retval] long *columnCount + ); + + /** @brief Returns the total number of selected rows + @param [out] rowCount + Number of rows currently selected + @retval S_OK + */ + [propget] HRESULT nSelectedRows + ( + [out, retval] long *rowCount + ); + + /** @brief Returns the description text of the specified row in the table. + @param [in] row + The 0 based index of the row for which to retrieve the description. + @param [out] description + Returns the description text of the specified row in the table if such a + description exists. Otherwise a NULL pointer is returned. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + @retval E_INVALIDARG if bad [in] passed, [out] value is NULL + */ + [propget] HRESULT rowDescription + ( + [in] long row, + [out, retval] BSTR *description + ); + + /** @brief Returns a list of accessibles currently selected. + @param [out] cells + Pointer to an array of references to selected accessibles. The array is + allocated by the server. Free it with CoTaskMemFree. + @param [out] nSelectedCells + The number of accessibles returned; the size of the returned array. + @retval S_OK + @retval S_FALSE if there are none, [out] values are NULL and 0 respectively + */ + [propget] HRESULT selectedCells + ( + [out, size_is(,*nSelectedCells,)] IUnknown ***cells, + [out, retval] long *nSelectedCells + ); + + /** @brief Returns a list of column indexes currently selected (0 based). + @param [out] selectedColumns + A pointer to an array of column indexes of selected columns (each index is + 0 based). The array is allocated by the server. Free it with CoTaskMemFree. + @param [out] nColumns + The number of column indexes returned; the size of the returned array. + @retval S_OK + @retval S_FALSE if there are none, [out] values are NULL and 0 respectively + */ + [propget] HRESULT selectedColumns + ( + [out, size_is(,*nColumns)] long **selectedColumns, + [out, retval] long *nColumns + ); + + /** @brief Returns a list of row indexes currently selected (0 based). + @param [out] selectedRows + An array of row indexes of selected rows (each index is 0 based), allocated + by the server. Free it with CoTaskMemFree. + @param [out] nRows + The number of row indexes returned; the size of the returned array. + @retval S_OK + @retval S_FALSE if there are none, [out] values are NULL and 0 respectively + */ + [propget] HRESULT selectedRows + ( + [out, size_is(,*nRows)] long **selectedRows, + [out, retval] long *nRows + ); + + /** @brief Returns the summary description of the table. The returned object could be + an IAccessible or an IAccessible2. + @param [out] accessible + Returns a reference to an implementation dependent accessible object + representing the table's summary or a NULL pointer if the table + does not support a summary. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + */ + [propget] HRESULT summary + ( + [out, retval] IUnknown **accessible + ); + + /** @brief Returns a boolean value indicating whether the specified column is + completely selected. + @param [in] column + 0 based index of the column for which to determine whether it is selected. + @param [out] isSelected + Returns TRUE if the specified column is selected completely and FALSE otherwise. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed, [out] value is FALSE + */ + [propget] HRESULT isColumnSelected + ( + [in] long column, + [out, retval] boolean *isSelected + ); + + /** @brief Returns a boolean value indicating whether the specified row is completely + selected. + @param [in] row + 0 based index of the row for which to determine whether it is selected. + @param [out] isSelected + Returns TRUE if the specified row is selected completely and FALSE otherwise. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed, [out] value is FALSE + */ + [propget] HRESULT isRowSelected + ( + [in] long row, + [out, retval] boolean *isSelected + ); + + /** @brief Selects a row and unselects all previously selected rows. + + The behavior should mimic that of the application, but for those applications + which do not have a means in the GUI to select a full row of cells the behavior + should be as follows: First any selected rows in the table are unselected. Then + the entire row of cells for the specified row is selected. If any of the + cells in the selected row span additional rows, the cells in those rows + are also selected. + @param [in] row + 0 based index of the row to be selected. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT selectRow + ( + [in] long row + ); + + /** @brief Selects a column and unselects all previously selected columns. + + The behavior should mimic that of the application, but for those applications + which do not have a means in the GUI to select a full column of cells the behavior + should be as follows: First any selected columns in the table are unselected. Then + the entire column of cells for the specified column is selected. If any of the + cells in the selected column span additional columns, the cells in those columns + are also selected. + @param [in] column + 0 based index of the column to be selected. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT selectColumn + ( + [in] long column + ); + + /** @brief Unselects one row, leaving other selected rows selected (if any). + + The behavior should mimic that of the application, but for those applications + which do not have a means in the GUI to unselect a full row of cells the + behavior should be as follows: The entire row of cells for the specified + row is unselected. If any of the cells in the selected row span additional + rows, the cells in those rows are also unselected. + @param [in] row + 0 based index of the row to be unselected. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT unselectRow + ( + [in] long row + ); + + /** @brief Unselects one column, leaving other selected columns selected (if any). + + The behavior should mimic that of the application, but for those applications + which do not have a means in the GUI to unselect a full column of cells the + behavior should be as follows: The entire column of cells for the specified + column is unselected. If any of the cells in the selected column span additional + columns, the cells in those columns are also unselected. + @param [in] column + 0 based index of the column to be unselected. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT unselectColumn + ( + [in] long column + ); + + /** @brief Returns the type and extents describing how a table changed. + + Provided for use by the IA2_EVENT_TABLE_MODEL_CHANGED event handler. + + This data is only guaranteed to be valid while the thread notifying the event + continues. Once the handler has returned, the validity of the data depends on + how the server manages the life cycle of its objects. Also, note that the server + may have different life cycle management strategies for controls depending on + whether or not a control manages its children. Lists, trees, and tables can have + a large number of children and thus it's possible that the child objects for those + controls would only be created as needed. Servers should document their life cycle + strategy as this will be of interest to assistive technology or script engines + accessing data out of process or from other threads. Servers only need to save the + most recent row and column values associated with the change and a scope of the + entire application is adequate. + + @param [out] modelChange + A struct of (type(insert, delete, update), firstRow, lastRow, firstColumn, lastColumn). + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + */ + [propget] HRESULT modelChange + ( + [out, retval] IA2TableModelChange *modelChange + ); + +} +/************************************************************************* + * + * File Name (AccessibleTableCell.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) Linux Foundation 2007, 2009 + * Copyright (c) IBM Corp. 2006 + * Copyright (c) Sun Microsystems, Inc. 2000, 2006 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + ************************************************************************/ + +import "objidl.idl"; +import "oaidl.idl"; +import "oleacc.idl"; + + +/** @brief This interface gives access to the cells of a two-dimensional table. + + Please also refer to the IAccessibleTable2 interface. + +*/ +[object, uuid(594116B1-C99F-4847-AD06-0A7A86ECE645)] +interface IAccessibleTableCell : IUnknown +{ + + /** @brief Returns the number of columns occupied by this cell accessible. + + The result is greater than 1 if the specified cell spans multiple columns. + @param [out] nColumnsSpanned + Returns the 1 based column extent of the specified cell. + @retval S_OK + */ + [propget] HRESULT columnExtent + ( + [out, retval] long *nColumnsSpanned + ); + + /** @brief Returns the column headers as an array of cell accessibles. + + @param [out] cellAccessibles + Pointer to an array of references to cell accessibles. The array is allocated + by the server. Free it with CoTaskMemFree. + @param [out] nColumnHeaderCells + The number of accessibles returned; the size of the returned array. + @retval S_OK + @retval S_FALSE if there is no header, [out] values are NULL and 0 respectively + */ + [propget] HRESULT columnHeaderCells + ( + [out, size_is(,*nColumnHeaderCells,)] IUnknown ***cellAccessibles, + [out, retval] long *nColumnHeaderCells + ); + + /** @brief Translates this cell accessible into the corresponding column index. + + @param [out] columnIndex + Returns the 0 based column index of the cell of the specified cell or the index of + the first column if the cell spans multiple columns. + @retval S_OK + */ + [propget] HRESULT columnIndex + ( + [out, retval] long *columnIndex + ); + + /** @brief Returns the number of rows occupied by this cell accessible. + + @param [out] nRowsSpanned + Returns the row extent of the specified cell. + @retval S_OK + */ + [propget] HRESULT rowExtent + ( + [out, retval] long *nRowsSpanned + ); + + /** @brief Returns the row headers as an array of cell accessibles. + + @param [out] cellAccessibles + Pointer to an array of references to cell accessibles. The array is allocated + by the server. Free it with CoTaskMemFree. + @param [out] nRowHeaderCells + The number of accessibles returned; the size of the returned array. + @retval S_OK + @retval S_FALSE if there is no header, [out] values are NULL and 0 respectively + */ + [propget] HRESULT rowHeaderCells + ( + [out, size_is(,*nRowHeaderCells,)] IUnknown ***cellAccessibles, + [out, retval] long *nRowHeaderCells + ); + + /** @brief Translates this cell accessible into the corresponding row index. + + @param [out] rowIndex + Returns the 0 based row index of the specified cell or the index of + the first row if the cell spans multiple rows. + @retval S_OK + */ + [propget] HRESULT rowIndex + ( + [out, retval] long *rowIndex + ); + + /** @brief Returns a boolean value indicating whether this cell is selected. + + @param [out] isSelected + Returns TRUE if the specified cell is selected and FALSE otherwise. + @retval S_OK + */ + [propget] HRESULT isSelected + ( + [out, retval] boolean *isSelected + ); + + /** @brief Gets the row and column indexes and extents of this cell accessible + and whether or not it is selected. + + This is a convenience function. It is not mandatory to implement it. + @param [out] row + 0 based row index. + @param [out] column + 0 based column index. + @param [out] rowExtents + Number of cells spanned by this cell in this row. + @param [out] columnExtents + Number of cells spanned by this cell in this column. + @param [out] isSelected + Indicates if the specified cell is selected. + @retval S_OK + */ + [propget] HRESULT rowColumnExtents + ( + [out] long *row, + [out] long *column, + [out] long *rowExtents, + [out] long *columnExtents, + [out, retval] boolean *isSelected + ); + + /** @brief Returns a reference to the accessbile of the containing table. + + @param [out] table + Returns a reference to the IUnknown of the containing table. + @retval S_OK + */ + [propget] HRESULT table + ( + [out, retval] IUnknown **table + ); + +} +/************************************************************************* + * + * File Name (AccessibleImage) + * + * IAccessible2 IDL Specification + * + * Copyright (c) Linux Foundation 2007, 2008 + * Copyright (c) IBM Corp. 2006 + * Copyright (c) Sun Microsystems, Inc. 2000, 2006 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02110-1301 USA + * + ************************************************************************/ + +import "objidl.idl"; +import "oaidl.idl"; +import "oleacc.idl"; + + +/** @brief This interface represents images and icons. + + This interface is used for a representation of images like icons on buttons. + %IAccessibleImage only needs to be implemented in certain situations. Some + examples are: + <ol> + <li>The accessible name and description are not enough to fully + describe the image, e.g. when the accessible description is used to define the + behavior of an actionable image and the image itself conveys semantically + significant information. + <li>The user can edit the content that includes an + image and therefore the user needs to be able to review the image's position. + </ol> +*/ +[object, uuid(FE5ABB3D-615E-4f7b-909F-5F0EDA9E8DDE)] +interface IAccessibleImage : IUnknown +{ + /** @brief Returns the localized description of the image. + @param [out] description + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + */ + [propget] HRESULT description + ( + [out, retval] BSTR *description + ); + + /** @brief Returns the coordinates of the image. + @param [in] coordinateType + Specifies whether the returned coordinates should be relative to the screen or the parent object. + @param [out] x + @param [out] y + @retval S_OK + */ + [propget] HRESULT imagePosition + ( + [in] enum IA2CoordinateType coordinateType, + [out] long *x, + [out, retval] long *y + ); + + /** @brief Returns the size of the image in units specified by parent's coordinate system. + @param [out] height + @param [out] width + @retval S_OK + */ + + [propget] HRESULT imageSize + ( + [out] long *height, + [out, retval] long *width + ); +} +/************************************************************************* + * + * File Name (AccessibleEventID.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) Linux Foundation 2007, 2008 + * Copyright (c) IBM Corp. 2006 + * Copyright (c) Sun Microsystems, Inc. 2000, 2006 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02110-1301 USA + * + ************************************************************************/ + +/** %IAccessible2 specific event constants + + This enum defines the event IDs fired by %IAccessible2 objects. The event IDs + are in addition to those used by MSAA. +*/ +enum IA2EventID { + + /** The change of the number or attributes of actions of an accessible + object is signaled by events of this type. + */ + IA2_EVENT_ACTION_CHANGED = 0x101, + + /** The active descendant of a component has changed. + + Note: This event constant is misspelled and thus is deprecated and will be + removed in a later version. Please use the correctly spelled version which + follows. + */ + IA2_EVENT_ACTIVE_DECENDENT_CHANGED, + + /** The active descendant of a component has changed. The active descendant + is used in objects with transient children. + + Note: Due to the fact that MSAA's WinEvents don't allow the active child index + to be passed on the IA2_EVENT_ACTIVE_DESCENDANT_CHANGED event the manages + descendants scheme can't be used. Instead the active child object has to fire + MSAA's EVENT_OBJECT_FOCUS. In a future release a new event mechanism may be + added to provide for event specific data to be passed with the event. At that + time the IA2_EVENT_ACTIVE_DECENDENT_CHANGED event and + IA2_STATE_MANAGES_DESCENDANTS state would be useful. + */ + IA2_EVENT_ACTIVE_DESCENDANT_CHANGED = IA2_EVENT_ACTIVE_DECENDENT_CHANGED, + + /** The document wide attributes of the document object have changed. + */ + IA2_EVENT_DOCUMENT_ATTRIBUTE_CHANGED, + + /** The contents of the document have changed. + */ + IA2_EVENT_DOCUMENT_CONTENT_CHANGED, + + /** The loading of the document has completed. + */ + IA2_EVENT_DOCUMENT_LOAD_COMPLETE, + + /** The loading of the document was interrupted. + */ + IA2_EVENT_DOCUMENT_LOAD_STOPPED, + + /** The document contents are being reloaded. + */ + IA2_EVENT_DOCUMENT_RELOAD, + + /** The ending index of this link within the containing string has changed. + */ + IA2_EVENT_HYPERLINK_END_INDEX_CHANGED, + + /** The number of anchors associated with this hyperlink object has changed. + */ + IA2_EVENT_HYPERLINK_NUMBER_OF_ANCHORS_CHANGED, + + /** The hyperlink selected state changed from selected to unselected or + from unselected to selected. + */ + IA2_EVENT_HYPERLINK_SELECTED_LINK_CHANGED, + + /** One of the links associated with the hypertext object has been activated. + */ + IA2_EVENT_HYPERTEXT_LINK_ACTIVATED, + + /** One of the links associated with the hypertext object has been selected. + */ + IA2_EVENT_HYPERTEXT_LINK_SELECTED, + + /** The starting index of this link within the containing string has changed. + */ + IA2_EVENT_HYPERLINK_START_INDEX_CHANGED, + + /** Focus has changed from one hypertext object to another, or focus moved + from a non-hypertext object to a hypertext object, or focus moved from a + hypertext object to a non-hypertext object. + */ + IA2_EVENT_HYPERTEXT_CHANGED, + + /** The number of hyperlinks associated with a hypertext object changed + */ + IA2_EVENT_HYPERTEXT_NLINKS_CHANGED, + + /** An object's attributes changed. + Also see ::IA2_EVENT_TEXT_ATTRIBUTE_CHANGED. + */ + IA2_EVENT_OBJECT_ATTRIBUTE_CHANGED, + + /** A slide changed in a presentation document or a page boundary was + crossed in a word processing document. + */ + IA2_EVENT_PAGE_CHANGED, + + /** The caret moved from one section to the next. + */ + IA2_EVENT_SECTION_CHANGED, + + /** A table caption changed. + */ + IA2_EVENT_TABLE_CAPTION_CHANGED, + + /** A table's column description changed. + */ + IA2_EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED, + + /** A table's column header changed. + */ + IA2_EVENT_TABLE_COLUMN_HEADER_CHANGED, + + /** A table's data changed. + */ + IA2_EVENT_TABLE_MODEL_CHANGED, + + /** A table's row description changed. + */ + IA2_EVENT_TABLE_ROW_DESCRIPTION_CHANGED, + + /** A table's row header changed. + */ + IA2_EVENT_TABLE_ROW_HEADER_CHANGED, + + /** A table's summary changed. + */ + IA2_EVENT_TABLE_SUMMARY_CHANGED, + + /** A text object's attributes changed. + Also see ::IA2_EVENT_OBJECT_ATTRIBUTE_CHANGED. + */ + IA2_EVENT_TEXT_ATTRIBUTE_CHANGED, + + /** The caret has moved to a new position. + */ + IA2_EVENT_TEXT_CARET_MOVED, + + /** <b>Deprecated.</b> This event is equivalent to ::IA2_EVENT_TEXT_UPDATED. + */ + IA2_EVENT_TEXT_CHANGED, + + /** The caret moved from one column to the next. + */ + IA2_EVENT_TEXT_COLUMN_CHANGED, + + /** Text was inserted. + */ + IA2_EVENT_TEXT_INSERTED, + + /** Text was removed. + */ + IA2_EVENT_TEXT_REMOVED, + + /** This event indicates general text changes, i.e. changes to text that are + exposed through the IAccessibleText interface. For compatibility with ATK/AT-SPI + which does not have an equivalent event, servers can alternatively fire + ::IA2_EVENT_TEXT_REMOVED and ::IA2_EVENT_TEXT_INSERTED. + */ + IA2_EVENT_TEXT_UPDATED, + + /** The text selection changed. Later versions of Microsoft development environments + have an equivalent event identified, EVENT_OBJECT_TEXTSELECTIONCHANGED. Servers + should use that if it is available and use IA2_EVENT_TEXT_SELECTION_CHANGED otherwise. + Clients should be prepared to respond to either event. + + */ + IA2_EVENT_TEXT_SELECTION_CHANGED, + + /** A visible data event indicates the change of the visual appearance + of an accessible object. This includes for example most of the + attributes available via the IAccessibleComponent interface. + */ + IA2_EVENT_VISIBLE_DATA_CHANGED + +}; +/************************************************************************* + * + * File Name (AccessibleApplication.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) Linux Foundation 2007, 2008 + * Copyright (c) IBM Corp. 2006 + * Copyright (c) Sun Microsystems, Inc. 2000, 2006 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02110-1301 USA + * + ************************************************************************/ + +import "objidl.idl"; +import "oaidl.idl"; +import "oleacc.idl"; + +/** @brief This interface gives access to the application's name and version information. + + This interface provides the AT with the information it needs to differentiate + this application from other applications, from other versions of this + application, or from other versions of this application running on different + versions of an accessibility bridge or accessibility toolkit. + + Servers implementing IAccessible2 should provide access to the %IAccessibleApplication + interface via QueryService from any object so that ATs can easily determine specific + information about the application such as its name or version. +*/ +[object, uuid(D49DED83-5B25-43F4-9B95-93B44595979E)] +interface IAccessibleApplication : IUnknown +{ + + /** @brief Returns the application name. + @param [out] name + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + */ + [propget] HRESULT appName + ( + [out, retval] BSTR *name + ); + + /** @brief Returns the application version. + @param [out] version + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + */ + [propget] HRESULT appVersion + ( + [out, retval] BSTR *version + ); + + /** @brief Returns the toolkit/bridge name. + @param [out] name + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + */ + [propget] HRESULT toolkitName + ( + [out, retval] BSTR *name + ); + + /** @brief Returns the toolkit/bridge version. + @param [out] version + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + */ + [propget] HRESULT toolkitVersion + ( + [out, retval] BSTR *version + ); + +} + +/************************************************************************* + * + * File Name (IA2TypeLibrary.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) Linux Foundation 2007, 2009 + * Copyright (c) IBM Corp. 2006 + * Copyright (c) Sun Microsystems, Inc. 2000, 2006 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02110-1301 USA + * + ************************************************************************/ + +// This is not a standalone file. It is to be appended to the end of the +// merged IDL file. + +cpp_quote("") +cpp_quote("// Type Library Definitions") +cpp_quote("") + +[ + uuid(c974e070-3787-490a-87b0-e333b06ca1e2), + helpstring("IAccessible2 Type Library"), + version(1.1), + hidden +] + +library IAccessible2Lib +{ + importlib ("stdole2.tlb"); + interface IAccessible2; + interface IAccessibleAction; + interface IAccessibleApplication; + interface IAccessibleComponent; + interface IAccessibleEditableText; + interface IAccessibleHyperlink; + interface IAccessibleHypertext; + interface IAccessibleImage; + interface IAccessibleRelation; + interface IAccessibleTable; + interface IAccessibleTable2; + interface IAccessibleTableCell; + interface IAccessibleText; + interface IAccessibleValue; + enum IA2CoordinateType; + enum IA2EventID; + enum IA2Role; + enum IA2ScrollType; + enum IA2States; + enum IA2TableModelChangeType; + enum IA2TextBoundaryType; + enum IA2TextSpecialOffsets; +} diff --git a/third_party/iaccessible2/iaccessible2.gyp b/third_party/iaccessible2/iaccessible2.gyp new file mode 100644 index 0000000..3853c7b --- /dev/null +++ b/third_party/iaccessible2/iaccessible2.gyp @@ -0,0 +1,41 @@ +# Copyright (c) 2010 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +{ + 'includes': [ + '../../build/common.gypi', + ], + + 'target_defaults': { + 'include_dirs': [ + '.', + '<(INTERMEDIATE_DIR)', + ], + }, + 'targets': [ + { + 'target_name': 'iaccessible2', + 'type': '<(library)', + 'msvs_guid': 'C974E070-3787-490A-87B0-E333B06CA1E2', + 'sources': [ + 'ia2_api_all.idl', + '<(INTERMEDIATE_DIR)/ia2_api_all.h', + '<(INTERMEDIATE_DIR)/ia2_api_all_i.c', + '<(INTERMEDIATE_DIR)/ia2_api_all_p.c', + ], + 'direct_dependent_settings': { + 'include_dirs': [ + # Bit of a hack to work around the built in vstudio rule. + '<(INTERMEDIATE_DIR)/../iaccessible2', + ], + }, + }, + ], +} + +# Local Variables: +# tab-width:2 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=2 shiftwidth=2: diff --git a/webkit/glue/webaccessibility.cc b/webkit/glue/webaccessibility.cc index 1af91d6..33232ca 100644 --- a/webkit/glue/webaccessibility.cc +++ b/webkit/glue/webaccessibility.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -7,16 +7,11 @@ #include "third_party/WebKit/WebKit/chromium/public/WebAccessibilityCache.h" #include "third_party/WebKit/WebKit/chromium/public/WebAccessibilityObject.h" #include "third_party/WebKit/WebKit/chromium/public/WebAccessibilityRole.h" -#include "third_party/WebKit/WebKit/chromium/public/WebPoint.h" -#include "third_party/WebKit/WebKit/chromium/public/WebRect.h" #include "third_party/WebKit/WebKit/chromium/public/WebString.h" using WebKit::WebAccessibilityCache; using WebKit::WebAccessibilityRole; using WebKit::WebAccessibilityObject; -using WebKit::WebPoint; -using WebKit::WebRect; -using WebKit::WebString; namespace webkit_glue { @@ -101,240 +96,82 @@ WebAccessibility::Role ConvertRole(WebKit::WebAccessibilityRole role) { } } -long ConvertState(const WebAccessibilityObject& o) { - long state = 0; +uint32 ConvertState(const WebAccessibilityObject& o) { + uint32 state = 0; if (o.isChecked()) - state |= static_cast<long>(1 << WebAccessibility::STATE_CHECKED); + state |= (1 << WebAccessibility::STATE_CHECKED); if (o.canSetFocusAttribute()) - state |= static_cast<long>(1 << WebAccessibility::STATE_FOCUSABLE); + state |= (1 << WebAccessibility::STATE_FOCUSABLE); if (o.isFocused()) - state |= static_cast<long>(1 << WebAccessibility::STATE_FOCUSED); + state |= (1 << WebAccessibility::STATE_FOCUSED); if (o.isHovered()) - state |= static_cast<long>(1 << WebAccessibility::STATE_HOTTRACKED); + state |= (1 << WebAccessibility::STATE_HOTTRACKED); if (o.isIndeterminate()) - state |= static_cast<long>(1 << WebAccessibility::STATE_INDETERMINATE); + state |= (1 << WebAccessibility::STATE_INDETERMINATE); if (o.isAnchor()) - state |= static_cast<long>(1 << WebAccessibility::STATE_LINKED); + state |= (1 << WebAccessibility::STATE_LINKED); if (o.isMultiSelectable()) - state |= static_cast<long>(1 << WebAccessibility::STATE_MULTISELECTABLE); + state |= (1 << WebAccessibility::STATE_MULTISELECTABLE); if (o.isOffScreen()) - state |= static_cast<long>(1 << WebAccessibility::STATE_OFFSCREEN); + state |= (1 << WebAccessibility::STATE_OFFSCREEN); if (o.isPressed()) - state |= static_cast<long>(1 << WebAccessibility::STATE_PRESSED); + state |= (1 << WebAccessibility::STATE_PRESSED); if (o.isPasswordField()) - state |= static_cast<long>(1 << WebAccessibility::STATE_PROTECTED); + state |= (1 << WebAccessibility::STATE_PROTECTED); if (o.isReadOnly()) - state |= static_cast<long>(1 << WebAccessibility::STATE_READONLY); + state |= (1 << WebAccessibility::STATE_READONLY); if (o.isVisited()) - state |= static_cast<long>(1 << WebAccessibility::STATE_TRAVERSED); + state |= (1 << WebAccessibility::STATE_TRAVERSED); if (!o.isEnabled()) - state |= static_cast<long>(1 << WebAccessibility::STATE_UNAVAILABLE); + state |= (1 << WebAccessibility::STATE_UNAVAILABLE); return state; } -int32 WebAccessibility::GetAccObjInfo(WebAccessibilityCache* cache, - const WebAccessibility::InParams& in_params, - WebAccessibility::OutParams* out_params) { - // Find object requested by |object_id|. - WebAccessibilityObject active_acc_obj; - - // Since ids assigned by Chrome starts at 1000, whereas platform-specific ids - // used to reference a child will be in a wholly different range, we know - // that any id that high should be treated as a non-direct descendant. - bool local_child = false; - if (cache->isValidId(in_params.child_id)) { - // Object is not a direct child, re-map the input parameters accordingly. - // The object to be retrieved is referred to by the |in_params.child_id|, as - // a result of e.g. a focus event. - active_acc_obj = cache->getObjectById(in_params.child_id); - } else { - local_child = true; - - active_acc_obj = cache->getObjectById(in_params.object_id); - if (active_acc_obj.isNull()) - return RETURNCODE_FAIL; - - // child_id == 0 means self. Otherwise, it's a local child - 1. - if (in_params.child_id > 0) { - unsigned index = in_params.child_id - 1; - if (index >= active_acc_obj.childCount()) - return RETURNCODE_FAIL; - - active_acc_obj = active_acc_obj.childAt(index); - } - } - - if (active_acc_obj.isNull()) - return RETURNCODE_FAIL; - - // Temp paramters for holding output information. - WebAccessibilityObject out_acc_obj; - string16 out_string; - - switch (in_params.function_id) { - case WebAccessibility::FUNCTION_DODEFAULTACTION: { - if (!active_acc_obj.performDefaultAction()) - return RETURNCODE_FALSE; - break; - } - case WebAccessibility::FUNCTION_HITTEST: { - WebPoint point(in_params.input_long1, in_params.input_long2); - out_acc_obj = active_acc_obj.hitTest(point); - if (out_acc_obj.isNull()) - return RETURNCODE_FALSE; - break; - } - case WebAccessibility::FUNCTION_LOCATION: { - WebRect rect = active_acc_obj.boundingBoxRect(); - out_params->output_long1 = rect.x; - out_params->output_long2 = rect.y; - out_params->output_long3 = rect.width; - out_params->output_long4 = rect.height; - break; - } - case WebAccessibility::FUNCTION_NAVIGATE: { - WebAccessibility::Direction dir = - static_cast<WebAccessibility::Direction>(in_params.input_long1); - switch (dir) { - case WebAccessibility::DIRECTION_DOWN: - case WebAccessibility::DIRECTION_UP: - case WebAccessibility::DIRECTION_LEFT: - case WebAccessibility::DIRECTION_RIGHT: - // These directions are not implemented, matching Mozilla and IE. - return RETURNCODE_FALSE; - case WebAccessibility::DIRECTION_LASTCHILD: - case WebAccessibility::DIRECTION_FIRSTCHILD: - // MSDN states that navigating to first/last child can only be from - // self. - if (!local_child) - return RETURNCODE_FALSE; - - if (dir == WebAccessibility::DIRECTION_FIRSTCHILD) { - out_acc_obj = active_acc_obj.firstChild(); - } else { - out_acc_obj = active_acc_obj.lastChild(); - } - break; - case WebAccessibility::DIRECTION_NEXT: - case WebAccessibility::DIRECTION_PREVIOUS: { - if (dir == WebAccessibility::DIRECTION_NEXT) { - out_acc_obj = active_acc_obj.nextSibling(); - } else { - out_acc_obj = active_acc_obj.previousSibling(); - } - break; - } - default: - return RETURNCODE_FALSE; - } +WebAccessibility::WebAccessibility() + : id(-1), + role(ROLE_NONE), + state(-1) { +} - if (out_acc_obj.isNull()) - return RETURNCODE_FALSE; +WebAccessibility::WebAccessibility(const WebKit::WebAccessibilityObject& src, + WebKit::WebAccessibilityCache* cache) { + Init(src, cache); +} - break; - } - case WebAccessibility::FUNCTION_GETCHILD: { - out_params->object_id = in_params.object_id; - out_acc_obj = active_acc_obj; - break; - } - case WebAccessibility::FUNCTION_CHILDCOUNT: { - out_params->output_long1 = active_acc_obj.childCount(); - break; - } - case WebAccessibility::FUNCTION_DEFAULTACTION: { - out_string = active_acc_obj.actionVerb(); - if (out_string.empty()) - return RETURNCODE_FALSE; - break; - } - case WebAccessibility::FUNCTION_DESCRIPTION: { - out_string = active_acc_obj.accessibilityDescription(); - if (out_string.empty()) - return RETURNCODE_FALSE; - // From the Mozilla MSAA implementation: - // "Signal to screen readers that this description is speakable and is not - // a formatted positional information description. Don't localize the - // 'Description: ' part of this string, it will be parsed out by assistive - // technologies." - out_string = L"Description: " + out_string; - break; - } - case WebAccessibility::FUNCTION_GETFOCUSEDCHILD: { - out_acc_obj = active_acc_obj.focusedChild(); - if (out_acc_obj.isNull()) - return RETURNCODE_FALSE; - break; - } - case WebAccessibility::FUNCTION_HELPTEXT: { - out_string = active_acc_obj.helpText(); - if (out_string.empty()) - return RETURNCODE_FALSE; - break; - } - case WebAccessibility::FUNCTION_KEYBOARDSHORTCUT: { - out_string = active_acc_obj.keyboardShortcut(); - if (out_string.empty()) - return RETURNCODE_FALSE; - break; - } - case WebAccessibility::FUNCTION_NAME: { - out_string = active_acc_obj.title(); - if (out_string.empty()) - return RETURNCODE_FALSE; - break; - } - case WebAccessibility::FUNCTION_GETPARENT: { - out_acc_obj = active_acc_obj.parentObject(); - if (out_acc_obj.isNull()) - return RETURNCODE_FALSE; - break; - } - case WebAccessibility::FUNCTION_ROLE: { - out_params->output_long1 = ConvertRole(active_acc_obj.roleValue()); - break; - } - case WebAccessibility::FUNCTION_STATE: { - out_params->output_long1 = ConvertState(active_acc_obj); - break; - } - case WebAccessibility::FUNCTION_VALUE: { - out_string = active_acc_obj.stringValue(); - if (out_string.empty()) - return RETURNCODE_FALSE; - break; - } - default: - // Non-supported function id. - return RETURNCODE_FAIL; +void WebAccessibility::Init(const WebKit::WebAccessibilityObject& src, + WebKit::WebAccessibilityCache* cache) { + name = src.title(); + value = src.stringValue(); + action = src.actionVerb(); + description = src.accessibilityDescription(); + help = src.helpText(); + shortcut = src.keyboardShortcut(); + role = ConvertRole(src.roleValue()); + state = ConvertState(src); + location = src.boundingBoxRect(); + + // Add the source object to the cache and store its id. + id = cache->addOrGetId(src); + + // Recursively create children. + int child_count = src.childCount(); + children.resize(child_count); + for (int i = 0; i < child_count; i++) { + children[i].Init(src.childAt(i), cache); } - - // Output and hashmap assignments, as appropriate. - if (!out_string.empty()) - out_params->output_string = out_string; - - if (out_acc_obj.isNull()) - return RETURNCODE_TRUE; - - int id = cache->addOrGetId(out_acc_obj); - out_params->object_id = id; - out_params->output_long1 = -1; - - // TODO(ctguil): Handle simple objects returned. - return RETURNCODE_TRUE; } } // namespace webkit_glue diff --git a/webkit/glue/webaccessibility.h b/webkit/glue/webaccessibility.h index 4bfd7743..ea000e7 100644 --- a/webkit/glue/webaccessibility.h +++ b/webkit/glue/webaccessibility.h @@ -1,11 +1,16 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef WEBKIT_GLUE_WEBACCESSIBILITY_H_ #define WEBKIT_GLUE_WEBACCESSIBILITY_H_ +#include <vector> + #include "base/string16.h" +#include "third_party/WebKit/WebKit/chromium/public/WebAccessibilityObject.h" +#include "third_party/WebKit/WebKit/chromium/public/WebAccessibilityRole.h" +#include "third_party/WebKit/WebKit/chromium/public/WebRect.h" namespace WebKit { class WebAccessibilityCache; @@ -13,62 +18,15 @@ class WebAccessibilityCache; namespace webkit_glue { -class WebAccessibility { +// A compact representation of the accessibility information for a +// single web object, in a form that can be serialized and sent from +// the renderer process to the browser process. +struct WebAccessibility { public: - // This defines an enumeration of IDs that can uniquely identify a call to a - // specific accessibility information function. Should match the support - // implemented in WebKit and GlueAccessibilityObject (functions marked with - // return value E_NOTIMPL in WebKit are also excluded). - enum Function { - FUNCTION_NONE = 0, - - // Supported accessibility information retrieval functions. - FUNCTION_DODEFAULTACTION, - FUNCTION_HITTEST, - FUNCTION_LOCATION, - FUNCTION_NAVIGATE, - FUNCTION_GETCHILD, - FUNCTION_CHILDCOUNT, - FUNCTION_DEFAULTACTION, - FUNCTION_DESCRIPTION, - FUNCTION_GETFOCUSEDCHILD, - FUNCTION_HELPTEXT, - FUNCTION_KEYBOARDSHORTCUT, - FUNCTION_NAME, - FUNCTION_GETPARENT, - FUNCTION_ROLE, - FUNCTION_STATE, - FUNCTION_VALUE - - // The deprecated put_accName and put_accValue (IAccessible) are not - // supported here, nor is accSelect, get_accHelpTopic and get_accSelection - // (matching WebKit's support for IAccessible). - }; - - // This defines an enumeration of navigation directions based on (but - // independent of) the MSAA Navigation Constants. However, to avoid the use of - // COM in our Glue layer, we use this as a substitute with a one-to-one - // conversion between Browser side (has COM) and Glue. - enum Direction { - DIRECTION_NONE = 0, - - // Valid directions. - DIRECTION_UP, - DIRECTION_DOWN, - DIRECTION_LEFT, - DIRECTION_RIGHT, - DIRECTION_NEXT, - DIRECTION_PREVIOUS, - DIRECTION_FIRSTCHILD, - DIRECTION_LASTCHILD - }; - - // This defines an enumeration (in alphabetical order) of the supported - // accessibility roles in our Glue layer (used in - // GlueAccessibilityObject::Role). Any interface using roles must provide a - // conversion to its own roles (see e.g. BrowserAccessibility::get_accRole and - // BrowserAccessibility::MSAARole). + // An alphabetical enumeration of accessibility roles. enum Role { + ROLE_NONE = 0, + ROLE_APPLICATION, ROLE_CELL, ROLE_CHECKBUTTON, @@ -99,14 +57,14 @@ class WebAccessibility { ROLE_TABLE, ROLE_TEXT, ROLE_TOOLBAR, - ROLE_TOOLTIP + ROLE_TOOLTIP, + NUM_ROLES }; - // This defines an enumeration (in alphabetical order) of the supported - // accessibility states in our Glue layer (used in - // GlueAccessibilityObject::State). Any interface using states must provide a - // conversion to its own states (see e.g. BrowserAccessibility::get_accState - // and BrowserAccessibility::MSAAState). + // An alphabetical enumeration of accessibility states. + // A state bitmask is formed by shifting 1 to the left by each state, + // for example: + // int mask = (1 << STATE_CHECKED) | (1 << STATE_FOCUSED); enum State { STATE_CHECKED, STATE_FOCUSABLE, @@ -123,58 +81,32 @@ class WebAccessibility { STATE_UNAVAILABLE }; - enum ReturnCode { - RETURNCODE_TRUE, // MSAA S_OK - RETURNCODE_FALSE, // MSAA S_FALSE - RETURNCODE_FAIL // E_FAIL - }; - - // Parameters structure to hold a union of the possible accessibility function - // INPUT variables, with the unused fields always set to default value. Used - // in ViewMsg_GetAccessibilityInfo, as only parameter. - struct InParams { - // Identifier to uniquely distinguish which instance of accessibility - // information is being called upon on the renderer side. - int object_id; - - // Identifier to resolve which accessibility information retrieval function - // is being called. - int function_id; - - // Id of accessible child, whose information is being requested. - int child_id; - - // LONG input parameters, used differently depending on the function called. - long input_long1; - long input_long2; - }; - - // Parameters structure to hold a union of the possible accessibility function - // OUTPUT variables, with the unused fields always set to default value. Used - // in ViewHostMsg_GetAccessibilityInfoResponse, as only parameter. - struct OutParams { - // Identifier to uniquely distinguish which instance of accessibility - // information is being called upon on the renderer side. - int object_id; - - // LONG output parameters, used differently depending on the function - // called. [output_long1] can in some cases be set to -1 to indicate that - // the child object found by the called IAccessible function is not a simple - // object. - long output_long1; - long output_long2; - long output_long3; - long output_long4; - - // String output parameter. - string16 output_string; - - // Return code of the accessibility function call. - int32 return_code; - }; - - static int32 GetAccObjInfo(WebKit::WebAccessibilityCache* cache, - const InParams& in_params, OutParams* out_params); + // Empty constructor, for serialization. + WebAccessibility(); + + // Construct from a WebAccessibilityObject. Recursively creates child + // nodes as needed to complete the tree. Adds |src| to |cache| and + // stores its cache ID. + WebAccessibility(const WebKit::WebAccessibilityObject& src, + WebKit::WebAccessibilityCache* cache); + + // Initialize an already-created struct, same as the constructor a + void Init(const WebKit::WebAccessibilityObject& src, + WebKit::WebAccessibilityCache* cache); + + // This is a simple serializable struct. All member variables should be + // copyable. + int32 id; + string16 name; + string16 value; + string16 action; + string16 description; + string16 help; + string16 shortcut; + Role role; + uint32 state; + WebKit::WebRect location; + std::vector<WebAccessibility> children; }; } // namespace webkit_glue diff --git a/webkit/glue/webaccessibilitymanager.h b/webkit/glue/webaccessibilitymanager.h deleted file mode 100644 index 2debcb7..0000000 --- a/webkit/glue/webaccessibilitymanager.h +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBKIT_GLUE_WEBACCESSIBILITYMANAGER_H_ -#define WEBKIT_GLUE_WEBACCESSIBILITYMANAGER_H_ - -#include "webkit/glue/webaccessibility.h" - -namespace WebKit { -class WebAccessibilityObject; -class WebView; -} - -//////////////////////////////////////////////////////////////////////////////// -// -// WebAccessibilityManager -// -// Responds to incoming accessibility requests from the browser side. Retrieves -// the requested information from the active AccessibilityObject, through the -// GlueAccessibilityObject. -//////////////////////////////////////////////////////////////////////////////// -namespace webkit_glue { - -class WebAccessibilityManager { - public: - WebAccessibilityManager() {} - virtual ~WebAccessibilityManager() {} - - // Creates a new instance of WebAccessibilityManager. - static WebAccessibilityManager* Create(); - - // Retrieves the accessibility information as requested in in_params, by - // calling into WebKit's AccessibilityObject. Maintains a hashmap of the - // currently active (browser side ref-count non-zero) instances. Returns true - // if successful, false otherwise. - virtual bool GetAccObjInfo(WebKit::WebView* view, - const WebAccessibility::InParams& in_params, - WebAccessibility::OutParams* out_params) = 0; - - // Erases the entry identified by the [acc_obj_id] from the hash maps. If - // [clear_all] is true, all entries are erased. Returns true if successful, - // false otherwise. - virtual bool ClearAccObjMap(int acc_obj_id, bool clear_all) = 0; - - // Retrieves the id of the input AccessibilityObject, due to a focus event. - // Returns an id greater than or equal to 0 if successful, -1 otherwise. - virtual int FocusAccObj(const WebKit::WebAccessibilityObject& object) = 0; - - private: - // Retrieves the RenderObject associated with this WebView, and uses it to - // initialize the root of the GlueAccessibilityObject tree with the - // associated accessibility information. Returns true if successful, false - // otherwise. - virtual bool InitAccObjRoot(WebKit::WebView* view) = 0; - - DISALLOW_COPY_AND_ASSIGN(WebAccessibilityManager); -}; - -} // namespace webkit_glue - -#endif // WEBKIT_GLUE_WEBACCESSIBILITYMANAGER_H_ diff --git a/webkit/glue/webkit_glue.gypi b/webkit/glue/webkit_glue.gypi index a0e4437..d55ba2e 100644 --- a/webkit/glue/webkit_glue.gypi +++ b/webkit/glue/webkit_glue.gypi @@ -351,10 +351,6 @@ ['OS!="win"', { 'sources/': [['exclude', '_win\\.cc$']], 'sources!': [ - # These files are Windows-only now but may be ported to other - # platforms. - 'webaccessibility.cc', - 'webaccessibility.h', 'webthemeengine_impl_win.cc', ], }, { # else: OS=="win" |