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_svtools.hxx" 30 #include "svtaccessiblefactory.hxx" 31 #include <osl/module.h> 32 33 // #define UNLOAD_ON_LAST_CLIENT_DYING 34 // this is not recommended currently. If enabled, the implementation will log 35 // the number of active clients, and unload the acc library when the last client 36 // goes away. 37 // Sounds like a good idea, unfortunately, there's no guarantee that all objects 38 // implemented in this library are already dead. 39 // Iow, just because an object implementing an XAccessible (implemented in this lib 40 // here) died, it's not said that everybody released all references to the 41 // XAccessibleContext used by this component, and implemented in the acc lib. 42 // So we cannot really unload the lib. 43 // 44 // Alternatively, if the lib would us own "usage counting", i.e. every component 45 // implemented therein would affect a static ref count, the acc lib could care 46 // for unloading itself. 47 48 //........................................................................ 49 namespace svt 50 { 51 //........................................................................ 52 53 using namespace ::com::sun::star::uno; 54 using namespace ::com::sun::star::awt; 55 using namespace ::com::sun::star::accessibility; 56 57 namespace 58 { 59 #ifdef UNLOAD_ON_LAST_CLIENT_DYING 60 static oslInterlockedCount s_nAccessibleFactoryAccesss = 0; 61 #endif // UNLOAD_ON_LAST_CLIENT_DYING 62 static oslModule s_hAccessibleImplementationModule = NULL; 63 static GetSvtAccessibilityComponentFactory s_pAccessibleFactoryFunc = NULL; 64 static ::rtl::Reference< IAccessibleFactory > s_pFactory; 65 66 //==================================================================== 67 //= AccessibleDummyFactory 68 //==================================================================== 69 class AccessibleDummyFactory : public IAccessibleFactory 70 { 71 public: 72 AccessibleDummyFactory(); 73 74 protected: 75 virtual ~AccessibleDummyFactory(); 76 77 private: 78 AccessibleDummyFactory( const AccessibleDummyFactory& ); // never implemented 79 AccessibleDummyFactory& operator=( const AccessibleDummyFactory& ); // never implemented 80 81 oslInterlockedCount m_refCount; 82 83 public: 84 // IReference 85 virtual oslInterlockedCount SAL_CALL acquire(); 86 virtual oslInterlockedCount SAL_CALL release(); 87 88 // IAccessibleFactory 89 virtual IAccessibleTabListBox* 90 createAccessibleTabListBox( 91 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& /*rxParent*/, 92 SvHeaderTabListBox& /*rBox*/ 93 ) const 94 { 95 return NULL; 96 } 97 98 virtual IAccessibleBrowseBox* 99 createAccessibleBrowseBox( 100 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& /*_rxParent*/, 101 IAccessibleTableProvider& /*_rBrowseBox*/ 102 ) const 103 { 104 return NULL; 105 } 106 107 virtual table::IAccessibleTableControl* 108 createAccessibleTableControl( 109 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& /*_rxParent*/, 110 table::IAccessibleTable& /*_rTable*/ 111 ) const 112 { 113 return NULL; 114 } 115 116 virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > 117 createAccessibleIconChoiceCtrl( 118 SvtIconChoiceCtrl& /*_rIconCtrl*/, 119 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& /*_xParent*/ 120 ) const 121 { 122 return NULL; 123 } 124 125 virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > 126 createAccessibleTabBar( 127 TabBar& /*_rTabBar*/ 128 ) const 129 { 130 return NULL; 131 } 132 133 virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > 134 createAccessibleTextWindowContext( 135 VCLXWindow* /*pVclXWindow*/, TextEngine& /*rEngine*/, TextView& /*rView*/, bool /*bCompoundControlChild*/ 136 ) const 137 { 138 return NULL; 139 } 140 141 virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > 142 createAccessibleTreeListBox( 143 SvTreeListBox& /*_rListBox*/, 144 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& /*_xParent*/ 145 ) const 146 { 147 return NULL; 148 } 149 150 virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > 151 createAccessibleBrowseBoxHeaderBar( 152 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& /*rxParent*/, 153 IAccessibleTableProvider& /*_rOwningTable*/, 154 AccessibleBrowseBoxObjType /*_eObjType*/ 155 ) const 156 { 157 return NULL; 158 } 159 160 virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > 161 createAccessibleBrowseBoxTableCell( 162 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& /*_rxParent*/, 163 IAccessibleTableProvider& /*_rBrowseBox*/, 164 const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& /*_xFocusWindow*/, 165 sal_Int32 /*_nRowId*/, 166 sal_uInt16 /*_nColId*/, 167 sal_Int32 /*_nOffset*/ 168 ) const 169 { 170 return NULL; 171 } 172 173 virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > 174 createAccessibleBrowseBoxHeaderCell( 175 sal_Int32 /*_nColumnRowId*/, 176 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& /*rxParent*/, 177 IAccessibleTableProvider& /*_rBrowseBox*/, 178 const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& /*_xFocusWindow*/, 179 AccessibleBrowseBoxObjType /*_eObjType*/ 180 ) const 181 { 182 return NULL; 183 } 184 185 virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > 186 createAccessibleCheckBoxCell( 187 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& /*_rxParent*/, 188 IAccessibleTableProvider& /*_rBrowseBox*/, 189 const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& /*_xFocusWindow*/, 190 sal_Int32 /*_nRowPos*/, 191 sal_uInt16 /*_nColPos*/, 192 const TriState& /*_eState*/, 193 sal_Bool /*_bEnabled*/, 194 sal_Bool /*_bIsTriState*/ 195 ) const 196 { 197 return NULL; 198 } 199 200 virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > 201 createEditBrowseBoxTableCellAccess( 202 const ::com::sun::star::uno::Reference< com::sun::star::accessibility::XAccessible >& /*_rxParent*/, 203 const ::com::sun::star::uno::Reference< com::sun::star::accessibility::XAccessible >& /*_rxControlAccessible*/, 204 const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& /*_rxFocusWindow*/, 205 IAccessibleTableProvider& /*_rBrowseBox*/, 206 sal_Int32 /*_nRowPos*/, 207 sal_uInt16 /*_nColPos*/ 208 ) const 209 { 210 return NULL; 211 } 212 213 virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > 214 createAccessibleToolPanelDeck( 215 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& /*i_rAccessibleParent*/, 216 ::svt::ToolPanelDeck& /*i_rPanelDeck*/ 217 ) 218 { 219 return NULL; 220 } 221 virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > 222 createAccessibleToolPanelTabBar( 223 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& /*i_rAccessibleParent*/, 224 ::svt::IToolPanelDeck& /*i_rPanelDeck*/, 225 ::svt::PanelTabBar& /*i_rTabBar*/ 226 ) 227 { 228 return NULL; 229 } 230 }; 231 232 //---------------------------------------------------------------- 233 AccessibleDummyFactory::AccessibleDummyFactory() 234 { 235 } 236 237 //---------------------------------------------------------------- 238 AccessibleDummyFactory::~AccessibleDummyFactory() 239 { 240 } 241 242 //---------------------------------------------------------------- 243 oslInterlockedCount SAL_CALL AccessibleDummyFactory::acquire() 244 { 245 return osl_incrementInterlockedCount( &m_refCount ); 246 } 247 248 //---------------------------------------------------------------- 249 oslInterlockedCount SAL_CALL AccessibleDummyFactory::release() 250 { 251 if ( 0 == osl_decrementInterlockedCount( &m_refCount ) ) 252 { 253 delete this; 254 return 0; 255 } 256 return m_refCount; 257 } 258 } 259 260 //==================================================================== 261 //= AccessibleFactoryAccess 262 //==================================================================== 263 //-------------------------------------------------------------------- 264 AccessibleFactoryAccess::AccessibleFactoryAccess() 265 :m_bInitialized( false ) 266 { 267 } 268 269 //-------------------------------------------------------------------- 270 extern "C" { static void SAL_CALL thisModule() {} } 271 272 void AccessibleFactoryAccess::ensureInitialized() 273 { 274 if ( m_bInitialized ) 275 return; 276 277 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 278 279 #ifdef UNLOAD_ON_LAST_CLIENT_DYING 280 if ( 1 == osl_incrementInterlockedCount( &s_nAccessibleFactoryAccesss ) ) 281 { // the first client 282 #endif // UNLOAD_ON_LAST_CLIENT_DYING 283 // load the library implementing the factory 284 if ( !s_pFactory.get() ) 285 { 286 const ::rtl::OUString sModuleName = ::rtl::OUString::createFromAscii( 287 SVLIBRARY( "acc" ) 288 ); 289 s_hAccessibleImplementationModule = osl_loadModuleRelative( &thisModule, sModuleName.pData, 0 ); 290 if ( s_hAccessibleImplementationModule != NULL ) 291 { 292 const ::rtl::OUString sFactoryCreationFunc = 293 ::rtl::OUString::createFromAscii( "getSvtAccessibilityComponentFactory" ); 294 s_pAccessibleFactoryFunc = (GetSvtAccessibilityComponentFactory) 295 osl_getFunctionSymbol( s_hAccessibleImplementationModule, sFactoryCreationFunc.pData ); 296 297 } 298 OSL_ENSURE( s_pAccessibleFactoryFunc, "ac_registerClient: could not load the library, or not retrieve the needed symbol!" ); 299 300 // get a factory instance 301 if ( s_pAccessibleFactoryFunc ) 302 { 303 IAccessibleFactory* pFactory = static_cast< IAccessibleFactory* >( (*s_pAccessibleFactoryFunc)() ); 304 if ( pFactory ) 305 { 306 s_pFactory = pFactory; 307 pFactory->release(); 308 } 309 } 310 } 311 312 if ( !s_pFactory.get() ) 313 // the attempt to load the lib, or to create the factory, failed 314 // -> fall back to a dummy factory 315 s_pFactory = new AccessibleDummyFactory; 316 #ifdef UNLOAD_ON_LAST_CLIENT_DYING 317 } 318 #endif 319 320 m_bInitialized = true; 321 } 322 323 //-------------------------------------------------------------------- 324 AccessibleFactoryAccess::~AccessibleFactoryAccess() 325 { 326 if ( m_bInitialized ) 327 { 328 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 329 330 #ifdef UNLOAD_ON_LAST_CLIENT_DYING 331 if( 0 == osl_decrementInterlockedCount( &s_nAccessibleFactoryAccesss ) ) 332 { 333 s_pFactory = NULL; 334 s_pAccessibleFactoryFunc = NULL; 335 if ( s_hAccessibleImplementationModule ) 336 { 337 osl_unloadModule( s_hAccessibleImplementationModule ); 338 s_hAccessibleImplementationModule = NULL; 339 } 340 } 341 #endif // UNLOAD_ON_LAST_CLIENT_DYING 342 } 343 } 344 345 //-------------------------------------------------------------------- 346 IAccessibleFactory& AccessibleFactoryAccess::getFactory() 347 { 348 ensureInitialized(); 349 DBG_ASSERT( s_pFactory.is(), "AccessibleFactoryAccess::getFactory: at least a dummy factory should have been created!" ); 350 return *s_pFactory; 351 } 352 353 //........................................................................ 354 } // namespace svt 355 //........................................................................ 356