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