summaryrefslogtreecommitdiff
path: root/vcl/unx/gtk/a11y/atkutil.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/unx/gtk/a11y/atkutil.cxx')
-rw-r--r--vcl/unx/gtk/a11y/atkutil.cxx801
1 files changed, 801 insertions, 0 deletions
diff --git a/vcl/unx/gtk/a11y/atkutil.cxx b/vcl/unx/gtk/a11y/atkutil.cxx
new file mode 100644
index 000000000000..076e36291ae6
--- /dev/null
+++ b/vcl/unx/gtk/a11y/atkutil.cxx
@@ -0,0 +1,801 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_vcl.hxx"
+
+#include <com/sun/star/accessibility/XAccessibleContext.hpp>
+#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
+#include <com/sun/star/accessibility/XAccessibleSelection.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+// --> OD 2009-04-14 #i93269#
+#include <com/sun/star/accessibility/XAccessibleText.hpp>
+// <--
+#include <cppuhelper/implbase1.hxx>
+#include <vos/mutex.hxx>
+#include <rtl/ref.hxx>
+
+#include <vcl/svapp.hxx>
+#include <vcl/window.hxx>
+#include <vcl/menu.hxx>
+#include <vcl/toolbox.hxx>
+
+#include "atkwrapper.hxx"
+#include "atkutil.hxx"
+
+#include <gtk/gtk.h>
+
+#include <set>
+
+// #define ENABLE_TRACING
+
+#ifdef ENABLE_TRACING
+#include <stdio.h>
+#endif
+
+using namespace ::com::sun::star;
+
+static uno::WeakReference< accessibility::XAccessible > xNextFocusObject;
+static guint focus_notify_handler = 0;
+
+/*****************************************************************************/
+
+extern "C" {
+
+static gint
+atk_wrapper_focus_idle_handler (gpointer data)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ focus_notify_handler = 0;
+
+ uno::Reference< accessibility::XAccessible > xAccessible = xNextFocusObject;
+ if( xAccessible.get() == reinterpret_cast < accessibility::XAccessible * > (data) )
+ {
+ AtkObject *atk_obj = xAccessible.is() ? atk_object_wrapper_ref( xAccessible ) : NULL;
+ // Gail does not notify focus changes to NULL, so do we ..
+ if( atk_obj )
+ {
+#ifdef ENABLE_TRACING
+ fprintf(stderr, "notifying focus event for %p\n", atk_obj);
+#endif
+ atk_focus_tracker_notify(atk_obj);
+ // --> OD 2009-04-14 #i93269#
+ // emit text_caret_moved event for <XAccessibleText> object,
+ // if cursor is inside the <XAccessibleText> object.
+ // also emit state-changed:focused event under the same condition.
+ {
+ AtkObjectWrapper* wrapper_obj = ATK_OBJECT_WRAPPER (atk_obj);
+ if( wrapper_obj && !wrapper_obj->mpText && wrapper_obj->mpContext )
+ {
+ uno::Any any = wrapper_obj->mpContext->queryInterface( accessibility::XAccessibleText::static_type(NULL) );
+ if ( typelib_TypeClass_INTERFACE == any.pType->eTypeClass &&
+ any.pReserved != 0 )
+ {
+ wrapper_obj->mpText = reinterpret_cast< accessibility::XAccessibleText * > (any.pReserved);
+ if ( wrapper_obj->mpText != 0 )
+ {
+ wrapper_obj->mpText->acquire();
+ gint caretPos = wrapper_obj->mpText->getCaretPosition();
+
+ if ( caretPos != -1 )
+ {
+ atk_object_notify_state_change( atk_obj, ATK_STATE_FOCUSED, TRUE );
+ g_signal_emit_by_name( atk_obj, "text_caret_moved", caretPos );
+ }
+ }
+ }
+ }
+ }
+ // <--
+ g_object_unref(atk_obj);
+ }
+ }
+
+ return FALSE;
+}
+
+} // extern "C"
+
+/*****************************************************************************/
+
+static void
+atk_wrapper_focus_tracker_notify_when_idle( const uno::Reference< accessibility::XAccessible > &xAccessible )
+{
+ if( focus_notify_handler )
+ g_source_remove(focus_notify_handler);
+
+ xNextFocusObject = xAccessible;
+
+ focus_notify_handler = g_idle_add (atk_wrapper_focus_idle_handler, xAccessible.get());
+}
+
+/*****************************************************************************/
+
+class DocumentFocusListener :
+ public ::cppu::WeakImplHelper1< accessibility::XAccessibleEventListener >
+{
+
+ std::set< uno::Reference< uno::XInterface > > m_aRefList;
+
+public:
+ void attachRecursive(
+ const uno::Reference< accessibility::XAccessible >& xAccessible
+ ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException);
+
+ void attachRecursive(
+ const uno::Reference< accessibility::XAccessible >& xAccessible,
+ const uno::Reference< accessibility::XAccessibleContext >& xContext
+ ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException);
+
+ void attachRecursive(
+ const uno::Reference< accessibility::XAccessible >& xAccessible,
+ const uno::Reference< accessibility::XAccessibleContext >& xContext,
+ const uno::Reference< accessibility::XAccessibleStateSet >& xStateSet
+ ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException);
+
+ void detachRecursive(
+ const uno::Reference< accessibility::XAccessible >& xAccessible
+ ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException);
+
+ void detachRecursive(
+ const uno::Reference< accessibility::XAccessible >& xAccessible,
+ const uno::Reference< accessibility::XAccessibleContext >& xContext
+ ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException);
+
+ void detachRecursive(
+ const uno::Reference< accessibility::XAccessible >& xAccessible,
+ const uno::Reference< accessibility::XAccessibleContext >& xContext,
+ const uno::Reference< accessibility::XAccessibleStateSet >& xStateSet
+ ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException);
+
+ static uno::Reference< accessibility::XAccessible > getAccessible(const lang::EventObject& aEvent )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException);
+
+ // XEventListener
+ virtual void disposing( const lang::EventObject& Source ) throw (uno::RuntimeException);
+
+ // XAccessibleEventListener
+ virtual void notifyEvent( const accessibility::AccessibleEventObject& aEvent ) throw( uno::RuntimeException );
+};
+
+/*****************************************************************************/
+
+void DocumentFocusListener::disposing( const lang::EventObject& aEvent )
+ throw (uno::RuntimeException)
+{
+// fprintf(stderr, "In DocumentFocusListener::disposing (%p)\n", this);
+// fprintf(stderr, "m_aRefList has %d entries\n", m_aRefList.size());
+
+ // Unref the object here, but do not remove as listener since the object
+ // might no longer be in a state that safely allows this.
+ if( aEvent.Source.is() )
+ m_aRefList.erase(aEvent.Source);
+
+// fprintf(stderr, "m_aRefList has %d entries\n", m_aRefList.size());
+
+}
+
+/*****************************************************************************/
+
+void DocumentFocusListener::notifyEvent( const accessibility::AccessibleEventObject& aEvent )
+ throw( uno::RuntimeException )
+{
+ switch( aEvent.EventId )
+ {
+ case accessibility::AccessibleEventId::STATE_CHANGED:
+ try
+ {
+ sal_Int16 nState = accessibility::AccessibleStateType::INVALID;
+ aEvent.NewValue >>= nState;
+
+ if( accessibility::AccessibleStateType::FOCUSED == nState )
+ atk_wrapper_focus_tracker_notify_when_idle( getAccessible(aEvent) );
+ }
+ catch(const lang::IndexOutOfBoundsException &e)
+ {
+ g_warning("Focused object has invalid index in parent");
+ }
+ break;
+
+ case accessibility::AccessibleEventId::CHILD:
+ {
+ uno::Reference< accessibility::XAccessible > xChild;
+ if( (aEvent.OldValue >>= xChild) && xChild.is() )
+ detachRecursive(xChild);
+
+ if( (aEvent.NewValue >>= xChild) && xChild.is() )
+ attachRecursive(xChild);
+ }
+ break;
+
+ case accessibility::AccessibleEventId::INVALIDATE_ALL_CHILDREN:
+/* {
+ uno::Reference< accessibility::XAccessible > xAccessible( getAccessible(aEvent) );
+ detachRecursive(xAccessible);
+ attachRecursive(xAccessible);
+ }
+*/
+ g_warning( "Invalidate all children called\n" );
+ break;
+ default:
+ break;
+ }
+}
+
+/*****************************************************************************/
+
+uno::Reference< accessibility::XAccessible > DocumentFocusListener::getAccessible(const lang::EventObject& aEvent )
+ throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ uno::Reference< accessibility::XAccessible > xAccessible(aEvent.Source, uno::UNO_QUERY);
+
+ if( xAccessible.is() )
+ return xAccessible;
+
+ uno::Reference< accessibility::XAccessibleContext > xContext(aEvent.Source, uno::UNO_QUERY);
+
+ if( xContext.is() )
+ {
+ uno::Reference< accessibility::XAccessible > xParent( xContext->getAccessibleParent() );
+ if( xParent.is() )
+ {
+ uno::Reference< accessibility::XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
+ if( xParentContext.is() )
+ {
+ return xParentContext->getAccessibleChild( xContext->getAccessibleIndexInParent() );
+ }
+ }
+ }
+
+ return uno::Reference< accessibility::XAccessible >();
+}
+
+/*****************************************************************************/
+
+void DocumentFocusListener::attachRecursive(
+ const uno::Reference< accessibility::XAccessible >& xAccessible
+) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ uno::Reference< accessibility::XAccessibleContext > xContext =
+ xAccessible->getAccessibleContext();
+
+ if( xContext.is() )
+ attachRecursive(xAccessible, xContext);
+}
+
+/*****************************************************************************/
+
+void DocumentFocusListener::attachRecursive(
+ const uno::Reference< accessibility::XAccessible >& xAccessible,
+ const uno::Reference< accessibility::XAccessibleContext >& xContext
+) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ uno::Reference< accessibility::XAccessibleStateSet > xStateSet =
+ xContext->getAccessibleStateSet();
+
+ if( xStateSet.is() )
+ attachRecursive(xAccessible, xContext, xStateSet);
+}
+
+/*****************************************************************************/
+
+void DocumentFocusListener::attachRecursive(
+ const uno::Reference< accessibility::XAccessible >& xAccessible,
+ const uno::Reference< accessibility::XAccessibleContext >& xContext,
+ const uno::Reference< accessibility::XAccessibleStateSet >& xStateSet
+) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ if( xStateSet->contains(accessibility::AccessibleStateType::FOCUSED ) )
+ atk_wrapper_focus_tracker_notify_when_idle( xAccessible );
+
+ uno::Reference< accessibility::XAccessibleEventBroadcaster > xBroadcaster =
+ uno::Reference< accessibility::XAccessibleEventBroadcaster >(xContext, uno::UNO_QUERY);
+
+ // If not already done, add the broadcaster to the list and attach as listener.
+ if( xBroadcaster.is() && m_aRefList.insert(xBroadcaster).second )
+ {
+ xBroadcaster->addEventListener(static_cast< accessibility::XAccessibleEventListener *>(this));
+
+ if( ! xStateSet->contains(accessibility::AccessibleStateType::MANAGES_DESCENDANTS ) )
+ {
+ sal_Int32 n, nmax = xContext->getAccessibleChildCount();
+ for( n = 0; n < nmax; n++ )
+ {
+ uno::Reference< accessibility::XAccessible > xChild( xContext->getAccessibleChild( n ) );
+
+ if( xChild.is() )
+ attachRecursive(xChild);
+ }
+ }
+ }
+}
+
+/*****************************************************************************/
+
+void DocumentFocusListener::detachRecursive(
+ const uno::Reference< accessibility::XAccessible >& xAccessible
+) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ uno::Reference< accessibility::XAccessibleContext > xContext =
+ xAccessible->getAccessibleContext();
+
+ if( xContext.is() )
+ detachRecursive(xAccessible, xContext);
+}
+
+/*****************************************************************************/
+
+void DocumentFocusListener::detachRecursive(
+ const uno::Reference< accessibility::XAccessible >& xAccessible,
+ const uno::Reference< accessibility::XAccessibleContext >& xContext
+) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ uno::Reference< accessibility::XAccessibleStateSet > xStateSet =
+ xContext->getAccessibleStateSet();
+
+ if( xStateSet.is() )
+ detachRecursive(xAccessible, xContext, xStateSet);
+}
+
+/*****************************************************************************/
+
+void DocumentFocusListener::detachRecursive(
+ const uno::Reference< accessibility::XAccessible >&,
+ const uno::Reference< accessibility::XAccessibleContext >& xContext,
+ const uno::Reference< accessibility::XAccessibleStateSet >& xStateSet
+) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ uno::Reference< accessibility::XAccessibleEventBroadcaster > xBroadcaster =
+ uno::Reference< accessibility::XAccessibleEventBroadcaster >(xContext, uno::UNO_QUERY);
+
+ if( xBroadcaster.is() && 0 < m_aRefList.erase(xBroadcaster) )
+ {
+ xBroadcaster->removeEventListener(static_cast< accessibility::XAccessibleEventListener *>(this));
+
+ if( ! xStateSet->contains(accessibility::AccessibleStateType::MANAGES_DESCENDANTS ) )
+ {
+ sal_Int32 n, nmax = xContext->getAccessibleChildCount();
+ for( n = 0; n < nmax; n++ )
+ {
+ uno::Reference< accessibility::XAccessible > xChild( xContext->getAccessibleChild( n ) );
+
+ if( xChild.is() )
+ detachRecursive(xChild);
+ }
+ }
+ }
+}
+
+/*****************************************************************************/
+
+/*
+ * page tabs in gtk are widgets, so we need to simulate focus events for those
+ */
+
+static void handle_tabpage_activated(Window *pWindow)
+{
+ uno::Reference< accessibility::XAccessible > xAccessible =
+ pWindow->GetAccessible();
+
+ if( ! xAccessible.is() )
+ return;
+
+ uno::Reference< accessibility::XAccessibleSelection > xSelection(
+ xAccessible->getAccessibleContext(), uno::UNO_QUERY);
+
+ if( xSelection.is() )
+ atk_wrapper_focus_tracker_notify_when_idle( xSelection->getSelectedAccessibleChild(0) );
+}
+
+/*****************************************************************************/
+
+/*
+ * toolbar items in gtk are widgets, so we need to simulate focus events for those
+ */
+
+static void notify_toolbox_item_focus(ToolBox *pToolBox)
+{
+ uno::Reference< accessibility::XAccessible > xAccessible =
+ pToolBox->GetAccessible();
+
+ if( ! xAccessible.is() )
+ return;
+
+ uno::Reference< accessibility::XAccessibleContext > xContext =
+ xAccessible->getAccessibleContext();
+
+ if( ! xContext.is() )
+ return;
+
+ sal_Int32 nPos = pToolBox->GetItemPos( pToolBox->GetHighlightItemId() );
+ if( nPos != TOOLBOX_ITEM_NOTFOUND )
+ atk_wrapper_focus_tracker_notify_when_idle( xContext->getAccessibleChild( nPos ) );
+}
+
+static void handle_toolbox_highlight(Window *pWindow)
+{
+ ToolBox *pToolBox = static_cast <ToolBox *> (pWindow);
+
+ // Make sure either the toolbox or its parent toolbox has the focus
+ if ( ! pToolBox->HasFocus() )
+ {
+ ToolBox* pToolBoxParent = dynamic_cast< ToolBox* >( pToolBox->GetParent() );
+ if ( ! pToolBoxParent || ! pToolBoxParent->HasFocus() )
+ return;
+ }
+
+ notify_toolbox_item_focus(pToolBox);
+}
+
+static void handle_toolbox_highlightoff(Window *pWindow)
+{
+ ToolBox *pToolBox = static_cast <ToolBox *> (pWindow);
+ ToolBox* pToolBoxParent = dynamic_cast< ToolBox* >( pToolBox->GetParent() );
+
+ // Notify when leaving sub toolboxes
+ if( pToolBoxParent && pToolBoxParent->HasFocus() )
+ notify_toolbox_item_focus( pToolBoxParent );
+}
+
+/*****************************************************************************/
+
+static void create_wrapper_for_child(
+ const uno::Reference< accessibility::XAccessibleContext >& xContext,
+ sal_Int32 index)
+{
+ if( xContext.is() )
+ {
+ uno::Reference< accessibility::XAccessible > xChild(xContext->getAccessibleChild(index));
+ if( xChild.is() )
+ {
+ // create the wrapper object - it will survive the unref unless it is a transient object
+ g_object_unref( atk_object_wrapper_ref( xChild ) );
+ }
+ }
+}
+
+/*****************************************************************************/
+
+static void handle_toolbox_buttonchange(VclWindowEvent const *pEvent)
+{
+ Window* pWindow = pEvent->GetWindow();
+ sal_Int32 index = (sal_Int32)(sal_IntPtr) pEvent->GetData();
+
+ if( pWindow && pWindow->IsReallyVisible() )
+ {
+ uno::Reference< accessibility::XAccessible > xAccessible(pWindow->GetAccessible());
+ if( xAccessible.is() )
+ {
+ create_wrapper_for_child(xAccessible->getAccessibleContext(), index);
+ }
+ }
+}
+
+/*****************************************************************************/
+
+/* currently not needed anymore...
+static void create_wrapper_for_children(Window *pWindow)
+{
+ if( pWindow && pWindow->IsReallyVisible() )
+ {
+ uno::Reference< accessibility::XAccessible > xAccessible(pWindow->GetAccessible());
+ if( xAccessible.is() )
+ {
+ uno::Reference< accessibility::XAccessibleContext > xContext(xAccessible->getAccessibleContext());
+ if( xContext.is() )
+ {
+ sal_Int32 nChildren = xContext->getAccessibleChildCount();
+ for( sal_Int32 i = 0; i < nChildren; ++i )
+ create_wrapper_for_child(xContext, i);
+ }
+ }
+ }
+}
+*/
+
+/*****************************************************************************/
+
+static std::set< Window * > g_aWindowList;
+
+static void handle_get_focus(::VclWindowEvent const * pEvent)
+{
+ static rtl::Reference< DocumentFocusListener > aDocumentFocusListener =
+ new DocumentFocusListener();
+
+ Window *pWindow = pEvent->GetWindow();
+
+ // The menu bar is handled through VCLEVENT_MENU_HIGHLIGHTED
+ if( ! pWindow || !pWindow->IsReallyVisible() || pWindow->GetType() == WINDOW_MENUBARWINDOW )
+ return;
+
+ // ToolBoxes are handled through VCLEVENT_TOOLBOX_HIGHLIGHT
+ if( pWindow->GetType() == WINDOW_TOOLBOX )
+ return;
+
+ if( pWindow->GetType() == WINDOW_TABCONTROL )
+ {
+ handle_tabpage_activated( pWindow );
+ return;
+ }
+
+ uno::Reference< accessibility::XAccessible > xAccessible =
+ pWindow->GetAccessible();
+
+ if( ! xAccessible.is() )
+ return;
+
+ uno::Reference< accessibility::XAccessibleContext > xContext =
+ xAccessible->getAccessibleContext();
+
+ if( ! xContext.is() )
+ return;
+
+ uno::Reference< accessibility::XAccessibleStateSet > xStateSet =
+ xContext->getAccessibleStateSet();
+
+ if( ! xStateSet.is() )
+ return;
+
+/* the UNO ToolBox wrapper does not (yet?) support XAccessibleSelection, so we
+ * need to add listeners to the children instead of re-using the tabpage stuff
+ */
+ if( xStateSet->contains(accessibility::AccessibleStateType::FOCUSED) &&
+ ( pWindow->GetType() != WINDOW_TREELISTBOX ) )
+ {
+ atk_wrapper_focus_tracker_notify_when_idle( xAccessible );
+ }
+ else
+ {
+ if( g_aWindowList.find(pWindow) == g_aWindowList.end() )
+ {
+ g_aWindowList.insert(pWindow);
+ try
+ {
+ aDocumentFocusListener->attachRecursive(xAccessible, xContext, xStateSet);
+ }
+ catch( const uno::Exception &e )
+ {
+ g_warning( "Exception caught processing focus events" );
+ }
+ }
+#ifdef ENABLE_TRACING
+ else
+ fprintf(stderr, "Window %p already in the list\n", pWindow );
+#endif
+ }
+}
+
+/*****************************************************************************/
+
+static void handle_menu_highlighted(::VclMenuEvent const * pEvent)
+{
+ try
+ {
+ Menu* pMenu = pEvent->GetMenu();
+ USHORT nPos = pEvent->GetItemPos();
+
+ if( pMenu && nPos != 0xFFFF)
+ {
+ uno::Reference< accessibility::XAccessible > xAccessible ( pMenu->GetAccessible() );
+
+ if( xAccessible.is() )
+ {
+ uno::Reference< accessibility::XAccessibleContext > xContext ( xAccessible->getAccessibleContext() );
+
+ if( xContext.is() )
+ atk_wrapper_focus_tracker_notify_when_idle( xContext->getAccessibleChild( nPos ) );
+ }
+ }
+ }
+ catch( const uno::Exception& e )
+ {
+ g_warning( "Exception caught processing menu highlight events" );
+ }
+}
+
+/*****************************************************************************/
+
+long WindowEventHandler(void *, ::VclSimpleEvent const * pEvent)
+{
+ switch (pEvent->GetId())
+ {
+ case VCLEVENT_WINDOW_SHOW:
+// fprintf(stderr, "got VCLEVENT_WINDOW_SHOW for %p\n",
+// static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
+ break;
+ case VCLEVENT_WINDOW_HIDE:
+// fprintf(stderr, "got VCLEVENT_WINDOW_HIDE for %p\n",
+// static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
+ break;
+ case VCLEVENT_WINDOW_CLOSE:
+// fprintf(stderr, "got VCLEVENT_WINDOW_CLOSE for %p\n",
+// static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
+ break;
+ case VCLEVENT_WINDOW_GETFOCUS:
+ handle_get_focus(static_cast< ::VclWindowEvent const * >(pEvent));
+ break;
+ case VCLEVENT_WINDOW_LOSEFOCUS:
+// fprintf(stderr, "got VCLEVENT_WINDOW_LOSEFOCUS for %p\n",
+// static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
+ break;
+ case VCLEVENT_WINDOW_MINIMIZE:
+// fprintf(stderr, "got VCLEVENT_WINDOW_MINIMIZE for %p\n",
+// static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
+ break;
+ case VCLEVENT_WINDOW_NORMALIZE:
+// fprintf(stderr, "got VCLEVENT_WINDOW_NORMALIZE for %p\n",
+// static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
+ break;
+ case VCLEVENT_WINDOW_KEYINPUT:
+ case VCLEVENT_WINDOW_KEYUP:
+ case VCLEVENT_WINDOW_COMMAND:
+ case VCLEVENT_WINDOW_MOUSEMOVE:
+ break;
+ /*
+ fprintf(stderr, "got VCLEVENT_WINDOW_COMMAND (%d) for %p\n",
+ static_cast< ::CommandEvent const * > (
+ static_cast< ::VclWindowEvent const * >(pEvent)->GetData())->GetCommand(),
+ static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
+ */
+ case VCLEVENT_MENU_HIGHLIGHT:
+ if (const VclMenuEvent* pMenuEvent = dynamic_cast<const VclMenuEvent*>(pEvent))
+ {
+ handle_menu_highlighted(pMenuEvent);
+ }
+ else if (const VclAccessibleEvent* pAccEvent = dynamic_cast<const VclAccessibleEvent*>(pEvent))
+ {
+ uno::Reference< accessibility::XAccessible > xAccessible = pAccEvent->GetAccessible();
+ if (xAccessible.is())
+ atk_wrapper_focus_tracker_notify_when_idle(xAccessible);
+ }
+ break;
+
+ case VCLEVENT_TOOLBOX_HIGHLIGHT:
+ handle_toolbox_highlight(static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
+ break;
+
+ case VCLEVENT_TOOLBOX_BUTTONSTATECHANGED:
+ handle_toolbox_buttonchange(static_cast< ::VclWindowEvent const * >(pEvent));
+ break;
+
+ case VCLEVENT_OBJECT_DYING:
+ g_aWindowList.erase( static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow() );
+ // fallthrough intentional !
+ case VCLEVENT_TOOLBOX_HIGHLIGHTOFF:
+ handle_toolbox_highlightoff(static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
+ break;
+
+ case VCLEVENT_TABPAGE_ACTIVATE:
+ handle_tabpage_activated(static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
+ break;
+
+ case VCLEVENT_COMBOBOX_SETTEXT:
+ // MT 2010/02: This looks quite strange to me. Stumbled over this when fixing #i104290#.
+ // This kicked in when leaving the combobox in the toolbar, after that the events worked.
+ // 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.
+ // Fix for #i104290# was done in toolkit/source/awt/vclxaccessiblecomponent, FOCUSED state for compound controls in general.
+ // create_wrapper_for_children(static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
+ break;
+
+ default:
+// OSL_TRACE("got event %d \n", pEvent->GetId());
+ break;
+ }
+ return 0;
+}
+
+static Link g_aEventListenerLink( NULL, (PSTUB) WindowEventHandler );
+
+/*****************************************************************************/
+
+extern "C" {
+
+static G_CONST_RETURN gchar *
+ooo_atk_util_get_toolkit_name (void)
+{
+ return "VCL";
+}
+
+/*****************************************************************************/
+
+static G_CONST_RETURN gchar *
+ooo_atk_util_get_toolkit_version (void)
+{
+ /*
+ * Version is passed in as a -D flag when this file is
+ * compiled.
+ */
+
+ return VERSION;
+}
+
+/*****************************************************************************/
+
+/*
+ * GObject inheritance
+ */
+
+static void
+ooo_atk_util_class_init (AtkUtilClass *)
+{
+ AtkUtilClass *atk_class;
+ gpointer data;
+
+ data = g_type_class_peek (ATK_TYPE_UTIL);
+ atk_class = ATK_UTIL_CLASS (data);
+
+ atk_class->get_toolkit_name = ooo_atk_util_get_toolkit_name;
+ atk_class->get_toolkit_version = ooo_atk_util_get_toolkit_version;
+
+ Application::AddEventListener( g_aEventListenerLink );
+}
+
+} // extern "C"
+
+/*****************************************************************************/
+
+GType
+ooo_atk_util_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type)
+ {
+ GType parent_type = g_type_from_name( "GailUtil" );
+
+ if( ! parent_type )
+ {
+ g_warning( "Unknown type: GailUtil" );
+ parent_type = ATK_TYPE_UTIL;
+ }
+
+ GTypeQuery type_query;
+ g_type_query( parent_type, &type_query );
+
+ static const GTypeInfo typeInfo =
+ {
+ type_query.class_size,
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ooo_atk_util_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL,
+ type_query.instance_size,
+ 0,
+ (GInstanceInitFunc) NULL,
+ NULL
+ } ;
+
+ type = g_type_register_static (parent_type, "OOoUtil", &typeInfo, (GTypeFlags)0) ;
+ }
+
+ return type;
+}
+
+