Change argument of get_layer and get_mdi_zorder function pointers to be
[platform/upstream/atk.git] / atk / atkcomponent.c
1 /* ATK -  Accessibility Toolkit
2  * Copyright 2001 Sun Microsystems Inc.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20
21 #include "atkcomponent.h"
22
23 static gboolean   atk_component_real_contains                (AtkComponent *component,
24                                                               gint         x,
25                                                               gint         y,
26                                                               AtkCoordType coord_type);
27
28 static AtkObject* atk_component_real_ref_accessible_at_point (AtkComponent *component,
29                                                               gint         x,
30                                                               gint         y,
31                                                               AtkCoordType coord_type);
32
33 static void      atk_component_real_get_position             (AtkComponent *component,
34                                                               gint         *x,
35                                                               gint         *y,
36                                                               AtkCoordType coord_type);
37
38 static void      atk_component_real_get_size                 (AtkComponent *component,
39                                                               gint         *width,
40                                                               gint         *height);
41
42 GType
43 atk_component_get_type (void)
44 {
45   static GType type = 0;
46
47   if (!type) {
48     static const GTypeInfo tinfo =
49     {
50       sizeof (AtkComponentIface),
51       (GBaseInitFunc) NULL,
52       (GBaseFinalizeFunc) NULL,
53
54     };
55
56     type = g_type_register_static (G_TYPE_INTERFACE, "AtkComponent", &tinfo, 0);
57   }
58
59   return type;
60 }
61
62 /**
63  * atk_component_add_focus_handler:
64  * @component: The #AtkComponent to attach the @handler to
65  * @handler: The #AtkFocusHandler to be attached to @component
66  *
67  * Add the specified handler to the set of functions to be called 
68  * when this object receives focus events (in or out). If the handler is
69  * already added it is not added again
70  *
71  * Returns: a handler id which can be used in atk_component_remove_focus_handler
72  * or zero if the handler was already added.
73  **/
74 guint
75 atk_component_add_focus_handler (AtkComponent    *component,
76                                  AtkFocusHandler handler)
77 {
78   AtkComponentIface *iface = NULL;
79   g_return_val_if_fail (ATK_IS_COMPONENT (component), 0);
80
81   iface = ATK_COMPONENT_GET_IFACE (component);
82
83   if (iface->add_focus_handler)
84     return (iface->add_focus_handler) (component, handler);
85   else
86     return 0;
87 }
88
89 /**
90  * atk_component_remove_focus_handler:
91  * @component: the #AtkComponent to remove the focus handler from
92  * @handler_id: the handler id of the focus handler to be removed
93  * from @component
94  *
95  * Remove the handler specified by @handler_id from the list of
96  * functions to be executed when this object receives focus events 
97  * (in or out).
98  **/
99 void
100 atk_component_remove_focus_handler (AtkComponent    *component,
101                                     guint           handler_id)
102 {
103   AtkComponentIface *iface = NULL;
104   g_return_if_fail (ATK_IS_COMPONENT (component));
105
106   iface = ATK_COMPONENT_GET_IFACE (component);
107
108   if (iface->remove_focus_handler)
109     (iface->remove_focus_handler) (component, handler_id);
110 }
111
112 /**
113  * atk_component_contains:
114  * @component: the #AtkComponent
115  * @x: x coordinate
116  * @y: y coordinate
117  * @coord_type: specifies whether the coordinates are relative to the screen
118  * or to the components top level window
119  *
120  * Checks whether the specified point is within the extent of the @component.
121  *
122  * Returns: %TRUE or %FALSE indicating whether the specified point is within
123  * the extent of the @component or not
124  **/
125 gboolean
126 atk_component_contains (AtkComponent    *component,
127                         gint            x,
128                         gint            y,
129                         AtkCoordType    coord_type)
130 {
131   AtkComponentIface *iface = NULL;
132   g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
133
134   iface = ATK_COMPONENT_GET_IFACE (component);
135
136   if (iface->contains)
137     return (iface->contains) (component, x, y, coord_type);
138   else
139   {
140     /*
141      * if this method is not overridden use the default implementation.
142      */
143     return atk_component_real_contains (component, x, y, coord_type);
144   }
145 }
146
147 /**
148  * atk_component_ref_accessible_at_point:
149  * @component: the #AtkComponent
150  * @x: x coordinate
151  * @y: y coordinate
152  * @coord_type: specifies whether the coordinates are relative to the screen
153  * or to the components top level window
154  *
155  * Gets a reference to the accessible child, if one exists, at the
156  * coordinate point specified by @x and @y.
157  *
158  * Returns: a reference to the accessible child, if one exists
159  **/
160 AtkObject*
161 atk_component_ref_accessible_at_point (AtkComponent    *component,
162                                        gint            x,
163                                        gint            y,
164                                        AtkCoordType    coord_type)
165 {
166   AtkComponentIface *iface = NULL;
167   g_return_val_if_fail (ATK_IS_COMPONENT (component), NULL);
168
169   iface = ATK_COMPONENT_GET_IFACE (component);
170
171   if (iface->ref_accessible_at_point)
172     return (iface->ref_accessible_at_point) (component, x, y, coord_type);
173   else
174   {
175     /*
176      * if this method is not overridden use the default implementation.
177      */
178     return atk_component_real_ref_accessible_at_point (component, x, y, coord_type);
179   }
180 }
181
182 /**
183  * atk_component_get_extents:
184  * @component: an #AtkComponent
185  * @x: address of #gint to put x coordinate
186  * @y: address of #gint to put y coordinate
187  * @width: address of #gint to put width
188  * @height: address of #gint to put height
189  * @coord_type: specifies whether the coordinates are relative to the screen
190  * or to the components top level window
191  *
192  * Gets the rectangle which gives the extent of the @component.
193  *
194  **/
195 void
196 atk_component_get_extents    (AtkComponent    *component,
197                               gint            *x,
198                               gint            *y,
199                               gint            *width,
200                               gint            *height,
201                               AtkCoordType    coord_type)
202 {
203   AtkComponentIface *iface = NULL;
204   gint local_x, local_y, local_width, local_height;
205   gint *real_x, *real_y, *real_width, *real_height;
206
207   g_return_if_fail (ATK_IS_COMPONENT (component));
208
209   if (x)
210     real_x = x;
211   else
212     real_x = &local_x;
213   if (y)
214     real_y = y;
215   else
216     real_y = &local_y;
217   if (width)
218     real_width = width;
219   else
220     real_width = &local_width;
221   if (height)
222     real_height = height;
223   else
224     real_height = &local_height;
225
226   iface = ATK_COMPONENT_GET_IFACE (component);
227
228   if (iface->get_extents)
229     (iface->get_extents) (component, real_x, real_y, real_width, real_height, coord_type);
230 }
231
232 /**
233  * atk_component_get_position:
234  * @component: an #AtkComponent
235  * @x: address of #gint to put x coordinate position
236  * @y: address of #gint to put y coordinate position
237  * @coord_type: specifies whether the coordinates are relative to the screen
238  * or to the components top level window
239  *
240  * Gets the position of @component in the form of 
241  * a point specifying @component's top-left corner.
242  **/
243 void
244 atk_component_get_position   (AtkComponent    *component,
245                               gint            *x,
246                               gint            *y,
247                               AtkCoordType    coord_type)
248 {
249   AtkComponentIface *iface = NULL;
250   gint local_x, local_y;
251   gint *real_x, *real_y;
252
253   g_return_if_fail (ATK_IS_COMPONENT (component));
254
255   if (x)
256     real_x = x;
257   else
258     real_x = &local_x;
259   if (y)
260     real_y = y;
261   else
262     real_y = &local_y;
263
264   iface = ATK_COMPONENT_GET_IFACE (component);
265
266   if (iface->get_position)
267     (iface->get_position) (component, real_x, real_y, coord_type);
268   else
269   {
270     /*
271      * if this method is not overridden use the default implementation.
272      */
273     atk_component_real_get_position (component, real_x, real_y, coord_type);
274   }
275 }
276
277 /**
278  * atk_component_get_size:
279  * @component: an #AtkComponent
280  * @width: address of #gint to put width of @component
281  * @height: address of #gint to put height of @component
282  *
283  * Gets the size of the @component in terms of width and height.
284  **/
285 void
286 atk_component_get_size       (AtkComponent    *component,
287                               gint            *width,
288                               gint            *height)
289 {
290   AtkComponentIface *iface = NULL;
291   gint local_width, local_height;
292   gint *real_width, *real_height;
293
294   g_return_if_fail (ATK_IS_COMPONENT (component));
295
296   if (width)
297     real_width = width;
298   else
299     real_width = &local_width;
300   if (height)
301     real_height = height;
302   else
303     real_height = &local_height;
304
305   g_return_if_fail (ATK_IS_COMPONENT (component));
306
307   iface = ATK_COMPONENT_GET_IFACE (component);
308
309   if (iface->get_size)
310     (iface->get_size) (component, real_width, real_height);
311   else
312   {
313     /*
314      * if this method is not overridden use the default implementation.
315      */
316     atk_component_real_get_size (component, real_width, real_height);
317   }
318 }
319
320 /**
321  * atk_component_get_layer:
322  * @component: an #AtkComponent
323  *
324  * Gets the layer of the component.
325  *
326  * Returns: an #AtkLayer which is the layer of the component
327  **/
328 AtkLayer
329 atk_component_get_layer (AtkComponent *component) 
330 {
331   AtkComponentIface *iface;
332
333   g_return_val_if_fail (ATK_IS_COMPONENT (component), ATK_LAYER_INVALID);
334
335   iface = ATK_COMPONENT_GET_IFACE (component);
336   if (iface->get_layer)
337     return (iface->get_layer) (component);
338   else
339     return ATK_LAYER_WIDGET;
340 }
341
342 /**
343  * atk_component_get_mdi_zorder:
344  * @component: an #AtkComponent
345  *
346  * Gets the zorder of the component. The value G_MININT will be returned 
347  * if the layer of the component is not ATK_LAYER_MDI.
348  *
349  * Returns: a gint which is the zorder of the component, i.e. the depth at 
350  * which the component is shown in relation to other components in the same 
351  * container.
352  **/
353 gint
354 atk_component_get_mdi_zorder (AtkComponent *component) 
355 {
356   AtkComponentIface *iface;
357
358   g_return_val_if_fail (ATK_IS_COMPONENT (component), G_MININT);
359
360   iface = ATK_COMPONENT_GET_IFACE (component);
361   if (iface->get_mdi_zorder)
362     return (iface->get_mdi_zorder) (component);
363   else
364     return G_MININT;
365 }
366
367 /**
368  * atk_component_grab_focus:
369  * @component: an #AtkComponent
370  *
371  * Grabs focus for this @component.
372  *
373  * Returns: %TRUE if successful, %FALSE otherwise.
374  **/
375 gboolean
376 atk_component_grab_focus (AtkComponent    *component)
377 {
378   AtkComponentIface *iface = NULL;
379   g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
380
381   iface = ATK_COMPONENT_GET_IFACE (component);
382
383   if (iface->grab_focus)
384     return (iface->grab_focus) (component);
385   else
386     return FALSE;
387 }
388
389 /**
390  * atk_component_set_extents:
391  * @component: an #AtkComponent
392  * @x: x coordinate
393  * @y: y coordinate
394  * @width: width to set for @component
395  * @height: height to set for @component
396  * @coord_type: specifies whether the coordinates are relative to the screen
397  * or to the components top level window
398  *
399  * Sets the extents of @component.
400  *
401  * Returns: %TRUE or %FALSE whether the extents were set or not
402  **/
403 gboolean
404 atk_component_set_extents   (AtkComponent    *component,
405                              gint            x,
406                              gint            y,
407                              gint            width,
408                              gint            height,
409                              AtkCoordType    coord_type)
410 {
411   AtkComponentIface *iface = NULL;
412   g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
413
414   iface = ATK_COMPONENT_GET_IFACE (component);
415
416   if (iface->set_extents)
417     return (iface->set_extents) (component, x, y, width, height, coord_type);
418   else
419     return FALSE;
420 }
421
422 /**
423  * atk_component_set_position:
424  * @component: an #AtkComponent
425  * @x: x coordinate
426  * @y: y coordinate
427  * @coord_type: specifies whether the coordinates are relative to the screen
428  * or to the components top level window
429  *
430  * Sets the postition of @component.
431  * 
432  * Returns: %TRUE or %FALSE whether or not the position was set or not
433  **/
434 gboolean
435 atk_component_set_position   (AtkComponent    *component,
436                               gint            x,
437                               gint            y,
438                               AtkCoordType    coord_type)
439 {
440   AtkComponentIface *iface = NULL;
441   g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
442
443   iface = ATK_COMPONENT_GET_IFACE (component);
444
445   if (iface->set_position)
446     return (iface->set_position) (component, x, y, coord_type);
447   else
448     return FALSE;
449 }
450
451 /**
452  * atk_component_set_size:
453  * @component: an #AtkComponent
454  * @width: width to set for @component
455  * @height: height to set for @component
456  *
457  * Set the size of the @component in terms of width and height.
458  *
459  * Returns: %TRUE or %FALSE whether the size was set or not
460  **/
461 gboolean
462 atk_component_set_size       (AtkComponent    *component,
463                               gint            x,
464                               gint            y)
465 {
466   AtkComponentIface *iface = NULL;
467   g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
468
469   iface = ATK_COMPONENT_GET_IFACE (component);
470
471   if (iface->set_size)
472     return (iface->set_size) (component, x, y);
473   else
474     return FALSE;
475 }
476
477 static gboolean
478 atk_component_real_contains (AtkComponent *component,
479                              gint         x,
480                              gint         y,
481                              AtkCoordType coord_type)
482 {
483   gint real_x, real_y, width, height;
484
485   real_x = real_y = width = height = 0;
486
487   atk_component_get_extents (component, &real_x, &real_y, &width, &height, coord_type);
488
489   if ((x >= real_x) &&
490       (x < real_x + width) &&
491       (y >= real_y) &&
492       (y < real_y + height))
493     return TRUE;
494   else
495     return FALSE;
496 }
497
498 static AtkObject* 
499 atk_component_real_ref_accessible_at_point (AtkComponent *component,
500                                             gint         x,
501                                             gint         y,
502                                             AtkCoordType coord_type)
503 {
504   gint count, i;
505
506   count = atk_object_get_n_accessible_children (ATK_OBJECT (component));
507
508   for (i = 0; i < count; i++)
509   {
510     AtkObject *obj;
511
512     obj = atk_object_ref_accessible_child (ATK_OBJECT (component), i);
513
514     if (obj != NULL)
515     {
516       if (atk_component_contains (ATK_COMPONENT (obj), x, y, coord_type))
517       {
518         return obj;
519       }
520       else
521       {
522         g_object_unref (obj);
523       }
524     }
525   }
526   return NULL;
527 }
528
529 static void
530 atk_component_real_get_position (AtkComponent *component,
531                                  gint         *x,
532                                  gint         *y,
533                                  AtkCoordType coord_type)
534 {
535   gint width, height;
536
537   atk_component_get_extents (component, x, y, &width, &height, coord_type);
538 }
539
540 static void
541 atk_component_real_get_size (AtkComponent *component,
542                              gint         *width,
543                              gint         *height)
544 {
545   gint x, y;
546   AtkCoordType coord_type;
547
548   /*
549    * Pick one coordinate type; it does not matter for size
550    */
551   coord_type = ATK_XY_WINDOW;
552
553   atk_component_get_extents (component, &x, &y, width, height, coord_type);
554 }
555
556
557