1 /* This file is part of GEGL
2 *
3 * GEGL is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 3 of the License, or (at your option) any later version.
7 *
8 * GEGL is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with GEGL; if not, see <https://www.gnu.org/licenses/>.
15 *
16 * Copyright 2014 Øyvind Kolås
17 */
18
19 #include "config.h"
20
21 #include <glib-object.h>
22 #include <string.h>
23
24 #include "gegl.h"
25 #include "gegl-operation.h"
26 #include "gegl-operations.h"
27 #include "gegl-operation-property-keys.h"
28
29 static GHashTable *
gegl_param_spec_get_property_key_ht(GParamSpec * pspec,gboolean create)30 gegl_param_spec_get_property_key_ht (GParamSpec *pspec,
31 gboolean create)
32 {
33 GHashTable *ret = NULL;
34 if (pspec)
35 {
36 GQuark quark = g_quark_from_static_string ("gegl-property-keys");
37 ret = g_param_spec_get_qdata (pspec, quark);
38 if (!ret && create)
39 {
40 ret = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
41 g_param_spec_set_qdata_full (pspec, quark, ret,
42 (GDestroyNotify)g_hash_table_unref);
43 }
44 }
45 return ret;
46 }
47
48 const gchar *
gegl_param_spec_get_property_key(GParamSpec * pspec,const gchar * key_name)49 gegl_param_spec_get_property_key (GParamSpec *pspec,
50 const gchar *key_name)
51 {
52 GHashTable *ht;
53 ht = gegl_param_spec_get_property_key_ht (pspec, FALSE);
54 if (ht)
55 return g_hash_table_lookup (ht, key_name);
56 return NULL;
57 }
58
59 void
gegl_param_spec_set_property_key(GParamSpec * pspec,const gchar * key_name,const gchar * value)60 gegl_param_spec_set_property_key (GParamSpec *pspec,
61 const gchar *key_name,
62 const gchar *value)
63 {
64 GHashTable *ht;
65 ht = gegl_param_spec_get_property_key_ht (pspec, TRUE);
66
67 if (value)
68 g_hash_table_insert (ht, g_strdup (key_name), g_strdup (value));
69 else
70 g_hash_table_remove (ht, key_name);
71 }
72
73 static GHashTable *
gegl_operation_class_get_property_key_ht(GeglOperationClass * operation_class,const gchar * property_name,gboolean create)74 gegl_operation_class_get_property_key_ht (GeglOperationClass *operation_class,
75 const gchar *property_name,
76 gboolean create)
77 {
78 GParamSpec *pspec;
79 pspec = g_object_class_find_property (G_OBJECT_CLASS (operation_class),
80 property_name);
81 if (pspec)
82 return gegl_param_spec_get_property_key_ht (pspec, create);
83 return NULL;
84 }
85
86 gchar **
gegl_operation_list_property_keys(const gchar * operation_name,const gchar * property_name,guint * n_keys)87 gegl_operation_list_property_keys (const gchar *operation_name,
88 const gchar *property_name,
89 guint *n_keys)
90 {
91 GType type;
92 GObjectClass *klass;
93 GHashTable *ht = NULL;
94 GList *list, *l;
95 gchar **ret;
96 int count;
97 int i;
98 type = gegl_operation_gtype_from_name (operation_name);
99 if (!type)
100 {
101 if (n_keys)
102 *n_keys = 0;
103 return NULL;
104 }
105 klass = g_type_class_ref (type);
106 ht = gegl_operation_class_get_property_key_ht (GEGL_OPERATION_CLASS (klass),
107 property_name, FALSE);
108 if (!ht)
109 {
110 count = 0;
111 ret = g_malloc0 (sizeof (gpointer));;
112 }
113 else
114 {
115 count = g_hash_table_size (ht);
116 ret = g_malloc0 (sizeof (gpointer) * (count + 1));
117 list = g_hash_table_get_keys (ht);
118 for (i = 0, l = list; l; l = l->next, i++)
119 {
120 ret[i] = l->data;
121 }
122 g_list_free (list);
123 }
124 if (n_keys)
125 *n_keys = count;
126 g_type_class_unref (klass);
127 return ret;
128 }
129
130 void
gegl_operation_class_set_property_key(GeglOperationClass * operation_class,const gchar * property_name,const gchar * key_name,const gchar * value)131 gegl_operation_class_set_property_key (GeglOperationClass *operation_class,
132 const gchar *property_name,
133 const gchar *key_name,
134 const gchar *value)
135 {
136 GParamSpec *pspec;
137 pspec = g_object_class_find_property (G_OBJECT_CLASS (operation_class),
138 property_name);
139 if (pspec)
140 gegl_param_spec_set_property_key (pspec, key_name, value);
141 }
142
143
144 const gchar *
gegl_operation_class_get_property_key(GeglOperationClass * operation_class,const gchar * property_name,const gchar * key_name)145 gegl_operation_class_get_property_key (GeglOperationClass *operation_class,
146 const gchar *property_name,
147 const gchar *key_name)
148 {
149 GParamSpec *pspec;
150 pspec = g_object_class_find_property (G_OBJECT_CLASS (operation_class),
151 property_name);
152 if (pspec)
153 return gegl_param_spec_get_property_key (pspec, key_name);
154 return NULL;
155 }
156
157 const gchar *
gegl_operation_get_property_key(const gchar * operation_name,const gchar * property_name,const gchar * property_key_name)158 gegl_operation_get_property_key (const gchar *operation_name,
159 const gchar *property_name,
160 const gchar *property_key_name)
161 {
162 GType type;
163 GObjectClass *klass;
164 const gchar *ret = NULL;
165 type = gegl_operation_gtype_from_name (operation_name);
166 if (!type)
167 {
168 return NULL;
169 }
170 klass = g_type_class_ref (type);
171 ret = gegl_operation_class_get_property_key (GEGL_OPERATION_CLASS (klass),
172 property_name,
173 property_key_name);
174 g_type_class_unref (klass);
175 return ret;
176 }
177