Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <toolkit/helper/accessibilityclient.hxx>
30 : : #include <toolkit/helper/accessiblefactory.hxx>
31 : : #include <osl/module.h>
32 : : #include <osl/diagnose.h>
33 : : #include <tools/solar.h>
34 : :
35 : : // #define UNLOAD_ON_LAST_CLIENT_DYING
36 : : // this is not recommended currently. If enabled, the implementation will log
37 : : // the number of active clients, and unload the acc library when the last client
38 : : // goes away.
39 : : // Sounds like a good idea, unfortunately, there's no guarantee that all objects
40 : : // implemented in this library are already dead.
41 : : // Iow, just because an object implementing an XAccessible (implemented in this lib
42 : : // here) died, it's not said that everybody released all references to the
43 : : // XAccessibleContext used by this component, and implemented in the acc lib.
44 : : // So we cannot really unload the lib.
45 : : //
46 : : // Alternatively, if the lib would us own "usage counting", i.e. every component
47 : : // implemented therein would affect a static ref count, the acc lib could care
48 : : // for unloading itself.
49 : :
50 : : //........................................................................
51 : : namespace toolkit
52 : : {
53 : : //........................................................................
54 : :
55 : : using namespace ::com::sun::star::uno;
56 : : using namespace ::com::sun::star::accessibility;
57 : :
58 : : namespace
59 : : {
60 : : #ifdef UNLOAD_ON_LAST_CLIENT_DYING
61 : : static oslInterlockedCount s_nAccessibilityClients = 0;
62 : : #endif // UNLOAD_ON_LAST_CLIENT_DYING
63 : : static oslModule s_hAccessibleImplementationModule = NULL;
64 : : static GetStandardAccComponentFactory s_pAccessibleFactoryFunc = NULL;
65 : 347 : static ::rtl::Reference< IAccessibleFactory > s_pFactory;
66 : : }
67 : :
68 : : //====================================================================
69 : : //= AccessibleDummyFactory
70 : : //====================================================================
71 : : class AccessibleDummyFactory : public IAccessibleFactory
72 : : {
73 : : public:
74 : : AccessibleDummyFactory();
75 : :
76 : : protected:
77 : : virtual ~AccessibleDummyFactory();
78 : :
79 : : private:
80 : : AccessibleDummyFactory( const AccessibleDummyFactory& ); // never implemented
81 : : AccessibleDummyFactory& operator=( const AccessibleDummyFactory& ); // never implemented
82 : :
83 : : oslInterlockedCount m_refCount;
84 : :
85 : : public:
86 : : // IReference
87 : : virtual oslInterlockedCount SAL_CALL acquire();
88 : : virtual oslInterlockedCount SAL_CALL release();
89 : :
90 : : // IAccessibleFactory
91 : : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
92 : 0 : createAccessibleContext( VCLXButton* /*_pXWindow*/ )
93 : : {
94 : 0 : return NULL;
95 : : }
96 : : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
97 : 0 : createAccessibleContext( VCLXCheckBox* /*_pXWindow*/ )
98 : : {
99 : 0 : return NULL;
100 : : }
101 : : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
102 : 0 : createAccessibleContext( VCLXRadioButton* /*_pXWindow*/ )
103 : : {
104 : 0 : return NULL;
105 : : }
106 : : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
107 : 0 : createAccessibleContext( VCLXListBox* /*_pXWindow*/ )
108 : : {
109 : 0 : return NULL;
110 : : }
111 : : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
112 : 0 : createAccessibleContext( VCLXFixedHyperlink* /*_pXWindow*/ )
113 : : {
114 : 0 : return NULL;
115 : : }
116 : : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
117 : 0 : createAccessibleContext( VCLXFixedText* /*_pXWindow*/ )
118 : : {
119 : 0 : return NULL;
120 : : }
121 : : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
122 : 0 : createAccessibleContext( VCLXScrollBar* /*_pXWindow*/ )
123 : : {
124 : 0 : return NULL;
125 : : }
126 : : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
127 : 0 : createAccessibleContext( VCLXEdit* /*_pXWindow*/ )
128 : : {
129 : 0 : return NULL;
130 : : }
131 : : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
132 : 0 : createAccessibleContext( VCLXComboBox* /*_pXWindow*/ )
133 : : {
134 : 0 : return NULL;
135 : : }
136 : : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
137 : 0 : createAccessibleContext( VCLXToolBox* /*_pXWindow*/ )
138 : : {
139 : 0 : return NULL;
140 : : }
141 : : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
142 : 0 : createAccessibleContext( VCLXWindow* /*_pXWindow*/ )
143 : : {
144 : 0 : return NULL;
145 : : }
146 : : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
147 : 0 : createAccessible( Menu* /*_pMenu*/, sal_Bool /*_bIsMenuBar*/ )
148 : : {
149 : 0 : return NULL;
150 : : }
151 : : };
152 : :
153 : : //--------------------------------------------------------------------
154 : 0 : AccessibleDummyFactory::AccessibleDummyFactory()
155 : : {
156 : 0 : }
157 : :
158 : : //--------------------------------------------------------------------
159 : 0 : AccessibleDummyFactory::~AccessibleDummyFactory()
160 : : {
161 [ # # ]: 0 : }
162 : :
163 : : //--------------------------------------------------------------------
164 : 0 : oslInterlockedCount SAL_CALL AccessibleDummyFactory::acquire()
165 : : {
166 : 0 : return osl_incrementInterlockedCount( &m_refCount );
167 : : }
168 : :
169 : : //--------------------------------------------------------------------
170 : 0 : oslInterlockedCount SAL_CALL AccessibleDummyFactory::release()
171 : : {
172 [ # # ]: 0 : if ( 0 == osl_decrementInterlockedCount( &m_refCount ) )
173 : : {
174 [ # # ]: 0 : delete this;
175 : 0 : return 0;
176 : : }
177 : 0 : return m_refCount;
178 : : }
179 : :
180 : : //====================================================================
181 : : //= AccessibilityClient
182 : : //====================================================================
183 : : //--------------------------------------------------------------------
184 : 44244 : AccessibilityClient::AccessibilityClient()
185 : 44244 : :m_bInitialized( false )
186 : : {
187 : 44244 : }
188 : :
189 : : //--------------------------------------------------------------------
190 : 0 : extern "C" { static void SAL_CALL thisModule() {} }
191 : :
192 : 496 : void AccessibilityClient::ensureInitialized()
193 : : {
194 [ + + ]: 496 : if ( m_bInitialized )
195 : 496 : return;
196 : :
197 [ + - ][ + - ]: 461 : ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
198 : :
199 : : #ifdef UNLOAD_ON_LAST_CLIENT_DYING
200 : : if ( 1 == osl_incrementInterlockedCount( &s_nAccessibilityClients ) )
201 : : { // the first client
202 : : #endif // UNLOAD_ON_LAST_CLIENT_DYING
203 : : // load the library implementing the factory
204 [ + + ]: 461 : if ( !s_pFactory.get() )
205 : : {
206 : 20 : const ::rtl::OUString sModuleName( SVLIBRARY( "acc" ) );
207 [ + - ]: 20 : s_hAccessibleImplementationModule = osl_loadModuleRelative( &thisModule, sModuleName.pData, 0 );
208 [ + - ]: 20 : if ( s_hAccessibleImplementationModule != NULL )
209 : : {
210 : : const ::rtl::OUString sFactoryCreationFunc =
211 : 20 : ::rtl::OUString("getStandardAccessibleFactory");
212 : : s_pAccessibleFactoryFunc = (GetStandardAccComponentFactory)
213 [ + - ]: 20 : osl_getFunctionSymbol( s_hAccessibleImplementationModule, sFactoryCreationFunc.pData );
214 : :
215 : : }
216 : : OSL_ENSURE( s_pAccessibleFactoryFunc, "AccessibilityClient::ensureInitialized: could not load the library, or not retrieve the needed symbol!" );
217 : :
218 : : // get a factory instance
219 [ + - ]: 20 : if ( s_pAccessibleFactoryFunc )
220 : : {
221 [ + - ]: 20 : IAccessibleFactory* pFactory = static_cast< IAccessibleFactory* >( (*s_pAccessibleFactoryFunc)() );
222 : : OSL_ENSURE( pFactory, "AccessibilityClient::ensureInitialized: no factory provided by the A11Y lib!" );
223 [ + - ]: 20 : if ( pFactory )
224 : : {
225 [ + - ]: 20 : s_pFactory = pFactory;
226 [ + - ]: 20 : pFactory->release();
227 : : }
228 : 20 : }
229 : : }
230 : :
231 [ - + ]: 461 : if ( !s_pFactory.get() )
232 : : // the attempt to load the lib, or to create the factory, failed
233 : : // -> fall back to a dummy factory
234 [ # # ][ # # ]: 0 : s_pFactory = new AccessibleDummyFactory;
235 : : #ifdef UNLOAD_ON_LAST_CLIENT_DYING
236 : : }
237 : : #endif
238 : :
239 [ + - ]: 496 : m_bInitialized = true;
240 : : }
241 : :
242 : : //--------------------------------------------------------------------
243 : 40723 : AccessibilityClient::~AccessibilityClient()
244 : : {
245 [ + + ]: 40723 : if ( m_bInitialized )
246 : : {
247 [ + - ][ + - ]: 441 : ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
[ + - ]
248 : :
249 : : #ifdef UNLOAD_ON_LAST_CLIENT_DYING
250 : : if( 0 == osl_decrementInterlockedCount( &s_nAccessibilityClients ) )
251 : : {
252 : : s_pFactory = NULL;
253 : : s_pAccessibleFactoryFunc = NULL;
254 : : if ( s_hAccessibleImplementationModule )
255 : : {
256 : : osl_unloadModule( s_hAccessibleImplementationModule );
257 : : s_hAccessibleImplementationModule = NULL;
258 : : }
259 : : }
260 : : #endif // UNLOAD_ON_LAST_CLIENT_DYING
261 : : }
262 : 40723 : }
263 : :
264 : : //--------------------------------------------------------------------
265 : 496 : IAccessibleFactory& AccessibilityClient::getFactory()
266 : : {
267 : 496 : ensureInitialized();
268 : : OSL_ENSURE( s_pFactory.is(), "AccessibilityClient::getFactory: at least a dummy factory should have been created!" );
269 : 496 : return *s_pFactory;
270 : : }
271 : :
272 : : //........................................................................
273 [ + - ][ + - ]: 1041 : } // namespace toolkit
274 : : //........................................................................
275 : :
276 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|