xref: /aoo41x/main/vcl/unx/gtk/a11y/atkutil.cxx (revision 9f62ea84)
1*9f62ea84SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*9f62ea84SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*9f62ea84SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*9f62ea84SAndrew Rist  * distributed with this work for additional information
6*9f62ea84SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*9f62ea84SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*9f62ea84SAndrew Rist  * "License"); you may not use this file except in compliance
9*9f62ea84SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*9f62ea84SAndrew Rist  *
11*9f62ea84SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*9f62ea84SAndrew Rist  *
13*9f62ea84SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*9f62ea84SAndrew Rist  * software distributed under the License is distributed on an
15*9f62ea84SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*9f62ea84SAndrew Rist  * KIND, either express or implied.  See the License for the
17*9f62ea84SAndrew Rist  * specific language governing permissions and limitations
18*9f62ea84SAndrew Rist  * under the License.
19*9f62ea84SAndrew Rist  *
20*9f62ea84SAndrew Rist  *************************************************************/
21*9f62ea84SAndrew Rist 
22*9f62ea84SAndrew 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
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
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 
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 
202cdf0e10cSrcweir void DocumentFocusListener::notifyEvent( const accessibility::AccessibleEventObject& aEvent )
203cdf0e10cSrcweir     throw( uno::RuntimeException )
204cdf0e10cSrcweir {
205cdf0e10cSrcweir     switch( aEvent.EventId )
206cdf0e10cSrcweir     {
207cdf0e10cSrcweir         case accessibility::AccessibleEventId::STATE_CHANGED:
208cdf0e10cSrcweir             try
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             catch(const lang::IndexOutOfBoundsException &e)
217cdf0e10cSrcweir             {
218cdf0e10cSrcweir                 g_warning("Focused object has invalid index in parent");
219cdf0e10cSrcweir             }
220cdf0e10cSrcweir             break;
221cdf0e10cSrcweir 
222cdf0e10cSrcweir         case accessibility::AccessibleEventId::CHILD:
223cdf0e10cSrcweir         {
224cdf0e10cSrcweir             uno::Reference< accessibility::XAccessible > xChild;
225cdf0e10cSrcweir             if( (aEvent.OldValue >>= xChild) && xChild.is() )
226cdf0e10cSrcweir                 detachRecursive(xChild);
227cdf0e10cSrcweir 
228cdf0e10cSrcweir             if( (aEvent.NewValue >>= xChild) && xChild.is() )
229cdf0e10cSrcweir                 attachRecursive(xChild);
230cdf0e10cSrcweir         }
231cdf0e10cSrcweir             break;
232cdf0e10cSrcweir 
233cdf0e10cSrcweir         case accessibility::AccessibleEventId::INVALIDATE_ALL_CHILDREN:
234cdf0e10cSrcweir /*        {
235cdf0e10cSrcweir             uno::Reference< accessibility::XAccessible > xAccessible( getAccessible(aEvent) );
236cdf0e10cSrcweir             detachRecursive(xAccessible);
237cdf0e10cSrcweir             attachRecursive(xAccessible);
238cdf0e10cSrcweir         }
239cdf0e10cSrcweir */
240cdf0e10cSrcweir             g_warning( "Invalidate all children called\n" );
241cdf0e10cSrcweir             break;
242cdf0e10cSrcweir         default:
243cdf0e10cSrcweir             break;
244cdf0e10cSrcweir     }
245cdf0e10cSrcweir }
246cdf0e10cSrcweir 
247cdf0e10cSrcweir /*****************************************************************************/
248cdf0e10cSrcweir 
249cdf0e10cSrcweir uno::Reference< accessibility::XAccessible > DocumentFocusListener::getAccessible(const lang::EventObject& aEvent )
250cdf0e10cSrcweir     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
251cdf0e10cSrcweir {
252cdf0e10cSrcweir     uno::Reference< accessibility::XAccessible > xAccessible(aEvent.Source, uno::UNO_QUERY);
253cdf0e10cSrcweir 
254cdf0e10cSrcweir     if( xAccessible.is() )
255cdf0e10cSrcweir         return xAccessible;
256cdf0e10cSrcweir 
257cdf0e10cSrcweir     uno::Reference< accessibility::XAccessibleContext > xContext(aEvent.Source, uno::UNO_QUERY);
258cdf0e10cSrcweir 
259cdf0e10cSrcweir     if( xContext.is() )
260cdf0e10cSrcweir     {
261cdf0e10cSrcweir         uno::Reference< accessibility::XAccessible > xParent( xContext->getAccessibleParent() );
262cdf0e10cSrcweir         if( xParent.is() )
263cdf0e10cSrcweir         {
264cdf0e10cSrcweir             uno::Reference< accessibility::XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
265cdf0e10cSrcweir             if( xParentContext.is() )
266cdf0e10cSrcweir             {
267cdf0e10cSrcweir                 return xParentContext->getAccessibleChild( xContext->getAccessibleIndexInParent() );
268cdf0e10cSrcweir             }
269cdf0e10cSrcweir         }
270cdf0e10cSrcweir     }
271cdf0e10cSrcweir 
272cdf0e10cSrcweir     return uno::Reference< accessibility::XAccessible >();
273cdf0e10cSrcweir }
274cdf0e10cSrcweir 
275cdf0e10cSrcweir /*****************************************************************************/
276cdf0e10cSrcweir 
277cdf0e10cSrcweir void DocumentFocusListener::attachRecursive(
278cdf0e10cSrcweir     const uno::Reference< accessibility::XAccessible >& xAccessible
279cdf0e10cSrcweir ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
280cdf0e10cSrcweir {
281cdf0e10cSrcweir     uno::Reference< accessibility::XAccessibleContext > xContext =
282cdf0e10cSrcweir         xAccessible->getAccessibleContext();
283cdf0e10cSrcweir 
284cdf0e10cSrcweir     if( xContext.is() )
285cdf0e10cSrcweir         attachRecursive(xAccessible, xContext);
286cdf0e10cSrcweir }
287cdf0e10cSrcweir 
288cdf0e10cSrcweir /*****************************************************************************/
289cdf0e10cSrcweir 
290cdf0e10cSrcweir void DocumentFocusListener::attachRecursive(
291cdf0e10cSrcweir     const uno::Reference< accessibility::XAccessible >& xAccessible,
292cdf0e10cSrcweir     const uno::Reference< accessibility::XAccessibleContext >& xContext
293cdf0e10cSrcweir )  throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
294cdf0e10cSrcweir {
295cdf0e10cSrcweir     uno::Reference< accessibility::XAccessibleStateSet > xStateSet =
296cdf0e10cSrcweir         xContext->getAccessibleStateSet();
297cdf0e10cSrcweir 
298cdf0e10cSrcweir     if( xStateSet.is() )
299cdf0e10cSrcweir         attachRecursive(xAccessible, xContext, xStateSet);
300cdf0e10cSrcweir }
301cdf0e10cSrcweir 
302cdf0e10cSrcweir /*****************************************************************************/
303cdf0e10cSrcweir 
304cdf0e10cSrcweir void DocumentFocusListener::attachRecursive(
305cdf0e10cSrcweir     const uno::Reference< accessibility::XAccessible >& xAccessible,
306cdf0e10cSrcweir     const uno::Reference< accessibility::XAccessibleContext >& xContext,
307cdf0e10cSrcweir     const uno::Reference< accessibility::XAccessibleStateSet >& xStateSet
308cdf0e10cSrcweir ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
309cdf0e10cSrcweir {
310cdf0e10cSrcweir     if( xStateSet->contains(accessibility::AccessibleStateType::FOCUSED ) )
311cdf0e10cSrcweir         atk_wrapper_focus_tracker_notify_when_idle( xAccessible );
312cdf0e10cSrcweir 
313cdf0e10cSrcweir     uno::Reference< accessibility::XAccessibleEventBroadcaster > xBroadcaster =
314cdf0e10cSrcweir         uno::Reference< accessibility::XAccessibleEventBroadcaster >(xContext, uno::UNO_QUERY);
315cdf0e10cSrcweir 
316cdf0e10cSrcweir     // If not already done, add the broadcaster to the list and attach as listener.
317cdf0e10cSrcweir     if( xBroadcaster.is() && m_aRefList.insert(xBroadcaster).second )
318cdf0e10cSrcweir     {
319cdf0e10cSrcweir         xBroadcaster->addEventListener(static_cast< accessibility::XAccessibleEventListener *>(this));
320cdf0e10cSrcweir 
321cdf0e10cSrcweir         if( ! xStateSet->contains(accessibility::AccessibleStateType::MANAGES_DESCENDANTS ) )
322cdf0e10cSrcweir         {
323cdf0e10cSrcweir             sal_Int32 n, nmax = xContext->getAccessibleChildCount();
324cdf0e10cSrcweir             for( n = 0; n < nmax; n++ )
325cdf0e10cSrcweir             {
326cdf0e10cSrcweir                 uno::Reference< accessibility::XAccessible > xChild( xContext->getAccessibleChild( n ) );
327cdf0e10cSrcweir 
328cdf0e10cSrcweir                 if( xChild.is() )
329cdf0e10cSrcweir                     attachRecursive(xChild);
330cdf0e10cSrcweir             }
331cdf0e10cSrcweir         }
332cdf0e10cSrcweir     }
333cdf0e10cSrcweir }
334cdf0e10cSrcweir 
335cdf0e10cSrcweir /*****************************************************************************/
336cdf0e10cSrcweir 
337cdf0e10cSrcweir void DocumentFocusListener::detachRecursive(
338cdf0e10cSrcweir     const uno::Reference< accessibility::XAccessible >& xAccessible
339cdf0e10cSrcweir ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
340cdf0e10cSrcweir {
341cdf0e10cSrcweir     uno::Reference< accessibility::XAccessibleContext > xContext =
342cdf0e10cSrcweir         xAccessible->getAccessibleContext();
343cdf0e10cSrcweir 
344cdf0e10cSrcweir     if( xContext.is() )
345cdf0e10cSrcweir         detachRecursive(xAccessible, xContext);
346cdf0e10cSrcweir }
347cdf0e10cSrcweir 
348cdf0e10cSrcweir /*****************************************************************************/
349cdf0e10cSrcweir 
350cdf0e10cSrcweir void DocumentFocusListener::detachRecursive(
351cdf0e10cSrcweir     const uno::Reference< accessibility::XAccessible >& xAccessible,
352cdf0e10cSrcweir     const uno::Reference< accessibility::XAccessibleContext >& xContext
353cdf0e10cSrcweir )  throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
354cdf0e10cSrcweir {
355cdf0e10cSrcweir     uno::Reference< accessibility::XAccessibleStateSet > xStateSet =
356cdf0e10cSrcweir         xContext->getAccessibleStateSet();
357cdf0e10cSrcweir 
358cdf0e10cSrcweir     if( xStateSet.is() )
359cdf0e10cSrcweir         detachRecursive(xAccessible, xContext, xStateSet);
360cdf0e10cSrcweir }
361cdf0e10cSrcweir 
362cdf0e10cSrcweir /*****************************************************************************/
363cdf0e10cSrcweir 
364cdf0e10cSrcweir void DocumentFocusListener::detachRecursive(
365cdf0e10cSrcweir     const uno::Reference< accessibility::XAccessible >&,
366cdf0e10cSrcweir     const uno::Reference< accessibility::XAccessibleContext >& xContext,
367cdf0e10cSrcweir     const uno::Reference< accessibility::XAccessibleStateSet >& xStateSet
368cdf0e10cSrcweir ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
369cdf0e10cSrcweir {
370cdf0e10cSrcweir     uno::Reference< accessibility::XAccessibleEventBroadcaster > xBroadcaster =
371cdf0e10cSrcweir         uno::Reference< accessibility::XAccessibleEventBroadcaster >(xContext, uno::UNO_QUERY);
372cdf0e10cSrcweir 
373cdf0e10cSrcweir     if( xBroadcaster.is() && 0 < m_aRefList.erase(xBroadcaster) )
374cdf0e10cSrcweir     {
375cdf0e10cSrcweir         xBroadcaster->removeEventListener(static_cast< accessibility::XAccessibleEventListener *>(this));
376cdf0e10cSrcweir 
377cdf0e10cSrcweir         if( ! xStateSet->contains(accessibility::AccessibleStateType::MANAGES_DESCENDANTS ) )
378cdf0e10cSrcweir         {
379cdf0e10cSrcweir             sal_Int32 n, nmax = xContext->getAccessibleChildCount();
380cdf0e10cSrcweir             for( n = 0; n < nmax; n++ )
381cdf0e10cSrcweir             {
382cdf0e10cSrcweir                 uno::Reference< accessibility::XAccessible > xChild( xContext->getAccessibleChild( n ) );
383cdf0e10cSrcweir 
384cdf0e10cSrcweir                 if( xChild.is() )
385cdf0e10cSrcweir                     detachRecursive(xChild);
386cdf0e10cSrcweir             }
387cdf0e10cSrcweir         }
388cdf0e10cSrcweir     }
389cdf0e10cSrcweir }
390cdf0e10cSrcweir 
391cdf0e10cSrcweir /*****************************************************************************/
392cdf0e10cSrcweir 
393cdf0e10cSrcweir /*
394cdf0e10cSrcweir  * page tabs in gtk are widgets, so we need to simulate focus events for those
395cdf0e10cSrcweir  */
396cdf0e10cSrcweir 
397cdf0e10cSrcweir static void handle_tabpage_activated(Window *pWindow)
398cdf0e10cSrcweir {
399cdf0e10cSrcweir     uno::Reference< accessibility::XAccessible > xAccessible =
400cdf0e10cSrcweir         pWindow->GetAccessible();
401cdf0e10cSrcweir 
402cdf0e10cSrcweir     if( ! xAccessible.is() )
403cdf0e10cSrcweir         return;
404cdf0e10cSrcweir 
405cdf0e10cSrcweir     uno::Reference< accessibility::XAccessibleSelection > xSelection(
406cdf0e10cSrcweir         xAccessible->getAccessibleContext(), uno::UNO_QUERY);
407cdf0e10cSrcweir 
408cdf0e10cSrcweir     if( xSelection.is() )
409cdf0e10cSrcweir         atk_wrapper_focus_tracker_notify_when_idle( xSelection->getSelectedAccessibleChild(0) );
410cdf0e10cSrcweir }
411cdf0e10cSrcweir 
412cdf0e10cSrcweir /*****************************************************************************/
413cdf0e10cSrcweir 
414cdf0e10cSrcweir /*
415cdf0e10cSrcweir  * toolbar items in gtk are widgets, so we need to simulate focus events for those
416cdf0e10cSrcweir  */
417cdf0e10cSrcweir 
418cdf0e10cSrcweir static void notify_toolbox_item_focus(ToolBox *pToolBox)
419cdf0e10cSrcweir {
420cdf0e10cSrcweir     uno::Reference< accessibility::XAccessible > xAccessible =
421cdf0e10cSrcweir         pToolBox->GetAccessible();
422cdf0e10cSrcweir 
423cdf0e10cSrcweir     if( ! xAccessible.is() )
424cdf0e10cSrcweir         return;
425cdf0e10cSrcweir 
426cdf0e10cSrcweir     uno::Reference< accessibility::XAccessibleContext > xContext =
427cdf0e10cSrcweir         xAccessible->getAccessibleContext();
428cdf0e10cSrcweir 
429cdf0e10cSrcweir     if( ! xContext.is() )
430cdf0e10cSrcweir         return;
431cdf0e10cSrcweir 
432cdf0e10cSrcweir     sal_Int32 nPos = pToolBox->GetItemPos( pToolBox->GetHighlightItemId() );
433cdf0e10cSrcweir     if( nPos != TOOLBOX_ITEM_NOTFOUND )
434cdf0e10cSrcweir         atk_wrapper_focus_tracker_notify_when_idle( xContext->getAccessibleChild( nPos ) );
435cdf0e10cSrcweir }
436cdf0e10cSrcweir 
437cdf0e10cSrcweir static void handle_toolbox_highlight(Window *pWindow)
438cdf0e10cSrcweir {
439cdf0e10cSrcweir     ToolBox *pToolBox = static_cast <ToolBox *> (pWindow);
440cdf0e10cSrcweir 
441cdf0e10cSrcweir     // Make sure either the toolbox or its parent toolbox has the focus
442cdf0e10cSrcweir     if ( ! pToolBox->HasFocus() )
443cdf0e10cSrcweir     {
444cdf0e10cSrcweir         ToolBox* pToolBoxParent = dynamic_cast< ToolBox* >( pToolBox->GetParent() );
445cdf0e10cSrcweir         if ( ! pToolBoxParent || ! pToolBoxParent->HasFocus() )
446cdf0e10cSrcweir             return;
447cdf0e10cSrcweir     }
448cdf0e10cSrcweir 
449cdf0e10cSrcweir     notify_toolbox_item_focus(pToolBox);
450cdf0e10cSrcweir }
451cdf0e10cSrcweir 
452cdf0e10cSrcweir static void handle_toolbox_highlightoff(Window *pWindow)
453cdf0e10cSrcweir {
454cdf0e10cSrcweir     ToolBox *pToolBox = static_cast <ToolBox *> (pWindow);
455cdf0e10cSrcweir     ToolBox* pToolBoxParent = dynamic_cast< ToolBox* >( pToolBox->GetParent() );
456cdf0e10cSrcweir 
457cdf0e10cSrcweir     // Notify when leaving sub toolboxes
458cdf0e10cSrcweir     if( pToolBoxParent && pToolBoxParent->HasFocus() )
459cdf0e10cSrcweir         notify_toolbox_item_focus( pToolBoxParent );
460cdf0e10cSrcweir }
461cdf0e10cSrcweir 
462cdf0e10cSrcweir /*****************************************************************************/
463cdf0e10cSrcweir 
464cdf0e10cSrcweir static void create_wrapper_for_child(
465cdf0e10cSrcweir     const uno::Reference< accessibility::XAccessibleContext >& xContext,
466cdf0e10cSrcweir     sal_Int32 index)
467cdf0e10cSrcweir {
468cdf0e10cSrcweir     if( xContext.is() )
469cdf0e10cSrcweir     {
470cdf0e10cSrcweir         uno::Reference< accessibility::XAccessible > xChild(xContext->getAccessibleChild(index));
471cdf0e10cSrcweir         if( xChild.is() )
472cdf0e10cSrcweir         {
473cdf0e10cSrcweir             // create the wrapper object - it will survive the unref unless it is a transient object
474cdf0e10cSrcweir             g_object_unref( atk_object_wrapper_ref( xChild ) );
475cdf0e10cSrcweir         }
476cdf0e10cSrcweir     }
477cdf0e10cSrcweir }
478cdf0e10cSrcweir 
479cdf0e10cSrcweir /*****************************************************************************/
480cdf0e10cSrcweir 
481cdf0e10cSrcweir static void handle_toolbox_buttonchange(VclWindowEvent const *pEvent)
482cdf0e10cSrcweir {
483cdf0e10cSrcweir     Window* pWindow = pEvent->GetWindow();
484cdf0e10cSrcweir     sal_Int32 index = (sal_Int32)(sal_IntPtr) pEvent->GetData();
485cdf0e10cSrcweir 
486cdf0e10cSrcweir     if( pWindow && pWindow->IsReallyVisible() )
487cdf0e10cSrcweir     {
488cdf0e10cSrcweir         uno::Reference< accessibility::XAccessible > xAccessible(pWindow->GetAccessible());
489cdf0e10cSrcweir         if( xAccessible.is() )
490cdf0e10cSrcweir         {
491cdf0e10cSrcweir             create_wrapper_for_child(xAccessible->getAccessibleContext(), index);
492cdf0e10cSrcweir         }
493cdf0e10cSrcweir     }
494cdf0e10cSrcweir }
495cdf0e10cSrcweir 
496cdf0e10cSrcweir /*****************************************************************************/
497cdf0e10cSrcweir 
498cdf0e10cSrcweir /* currently not needed anymore...
499cdf0e10cSrcweir static void create_wrapper_for_children(Window *pWindow)
500cdf0e10cSrcweir {
501cdf0e10cSrcweir     if( pWindow && pWindow->IsReallyVisible() )
502cdf0e10cSrcweir     {
503cdf0e10cSrcweir         uno::Reference< accessibility::XAccessible > xAccessible(pWindow->GetAccessible());
504cdf0e10cSrcweir         if( xAccessible.is() )
505cdf0e10cSrcweir         {
506cdf0e10cSrcweir             uno::Reference< accessibility::XAccessibleContext > xContext(xAccessible->getAccessibleContext());
507cdf0e10cSrcweir             if( xContext.is() )
508cdf0e10cSrcweir             {
509cdf0e10cSrcweir                 sal_Int32 nChildren = xContext->getAccessibleChildCount();
510cdf0e10cSrcweir                 for( sal_Int32 i = 0; i < nChildren; ++i )
511cdf0e10cSrcweir                     create_wrapper_for_child(xContext, i);
512cdf0e10cSrcweir             }
513cdf0e10cSrcweir         }
514cdf0e10cSrcweir     }
515cdf0e10cSrcweir }
516cdf0e10cSrcweir */
517cdf0e10cSrcweir 
518cdf0e10cSrcweir /*****************************************************************************/
519cdf0e10cSrcweir 
520cdf0e10cSrcweir static std::set< Window * > g_aWindowList;
521cdf0e10cSrcweir 
522cdf0e10cSrcweir static void handle_get_focus(::VclWindowEvent const * pEvent)
523cdf0e10cSrcweir {
524cdf0e10cSrcweir     static rtl::Reference< DocumentFocusListener > aDocumentFocusListener =
525cdf0e10cSrcweir         new DocumentFocusListener();
526cdf0e10cSrcweir 
527cdf0e10cSrcweir     Window *pWindow = pEvent->GetWindow();
528cdf0e10cSrcweir 
529cdf0e10cSrcweir     // The menu bar is handled through VCLEVENT_MENU_HIGHLIGHTED
530cdf0e10cSrcweir     if( ! pWindow || !pWindow->IsReallyVisible() || pWindow->GetType() == WINDOW_MENUBARWINDOW )
531cdf0e10cSrcweir         return;
532cdf0e10cSrcweir 
533cdf0e10cSrcweir     // ToolBoxes are handled through VCLEVENT_TOOLBOX_HIGHLIGHT
534cdf0e10cSrcweir     if( pWindow->GetType() == WINDOW_TOOLBOX )
535cdf0e10cSrcweir         return;
536cdf0e10cSrcweir 
537cdf0e10cSrcweir     if( pWindow->GetType() == WINDOW_TABCONTROL )
538cdf0e10cSrcweir     {
539cdf0e10cSrcweir         handle_tabpage_activated( pWindow );
540cdf0e10cSrcweir         return;
541cdf0e10cSrcweir     }
542cdf0e10cSrcweir 
543cdf0e10cSrcweir     uno::Reference< accessibility::XAccessible > xAccessible =
544cdf0e10cSrcweir         pWindow->GetAccessible();
545cdf0e10cSrcweir 
546cdf0e10cSrcweir     if( ! xAccessible.is() )
547cdf0e10cSrcweir         return;
548cdf0e10cSrcweir 
549cdf0e10cSrcweir     uno::Reference< accessibility::XAccessibleContext > xContext =
550cdf0e10cSrcweir         xAccessible->getAccessibleContext();
551cdf0e10cSrcweir 
552cdf0e10cSrcweir     if( ! xContext.is() )
553cdf0e10cSrcweir         return;
554cdf0e10cSrcweir 
555cdf0e10cSrcweir     uno::Reference< accessibility::XAccessibleStateSet > xStateSet =
556cdf0e10cSrcweir         xContext->getAccessibleStateSet();
557cdf0e10cSrcweir 
558cdf0e10cSrcweir     if( ! xStateSet.is() )
559cdf0e10cSrcweir         return;
560cdf0e10cSrcweir 
561cdf0e10cSrcweir /* the UNO ToolBox wrapper does not (yet?) support XAccessibleSelection, so we
562cdf0e10cSrcweir  * need to add listeners to the children instead of re-using the tabpage stuff
563cdf0e10cSrcweir  */
564cdf0e10cSrcweir     if( xStateSet->contains(accessibility::AccessibleStateType::FOCUSED) &&
565cdf0e10cSrcweir         ( pWindow->GetType() != WINDOW_TREELISTBOX ) )
566cdf0e10cSrcweir     {
567cdf0e10cSrcweir         atk_wrapper_focus_tracker_notify_when_idle( xAccessible );
568cdf0e10cSrcweir     }
569cdf0e10cSrcweir     else
570cdf0e10cSrcweir     {
571cdf0e10cSrcweir         if( g_aWindowList.find(pWindow) == g_aWindowList.end() )
572cdf0e10cSrcweir         {
573cdf0e10cSrcweir             g_aWindowList.insert(pWindow);
574cdf0e10cSrcweir             try
575cdf0e10cSrcweir             {
576cdf0e10cSrcweir                 aDocumentFocusListener->attachRecursive(xAccessible, xContext, xStateSet);
577cdf0e10cSrcweir             }
578cdf0e10cSrcweir             catch( const uno::Exception &e )
579cdf0e10cSrcweir             {
580cdf0e10cSrcweir                 g_warning( "Exception caught processing focus events" );
581cdf0e10cSrcweir             }
582cdf0e10cSrcweir         }
583cdf0e10cSrcweir #ifdef ENABLE_TRACING
584cdf0e10cSrcweir         else
585cdf0e10cSrcweir             fprintf(stderr, "Window %p already in the list\n", pWindow );
586cdf0e10cSrcweir #endif
587cdf0e10cSrcweir     }
588cdf0e10cSrcweir }
589cdf0e10cSrcweir 
590cdf0e10cSrcweir /*****************************************************************************/
591cdf0e10cSrcweir 
592cdf0e10cSrcweir static void handle_menu_highlighted(::VclMenuEvent const * pEvent)
593cdf0e10cSrcweir {
594cdf0e10cSrcweir     try
595cdf0e10cSrcweir     {
596cdf0e10cSrcweir         Menu* pMenu = pEvent->GetMenu();
597cdf0e10cSrcweir         sal_uInt16 nPos = pEvent->GetItemPos();
598cdf0e10cSrcweir 
599cdf0e10cSrcweir         if( pMenu &&  nPos != 0xFFFF)
600cdf0e10cSrcweir         {
601cdf0e10cSrcweir             uno::Reference< accessibility::XAccessible > xAccessible ( pMenu->GetAccessible() );
602cdf0e10cSrcweir 
603cdf0e10cSrcweir             if( xAccessible.is() )
604cdf0e10cSrcweir             {
605cdf0e10cSrcweir                 uno::Reference< accessibility::XAccessibleContext > xContext ( xAccessible->getAccessibleContext() );
606cdf0e10cSrcweir 
607cdf0e10cSrcweir                 if( xContext.is() )
608cdf0e10cSrcweir                     atk_wrapper_focus_tracker_notify_when_idle( xContext->getAccessibleChild( nPos ) );
609cdf0e10cSrcweir             }
610cdf0e10cSrcweir         }
611cdf0e10cSrcweir     }
612cdf0e10cSrcweir     catch( const uno::Exception& e )
613cdf0e10cSrcweir     {
614cdf0e10cSrcweir         g_warning( "Exception caught processing menu highlight events" );
615cdf0e10cSrcweir     }
616cdf0e10cSrcweir }
617cdf0e10cSrcweir 
618cdf0e10cSrcweir /*****************************************************************************/
619cdf0e10cSrcweir 
620cdf0e10cSrcweir long WindowEventHandler(void *, ::VclSimpleEvent const * pEvent)
621cdf0e10cSrcweir {
622cdf0e10cSrcweir     switch (pEvent->GetId())
623cdf0e10cSrcweir     {
624cdf0e10cSrcweir     case VCLEVENT_WINDOW_SHOW:
625cdf0e10cSrcweir //        fprintf(stderr, "got VCLEVENT_WINDOW_SHOW for %p\n",
626cdf0e10cSrcweir //            static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
627cdf0e10cSrcweir         break;
628cdf0e10cSrcweir     case VCLEVENT_WINDOW_HIDE:
629cdf0e10cSrcweir //        fprintf(stderr, "got VCLEVENT_WINDOW_HIDE for %p\n",
630cdf0e10cSrcweir //            static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
631cdf0e10cSrcweir         break;
632cdf0e10cSrcweir     case VCLEVENT_WINDOW_CLOSE:
633cdf0e10cSrcweir //        fprintf(stderr, "got VCLEVENT_WINDOW_CLOSE for %p\n",
634cdf0e10cSrcweir //            static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
635cdf0e10cSrcweir         break;
636cdf0e10cSrcweir     case VCLEVENT_WINDOW_GETFOCUS:
637cdf0e10cSrcweir         handle_get_focus(static_cast< ::VclWindowEvent const * >(pEvent));
638cdf0e10cSrcweir         break;
639cdf0e10cSrcweir     case VCLEVENT_WINDOW_LOSEFOCUS:
640cdf0e10cSrcweir //        fprintf(stderr, "got VCLEVENT_WINDOW_LOSEFOCUS for %p\n",
641cdf0e10cSrcweir //            static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
642cdf0e10cSrcweir         break;
643cdf0e10cSrcweir     case VCLEVENT_WINDOW_MINIMIZE:
644cdf0e10cSrcweir //        fprintf(stderr, "got VCLEVENT_WINDOW_MINIMIZE for %p\n",
645cdf0e10cSrcweir //            static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
646cdf0e10cSrcweir         break;
647cdf0e10cSrcweir     case VCLEVENT_WINDOW_NORMALIZE:
648cdf0e10cSrcweir //        fprintf(stderr, "got VCLEVENT_WINDOW_NORMALIZE for %p\n",
649cdf0e10cSrcweir //            static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
650cdf0e10cSrcweir         break;
651cdf0e10cSrcweir     case VCLEVENT_WINDOW_KEYINPUT:
652cdf0e10cSrcweir     case VCLEVENT_WINDOW_KEYUP:
653cdf0e10cSrcweir     case VCLEVENT_WINDOW_COMMAND:
654cdf0e10cSrcweir     case VCLEVENT_WINDOW_MOUSEMOVE:
655cdf0e10cSrcweir         break;
656cdf0e10cSrcweir  /*
657cdf0e10cSrcweir         fprintf(stderr, "got VCLEVENT_WINDOW_COMMAND (%d) for %p\n",
658cdf0e10cSrcweir             static_cast< ::CommandEvent const * > (
659cdf0e10cSrcweir                 static_cast< ::VclWindowEvent const * >(pEvent)->GetData())->GetCommand(),
660cdf0e10cSrcweir             static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
661cdf0e10cSrcweir  */
662cdf0e10cSrcweir     case VCLEVENT_MENU_HIGHLIGHT:
663cdf0e10cSrcweir         if (const VclMenuEvent* pMenuEvent = dynamic_cast<const VclMenuEvent*>(pEvent))
664cdf0e10cSrcweir         {
665cdf0e10cSrcweir             handle_menu_highlighted(pMenuEvent);
666cdf0e10cSrcweir         }
667cdf0e10cSrcweir         else if (const VclAccessibleEvent* pAccEvent = dynamic_cast<const VclAccessibleEvent*>(pEvent))
668cdf0e10cSrcweir         {
669cdf0e10cSrcweir             uno::Reference< accessibility::XAccessible > xAccessible = pAccEvent->GetAccessible();
670cdf0e10cSrcweir             if (xAccessible.is())
671cdf0e10cSrcweir                 atk_wrapper_focus_tracker_notify_when_idle(xAccessible);
672cdf0e10cSrcweir         }
673cdf0e10cSrcweir         break;
674cdf0e10cSrcweir 
675cdf0e10cSrcweir     case VCLEVENT_TOOLBOX_HIGHLIGHT:
676cdf0e10cSrcweir         handle_toolbox_highlight(static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
677cdf0e10cSrcweir         break;
678cdf0e10cSrcweir 
679cdf0e10cSrcweir     case VCLEVENT_TOOLBOX_BUTTONSTATECHANGED:
680cdf0e10cSrcweir         handle_toolbox_buttonchange(static_cast< ::VclWindowEvent const * >(pEvent));
681cdf0e10cSrcweir         break;
682cdf0e10cSrcweir 
683cdf0e10cSrcweir     case VCLEVENT_OBJECT_DYING:
684cdf0e10cSrcweir         g_aWindowList.erase( static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow() );
685cdf0e10cSrcweir         // fallthrough intentional !
686cdf0e10cSrcweir     case VCLEVENT_TOOLBOX_HIGHLIGHTOFF:
687cdf0e10cSrcweir         handle_toolbox_highlightoff(static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
688cdf0e10cSrcweir         break;
689cdf0e10cSrcweir 
690cdf0e10cSrcweir     case VCLEVENT_TABPAGE_ACTIVATE:
691cdf0e10cSrcweir         handle_tabpage_activated(static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
692cdf0e10cSrcweir         break;
693cdf0e10cSrcweir 
694cdf0e10cSrcweir     case VCLEVENT_COMBOBOX_SETTEXT:
695cdf0e10cSrcweir         // MT 2010/02: This looks quite strange to me. Stumbled over this when fixing #i104290#.
696cdf0e10cSrcweir         // This kicked in when leaving the combobox in the toolbar, after that the events worked.
697cdf0e10cSrcweir         // 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.
698cdf0e10cSrcweir         // Fix for #i104290# was done in toolkit/source/awt/vclxaccessiblecomponent, FOCUSED state for compound controls in general.
699cdf0e10cSrcweir         // create_wrapper_for_children(static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
700cdf0e10cSrcweir         break;
701cdf0e10cSrcweir 
702cdf0e10cSrcweir     default:
703cdf0e10cSrcweir //        OSL_TRACE("got event %d \n", pEvent->GetId());
704cdf0e10cSrcweir         break;
705cdf0e10cSrcweir     }
706cdf0e10cSrcweir     return 0;
707cdf0e10cSrcweir }
708cdf0e10cSrcweir 
709cdf0e10cSrcweir static Link g_aEventListenerLink( NULL, (PSTUB) WindowEventHandler );
710cdf0e10cSrcweir 
711cdf0e10cSrcweir /*****************************************************************************/
712cdf0e10cSrcweir 
713cdf0e10cSrcweir extern "C" {
714cdf0e10cSrcweir 
715cdf0e10cSrcweir static G_CONST_RETURN gchar *
716cdf0e10cSrcweir ooo_atk_util_get_toolkit_name (void)
717cdf0e10cSrcweir {
718cdf0e10cSrcweir     return "VCL";
719cdf0e10cSrcweir }
720cdf0e10cSrcweir 
721cdf0e10cSrcweir /*****************************************************************************/
722cdf0e10cSrcweir 
723cdf0e10cSrcweir static G_CONST_RETURN gchar *
724cdf0e10cSrcweir ooo_atk_util_get_toolkit_version (void)
725cdf0e10cSrcweir {
726cdf0e10cSrcweir     /*
727cdf0e10cSrcweir      * Version is passed in as a -D flag when this file is
728cdf0e10cSrcweir      * compiled.
729cdf0e10cSrcweir      */
730cdf0e10cSrcweir 
731cdf0e10cSrcweir     return VERSION;
732cdf0e10cSrcweir }
733cdf0e10cSrcweir 
734cdf0e10cSrcweir /*****************************************************************************/
735cdf0e10cSrcweir 
736cdf0e10cSrcweir /*
737cdf0e10cSrcweir  * GObject inheritance
738cdf0e10cSrcweir  */
739cdf0e10cSrcweir 
740cdf0e10cSrcweir static void
741cdf0e10cSrcweir ooo_atk_util_class_init (AtkUtilClass *)
742cdf0e10cSrcweir {
743cdf0e10cSrcweir     AtkUtilClass *atk_class;
744cdf0e10cSrcweir     gpointer data;
745cdf0e10cSrcweir 
746cdf0e10cSrcweir     data = g_type_class_peek (ATK_TYPE_UTIL);
747cdf0e10cSrcweir     atk_class = ATK_UTIL_CLASS (data);
748cdf0e10cSrcweir 
749cdf0e10cSrcweir     atk_class->get_toolkit_name = ooo_atk_util_get_toolkit_name;
750cdf0e10cSrcweir     atk_class->get_toolkit_version = ooo_atk_util_get_toolkit_version;
751cdf0e10cSrcweir 
752cdf0e10cSrcweir     Application::AddEventListener( g_aEventListenerLink );
753cdf0e10cSrcweir }
754cdf0e10cSrcweir 
755cdf0e10cSrcweir } // extern "C"
756cdf0e10cSrcweir 
757cdf0e10cSrcweir /*****************************************************************************/
758cdf0e10cSrcweir 
759cdf0e10cSrcweir GType
760cdf0e10cSrcweir ooo_atk_util_get_type (void)
761cdf0e10cSrcweir {
762cdf0e10cSrcweir     static GType type = 0;
763cdf0e10cSrcweir 
764cdf0e10cSrcweir     if (!type)
765cdf0e10cSrcweir     {
766cdf0e10cSrcweir         GType parent_type = g_type_from_name( "GailUtil" );
767cdf0e10cSrcweir 
768cdf0e10cSrcweir         if( ! parent_type )
769cdf0e10cSrcweir         {
770cdf0e10cSrcweir             g_warning( "Unknown type: GailUtil" );
771cdf0e10cSrcweir             parent_type = ATK_TYPE_UTIL;
772cdf0e10cSrcweir         }
773cdf0e10cSrcweir 
774cdf0e10cSrcweir         GTypeQuery type_query;
775cdf0e10cSrcweir         g_type_query( parent_type, &type_query );
776cdf0e10cSrcweir 
777cdf0e10cSrcweir         static const GTypeInfo typeInfo =
778cdf0e10cSrcweir         {
779cdf0e10cSrcweir             type_query.class_size,
780cdf0e10cSrcweir             (GBaseInitFunc) NULL,
781cdf0e10cSrcweir             (GBaseFinalizeFunc) NULL,
782cdf0e10cSrcweir             (GClassInitFunc) ooo_atk_util_class_init,
783cdf0e10cSrcweir             (GClassFinalizeFunc) NULL,
784cdf0e10cSrcweir             NULL,
785cdf0e10cSrcweir             type_query.instance_size,
786cdf0e10cSrcweir             0,
787cdf0e10cSrcweir             (GInstanceInitFunc) NULL,
788cdf0e10cSrcweir             NULL
789cdf0e10cSrcweir         } ;
790cdf0e10cSrcweir 
791cdf0e10cSrcweir         type = g_type_register_static (parent_type, "OOoUtil", &typeInfo, (GTypeFlags)0) ;
792cdf0e10cSrcweir   }
793cdf0e10cSrcweir 
794cdf0e10cSrcweir   return type;
795cdf0e10cSrcweir }
796cdf0e10cSrcweir 
797cdf0e10cSrcweir 
798