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