Merge tag 'upstream/2.35.1' into tizen
[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 #include "config.h"
21
22 #include "atkcomponent.h"
23
24 /**
25  * SECTION:atkcomponent
26  * @Short_description: The ATK interface provided by UI components
27  * which occupy a physical area on the screen.
28  * which the user can activate/interact with.
29  * @Title:AtkComponent
30  *
31  * #AtkComponent should be implemented by most if not all UI elements
32  * with an actual on-screen presence, i.e. components which can be
33  * said to have a screen-coordinate bounding box.  Virtually all
34  * widgets will need to have #AtkComponent implementations provided
35  * for their corresponding #AtkObject class.  In short, only UI
36  * elements which are *not* GUI elements will omit this ATK interface.
37  *
38  * A possible exception might be textual information with a
39  * transparent background, in which case text glyph bounding box
40  * information is provided by #AtkText.
41  */
42
43 enum {
44   BOUNDS_CHANGED,
45   LAST_SIGNAL
46 };
47
48 static void       atk_component_base_init (AtkComponentIface *class);
49
50 static gboolean   atk_component_real_contains                (AtkComponent *component,
51                                                               gint         x,
52                                                               gint         y,
53                                                               AtkCoordType coord_type);
54
55 static AtkObject* atk_component_real_ref_accessible_at_point (AtkComponent *component,
56                                                               gint         x,
57                                                               gint         y,
58                                                               AtkCoordType coord_type);
59
60 static void      atk_component_real_get_position             (AtkComponent *component,
61                                                               gint         *x,
62                                                               gint         *y,
63                                                               AtkCoordType coord_type);
64
65 static void      atk_component_real_get_size                 (AtkComponent *component,
66                                                               gint         *width,
67                                                               gint         *height);
68
69 static guint atk_component_signals[LAST_SIGNAL] = { 0 };
70
71 GType
72 atk_component_get_type (void)
73 {
74   static GType type = 0;
75
76   if (!type) {
77     static const GTypeInfo tinfo =
78     {
79       sizeof (AtkComponentIface),
80       (GBaseInitFunc) atk_component_base_init,
81       (GBaseFinalizeFunc) NULL,
82
83     };
84
85     type = g_type_register_static (G_TYPE_INTERFACE, "AtkComponent", &tinfo, 0);
86   }
87
88   return type;
89 }
90
91 static void
92 atk_component_base_init (AtkComponentIface *class)
93 {
94   static gboolean initialized = FALSE;
95
96   if (! initialized)
97     {
98       class->ref_accessible_at_point = atk_component_real_ref_accessible_at_point;
99       class->contains = atk_component_real_contains;
100       class->get_position = atk_component_real_get_position;
101       class->get_size = atk_component_real_get_size;
102
103
104       /**
105        * AtkComponent::bounds-changed:
106        * @atkcomponent: the object which received the signal.
107        * @arg1: The AtkRectangle giving the new position and size.
108        *
109        * The 'bounds-changed" signal is emitted when the bposition or
110        * size of the component changes.
111        */
112       atk_component_signals[BOUNDS_CHANGED] =
113         g_signal_new ("bounds_changed",
114                       ATK_TYPE_COMPONENT,
115                       G_SIGNAL_RUN_LAST,
116                       G_STRUCT_OFFSET (AtkComponentIface, bounds_changed),
117                       (GSignalAccumulator) NULL, NULL,
118                       g_cclosure_marshal_VOID__BOXED,
119                       G_TYPE_NONE, 1,
120                       ATK_TYPE_RECTANGLE | G_SIGNAL_TYPE_STATIC_SCOPE);
121
122       initialized = TRUE;
123     }
124 }
125
126
127 /**
128  * atk_component_add_focus_handler: (skip)
129  * @component: The #AtkComponent to attach the @handler to
130  * @handler: The #AtkFocusHandler to be attached to @component
131  *
132  * Add the specified handler to the set of functions to be called
133  * when this object receives focus events (in or out). If the handler is
134  * already added it is not added again
135  *
136  * Deprecated: 2.9.4: If you need to track when an object gains or
137  * lose the focus, use the #AtkObject::state-change "focused" notification instead.
138  *
139  * Returns: a handler id which can be used in atk_component_remove_focus_handler()
140  * or zero if the handler was already added.
141  **/
142 guint
143 atk_component_add_focus_handler (AtkComponent    *component,
144                                  AtkFocusHandler handler)
145 {
146   AtkComponentIface *iface = NULL;
147   g_return_val_if_fail (ATK_IS_COMPONENT (component), 0);
148
149   iface = ATK_COMPONENT_GET_IFACE (component);
150
151   if (iface->add_focus_handler)
152     return (iface->add_focus_handler) (component, handler);
153   else
154     return 0;
155 }
156
157 /**
158  * atk_component_remove_focus_handler:
159  * @component: the #AtkComponent to remove the focus handler from
160  * @handler_id: the handler id of the focus handler to be removed
161  * from @component
162  *
163  * Remove the handler specified by @handler_id from the list of
164  * functions to be executed when this object receives focus events
165  * (in or out).
166  *
167  * Deprecated: 2.9.4: If you need to track when an object gains or
168  * lose the focus, use the #AtkObject::state-change "focused" notification instead.
169  *
170  **/
171 void
172 atk_component_remove_focus_handler (AtkComponent    *component,
173                                     guint           handler_id)
174 {
175   AtkComponentIface *iface = NULL;
176   g_return_if_fail (ATK_IS_COMPONENT (component));
177
178   iface = ATK_COMPONENT_GET_IFACE (component);
179
180   if (iface->remove_focus_handler)
181     (iface->remove_focus_handler) (component, handler_id);
182 }
183
184 /**
185  * atk_component_contains:
186  * @component: the #AtkComponent
187  * @x: x coordinate
188  * @y: y coordinate
189  * @coord_type: specifies whether the coordinates are relative to the screen
190  * or to the components top level window
191  *
192  * Checks whether the specified point is within the extent of the @component.
193  *
194  * Toolkit implementor note: ATK provides a default implementation for
195  * this virtual method. In general there are little reason to
196  * re-implement it.
197  *
198  * Returns: %TRUE or %FALSE indicating whether the specified point is within
199  * the extent of the @component or not
200  **/
201 gboolean
202 atk_component_contains (AtkComponent    *component,
203                         gint            x,
204                         gint            y,
205                         AtkCoordType    coord_type)
206 {
207   AtkComponentIface *iface = NULL;
208   g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
209
210   iface = ATK_COMPONENT_GET_IFACE (component);
211
212   if (iface->contains)
213     return (iface->contains) (component, x, y, coord_type);
214   else
215     return FALSE;
216 }
217
218 /**
219  * atk_component_ref_accessible_at_point:
220  * @component: the #AtkComponent
221  * @x: x coordinate
222  * @y: y coordinate
223  * @coord_type: specifies whether the coordinates are relative to the screen
224  * or to the components top level window
225  *
226  * Gets a reference to the accessible child, if one exists, at the
227  * coordinate point specified by @x and @y.
228  *
229  * Returns: (nullable) (transfer full): a reference to the accessible
230  * child, if one exists
231  **/
232 AtkObject*
233 atk_component_ref_accessible_at_point (AtkComponent    *component,
234                                        gint            x,
235                                        gint            y,
236                                        AtkCoordType    coord_type)
237 {
238   AtkComponentIface *iface = NULL;
239   g_return_val_if_fail (ATK_IS_COMPONENT (component), NULL);
240
241   iface = ATK_COMPONENT_GET_IFACE (component);
242
243   if (iface->ref_accessible_at_point)
244     return (iface->ref_accessible_at_point) (component, x, y, coord_type);
245   else
246     return NULL;
247 }
248
249 /**
250  * atk_component_get_extents:
251  * @component: an #AtkComponent
252  * @x: (out) (optional): address of #gint to put x coordinate
253  * @y: (out) (optional): address of #gint to put y coordinate
254  * @width: (out) (optional): address of #gint to put width
255  * @height: (out) (optional): address of #gint to put height
256  * @coord_type: specifies whether the coordinates are relative to the screen
257  * or to the components top level window
258  *
259  * Gets the rectangle which gives the extent of the @component.
260  *
261  * If the extent can not be obtained (e.g. a non-embedded plug or missing
262  * support), all of x, y, width, height are set to -1.
263  *
264  **/
265 void
266 atk_component_get_extents    (AtkComponent    *component,
267                               gint            *x,
268                               gint            *y,
269                               gint            *width,
270                               gint            *height,
271                               AtkCoordType    coord_type)
272 {
273   AtkComponentIface *iface = NULL;
274   gint local_x, local_y, local_width, local_height;
275   gint *real_x, *real_y, *real_width, *real_height;
276
277   g_return_if_fail (ATK_IS_COMPONENT (component));
278
279   if (x)
280     real_x = x;
281   else
282     real_x = &local_x;
283   if (y)
284     real_y = y;
285   else
286     real_y = &local_y;
287   if (width)
288     real_width = width;
289   else
290     real_width = &local_width;
291   if (height)
292     real_height = height;
293   else
294     real_height = &local_height;
295
296   iface = ATK_COMPONENT_GET_IFACE (component);
297
298   if (iface->get_extents)
299     (iface->get_extents) (component, real_x, real_y, real_width, real_height, coord_type);
300   else
301     {
302       *real_x = -1;
303       *real_y = -1;
304       *real_width = -1;
305       *real_height = -1;
306     }
307 }
308
309 /**
310  * atk_component_get_position:
311  * @component: an #AtkComponent
312  * @x: (out) (optional): address of #gint to put x coordinate position
313  * @y: (out) (optional): address of #gint to put y coordinate position
314  * @coord_type: specifies whether the coordinates are relative to the screen
315  * or to the components top level window
316  *
317  * Gets the position of @component in the form of
318  * a point specifying @component's top-left corner.
319  *
320  * If the position can not be obtained (e.g. a non-embedded plug or missing
321  * support), x and y are set to -1.
322  *
323  * Deprecated: Since 2.12. Use atk_component_get_extents() instead.
324  **/
325 void
326 atk_component_get_position   (AtkComponent    *component,
327                               gint            *x,
328                               gint            *y,
329                               AtkCoordType    coord_type)
330 {
331   AtkComponentIface *iface = NULL;
332   gint local_x, local_y;
333   gint *real_x, *real_y;
334
335   g_return_if_fail (ATK_IS_COMPONENT (component));
336
337   if (x)
338     real_x = x;
339   else
340     real_x = &local_x;
341   if (y)
342     real_y = y;
343   else
344     real_y = &local_y;
345
346   iface = ATK_COMPONENT_GET_IFACE (component);
347
348   if (iface->get_position)
349     (iface->get_position) (component, real_x, real_y, coord_type);
350   else
351     {
352       *real_x = -1;
353       *real_y = -1;
354     }
355 }
356
357 /**
358  * atk_component_get_size:
359  * @component: an #AtkComponent
360  * @width: (out) (optional): address of #gint to put width of @component
361  * @height: (out) (optional): address of #gint to put height of @component
362  *
363  * Gets the size of the @component in terms of width and height.
364  *
365  * If the size can not be obtained (e.g. a non-embedded plug or missing
366  * support), width and height are set to -1.
367  *
368  * Deprecated: Since 2.12. Use atk_component_get_extents() instead.
369  **/
370 void
371 atk_component_get_size       (AtkComponent    *component,
372                               gint            *width,
373                               gint            *height)
374 {
375   AtkComponentIface *iface = NULL;
376   gint local_width, local_height;
377   gint *real_width, *real_height;
378
379   g_return_if_fail (ATK_IS_COMPONENT (component));
380
381   if (width)
382     real_width = width;
383   else
384     real_width = &local_width;
385   if (height)
386     real_height = height;
387   else
388     real_height = &local_height;
389
390   g_return_if_fail (ATK_IS_COMPONENT (component));
391
392   iface = ATK_COMPONENT_GET_IFACE (component);
393
394   if (iface->get_size)
395     (iface->get_size) (component, real_width, real_height);
396   else
397     {
398       *real_width = -1;
399       *real_height = -1;
400     }
401 }
402
403 /**
404  * atk_component_get_layer:
405  * @component: an #AtkComponent
406  *
407  * Gets the layer of the component.
408  *
409  * Returns: an #AtkLayer which is the layer of the component
410  **/
411 AtkLayer
412 atk_component_get_layer (AtkComponent *component)
413 {
414   AtkComponentIface *iface;
415
416   g_return_val_if_fail (ATK_IS_COMPONENT (component), ATK_LAYER_INVALID);
417
418   iface = ATK_COMPONENT_GET_IFACE (component);
419   if (iface->get_layer)
420     return (iface->get_layer) (component);
421   else
422     return ATK_LAYER_WIDGET;
423 }
424
425 /**
426  * atk_component_get_mdi_zorder:
427  * @component: an #AtkComponent
428  *
429  * Gets the zorder of the component. The value G_MININT will be returned
430  * if the layer of the component is not ATK_LAYER_MDI or ATK_LAYER_WINDOW.
431  *
432  * Returns: a gint which is the zorder of the component, i.e. the depth at
433  * which the component is shown in relation to other components in the same
434  * container.
435  **/
436 gint
437 atk_component_get_mdi_zorder (AtkComponent *component)
438 {
439   AtkComponentIface *iface;
440
441   g_return_val_if_fail (ATK_IS_COMPONENT (component), G_MININT);
442
443   iface = ATK_COMPONENT_GET_IFACE (component);
444   if (iface->get_mdi_zorder)
445     return (iface->get_mdi_zorder) (component);
446   else
447     return G_MININT;
448 }
449
450 /**
451  * atk_component_get_alpha:
452  * @component: an #AtkComponent
453  *
454  * Returns the alpha value (i.e. the opacity) for this
455  * @component, on a scale from 0 (fully transparent) to 1.0
456  * (fully opaque).
457  *
458  * Returns: An alpha value from 0 to 1.0, inclusive.
459  * Since: 1.12
460  **/
461 gdouble
462 atk_component_get_alpha (AtkComponent    *component)
463 {
464   AtkComponentIface *iface;
465
466   g_return_val_if_fail (ATK_IS_COMPONENT (component), G_MININT);
467
468   iface = ATK_COMPONENT_GET_IFACE (component);
469   if (iface->get_alpha)
470     return (iface->get_alpha) (component);
471   else
472     return (gdouble) 1.0;
473 }
474
475 /**
476  * atk_component_grab_focus:
477  * @component: an #AtkComponent
478  *
479  * Grabs focus for this @component.
480  *
481  * Returns: %TRUE if successful, %FALSE otherwise.
482  **/
483 gboolean
484 atk_component_grab_focus (AtkComponent    *component)
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->grab_focus)
492     return (iface->grab_focus) (component);
493   else
494     return FALSE;
495 }
496
497 /**
498  * atk_component_grab_highlight:
499  * @component: an #AtkComponent
500  *
501  * Grabs highlight for this @component.
502  *
503  * Returns: %TRUE if successful, %FALSE otherwise.
504  **/
505 gboolean
506 atk_component_grab_highlight (AtkComponent    *component)
507 {
508   AtkComponentIface *iface = NULL;
509   g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
510
511   iface = ATK_COMPONENT_GET_IFACE (component);
512
513   if (iface->grab_highlight)
514     return (iface->grab_highlight) (component);
515   else
516     return FALSE;
517 }
518
519 /**
520  * atk_component_clear_highlight:
521  * @component: an #AtkComponent
522  *
523  * Clears highlight for this @component.
524  *
525  * Returns: %TRUE if successful, %FALSE otherwise.
526  **/
527 gboolean
528 atk_component_clear_highlight (AtkComponent    *component)
529 {
530   AtkComponentIface *iface = NULL;
531   g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
532
533   iface = ATK_COMPONENT_GET_IFACE (component);
534
535   if (iface->clear_highlight)
536     return (iface->clear_highlight) (component);
537   else
538     return FALSE;
539 }
540
541 /**
542  * atk_component_get_highlight_index:
543  * @component: an #AtkComponent
544  *
545  * Returns: highlight index of the @component (if >0),
546  * 0 if highlight index is not set or -1 if an error occured.
547  *
548  **/
549 gint
550 atk_component_get_highlight_index (AtkComponent    *component)
551 {
552   AtkComponentIface *iface = NULL;
553   g_return_val_if_fail (ATK_IS_COMPONENT (component), -1);
554
555   iface = ATK_COMPONENT_GET_IFACE (component);
556
557   if (iface->get_highlight_index)
558     return (iface->get_highlight_index) (component);
559   else
560     return -1;
561 }
562
563 /**
564  * atk_component_set_extents:
565  * @component: an #AtkComponent
566  * @x: x coordinate
567  * @y: y coordinate
568  * @width: width to set for @component
569  * @height: height to set for @component
570  * @coord_type: specifies whether the coordinates are relative to the screen
571  * or to the components top level window
572  *
573  * Sets the extents of @component.
574  *
575  * Returns: %TRUE or %FALSE whether the extents were set or not
576  **/
577 gboolean
578 atk_component_set_extents   (AtkComponent    *component,
579                              gint            x,
580                              gint            y,
581                              gint            width,
582                              gint            height,
583                              AtkCoordType    coord_type)
584 {
585   AtkComponentIface *iface = NULL;
586   g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
587
588   iface = ATK_COMPONENT_GET_IFACE (component);
589
590   if (iface->set_extents)
591     return (iface->set_extents) (component, x, y, width, height, coord_type);
592   else
593     return FALSE;
594 }
595
596 /**
597  * atk_component_set_position:
598  * @component: an #AtkComponent
599  * @x: x coordinate
600  * @y: y coordinate
601  * @coord_type: specifies whether the coordinates are relative to the screen
602  * or to the component's top level window
603  *
604  * Sets the position of @component.
605  *
606  * Contrary to atk_component_scroll_to, this does not trigger any scrolling,
607  * this just moves @component in its parent.
608  *
609  * Returns: %TRUE or %FALSE whether or not the position was set or not
610  **/
611 gboolean
612 atk_component_set_position   (AtkComponent    *component,
613                               gint            x,
614                               gint            y,
615                               AtkCoordType    coord_type)
616 {
617   AtkComponentIface *iface = NULL;
618   g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
619
620   iface = ATK_COMPONENT_GET_IFACE (component);
621
622   if (iface->set_position)
623     return (iface->set_position) (component, x, y, coord_type);
624   else
625     return FALSE;
626 }
627
628 /**
629  * atk_component_set_size:
630  * @component: an #AtkComponent
631  * @width: width to set for @component
632  * @height: height to set for @component
633  *
634  * Set the size of the @component in terms of width and height.
635  *
636  * Returns: %TRUE or %FALSE whether the size was set or not
637  **/
638 gboolean
639 atk_component_set_size       (AtkComponent    *component,
640                               gint            x,
641                               gint            y)
642 {
643   AtkComponentIface *iface = NULL;
644   g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
645
646   iface = ATK_COMPONENT_GET_IFACE (component);
647
648   if (iface->set_size)
649     return (iface->set_size) (component, x, y);
650   else
651     return FALSE;
652 }
653
654 /**
655  * atk_component_scroll_to:
656  * @component: an #AtkComponent
657  * @type: specify where the object should be made visible.
658  *
659  * Makes @component visible on the screen by scrolling all necessary parents.
660  *
661  * Contrary to atk_component_set_position, this does not actually move
662  * @component in its parent, this only makes the parents scroll so that the
663  * object shows up on the screen, given its current position within the parents.
664  *
665  * Returns: whether scrolling was successful.
666  *
667  * Since: 2.30
668  */
669 gboolean
670 atk_component_scroll_to (AtkComponent  *component,
671                          AtkScrollType  type)
672 {
673   AtkComponentIface *iface = NULL;
674   g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
675
676   iface = ATK_COMPONENT_GET_IFACE (component);
677
678   if (iface->scroll_to)
679     return (iface->scroll_to) (component, type);
680
681   return FALSE;
682 }
683
684 /**
685  * atk_component_scroll_to_point:
686  * @component: an #AtkComponent
687  * @coords: specify whether coordinates are relative to the screen or to the
688  * parent object.
689  * @x: x-position where to scroll to
690  * @y: y-position where to scroll to
691  *
692  * Move the top-left of @component to a given position of the screen by
693  * scrolling all necessary parents.
694  *
695  * Returns: whether scrolling was successful.
696  *
697  * Since: 2.30
698  */
699 gboolean
700 atk_component_scroll_to_point (AtkComponent *component,
701                                AtkCoordType  coords,
702                                gint          x,
703                                gint          y)
704 {
705   AtkComponentIface *iface = NULL;
706   g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
707
708   iface = ATK_COMPONENT_GET_IFACE (component);
709
710   if (iface->scroll_to_point)
711     return (iface->scroll_to_point) (component, coords, x, y);
712
713   return FALSE;
714 }
715
716 static gboolean
717 atk_component_real_contains (AtkComponent *component,
718                              gint         x,
719                              gint         y,
720                              AtkCoordType coord_type)
721 {
722   gint real_x, real_y, width, height;
723
724   real_x = real_y = width = height = 0;
725
726   atk_component_get_extents (component, &real_x, &real_y, &width, &height, coord_type);
727
728   if ((x >= real_x) &&
729       (x < real_x + width) &&
730       (y >= real_y) &&
731       (y < real_y + height))
732     return TRUE;
733   else
734     return FALSE;
735 }
736
737 static AtkObject*
738 atk_component_real_ref_accessible_at_point (AtkComponent *component,
739                                             gint         x,
740                                             gint         y,
741                                             AtkCoordType coord_type)
742 {
743   gint count, i;
744
745   count = atk_object_get_n_accessible_children (ATK_OBJECT (component));
746
747   for (i = 0; i < count; i++)
748   {
749     AtkObject *obj;
750
751     obj = atk_object_ref_accessible_child (ATK_OBJECT (component), i);
752
753     if (obj != NULL)
754     {
755       if (atk_component_contains (ATK_COMPONENT (obj), x, y, coord_type))
756       {
757         return obj;
758       }
759       else
760       {
761         g_object_unref (obj);
762       }
763     }
764   }
765   return NULL;
766 }
767
768 static void
769 atk_component_real_get_position (AtkComponent *component,
770                                  gint         *x,
771                                  gint         *y,
772                                  AtkCoordType coord_type)
773 {
774   gint width, height;
775
776   atk_component_get_extents (component, x, y, &width, &height, coord_type);
777 }
778
779 static void
780 atk_component_real_get_size (AtkComponent *component,
781                              gint         *width,
782                              gint         *height)
783 {
784   gint x, y;
785   AtkCoordType coord_type;
786
787   /*
788    * Pick one coordinate type; it does not matter for size
789    */
790   coord_type = ATK_XY_WINDOW;
791
792   atk_component_get_extents (component, &x, &y, width, height, coord_type);
793 }
794
795 static AtkRectangle *
796 atk_rectangle_copy (const AtkRectangle *rectangle)
797 {
798   AtkRectangle *result = g_new (AtkRectangle, 1);
799   *result = *rectangle;
800
801   return result;
802 }
803
804 GType
805 atk_rectangle_get_type (void)
806 {
807   static GType our_type = 0;
808
809   if (our_type == 0)
810     our_type = g_boxed_type_register_static ("AtkRectangle",
811                                              (GBoxedCopyFunc)atk_rectangle_copy,
812                                              (GBoxedFreeFunc)g_free);
813   return our_type;
814 }
815