123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- /* LIBGIMP - The GIMP Library
- * Copyright (C) 1995-2003 Peter Mattis and Spencer Kimball
- *
- * gimpconfig-register.c
- * Copyright (C) 2008-2019 Michael Natterer <mitch@gimp.org>
- *
- * This library is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see
- * <https://www.gnu.org/licenses/>.
- */
- #include "config.h"
- #include <cairo.h>
- #include <gdk-pixbuf/gdk-pixbuf.h>
- #include <gegl-paramspecs.h>
- #include "libgimpbase/gimpbase.h"
- #include "gimpconfig.h"
- /* local function prototypes */
- static void gimp_config_class_init (GObjectClass *klass,
- GParamSpec **pspecs);
- static void gimp_config_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec);
- static void gimp_config_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec);
- static GValue * gimp_config_value_get (GObject *object,
- GParamSpec *pspec);
- static GValue * gimp_config_value_new (GParamSpec *pspec);
- static void gimp_config_value_free (GValue *value);
- /* public functions */
- /**
- * gimp_config_type_register:
- * @parent_type: type from which this type will be derived
- * @type_name: string used as the name of the new type
- * @pspecs: (array length=n_pspecs): array of #GParamSpec to install as properties on the new type
- * @n_pspecs: the number of param specs in @pspecs
- *
- * This function is a fancy wrapper around g_type_register_static().
- * It creates a new object type as subclass of @parent_type, installs
- * @pspecs on it and makes the new type implement the #GimpConfig
- * interface.
- *
- * Returns: the newly registered #GType
- *
- * Since: 3.0
- **/
- GType
- gimp_config_type_register (GType parent_type,
- const gchar *type_name,
- GParamSpec **pspecs,
- gint n_pspecs)
- {
- GParamSpec **terminated_pspecs;
- GTypeQuery query;
- GType config_type;
- g_return_val_if_fail (g_type_is_a (parent_type, G_TYPE_OBJECT), G_TYPE_NONE);
- g_return_val_if_fail (type_name != NULL, G_TYPE_NONE);
- g_return_val_if_fail (pspecs != NULL || n_pspecs == 0, G_TYPE_NONE);
- terminated_pspecs = g_new0 (GParamSpec *, n_pspecs + 1);
- memcpy (terminated_pspecs, pspecs, sizeof (GParamSpec *) * n_pspecs);
- g_type_query (parent_type, &query);
- {
- GTypeInfo info =
- {
- query.class_size,
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) gimp_config_class_init,
- NULL, /* class_finalize */
- terminated_pspecs,
- query.instance_size,
- 0, /* n_preallocs */
- (GInstanceInitFunc) NULL,
- };
- config_type = g_type_register_static (parent_type, type_name,
- &info, 0);
- if (! g_type_is_a (parent_type, GIMP_TYPE_CONFIG))
- {
- const GInterfaceInfo config_info =
- {
- NULL, /* interface_init */
- NULL, /* interface_finalize */
- NULL /* interface_data */
- };
- g_type_add_interface_static (config_type, GIMP_TYPE_CONFIG,
- &config_info);
- }
- }
- return config_type;
- }
- /* private functions */
- static void
- gimp_config_class_init (GObjectClass *klass,
- GParamSpec **pspecs)
- {
- gint i;
- klass->set_property = gimp_config_set_property;
- klass->get_property = gimp_config_get_property;
- for (i = 0; pspecs[i] != NULL; i++)
- {
- GParamSpec *pspec = pspecs[i];
- GParamSpec *copy = gimp_config_param_spec_duplicate (pspec);
- if (copy)
- {
- g_object_class_install_property (klass, i + 1, copy);
- }
- else
- {
- GType value_type = G_PARAM_SPEC_VALUE_TYPE (pspec);
- const gchar *type_name = g_type_name (value_type);
- /* There are some properties that we don't care to copy because they
- * are not serializable anyway (or we don't want them to be).
- * GimpContext properties are one such property type. We can find them
- * e.g. in some custom GEGL ops, such as "gimp:offset". So we silently
- * ignore these.
- * We might add more types of properties to the list as we discover
- * more cases. We keep warnings for all the other types which we
- * explicitly don't support.
- */
- if (g_strcmp0 (type_name, "GimpContext") != 0 &&
- /* Format specs are a GParamSpecPointer. There might be other
- * pointer specs we might be able to serialize, but BablFormat are
- * not one of these (there might be easy serializable formats, but
- * many are not and anyway it's probably not a data which ops or
- * plug-ins want to remember across run).
- */
- ! GEGL_IS_PARAM_SPEC_FORMAT (pspec))
- g_warning ("%s: not supported: %s (%s | %s)\n", G_STRFUNC,
- g_type_name (G_TYPE_FROM_INSTANCE (pspec)), pspec->name, type_name);
- }
- }
- }
- static void
- gimp_config_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
- {
- GValue *val = gimp_config_value_get (object, pspec);
- g_value_copy (value, val);
- }
- static void
- gimp_config_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
- {
- GValue *val = gimp_config_value_get (object, pspec);
- g_value_copy (val, value);
- }
- static GValue *
- gimp_config_value_get (GObject *object,
- GParamSpec *pspec)
- {
- GHashTable *properties;
- GValue *value;
- properties = g_object_get_data (object, "gimp-config-properties");
- if (! properties)
- {
- properties =
- g_hash_table_new_full (g_str_hash,
- g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) gimp_config_value_free);
- g_object_set_data_full (object, "gimp-config-properties", properties,
- (GDestroyNotify) g_hash_table_unref);
- }
- value = g_hash_table_lookup (properties, pspec->name);
- if (! value)
- {
- value = gimp_config_value_new (pspec);
- g_hash_table_insert (properties, g_strdup (pspec->name), value);
- }
- return value;
- }
- static GValue *
- gimp_config_value_new (GParamSpec *pspec)
- {
- GValue *value = g_slice_new0 (GValue);
- g_value_init (value, pspec->value_type);
- g_param_value_set_default (pspec, value);
- return value;
- }
- static void
- gimp_config_value_free (GValue *value)
- {
- g_value_unset (value);
- g_slice_free (GValue, value);
- }
|