4f3a07cdf1f36c5f73800d11ddbddc227de2c3b0
[platform/upstream/atk.git] / atk / atkgobjectaccessible.c
1 /* ATK - Accessibility Toolkit
2  * Copyright 2001, 2002, 2003 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 <atk/atkgobjectaccessible.h>
21 #include <atk/atkregistry.h>
22 #include <atk/atkutil.h>
23
24 /**
25  * SECTION:atkgobjectaccessible
26  * @Short_description: This object class is derived from AtkObject and
27  *  can be used as a basis implementing accessible objects.
28  * @Title:AtkGObjectAccessible
29  *
30  * This object class is derived from AtkObject. It can be used as a
31  * basis for implementing accessible objects for GObjects which are
32  * not derived from GtkWidget. One example of its use is in providing
33  * an accessible object for GnomeCanvasItem in the GAIL library.
34  */
35 static void       atk_gobject_accessible_class_init       (AtkGObjectAccessibleClass   *klass);
36 static void       atk_real_gobject_accessible_initialize  (AtkObject         *atk_obj,
37                                                            gpointer          data);
38 static void       atk_gobject_accessible_dispose          (gpointer          data);
39
40 static GQuark quark_accessible_object = 0;
41 static GQuark quark_object = 0;
42 static gpointer parent_class = NULL;
43
44 GType
45 atk_gobject_accessible_get_type (void)
46 {
47   static GType type = 0;
48
49   if (!type)
50     {
51       static const GTypeInfo tinfo =
52       {
53         sizeof (AtkGObjectAccessibleClass),
54         (GBaseInitFunc) NULL, /* base init */
55         (GBaseFinalizeFunc) NULL, /* base finalize */
56         (GClassInitFunc) atk_gobject_accessible_class_init,
57         (GClassFinalizeFunc) NULL, /* class finalize */
58         NULL, /* class data */
59         sizeof (AtkGObjectAccessible),
60         0, /* nb preallocs */
61         (GInstanceInitFunc) NULL, /* instance init */
62         NULL /* value table */
63       };
64
65       type = g_type_register_static (ATK_TYPE_OBJECT,
66                                      "AtkGObjectAccessible", &tinfo, 0);
67     }
68
69   return type;
70 }
71
72 /**
73  * atk_gobject_accessible_for_object:
74  * @obj: a #GObject
75  *
76  * Gets the accessible object for the specified @obj.
77  *
78  * Returns: (transfer none): a #AtkObject which is the accessible object for
79  * the @obj
80  **/
81 AtkObject*
82 atk_gobject_accessible_for_object (GObject *obj)
83 {
84   AtkObject* accessible;
85
86   g_return_val_if_fail (G_IS_OBJECT (obj), NULL);
87   /* See if we have a cached accessible for this object */
88
89   accessible = g_object_get_qdata (obj,
90                                    quark_accessible_object);
91
92   if (!accessible)
93     {
94       AtkObjectFactory *factory;
95       AtkRegistry *default_registry;
96
97       default_registry = atk_get_default_registry ();
98       factory = atk_registry_get_factory (default_registry, 
99                                           G_OBJECT_TYPE (obj));
100       accessible = atk_object_factory_create_accessible (factory,
101                                                          obj);
102       if (!ATK_IS_GOBJECT_ACCESSIBLE (accessible))
103         {
104           /*
105            * The AtkObject which was created was not a AtkGObjectAccessible
106            */
107           g_object_weak_ref (obj,
108                              (GWeakNotify) g_object_unref,
109                              accessible); 
110           if (!quark_accessible_object)
111             quark_accessible_object = g_quark_from_static_string ("accessible-object");
112         }
113       g_object_set_qdata (obj, quark_accessible_object, accessible);
114     }
115   return accessible;
116 }
117
118 /**
119  * atk_gobject_accessible_get_object:
120  * @obj: a #AtkGObjectAccessible
121  *
122  * Gets the GObject for which @obj is the accessible object.
123  *
124  * Returns: (transfer none): a #GObject which is the object for which @obj is
125  * the accessible object
126  **/
127 GObject *
128 atk_gobject_accessible_get_object (AtkGObjectAccessible *obj)
129 {
130   g_return_val_if_fail (ATK_IS_GOBJECT_ACCESSIBLE (obj), NULL);
131
132   return g_object_get_qdata (G_OBJECT (obj), quark_object);
133 }
134  
135 static void
136 atk_real_gobject_accessible_initialize (AtkObject  *atk_obj,
137                                         gpointer   data)
138 {
139   AtkGObjectAccessible *atk_gobj;
140
141   atk_gobj = ATK_GOBJECT_ACCESSIBLE (atk_obj);
142
143   g_object_set_qdata (G_OBJECT (atk_gobj), quark_object, data);
144   atk_obj->layer = ATK_LAYER_WIDGET;
145
146   g_object_weak_ref (data,
147                      (GWeakNotify) atk_gobject_accessible_dispose,
148                      atk_gobj);
149 }
150
151 static void
152 atk_gobject_accessible_dispose (gpointer  data)
153 {
154   GObject *object;
155
156   g_return_if_fail (ATK_IS_GOBJECT_ACCESSIBLE (data));
157
158   object = atk_gobject_accessible_get_object (data);
159   if (object)
160       g_object_set_qdata (object, quark_accessible_object, NULL);
161
162   g_object_set_qdata (G_OBJECT (data), quark_object, NULL);
163   atk_object_notify_state_change (ATK_OBJECT (data), ATK_STATE_DEFUNCT,
164                                   TRUE); 
165   g_object_unref (data);
166 }
167
168 static void
169 atk_gobject_accessible_class_init (AtkGObjectAccessibleClass *klass)
170
171   AtkObjectClass *class;
172
173   class = ATK_OBJECT_CLASS (klass);
174
175   parent_class = g_type_class_peek_parent (klass);
176
177   class->initialize = atk_real_gobject_accessible_initialize;
178
179   if (!quark_accessible_object)
180     quark_accessible_object = g_quark_from_static_string ("accessible-object");
181   quark_object = g_quark_from_static_string ("object-for-accessible");
182 }