1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: svtaccessiblefactory.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
33 #include "svtaccessiblefactory.hxx"
34 #include <osl/module.h>
36 // #define UNLOAD_ON_LAST_CLIENT_DYING
37 // this is not recommended currently. If enabled, the implementation will log
38 // the number of active clients, and unload the acc library when the last client
40 // Sounds like a good idea, unfortunately, there's no guarantee that all objects
41 // implemented in this library are already dead.
42 // Iow, just because an object implementing an XAccessible (implemented in this lib
43 // here) died, it's not said that everybody released all references to the
44 // XAccessibleContext used by this component, and implemented in the acc lib.
45 // So we cannot really unload the lib.
47 // Alternatively, if the lib would us own "usage counting", i.e. every component
48 // implemented therein would affect a static ref count, the acc lib could care
49 // for unloading itself.
51 //........................................................................
54 //........................................................................
56 using namespace ::com::sun::star::uno
;
57 using namespace ::com::sun::star::awt
;
58 using namespace ::com::sun::star::accessibility
;
62 #ifdef UNLOAD_ON_LAST_CLIENT_DYING
63 static oslInterlockedCount s_nAccessibleFactoryAccesss
= 0;
64 #endif // UNLOAD_ON_LAST_CLIENT_DYING
65 static oslModule s_hAccessibleImplementationModule
= NULL
;
66 static GetSvtAccessibilityComponentFactory s_pAccessibleFactoryFunc
= NULL
;
67 static ::rtl::Reference
< IAccessibleFactory
> s_pFactory
;
69 //====================================================================
70 //= AccessibleDummyFactory
71 //====================================================================
72 class AccessibleDummyFactory
: public IAccessibleFactory
75 AccessibleDummyFactory();
78 virtual ~AccessibleDummyFactory();
81 AccessibleDummyFactory( const AccessibleDummyFactory
& ); // never implemented
82 AccessibleDummyFactory
& operator=( const AccessibleDummyFactory
& ); // never implemented
84 oslInterlockedCount m_refCount
;
88 virtual oslInterlockedCount SAL_CALL
acquire();
89 virtual oslInterlockedCount SAL_CALL
release();
92 virtual IAccessibleTabListBox
*
93 createAccessibleTabListBox(
94 const ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>& /*rxParent*/,
95 SvHeaderTabListBox
& /*rBox*/
101 virtual IAccessibleBrowseBox
*
102 createAccessibleBrowseBox(
103 const ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>& /*_rxParent*/,
104 IAccessibleTableProvider
& /*_rBrowseBox*/
110 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>
111 createAccessibleIconChoiceCtrl(
112 SvtIconChoiceCtrl
& /*_rIconCtrl*/,
113 const ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>& /*_xParent*/
119 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>
120 createAccessibleTabBar(
127 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessibleContext
>
128 createAccessibleTextWindowContext(
129 VCLXWindow
* /*pVclXWindow*/, TextEngine
& /*rEngine*/, TextView
& /*rView*/, bool /*bCompoundControlChild*/
135 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>
136 createAccessibleTreeListBox(
137 SvTreeListBox
& /*_rListBox*/,
138 const ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>& /*_xParent*/
144 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>
145 createAccessibleBrowseBoxHeaderBar(
146 const ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>& /*rxParent*/,
147 IAccessibleTableProvider
& /*_rOwningTable*/,
148 AccessibleBrowseBoxObjType
/*_eObjType*/
154 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>
155 createAccessibleBrowseBoxTableCell(
156 const ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>& /*_rxParent*/,
157 IAccessibleTableProvider
& /*_rBrowseBox*/,
158 const ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XWindow
>& /*_xFocusWindow*/,
159 sal_Int32
/*_nRowId*/,
160 sal_uInt16
/*_nColId*/,
161 sal_Int32
/*_nOffset*/
167 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>
168 createAccessibleBrowseBoxHeaderCell(
169 sal_Int32
/*_nColumnRowId*/,
170 const ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>& /*rxParent*/,
171 IAccessibleTableProvider
& /*_rBrowseBox*/,
172 const ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XWindow
>& /*_xFocusWindow*/,
173 AccessibleBrowseBoxObjType
/*_eObjType*/
179 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>
180 createAccessibleCheckBoxCell(
181 const ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>& /*_rxParent*/,
182 IAccessibleTableProvider
& /*_rBrowseBox*/,
183 const ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XWindow
>& /*_xFocusWindow*/,
184 sal_Int32
/*_nRowPos*/,
185 sal_uInt16
/*_nColPos*/,
186 const TriState
& /*_eState*/,
187 sal_Bool
/*_bEnabled*/,
188 sal_Bool
/*_bIsTriState*/
194 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>
195 createEditBrowseBoxTableCellAccess(
196 const ::com::sun::star::uno::Reference
< com::sun::star::accessibility::XAccessible
>& /*_rxParent*/,
197 const ::com::sun::star::uno::Reference
< com::sun::star::accessibility::XAccessible
>& /*_rxControlAccessible*/,
198 const ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XWindow
>& /*_rxFocusWindow*/,
199 IAccessibleTableProvider
& /*_rBrowseBox*/,
200 sal_Int32
/*_nRowPos*/,
201 sal_uInt16
/*_nColPos*/
208 //----------------------------------------------------------------
209 AccessibleDummyFactory::AccessibleDummyFactory()
213 //----------------------------------------------------------------
214 AccessibleDummyFactory::~AccessibleDummyFactory()
218 //----------------------------------------------------------------
219 oslInterlockedCount SAL_CALL
AccessibleDummyFactory::acquire()
221 return osl_incrementInterlockedCount( &m_refCount
);
224 //----------------------------------------------------------------
225 oslInterlockedCount SAL_CALL
AccessibleDummyFactory::release()
227 if ( 0 == osl_decrementInterlockedCount( &m_refCount
) )
236 //====================================================================
237 //= AccessibleFactoryAccess
238 //====================================================================
239 //--------------------------------------------------------------------
240 AccessibleFactoryAccess::AccessibleFactoryAccess()
241 :m_bInitialized( false )
245 //--------------------------------------------------------------------
246 extern "C" { static void SAL_CALL
thisModule() {} }
248 void AccessibleFactoryAccess::ensureInitialized()
250 if ( m_bInitialized
)
253 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
255 #ifdef UNLOAD_ON_LAST_CLIENT_DYING
256 if ( 1 == osl_incrementInterlockedCount( &s_nAccessibleFactoryAccesss
) )
257 { // the first client
258 #endif // UNLOAD_ON_LAST_CLIENT_DYING
259 // load the library implementing the factory
260 if ( !s_pFactory
.get() )
262 const ::rtl::OUString sModuleName
= ::rtl::OUString::createFromAscii(
265 s_hAccessibleImplementationModule
= osl_loadModuleRelative( &thisModule
, sModuleName
.pData
, 0 );
266 if ( s_hAccessibleImplementationModule
!= NULL
)
268 const ::rtl::OUString sFactoryCreationFunc
=
269 ::rtl::OUString::createFromAscii( "getSvtAccessibilityComponentFactory" );
270 s_pAccessibleFactoryFunc
= (GetSvtAccessibilityComponentFactory
)
271 osl_getFunctionSymbol( s_hAccessibleImplementationModule
, sFactoryCreationFunc
.pData
);
274 OSL_ENSURE( s_pAccessibleFactoryFunc
, "ac_registerClient: could not load the library, or not retrieve the needed symbol!" );
276 // get a factory instance
277 if ( s_pAccessibleFactoryFunc
)
279 IAccessibleFactory
* pFactory
= static_cast< IAccessibleFactory
* >( (*s_pAccessibleFactoryFunc
)() );
282 s_pFactory
= pFactory
;
288 if ( !s_pFactory
.get() )
289 // the attempt to load the lib, or to create the factory, failed
290 // -> fall back to a dummy factory
291 s_pFactory
= new AccessibleDummyFactory
;
292 #ifdef UNLOAD_ON_LAST_CLIENT_DYING
296 m_bInitialized
= true;
299 //--------------------------------------------------------------------
300 AccessibleFactoryAccess::~AccessibleFactoryAccess()
302 if ( m_bInitialized
)
304 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
306 #ifdef UNLOAD_ON_LAST_CLIENT_DYING
307 if( 0 == osl_decrementInterlockedCount( &s_nAccessibleFactoryAccesss
) )
310 s_pAccessibleFactoryFunc
= NULL
;
311 if ( s_hAccessibleImplementationModule
)
313 osl_unloadModule( s_hAccessibleImplementationModule
);
314 s_hAccessibleImplementationModule
= NULL
;
317 #endif // UNLOAD_ON_LAST_CLIENT_DYING
321 //--------------------------------------------------------------------
322 IAccessibleFactory
& AccessibleFactoryAccess::getFactory()
325 DBG_ASSERT( s_pFactory
.is(), "AccessibleFactoryAccess::getFactory: at least a dummy factory should have been created!" );
329 //........................................................................
331 //........................................................................