diff options
author | Bill Haneman <billh@src.gnome.org> | 2001-04-26 14:23:41 +0000 |
---|---|---|
committer | Bill Haneman <billh@src.gnome.org> | 2001-04-26 14:23:41 +0000 |
commit | dba66b4bec94a908cd35a5537209db255fa5fa33 (patch) | |
tree | 3c6361db3558e2e2c70e9c802193974f45d24bf0 /atk/atkregistry.c | |
download | atk-dba66b4bec94a908cd35a5537209db255fa5fa33.tar.gz |
Initial revision
Diffstat (limited to 'atk/atkregistry.c')
-rw-r--r-- | atk/atkregistry.c | 229 |
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; +} |