Deprecate AtkObject::focus-event signal and all related methods
[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 enum {
24   BOUNDS_CHANGED,
25   LAST_SIGNAL
26 };
27
28 static void       atk_component_base_init (AtkComponentIface *class);
29
30 static gboolean   atk_component_real_contains                (AtkComponent *component,
31                                                               gint         x,
32                                                               gint         y,
33                                                               AtkCoordType coord_type);
34
35 static AtkObject* atk_component_real_ref_accessible_at_point (AtkComponent *component,
36                                                               gint         x,
37                                                               gint         y,
38                                                               AtkCoordType coord_type);
39
40 static void      atk_component_real_get_position             (AtkComponent *component,
41                                                               gint         *x,
42                                                               gint         *y,
43                                                               AtkCoordType coord_type);
44
45 static void      atk_component_real_get_size                 (AtkComponent *component,
46                                                               gint         *width,
47                                                               gint         *height);
48
49 static guint atk_component_signals[LAST_SIGNAL] = { 0 };
50
51 GType
52 atk_component_get_type (void)
53 {
54   static GType type = 0;
55
56   if (!type) {
57     static const GTypeInfo tinfo =
58     {
59       sizeof (AtkComponentIface),
60       (GBaseInitFunc) atk_component_base_init,
61       (GBaseFinalizeFunc) NULL,
62
63     };
64
65     type = g_type_register_static (G_TYPE_INTERFACE, "AtkComponent", &tinfo, 0);
66   }
67
68   return type;
69 }
70
71 static void
72 atk_component_base_init (AtkComponentIface *class)
73 {
74   static gboolean initialized = FALSE;
75
76   if (! initialized)
77     {
78       class->ref_accessible_at_point = atk_component_real_ref_accessible_at_point;
79       class->contains = atk_component_real_contains;
80       class->get_position = atk_component_real_get_position;
81       class->get_size = atk_component_real_get_size;
82
83       atk_component_signals[BOUNDS_CHANGED] =
84         g_signal_new ("bounds_changed",
85                       ATK_TYPE_COMPONENT,
86                       G_SIGNAL_RUN_LAST,
87                       G_STRUCT_OFFSET (AtkComponentIface, bounds_changed),
88                       (GSignalAccumulator) NULL, NULL,
89                       g_cclosure_marshal_VOID__BOXED,
90                       G_TYPE_NONE, 1,
91                       ATK_TYPE_RECTANGLE | G_SIGNAL_TYPE_STATIC_SCOPE);
92
93       initialized = TRUE;
94     }
95 }
96
97
98 /**
99  * atk_component_add_focus_handler:
100  * @component: The #AtkComponent to attach the @handler to
101  * @handler: The #AtkFocusHandler to be attached to @component
102  *
103  * Add the specified handler to the set of functions to be called 
104  * when this object receives focus events (in or out). If the handler is
105  * already added it is not added again
106  *
107  * Deprecated: This method is deprecated since ATK version 2.9.4. If
108  * you need to track when an object gains or lose the focus, use
109  * state-changed:focused notification instead.
110  *
111  * Returns: a handler id which can be used in atk_component_remove_focus_handler()
112  * or zero if the handler was already added.
113  **/
114 guint
115 atk_component_add_focus_handler (AtkComponent    *component,
116                                  AtkFocusHandler handler)
117 {
118   AtkComponentIface *iface = NULL;
119   g_return_val_if_fail (ATK_IS_COMPONENT (component), 0);
120
121   iface = ATK_COMPONENT_GET_IFACE (component);
122
123   if (iface->add_focus_handler)
124     return (iface->add_focus_handler) (component, handler);
125   else
126     return 0;
127 }
128
129 /**
130  * atk_component_remove_focus_handler:
131  * @component: the #AtkComponent to remove the focus handler from
132  * @handler_id: the handler id of the focus handler to be removed
133  * from @component
134  *
135  * Remove the handler specified by @handler_id from the list of
136  * functions to be executed when this object receives focus events 
137  * (in or out).
138  *
139  * Deprecated: This method is deprecated since ATK version 2.9.4. If
140  * you need to track when an object gains or lose the focus, use
141  * state-changed:focused notification instead.
142  *
143  **/
144 void
145 atk_component_remove_focus_handler (AtkComponent    *component,
146                                     guint           handler_id)
147 {
148   AtkComponentIface *iface = NULL;
149   g_return_if_fail (ATK_IS_COMPONENT (component));
150
151   iface = ATK_COMPONENT_GET_IFACE (component);
152
153   if (iface->remove_focus_handler)
154     (iface->remove_focus_handler) (component, handler_id);
155 }
156
157 /**
158  * atk_component_contains:
159  * @component: the #AtkComponent
160  * @x: x coordinate
161  * @y: y coordinate
162  * @coord_type: specifies whether the coordinates are relative to the screen
163  * or to the components top level window
164  *
165  * Checks whether the specified point is within the extent of the @component.
166  *
167  * Returns: %TRUE or %FALSE indicating whether the specified point is within
168  * the extent of the @component or not
169  **/
170 gboolean
171 atk_component_contains (AtkComponent    *component,
172                         gint            x,
173                         gint            y,
174                         AtkCoordType    coord_type)
175 {
176   AtkComponentIface *iface = NULL;
177   g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
178
179   iface = ATK_COMPONENT_GET_IFACE (component);
180
181   if (iface->contains)
182     return (iface->contains) (component, x, y, coord_type);
183   else
184     return FALSE;
185 }
186
187 /**
188  * atk_component_ref_accessible_at_point:
189  * @component: the #AtkComponent
190  * @x: x coordinate
191  * @y: y coordinate
192  * @coord_type: specifies whether the coordinates are relative to the screen
193  * or to the components top level window
194  *
195  * Gets a reference to the accessible child, if one exists, at the
196  * coordinate point specified by @x and @y.
197  *
198  * Returns: (transfer full): a reference to the accessible child, if one exists
199  **/
200 AtkObject*
201 atk_component_ref_accessible_at_point (AtkComponent    *component,
202                                        gint            x,
203                                        gint            y,
204                                        AtkCoordType    coord_type)
205 {
206   AtkComponentIface *iface = NULL;
207   g_return_val_if_fail (ATK_IS_COMPONENT (component), NULL);
208
209   iface = ATK_COMPONENT_GET_IFACE (component);
210
211   if (iface->ref_accessible_at_point)
212     return (iface->ref_accessible_at_point) (component, x, y, coord_type);
213   else
214     return NULL;
215 }
216
217 /**
218  * atk_component_get_extents:
219  * @component: an #AtkComponent
220  * @x: address of #gint to put x coordinate
221  * @y: address of #gint to put y coordinate
222  * @width: address of #gint to put width
223  * @height: address of #gint to put height
224  * @coord_type: specifies whether the coordinates are relative to the screen
225  * or to the components top level window
226  *
227  * Gets the rectangle which gives the extent of the @component.
228  *
229  **/
230 void
231 atk_component_get_extents    (AtkComponent    *component,
232                               gint            *x,
233                               gint            *y,
234                               gint            *width,
235                               gint            *height,
236                               AtkCoordType    coord_type)
237 {
238   AtkComponentIface *iface = NULL;
239   gint local_x, local_y, local_width, local_height;
240   gint *real_x, *real_y, *real_width, *real_height;
241
242   g_return_if_fail (ATK_IS_COMPONENT (component));
243
244   if (x)
245     real_x = x;
246   else
247     real_x = &local_x;
248   if (y)
249     real_y = y;
250   else
251     real_y = &local_y;
252   if (width)
253     real_width = width;
254   else
255     real_width = &local_width;
256   if (height)
257     real_height = height;
258   else
259     real_height = &local_height;
260
261   iface = ATK_COMPONENT_GET_IFACE (component);
262
263   if (iface->get_extents)
264     (iface->get_extents) (component, real_x, real_y, real_width, real_height, coord_type);
265 }
266
267 /**
268  * atk_component_get_position:
269  * @component: an #AtkComponent
270  * @x: address of #gint to put x coordinate position
271  * @y: address of #gint to put y coordinate position
272  * @coord_type: specifies whether the coordinates are relative to the screen
273  * or to the components top level window
274  *
275  * Gets the position of @component in the form of 
276  * a point specifying @component's top-left corner.
277  **/
278 void
279 atk_component_get_position   (AtkComponent    *component,
280                               gint            *x,
281                               gint            *y,
282                               AtkCoordType    coord_type)
283 {
284   AtkComponentIface *iface = NULL;
285   gint local_x, local_y;
286   gint *real_x, *real_y;
287
288   g_return_if_fail (ATK_IS_COMPONENT (component));
289
290   if (x)
291     real_x = x;
292   else
293     real_x = &local_x;
294   if (y)
295     real_y = y;
296   else
297     real_y = &local_y;
298
299   iface = ATK_COMPONENT_GET_IFACE (component);
300
301   if (iface->get_position)
302     (iface->get_position) (component, real_x, real_y, coord_type);
303 }
304
305 /**
306  * atk_component_get_size:
307  * @component: an #AtkComponent
308  * @width: address of #gint to put width of @component
309  * @height: address of #gint to put height of @component
310  *
311  * Gets the size of the @component in terms of width and height.
312  **/
313 void
314 atk_component_get_size       (AtkComponent    *component,
315                               gint            *width,
316                               gint            *height)
317 {
318   AtkComponentIface *iface = NULL;
319   gint local_width, local_height;
320   gint *real_width, *real_height;
321
322   g_return_if_fail (ATK_IS_COMPONENT (component));
323
324   if (width)
325     real_width = width;
326   else
327     real_width = &local_width;
328   if (height)
329     real_height = height;
330   else
331     real_height = &local_height;
332
333   g_return_if_fail (ATK_IS_COMPONENT (component));
334
335   iface = ATK_COMPONENT_GET_IFACE (component);
336
337   if (iface->get_size)
338     (iface->get_size) (component, real_width, real_height);
339 }
340
341 /**
342  * atk_component_get_layer:
343  * @component: an #AtkComponent
344  *
345  * Gets the layer of the component.
346  *
347  * Returns: an #AtkLayer which is the layer of the component
348  **/
349 AtkLayer
350 atk_component_get_layer (AtkComponent *component) 
351 {
352   AtkComponentIface *iface;
353
354   g_return_val_if_fail (ATK_IS_COMPONENT (component), ATK_LAYER_INVALID);
355
356   iface = ATK_COMPONENT_GET_IFACE (component);
357   if (iface->get_layer)
358     return (iface->get_layer) (component);
359   else
360     return ATK_LAYER_WIDGET;
361 }
362
363 /**
364  * atk_component_get_mdi_zorder:
365  * @component: an #AtkComponent
366  *
367  * Gets the zorder of the component. The value G_MININT will be returned 
368  * if the layer of the component is not ATK_LAYER_MDI or ATK_LAYER_WINDOW.
369  *
370  * Returns: a gint which is the zorder of the component, i.e. the depth at 
371  * which the component is shown in relation to other components in the same 
372  * container.
373  **/
374 gint
375 atk_component_get_mdi_zorder (AtkComponent *component) 
376 {
377   AtkComponentIface *iface;
378
379   g_return_val_if_fail (ATK_IS_COMPONENT (component), G_MININT);
380
381   iface = ATK_COMPONENT_GET_IFACE (component);
382   if (iface->get_mdi_zorder)
383     return (iface->get_mdi_zorder) (component);
384   else
385     return G_MININT;
386 }
387
388 /**
389  * atk_component_get_alpha:
390  * @component: an #AtkComponent
391  *
392  * Returns the alpha value (i.e. the opacity) for this
393  * @component, on a scale from 0 (fully transparent) to 1.0
394  * (fully opaque).
395  *
396  * Returns: An alpha value from 0 to 1.0, inclusive.
397  * Since: 1.12
398  **/
399 gdouble
400 atk_component_get_alpha (AtkComponent    *component)
401 {
402   AtkComponentIface *iface;
403
404   g_return_val_if_fail (ATK_IS_COMPONENT (component), G_MININT);
405
406   iface = ATK_COMPONENT_GET_IFACE (component);
407   if (iface->get_alpha)
408     return (iface->get_alpha) (component);
409   else
410     return (gdouble) 1.0;
411 }
412
413 /**
414  * atk_component_grab_focus:
415  * @component: an #AtkComponent
416  *
417  * Grabs focus for this @component.
418  *
419  * Returns: %TRUE if successful, %FALSE otherwise.
420  **/
421 gboolean
422 atk_component_grab_focus (AtkComponent    *component)
423 {
424   AtkComponentIface *iface = NULL;
425   g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
426
427   iface = ATK_COMPONENT_GET_IFACE (component);
428
429   if (iface->grab_focus)
430     return (iface->grab_focus) (component);
431   else
432     return FALSE;
433 }
434
435 /**
436  * atk_component_set_extents:
437  * @component: an #AtkComponent
438  * @x: x coordinate
439  * @y: y coordinate
440  * @width: width to set for @component
441  * @height: height to set for @component
442  * @coord_type: specifies whether the coordinates are relative to the screen
443  * or to the components top level window
444  *
445  * Sets the extents of @component.
446  *
447  * Returns: %TRUE or %FALSE whether the extents were set or not
448  **/
449 gboolean
450 atk_component_set_extents   (AtkComponent    *component,
451                              gint            x,
452                              gint            y,
453                              gint            width,
454                              gint            height,
455                              AtkCoordType    coord_type)
456 {
457   AtkComponentIface *iface = NULL;
458   g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
459
460   iface = ATK_COMPONENT_GET_IFACE (component);
461
462   if (iface->set_extents)
463     return (iface->set_extents) (component, x, y, width, height, coord_type);
464   else
465     return FALSE;
466 }
467
468 /**
469  * atk_component_set_position:
470  * @component: an #AtkComponent
471  * @x: x coordinate
472  * @y: y coordinate
473  * @coord_type: specifies whether the coordinates are relative to the screen
474  * or to the components top level window
475  *
476  * Sets the postition of @component.
477  * 
478  * Returns: %TRUE or %FALSE whether or not the position was set or not
479  **/
480 gboolean
481 atk_component_set_position   (AtkComponent    *component,
482                               gint            x,
483                               gint            y,
484                               AtkCoordType    coord_type)
485 {
486   AtkComponentIface *iface = NULL;
487   g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
488
489   iface = ATK_COMPONENT_GET_IFACE (component);
490
491   if (iface->set_position)
492     return (iface->set_position) (component, x, y, coord_type);
493   else
494     return FALSE;
495 }
496
497 /**
498  * atk_component_set_size:
499  * @component: an #AtkComponent
500  * @width: width to set for @component
501  * @height: height to set for @component
502  *
503  * Set the size of the @component in terms of width and height.
504  *
505  * Returns: %TRUE or %FALSE whether the size was set or not
506  **/
507 gboolean
508 atk_component_set_size       (AtkComponent    *component,
509                               gint            x,
510                               gint            y)
511 {
512   AtkComponentIface *iface = NULL;
513   g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
514
515   iface = ATK_COMPONENT_GET_IFACE (component);
516
517   if (iface->set_size)
518     return (iface->set_size) (component, x, y);
519   else
520     return FALSE;
521 }
522
523 static gboolean
524 atk_component_real_contains (AtkComponent *component,
525                              gint         x,
526                              gint         y,
527                              AtkCoordType coord_type)
528 {
529   gint real_x, real_y, width, height;
530
531   real_x = real_y = width = height = 0;
532
533   atk_component_get_extents (component, &real_x, &real_y, &width, &height, coord_type);
534
535   if ((x >= real_x) &&
536       (x < real_x + width) &&
537       (y >= real_y) &&
538       (y < real_y + height))
539     return TRUE;
540   else
541     return FALSE;
542 }
543
544 static AtkObject* 
545 atk_component_real_ref_accessible_at_point (AtkComponent *component,
546                                             gint         x,
547                                             gint         y,
548                                             AtkCoordType coord_type)
549 {
550   gint count, i;
551
552   count = atk_object_get_n_accessible_children (ATK_OBJECT (component));
553
554   for (i = 0; i < count; i++)
555   {
556     AtkObject *obj;
557
558     obj = atk_object_ref_accessible_child (ATK_OBJECT (component), i);
559
560     if (obj != NULL)
561     {
562       if (atk_component_contains (ATK_COMPONENT (obj), x, y, coord_type))
563       {
564         return obj;
565       }
566       else
567       {
568         g_object_unref (obj);
569       }
570     }
571   }
572   return NULL;
573 }
574
575 static void
576 atk_component_real_get_position (AtkComponent *component,
577                                  gint         *x,
578                                  gint         *y,
579                                  AtkCoordType coord_type)
580 {
581   gint width, height;
582
583   atk_component_get_extents (component, x, y, &width, &height, coord_type);
584 }
585
586 static void
587 atk_component_real_get_size (AtkComponent *component,
588                              gint         *width,
589                              gint         *height)
590 {
591   gint x, y;
592   AtkCoordType coord_type;
593
594   /*
595    * Pick one coordinate type; it does not matter for size
596    */
597   coord_type = ATK_XY_WINDOW;
598
599   atk_component_get_extents (component, &x, &y, width, height, coord_type);
600 }
601
602 static AtkRectangle *
603 atk_rectangle_copy (const AtkRectangle *rectangle)
604 {
605   AtkRectangle *result = g_new (AtkRectangle, 1);
606   *result = *rectangle;
607
608   return result;
609 }
610
611 GType
612 atk_rectangle_get_type (void)
613 {
614   static GType our_type = 0;
615
616   if (our_type == 0)
617     our_type = g_boxed_type_register_static ("AtkRectangle",
618                                              (GBoxedCopyFunc)atk_rectangle_copy,
619                                              (GBoxedFreeFunc)g_free);
620   return our_type;
621 }
622