source: trunk/third/atk/atk/atkcomponent.c @ 20776

Revision 20776, 16.6 KB checked in by ghudson, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r20775, which included commits to RCS files with non-trunk default branches.
  • Property svn:executable set to *
Line 
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
23enum {
24  BOUNDS_CHANGED,
25  LAST_SIGNAL
26};
27
28static void       atk_component_base_init (AtkComponentIface *class);
29
30static gboolean   atk_component_real_contains                (AtkComponent *component,
31                                                              gint         x,
32                                                              gint         y,
33                                                              AtkCoordType coord_type);
34
35static AtkObject* atk_component_real_ref_accessible_at_point (AtkComponent *component,
36                                                              gint         x,
37                                                              gint         y,
38                                                              AtkCoordType coord_type);
39
40static void      atk_component_real_get_position             (AtkComponent *component,
41                                                              gint         *x,
42                                                              gint         *y,
43                                                              AtkCoordType coord_type);
44
45static void      atk_component_real_get_size                 (AtkComponent *component,
46                                                              gint         *width,
47                                                              gint         *height);
48
49static guint atk_component_signals[LAST_SIGNAL] = { 0 };
50
51GType
52atk_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
71static void
72atk_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 * Returns: a handler id which can be used in atk_component_remove_focus_handler
108 * or zero if the handler was already added.
109 **/
110guint
111atk_component_add_focus_handler (AtkComponent    *component,
112                                 AtkFocusHandler handler)
113{
114  AtkComponentIface *iface = NULL;
115  g_return_val_if_fail (ATK_IS_COMPONENT (component), 0);
116
117  iface = ATK_COMPONENT_GET_IFACE (component);
118
119  if (iface->add_focus_handler)
120    return (iface->add_focus_handler) (component, handler);
121  else
122    return 0;
123}
124
125/**
126 * atk_component_remove_focus_handler:
127 * @component: the #AtkComponent to remove the focus handler from
128 * @handler_id: the handler id of the focus handler to be removed
129 * from @component
130 *
131 * Remove the handler specified by @handler_id from the list of
132 * functions to be executed when this object receives focus events
133 * (in or out).
134 **/
135void
136atk_component_remove_focus_handler (AtkComponent    *component,
137                                    guint           handler_id)
138{
139  AtkComponentIface *iface = NULL;
140  g_return_if_fail (ATK_IS_COMPONENT (component));
141
142  iface = ATK_COMPONENT_GET_IFACE (component);
143
144  if (iface->remove_focus_handler)
145    (iface->remove_focus_handler) (component, handler_id);
146}
147
148/**
149 * atk_component_contains:
150 * @component: the #AtkComponent
151 * @x: x coordinate
152 * @y: y coordinate
153 * @coord_type: specifies whether the coordinates are relative to the screen
154 * or to the components top level window
155 *
156 * Checks whether the specified point is within the extent of the @component.
157 *
158 * Returns: %TRUE or %FALSE indicating whether the specified point is within
159 * the extent of the @component or not
160 **/
161gboolean
162atk_component_contains (AtkComponent    *component,
163                        gint            x,
164                        gint            y,
165                        AtkCoordType    coord_type)
166{
167  AtkComponentIface *iface = NULL;
168  g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
169
170  iface = ATK_COMPONENT_GET_IFACE (component);
171
172  if (iface->contains)
173    return (iface->contains) (component, x, y, coord_type);
174  else
175    return FALSE;
176}
177
178/**
179 * atk_component_ref_accessible_at_point:
180 * @component: the #AtkComponent
181 * @x: x coordinate
182 * @y: y coordinate
183 * @coord_type: specifies whether the coordinates are relative to the screen
184 * or to the components top level window
185 *
186 * Gets a reference to the accessible child, if one exists, at the
187 * coordinate point specified by @x and @y.
188 *
189 * Returns: a reference to the accessible child, if one exists
190 **/
191AtkObject*
192atk_component_ref_accessible_at_point (AtkComponent    *component,
193                                       gint            x,
194                                       gint            y,
195                                       AtkCoordType    coord_type)
196{
197  AtkComponentIface *iface = NULL;
198  g_return_val_if_fail (ATK_IS_COMPONENT (component), NULL);
199
200  iface = ATK_COMPONENT_GET_IFACE (component);
201
202  if (iface->ref_accessible_at_point)
203    return (iface->ref_accessible_at_point) (component, x, y, coord_type);
204  else
205    return NULL;
206}
207
208/**
209 * atk_component_get_extents:
210 * @component: an #AtkComponent
211 * @x: address of #gint to put x coordinate
212 * @y: address of #gint to put y coordinate
213 * @width: address of #gint to put width
214 * @height: address of #gint to put height
215 * @coord_type: specifies whether the coordinates are relative to the screen
216 * or to the components top level window
217 *
218 * Gets the rectangle which gives the extent of the @component.
219 *
220 **/
221void
222atk_component_get_extents    (AtkComponent    *component,
223                              gint            *x,
224                              gint            *y,
225                              gint            *width,
226                              gint            *height,
227                              AtkCoordType    coord_type)
228{
229  AtkComponentIface *iface = NULL;
230  gint local_x, local_y, local_width, local_height;
231  gint *real_x, *real_y, *real_width, *real_height;
232
233  g_return_if_fail (ATK_IS_COMPONENT (component));
234
235  if (x)
236    real_x = x;
237  else
238    real_x = &local_x;
239  if (y)
240    real_y = y;
241  else
242    real_y = &local_y;
243  if (width)
244    real_width = width;
245  else
246    real_width = &local_width;
247  if (height)
248    real_height = height;
249  else
250    real_height = &local_height;
251
252  iface = ATK_COMPONENT_GET_IFACE (component);
253
254  if (iface->get_extents)
255    (iface->get_extents) (component, real_x, real_y, real_width, real_height, coord_type);
256}
257
258/**
259 * atk_component_get_position:
260 * @component: an #AtkComponent
261 * @x: address of #gint to put x coordinate position
262 * @y: address of #gint to put y coordinate position
263 * @coord_type: specifies whether the coordinates are relative to the screen
264 * or to the components top level window
265 *
266 * Gets the position of @component in the form of
267 * a point specifying @component's top-left corner.
268 **/
269void
270atk_component_get_position   (AtkComponent    *component,
271                              gint            *x,
272                              gint            *y,
273                              AtkCoordType    coord_type)
274{
275  AtkComponentIface *iface = NULL;
276  gint local_x, local_y;
277  gint *real_x, *real_y;
278
279  g_return_if_fail (ATK_IS_COMPONENT (component));
280
281  if (x)
282    real_x = x;
283  else
284    real_x = &local_x;
285  if (y)
286    real_y = y;
287  else
288    real_y = &local_y;
289
290  iface = ATK_COMPONENT_GET_IFACE (component);
291
292  if (iface->get_position)
293    (iface->get_position) (component, real_x, real_y, coord_type);
294}
295
296/**
297 * atk_component_get_size:
298 * @component: an #AtkComponent
299 * @width: address of #gint to put width of @component
300 * @height: address of #gint to put height of @component
301 *
302 * Gets the size of the @component in terms of width and height.
303 **/
304void
305atk_component_get_size       (AtkComponent    *component,
306                              gint            *width,
307                              gint            *height)
308{
309  AtkComponentIface *iface = NULL;
310  gint local_width, local_height;
311  gint *real_width, *real_height;
312
313  g_return_if_fail (ATK_IS_COMPONENT (component));
314
315  if (width)
316    real_width = width;
317  else
318    real_width = &local_width;
319  if (height)
320    real_height = height;
321  else
322    real_height = &local_height;
323
324  g_return_if_fail (ATK_IS_COMPONENT (component));
325
326  iface = ATK_COMPONENT_GET_IFACE (component);
327
328  if (iface->get_size)
329    (iface->get_size) (component, real_width, real_height);
330}
331
332/**
333 * atk_component_get_layer:
334 * @component: an #AtkComponent
335 *
336 * Gets the layer of the component.
337 *
338 * Returns: an #AtkLayer which is the layer of the component
339 **/
340AtkLayer
341atk_component_get_layer (AtkComponent *component)
342{
343  AtkComponentIface *iface;
344
345  g_return_val_if_fail (ATK_IS_COMPONENT (component), ATK_LAYER_INVALID);
346
347  iface = ATK_COMPONENT_GET_IFACE (component);
348  if (iface->get_layer)
349    return (iface->get_layer) (component);
350  else
351    return ATK_LAYER_WIDGET;
352}
353
354/**
355 * atk_component_get_mdi_zorder:
356 * @component: an #AtkComponent
357 *
358 * Gets the zorder of the component. The value G_MININT will be returned
359 * if the layer of the component is not ATK_LAYER_MDI or ATK_LAYER_WINDOW.
360 *
361 * Returns: a gint which is the zorder of the component, i.e. the depth at
362 * which the component is shown in relation to other components in the same
363 * container.
364 **/
365gint
366atk_component_get_mdi_zorder (AtkComponent *component)
367{
368  AtkComponentIface *iface;
369
370  g_return_val_if_fail (ATK_IS_COMPONENT (component), G_MININT);
371
372  iface = ATK_COMPONENT_GET_IFACE (component);
373  if (iface->get_mdi_zorder)
374    return (iface->get_mdi_zorder) (component);
375  else
376    return G_MININT;
377}
378
379/**
380 * atk_component_grab_focus:
381 * @component: an #AtkComponent
382 *
383 * Grabs focus for this @component.
384 *
385 * Returns: %TRUE if successful, %FALSE otherwise.
386 **/
387gboolean
388atk_component_grab_focus (AtkComponent    *component)
389{
390  AtkComponentIface *iface = NULL;
391  g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
392
393  iface = ATK_COMPONENT_GET_IFACE (component);
394
395  if (iface->grab_focus)
396    return (iface->grab_focus) (component);
397  else
398    return FALSE;
399}
400
401/**
402 * atk_component_set_extents:
403 * @component: an #AtkComponent
404 * @x: x coordinate
405 * @y: y coordinate
406 * @width: width to set for @component
407 * @height: height to set for @component
408 * @coord_type: specifies whether the coordinates are relative to the screen
409 * or to the components top level window
410 *
411 * Sets the extents of @component.
412 *
413 * Returns: %TRUE or %FALSE whether the extents were set or not
414 **/
415gboolean
416atk_component_set_extents   (AtkComponent    *component,
417                             gint            x,
418                             gint            y,
419                             gint            width,
420                             gint            height,
421                             AtkCoordType    coord_type)
422{
423  AtkComponentIface *iface = NULL;
424  g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
425
426  iface = ATK_COMPONENT_GET_IFACE (component);
427
428  if (iface->set_extents)
429    return (iface->set_extents) (component, x, y, width, height, coord_type);
430  else
431    return FALSE;
432}
433
434/**
435 * atk_component_set_position:
436 * @component: an #AtkComponent
437 * @x: x coordinate
438 * @y: y coordinate
439 * @coord_type: specifies whether the coordinates are relative to the screen
440 * or to the components top level window
441 *
442 * Sets the postition of @component.
443 *
444 * Returns: %TRUE or %FALSE whether or not the position was set or not
445 **/
446gboolean
447atk_component_set_position   (AtkComponent    *component,
448                              gint            x,
449                              gint            y,
450                              AtkCoordType    coord_type)
451{
452  AtkComponentIface *iface = NULL;
453  g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
454
455  iface = ATK_COMPONENT_GET_IFACE (component);
456
457  if (iface->set_position)
458    return (iface->set_position) (component, x, y, coord_type);
459  else
460    return FALSE;
461}
462
463/**
464 * atk_component_set_size:
465 * @component: an #AtkComponent
466 * @width: width to set for @component
467 * @height: height to set for @component
468 *
469 * Set the size of the @component in terms of width and height.
470 *
471 * Returns: %TRUE or %FALSE whether the size was set or not
472 **/
473gboolean
474atk_component_set_size       (AtkComponent    *component,
475                              gint            x,
476                              gint            y)
477{
478  AtkComponentIface *iface = NULL;
479  g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
480
481  iface = ATK_COMPONENT_GET_IFACE (component);
482
483  if (iface->set_size)
484    return (iface->set_size) (component, x, y);
485  else
486    return FALSE;
487}
488
489static gboolean
490atk_component_real_contains (AtkComponent *component,
491                             gint         x,
492                             gint         y,
493                             AtkCoordType coord_type)
494{
495  gint real_x, real_y, width, height;
496
497  real_x = real_y = width = height = 0;
498
499  atk_component_get_extents (component, &real_x, &real_y, &width, &height, coord_type);
500
501  if ((x >= real_x) &&
502      (x < real_x + width) &&
503      (y >= real_y) &&
504      (y < real_y + height))
505    return TRUE;
506  else
507    return FALSE;
508}
509
510static AtkObject*
511atk_component_real_ref_accessible_at_point (AtkComponent *component,
512                                            gint         x,
513                                            gint         y,
514                                            AtkCoordType coord_type)
515{
516  gint count, i;
517
518  count = atk_object_get_n_accessible_children (ATK_OBJECT (component));
519
520  for (i = 0; i < count; i++)
521  {
522    AtkObject *obj;
523
524    obj = atk_object_ref_accessible_child (ATK_OBJECT (component), i);
525
526    if (obj != NULL)
527    {
528      if (atk_component_contains (ATK_COMPONENT (obj), x, y, coord_type))
529      {
530        return obj;
531      }
532      else
533      {
534        g_object_unref (obj);
535      }
536    }
537  }
538  return NULL;
539}
540
541static void
542atk_component_real_get_position (AtkComponent *component,
543                                 gint         *x,
544                                 gint         *y,
545                                 AtkCoordType coord_type)
546{
547  gint width, height;
548
549  atk_component_get_extents (component, x, y, &width, &height, coord_type);
550}
551
552static void
553atk_component_real_get_size (AtkComponent *component,
554                             gint         *width,
555                             gint         *height)
556{
557  gint x, y;
558  AtkCoordType coord_type;
559
560  /*
561   * Pick one coordinate type; it does not matter for size
562   */
563  coord_type = ATK_XY_WINDOW;
564
565  atk_component_get_extents (component, &x, &y, width, height, coord_type);
566}
567
568static AtkRectangle *
569atk_rectangle_copy (const AtkRectangle *rectangle)
570{
571  AtkRectangle *result = g_new (AtkRectangle, 1);
572  *result = *rectangle;
573
574  return result;
575}
576
577GType
578atk_rectangle_get_type (void)
579{
580  static GType our_type = 0;
581
582  if (our_type == 0)
583    our_type = g_boxed_type_register_static ("AtkRectangle",
584                                             (GBoxedCopyFunc)atk_rectangle_copy,
585                                             (GBoxedFreeFunc)g_free);
586  return our_type;
587}
588
Note: See TracBrowser for help on using the repository browser.