1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_vcl.hxx" 30 31 #include "atkwrapper.hxx" 32 33 #include <com/sun/star/accessibility/XAccessibleComponent.hpp> 34 35 #ifdef ENABLE_TRACING 36 #include <stdio.h> 37 #endif 38 39 using namespace ::com::sun::star; 40 41 static accessibility::XAccessibleComponent* 42 getComponent( AtkComponent *pComponent ) throw (uno::RuntimeException) 43 { 44 AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pComponent ); 45 if( pWrap ) 46 { 47 if( !pWrap->mpComponent && pWrap->mpContext ) 48 { 49 uno::Any any = pWrap->mpContext->queryInterface( accessibility::XAccessibleComponent::static_type(NULL) ); 50 pWrap->mpComponent = reinterpret_cast< accessibility::XAccessibleComponent * > (any.pReserved); 51 pWrap->mpComponent->acquire(); 52 } 53 54 return pWrap->mpComponent; 55 } 56 57 return NULL; 58 } 59 60 /*****************************************************************************/ 61 62 static awt::Point 63 translatePoint( accessibility::XAccessibleComponent *pComponent, 64 gint x, gint y, AtkCoordType t) 65 { 66 awt::Point aOrigin( 0, 0 ); 67 if( t == ATK_XY_SCREEN ) 68 aOrigin = pComponent->getLocationOnScreen(); 69 70 #ifdef ENABLE_TRACING 71 fprintf(stderr, "coordinates ( %u, %u ) translated to: ( %u, %u )\n", 72 x, y, x - aOrigin.X, y - aOrigin.Y); 73 #endif 74 75 return awt::Point( x - aOrigin.X, y - aOrigin.Y ); 76 } 77 78 /*****************************************************************************/ 79 80 extern "C" { 81 82 static gboolean 83 component_wrapper_grab_focus (AtkComponent *component) 84 { 85 try 86 { 87 accessibility::XAccessibleComponent* pComponent = getComponent( component ); 88 if( pComponent ) 89 { 90 pComponent->grabFocus(); 91 return TRUE; 92 } 93 } 94 catch( const uno::Exception &e ) 95 { 96 g_warning( "Exception in grabFocus()" ); 97 } 98 99 return FALSE; 100 } 101 102 /*****************************************************************************/ 103 104 static gboolean 105 component_wrapper_contains (AtkComponent *component, 106 gint x, 107 gint y, 108 AtkCoordType coord_type) 109 { 110 try 111 { 112 accessibility::XAccessibleComponent* pComponent = getComponent( component ); 113 if( pComponent ) 114 return pComponent->containsPoint( translatePoint( pComponent, x, y, coord_type ) ); 115 } 116 catch( const uno::Exception &e ) 117 { 118 g_warning( "Exception in containsPoint()" ); 119 } 120 121 return FALSE; 122 } 123 124 /*****************************************************************************/ 125 126 static AtkObject * 127 component_wrapper_ref_accessible_at_point (AtkComponent *component, 128 gint x, 129 gint y, 130 AtkCoordType coord_type) 131 { 132 try 133 { 134 accessibility::XAccessibleComponent* pComponent = getComponent( component ); 135 136 if( pComponent ) 137 { 138 uno::Reference< accessibility::XAccessible > xAccessible; 139 xAccessible = pComponent->getAccessibleAtPoint( 140 translatePoint( pComponent, x, y, coord_type ) ); 141 142 #ifdef ENABLE_TRACING 143 fprintf(stderr, "getAccessibleAtPoint( %u, %u ) returned %p\n", 144 x, y, xAccessible.get()); 145 146 uno::Reference< accessibility::XAccessibleComponent > xComponent( 147 xAccessible->getAccessibleContext(), uno::UNO_QUERY ); 148 149 if( xComponent.is() ) 150 { 151 awt::Rectangle rect = xComponent->getBounds(); 152 fprintf(stderr, "%p->getBounds() returned: ( %u, %u, %u, %u )\n", 153 xAccessible.get(), rect.X, rect.Y, rect.Width, rect.Height ); 154 } 155 #endif 156 157 return atk_object_wrapper_ref( xAccessible ); 158 } 159 } 160 catch( const uno::Exception &e ) 161 { 162 g_warning( "Exception in getAccessibleAtPoint()" ); 163 } 164 165 return NULL; 166 } 167 168 /*****************************************************************************/ 169 170 static void 171 component_wrapper_get_position (AtkComponent *component, 172 gint *x, 173 gint *y, 174 AtkCoordType coord_type) 175 { 176 try 177 { 178 accessibility::XAccessibleComponent* pComponent = getComponent( component ); 179 if( pComponent ) 180 { 181 awt::Point aPos; 182 183 if( coord_type == ATK_XY_SCREEN ) 184 aPos = pComponent->getLocationOnScreen(); 185 else 186 aPos = pComponent->getLocation(); 187 188 *x = aPos.X; 189 *y = aPos.Y; 190 191 #ifdef ENABLE_TRACING 192 fprintf(stderr, "getLocation[OnScreen]() returned: ( %u, %u )\n", *x, *y ); 193 #endif 194 } 195 } 196 catch( const uno::Exception &e ) 197 { 198 g_warning( "Exception in getLocation[OnScreen]()" ); 199 } 200 } 201 202 /*****************************************************************************/ 203 204 static void 205 component_wrapper_get_size (AtkComponent *component, 206 gint *width, 207 gint *height) 208 { 209 try 210 { 211 accessibility::XAccessibleComponent* pComponent = getComponent( component ); 212 if( pComponent ) 213 { 214 awt::Size aSize = pComponent->getSize(); 215 *width = aSize.Width; 216 *height = aSize.Height; 217 218 #ifdef ENABLE_TRACING 219 fprintf(stderr, "getSize() returned: ( %u, %u )\n", *width, *height ); 220 #endif 221 } 222 } 223 catch( const uno::Exception &e ) 224 { 225 g_warning( "Exception in getSize()" ); 226 } 227 } 228 229 /*****************************************************************************/ 230 231 static void 232 component_wrapper_get_extents (AtkComponent *component, 233 gint *x, 234 gint *y, 235 gint *width, 236 gint *height, 237 AtkCoordType coord_type) 238 { 239 component_wrapper_get_position( component, x, y, coord_type ); 240 component_wrapper_get_size( component, width, height ); 241 } 242 243 /*****************************************************************************/ 244 245 static gboolean 246 component_wrapper_set_extents (AtkComponent *, gint, gint, gint, gint, AtkCoordType) 247 { 248 g_warning( "AtkComponent::set_extents unimplementable" ); 249 return FALSE; 250 } 251 252 /*****************************************************************************/ 253 254 static gboolean 255 component_wrapper_set_position (AtkComponent *, gint, gint, AtkCoordType) 256 { 257 g_warning( "AtkComponent::set_position unimplementable" ); 258 return FALSE; 259 } 260 261 /*****************************************************************************/ 262 263 static gboolean 264 component_wrapper_set_size (AtkComponent *, gint, gint) 265 { 266 g_warning( "AtkComponent::set_size unimplementable" ); 267 return FALSE; 268 } 269 270 /*****************************************************************************/ 271 272 static AtkLayer 273 component_wrapper_get_layer (AtkComponent *component) 274 { 275 AtkRole role = atk_object_get_role( ATK_OBJECT( component ) ); 276 AtkLayer layer = ATK_LAYER_WIDGET; 277 278 switch (role) 279 { 280 case ATK_ROLE_POPUP_MENU: 281 case ATK_ROLE_MENU_ITEM: 282 case ATK_ROLE_CHECK_MENU_ITEM: 283 case ATK_ROLE_SEPARATOR: 284 case ATK_ROLE_LIST_ITEM: 285 layer = ATK_LAYER_POPUP; 286 break; 287 case ATK_ROLE_MENU: 288 { 289 AtkObject * parent = atk_object_get_parent( ATK_OBJECT( component ) ); 290 if( atk_object_get_role( parent ) != ATK_ROLE_MENU_BAR ) 291 layer = ATK_LAYER_POPUP; 292 } 293 break; 294 295 case ATK_ROLE_LIST: 296 { 297 AtkObject * parent = atk_object_get_parent( ATK_OBJECT( component ) ); 298 if( atk_object_get_role( parent ) == ATK_ROLE_COMBO_BOX ) 299 layer = ATK_LAYER_POPUP; 300 } 301 break; 302 303 default: 304 ; 305 } 306 307 return layer; 308 } 309 310 /*****************************************************************************/ 311 312 static gint 313 component_wrapper_get_mdi_zorder (AtkComponent *) 314 { 315 // only needed for ATK_LAYER_MDI (not used) or ATK_LAYER_WINDOW (inherited from GAIL) 316 return G_MININT; 317 } 318 319 /*****************************************************************************/ 320 321 // This code is mostly stolen from libgail .. 322 323 static guint 324 component_wrapper_add_focus_handler (AtkComponent *component, 325 AtkFocusHandler handler) 326 { 327 GSignalMatchType match_type; 328 gulong ret; 329 guint signal_id; 330 331 match_type = (GSignalMatchType) (G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC); 332 signal_id = g_signal_lookup( "focus-event", ATK_TYPE_OBJECT ); 333 334 ret = g_signal_handler_find( component, match_type, signal_id, 0, NULL, 335 (gpointer) &handler, NULL); 336 if (!ret) 337 { 338 return g_signal_connect_closure_by_id (component, 339 signal_id, 0, 340 g_cclosure_new ( 341 G_CALLBACK (handler), NULL, 342 (GClosureNotify) NULL), 343 FALSE); 344 } 345 else 346 { 347 return 0; 348 } 349 } 350 351 /*****************************************************************************/ 352 353 static void 354 component_wrapper_remove_focus_handler (AtkComponent *component, 355 guint handler_id) 356 { 357 g_signal_handler_disconnect (component, handler_id); 358 } 359 360 /*****************************************************************************/ 361 362 } // extern "C" 363 364 void 365 componentIfaceInit (AtkComponentIface *iface) 366 { 367 g_return_if_fail (iface != NULL); 368 369 iface->add_focus_handler = component_wrapper_add_focus_handler; 370 iface->contains = component_wrapper_contains; 371 iface->get_extents = component_wrapper_get_extents; 372 iface->get_layer = component_wrapper_get_layer; 373 iface->get_mdi_zorder = component_wrapper_get_mdi_zorder; 374 iface->get_position = component_wrapper_get_position; 375 iface->get_size = component_wrapper_get_size; 376 iface->grab_focus = component_wrapper_grab_focus; 377 iface->ref_accessible_at_point = component_wrapper_ref_accessible_at_point; 378 iface->remove_focus_handler = component_wrapper_remove_focus_handler; 379 iface->set_extents = component_wrapper_set_extents; 380 iface->set_position = component_wrapper_set_position; 381 iface->set_size = component_wrapper_set_size; 382 } 383