| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/browser_accessibility.h" | 5 #include "chrome/browser/browser_accessibility.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "chrome/browser/browser_accessibility_manager.h" | 8 #include "chrome/browser/browser_accessibility_manager.h" |
| 9 #include "chrome/common/accessibility.h" | 9 |
| 10 using webkit_glue::WebAccessibility; |
| 10 | 11 |
| 11 BrowserAccessibility::BrowserAccessibility() | 12 BrowserAccessibility::BrowserAccessibility() |
| 12 : iaccessible_id_(-1), | 13 : iaccessible_id_(-1), |
| 13 instance_active_(true) { | 14 instance_active_(true) { |
| 14 } | 15 } |
| 15 | 16 |
| 16 HRESULT BrowserAccessibility::accDoDefaultAction(VARIANT var_id) { | 17 HRESULT BrowserAccessibility::accDoDefaultAction(VARIANT var_id) { |
| 17 if (!instance_active()) { | 18 if (!instance_active()) { |
| 18 // Instance no longer active, fail gracefully. | 19 // Instance no longer active, fail gracefully. |
| 19 // TODO(klink): Once we have MSAA events, change these fails for having | 20 // TODO(klink): Once we have MSAA events, change these fails for having |
| 20 // BrowserAccessibilityManager firing the right event. | 21 // BrowserAccessibilityManager firing the right event. |
| 21 return E_FAIL; | 22 return E_FAIL; |
| 22 } | 23 } |
| 23 | 24 |
| 24 if (var_id.vt != VT_I4) | 25 if (var_id.vt != VT_I4) |
| 25 return E_INVALIDARG; | 26 return E_INVALIDARG; |
| 26 | 27 |
| 27 if (!RequestAccessibilityInfo(IACCESSIBLE_FUNC_ACCDODEFAULTACTION, var_id, | 28 if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_DODEFAULTACTION, |
| 28 NULL, NULL)) { | 29 var_id, NULL, NULL)) { |
| 29 return E_FAIL; | 30 return E_FAIL; |
| 30 } | 31 } |
| 31 | 32 |
| 32 if (!response().return_code) | 33 if (!response().return_code) |
| 33 return S_FALSE; | 34 return S_FALSE; |
| 34 | 35 |
| 35 return S_OK; | 36 return S_OK; |
| 36 } | 37 } |
| 37 | 38 |
| 38 STDMETHODIMP BrowserAccessibility::accHitTest(LONG x_left, LONG y_top, | 39 STDMETHODIMP BrowserAccessibility::accHitTest(LONG x_left, LONG y_top, |
| 39 VARIANT* child) { | 40 VARIANT* child) { |
| 40 if (!instance_active()) { | 41 if (!instance_active()) { |
| 41 // Instance no longer active, fail gracefully. | 42 // Instance no longer active, fail gracefully. |
| 42 return E_FAIL; | 43 return E_FAIL; |
| 43 } | 44 } |
| 44 | 45 |
| 45 if (!child) | 46 if (!child) |
| 46 return E_INVALIDARG; | 47 return E_INVALIDARG; |
| 47 | 48 |
| 48 if (!parent_hwnd()) { | 49 if (!parent_hwnd()) { |
| 49 // Parent HWND needed for coordinate conversion. | 50 // Parent HWND needed for coordinate conversion. |
| 50 return E_FAIL; | 51 return E_FAIL; |
| 51 } | 52 } |
| 52 | 53 |
| 53 // Convert coordinates to test from screen into client window coordinates, to | 54 // Convert coordinates to test from screen into client window coordinates, to |
| 54 // maintain sandbox functionality on renderer side. | 55 // maintain sandbox functionality on renderer side. |
| 55 POINT p = {x_left, y_top}; | 56 POINT p = {x_left, y_top}; |
| 56 ::ScreenToClient(parent_hwnd(), &p); | 57 ::ScreenToClient(parent_hwnd(), &p); |
| 57 | 58 |
| 58 if (!RequestAccessibilityInfo(IACCESSIBLE_FUNC_ACCHITTEST, EmptyVariant(), | 59 if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_HITTEST, |
| 59 p.x, p.y)) { | 60 EmptyVariant(), p.x, p.y)) { |
| 60 return E_FAIL; | 61 return E_FAIL; |
| 61 } | 62 } |
| 62 | 63 |
| 63 if (!response().return_code) { | 64 if (!response().return_code) { |
| 64 // The point is outside of the object's boundaries. | 65 // The point is outside of the object's boundaries. |
| 65 child->vt = VT_EMPTY; | 66 child->vt = VT_EMPTY; |
| 66 return S_FALSE; | 67 return S_FALSE; |
| 67 } | 68 } |
| 68 | 69 |
| 69 if (response().output_long1 == -1) { | 70 if (response().output_long1 == -1) { |
| 70 if (CreateInstance(IID_IAccessible, response().iaccessible_id, | 71 if (CreateInstance(IID_IAccessible, response().object_id, |
| 71 reinterpret_cast<void**>(&child->pdispVal)) == S_OK) { | 72 reinterpret_cast<void**>(&child->pdispVal)) == S_OK) { |
| 72 child->vt = VT_DISPATCH; | 73 child->vt = VT_DISPATCH; |
| 73 // Increment the reference count for the retrieved interface. | 74 // Increment the reference count for the retrieved interface. |
| 74 child->pdispVal->AddRef(); | 75 child->pdispVal->AddRef(); |
| 75 } else { | 76 } else { |
| 76 return E_NOINTERFACE; | 77 return E_NOINTERFACE; |
| 77 } | 78 } |
| 78 } else { | 79 } else { |
| 79 child->vt = VT_I4; | 80 child->vt = VT_I4; |
| 80 child->lVal = response().output_long1; | 81 child->lVal = response().output_long1; |
| 81 } | 82 } |
| 82 | 83 |
| 83 return S_OK; | 84 return S_OK; |
| 84 } | 85 } |
| 85 | 86 |
| 86 STDMETHODIMP BrowserAccessibility::accLocation(LONG* x_left, LONG* y_top, | 87 STDMETHODIMP BrowserAccessibility::accLocation(LONG* x_left, LONG* y_top, |
| 87 LONG* width, LONG* height, | 88 LONG* width, LONG* height, |
| 88 VARIANT var_id) { | 89 VARIANT var_id) { |
| 89 if (!instance_active()) { | 90 if (!instance_active()) { |
| 90 // Instance no longer active, fail gracefully. | 91 // Instance no longer active, fail gracefully. |
| 91 return E_FAIL; | 92 return E_FAIL; |
| 92 } | 93 } |
| 93 | 94 |
| 94 if (var_id.vt != VT_I4 || !x_left || !y_top || !width || !height || | 95 if (var_id.vt != VT_I4 || !x_left || !y_top || !width || !height || |
| 95 !parent_hwnd()) { | 96 !parent_hwnd()) { |
| 96 return E_INVALIDARG; | 97 return E_INVALIDARG; |
| 97 } | 98 } |
| 98 | 99 |
| 99 if (!RequestAccessibilityInfo(IACCESSIBLE_FUNC_ACCLOCATION, var_id, NULL, | 100 if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_LOCATION, var_id, |
| 100 NULL)) { | 101 NULL, NULL)) { |
| 101 return E_FAIL; | 102 return E_FAIL; |
| 102 } | 103 } |
| 103 | 104 |
| 104 POINT top_left = {0, 0}; | 105 POINT top_left = {0, 0}; |
| 105 | 106 |
| 106 // Find the top left corner of the containing window in screen coords, and | 107 // Find the top left corner of the containing window in screen coords, and |
| 107 // adjust the output position by this amount. | 108 // adjust the output position by this amount. |
| 108 ::ClientToScreen(parent_hwnd(), &top_left); | 109 ::ClientToScreen(parent_hwnd(), &top_left); |
| 109 | 110 |
| 110 *x_left = response().output_long1 + top_left.x; | 111 *x_left = response().output_long1 + top_left.x; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 131 // MSAA states that navigating to first/last child can only be from self. | 132 // MSAA states that navigating to first/last child can only be from self. |
| 132 return E_INVALIDARG; | 133 return E_INVALIDARG; |
| 133 } | 134 } |
| 134 | 135 |
| 135 if (nav_dir == NAVDIR_DOWN || nav_dir == NAVDIR_UP || | 136 if (nav_dir == NAVDIR_DOWN || nav_dir == NAVDIR_UP || |
| 136 nav_dir == NAVDIR_LEFT || nav_dir == NAVDIR_RIGHT) { | 137 nav_dir == NAVDIR_LEFT || nav_dir == NAVDIR_RIGHT) { |
| 137 // Directions not implemented, matching Mozilla and IE. | 138 // Directions not implemented, matching Mozilla and IE. |
| 138 return E_INVALIDARG; | 139 return E_INVALIDARG; |
| 139 } | 140 } |
| 140 | 141 |
| 141 if (!RequestAccessibilityInfo(IACCESSIBLE_FUNC_ACCNAVIGATE, start, nav_dir, | 142 if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_NAVIGATE, start, |
| 142 NULL)) { | 143 nav_dir, NULL)) { |
| 143 return E_FAIL; | 144 return E_FAIL; |
| 144 } | 145 } |
| 145 | 146 |
| 146 if (!response().return_code) { | 147 if (!response().return_code) { |
| 147 // No screen element was found in the specified direction. | 148 // No screen element was found in the specified direction. |
| 148 end->vt = VT_EMPTY; | 149 end->vt = VT_EMPTY; |
| 149 return S_FALSE; | 150 return S_FALSE; |
| 150 } | 151 } |
| 151 | 152 |
| 152 if (response().output_long1 == -1) { | 153 if (response().output_long1 == -1) { |
| 153 if (CreateInstance(IID_IAccessible, response().iaccessible_id, | 154 if (CreateInstance(IID_IAccessible, response().object_id, |
| 154 reinterpret_cast<void**>(&end->pdispVal)) == S_OK) { | 155 reinterpret_cast<void**>(&end->pdispVal)) == S_OK) { |
| 155 end->vt = VT_DISPATCH; | 156 end->vt = VT_DISPATCH; |
| 156 // Increment the reference count for the retrieved interface. | 157 // Increment the reference count for the retrieved interface. |
| 157 end->pdispVal->AddRef(); | 158 end->pdispVal->AddRef(); |
| 158 } else { | 159 } else { |
| 159 return E_NOINTERFACE; | 160 return E_NOINTERFACE; |
| 160 } | 161 } |
| 161 } else { | 162 } else { |
| 162 end->vt = VT_I4; | 163 end->vt = VT_I4; |
| 163 end->lVal = response().output_long1; | 164 end->lVal = response().output_long1; |
| 164 } | 165 } |
| 165 | 166 |
| 166 return S_OK; | 167 return S_OK; |
| 167 } | 168 } |
| 168 | 169 |
| 169 STDMETHODIMP BrowserAccessibility::get_accChild(VARIANT var_child, | 170 STDMETHODIMP BrowserAccessibility::get_accChild(VARIANT var_child, |
| 170 IDispatch** disp_child) { | 171 IDispatch** disp_child) { |
| 171 if (!instance_active()) { | 172 if (!instance_active()) { |
| 172 // Instance no longer active, fail gracefully. | 173 // Instance no longer active, fail gracefully. |
| 173 return E_FAIL; | 174 return E_FAIL; |
| 174 } | 175 } |
| 175 | 176 |
| 176 if (var_child.vt != VT_I4 || !disp_child) | 177 if (var_child.vt != VT_I4 || !disp_child) |
| 177 return E_INVALIDARG; | 178 return E_INVALIDARG; |
| 178 | 179 |
| 179 // If var_child is the parent, remain with the same IDispatch. | 180 // If var_child is the parent, remain with the same IDispatch. |
| 180 if (var_child.lVal == CHILDID_SELF && iaccessible_id_ != 0) | 181 if (var_child.lVal == CHILDID_SELF && iaccessible_id_ != 0) |
| 181 return S_OK; | 182 return S_OK; |
| 182 | 183 |
| 183 if (!RequestAccessibilityInfo(IACCESSIBLE_FUNC_GET_ACCCHILD, var_child, NULL, | 184 if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_GETCHILD, var_child, |
| 184 NULL)) { | 185 NULL, NULL)) { |
| 185 return E_FAIL; | 186 return E_FAIL; |
| 186 } | 187 } |
| 187 | 188 |
| 188 if (!response().return_code) { | 189 if (!response().return_code) { |
| 189 // When at a leaf, children are handled by the parent object. | 190 // When at a leaf, children are handled by the parent object. |
| 190 *disp_child = NULL; | 191 *disp_child = NULL; |
| 191 return S_FALSE; | 192 return S_FALSE; |
| 192 } | 193 } |
| 193 | 194 |
| 194 // Retrieve the IUnknown interface for the parent view, and assign the | 195 // Retrieve the IUnknown interface for the parent view, and assign the |
| 195 // IDispatch returned. | 196 // IDispatch returned. |
| 196 if (CreateInstance(IID_IAccessible, response().iaccessible_id, | 197 if (CreateInstance(IID_IAccessible, response().object_id, |
| 197 reinterpret_cast<void**>(disp_child)) == S_OK) { | 198 reinterpret_cast<void**>(disp_child)) == S_OK) { |
| 198 // Increment the reference count for the retrieved interface. | 199 // Increment the reference count for the retrieved interface. |
| 199 (*disp_child)->AddRef(); | 200 (*disp_child)->AddRef(); |
| 200 return S_OK; | 201 return S_OK; |
| 201 } else { | 202 } else { |
| 202 return E_NOINTERFACE; | 203 return E_NOINTERFACE; |
| 203 } | 204 } |
| 204 } | 205 } |
| 205 | 206 |
| 206 STDMETHODIMP BrowserAccessibility::get_accChildCount(LONG* child_count) { | 207 STDMETHODIMP BrowserAccessibility::get_accChildCount(LONG* child_count) { |
| 207 if (!instance_active()) { | 208 if (!instance_active()) { |
| 208 // Instance no longer active, fail gracefully. | 209 // Instance no longer active, fail gracefully. |
| 209 return E_FAIL; | 210 return E_FAIL; |
| 210 } | 211 } |
| 211 | 212 |
| 212 if (!child_count) | 213 if (!child_count) |
| 213 return E_INVALIDARG; | 214 return E_INVALIDARG; |
| 214 | 215 |
| 215 if (!RequestAccessibilityInfo(IACCESSIBLE_FUNC_GET_ACCCHILDCOUNT, | 216 if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_CHILDCOUNT, |
| 216 EmptyVariant(), NULL, NULL)) { | 217 EmptyVariant(), NULL, NULL)) { |
| 217 return E_FAIL; | 218 return E_FAIL; |
| 218 } | 219 } |
| 219 | 220 |
| 220 *child_count = response().output_long1; | 221 *child_count = response().output_long1; |
| 221 return S_OK; | 222 return S_OK; |
| 222 } | 223 } |
| 223 | 224 |
| 224 STDMETHODIMP BrowserAccessibility::get_accDefaultAction(VARIANT var_id, | 225 STDMETHODIMP BrowserAccessibility::get_accDefaultAction(VARIANT var_id, |
| 225 BSTR* def_action) { | 226 BSTR* def_action) { |
| 226 if (!instance_active()) { | 227 if (!instance_active()) { |
| 227 // Instance no longer active, fail gracefully. | 228 // Instance no longer active, fail gracefully. |
| 228 return E_FAIL; | 229 return E_FAIL; |
| 229 } | 230 } |
| 230 | 231 |
| 231 if (var_id.vt != VT_I4 || !def_action) | 232 if (var_id.vt != VT_I4 || !def_action) |
| 232 return E_INVALIDARG; | 233 return E_INVALIDARG; |
| 233 | 234 |
| 234 if (!RequestAccessibilityInfo(IACCESSIBLE_FUNC_GET_ACCDEFAULTACTION, var_id, | 235 if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_DEFAULTACTION, |
| 235 NULL, NULL)) { | 236 var_id, NULL, NULL)) { |
| 236 return E_FAIL; | 237 return E_FAIL; |
| 237 } | 238 } |
| 238 | 239 |
| 239 if (!response().return_code) { | 240 if (!response().return_code) { |
| 240 // No string found. | 241 // No string found. |
| 241 return S_FALSE; | 242 return S_FALSE; |
| 242 } | 243 } |
| 243 | 244 |
| 244 *def_action = CComBSTR(response().output_string.c_str()).Detach(); | 245 *def_action = CComBSTR(response().output_string.c_str()).Detach(); |
| 245 | 246 |
| 246 DCHECK(*def_action); | 247 DCHECK(*def_action); |
| 247 return S_OK; | 248 return S_OK; |
| 248 } | 249 } |
| 249 | 250 |
| 250 STDMETHODIMP BrowserAccessibility::get_accDescription(VARIANT var_id, | 251 STDMETHODIMP BrowserAccessibility::get_accDescription(VARIANT var_id, |
| 251 BSTR* desc) { | 252 BSTR* desc) { |
| 252 if (!instance_active()) { | 253 if (!instance_active()) { |
| 253 // Instance no longer active, fail gracefully. | 254 // Instance no longer active, fail gracefully. |
| 254 return E_FAIL; | 255 return E_FAIL; |
| 255 } | 256 } |
| 256 | 257 |
| 257 if (var_id.vt != VT_I4 || !desc) | 258 if (var_id.vt != VT_I4 || !desc) |
| 258 return E_INVALIDARG; | 259 return E_INVALIDARG; |
| 259 | 260 |
| 260 if (!RequestAccessibilityInfo(IACCESSIBLE_FUNC_GET_ACCDESCRIPTION, var_id, | 261 if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_DESCRIPTION, var_id, |
| 261 NULL, NULL)) { | 262 NULL, NULL)) { |
| 262 return E_FAIL; | 263 return E_FAIL; |
| 263 } | 264 } |
| 264 | 265 |
| 265 if (!response().return_code) { | 266 if (!response().return_code) { |
| 266 // No string found. | 267 // No string found. |
| 267 return S_FALSE; | 268 return S_FALSE; |
| 268 } | 269 } |
| 269 | 270 |
| 270 *desc = CComBSTR(response().output_string.c_str()).Detach(); | 271 *desc = CComBSTR(response().output_string.c_str()).Detach(); |
| 271 | 272 |
| 272 DCHECK(*desc); | 273 DCHECK(*desc); |
| 273 return S_OK; | 274 return S_OK; |
| 274 } | 275 } |
| 275 | 276 |
| 276 STDMETHODIMP BrowserAccessibility::get_accFocus(VARIANT* focus_child) { | 277 STDMETHODIMP BrowserAccessibility::get_accFocus(VARIANT* focus_child) { |
| 277 if (!instance_active()) { | 278 if (!instance_active()) { |
| 278 // Instance no longer active, fail gracefully. | 279 // Instance no longer active, fail gracefully. |
| 279 return E_FAIL; | 280 return E_FAIL; |
| 280 } | 281 } |
| 281 | 282 |
| 282 if (!focus_child) | 283 if (!focus_child) |
| 283 return E_INVALIDARG; | 284 return E_INVALIDARG; |
| 284 | 285 |
| 285 if (!RequestAccessibilityInfo(IACCESSIBLE_FUNC_GET_ACCFOCUS, EmptyVariant(), | 286 if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_GETFOCUSEDCHILD, |
| 286 NULL, NULL)) { | 287 EmptyVariant(), NULL, NULL)) { |
| 287 return E_FAIL; | 288 return E_FAIL; |
| 288 } | 289 } |
| 289 | 290 |
| 290 if (!response().return_code) { | 291 if (!response().return_code) { |
| 291 // The window that contains this object is not the active window. | 292 // The window that contains this object is not the active window. |
| 292 focus_child->vt = VT_EMPTY; | 293 focus_child->vt = VT_EMPTY; |
| 293 return S_FALSE; | 294 return S_FALSE; |
| 294 } | 295 } |
| 295 | 296 |
| 296 if (response().output_long1 == -1) { | 297 if (response().output_long1 == -1) { |
| 297 if (CreateInstance(IID_IAccessible, response().iaccessible_id, | 298 if (CreateInstance(IID_IAccessible, response().object_id, |
| 298 reinterpret_cast<void**>(&focus_child->pdispVal)) == S_OK) { | 299 reinterpret_cast<void**>(&focus_child->pdispVal)) == S_OK) { |
| 299 focus_child->vt = VT_DISPATCH; | 300 focus_child->vt = VT_DISPATCH; |
| 300 // Increment the reference count for the retrieved interface. | 301 // Increment the reference count for the retrieved interface. |
| 301 focus_child->pdispVal->AddRef(); | 302 focus_child->pdispVal->AddRef(); |
| 302 } else { | 303 } else { |
| 303 return E_NOINTERFACE; | 304 return E_NOINTERFACE; |
| 304 } | 305 } |
| 305 } else { | 306 } else { |
| 306 focus_child->vt = VT_I4; | 307 focus_child->vt = VT_I4; |
| 307 focus_child->lVal = response().output_long1; | 308 focus_child->lVal = response().output_long1; |
| 308 } | 309 } |
| 309 | 310 |
| 310 return S_OK; | 311 return S_OK; |
| 311 } | 312 } |
| 312 | 313 |
| 313 STDMETHODIMP BrowserAccessibility::get_accHelp(VARIANT var_id, BSTR* help) { | 314 STDMETHODIMP BrowserAccessibility::get_accHelp(VARIANT var_id, BSTR* help) { |
| 314 if (!instance_active()) { | 315 if (!instance_active()) { |
| 315 // Instance no longer active, fail gracefully. | 316 // Instance no longer active, fail gracefully. |
| 316 return E_FAIL; | 317 return E_FAIL; |
| 317 } | 318 } |
| 318 | 319 |
| 319 if (var_id.vt != VT_I4 || !help) | 320 if (var_id.vt != VT_I4 || !help) |
| 320 return E_INVALIDARG; | 321 return E_INVALIDARG; |
| 321 | 322 |
| 322 if (!RequestAccessibilityInfo(IACCESSIBLE_FUNC_GET_ACCHELP, var_id, NULL, | 323 if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_HELPTEXT, var_id, |
| 323 NULL)) { | 324 NULL, NULL)) { |
| 324 return E_FAIL; | 325 return E_FAIL; |
| 325 } | 326 } |
| 326 | 327 |
| 327 if (!response().return_code) { | 328 if (!response().return_code || response().output_string.empty()) { |
| 328 // No string found. | 329 // No string found. |
| 329 return S_FALSE; | 330 return S_FALSE; |
| 330 } | 331 } |
| 331 | 332 |
| 332 *help = CComBSTR(response().output_string.c_str()).Detach(); | 333 *help = CComBSTR(response().output_string.c_str()).Detach(); |
| 333 | 334 |
| 334 DCHECK(*help); | 335 DCHECK(*help); |
| 335 return S_OK; | 336 return S_OK; |
| 336 } | 337 } |
| 337 | 338 |
| 338 STDMETHODIMP BrowserAccessibility::get_accKeyboardShortcut(VARIANT var_id, | 339 STDMETHODIMP BrowserAccessibility::get_accKeyboardShortcut(VARIANT var_id, |
| 339 BSTR* acc_key) { | 340 BSTR* acc_key) { |
| 340 if (!instance_active()) { | 341 if (!instance_active()) { |
| 341 // Instance no longer active, fail gracefully. | 342 // Instance no longer active, fail gracefully. |
| 342 return E_FAIL; | 343 return E_FAIL; |
| 343 } | 344 } |
| 344 | 345 |
| 345 if (var_id.vt != VT_I4 || !acc_key) | 346 if (var_id.vt != VT_I4 || !acc_key) |
| 346 return E_INVALIDARG; | 347 return E_INVALIDARG; |
| 347 | 348 |
| 348 if (!RequestAccessibilityInfo(IACCESSIBLE_FUNC_GET_ACCKEYBOARDSHORTCUT, | 349 if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_KEYBOARDSHORTCUT, |
| 349 var_id, NULL, NULL)) { | 350 var_id, NULL, NULL)) { |
| 350 return E_FAIL; | 351 return E_FAIL; |
| 351 } | 352 } |
| 352 | 353 |
| 353 if (!response().return_code) { | 354 if (!response().return_code) { |
| 354 // No string found. | 355 // No string found. |
| 355 return S_FALSE; | 356 return S_FALSE; |
| 356 } | 357 } |
| 357 | 358 |
| 358 *acc_key = CComBSTR(response().output_string.c_str()).Detach(); | 359 *acc_key = CComBSTR(response().output_string.c_str()).Detach(); |
| 359 | 360 |
| 360 DCHECK(*acc_key); | 361 DCHECK(*acc_key); |
| 361 return S_OK; | 362 return S_OK; |
| 362 } | 363 } |
| 363 | 364 |
| 364 STDMETHODIMP BrowserAccessibility::get_accName(VARIANT var_id, BSTR* name) { | 365 STDMETHODIMP BrowserAccessibility::get_accName(VARIANT var_id, BSTR* name) { |
| 365 if (!instance_active()) { | 366 if (!instance_active()) { |
| 366 // Instance no longer active, fail gracefully. | 367 // Instance no longer active, fail gracefully. |
| 367 return E_FAIL; | 368 return E_FAIL; |
| 368 } | 369 } |
| 369 | 370 |
| 370 if (var_id.vt != VT_I4 || !name) | 371 if (var_id.vt != VT_I4 || !name) |
| 371 return E_INVALIDARG; | 372 return E_INVALIDARG; |
| 372 | 373 |
| 373 if (!RequestAccessibilityInfo(IACCESSIBLE_FUNC_GET_ACCNAME, var_id, NULL, | 374 if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_NAME, var_id, NULL, |
| 374 NULL)) { | 375 NULL)) { |
| 375 return E_FAIL; | 376 return E_FAIL; |
| 376 } | 377 } |
| 377 | 378 |
| 378 if (!response().return_code) { | 379 if (!response().return_code) { |
| 379 // No string found. | 380 // No string found. |
| 380 return S_FALSE; | 381 return S_FALSE; |
| 381 } | 382 } |
| 382 | 383 |
| 383 *name = CComBSTR(response().output_string.c_str()).Detach(); | 384 *name = CComBSTR(response().output_string.c_str()).Detach(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 404 IID_IAccessible, | 405 IID_IAccessible, |
| 405 reinterpret_cast<void**>(disp_parent)); | 406 reinterpret_cast<void**>(disp_parent)); |
| 406 | 407 |
| 407 if (!SUCCEEDED(hr)) { | 408 if (!SUCCEEDED(hr)) { |
| 408 *disp_parent = NULL; | 409 *disp_parent = NULL; |
| 409 return S_FALSE; | 410 return S_FALSE; |
| 410 } | 411 } |
| 411 return S_OK; | 412 return S_OK; |
| 412 } | 413 } |
| 413 | 414 |
| 414 if (!RequestAccessibilityInfo(IACCESSIBLE_FUNC_GET_ACCPARENT, EmptyVariant(), | 415 if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_GETPARENT, |
| 415 NULL, NULL)) { | 416 EmptyVariant(), NULL, NULL)) { |
| 416 return E_FAIL; | 417 return E_FAIL; |
| 417 } | 418 } |
| 418 | 419 |
| 419 if (!response().return_code) { | 420 if (!response().return_code) { |
| 420 // No parent exists for this object. | 421 // No parent exists for this object. |
| 421 return S_FALSE; | 422 return S_FALSE; |
| 422 } | 423 } |
| 423 | 424 |
| 424 // Retrieve the IUnknown interface for the parent view, and assign the | 425 // Retrieve the IUnknown interface for the parent view, and assign the |
| 425 // IDispatch returned. | 426 // IDispatch returned. |
| 426 if (CreateInstance(IID_IAccessible, response().iaccessible_id, | 427 if (CreateInstance(IID_IAccessible, response().object_id, |
| 427 reinterpret_cast<void**>(disp_parent)) == S_OK) { | 428 reinterpret_cast<void**>(disp_parent)) == S_OK) { |
| 428 // Increment the reference count for the retrieved interface. | 429 // Increment the reference count for the retrieved interface. |
| 429 (*disp_parent)->AddRef(); | 430 (*disp_parent)->AddRef(); |
| 430 return S_OK; | 431 return S_OK; |
| 431 } else { | 432 } else { |
| 432 return E_NOINTERFACE; | 433 return E_NOINTERFACE; |
| 433 } | 434 } |
| 434 } | 435 } |
| 435 | 436 |
| 436 STDMETHODIMP BrowserAccessibility::get_accRole(VARIANT var_id, VARIANT* role) { | 437 STDMETHODIMP BrowserAccessibility::get_accRole(VARIANT var_id, VARIANT* role) { |
| 437 if (!instance_active()) { | 438 if (!instance_active()) { |
| 438 // Instance no longer active, fail gracefully. | 439 // Instance no longer active, fail gracefully. |
| 439 return E_FAIL; | 440 return E_FAIL; |
| 440 } | 441 } |
| 441 | 442 |
| 442 if (var_id.vt != VT_I4 || !role) | 443 if (var_id.vt != VT_I4 || !role) |
| 443 return E_INVALIDARG; | 444 return E_INVALIDARG; |
| 444 | 445 |
| 445 if (!RequestAccessibilityInfo(IACCESSIBLE_FUNC_GET_ACCROLE, var_id, NULL, | 446 if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_ROLE, var_id, NULL, |
| 446 NULL)) { | 447 NULL)) { |
| 447 return E_FAIL; | 448 return E_FAIL; |
| 448 } | 449 } |
| 449 | 450 |
| 450 role->vt = VT_I4; | 451 role->vt = VT_I4; |
| 451 role->lVal = response().output_long1; | 452 role->lVal = MSAARole(response().output_long1); |
| 452 | |
| 453 return S_OK; | 453 return S_OK; |
| 454 } | 454 } |
| 455 | 455 |
| 456 STDMETHODIMP BrowserAccessibility::get_accState(VARIANT var_id, | 456 STDMETHODIMP BrowserAccessibility::get_accState(VARIANT var_id, |
| 457 VARIANT* state) { | 457 VARIANT* state) { |
| 458 if (!instance_active()) { | 458 if (!instance_active()) { |
| 459 // Instance no longer active, fail gracefully. | 459 // Instance no longer active, fail gracefully. |
| 460 return E_FAIL; | 460 return E_FAIL; |
| 461 } | 461 } |
| 462 | 462 |
| 463 if (var_id.vt != VT_I4 || !state) | 463 if (var_id.vt != VT_I4 || !state) |
| 464 return E_INVALIDARG; | 464 return E_INVALIDARG; |
| 465 | 465 |
| 466 if (!RequestAccessibilityInfo(IACCESSIBLE_FUNC_GET_ACCSTATE, var_id, NULL, | 466 if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_STATE, var_id, NULL, |
| 467 NULL)) { | 467 NULL)) { |
| 468 return E_FAIL; | 468 return E_FAIL; |
| 469 } | 469 } |
| 470 | 470 |
| 471 state->vt = VT_I4; | 471 state->vt = VT_I4; |
| 472 state->lVal = response().output_long1; | 472 state->lVal = MSAAState(response().output_long1); |
| 473 | |
| 474 return S_OK; | 473 return S_OK; |
| 475 } | 474 } |
| 476 | 475 |
| 477 STDMETHODIMP BrowserAccessibility::get_accValue(VARIANT var_id, BSTR* value) { | 476 STDMETHODIMP BrowserAccessibility::get_accValue(VARIANT var_id, BSTR* value) { |
| 478 if (!instance_active()) { | 477 if (!instance_active()) { |
| 479 // Instance no longer active, fail gracefully. | 478 // Instance no longer active, fail gracefully. |
| 480 return E_FAIL; | 479 return E_FAIL; |
| 481 } | 480 } |
| 482 | 481 |
| 483 if (var_id.vt != VT_I4 || !value) | 482 if (var_id.vt != VT_I4 || !value) |
| 484 return E_INVALIDARG; | 483 return E_INVALIDARG; |
| 485 | 484 |
| 486 if (!RequestAccessibilityInfo(IACCESSIBLE_FUNC_GET_ACCVALUE, var_id, NULL, | 485 if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_VALUE, var_id, NULL, |
| 487 NULL)) { | 486 NULL)) { |
| 488 return E_FAIL; | 487 return E_FAIL; |
| 489 } | 488 } |
| 490 | 489 |
| 491 if (!response().return_code) { | 490 if (!response().return_code || response().output_string.empty()) { |
| 492 // No string found. | 491 // No string found. |
| 493 return S_FALSE; | 492 return S_FALSE; |
| 494 } | 493 } |
| 495 | 494 |
| 496 *value = CComBSTR(response().output_string.c_str()).Detach(); | 495 *value = CComBSTR(response().output_string.c_str()).Detach(); |
| 497 | 496 |
| 498 DCHECK(*value); | 497 DCHECK(*value); |
| 499 return S_OK; | 498 return S_OK; |
| 500 } | 499 } |
| 501 | 500 |
| 502 STDMETHODIMP BrowserAccessibility::accSelect(LONG flags_select, | 501 STDMETHODIMP BrowserAccessibility::accSelect(LONG flags_select, |
| 503 VARIANT var_id) { | 502 VARIANT var_id) { |
| 504 return DISP_E_MEMBERNOTFOUND; | 503 return E_NOTIMPL; |
| 505 } | 504 } |
| 506 | 505 |
| 507 STDMETHODIMP BrowserAccessibility::get_accHelpTopic(BSTR* help_file, | 506 STDMETHODIMP BrowserAccessibility::get_accHelpTopic(BSTR* help_file, |
| 508 VARIANT var_id, | 507 VARIANT var_id, |
| 509 LONG* topic_id) { | 508 LONG* topic_id) { |
| 510 if (help_file) { | 509 if (help_file) { |
| 511 *help_file = NULL; | 510 *help_file = NULL; |
| 512 } | 511 } |
| 513 if (topic_id) { | 512 if (topic_id) { |
| 514 *topic_id = static_cast<LONG>(-1); | 513 *topic_id = static_cast<LONG>(-1); |
| 515 } | 514 } |
| 516 return DISP_E_MEMBERNOTFOUND; | 515 return E_NOTIMPL; |
| 517 } | 516 } |
| 518 | 517 |
| 519 STDMETHODIMP BrowserAccessibility::get_accSelection(VARIANT* selected) { | 518 STDMETHODIMP BrowserAccessibility::get_accSelection(VARIANT* selected) { |
| 520 if (selected) | 519 if (selected) |
| 521 selected->vt = VT_EMPTY; | 520 selected->vt = VT_EMPTY; |
| 522 | 521 |
| 523 return DISP_E_MEMBERNOTFOUND; | 522 return E_NOTIMPL; |
| 524 } | 523 } |
| 525 | 524 |
| 526 STDMETHODIMP BrowserAccessibility::put_accName(VARIANT var_id, BSTR put_name) { | 525 STDMETHODIMP BrowserAccessibility::put_accName(VARIANT var_id, BSTR put_name) { |
| 527 return DISP_E_MEMBERNOTFOUND; | 526 return E_NOTIMPL; |
| 528 } | 527 } |
| 529 | 528 |
| 530 STDMETHODIMP BrowserAccessibility::put_accValue(VARIANT var_id, BSTR put_val) { | 529 STDMETHODIMP BrowserAccessibility::put_accValue(VARIANT var_id, BSTR put_val) { |
| 531 return DISP_E_MEMBERNOTFOUND; | 530 return E_NOTIMPL; |
| 532 } | 531 } |
| 533 | 532 |
| 534 STDMETHODIMP BrowserAccessibility::CreateInstance(REFIID iid, | 533 STDMETHODIMP BrowserAccessibility::CreateInstance(REFIID iid, |
| 535 int iaccessible_id, | 534 int iaccessible_id, |
| 536 void** interface_ptr) { | 535 void** interface_ptr) { |
| 537 return BrowserAccessibilityManager::GetInstance()-> | 536 return BrowserAccessibilityManager::GetInstance()-> |
| 538 CreateAccessibilityInstance(iid, iaccessible_id, instance_id(), | 537 CreateAccessibilityInstance(iid, iaccessible_id, instance_id(), |
| 539 interface_ptr); | 538 interface_ptr); |
| 540 } | 539 } |
| 541 | 540 |
| 542 bool BrowserAccessibility::RequestAccessibilityInfo(int iaccessible_func_id, | 541 bool BrowserAccessibility::RequestAccessibilityInfo(int iaccessible_func_id, |
| 543 VARIANT var_id, LONG input1, | 542 VARIANT var_id, LONG input1, |
| 544 LONG input2) { | 543 LONG input2) { |
| 545 return BrowserAccessibilityManager::GetInstance()->RequestAccessibilityInfo( | 544 return BrowserAccessibilityManager::GetInstance()->RequestAccessibilityInfo( |
| 546 iaccessible_id(), instance_id(), iaccessible_func_id, var_id, input1, | 545 iaccessible_id(), instance_id(), iaccessible_func_id, var_id.lVal, input1, |
| 547 input2); | 546 input2); |
| 548 } | 547 } |
| 549 | 548 |
| 550 const AccessibilityOutParams& BrowserAccessibility::response() { | 549 const WebAccessibility::OutParams& BrowserAccessibility::response() { |
| 551 return BrowserAccessibilityManager::GetInstance()->response(); | 550 return BrowserAccessibilityManager::GetInstance()->response(); |
| 552 } | 551 } |
| 553 | 552 |
| 554 HWND BrowserAccessibility::parent_hwnd() { | 553 HWND BrowserAccessibility::parent_hwnd() { |
| 555 return BrowserAccessibilityManager::GetInstance()->parent_hwnd(instance_id()); | 554 return BrowserAccessibilityManager::GetInstance()->parent_hwnd(instance_id()); |
| 556 } | 555 } |
| 556 |
| 557 long BrowserAccessibility::MSAARole(long browser_accessibility_role) { |
| 558 switch (browser_accessibility_role) { |
| 559 case WebAccessibility::ROLE_PUSHBUTTON : |
| 560 return ROLE_SYSTEM_PUSHBUTTON; |
| 561 case WebAccessibility::ROLE_RADIOBUTTON : |
| 562 return ROLE_SYSTEM_RADIOBUTTON; |
| 563 case WebAccessibility::ROLE_CHECKBUTTON : |
| 564 return ROLE_SYSTEM_CHECKBUTTON; |
| 565 case WebAccessibility::ROLE_SLIDER : |
| 566 return ROLE_SYSTEM_SLIDER; |
| 567 case WebAccessibility::ROLE_PAGETABLIST : |
| 568 return ROLE_SYSTEM_PAGETABLIST; |
| 569 case WebAccessibility::ROLE_TEXT : |
| 570 return ROLE_SYSTEM_TEXT; |
| 571 case WebAccessibility::ROLE_STATICTEXT : |
| 572 return ROLE_SYSTEM_STATICTEXT; |
| 573 case WebAccessibility::ROLE_OUTLINE : |
| 574 return ROLE_SYSTEM_OUTLINE; |
| 575 case WebAccessibility::ROLE_COLUMN : |
| 576 return ROLE_SYSTEM_COLUMN; |
| 577 case WebAccessibility::ROLE_ROW : |
| 578 return ROLE_SYSTEM_ROW; |
| 579 case WebAccessibility::ROLE_GROUPING : |
| 580 return ROLE_SYSTEM_GROUPING; |
| 581 case WebAccessibility::ROLE_LIST : |
| 582 return ROLE_SYSTEM_LIST; |
| 583 case WebAccessibility::ROLE_TABLE : |
| 584 return ROLE_SYSTEM_TABLE; |
| 585 case WebAccessibility::ROLE_LINK : |
| 586 return ROLE_SYSTEM_LINK; |
| 587 case WebAccessibility::ROLE_GRAPHIC : |
| 588 return ROLE_SYSTEM_GRAPHIC; |
| 589 case WebAccessibility::ROLE_CLIENT : |
| 590 default: |
| 591 // This is the default role for MSAA. |
| 592 return ROLE_SYSTEM_CLIENT; |
| 593 } |
| 594 } |
| 595 |
| 596 long BrowserAccessibility::MSAAState(long browser_accessibility_state) { |
| 597 long state = 0; |
| 598 |
| 599 if ((browser_accessibility_state >> WebAccessibility::STATE_LINKED) & 1) |
| 600 state |= STATE_SYSTEM_LINKED; |
| 601 |
| 602 if ((browser_accessibility_state >> WebAccessibility::STATE_HOTTRACKED) & 1) |
| 603 state |= STATE_SYSTEM_HOTTRACKED; |
| 604 |
| 605 if ((browser_accessibility_state >> WebAccessibility::STATE_UNAVAILABLE) & 1) |
| 606 state |= STATE_SYSTEM_UNAVAILABLE; |
| 607 |
| 608 if ((browser_accessibility_state >> WebAccessibility::STATE_READONLY) & 1) |
| 609 state |= STATE_SYSTEM_READONLY; |
| 610 |
| 611 if ((browser_accessibility_state >> WebAccessibility::STATE_OFFSCREEN) & 1) |
| 612 state |= STATE_SYSTEM_OFFSCREEN; |
| 613 |
| 614 if ((browser_accessibility_state >> |
| 615 WebAccessibility::STATE_MULTISELECTABLE) & 1) { |
| 616 state |= STATE_SYSTEM_MULTISELECTABLE; |
| 617 } |
| 618 |
| 619 if ((browser_accessibility_state >> WebAccessibility::STATE_PROTECTED) & 1) |
| 620 state |= STATE_SYSTEM_PROTECTED; |
| 621 |
| 622 if ((browser_accessibility_state >> |
| 623 WebAccessibility::STATE_INDETERMINATE) & 1) { |
| 624 state |= STATE_SYSTEM_INDETERMINATE; |
| 625 } |
| 626 |
| 627 if ((browser_accessibility_state >> WebAccessibility::STATE_CHECKED) & 1) |
| 628 state |= STATE_SYSTEM_CHECKED; |
| 629 |
| 630 if ((browser_accessibility_state >> WebAccessibility::STATE_PRESSED) & 1) |
| 631 state |= STATE_SYSTEM_PRESSED; |
| 632 |
| 633 if ((browser_accessibility_state >> WebAccessibility::STATE_FOCUSED) & 1) |
| 634 state |= STATE_SYSTEM_FOCUSED; |
| 635 |
| 636 if ((browser_accessibility_state >> WebAccessibility::STATE_TRAVERSED) & 1) |
| 637 state |= STATE_SYSTEM_TRAVERSED; |
| 638 |
| 639 if ((browser_accessibility_state >> WebAccessibility::STATE_FOCUSABLE) & 1) |
| 640 state |= STATE_SYSTEM_FOCUSABLE; |
| 641 |
| 642 return state; |
| 643 } |
| OLD | NEW |