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