Move setting of LD_LIBRARY_PATH closer to invocation of cppunittester
[LibreOffice.git] / vcl / unx / gtk3 / a11y / atkcomponent.cxx
blob9b5bb2f6edfbb3fb12cdee26715770b6690ac147
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "atkwrapper.hxx"
21 #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
22 #include <sal/log.hxx>
23 #include <gtk/gtk.h>
25 using namespace ::com::sun::star;
27 static AtkObjectWrapper* getObjectWrapper(AtkComponent *pComponent)
29 AtkObjectWrapper *pWrap = nullptr;
30 if (ATK_IS_OBJECT_WRAPPER(pComponent))
31 pWrap = ATK_OBJECT_WRAPPER(pComponent);
32 else if (GTK_IS_DRAWING_AREA(pComponent)) //when using a GtkDrawingArea as a custom widget in welded gtk3
34 GtkWidget* pDrawingArea = GTK_WIDGET(pComponent);
35 AtkObject* pAtkObject = gtk_widget_get_accessible(pDrawingArea);
36 pWrap = ATK_IS_OBJECT_WRAPPER(pAtkObject) ? ATK_OBJECT_WRAPPER(pAtkObject) : nullptr;
38 return pWrap;
41 /// @throws uno::RuntimeException
42 static css::uno::Reference<css::accessibility::XAccessibleComponent>
43 getComponent(AtkObjectWrapper *pWrap)
45 if (pWrap)
47 if (!pWrap->mpComponent.is())
48 pWrap->mpComponent.set(pWrap->mpContext, css::uno::UNO_QUERY);
49 return pWrap->mpComponent;
52 return css::uno::Reference<css::accessibility::XAccessibleComponent>();
55 static awt::Point
56 lcl_getLocationInWindow(AtkComponent* pAtkComponent,
57 css::uno::Reference<accessibility::XAccessibleComponent> const& xComponent)
59 // calculate position in window by adding the component's position in the parent
60 // to the parent's position in the window (unless parent is a window itself)
61 awt::Point aPos = xComponent->getLocation();
62 AtkObject* pParent = atk_object_get_parent(ATK_OBJECT(pAtkComponent));
63 if (ATK_IS_COMPONENT(pParent) && pParent->role != AtkRole::ATK_ROLE_DIALOG
64 && pParent->role != AtkRole::ATK_ROLE_FILE_CHOOSER
65 && pParent->role != AtkRole::ATK_ROLE_FRAME
66 && pParent->role != AtkRole::ATK_ROLE_WINDOW)
68 int nX;
69 int nY;
70 atk_component_get_extents(ATK_COMPONENT(pParent), &nX, &nY, nullptr, nullptr, ATK_XY_WINDOW);
71 aPos.X += nX;
72 aPos.Y += nY;
75 return aPos;
78 /*****************************************************************************/
80 static awt::Point
81 translatePoint( AtkComponent* pAtkComponent,
82 css::uno::Reference<accessibility::XAccessibleComponent> const & pComponent,
83 gint x, gint y, AtkCoordType t)
85 awt::Point aOrigin( 0, 0 );
86 if( t == ATK_XY_SCREEN )
87 aOrigin = pComponent->getLocationOnScreen();
88 else if (t == ATK_XY_WINDOW)
89 aOrigin = lcl_getLocationInWindow(pAtkComponent, pComponent);
90 return awt::Point( x - aOrigin.X, y - aOrigin.Y );
93 /*****************************************************************************/
95 extern "C" {
97 static gboolean
98 component_wrapper_grab_focus (AtkComponent *component)
100 AtkObjectWrapper* obj = getObjectWrapper(component);
101 //if we're a native GtkDrawingArea with custom a11y, use the default toolkit a11y
102 if (obj && obj->mpOrig)
103 return atk_component_grab_focus(ATK_COMPONENT(obj->mpOrig));
107 css::uno::Reference<css::accessibility::XAccessibleComponent> pComponent
108 = getComponent(obj);
109 if( pComponent.is() )
111 pComponent->grabFocus();
112 return true;
115 catch( const uno::Exception & )
117 g_warning( "Exception in grabFocus()" );
120 return FALSE;
123 /*****************************************************************************/
125 static gboolean
126 component_wrapper_contains (AtkComponent *component,
127 gint x,
128 gint y,
129 AtkCoordType coord_type)
131 AtkObjectWrapper* obj = getObjectWrapper(component);
132 //if we're a native GtkDrawingArea with custom a11y, use the default toolkit a11y
133 if (obj && obj->mpOrig)
134 return atk_component_contains(ATK_COMPONENT(obj->mpOrig), x, y, coord_type);
138 css::uno::Reference<css::accessibility::XAccessibleComponent> pComponent
139 = getComponent(obj);
140 if( pComponent.is() )
141 return pComponent->containsPoint(
142 translatePoint(component, pComponent, x, y, coord_type));
144 catch( const uno::Exception & )
146 g_warning( "Exception in containsPoint()" );
149 return FALSE;
152 /*****************************************************************************/
154 static AtkObject *
155 component_wrapper_ref_accessible_at_point (AtkComponent *component,
156 gint x,
157 gint y,
158 AtkCoordType coord_type)
160 AtkObjectWrapper* obj = getObjectWrapper(component);
161 //if we're a native GtkDrawingArea with custom a11y, use the default toolkit a11y
162 if (obj && obj->mpOrig)
163 return atk_component_ref_accessible_at_point(ATK_COMPONENT(obj->mpOrig), x, y, coord_type);
167 css::uno::Reference<css::accessibility::XAccessibleComponent> pComponent
168 = getComponent(obj);
170 if( pComponent.is() )
172 uno::Reference< accessibility::XAccessible > xAccessible = pComponent->getAccessibleAtPoint(
173 translatePoint(component, pComponent, x, y, coord_type));
174 return atk_object_wrapper_ref( xAccessible );
177 catch( const uno::Exception & )
179 g_warning( "Exception in getAccessibleAtPoint()" );
182 return nullptr;
185 /*****************************************************************************/
187 static void
188 component_wrapper_get_position (AtkComponent *component,
189 gint *x,
190 gint *y,
191 AtkCoordType coord_type)
193 AtkObjectWrapper* obj = getObjectWrapper(component);
194 //if we're a native GtkDrawingArea with custom a11y, use the default toolkit a11y
195 if (obj && obj->mpOrig)
197 atk_component_get_extents(ATK_COMPONENT(obj->mpOrig), x, y, nullptr, nullptr, coord_type);
198 return;
201 *x = *y = -1;
205 css::uno::Reference<css::accessibility::XAccessibleComponent> pComponent
206 = getComponent(obj);
207 if( pComponent.is() )
209 awt::Point aPos;
211 if( coord_type == ATK_XY_SCREEN )
212 aPos = pComponent->getLocationOnScreen();
213 else if (coord_type == ATK_XY_WINDOW)
214 aPos = lcl_getLocationInWindow(component, pComponent);
215 #if ATK_CHECK_VERSION(2, 30, 0)
216 else if (coord_type == ATK_XY_PARENT)
217 #else
218 // ATK_XY_PARENT added in ATK 2.30, so can't use the constant here
219 else
220 #endif
221 aPos = pComponent->getLocation();
222 #if ATK_CHECK_VERSION(2, 30, 0)
223 else
225 SAL_WARN("vcl.gtk",
226 "component_wrapper_get_position called with unknown AtkCoordType "
227 << coord_type);
228 return;
230 #endif
232 *x = aPos.X;
233 *y = aPos.Y;
236 catch( const uno::Exception & )
238 g_warning( "Exception in getLocation[OnScreen]()" );
242 /*****************************************************************************/
244 static void
245 component_wrapper_get_size (AtkComponent *component,
246 gint *width,
247 gint *height)
249 AtkObjectWrapper* obj = getObjectWrapper(component);
250 //if we're a native GtkDrawingArea with custom a11y, use the default toolkit a11y
251 if (obj && obj->mpOrig)
253 atk_component_get_extents(ATK_COMPONENT(obj->mpOrig), nullptr, nullptr, width, height, ATK_XY_WINDOW);
254 return;
257 *width = *height = -1;
261 css::uno::Reference<css::accessibility::XAccessibleComponent> pComponent
262 = getComponent(obj);
263 if( pComponent.is() )
265 awt::Size aSize = pComponent->getSize();
266 *width = aSize.Width;
267 *height = aSize.Height;
270 catch( const uno::Exception & )
272 g_warning( "Exception in getSize()" );
276 /*****************************************************************************/
278 static void
279 component_wrapper_get_extents (AtkComponent *component,
280 gint *x,
281 gint *y,
282 gint *width,
283 gint *height,
284 AtkCoordType coord_type)
286 component_wrapper_get_position( component, x, y, coord_type );
287 component_wrapper_get_size( component, width, height );
290 /*****************************************************************************/
292 static gboolean
293 component_wrapper_set_extents (AtkComponent *, gint, gint, gint, gint, AtkCoordType)
295 g_warning( "AtkComponent::set_extents unimplementable" );
296 return FALSE;
299 /*****************************************************************************/
301 static gboolean
302 component_wrapper_set_position (AtkComponent *, gint, gint, AtkCoordType)
304 g_warning( "AtkComponent::set_position unimplementable" );
305 return FALSE;
308 /*****************************************************************************/
310 static gboolean
311 component_wrapper_set_size (AtkComponent *, gint, gint)
313 g_warning( "AtkComponent::set_size unimplementable" );
314 return FALSE;
317 /*****************************************************************************/
319 static AtkLayer
320 component_wrapper_get_layer (AtkComponent *component)
322 AtkRole role = atk_object_get_role( ATK_OBJECT( component ) );
323 AtkLayer layer = ATK_LAYER_WIDGET;
325 switch (role)
327 case ATK_ROLE_POPUP_MENU:
328 case ATK_ROLE_MENU_ITEM:
329 case ATK_ROLE_CHECK_MENU_ITEM:
330 case ATK_ROLE_SEPARATOR:
331 case ATK_ROLE_LIST_ITEM:
332 layer = ATK_LAYER_POPUP;
333 break;
334 case ATK_ROLE_MENU:
336 AtkObject * parent = atk_object_get_parent( ATK_OBJECT( component ) );
337 if( atk_object_get_role( parent ) != ATK_ROLE_MENU_BAR )
338 layer = ATK_LAYER_POPUP;
340 break;
342 case ATK_ROLE_LIST:
344 AtkObject * parent = atk_object_get_parent( ATK_OBJECT( component ) );
345 if( atk_object_get_role( parent ) == ATK_ROLE_COMBO_BOX )
346 layer = ATK_LAYER_POPUP;
348 break;
350 default:
354 return layer;
357 /*****************************************************************************/
359 static gint
360 component_wrapper_get_mdi_zorder (AtkComponent *)
362 // only needed for ATK_LAYER_MDI (not used) or ATK_LAYER_WINDOW (inherited from GAIL)
363 return G_MININT;
366 /*****************************************************************************/
368 // This code is mostly stolen from libgail ..
370 static guint
371 component_wrapper_add_focus_handler (AtkComponent *component,
372 AtkFocusHandler handler)
374 GSignalMatchType match_type;
375 gulong ret;
376 guint signal_id;
378 match_type = GSignalMatchType(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC);
379 signal_id = g_signal_lookup( "focus-event", ATK_TYPE_OBJECT );
381 ret = g_signal_handler_find( component, match_type, signal_id, 0, nullptr,
382 static_cast<gpointer>(&handler), nullptr);
383 if (!ret)
385 return g_signal_connect_closure_by_id (component,
386 signal_id, 0,
387 g_cclosure_new (
388 G_CALLBACK (handler), nullptr,
389 nullptr),
390 FALSE);
392 else
394 return 0;
398 /*****************************************************************************/
400 static void
401 component_wrapper_remove_focus_handler (AtkComponent *component,
402 guint handler_id)
404 g_signal_handler_disconnect (component, handler_id);
407 /*****************************************************************************/
409 } // extern "C"
411 void
412 componentIfaceInit (gpointer iface_, gpointer)
414 auto const iface = static_cast<AtkComponentIface *>(iface_);
415 g_return_if_fail (iface != nullptr);
417 iface->add_focus_handler = component_wrapper_add_focus_handler;
418 iface->contains = component_wrapper_contains;
419 iface->get_extents = component_wrapper_get_extents;
420 iface->get_layer = component_wrapper_get_layer;
421 iface->get_mdi_zorder = component_wrapper_get_mdi_zorder;
422 iface->get_position = component_wrapper_get_position;
423 iface->get_size = component_wrapper_get_size;
424 iface->grab_focus = component_wrapper_grab_focus;
425 iface->ref_accessible_at_point = component_wrapper_ref_accessible_at_point;
426 iface->remove_focus_handler = component_wrapper_remove_focus_handler;
427 iface->set_extents = component_wrapper_set_extents;
428 iface->set_position = component_wrapper_set_position;
429 iface->set_size = component_wrapper_set_size;
432 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */