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