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