blob: 7cfa6baca2ef78a6af71521b18b592e7a03eb5a2 [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 "atkwrapper.hxx"
#include <com/sun/star/accessibility/XAccessibleComponent.hpp>
#ifdef ENABLE_TRACING
#include <stdio.h>
#endif
using namespace ::com::sun::star;
static accessibility::XAccessibleComponent*
getComponent( AtkComponent *pComponent ) throw (uno::RuntimeException)
{
AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pComponent );
if( pWrap )
{
if( !pWrap->mpComponent && pWrap->mpContext )
{
uno::Any any = pWrap->mpContext->queryInterface( accessibility::XAccessibleComponent::static_type(NULL) );
pWrap->mpComponent = reinterpret_cast< accessibility::XAccessibleComponent * > (any.pReserved);
pWrap->mpComponent->acquire();
}
return pWrap->mpComponent;
}
return NULL;
}
/*****************************************************************************/
static awt::Point
translatePoint( accessibility::XAccessibleComponent *pComponent,
gint x, gint y, AtkCoordType t)
{
awt::Point aOrigin( 0, 0 );
if( t == ATK_XY_SCREEN )
aOrigin = pComponent->getLocationOnScreen();
#ifdef ENABLE_TRACING
fprintf(stderr, "coordinates ( %u, %u ) translated to: ( %u, %u )\n",
x, y, x - aOrigin.X, y - aOrigin.Y);
#endif
return awt::Point( x - aOrigin.X, y - aOrigin.Y );
}
/*****************************************************************************/
extern "C" {
static gboolean
component_wrapper_grab_focus (AtkComponent *component)
{
try
{
accessibility::XAccessibleComponent* pComponent = getComponent( component );
if( pComponent )
{
pComponent->grabFocus();
return TRUE;
}
}
catch( const uno::Exception &e )
{
g_warning( "Exception in grabFocus()" );
}
return FALSE;
}
/*****************************************************************************/
static gboolean
component_wrapper_contains (AtkComponent *component,
gint x,
gint y,
AtkCoordType coord_type)
{
try
{
accessibility::XAccessibleComponent* pComponent = getComponent( component );
if( pComponent )
return pComponent->containsPoint( translatePoint( pComponent, x, y, coord_type ) );
}
catch( const uno::Exception &e )
{
g_warning( "Exception in containsPoint()" );
}
return FALSE;
}
/*****************************************************************************/
static AtkObject *
component_wrapper_ref_accessible_at_point (AtkComponent *component,
gint x,
gint y,
AtkCoordType coord_type)
{
try
{
accessibility::XAccessibleComponent* pComponent = getComponent( component );
if( pComponent )
{
uno::Reference< accessibility::XAccessible > xAccessible;
xAccessible = pComponent->getAccessibleAtPoint(
translatePoint( pComponent, x, y, coord_type ) );
#ifdef ENABLE_TRACING
fprintf(stderr, "getAccessibleAtPoint( %u, %u ) returned %p\n",
x, y, xAccessible.get());
uno::Reference< accessibility::XAccessibleComponent > xComponent(
xAccessible->getAccessibleContext(), uno::UNO_QUERY );
if( xComponent.is() )
{
awt::Rectangle rect = xComponent->getBounds();
fprintf(stderr, "%p->getBounds() returned: ( %u, %u, %u, %u )\n",
xAccessible.get(), rect.X, rect.Y, rect.Width, rect.Height );
}
#endif
return atk_object_wrapper_ref( xAccessible );
}
}
catch( const uno::Exception &e )
{
g_warning( "Exception in getAccessibleAtPoint()" );
}
return NULL;
}
/*****************************************************************************/
static void
component_wrapper_get_position (AtkComponent *component,
gint *x,
gint *y,
AtkCoordType coord_type)
{
try
{
accessibility::XAccessibleComponent* pComponent = getComponent( component );
if( pComponent )
{
awt::Point aPos;
if( coord_type == ATK_XY_SCREEN )
aPos = pComponent->getLocationOnScreen();
else
aPos = pComponent->getLocation();
*x = aPos.X;
*y = aPos.Y;
#ifdef ENABLE_TRACING
fprintf(stderr, "getLocation[OnScreen]() returned: ( %u, %u )\n", *x, *y );
#endif
}
}
catch( const uno::Exception &e )
{
g_warning( "Exception in getLocation[OnScreen]()" );
}
}
/*****************************************************************************/
static void
component_wrapper_get_size (AtkComponent *component,
gint *width,
gint *height)
{
try
{
accessibility::XAccessibleComponent* pComponent = getComponent( component );
if( pComponent )
{
awt::Size aSize = pComponent->getSize();
*width = aSize.Width;
*height = aSize.Height;
#ifdef ENABLE_TRACING
fprintf(stderr, "getSize() returned: ( %u, %u )\n", *width, *height );
#endif
}
}
catch( const uno::Exception &e )
{
g_warning( "Exception in getSize()" );
}
}
/*****************************************************************************/
static void
component_wrapper_get_extents (AtkComponent *component,
gint *x,
gint *y,
gint *width,
gint *height,
AtkCoordType coord_type)
{
component_wrapper_get_position( component, x, y, coord_type );
component_wrapper_get_size( component, width, height );
}
/*****************************************************************************/
static gboolean
component_wrapper_set_extents (AtkComponent *, gint, gint, gint, gint, AtkCoordType)
{
g_warning( "AtkComponent::set_extents unimplementable" );
return FALSE;
}
/*****************************************************************************/
static gboolean
component_wrapper_set_position (AtkComponent *, gint, gint, AtkCoordType)
{
g_warning( "AtkComponent::set_position unimplementable" );
return FALSE;
}
/*****************************************************************************/
static gboolean
component_wrapper_set_size (AtkComponent *, gint, gint)
{
g_warning( "AtkComponent::set_size unimplementable" );
return FALSE;
}
/*****************************************************************************/
static AtkLayer
component_wrapper_get_layer (AtkComponent *component)
{
AtkRole role = atk_object_get_role( ATK_OBJECT( component ) );
AtkLayer layer = ATK_LAYER_WIDGET;
switch (role)
{
case ATK_ROLE_POPUP_MENU:
case ATK_ROLE_MENU_ITEM:
case ATK_ROLE_CHECK_MENU_ITEM:
case ATK_ROLE_SEPARATOR:
case ATK_ROLE_LIST_ITEM:
layer = ATK_LAYER_POPUP;
break;
case ATK_ROLE_MENU:
{
AtkObject * parent = atk_object_get_parent( ATK_OBJECT( component ) );
if( atk_object_get_role( parent ) != ATK_ROLE_MENU_BAR )
layer = ATK_LAYER_POPUP;
}
break;
case ATK_ROLE_LIST:
{
AtkObject * parent = atk_object_get_parent( ATK_OBJECT( component ) );
if( atk_object_get_role( parent ) == ATK_ROLE_COMBO_BOX )
layer = ATK_LAYER_POPUP;
}
break;
default:
;
}
return layer;
}
/*****************************************************************************/
static gint
component_wrapper_get_mdi_zorder (AtkComponent *)
{
// only needed for ATK_LAYER_MDI (not used) or ATK_LAYER_WINDOW (inherited from GAIL)
return G_MININT;
}
/*****************************************************************************/
// This code is mostly stolen from libgail ..
static guint
component_wrapper_add_focus_handler (AtkComponent *component,
AtkFocusHandler handler)
{
GSignalMatchType match_type;
gulong ret;
guint signal_id;
match_type = (GSignalMatchType) (G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC);
signal_id = g_signal_lookup( "focus-event", ATK_TYPE_OBJECT );
ret = g_signal_handler_find( component, match_type, signal_id, 0, NULL,
(gpointer) &handler, NULL);
if (!ret)
{
return g_signal_connect_closure_by_id (component,
signal_id, 0,
g_cclosure_new (
G_CALLBACK (handler), NULL,
(GClosureNotify) NULL),
FALSE);
}
else
{
return 0;
}
}
/*****************************************************************************/
static void
component_wrapper_remove_focus_handler (AtkComponent *component,
guint handler_id)
{
g_signal_handler_disconnect (component, handler_id);
}
/*****************************************************************************/
} // extern "C"
void
componentIfaceInit (AtkComponentIface *iface)
{
g_return_if_fail (iface != NULL);
iface->add_focus_handler = component_wrapper_add_focus_handler;
iface->contains = component_wrapper_contains;
iface->get_extents = component_wrapper_get_extents;
iface->get_layer = component_wrapper_get_layer;
iface->get_mdi_zorder = component_wrapper_get_mdi_zorder;
iface->get_position = component_wrapper_get_position;
iface->get_size = component_wrapper_get_size;
iface->grab_focus = component_wrapper_grab_focus;
iface->ref_accessible_at_point = component_wrapper_ref_accessible_at_point;
iface->remove_focus_handler = component_wrapper_remove_focus_handler;
iface->set_extents = component_wrapper_set_extents;
iface->set_position = component_wrapper_set_position;
iface->set_size = component_wrapper_set_size;
}