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