Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include "atkwrapper.hxx"
21 :
22 : #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
23 :
24 : #ifdef ENABLE_TRACING
25 : #include <stdio.h>
26 : #endif
27 :
28 : using namespace ::com::sun::star;
29 :
30 : static accessibility::XAccessibleComponent*
31 0 : getComponent( AtkComponent *pComponent ) throw (uno::RuntimeException)
32 : {
33 0 : AtkObjectWrapper *pWrap = ATK_OBJECT_WRAPPER( pComponent );
34 0 : if( pWrap )
35 : {
36 0 : if( !pWrap->mpComponent && pWrap->mpContext )
37 : {
38 0 : uno::Any any = pWrap->mpContext->queryInterface( cppu::UnoType<accessibility::XAccessibleComponent>::get() );
39 0 : pWrap->mpComponent = static_cast< accessibility::XAccessibleComponent * > (any.pReserved);
40 0 : pWrap->mpComponent->acquire();
41 : }
42 :
43 0 : return pWrap->mpComponent;
44 : }
45 :
46 0 : return NULL;
47 : }
48 :
49 : /*****************************************************************************/
50 :
51 : static awt::Point
52 0 : translatePoint( accessibility::XAccessibleComponent *pComponent,
53 : gint x, gint y, AtkCoordType t)
54 : {
55 0 : awt::Point aOrigin( 0, 0 );
56 0 : if( t == ATK_XY_SCREEN )
57 0 : aOrigin = pComponent->getLocationOnScreen();
58 :
59 : #ifdef ENABLE_TRACING
60 : fprintf(stderr, "coordinates ( %u, %u ) translated to: ( %u, %u )\n",
61 : x, y, x - aOrigin.X, y - aOrigin.Y);
62 : #endif
63 :
64 0 : return awt::Point( x - aOrigin.X, y - aOrigin.Y );
65 : }
66 :
67 : /*****************************************************************************/
68 :
69 : extern "C" {
70 :
71 : static gboolean
72 0 : component_wrapper_grab_focus (AtkComponent *component)
73 : {
74 : try
75 : {
76 0 : accessibility::XAccessibleComponent* pComponent = getComponent( component );
77 0 : if( pComponent )
78 : {
79 0 : pComponent->grabFocus();
80 0 : return TRUE;
81 : }
82 : }
83 0 : catch( const uno::Exception & )
84 : {
85 0 : g_warning( "Exception in grabFocus()" );
86 : }
87 :
88 0 : return FALSE;
89 : }
90 :
91 : /*****************************************************************************/
92 :
93 : static gboolean
94 0 : component_wrapper_contains (AtkComponent *component,
95 : gint x,
96 : gint y,
97 : AtkCoordType coord_type)
98 : {
99 : try
100 : {
101 0 : accessibility::XAccessibleComponent* pComponent = getComponent( component );
102 0 : if( pComponent )
103 0 : return pComponent->containsPoint( translatePoint( pComponent, x, y, coord_type ) );
104 : }
105 0 : catch( const uno::Exception & )
106 : {
107 0 : g_warning( "Exception in containsPoint()" );
108 : }
109 :
110 0 : return FALSE;
111 : }
112 :
113 : /*****************************************************************************/
114 :
115 : static AtkObject *
116 0 : component_wrapper_ref_accessible_at_point (AtkComponent *component,
117 : gint x,
118 : gint y,
119 : AtkCoordType coord_type)
120 : {
121 : try
122 : {
123 0 : accessibility::XAccessibleComponent* pComponent = getComponent( component );
124 :
125 0 : if( pComponent )
126 : {
127 0 : uno::Reference< accessibility::XAccessible > xAccessible;
128 0 : xAccessible = pComponent->getAccessibleAtPoint(
129 0 : translatePoint( pComponent, x, y, coord_type ) );
130 :
131 : #ifdef ENABLE_TRACING
132 : fprintf(stderr, "getAccessibleAtPoint( %u, %u ) returned %p\n",
133 : x, y, xAccessible.get());
134 :
135 : uno::Reference< accessibility::XAccessibleComponent > xComponent(
136 : xAccessible->getAccessibleContext(), uno::UNO_QUERY );
137 :
138 : if( xComponent.is() )
139 : {
140 : awt::Rectangle rect = xComponent->getBounds();
141 : fprintf(stderr, "%p->getBounds() returned: ( %u, %u, %u, %u )\n",
142 : xAccessible.get(), rect.X, rect.Y, rect.Width, rect.Height );
143 : }
144 : #endif
145 :
146 0 : return atk_object_wrapper_ref( xAccessible );
147 : }
148 : }
149 0 : catch( const uno::Exception & )
150 : {
151 0 : g_warning( "Exception in getAccessibleAtPoint()" );
152 : }
153 :
154 0 : return NULL;
155 : }
156 :
157 : /*****************************************************************************/
158 :
159 : static void
160 0 : component_wrapper_get_position (AtkComponent *component,
161 : gint *x,
162 : gint *y,
163 : AtkCoordType coord_type)
164 : {
165 : try
166 : {
167 0 : accessibility::XAccessibleComponent* pComponent = getComponent( component );
168 0 : if( pComponent )
169 : {
170 0 : awt::Point aPos;
171 :
172 0 : if( coord_type == ATK_XY_SCREEN )
173 0 : aPos = pComponent->getLocationOnScreen();
174 : else
175 0 : aPos = pComponent->getLocation();
176 :
177 0 : *x = aPos.X;
178 0 : *y = aPos.Y;
179 :
180 : #ifdef ENABLE_TRACING
181 : fprintf(stderr, "getLocation[OnScreen]() returned: ( %u, %u )\n", *x, *y );
182 : #endif
183 : }
184 : }
185 0 : catch( const uno::Exception & )
186 : {
187 0 : g_warning( "Exception in getLocation[OnScreen]()" );
188 : }
189 0 : }
190 :
191 : /*****************************************************************************/
192 :
193 : static void
194 0 : component_wrapper_get_size (AtkComponent *component,
195 : gint *width,
196 : gint *height)
197 : {
198 : try
199 : {
200 0 : accessibility::XAccessibleComponent* pComponent = getComponent( component );
201 0 : if( pComponent )
202 : {
203 0 : awt::Size aSize = pComponent->getSize();
204 0 : *width = aSize.Width;
205 0 : *height = aSize.Height;
206 :
207 : #ifdef ENABLE_TRACING
208 : fprintf(stderr, "getSize() returned: ( %u, %u )\n", *width, *height );
209 : #endif
210 : }
211 : }
212 0 : catch( const uno::Exception & )
213 : {
214 0 : g_warning( "Exception in getSize()" );
215 : }
216 0 : }
217 :
218 : /*****************************************************************************/
219 :
220 : static void
221 0 : component_wrapper_get_extents (AtkComponent *component,
222 : gint *x,
223 : gint *y,
224 : gint *width,
225 : gint *height,
226 : AtkCoordType coord_type)
227 : {
228 0 : component_wrapper_get_position( component, x, y, coord_type );
229 0 : component_wrapper_get_size( component, width, height );
230 0 : }
231 :
232 : /*****************************************************************************/
233 :
234 : static gboolean
235 0 : component_wrapper_set_extents (AtkComponent *, gint, gint, gint, gint, AtkCoordType)
236 : {
237 0 : g_warning( "AtkComponent::set_extents unimplementable" );
238 0 : return FALSE;
239 : }
240 :
241 : /*****************************************************************************/
242 :
243 : static gboolean
244 0 : component_wrapper_set_position (AtkComponent *, gint, gint, AtkCoordType)
245 : {
246 0 : g_warning( "AtkComponent::set_position unimplementable" );
247 0 : return FALSE;
248 : }
249 :
250 : /*****************************************************************************/
251 :
252 : static gboolean
253 0 : component_wrapper_set_size (AtkComponent *, gint, gint)
254 : {
255 0 : g_warning( "AtkComponent::set_size unimplementable" );
256 0 : return FALSE;
257 : }
258 :
259 : /*****************************************************************************/
260 :
261 : static AtkLayer
262 0 : component_wrapper_get_layer (AtkComponent *component)
263 : {
264 0 : AtkRole role = atk_object_get_role( ATK_OBJECT( component ) );
265 0 : AtkLayer layer = ATK_LAYER_WIDGET;
266 :
267 0 : switch (role)
268 : {
269 : case ATK_ROLE_POPUP_MENU:
270 : case ATK_ROLE_MENU_ITEM:
271 : case ATK_ROLE_CHECK_MENU_ITEM:
272 : case ATK_ROLE_SEPARATOR:
273 : case ATK_ROLE_LIST_ITEM:
274 0 : layer = ATK_LAYER_POPUP;
275 0 : break;
276 : case ATK_ROLE_MENU:
277 : {
278 0 : AtkObject * parent = atk_object_get_parent( ATK_OBJECT( component ) );
279 0 : if( atk_object_get_role( parent ) != ATK_ROLE_MENU_BAR )
280 0 : layer = ATK_LAYER_POPUP;
281 : }
282 0 : break;
283 :
284 : case ATK_ROLE_LIST:
285 : {
286 0 : AtkObject * parent = atk_object_get_parent( ATK_OBJECT( component ) );
287 0 : if( atk_object_get_role( parent ) == ATK_ROLE_COMBO_BOX )
288 0 : layer = ATK_LAYER_POPUP;
289 : }
290 0 : break;
291 :
292 : default:
293 : ;
294 : }
295 :
296 0 : return layer;
297 : }
298 :
299 : /*****************************************************************************/
300 :
301 : static gint
302 0 : component_wrapper_get_mdi_zorder (AtkComponent *)
303 : {
304 : // only needed for ATK_LAYER_MDI (not used) or ATK_LAYER_WINDOW (inherited from GAIL)
305 0 : return G_MININT;
306 : }
307 :
308 : /*****************************************************************************/
309 :
310 : // This code is mostly stolen from libgail ..
311 :
312 : static guint
313 0 : component_wrapper_add_focus_handler (AtkComponent *component,
314 : AtkFocusHandler handler)
315 : {
316 : GSignalMatchType match_type;
317 : gulong ret;
318 : guint signal_id;
319 :
320 0 : match_type = (GSignalMatchType) (G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC);
321 0 : signal_id = g_signal_lookup( "focus-event", ATK_TYPE_OBJECT );
322 :
323 : ret = g_signal_handler_find( component, match_type, signal_id, 0, NULL,
324 0 : static_cast<gpointer>(&handler), NULL);
325 0 : if (!ret)
326 : {
327 : return g_signal_connect_closure_by_id (component,
328 : signal_id, 0,
329 : g_cclosure_new (
330 : G_CALLBACK (handler), NULL,
331 : nullptr),
332 0 : FALSE);
333 : }
334 : else
335 : {
336 0 : return 0;
337 : }
338 : }
339 :
340 : /*****************************************************************************/
341 :
342 : static void
343 0 : component_wrapper_remove_focus_handler (AtkComponent *component,
344 : guint handler_id)
345 : {
346 0 : g_signal_handler_disconnect (component, handler_id);
347 0 : }
348 :
349 : /*****************************************************************************/
350 :
351 : } // extern "C"
352 :
353 : void
354 0 : componentIfaceInit (AtkComponentIface *iface)
355 : {
356 0 : g_return_if_fail (iface != NULL);
357 :
358 0 : iface->add_focus_handler = component_wrapper_add_focus_handler;
359 0 : iface->contains = component_wrapper_contains;
360 0 : iface->get_extents = component_wrapper_get_extents;
361 0 : iface->get_layer = component_wrapper_get_layer;
362 0 : iface->get_mdi_zorder = component_wrapper_get_mdi_zorder;
363 0 : iface->get_position = component_wrapper_get_position;
364 0 : iface->get_size = component_wrapper_get_size;
365 0 : iface->grab_focus = component_wrapper_grab_focus;
366 0 : iface->ref_accessible_at_point = component_wrapper_ref_accessible_at_point;
367 0 : iface->remove_focus_handler = component_wrapper_remove_focus_handler;
368 0 : iface->set_extents = component_wrapper_set_extents;
369 0 : iface->set_position = component_wrapper_set_position;
370 0 : iface->set_size = component_wrapper_set_size;
371 : }
372 :
373 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|