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