/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the 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 )
{
    try {
        switch( aEvent.EventId )
        {
            case accessibility::AccessibleEventId::STATE_CHANGED:
            {
                sal_Int16 nState = accessibility::AccessibleStateType::INVALID;
                aEvent.NewValue >>= nState;

                if( accessibility::AccessibleStateType::FOCUSED == nState )
                    atk_wrapper_focus_tracker_notify_when_idle( getAccessible(aEvent) );
            }
            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;
        }
    }
    catch( const lang::IndexOutOfBoundsException& e )
    {
        g_warning("Focused object has invalid index in parent");
    }
}

/*****************************************************************************/

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();
        sal_uInt16 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;
}


