blob: abd5ce475d4f37c0f0c8b05ce21a76e79542bdc3 [file] [log] [blame]
/**************************************************************
*
* 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;
}