Revert "MSVC release builds: Ensure that /LTCG is used"
[atk.git] / atk / atkregistry.c
blob364d8baec20b3cc5d335babb43323630ae56136d
1 /* ATK - Accessibility Toolkit
2 * Copyright 2001 Sun Microsystems Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library 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.
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 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library 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.
20 #include "config.h"
22 #include "atkregistry.h"
23 #include "atknoopobjectfactory.h"
25 /**
26 * SECTION:atkregistry
27 * @Short_description: An object used to store the GType of the
28 * factories used to create an accessible object for an object of a
29 * particular GType.
30 * @Title:AtkRegistry
32 * The AtkRegistry is normally used to create appropriate ATK "peers"
33 * for user interface components. Application developers usually need
34 * only interact with the AtkRegistry by associating appropriate ATK
35 * implementation classes with GObject classes via the
36 * atk_registry_set_factory_type call, passing the appropriate GType
37 * for application custom widget classes.
40 static AtkRegistry *default_registry = NULL;
42 static void atk_registry_init (AtkRegistry *instance,
43 AtkRegistryClass *klass);
44 static void atk_registry_finalize (GObject *instance);
45 static void atk_registry_class_init (AtkRegistryClass *klass);
46 static AtkRegistry* atk_registry_new (void);
48 static gpointer parent_class = NULL;
50 GType
51 atk_registry_get_type (void)
53 static GType type = 0;
55 if (!type)
57 static const GTypeInfo info =
59 sizeof (AtkRegistryClass),
60 (GBaseInitFunc) NULL, /* base_init */
61 (GBaseFinalizeFunc) NULL, /* base_finalize */
62 (GClassInitFunc) atk_registry_class_init, /* class_init */
63 (GClassFinalizeFunc) NULL, /* class_finalize */
64 NULL, /* class_data */
65 sizeof (AtkRegistry), /* instance size */
66 0, /* n_preallocs */
67 (GInstanceInitFunc) atk_registry_init, /* instance init */
68 NULL /* value table */
71 type = g_type_register_static (G_TYPE_OBJECT, "AtkRegistry", &info, 0);
74 return type;
77 static void
78 atk_registry_class_init (AtkRegistryClass *klass)
80 GObjectClass *object_class = (GObjectClass *) klass;
82 parent_class = g_type_class_peek_parent (klass);
84 object_class->finalize = atk_registry_finalize;
87 #if 0
89 * Cannot define a class_finalize function when calling
90 * g_type_register_static()
92 static void
93 atk_registry_class_finalize (GObjectClass *klass)
95 g_return_if_fail (ATK_IS_REGISTRY_CLASS (klass));
97 g_object_unref (G_OBJECT (default_registry));
99 #endif
101 static void
102 atk_registry_init (AtkRegistry *instance, AtkRegistryClass *klass)
104 instance->factory_type_registry = g_hash_table_new ((GHashFunc) NULL,
105 (GEqualFunc) NULL);
106 instance->factory_singleton_cache = g_hash_table_new ((GHashFunc) NULL,
107 (GEqualFunc) NULL);
110 static AtkRegistry *
111 atk_registry_new (void)
113 GObject *object;
115 object = g_object_new (ATK_TYPE_REGISTRY, NULL);
117 g_return_val_if_fail (ATK_IS_REGISTRY (object), NULL);
119 return (AtkRegistry *) object;
122 static void
123 atk_registry_finalize (GObject *object)
125 AtkRegistry *registry = ATK_REGISTRY (object);
127 g_hash_table_destroy (registry->factory_type_registry);
128 g_hash_table_destroy (registry->factory_singleton_cache);
130 G_OBJECT_CLASS (parent_class)->finalize (object);
134 * atk_registry_set_factory_type:
135 * @registry: the #AtkRegistry in which to register the type association
136 * @type: an #AtkObject type
137 * @factory_type: an #AtkObjectFactory type to associate with @type. Must
138 * implement AtkObject appropriate for @type.
140 * Associate an #AtkObjectFactory subclass with a #GType. Note:
141 * The associated @factory_type will thereafter be responsible for
142 * the creation of new #AtkObject implementations for instances
143 * appropriate for @type.
145 void
146 atk_registry_set_factory_type (AtkRegistry *registry,
147 GType type,
148 GType factory_type)
150 GType old_type;
151 gpointer value;
152 AtkObjectFactory *old_factory;
154 g_return_if_fail (ATK_IS_REGISTRY (registry));
156 value = g_hash_table_lookup (registry->factory_type_registry,
157 (gpointer) type);
158 old_type = (GType) value;
159 if (old_type && old_type != factory_type)
161 g_hash_table_remove (registry->factory_type_registry,
162 (gpointer) type);
164 * If the old factory was created, notify it that it has
165 * been replaced, then free it.
167 old_factory = g_hash_table_lookup (registry->factory_singleton_cache,
168 (gpointer) old_type);
169 if (old_factory)
171 atk_object_factory_invalidate (old_factory);
172 g_type_free_instance ((GTypeInstance *) old_factory);
175 g_hash_table_insert (registry->factory_type_registry,
176 (gpointer) type,
177 (gpointer) factory_type);
181 * atk_registry_get_factory_type:
182 * @registry: an #AtkRegistry
183 * @type: a #GType with which to look up the associated #AtkObjectFactory
184 * subclass
186 * Provides a #GType indicating the #AtkObjectFactory subclass
187 * associated with @type.
189 * Returns: a #GType associated with type @type
191 GType
192 atk_registry_get_factory_type (AtkRegistry *registry,
193 GType type)
195 GType factory_type;
196 gpointer value;
199 * look up factory type in first hash;
200 * if there isn't an explicitly registered factory type,
201 * try inheriting one...
203 do {
204 value =
205 g_hash_table_lookup (registry->factory_type_registry,
206 (gpointer) type);
207 type = g_type_parent (type);
208 if (type == G_TYPE_INVALID)
210 break;
212 } while (value == NULL);
214 factory_type = (GType) value;
215 return factory_type;
219 * atk_registry_get_factory:
220 * @registry: an #AtkRegistry
221 * @type: a #GType with which to look up the associated #AtkObjectFactory
223 * Gets an #AtkObjectFactory appropriate for creating #AtkObjects
224 * appropriate for @type.
226 * Returns: (transfer none): an #AtkObjectFactory appropriate for creating
227 * #AtkObjects appropriate for @type.
229 AtkObjectFactory*
230 atk_registry_get_factory (AtkRegistry *registry,
231 GType type)
233 gpointer factory_pointer = NULL;
234 GType factory_type;
236 factory_type = atk_registry_get_factory_type (registry, type);
238 if (factory_type == G_TYPE_INVALID)
240 /* Factory type has not been specified for this object type */
241 static AtkObjectFactory* default_factory = NULL;
243 if (!default_factory)
244 default_factory = atk_no_op_object_factory_new ();
246 return default_factory;
249 /* ask second hashtable for instance of factory type */
250 factory_pointer =
251 g_hash_table_lookup (registry->factory_singleton_cache,
252 (gpointer) factory_type);
254 /* if there isn't one already, create one and save it */
255 if (factory_pointer == NULL)
257 factory_pointer = g_type_create_instance (factory_type);
258 g_hash_table_insert (registry->factory_singleton_cache,
259 (gpointer) factory_type,
260 factory_pointer);
263 return ATK_OBJECT_FACTORY (factory_pointer);
267 * atk_get_default_registry:
269 * Gets a default implementation of the #AtkObjectFactory/type
270 * registry.
271 * Note: For most toolkit maintainers, this will be the correct
272 * registry for registering new #AtkObject factories. Following
273 * a call to this function, maintainers may call atk_registry_set_factory_type()
274 * to associate an #AtkObjectFactory subclass with the GType of objects
275 * for whom accessibility information will be provided.
277 * Returns: (transfer full): a default implementation of the
278 * #AtkObjectFactory/type registry
280 AtkRegistry*
281 atk_get_default_registry (void)
283 if (!default_registry)
285 default_registry = atk_registry_new ();
287 return default_registry;