1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "svtaccessiblefactory.hxx"
21 #include <osl/module.h>
23 // #define UNLOAD_ON_LAST_CLIENT_DYING
24 // this is not recommended currently. If enabled, the implementation will log
25 // the number of active clients, and unload the acc library when the last client
27 // Sounds like a good idea, unfortunately, there's no guarantee that all objects
28 // implemented in this library are already dead.
29 // Iow, just because an object implementing an XAccessible (implemented in this lib
30 // here) died, it's not said that everybody released all references to the
31 // XAccessibleContext used by this component, and implemented in the acc lib.
32 // So we cannot really unload the lib.
34 // Alternatively, if the lib would us own "usage counting", i.e. every component
35 // implemented therein would affect a static ref count, the acc lib could care
36 // for unloading itself.
38 //........................................................................
41 //........................................................................
43 using namespace ::com::sun::star::uno
;
44 using namespace ::com::sun::star::awt
;
45 using namespace ::com::sun::star::accessibility
;
49 #ifdef UNLOAD_ON_LAST_CLIENT_DYING
50 static oslInterlockedCount s_nAccessibleFactoryAccesss
= 0;
51 #endif // UNLOAD_ON_LAST_CLIENT_DYING
52 #ifndef DISABLE_DYNLOADING
53 static oslModule s_hAccessibleImplementationModule
= NULL
;
55 static GetSvtAccessibilityComponentFactory s_pAccessibleFactoryFunc
= NULL
;
56 static ::rtl::Reference
< IAccessibleFactory
> s_pFactory
;
58 //====================================================================
59 //= AccessibleDummyFactory
60 //====================================================================
61 class AccessibleDummyFactory
: public IAccessibleFactory
64 AccessibleDummyFactory();
67 virtual ~AccessibleDummyFactory();
70 AccessibleDummyFactory( const AccessibleDummyFactory
& ); // never implemented
71 AccessibleDummyFactory
& operator=( const AccessibleDummyFactory
& ); // never implemented
73 oslInterlockedCount m_refCount
;
77 virtual oslInterlockedCount SAL_CALL
acquire();
78 virtual oslInterlockedCount SAL_CALL
release();
81 virtual IAccessibleTabListBox
*
82 createAccessibleTabListBox(
83 const ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>& /*rxParent*/,
84 SvHeaderTabListBox
& /*rBox*/
90 virtual IAccessibleBrowseBox
*
91 createAccessibleBrowseBox(
92 const ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>& /*_rxParent*/,
93 IAccessibleTableProvider
& /*_rBrowseBox*/
99 virtual table::IAccessibleTableControl
*
100 createAccessibleTableControl(
101 const ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>& /*_rxParent*/,
102 table::IAccessibleTable
& /*_rTable*/
108 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>
109 createAccessibleIconChoiceCtrl(
110 SvtIconChoiceCtrl
& /*_rIconCtrl*/,
111 const ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>& /*_xParent*/
117 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>
118 createAccessibleTabBar(
125 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessibleContext
>
126 createAccessibleTextWindowContext(
127 VCLXWindow
* /*pVclXWindow*/, TextEngine
& /*rEngine*/, TextView
& /*rView*/, bool /*bCompoundControlChild*/
133 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>
134 createAccessibleTreeListBox(
135 SvTreeListBox
& /*_rListBox*/,
136 const ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>& /*_xParent*/
142 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>
143 createAccessibleBrowseBoxHeaderBar(
144 const ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>& /*rxParent*/,
145 IAccessibleTableProvider
& /*_rOwningTable*/,
146 AccessibleBrowseBoxObjType
/*_eObjType*/
152 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>
153 createAccessibleBrowseBoxTableCell(
154 const ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>& /*_rxParent*/,
155 IAccessibleTableProvider
& /*_rBrowseBox*/,
156 const ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XWindow
>& /*_xFocusWindow*/,
157 sal_Int32
/*_nRowId*/,
158 sal_uInt16
/*_nColId*/,
159 sal_Int32
/*_nOffset*/
165 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>
166 createAccessibleBrowseBoxHeaderCell(
167 sal_Int32
/*_nColumnRowId*/,
168 const ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>& /*rxParent*/,
169 IAccessibleTableProvider
& /*_rBrowseBox*/,
170 const ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XWindow
>& /*_xFocusWindow*/,
171 AccessibleBrowseBoxObjType
/*_eObjType*/
177 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>
178 createAccessibleCheckBoxCell(
179 const ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>& /*_rxParent*/,
180 IAccessibleTableProvider
& /*_rBrowseBox*/,
181 const ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XWindow
>& /*_xFocusWindow*/,
182 sal_Int32
/*_nRowPos*/,
183 sal_uInt16
/*_nColPos*/,
184 const TriState
& /*_eState*/,
185 sal_Bool
/*_bIsTriState*/
191 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>
192 createEditBrowseBoxTableCellAccess(
193 const ::com::sun::star::uno::Reference
< com::sun::star::accessibility::XAccessible
>& /*_rxParent*/,
194 const ::com::sun::star::uno::Reference
< com::sun::star::accessibility::XAccessible
>& /*_rxControlAccessible*/,
195 const ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XWindow
>& /*_rxFocusWindow*/,
196 IAccessibleTableProvider
& /*_rBrowseBox*/,
197 sal_Int32
/*_nRowPos*/,
198 sal_uInt16
/*_nColPos*/
204 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessibleContext
>
205 createAccessibleToolPanelDeck(
206 const ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>& /*i_rAccessibleParent*/,
207 ::svt::ToolPanelDeck
& /*i_rPanelDeck*/
212 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessibleContext
>
213 createAccessibleToolPanelTabBar(
214 const ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>& /*i_rAccessibleParent*/,
215 ::svt::IToolPanelDeck
& /*i_rPanelDeck*/,
216 ::svt::PanelTabBar
& /*i_rTabBar*/
223 //----------------------------------------------------------------
224 AccessibleDummyFactory::AccessibleDummyFactory()
228 //----------------------------------------------------------------
229 AccessibleDummyFactory::~AccessibleDummyFactory()
233 //----------------------------------------------------------------
234 oslInterlockedCount SAL_CALL
AccessibleDummyFactory::acquire()
236 return osl_atomic_increment( &m_refCount
);
239 //----------------------------------------------------------------
240 oslInterlockedCount SAL_CALL
AccessibleDummyFactory::release()
242 if ( 0 == osl_atomic_decrement( &m_refCount
) )
251 //====================================================================
252 //= AccessibleFactoryAccess
253 //====================================================================
254 //--------------------------------------------------------------------
255 AccessibleFactoryAccess::AccessibleFactoryAccess()
256 :m_bInitialized( false )
260 //--------------------------------------------------------------------
261 #ifndef DISABLE_DYNLOADING
262 extern "C" { static void SAL_CALL
thisModule() {} }
264 extern "C" void* getSvtAccessibilityComponentFactory();
267 void AccessibleFactoryAccess::ensureInitialized()
269 if ( m_bInitialized
)
272 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
274 #ifdef UNLOAD_ON_LAST_CLIENT_DYING
275 if ( 1 == osl_atomic_increment( &s_nAccessibleFactoryAccesss
) )
276 { // the first client
277 #endif // UNLOAD_ON_LAST_CLIENT_DYING
278 // load the library implementing the factory
279 if ( !s_pFactory
.get() )
281 #ifndef DISABLE_DYNLOADING
282 const OUString
sModuleName( SVLIBRARY( "acc" ));
283 s_hAccessibleImplementationModule
= osl_loadModuleRelative( &thisModule
, sModuleName
.pData
, 0 );
284 if ( s_hAccessibleImplementationModule
!= NULL
)
286 const OUString
sFactoryCreationFunc( "getSvtAccessibilityComponentFactory" );
287 s_pAccessibleFactoryFunc
= (GetSvtAccessibilityComponentFactory
)
288 osl_getFunctionSymbol( s_hAccessibleImplementationModule
, sFactoryCreationFunc
.pData
);
291 OSL_ENSURE( s_pAccessibleFactoryFunc
, "ac_registerClient: could not load the library, or not retrieve the needed symbol!" );
293 s_pAccessibleFactoryFunc
= getSvtAccessibilityComponentFactory
;
295 // get a factory instance
296 if ( s_pAccessibleFactoryFunc
)
298 IAccessibleFactory
* pFactory
= static_cast< IAccessibleFactory
* >( (*s_pAccessibleFactoryFunc
)() );
301 s_pFactory
= pFactory
;
307 if ( !s_pFactory
.get() )
308 // the attempt to load the lib, or to create the factory, failed
309 // -> fall back to a dummy factory
310 s_pFactory
= new AccessibleDummyFactory
;
311 #ifdef UNLOAD_ON_LAST_CLIENT_DYING
315 m_bInitialized
= true;
318 //--------------------------------------------------------------------
319 AccessibleFactoryAccess::~AccessibleFactoryAccess()
321 if ( m_bInitialized
)
323 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
325 #ifdef UNLOAD_ON_LAST_CLIENT_DYING
326 if( 0 == osl_atomic_decrement( &s_nAccessibleFactoryAccesss
) )
329 s_pAccessibleFactoryFunc
= NULL
;
330 if ( s_hAccessibleImplementationModule
)
332 osl_unloadModule( s_hAccessibleImplementationModule
);
333 s_hAccessibleImplementationModule
= NULL
;
336 #endif // UNLOAD_ON_LAST_CLIENT_DYING
340 //--------------------------------------------------------------------
341 IAccessibleFactory
& AccessibleFactoryAccess::getFactory()
344 DBG_ASSERT( s_pFactory
.is(), "AccessibleFactoryAccess::getFactory: at least a dummy factory should have been created!" );
348 //........................................................................
350 //........................................................................
352 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */