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