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