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 "atkregistry.h"
21 #include "atknoopobjectfactory.h"
23 static AtkRegistry *default_registry = NULL;;
25 static void atk_registry_init (AtkRegistry *instance,
26 AtkRegistryClass *klass);
27 static void atk_registry_finalize (GObject *instance);
28 static void atk_registry_class_init (AtkRegistryClass *klass);
30 static AtkRegistry* atk_registry_new ();
31 static GType atk_registry_get_factory_type (AtkRegistry *registry,
35 atk_registry_get_type (void)
37 static GType type = 0;
41 static const GTypeInfo info =
43 sizeof (AtkRegistryClass),
44 (GBaseInitFunc) NULL, /* base_init */
45 (GBaseFinalizeFunc) NULL, /* base_finalize */
46 (GClassInitFunc) atk_registry_class_init, /* class_init */
47 (GClassFinalizeFunc) NULL, /* class_finalize */
48 NULL, /* class_data */
49 sizeof (AtkRegistry), /* instance size */
51 (GInstanceInitFunc) atk_registry_init, /* instance init */
52 NULL /* value table */
55 type = g_type_register_static (G_TYPE_OBJECT, "AtkRegistry", &info, 0);
62 atk_registry_class_init (AtkRegistryClass *klass)
64 GObjectClass *object_class;
66 /* is paranoia appropriate in a class initializer ? */
67 g_return_if_fail (G_IS_OBJECT_CLASS (klass));
69 object_class = G_OBJECT_CLASS (klass);
70 object_class->finalize = atk_registry_finalize;
71 default_registry = atk_registry_new ();
76 * Cannot define a class_finalize function when calling
77 * g_type_register_static()
80 atk_registry_class_finalize (GObjectClass *klass)
82 g_return_if_fail (ATK_IS_REGISTRY_CLASS (klass));
84 g_free (default_registry);
89 atk_registry_init (AtkRegistry *instance, AtkRegistryClass *klass)
91 instance->factory_type_registry = g_hash_table_new (NULL, NULL);
92 instance->factory_singleton_cache = g_hash_table_new (NULL, NULL);
100 object = g_object_new (ATK_TYPE_REGISTRY, NULL);
102 g_return_val_if_fail ((object != NULL), NULL);
103 g_return_val_if_fail (ATK_IS_REGISTRY (object), NULL);
105 return (AtkRegistry *) object;
109 atk_registry_finalize (GObject *instance)
111 AtkRegistry *registry;
113 g_return_if_fail (ATK_IS_REGISTRY (instance));
114 registry = ATK_REGISTRY (instance);
115 g_free (registry->factory_type_registry);
116 g_free (registry->factory_singleton_cache);
120 *atk_registry_set_factory_type:
121 *@registry: the #AtkRegistry in which to register the association
122 * between an #AtkObjectFactory #GType and an #AtkObject @GType
123 *@type: an #AtkObject #GType
124 *@factory_type: an #AtkObjectFactory #GType to associate with @type
126 *Associate an #AtkObjectFactory subclass with a #GType. Note:
127 * The associated @factory_type will thereafter be responsible for
128 * the creation of new #AtkObject implementations for instances
132 atk_registry_set_factory_type (AtkRegistry *registry,
138 AtkObjectFactory *old_factory;
140 g_return_if_fail (ATK_IS_REGISTRY (registry));
142 value = g_hash_table_lookup (registry->factory_type_registry,
143 GUINT_TO_POINTER (type));
144 old_type = GPOINTER_TO_UINT (value);
145 if (old_type && old_type != factory_type)
147 g_hash_table_remove (registry->factory_type_registry,
148 GUINT_TO_POINTER (type));
150 * If the old factory was created, notify it that it has
151 * been replaced, then free it.
153 old_factory = g_hash_table_lookup (registry->factory_singleton_cache,
154 GUINT_TO_POINTER (old_type));
157 atk_object_factory_invalidate (old_factory);
158 g_type_free_instance ((GTypeInstance *) old_factory);
161 g_hash_table_insert (registry->factory_type_registry,
162 GUINT_TO_POINTER (type),
163 GUINT_TO_POINTER (factory_type));
167 *atk_registry_get_factory_type:
168 *@registry: an #AtkRegistry
169 *@type: a #GType with which to look up the associated #AtkObjectFactory
172 *Provides a GType indicating the #AtkObjectFactory subclass
173 * associated with type @type
175 *Returns: a GType indicating the AtkObjectFactory subclass
176 * associated with type @type
179 atk_registry_get_factory_type (AtkRegistry *registry,
186 * look up factory type in first hash;
187 * if there isn't an explicitly registered factory type,
188 * try inheriting one...
192 g_hash_table_lookup (registry->factory_type_registry,
193 GUINT_TO_POINTER (type));
194 type = g_type_parent (type);
195 if (type == G_TYPE_INVALID)
199 } while (value == NULL);
201 factory_type = GPOINTER_TO_UINT (value);
206 *atk_registry_get_factory:
207 *@registry: an #AtkRegistry
208 *@type: a #GType with which to look up the associated #AtkObjectFactory
210 *Returns an #AtkObjectFactory appropriate for creating #AtkObjects
213 *Returns: an #AtkObjectFactory appropriate for creating #AtkObjects
217 atk_registry_get_factory (AtkRegistry *registry,
220 gpointer factory_pointer = NULL;
223 factory_type = atk_registry_get_factory_type (registry, type);
225 if (factory_type == G_TYPE_INVALID)
227 /* Factory type has not been specified for this object type */
228 static AtkObjectFactory* default_factory = NULL;
230 if (!default_factory)
231 default_factory = atk_no_op_object_factory_new ();
233 return default_factory;
236 /* ask second hashtable for instance of factory type */
238 g_hash_table_lookup (registry->factory_singleton_cache,
239 GUINT_TO_POINTER (factory_type));
241 /* if there isn't one already, create one and save it */
242 if (factory_pointer == NULL)
244 factory_pointer = g_type_create_instance (factory_type);
245 g_hash_table_insert (registry->factory_singleton_cache,
246 GUINT_TO_POINTER (factory_type),
250 return ATK_OBJECT_FACTORY (factory_pointer);
254 *atk_get_default_registry:
256 *Return a default implementation of the #AtkObjectFactory/type
258 *Note: For most toolkit maintainers, this will be the correct
259 * registry for registering new #AtkObject factories. Following
260 * a call to this function, maintainers may call atk_registry_set_factory_type()
261 * to associate an #AtkObjectFactory subclass with the GType of objects
262 * for whom accessability information will be provided.
264 *Returns: a default implementation of the #AtkObjectFactory/type
268 atk_get_default_registry ()
270 if (!default_registry)
272 default_registry = atk_registry_new();
274 return default_registry;