xref: /trunk/main/vcl/unx/gtk/a11y/atkcomponent.cxx (revision 9f62ea84)
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