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 #include <cppuhelper/bootstrap.hxx>
23 #include <com/sun/star/bridge/XUnoUrlResolver.hpp>
24 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
25 #include <vcl/window.hxx>
26 #include <toolkit/awt/Vclxwindow.hxx>
27
28 #ifndef _SV_SYSDATA_HXX
29 #if defined( WIN ) || defined( WNT ) || defined( OS2 )
30 typedef sal_Int32 HWND;
31 typedef sal_Int32 HMENU;
32 typedef sal_Int32 HDC;
33 typedef void *PVOID;
34 typedef PVOID HANDLE;
35 typedef HANDLE HFONT;
36 #endif
37 #include <vcl/sysdata.hxx>
38 #endif
39
40 #include "AccTopWindowListener.hxx"
41 #include "unomsaaevent.hxx"
42
43 #include <com/sun/star/awt/XExtendedToolkit.hpp>
44 #include <com/sun/star/uno/XInterface.hpp>
45 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
46 #include <com/sun/star/accessibility/XAccessibleEventListener.hpp>
47 #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
48 #include <com/sun/star/accessibility/AccessibleRole.hpp>
49 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
50
51 using namespace com::sun::star::uno;
52 using namespace com::sun::star::lang;
53 using namespace com::sun::star::bridge;
54 using namespace com::sun::star::awt;
55 using namespace rtl;
56 using namespace cppu;
57 //////////////////////////////////////////////////////////////////////
58 // Construction/Destruction
59 //////////////////////////////////////////////////////////////////////
60
61 AccTopWindowListener* g_pTop = NULL;
62 //when proccess exit, call FreeTopWindowListener() in svmain
FreeTopWindowListener()63 void FreeTopWindowListener()
64 {
65 if( g_pTop )
66 {
67 g_pTop->release();
68 g_pTop = NULL;
69 }
70 }
71
72 /**
73 * As a global method to invoke the handleWindowOpened() method
74 */
handleWindowOpened_impl(long pAcc)75 void handleWindowOpened_impl(long pAcc)
76 {
77 if( g_pTop && pAcc != NULL )
78 g_pTop->handleWindowOpened( (com::sun::star::accessibility::XAccessible*)((void*)pAcc) );
79 }
80
81 /**
82 * For the new opened window, generate all the UNO accessible's object, COM object and add
83 * accessible listener to monitor all these objects.
84 * @param pAccessible the accessible of the new opened window
85 */
handleWindowOpened(com::sun::star::accessibility::XAccessible * pAccessible)86 void AccTopWindowListener::handleWindowOpened( com::sun::star::accessibility::XAccessible* pAccessible )
87 {
88 //get SystemData from window
89 VCLXWindow* pvclwindow = (VCLXWindow*)pAccessible;
90 Window* window = pvclwindow->GetWindow();
91 // The SalFrame of window may be destructed at this time
92 const SystemEnvData* systemdata = NULL;
93 try
94 {
95 systemdata = window->GetSystemData();
96 }
97 catch(...)
98 {
99 systemdata = NULL;
100 }
101 Reference<com::sun::star::accessibility::XAccessibleContext> xContext(pAccessible->getAccessibleContext(),UNO_QUERY);
102 if(!xContext.is())
103 {
104 return;
105 }
106 com::sun::star::accessibility::XAccessibleContext* pAccessibleContext = xContext.get();
107 //Only AccessibleContext exist, add all listeners
108 if(pAccessibleContext != NULL && systemdata != NULL)
109 {
110 accManagerAgent.SaveTopWindowHandle((HWND)systemdata->hWnd, pAccessible);
111
112 AddAllListeners(pAccessible,NULL,(HWND)systemdata->hWnd);
113
114 if( window->GetStyle() & WB_MOVEABLE )
115 accManagerAgent.IncreaseState( pAccessible, -1 /* U_MOVEBLE */ );
116
117 short role = pAccessibleContext->getAccessibleRole();
118
119
120 if (role == com::sun::star::accessibility::AccessibleRole::POPUP_MENU ||
121 role == com::sun::star::accessibility::AccessibleRole::MENU )
122 {
123 accManagerAgent.NotifyAccEvent(UM_EVENT_MENUPOPUPSTART, pAccessible);
124 }
125
126 if (role == com::sun::star::accessibility::AccessibleRole::FRAME ||
127 role == com::sun::star::accessibility::AccessibleRole::DIALOG ||
128 role == com::sun::star::accessibility::AccessibleRole::WINDOW ||
129 role == com::sun::star::accessibility::AccessibleRole::ALERT)
130 {
131 accManagerAgent.NotifyAccEvent(UM_EVENT_SHOW, pAccessible);
132 }
133 }
134 }
135
AccTopWindowListener()136 AccTopWindowListener::AccTopWindowListener():
137 accManagerAgent(),
138 m_refcount(1)
139 {
140 }
141
~AccTopWindowListener()142 AccTopWindowListener::~AccTopWindowListener()
143 {
144 }
145
146 /**
147 * It is invoked when a new window is opened, the source of this EventObject is the window
148 */
windowOpened(const::com::sun::star::lang::EventObject & e)149 void AccTopWindowListener::windowOpened( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException)
150 {
151 if ( !e.Source.is())
152 {
153 return;
154 }
155
156 Reference< com::sun::star::accessibility::XAccessible > xAccessible ( e.Source, UNO_QUERY );
157 com::sun::star::accessibility::XAccessible* pAccessible = xAccessible.get();
158 if ( pAccessible == NULL)
159 {
160 return;
161 }
162
163 handleWindowOpened(pAccessible);
164
165 }
166
167 /**
168 * Add the accessible event listener to object and all its children objects.
169 * @param pAccessible the accessible object
170 * @param pParentXAcc the parent of current accessible object
171 * @param pWND the handle of top window which current object resides
172 */
AddAllListeners(com::sun::star::accessibility::XAccessible * pAccessible,com::sun::star::accessibility::XAccessible * pParentXAcc,HWND pWND)173 void AccTopWindowListener::AddAllListeners(com::sun::star::accessibility::XAccessible* pAccessible, com::sun::star::accessibility::XAccessible* pParentXAcc, HWND pWND)
174 {
175 Reference<com::sun::star::accessibility::XAccessibleContext> xContext(pAccessible->getAccessibleContext(),UNO_QUERY);
176 if(!xContext.is())
177 {
178 return;
179 }
180 com::sun::star::accessibility::XAccessibleContext* pAccessibleContext = xContext.get();
181 if(pAccessibleContext == NULL)
182 {
183 return;
184 }
185
186 accManagerAgent.InsertAccObj( pAccessible, pParentXAcc,pWND );
187
188 if (!accManagerAgent.IsContainer(pAccessible))
189 {
190 return;
191 }
192
193
194 short role = pAccessibleContext->getAccessibleRole();
195 if(com::sun::star::accessibility::AccessibleRole::DOCUMENT == role )
196 {
197 if(accManagerAgent.IsStateManageDescendant(pAccessible))
198 {
199 return ;
200 }
201 }
202
203
204 int count = pAccessibleContext->getAccessibleChildCount();
205 for (int i=0;i<count;i++)
206 {
207 Reference<com::sun::star::accessibility::XAccessible> mxAccessible
208 = pAccessibleContext->getAccessibleChild(i);
209
210 com::sun::star::accessibility::XAccessible* mpAccessible = mxAccessible.get();
211 if(mpAccessible != NULL)
212 {
213 Reference<com::sun::star::accessibility::XAccessibleContext> mxAccessibleContext
214 = mpAccessible->getAccessibleContext();
215 com::sun::star::accessibility::XAccessibleContext* mpContext = mxAccessibleContext.get();
216 if(mpContext != NULL)
217 {
218 //fprintf(output, "go on add child's children event listener\n");
219 AddAllListeners(mpAccessible,pAccessible,pWND);
220 }
221 }
222 }
223 }
224
windowClosing(const::com::sun::star::lang::EventObject & e)225 void AccTopWindowListener::windowClosing( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException)
226 {
227 }
228
229 /**
230 * Invoke this method when the top window is closed, remove all the objects and its children
231 * from current manager's cache, and remove the COM object and the accessible event listener
232 * assigned to the accessible objects.
233 */
windowClosed(const::com::sun::star::lang::EventObject & e)234 void AccTopWindowListener::windowClosed( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException)
235 {
236 if ( !e.Source.is())
237 {
238 return;
239 }
240 Reference< com::sun::star::accessibility::XAccessible > xAccessible ( e.Source, UNO_QUERY );
241 com::sun::star::accessibility::XAccessible* pAccessible = xAccessible.get();
242 if ( pAccessible == NULL)
243 {
244 return;
245 }
246
247
248 VCLXWindow* pvclwindow = (VCLXWindow*)pAccessible;
249 Window* window = pvclwindow->GetWindow();
250 const SystemEnvData* systemdata=window->GetSystemData();
251
252 Reference<com::sun::star::accessibility::XAccessibleContext> xContext(pAccessible->getAccessibleContext(),UNO_QUERY);
253 if(!xContext.is())
254 {
255 return;
256 }
257 com::sun::star::accessibility::XAccessibleContext* pAccessibleContext = xContext.get();
258
259 short role = -1;
260 if(pAccessibleContext != NULL)
261 {
262 role = pAccessibleContext->getAccessibleRole();
263
264 if (role == com::sun::star::accessibility::AccessibleRole::POPUP_MENU ||
265 role == com::sun::star::accessibility::AccessibleRole::MENU)
266 {
267 accManagerAgent.NotifyAccEvent(UM_EVENT_MENUPOPUPEND, pAccessible);
268 }
269 }
270
271
272 accManagerAgent.DeleteChildrenAccObj( pAccessible );
273 if( role != com::sun::star::accessibility::AccessibleRole::POPUP_MENU )
274 accManagerAgent.DeleteAccObj( pAccessible );
275
276 }
277
windowMinimized(const::com::sun::star::lang::EventObject &)278 void AccTopWindowListener::windowMinimized( const ::com::sun::star::lang::EventObject& ) throw (::com::sun::star::uno::RuntimeException)
279 {
280 }
281
windowNormalized(const::com::sun::star::lang::EventObject &)282 void AccTopWindowListener::windowNormalized( const ::com::sun::star::lang::EventObject& ) throw (::com::sun::star::uno::RuntimeException)
283 {
284 }
285
windowActivated(const::com::sun::star::lang::EventObject &)286 void AccTopWindowListener::windowActivated( const ::com::sun::star::lang::EventObject& ) throw (::com::sun::star::uno::RuntimeException)
287 {
288 }
289
windowDeactivated(const::com::sun::star::lang::EventObject &)290 void AccTopWindowListener::windowDeactivated( const ::com::sun::star::lang::EventObject& ) throw (::com::sun::star::uno::RuntimeException)
291 {
292 }
293
disposing(const::com::sun::star::lang::EventObject &)294 void AccTopWindowListener::disposing( const ::com::sun::star::lang::EventObject& ) throw (::com::sun::star::uno::RuntimeException)
295 {
296 }
297
298 //need to investigate further
queryInterface(const::com::sun::star::uno::Type & aType)299 ::com::sun::star::uno::Any SAL_CALL AccTopWindowListener::queryInterface( const ::com::sun::star::uno::Type& aType ) throw (::com::sun::star::uno::RuntimeException)
300 {
301 if (aType.equals( ::getCppuType( (Reference< com::sun::star::awt::XTopWindowListener> const *)0 ) ))
302 {
303 Reference< com::sun::star::awt::XTopWindowListener> xTopListener( static_cast< com::sun::star::awt::XTopWindowListener* >(this));
304 return makeAny(xTopListener);
305 }
306 return Any();
307 }
308
acquire()309 void AccTopWindowListener::acquire( ) throw ()
310 {
311 ::osl_incrementInterlockedCount( &m_refcount );
312 }
313
release()314 void AccTopWindowListener::release() throw ()
315 {
316 // thread-safe decrementation of reference count
317 if (0 == ::osl_decrementInterlockedCount( &m_refcount ))
318 {
319 delete this; // shutdown this object
320 }
321 }
322