summaryrefslogtreecommitdiff
path: root/atk/atkregistry.c
diff options
context:
space:
mode:
authorBill Haneman <billh@src.gnome.org>2001-04-26 14:23:41 +0000
committerBill Haneman <billh@src.gnome.org>2001-04-26 14:23:41 +0000
commitdba66b4bec94a908cd35a5537209db255fa5fa33 (patch)
tree3c6361db3558e2e2c70e9c802193974f45d24bf0 /atk/atkregistry.c
downloadatk-dba66b4bec94a908cd35a5537209db255fa5fa33.tar.gz
Initial revision
Diffstat (limited to 'atk/atkregistry.c')
-rw-r--r--atk/atkregistry.c229
1 files changed, 229 insertions, 0 deletions
diff --git a/atk/atkregistry.c b/atk/atkregistry.c
new file mode 100644
index 0000000..8ad9847
--- /dev/null
+++ b/atk/atkregistry.c
@@ -0,0 +1,229 @@
+/* ATK - Accessibility Toolkit
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "atkregistry.h"
+#include "atknoopobjectfactory.h"
+
+static AtkRegistry *default_registry = NULL;;
+
+static void atk_registry_init (AtkRegistry *instance,
+ AtkRegistryClass *klass);
+static void atk_registry_finalize (GObject *instance);
+static void atk_registry_class_init (AtkRegistryClass *klass);
+
+static AtkRegistry* atk_registry_new ();
+static GType atk_registry_get_factory_type (AtkRegistry *registry,
+ GType type);
+
+GType
+atk_registry_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type)
+ {
+ static const GTypeInfo info =
+ {
+ sizeof (AtkRegistryClass),
+ (GBaseInitFunc) NULL, /* base_init */
+ (GBaseFinalizeFunc) NULL, /* base_finalize */
+ (GClassInitFunc) atk_registry_class_init, /* class_init */
+ (GClassFinalizeFunc) NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (AtkRegistry), /* instance size */
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) atk_registry_init, /* instance init */
+ NULL /* value table */
+ };
+
+ type = g_type_register_static (G_TYPE_OBJECT, "AtkRegistry", &info, 0);
+ }
+
+ return type;
+}
+
+static void
+atk_registry_class_init (AtkRegistryClass *klass)
+{
+ GObjectClass *object_class;
+
+ /* is paranoia appropriate in a class initializer ? */
+ g_return_if_fail (G_IS_OBJECT_CLASS (klass));
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = atk_registry_finalize;
+ default_registry = atk_registry_new ();
+}
+
+#if 0
+/*
+ * Cannot define a class_finalize function when calling
+ * g_type_register_static()
+ */
+static void
+atk_registry_class_finalize (GObjectClass *klass)
+{
+ g_return_if_fail (ATK_IS_REGISTRY_CLASS (klass));
+
+ g_free (default_registry);
+}
+#endif
+
+static void
+atk_registry_init (AtkRegistry *instance, AtkRegistryClass *klass)
+{
+ instance->factory_type_registry = g_hash_table_new (NULL, NULL);
+ instance->factory_singleton_cache = g_hash_table_new (NULL, NULL);
+}
+
+static AtkRegistry*
+atk_registry_new ()
+{
+ GObject *object;
+
+ object = g_object_new (ATK_TYPE_REGISTRY, NULL);
+
+ g_return_val_if_fail ((object != NULL), NULL);
+ g_return_val_if_fail (ATK_IS_REGISTRY (object), NULL);
+
+ return (AtkRegistry *) object;
+}
+
+static void
+atk_registry_finalize (GObject *instance)
+{
+ AtkRegistry *registry;
+
+ g_return_if_fail (ATK_IS_REGISTRY (instance));
+ registry = ATK_REGISTRY (instance);
+ g_free (registry->factory_type_registry);
+ g_free (registry->factory_singleton_cache);
+}
+
+
+void
+atk_registry_set_factory_type (AtkRegistry *registry,
+ GType type,
+ GType factory_type)
+{
+ GType old_type;
+ gpointer value;
+ AtkObjectFactory *old_factory;
+
+ g_return_if_fail (ATK_IS_REGISTRY (registry));
+
+ value = g_hash_table_lookup (registry->factory_type_registry,
+ GUINT_TO_POINTER (type));
+ old_type = GPOINTER_TO_UINT (value);
+ if (old_type && old_type != factory_type)
+ {
+ g_hash_table_remove (registry->factory_type_registry,
+ GUINT_TO_POINTER (type));
+ /*
+ * If the old factory was created, notify it that it has
+ * been replaced, then free it.
+ */
+ old_factory = g_hash_table_lookup (registry->factory_singleton_cache,
+ GUINT_TO_POINTER (old_type));
+ if (old_factory)
+ {
+ atk_object_factory_invalidate (old_factory);
+ g_type_free_instance ((GTypeInstance *) old_factory);
+ }
+ }
+ g_hash_table_insert (registry->factory_type_registry,
+ GUINT_TO_POINTER (type),
+ GUINT_TO_POINTER (factory_type));
+}
+
+GType
+atk_registry_get_factory_type (AtkRegistry *registry,
+ GType type)
+{
+ GType factory_type;
+ gpointer value;
+
+ /*
+ * look up factory type in first hash;
+ * if there isn't an explicitly registered factory type,
+ * try inheriting one...
+ */
+ do {
+ value =
+ g_hash_table_lookup (registry->factory_type_registry,
+ GUINT_TO_POINTER (type));
+ type = g_type_parent (type);
+ if (type == G_TYPE_INVALID)
+ {
+ break;
+ }
+ } while (value == NULL);
+
+ factory_type = GPOINTER_TO_UINT (value);
+ return factory_type;
+}
+
+
+AtkObjectFactory*
+atk_registry_get_factory (AtkRegistry *registry,
+ GType type)
+{
+ gpointer factory_pointer = NULL;
+ GType factory_type;
+
+ factory_type = atk_registry_get_factory_type (registry, type);
+
+ if (factory_type == G_TYPE_INVALID)
+ {
+ /* Factory type has not been specified for this object type */
+ static AtkObjectFactory* default_factory = NULL;
+
+ if (!default_factory)
+ default_factory = atk_no_op_object_factory_new ();
+
+ return default_factory;
+ }
+
+ /* ask second hashtable for instance of factory type */
+ factory_pointer =
+ g_hash_table_lookup (registry->factory_singleton_cache,
+ GUINT_TO_POINTER (factory_type));
+
+ /* if there isn't one already, create one and save it */
+ if (factory_pointer == NULL)
+ {
+ factory_pointer = g_type_create_instance (factory_type);
+ g_hash_table_insert (registry->factory_singleton_cache,
+ GUINT_TO_POINTER (factory_type),
+ factory_pointer);
+ }
+
+ return ATK_OBJECT_FACTORY (factory_pointer);
+}
+
+
+AtkRegistry*
+atk_get_default_registry ()
+{
+ if (!default_registry)
+ {
+ default_registry = atk_registry_new();
+ }
+ return default_registry;
+}