xref: /aoo41x/main/vcl/unx/gtk/a11y/atkutil.cxx (revision cdf0e10c)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_vcl.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleContext.hpp>
32*cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
33*cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleSelection.hpp>
34*cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleEventId.hpp>
35*cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleStateType.hpp>
36*cdf0e10cSrcweir // --> OD 2009-04-14 #i93269#
37*cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleText.hpp>
38*cdf0e10cSrcweir // <--
39*cdf0e10cSrcweir #include <cppuhelper/implbase1.hxx>
40*cdf0e10cSrcweir #include <vos/mutex.hxx>
41*cdf0e10cSrcweir #include <rtl/ref.hxx>
42*cdf0e10cSrcweir 
43*cdf0e10cSrcweir #include <vcl/svapp.hxx>
44*cdf0e10cSrcweir #include <vcl/window.hxx>
45*cdf0e10cSrcweir #include <vcl/menu.hxx>
46*cdf0e10cSrcweir #include <vcl/toolbox.hxx>
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir #include "atkwrapper.hxx"
49*cdf0e10cSrcweir #include "atkutil.hxx"
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir #include <gtk/gtk.h>
52*cdf0e10cSrcweir 
53*cdf0e10cSrcweir #include <set>
54*cdf0e10cSrcweir 
55*cdf0e10cSrcweir // #define ENABLE_TRACING
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir #ifdef ENABLE_TRACING
58*cdf0e10cSrcweir #include <stdio.h>
59*cdf0e10cSrcweir #endif
60*cdf0e10cSrcweir 
61*cdf0e10cSrcweir using namespace ::com::sun::star;
62*cdf0e10cSrcweir 
63*cdf0e10cSrcweir static uno::WeakReference< accessibility::XAccessible > xNextFocusObject;
64*cdf0e10cSrcweir static guint focus_notify_handler = 0;
65*cdf0e10cSrcweir 
66*cdf0e10cSrcweir /*****************************************************************************/
67*cdf0e10cSrcweir 
68*cdf0e10cSrcweir extern "C" {
69*cdf0e10cSrcweir 
70*cdf0e10cSrcweir static gint
71*cdf0e10cSrcweir atk_wrapper_focus_idle_handler (gpointer data)
72*cdf0e10cSrcweir {
73*cdf0e10cSrcweir     vos::OGuard aGuard( Application::GetSolarMutex() );
74*cdf0e10cSrcweir 
75*cdf0e10cSrcweir     focus_notify_handler = 0;
76*cdf0e10cSrcweir 
77*cdf0e10cSrcweir     uno::Reference< accessibility::XAccessible > xAccessible = xNextFocusObject;
78*cdf0e10cSrcweir     if( xAccessible.get() == reinterpret_cast < accessibility::XAccessible * > (data) )
79*cdf0e10cSrcweir     {
80*cdf0e10cSrcweir         AtkObject *atk_obj = xAccessible.is() ? atk_object_wrapper_ref( xAccessible ) : NULL;
81*cdf0e10cSrcweir         // Gail does not notify focus changes to NULL, so do we ..
82*cdf0e10cSrcweir         if( atk_obj )
83*cdf0e10cSrcweir         {
84*cdf0e10cSrcweir #ifdef ENABLE_TRACING
85*cdf0e10cSrcweir             fprintf(stderr, "notifying focus event for %p\n", atk_obj);
86*cdf0e10cSrcweir #endif
87*cdf0e10cSrcweir             atk_focus_tracker_notify(atk_obj);
88*cdf0e10cSrcweir             // --> OD 2009-04-14 #i93269#
89*cdf0e10cSrcweir             // emit text_caret_moved event for <XAccessibleText> object,
90*cdf0e10cSrcweir             // if cursor is inside the <XAccessibleText> object.
91*cdf0e10cSrcweir             // also emit state-changed:focused event under the same condition.
92*cdf0e10cSrcweir             {
93*cdf0e10cSrcweir                 AtkObjectWrapper* wrapper_obj = ATK_OBJECT_WRAPPER (atk_obj);
94*cdf0e10cSrcweir                 if( wrapper_obj && !wrapper_obj->mpText && wrapper_obj->mpContext )
95*cdf0e10cSrcweir                 {
96*cdf0e10cSrcweir                     uno::Any any = wrapper_obj->mpContext->queryInterface( accessibility::XAccessibleText::static_type(NULL) );
97*cdf0e10cSrcweir                     if ( typelib_TypeClass_INTERFACE == any.pType->eTypeClass &&
98*cdf0e10cSrcweir                          any.pReserved != 0 )
99*cdf0e10cSrcweir                     {
100*cdf0e10cSrcweir                         wrapper_obj->mpText = reinterpret_cast< accessibility::XAccessibleText * > (any.pReserved);
101*cdf0e10cSrcweir                         if ( wrapper_obj->mpText != 0 )
102*cdf0e10cSrcweir                         {
103*cdf0e10cSrcweir                             wrapper_obj->mpText->acquire();
104*cdf0e10cSrcweir                             gint caretPos = wrapper_obj->mpText->getCaretPosition();
105*cdf0e10cSrcweir 
106*cdf0e10cSrcweir                             if ( caretPos != -1 )
107*cdf0e10cSrcweir                             {
108*cdf0e10cSrcweir                                 atk_object_notify_state_change( atk_obj, ATK_STATE_FOCUSED, TRUE );
109*cdf0e10cSrcweir                                 g_signal_emit_by_name( atk_obj, "text_caret_moved", caretPos );
110*cdf0e10cSrcweir                             }
111*cdf0e10cSrcweir                         }
112*cdf0e10cSrcweir                     }
113*cdf0e10cSrcweir                 }
114*cdf0e10cSrcweir             }
115*cdf0e10cSrcweir             // <--
116*cdf0e10cSrcweir             g_object_unref(atk_obj);
117*cdf0e10cSrcweir         }
118*cdf0e10cSrcweir     }
119*cdf0e10cSrcweir 
120*cdf0e10cSrcweir     return FALSE;
121*cdf0e10cSrcweir }
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir } // extern "C"
124*cdf0e10cSrcweir 
125*cdf0e10cSrcweir /*****************************************************************************/
126*cdf0e10cSrcweir 
127*cdf0e10cSrcweir static void
128*cdf0e10cSrcweir atk_wrapper_focus_tracker_notify_when_idle( const uno::Reference< accessibility::XAccessible > &xAccessible )
129*cdf0e10cSrcweir {
130*cdf0e10cSrcweir     if( focus_notify_handler )
131*cdf0e10cSrcweir         g_source_remove(focus_notify_handler);
132*cdf0e10cSrcweir 
133*cdf0e10cSrcweir     xNextFocusObject = xAccessible;
134*cdf0e10cSrcweir 
135*cdf0e10cSrcweir     focus_notify_handler = g_idle_add (atk_wrapper_focus_idle_handler, xAccessible.get());
136*cdf0e10cSrcweir }
137*cdf0e10cSrcweir 
138*cdf0e10cSrcweir /*****************************************************************************/
139*cdf0e10cSrcweir 
140*cdf0e10cSrcweir class DocumentFocusListener :
141*cdf0e10cSrcweir     public ::cppu::WeakImplHelper1< accessibility::XAccessibleEventListener >
142*cdf0e10cSrcweir {
143*cdf0e10cSrcweir 
144*cdf0e10cSrcweir     std::set< uno::Reference< uno::XInterface > > m_aRefList;
145*cdf0e10cSrcweir 
146*cdf0e10cSrcweir public:
147*cdf0e10cSrcweir     void attachRecursive(
148*cdf0e10cSrcweir         const uno::Reference< accessibility::XAccessible >& xAccessible
149*cdf0e10cSrcweir     ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException);
150*cdf0e10cSrcweir 
151*cdf0e10cSrcweir     void attachRecursive(
152*cdf0e10cSrcweir         const uno::Reference< accessibility::XAccessible >& xAccessible,
153*cdf0e10cSrcweir         const uno::Reference< accessibility::XAccessibleContext >& xContext
154*cdf0e10cSrcweir     ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException);
155*cdf0e10cSrcweir 
156*cdf0e10cSrcweir     void attachRecursive(
157*cdf0e10cSrcweir         const uno::Reference< accessibility::XAccessible >& xAccessible,
158*cdf0e10cSrcweir         const uno::Reference< accessibility::XAccessibleContext >& xContext,
159*cdf0e10cSrcweir         const uno::Reference< accessibility::XAccessibleStateSet >& xStateSet
160*cdf0e10cSrcweir     ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException);
161*cdf0e10cSrcweir 
162*cdf0e10cSrcweir     void detachRecursive(
163*cdf0e10cSrcweir         const uno::Reference< accessibility::XAccessible >& xAccessible
164*cdf0e10cSrcweir     ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException);
165*cdf0e10cSrcweir 
166*cdf0e10cSrcweir     void detachRecursive(
167*cdf0e10cSrcweir         const uno::Reference< accessibility::XAccessible >& xAccessible,
168*cdf0e10cSrcweir         const uno::Reference< accessibility::XAccessibleContext >& xContext
169*cdf0e10cSrcweir     ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException);
170*cdf0e10cSrcweir 
171*cdf0e10cSrcweir     void detachRecursive(
172*cdf0e10cSrcweir         const uno::Reference< accessibility::XAccessible >& xAccessible,
173*cdf0e10cSrcweir         const uno::Reference< accessibility::XAccessibleContext >& xContext,
174*cdf0e10cSrcweir         const uno::Reference< accessibility::XAccessibleStateSet >& xStateSet
175*cdf0e10cSrcweir     ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException);
176*cdf0e10cSrcweir 
177*cdf0e10cSrcweir     static uno::Reference< accessibility::XAccessible > getAccessible(const lang::EventObject& aEvent )
178*cdf0e10cSrcweir         throw (lang::IndexOutOfBoundsException, uno::RuntimeException);
179*cdf0e10cSrcweir 
180*cdf0e10cSrcweir     // XEventListener
181*cdf0e10cSrcweir     virtual void disposing( const lang::EventObject& Source ) throw (uno::RuntimeException);
182*cdf0e10cSrcweir 
183*cdf0e10cSrcweir     // XAccessibleEventListener
184*cdf0e10cSrcweir     virtual void notifyEvent( const accessibility::AccessibleEventObject& aEvent ) throw( uno::RuntimeException );
185*cdf0e10cSrcweir };
186*cdf0e10cSrcweir 
187*cdf0e10cSrcweir /*****************************************************************************/
188*cdf0e10cSrcweir 
189*cdf0e10cSrcweir void DocumentFocusListener::disposing( const lang::EventObject& aEvent )
190*cdf0e10cSrcweir     throw (uno::RuntimeException)
191*cdf0e10cSrcweir {
192*cdf0e10cSrcweir //    fprintf(stderr, "In DocumentFocusListener::disposing (%p)\n", this);
193*cdf0e10cSrcweir //    fprintf(stderr, "m_aRefList has %d entries\n", m_aRefList.size());
194*cdf0e10cSrcweir 
195*cdf0e10cSrcweir     // Unref the object here, but do not remove as listener since the object
196*cdf0e10cSrcweir     // might no longer be in a state that safely allows this.
197*cdf0e10cSrcweir     if( aEvent.Source.is() )
198*cdf0e10cSrcweir         m_aRefList.erase(aEvent.Source);
199*cdf0e10cSrcweir 
200*cdf0e10cSrcweir //    fprintf(stderr, "m_aRefList has %d entries\n", m_aRefList.size());
201*cdf0e10cSrcweir 
202*cdf0e10cSrcweir }
203*cdf0e10cSrcweir 
204*cdf0e10cSrcweir /*****************************************************************************/
205*cdf0e10cSrcweir 
206*cdf0e10cSrcweir void DocumentFocusListener::notifyEvent( const accessibility::AccessibleEventObject& aEvent )
207*cdf0e10cSrcweir     throw( uno::RuntimeException )
208*cdf0e10cSrcweir {
209*cdf0e10cSrcweir     switch( aEvent.EventId )
210*cdf0e10cSrcweir     {
211*cdf0e10cSrcweir         case accessibility::AccessibleEventId::STATE_CHANGED:
212*cdf0e10cSrcweir             try
213*cdf0e10cSrcweir             {
214*cdf0e10cSrcweir                 sal_Int16 nState = accessibility::AccessibleStateType::INVALID;
215*cdf0e10cSrcweir                 aEvent.NewValue >>= nState;
216*cdf0e10cSrcweir 
217*cdf0e10cSrcweir                 if( accessibility::AccessibleStateType::FOCUSED == nState )
218*cdf0e10cSrcweir                     atk_wrapper_focus_tracker_notify_when_idle( getAccessible(aEvent) );
219*cdf0e10cSrcweir             }
220*cdf0e10cSrcweir             catch(const lang::IndexOutOfBoundsException &e)
221*cdf0e10cSrcweir             {
222*cdf0e10cSrcweir                 g_warning("Focused object has invalid index in parent");
223*cdf0e10cSrcweir             }
224*cdf0e10cSrcweir             break;
225*cdf0e10cSrcweir 
226*cdf0e10cSrcweir         case accessibility::AccessibleEventId::CHILD:
227*cdf0e10cSrcweir         {
228*cdf0e10cSrcweir             uno::Reference< accessibility::XAccessible > xChild;
229*cdf0e10cSrcweir             if( (aEvent.OldValue >>= xChild) && xChild.is() )
230*cdf0e10cSrcweir                 detachRecursive(xChild);
231*cdf0e10cSrcweir 
232*cdf0e10cSrcweir             if( (aEvent.NewValue >>= xChild) && xChild.is() )
233*cdf0e10cSrcweir                 attachRecursive(xChild);
234*cdf0e10cSrcweir         }
235*cdf0e10cSrcweir             break;
236*cdf0e10cSrcweir 
237*cdf0e10cSrcweir         case accessibility::AccessibleEventId::INVALIDATE_ALL_CHILDREN:
238*cdf0e10cSrcweir /*        {
239*cdf0e10cSrcweir             uno::Reference< accessibility::XAccessible > xAccessible( getAccessible(aEvent) );
240*cdf0e10cSrcweir             detachRecursive(xAccessible);
241*cdf0e10cSrcweir             attachRecursive(xAccessible);
242*cdf0e10cSrcweir         }
243*cdf0e10cSrcweir */
244*cdf0e10cSrcweir             g_warning( "Invalidate all children called\n" );
245*cdf0e10cSrcweir             break;
246*cdf0e10cSrcweir         default:
247*cdf0e10cSrcweir             break;
248*cdf0e10cSrcweir     }
249*cdf0e10cSrcweir }
250*cdf0e10cSrcweir 
251*cdf0e10cSrcweir /*****************************************************************************/
252*cdf0e10cSrcweir 
253*cdf0e10cSrcweir uno::Reference< accessibility::XAccessible > DocumentFocusListener::getAccessible(const lang::EventObject& aEvent )
254*cdf0e10cSrcweir     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
255*cdf0e10cSrcweir {
256*cdf0e10cSrcweir     uno::Reference< accessibility::XAccessible > xAccessible(aEvent.Source, uno::UNO_QUERY);
257*cdf0e10cSrcweir 
258*cdf0e10cSrcweir     if( xAccessible.is() )
259*cdf0e10cSrcweir         return xAccessible;
260*cdf0e10cSrcweir 
261*cdf0e10cSrcweir     uno::Reference< accessibility::XAccessibleContext > xContext(aEvent.Source, uno::UNO_QUERY);
262*cdf0e10cSrcweir 
263*cdf0e10cSrcweir     if( xContext.is() )
264*cdf0e10cSrcweir     {
265*cdf0e10cSrcweir         uno::Reference< accessibility::XAccessible > xParent( xContext->getAccessibleParent() );
266*cdf0e10cSrcweir         if( xParent.is() )
267*cdf0e10cSrcweir         {
268*cdf0e10cSrcweir             uno::Reference< accessibility::XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
269*cdf0e10cSrcweir             if( xParentContext.is() )
270*cdf0e10cSrcweir             {
271*cdf0e10cSrcweir                 return xParentContext->getAccessibleChild( xContext->getAccessibleIndexInParent() );
272*cdf0e10cSrcweir             }
273*cdf0e10cSrcweir         }
274*cdf0e10cSrcweir     }
275*cdf0e10cSrcweir 
276*cdf0e10cSrcweir     return uno::Reference< accessibility::XAccessible >();
277*cdf0e10cSrcweir }
278*cdf0e10cSrcweir 
279*cdf0e10cSrcweir /*****************************************************************************/
280*cdf0e10cSrcweir 
281*cdf0e10cSrcweir void DocumentFocusListener::attachRecursive(
282*cdf0e10cSrcweir     const uno::Reference< accessibility::XAccessible >& xAccessible
283*cdf0e10cSrcweir ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
284*cdf0e10cSrcweir {
285*cdf0e10cSrcweir     uno::Reference< accessibility::XAccessibleContext > xContext =
286*cdf0e10cSrcweir         xAccessible->getAccessibleContext();
287*cdf0e10cSrcweir 
288*cdf0e10cSrcweir     if( xContext.is() )
289*cdf0e10cSrcweir         attachRecursive(xAccessible, xContext);
290*cdf0e10cSrcweir }
291*cdf0e10cSrcweir 
292*cdf0e10cSrcweir /*****************************************************************************/
293*cdf0e10cSrcweir 
294*cdf0e10cSrcweir void DocumentFocusListener::attachRecursive(
295*cdf0e10cSrcweir     const uno::Reference< accessibility::XAccessible >& xAccessible,
296*cdf0e10cSrcweir     const uno::Reference< accessibility::XAccessibleContext >& xContext
297*cdf0e10cSrcweir )  throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
298*cdf0e10cSrcweir {
299*cdf0e10cSrcweir     uno::Reference< accessibility::XAccessibleStateSet > xStateSet =
300*cdf0e10cSrcweir         xContext->getAccessibleStateSet();
301*cdf0e10cSrcweir 
302*cdf0e10cSrcweir     if( xStateSet.is() )
303*cdf0e10cSrcweir         attachRecursive(xAccessible, xContext, xStateSet);
304*cdf0e10cSrcweir }
305*cdf0e10cSrcweir 
306*cdf0e10cSrcweir /*****************************************************************************/
307*cdf0e10cSrcweir 
308*cdf0e10cSrcweir void DocumentFocusListener::attachRecursive(
309*cdf0e10cSrcweir     const uno::Reference< accessibility::XAccessible >& xAccessible,
310*cdf0e10cSrcweir     const uno::Reference< accessibility::XAccessibleContext >& xContext,
311*cdf0e10cSrcweir     const uno::Reference< accessibility::XAccessibleStateSet >& xStateSet
312*cdf0e10cSrcweir ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
313*cdf0e10cSrcweir {
314*cdf0e10cSrcweir     if( xStateSet->contains(accessibility::AccessibleStateType::FOCUSED ) )
315*cdf0e10cSrcweir         atk_wrapper_focus_tracker_notify_when_idle( xAccessible );
316*cdf0e10cSrcweir 
317*cdf0e10cSrcweir     uno::Reference< accessibility::XAccessibleEventBroadcaster > xBroadcaster =
318*cdf0e10cSrcweir         uno::Reference< accessibility::XAccessibleEventBroadcaster >(xContext, uno::UNO_QUERY);
319*cdf0e10cSrcweir 
320*cdf0e10cSrcweir     // If not already done, add the broadcaster to the list and attach as listener.
321*cdf0e10cSrcweir     if( xBroadcaster.is() && m_aRefList.insert(xBroadcaster).second )
322*cdf0e10cSrcweir     {
323*cdf0e10cSrcweir         xBroadcaster->addEventListener(static_cast< accessibility::XAccessibleEventListener *>(this));
324*cdf0e10cSrcweir 
325*cdf0e10cSrcweir         if( ! xStateSet->contains(accessibility::AccessibleStateType::MANAGES_DESCENDANTS ) )
326*cdf0e10cSrcweir         {
327*cdf0e10cSrcweir             sal_Int32 n, nmax = xContext->getAccessibleChildCount();
328*cdf0e10cSrcweir             for( n = 0; n < nmax; n++ )
329*cdf0e10cSrcweir             {
330*cdf0e10cSrcweir                 uno::Reference< accessibility::XAccessible > xChild( xContext->getAccessibleChild( n ) );
331*cdf0e10cSrcweir 
332*cdf0e10cSrcweir                 if( xChild.is() )
333*cdf0e10cSrcweir                     attachRecursive(xChild);
334*cdf0e10cSrcweir             }
335*cdf0e10cSrcweir         }
336*cdf0e10cSrcweir     }
337*cdf0e10cSrcweir }
338*cdf0e10cSrcweir 
339*cdf0e10cSrcweir /*****************************************************************************/
340*cdf0e10cSrcweir 
341*cdf0e10cSrcweir void DocumentFocusListener::detachRecursive(
342*cdf0e10cSrcweir     const uno::Reference< accessibility::XAccessible >& xAccessible
343*cdf0e10cSrcweir ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
344*cdf0e10cSrcweir {
345*cdf0e10cSrcweir     uno::Reference< accessibility::XAccessibleContext > xContext =
346*cdf0e10cSrcweir         xAccessible->getAccessibleContext();
347*cdf0e10cSrcweir 
348*cdf0e10cSrcweir     if( xContext.is() )
349*cdf0e10cSrcweir         detachRecursive(xAccessible, xContext);
350*cdf0e10cSrcweir }
351*cdf0e10cSrcweir 
352*cdf0e10cSrcweir /*****************************************************************************/
353*cdf0e10cSrcweir 
354*cdf0e10cSrcweir void DocumentFocusListener::detachRecursive(
355*cdf0e10cSrcweir     const uno::Reference< accessibility::XAccessible >& xAccessible,
356*cdf0e10cSrcweir     const uno::Reference< accessibility::XAccessibleContext >& xContext
357*cdf0e10cSrcweir )  throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
358*cdf0e10cSrcweir {
359*cdf0e10cSrcweir     uno::Reference< accessibility::XAccessibleStateSet > xStateSet =
360*cdf0e10cSrcweir         xContext->getAccessibleStateSet();
361*cdf0e10cSrcweir 
362*cdf0e10cSrcweir     if( xStateSet.is() )
363*cdf0e10cSrcweir         detachRecursive(xAccessible, xContext, xStateSet);
364*cdf0e10cSrcweir }
365*cdf0e10cSrcweir 
366*cdf0e10cSrcweir /*****************************************************************************/
367*cdf0e10cSrcweir 
368*cdf0e10cSrcweir void DocumentFocusListener::detachRecursive(
369*cdf0e10cSrcweir     const uno::Reference< accessibility::XAccessible >&,
370*cdf0e10cSrcweir     const uno::Reference< accessibility::XAccessibleContext >& xContext,
371*cdf0e10cSrcweir     const uno::Reference< accessibility::XAccessibleStateSet >& xStateSet
372*cdf0e10cSrcweir ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
373*cdf0e10cSrcweir {
374*cdf0e10cSrcweir     uno::Reference< accessibility::XAccessibleEventBroadcaster > xBroadcaster =
375*cdf0e10cSrcweir         uno::Reference< accessibility::XAccessibleEventBroadcaster >(xContext, uno::UNO_QUERY);
376*cdf0e10cSrcweir 
377*cdf0e10cSrcweir     if( xBroadcaster.is() && 0 < m_aRefList.erase(xBroadcaster) )
378*cdf0e10cSrcweir     {
379*cdf0e10cSrcweir         xBroadcaster->removeEventListener(static_cast< accessibility::XAccessibleEventListener *>(this));
380*cdf0e10cSrcweir 
381*cdf0e10cSrcweir         if( ! xStateSet->contains(accessibility::AccessibleStateType::MANAGES_DESCENDANTS ) )
382*cdf0e10cSrcweir         {
383*cdf0e10cSrcweir             sal_Int32 n, nmax = xContext->getAccessibleChildCount();
384*cdf0e10cSrcweir             for( n = 0; n < nmax; n++ )
385*cdf0e10cSrcweir             {
386*cdf0e10cSrcweir                 uno::Reference< accessibility::XAccessible > xChild( xContext->getAccessibleChild( n ) );
387*cdf0e10cSrcweir 
388*cdf0e10cSrcweir                 if( xChild.is() )
389*cdf0e10cSrcweir                     detachRecursive(xChild);
390*cdf0e10cSrcweir             }
391*cdf0e10cSrcweir         }
392*cdf0e10cSrcweir     }
393*cdf0e10cSrcweir }
394*cdf0e10cSrcweir 
395*cdf0e10cSrcweir /*****************************************************************************/
396*cdf0e10cSrcweir 
397*cdf0e10cSrcweir /*
398*cdf0e10cSrcweir  * page tabs in gtk are widgets, so we need to simulate focus events for those
399*cdf0e10cSrcweir  */
400*cdf0e10cSrcweir 
401*cdf0e10cSrcweir static void handle_tabpage_activated(Window *pWindow)
402*cdf0e10cSrcweir {
403*cdf0e10cSrcweir     uno::Reference< accessibility::XAccessible > xAccessible =
404*cdf0e10cSrcweir         pWindow->GetAccessible();
405*cdf0e10cSrcweir 
406*cdf0e10cSrcweir     if( ! xAccessible.is() )
407*cdf0e10cSrcweir         return;
408*cdf0e10cSrcweir 
409*cdf0e10cSrcweir     uno::Reference< accessibility::XAccessibleSelection > xSelection(
410*cdf0e10cSrcweir         xAccessible->getAccessibleContext(), uno::UNO_QUERY);
411*cdf0e10cSrcweir 
412*cdf0e10cSrcweir     if( xSelection.is() )
413*cdf0e10cSrcweir         atk_wrapper_focus_tracker_notify_when_idle( xSelection->getSelectedAccessibleChild(0) );
414*cdf0e10cSrcweir }
415*cdf0e10cSrcweir 
416*cdf0e10cSrcweir /*****************************************************************************/
417*cdf0e10cSrcweir 
418*cdf0e10cSrcweir /*
419*cdf0e10cSrcweir  * toolbar items in gtk are widgets, so we need to simulate focus events for those
420*cdf0e10cSrcweir  */
421*cdf0e10cSrcweir 
422*cdf0e10cSrcweir static void notify_toolbox_item_focus(ToolBox *pToolBox)
423*cdf0e10cSrcweir {
424*cdf0e10cSrcweir     uno::Reference< accessibility::XAccessible > xAccessible =
425*cdf0e10cSrcweir         pToolBox->GetAccessible();
426*cdf0e10cSrcweir 
427*cdf0e10cSrcweir     if( ! xAccessible.is() )
428*cdf0e10cSrcweir         return;
429*cdf0e10cSrcweir 
430*cdf0e10cSrcweir     uno::Reference< accessibility::XAccessibleContext > xContext =
431*cdf0e10cSrcweir         xAccessible->getAccessibleContext();
432*cdf0e10cSrcweir 
433*cdf0e10cSrcweir     if( ! xContext.is() )
434*cdf0e10cSrcweir         return;
435*cdf0e10cSrcweir 
436*cdf0e10cSrcweir     sal_Int32 nPos = pToolBox->GetItemPos( pToolBox->GetHighlightItemId() );
437*cdf0e10cSrcweir     if( nPos != TOOLBOX_ITEM_NOTFOUND )
438*cdf0e10cSrcweir         atk_wrapper_focus_tracker_notify_when_idle( xContext->getAccessibleChild( nPos ) );
439*cdf0e10cSrcweir }
440*cdf0e10cSrcweir 
441*cdf0e10cSrcweir static void handle_toolbox_highlight(Window *pWindow)
442*cdf0e10cSrcweir {
443*cdf0e10cSrcweir     ToolBox *pToolBox = static_cast <ToolBox *> (pWindow);
444*cdf0e10cSrcweir 
445*cdf0e10cSrcweir     // Make sure either the toolbox or its parent toolbox has the focus
446*cdf0e10cSrcweir     if ( ! pToolBox->HasFocus() )
447*cdf0e10cSrcweir     {
448*cdf0e10cSrcweir         ToolBox* pToolBoxParent = dynamic_cast< ToolBox* >( pToolBox->GetParent() );
449*cdf0e10cSrcweir         if ( ! pToolBoxParent || ! pToolBoxParent->HasFocus() )
450*cdf0e10cSrcweir             return;
451*cdf0e10cSrcweir     }
452*cdf0e10cSrcweir 
453*cdf0e10cSrcweir     notify_toolbox_item_focus(pToolBox);
454*cdf0e10cSrcweir }
455*cdf0e10cSrcweir 
456*cdf0e10cSrcweir static void handle_toolbox_highlightoff(Window *pWindow)
457*cdf0e10cSrcweir {
458*cdf0e10cSrcweir     ToolBox *pToolBox = static_cast <ToolBox *> (pWindow);
459*cdf0e10cSrcweir     ToolBox* pToolBoxParent = dynamic_cast< ToolBox* >( pToolBox->GetParent() );
460*cdf0e10cSrcweir 
461*cdf0e10cSrcweir     // Notify when leaving sub toolboxes
462*cdf0e10cSrcweir     if( pToolBoxParent && pToolBoxParent->HasFocus() )
463*cdf0e10cSrcweir         notify_toolbox_item_focus( pToolBoxParent );
464*cdf0e10cSrcweir }
465*cdf0e10cSrcweir 
466*cdf0e10cSrcweir /*****************************************************************************/
467*cdf0e10cSrcweir 
468*cdf0e10cSrcweir static void create_wrapper_for_child(
469*cdf0e10cSrcweir     const uno::Reference< accessibility::XAccessibleContext >& xContext,
470*cdf0e10cSrcweir     sal_Int32 index)
471*cdf0e10cSrcweir {
472*cdf0e10cSrcweir     if( xContext.is() )
473*cdf0e10cSrcweir     {
474*cdf0e10cSrcweir         uno::Reference< accessibility::XAccessible > xChild(xContext->getAccessibleChild(index));
475*cdf0e10cSrcweir         if( xChild.is() )
476*cdf0e10cSrcweir         {
477*cdf0e10cSrcweir             // create the wrapper object - it will survive the unref unless it is a transient object
478*cdf0e10cSrcweir             g_object_unref( atk_object_wrapper_ref( xChild ) );
479*cdf0e10cSrcweir         }
480*cdf0e10cSrcweir     }
481*cdf0e10cSrcweir }
482*cdf0e10cSrcweir 
483*cdf0e10cSrcweir /*****************************************************************************/
484*cdf0e10cSrcweir 
485*cdf0e10cSrcweir static void handle_toolbox_buttonchange(VclWindowEvent const *pEvent)
486*cdf0e10cSrcweir {
487*cdf0e10cSrcweir     Window* pWindow = pEvent->GetWindow();
488*cdf0e10cSrcweir     sal_Int32 index = (sal_Int32)(sal_IntPtr) pEvent->GetData();
489*cdf0e10cSrcweir 
490*cdf0e10cSrcweir     if( pWindow && pWindow->IsReallyVisible() )
491*cdf0e10cSrcweir     {
492*cdf0e10cSrcweir         uno::Reference< accessibility::XAccessible > xAccessible(pWindow->GetAccessible());
493*cdf0e10cSrcweir         if( xAccessible.is() )
494*cdf0e10cSrcweir         {
495*cdf0e10cSrcweir             create_wrapper_for_child(xAccessible->getAccessibleContext(), index);
496*cdf0e10cSrcweir         }
497*cdf0e10cSrcweir     }
498*cdf0e10cSrcweir }
499*cdf0e10cSrcweir 
500*cdf0e10cSrcweir /*****************************************************************************/
501*cdf0e10cSrcweir 
502*cdf0e10cSrcweir /* currently not needed anymore...
503*cdf0e10cSrcweir static void create_wrapper_for_children(Window *pWindow)
504*cdf0e10cSrcweir {
505*cdf0e10cSrcweir     if( pWindow && pWindow->IsReallyVisible() )
506*cdf0e10cSrcweir     {
507*cdf0e10cSrcweir         uno::Reference< accessibility::XAccessible > xAccessible(pWindow->GetAccessible());
508*cdf0e10cSrcweir         if( xAccessible.is() )
509*cdf0e10cSrcweir         {
510*cdf0e10cSrcweir             uno::Reference< accessibility::XAccessibleContext > xContext(xAccessible->getAccessibleContext());
511*cdf0e10cSrcweir             if( xContext.is() )
512*cdf0e10cSrcweir             {
513*cdf0e10cSrcweir                 sal_Int32 nChildren = xContext->getAccessibleChildCount();
514*cdf0e10cSrcweir                 for( sal_Int32 i = 0; i < nChildren; ++i )
515*cdf0e10cSrcweir                     create_wrapper_for_child(xContext, i);
516*cdf0e10cSrcweir             }
517*cdf0e10cSrcweir         }
518*cdf0e10cSrcweir     }
519*cdf0e10cSrcweir }
520*cdf0e10cSrcweir */
521*cdf0e10cSrcweir 
522*cdf0e10cSrcweir /*****************************************************************************/
523*cdf0e10cSrcweir 
524*cdf0e10cSrcweir static std::set< Window * > g_aWindowList;
525*cdf0e10cSrcweir 
526*cdf0e10cSrcweir static void handle_get_focus(::VclWindowEvent const * pEvent)
527*cdf0e10cSrcweir {
528*cdf0e10cSrcweir     static rtl::Reference< DocumentFocusListener > aDocumentFocusListener =
529*cdf0e10cSrcweir         new DocumentFocusListener();
530*cdf0e10cSrcweir 
531*cdf0e10cSrcweir     Window *pWindow = pEvent->GetWindow();
532*cdf0e10cSrcweir 
533*cdf0e10cSrcweir     // The menu bar is handled through VCLEVENT_MENU_HIGHLIGHTED
534*cdf0e10cSrcweir     if( ! pWindow || !pWindow->IsReallyVisible() || pWindow->GetType() == WINDOW_MENUBARWINDOW )
535*cdf0e10cSrcweir         return;
536*cdf0e10cSrcweir 
537*cdf0e10cSrcweir     // ToolBoxes are handled through VCLEVENT_TOOLBOX_HIGHLIGHT
538*cdf0e10cSrcweir     if( pWindow->GetType() == WINDOW_TOOLBOX )
539*cdf0e10cSrcweir         return;
540*cdf0e10cSrcweir 
541*cdf0e10cSrcweir     if( pWindow->GetType() == WINDOW_TABCONTROL )
542*cdf0e10cSrcweir     {
543*cdf0e10cSrcweir         handle_tabpage_activated( pWindow );
544*cdf0e10cSrcweir         return;
545*cdf0e10cSrcweir     }
546*cdf0e10cSrcweir 
547*cdf0e10cSrcweir     uno::Reference< accessibility::XAccessible > xAccessible =
548*cdf0e10cSrcweir         pWindow->GetAccessible();
549*cdf0e10cSrcweir 
550*cdf0e10cSrcweir     if( ! xAccessible.is() )
551*cdf0e10cSrcweir         return;
552*cdf0e10cSrcweir 
553*cdf0e10cSrcweir     uno::Reference< accessibility::XAccessibleContext > xContext =
554*cdf0e10cSrcweir         xAccessible->getAccessibleContext();
555*cdf0e10cSrcweir 
556*cdf0e10cSrcweir     if( ! xContext.is() )
557*cdf0e10cSrcweir         return;
558*cdf0e10cSrcweir 
559*cdf0e10cSrcweir     uno::Reference< accessibility::XAccessibleStateSet > xStateSet =
560*cdf0e10cSrcweir         xContext->getAccessibleStateSet();
561*cdf0e10cSrcweir 
562*cdf0e10cSrcweir     if( ! xStateSet.is() )
563*cdf0e10cSrcweir         return;
564*cdf0e10cSrcweir 
565*cdf0e10cSrcweir /* the UNO ToolBox wrapper does not (yet?) support XAccessibleSelection, so we
566*cdf0e10cSrcweir  * need to add listeners to the children instead of re-using the tabpage stuff
567*cdf0e10cSrcweir  */
568*cdf0e10cSrcweir     if( xStateSet->contains(accessibility::AccessibleStateType::FOCUSED) &&
569*cdf0e10cSrcweir         ( pWindow->GetType() != WINDOW_TREELISTBOX ) )
570*cdf0e10cSrcweir     {
571*cdf0e10cSrcweir         atk_wrapper_focus_tracker_notify_when_idle( xAccessible );
572*cdf0e10cSrcweir     }
573*cdf0e10cSrcweir     else
574*cdf0e10cSrcweir     {
575*cdf0e10cSrcweir         if( g_aWindowList.find(pWindow) == g_aWindowList.end() )
576*cdf0e10cSrcweir         {
577*cdf0e10cSrcweir             g_aWindowList.insert(pWindow);
578*cdf0e10cSrcweir             try
579*cdf0e10cSrcweir             {
580*cdf0e10cSrcweir                 aDocumentFocusListener->attachRecursive(xAccessible, xContext, xStateSet);
581*cdf0e10cSrcweir             }
582*cdf0e10cSrcweir             catch( const uno::Exception &e )
583*cdf0e10cSrcweir             {
584*cdf0e10cSrcweir                 g_warning( "Exception caught processing focus events" );
585*cdf0e10cSrcweir             }
586*cdf0e10cSrcweir         }
587*cdf0e10cSrcweir #ifdef ENABLE_TRACING
588*cdf0e10cSrcweir         else
589*cdf0e10cSrcweir             fprintf(stderr, "Window %p already in the list\n", pWindow );
590*cdf0e10cSrcweir #endif
591*cdf0e10cSrcweir     }
592*cdf0e10cSrcweir }
593*cdf0e10cSrcweir 
594*cdf0e10cSrcweir /*****************************************************************************/
595*cdf0e10cSrcweir 
596*cdf0e10cSrcweir static void handle_menu_highlighted(::VclMenuEvent const * pEvent)
597*cdf0e10cSrcweir {
598*cdf0e10cSrcweir     try
599*cdf0e10cSrcweir     {
600*cdf0e10cSrcweir         Menu* pMenu = pEvent->GetMenu();
601*cdf0e10cSrcweir         sal_uInt16 nPos = pEvent->GetItemPos();
602*cdf0e10cSrcweir 
603*cdf0e10cSrcweir         if( pMenu &&  nPos != 0xFFFF)
604*cdf0e10cSrcweir         {
605*cdf0e10cSrcweir             uno::Reference< accessibility::XAccessible > xAccessible ( pMenu->GetAccessible() );
606*cdf0e10cSrcweir 
607*cdf0e10cSrcweir             if( xAccessible.is() )
608*cdf0e10cSrcweir             {
609*cdf0e10cSrcweir                 uno::Reference< accessibility::XAccessibleContext > xContext ( xAccessible->getAccessibleContext() );
610*cdf0e10cSrcweir 
611*cdf0e10cSrcweir                 if( xContext.is() )
612*cdf0e10cSrcweir                     atk_wrapper_focus_tracker_notify_when_idle( xContext->getAccessibleChild( nPos ) );
613*cdf0e10cSrcweir             }
614*cdf0e10cSrcweir         }
615*cdf0e10cSrcweir     }
616*cdf0e10cSrcweir     catch( const uno::Exception& e )
617*cdf0e10cSrcweir     {
618*cdf0e10cSrcweir         g_warning( "Exception caught processing menu highlight events" );
619*cdf0e10cSrcweir     }
620*cdf0e10cSrcweir }
621*cdf0e10cSrcweir 
622*cdf0e10cSrcweir /*****************************************************************************/
623*cdf0e10cSrcweir 
624*cdf0e10cSrcweir long WindowEventHandler(void *, ::VclSimpleEvent const * pEvent)
625*cdf0e10cSrcweir {
626*cdf0e10cSrcweir     switch (pEvent->GetId())
627*cdf0e10cSrcweir     {
628*cdf0e10cSrcweir     case VCLEVENT_WINDOW_SHOW:
629*cdf0e10cSrcweir //        fprintf(stderr, "got VCLEVENT_WINDOW_SHOW for %p\n",
630*cdf0e10cSrcweir //            static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
631*cdf0e10cSrcweir         break;
632*cdf0e10cSrcweir     case VCLEVENT_WINDOW_HIDE:
633*cdf0e10cSrcweir //        fprintf(stderr, "got VCLEVENT_WINDOW_HIDE for %p\n",
634*cdf0e10cSrcweir //            static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
635*cdf0e10cSrcweir         break;
636*cdf0e10cSrcweir     case VCLEVENT_WINDOW_CLOSE:
637*cdf0e10cSrcweir //        fprintf(stderr, "got VCLEVENT_WINDOW_CLOSE for %p\n",
638*cdf0e10cSrcweir //            static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
639*cdf0e10cSrcweir         break;
640*cdf0e10cSrcweir     case VCLEVENT_WINDOW_GETFOCUS:
641*cdf0e10cSrcweir         handle_get_focus(static_cast< ::VclWindowEvent const * >(pEvent));
642*cdf0e10cSrcweir         break;
643*cdf0e10cSrcweir     case VCLEVENT_WINDOW_LOSEFOCUS:
644*cdf0e10cSrcweir //        fprintf(stderr, "got VCLEVENT_WINDOW_LOSEFOCUS for %p\n",
645*cdf0e10cSrcweir //            static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
646*cdf0e10cSrcweir         break;
647*cdf0e10cSrcweir     case VCLEVENT_WINDOW_MINIMIZE:
648*cdf0e10cSrcweir //        fprintf(stderr, "got VCLEVENT_WINDOW_MINIMIZE for %p\n",
649*cdf0e10cSrcweir //            static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
650*cdf0e10cSrcweir         break;
651*cdf0e10cSrcweir     case VCLEVENT_WINDOW_NORMALIZE:
652*cdf0e10cSrcweir //        fprintf(stderr, "got VCLEVENT_WINDOW_NORMALIZE for %p\n",
653*cdf0e10cSrcweir //            static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
654*cdf0e10cSrcweir         break;
655*cdf0e10cSrcweir     case VCLEVENT_WINDOW_KEYINPUT:
656*cdf0e10cSrcweir     case VCLEVENT_WINDOW_KEYUP:
657*cdf0e10cSrcweir     case VCLEVENT_WINDOW_COMMAND:
658*cdf0e10cSrcweir     case VCLEVENT_WINDOW_MOUSEMOVE:
659*cdf0e10cSrcweir         break;
660*cdf0e10cSrcweir  /*
661*cdf0e10cSrcweir         fprintf(stderr, "got VCLEVENT_WINDOW_COMMAND (%d) for %p\n",
662*cdf0e10cSrcweir             static_cast< ::CommandEvent const * > (
663*cdf0e10cSrcweir                 static_cast< ::VclWindowEvent const * >(pEvent)->GetData())->GetCommand(),
664*cdf0e10cSrcweir             static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
665*cdf0e10cSrcweir  */
666*cdf0e10cSrcweir     case VCLEVENT_MENU_HIGHLIGHT:
667*cdf0e10cSrcweir         if (const VclMenuEvent* pMenuEvent = dynamic_cast<const VclMenuEvent*>(pEvent))
668*cdf0e10cSrcweir         {
669*cdf0e10cSrcweir             handle_menu_highlighted(pMenuEvent);
670*cdf0e10cSrcweir         }
671*cdf0e10cSrcweir         else if (const VclAccessibleEvent* pAccEvent = dynamic_cast<const VclAccessibleEvent*>(pEvent))
672*cdf0e10cSrcweir         {
673*cdf0e10cSrcweir             uno::Reference< accessibility::XAccessible > xAccessible = pAccEvent->GetAccessible();
674*cdf0e10cSrcweir             if (xAccessible.is())
675*cdf0e10cSrcweir                 atk_wrapper_focus_tracker_notify_when_idle(xAccessible);
676*cdf0e10cSrcweir         }
677*cdf0e10cSrcweir         break;
678*cdf0e10cSrcweir 
679*cdf0e10cSrcweir     case VCLEVENT_TOOLBOX_HIGHLIGHT:
680*cdf0e10cSrcweir         handle_toolbox_highlight(static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
681*cdf0e10cSrcweir         break;
682*cdf0e10cSrcweir 
683*cdf0e10cSrcweir     case VCLEVENT_TOOLBOX_BUTTONSTATECHANGED:
684*cdf0e10cSrcweir         handle_toolbox_buttonchange(static_cast< ::VclWindowEvent const * >(pEvent));
685*cdf0e10cSrcweir         break;
686*cdf0e10cSrcweir 
687*cdf0e10cSrcweir     case VCLEVENT_OBJECT_DYING:
688*cdf0e10cSrcweir         g_aWindowList.erase( static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow() );
689*cdf0e10cSrcweir         // fallthrough intentional !
690*cdf0e10cSrcweir     case VCLEVENT_TOOLBOX_HIGHLIGHTOFF:
691*cdf0e10cSrcweir         handle_toolbox_highlightoff(static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
692*cdf0e10cSrcweir         break;
693*cdf0e10cSrcweir 
694*cdf0e10cSrcweir     case VCLEVENT_TABPAGE_ACTIVATE:
695*cdf0e10cSrcweir         handle_tabpage_activated(static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
696*cdf0e10cSrcweir         break;
697*cdf0e10cSrcweir 
698*cdf0e10cSrcweir     case VCLEVENT_COMBOBOX_SETTEXT:
699*cdf0e10cSrcweir         // MT 2010/02: This looks quite strange to me. Stumbled over this when fixing #i104290#.
700*cdf0e10cSrcweir         // This kicked in when leaving the combobox in the toolbar, after that the events worked.
701*cdf0e10cSrcweir         // I guess this was a try to work around missing combobox events, which didn't do the full job, and shouldn't be necessary anymore.
702*cdf0e10cSrcweir         // Fix for #i104290# was done in toolkit/source/awt/vclxaccessiblecomponent, FOCUSED state for compound controls in general.
703*cdf0e10cSrcweir         // create_wrapper_for_children(static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
704*cdf0e10cSrcweir         break;
705*cdf0e10cSrcweir 
706*cdf0e10cSrcweir     default:
707*cdf0e10cSrcweir //        OSL_TRACE("got event %d \n", pEvent->GetId());
708*cdf0e10cSrcweir         break;
709*cdf0e10cSrcweir     }
710*cdf0e10cSrcweir     return 0;
711*cdf0e10cSrcweir }
712*cdf0e10cSrcweir 
713*cdf0e10cSrcweir static Link g_aEventListenerLink( NULL, (PSTUB) WindowEventHandler );
714*cdf0e10cSrcweir 
715*cdf0e10cSrcweir /*****************************************************************************/
716*cdf0e10cSrcweir 
717*cdf0e10cSrcweir extern "C" {
718*cdf0e10cSrcweir 
719*cdf0e10cSrcweir static G_CONST_RETURN gchar *
720*cdf0e10cSrcweir ooo_atk_util_get_toolkit_name (void)
721*cdf0e10cSrcweir {
722*cdf0e10cSrcweir     return "VCL";
723*cdf0e10cSrcweir }
724*cdf0e10cSrcweir 
725*cdf0e10cSrcweir /*****************************************************************************/
726*cdf0e10cSrcweir 
727*cdf0e10cSrcweir static G_CONST_RETURN gchar *
728*cdf0e10cSrcweir ooo_atk_util_get_toolkit_version (void)
729*cdf0e10cSrcweir {
730*cdf0e10cSrcweir     /*
731*cdf0e10cSrcweir      * Version is passed in as a -D flag when this file is
732*cdf0e10cSrcweir      * compiled.
733*cdf0e10cSrcweir      */
734*cdf0e10cSrcweir 
735*cdf0e10cSrcweir     return VERSION;
736*cdf0e10cSrcweir }
737*cdf0e10cSrcweir 
738*cdf0e10cSrcweir /*****************************************************************************/
739*cdf0e10cSrcweir 
740*cdf0e10cSrcweir /*
741*cdf0e10cSrcweir  * GObject inheritance
742*cdf0e10cSrcweir  */
743*cdf0e10cSrcweir 
744*cdf0e10cSrcweir static void
745*cdf0e10cSrcweir ooo_atk_util_class_init (AtkUtilClass *)
746*cdf0e10cSrcweir {
747*cdf0e10cSrcweir     AtkUtilClass *atk_class;
748*cdf0e10cSrcweir     gpointer data;
749*cdf0e10cSrcweir 
750*cdf0e10cSrcweir     data = g_type_class_peek (ATK_TYPE_UTIL);
751*cdf0e10cSrcweir     atk_class = ATK_UTIL_CLASS (data);
752*cdf0e10cSrcweir 
753*cdf0e10cSrcweir     atk_class->get_toolkit_name = ooo_atk_util_get_toolkit_name;
754*cdf0e10cSrcweir     atk_class->get_toolkit_version = ooo_atk_util_get_toolkit_version;
755*cdf0e10cSrcweir 
756*cdf0e10cSrcweir     Application::AddEventListener( g_aEventListenerLink );
757*cdf0e10cSrcweir }
758*cdf0e10cSrcweir 
759*cdf0e10cSrcweir } // extern "C"
760*cdf0e10cSrcweir 
761*cdf0e10cSrcweir /*****************************************************************************/
762*cdf0e10cSrcweir 
763*cdf0e10cSrcweir GType
764*cdf0e10cSrcweir ooo_atk_util_get_type (void)
765*cdf0e10cSrcweir {
766*cdf0e10cSrcweir     static GType type = 0;
767*cdf0e10cSrcweir 
768*cdf0e10cSrcweir     if (!type)
769*cdf0e10cSrcweir     {
770*cdf0e10cSrcweir         GType parent_type = g_type_from_name( "GailUtil" );
771*cdf0e10cSrcweir 
772*cdf0e10cSrcweir         if( ! parent_type )
773*cdf0e10cSrcweir         {
774*cdf0e10cSrcweir             g_warning( "Unknown type: GailUtil" );
775*cdf0e10cSrcweir             parent_type = ATK_TYPE_UTIL;
776*cdf0e10cSrcweir         }
777*cdf0e10cSrcweir 
778*cdf0e10cSrcweir         GTypeQuery type_query;
779*cdf0e10cSrcweir         g_type_query( parent_type, &type_query );
780*cdf0e10cSrcweir 
781*cdf0e10cSrcweir         static const GTypeInfo typeInfo =
782*cdf0e10cSrcweir         {
783*cdf0e10cSrcweir             type_query.class_size,
784*cdf0e10cSrcweir             (GBaseInitFunc) NULL,
785*cdf0e10cSrcweir             (GBaseFinalizeFunc) NULL,
786*cdf0e10cSrcweir             (GClassInitFunc) ooo_atk_util_class_init,
787*cdf0e10cSrcweir             (GClassFinalizeFunc) NULL,
788*cdf0e10cSrcweir             NULL,
789*cdf0e10cSrcweir             type_query.instance_size,
790*cdf0e10cSrcweir             0,
791*cdf0e10cSrcweir             (GInstanceInitFunc) NULL,
792*cdf0e10cSrcweir             NULL
793*cdf0e10cSrcweir         } ;
794*cdf0e10cSrcweir 
795*cdf0e10cSrcweir         type = g_type_register_static (parent_type, "OOoUtil", &typeInfo, (GTypeFlags)0) ;
796*cdf0e10cSrcweir   }
797*cdf0e10cSrcweir 
798*cdf0e10cSrcweir   return type;
799*cdf0e10cSrcweir }
800*cdf0e10cSrcweir 
801*cdf0e10cSrcweir 
802