aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/lib/canvas/evas_smart.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libraries/evas/src/lib/canvas/evas_smart.c266
1 files changed, 266 insertions, 0 deletions
diff --git a/libraries/evas/src/lib/canvas/evas_smart.c b/libraries/evas/src/lib/canvas/evas_smart.c
new file mode 100644
index 0000000..0cfba05
--- /dev/null
+++ b/libraries/evas/src/lib/canvas/evas_smart.c
@@ -0,0 +1,266 @@
1#include "evas_common.h"
2#include "evas_private.h"
3
4
5static void _evas_smart_class_callbacks_create(Evas_Smart *s);
6
7/* all public */
8
9EAPI void
10evas_smart_free(Evas_Smart *s)
11{
12 MAGIC_CHECK(s, Evas_Smart, MAGIC_SMART);
13 return;
14 MAGIC_CHECK_END();
15 s->delete_me = 1;
16 if (s->usage > 0) return;
17 if (s->class_allocated) free((void *)s->smart_class);
18 free(s->callbacks.array);
19 free(s);
20}
21
22EAPI Evas_Smart *
23evas_smart_class_new(const Evas_Smart_Class *sc)
24{
25 Evas_Smart *s;
26
27 if (!sc) return NULL;
28
29 /* api does not match abi! for now refuse as we only have 1 version */
30 if (sc->version != EVAS_SMART_CLASS_VERSION) return NULL;
31
32 s = evas_mem_calloc(sizeof(Evas_Smart));
33 if (!s) return NULL;
34
35 s->magic = MAGIC_SMART;
36
37 s->smart_class = sc;
38 _evas_smart_class_callbacks_create(s);
39
40 return s;
41}
42
43EAPI const Evas_Smart_Class *
44evas_smart_class_get(const Evas_Smart *s)
45{
46 MAGIC_CHECK(s, Evas_Smart, MAGIC_SMART);
47 return NULL;
48 MAGIC_CHECK_END();
49 return s->smart_class;
50}
51
52EAPI void *
53evas_smart_data_get(const Evas_Smart *s)
54{
55 MAGIC_CHECK(s, Evas_Smart, MAGIC_SMART);
56 return NULL;
57 MAGIC_CHECK_END();
58 return (void *)s->smart_class->data;
59}
60
61EAPI const Evas_Smart_Cb_Description **
62evas_smart_callbacks_descriptions_get(const Evas_Smart *s, unsigned int *count)
63{
64 MAGIC_CHECK(s, Evas_Smart, MAGIC_SMART);
65 if (count) *count = 0;
66 return NULL;
67 MAGIC_CHECK_END();
68
69 if (count) *count = s->callbacks.size;
70 return s->callbacks.array;
71}
72
73EAPI const Evas_Smart_Cb_Description *
74evas_smart_callback_description_find(const Evas_Smart *s, const char *name)
75{
76 if (!name) return NULL;
77 MAGIC_CHECK(s, Evas_Smart, MAGIC_SMART);
78 return NULL;
79 MAGIC_CHECK_END();
80 return evas_smart_cb_description_find(&s->callbacks, name);
81}
82
83EAPI Eina_Bool
84evas_smart_class_inherit_full(Evas_Smart_Class *sc, const Evas_Smart_Class *parent_sc, unsigned int parent_sc_size)
85{
86 unsigned int off;
87
88 /* api does not match abi! for now refuse as we only have 1 version */
89 if (parent_sc->version != EVAS_SMART_CLASS_VERSION) return EINA_FALSE;
90
91#define _CP(m) sc->m = parent_sc->m
92 _CP(add);
93 _CP(del);
94 _CP(move);
95 _CP(resize);
96 _CP(show);
97 _CP(hide);
98 _CP(color_set);
99 _CP(clip_set);
100 _CP(clip_unset);
101 _CP(calculate);
102 _CP(member_add);
103 _CP(member_del);
104#undef _CP
105
106 sc->parent = parent_sc;
107
108 off = sizeof(Evas_Smart_Class);
109 if (parent_sc_size == off) return EINA_TRUE;
110
111 memcpy(((char *)sc) + off, ((char *)parent_sc) + off, parent_sc_size - off);
112 return EINA_TRUE;
113}
114
115EAPI int
116evas_smart_usage_get(const Evas_Smart *s)
117{
118 MAGIC_CHECK(s, Evas_Smart, MAGIC_SMART);
119 return 0;
120 MAGIC_CHECK_END();
121 return s->usage;
122}
123
124
125/* internal funcs */
126void
127evas_object_smart_use(Evas_Smart *s)
128{
129 s->usage++;
130}
131
132void
133evas_object_smart_unuse(Evas_Smart *s)
134{
135 s->usage--;
136 if ((s->usage <= 0) && (s->delete_me)) evas_smart_free(s);
137}
138
139Eina_Bool
140evas_smart_cb_descriptions_resize(Evas_Smart_Cb_Description_Array *a, unsigned int size)
141{
142 void *tmp;
143
144 if (size == a->size)
145 return EINA_TRUE;
146
147 if (size == EINA_FALSE)
148 {
149 free(a->array);
150 a->array = NULL;
151 a->size = 0;
152 return EINA_TRUE;
153 }
154
155 tmp = realloc(a->array, (size + 1) * sizeof(Evas_Smart_Cb_Description *));
156 if (tmp)
157 {
158 a->array = tmp;
159 a->size = size;
160 a->array[size] = NULL;
161 return EINA_TRUE;
162 }
163 else
164 {
165 ERR("realloc failed!");
166 return EINA_FALSE;
167 }
168}
169
170static int
171_evas_smart_cb_description_cmp_sort(const void *p1, const void *p2)
172{
173 const Evas_Smart_Cb_Description **a = (const Evas_Smart_Cb_Description **)p1;
174 const Evas_Smart_Cb_Description **b = (const Evas_Smart_Cb_Description **)p2;
175 return strcmp((*a)->name, (*b)->name);
176}
177
178void
179evas_smart_cb_descriptions_fix(Evas_Smart_Cb_Description_Array *a)
180{
181 unsigned int i, j;
182
183 if (!a)
184 {
185 ERR("no array to fix!");
186 return;
187 }
188
189 qsort(a->array, a->size, sizeof(Evas_Smart_Cb_Description *),
190 _evas_smart_cb_description_cmp_sort);
191
192 DBG("%u callbacks", a->size);
193 if (a->size)
194 DBG("%s [type=%s]", a->array[0]->name, a->array[0]->type);
195
196 for (i = 0, j = 1; j < a->size; j++)
197 {
198 const Evas_Smart_Cb_Description *cur, *prev;
199
200 cur = a->array[j];
201 prev = a->array[i];
202
203 DBG("%s [type=%s]", cur->name, cur->type);
204
205 if (strcmp(cur->name, prev->name) != 0)
206 {
207 i++;
208 if (i != j)
209 a->array[i] = a->array[j];
210 }
211 else
212 {
213 if (strcmp(cur->type, prev->type) == 0)
214 WRN("duplicated smart callback description"
215 " with name '%s' and type '%s'", cur->name, cur->type);
216 else
217 ERR("callback descriptions named '%s' differ"
218 " in type, keeping '%s', ignoring '%s'",
219 cur->name, prev->type, cur->type);
220 }
221 }
222
223 evas_smart_cb_descriptions_resize(a, i + 1);
224}
225
226static void
227_evas_smart_class_callbacks_create(Evas_Smart *s)
228{
229 const Evas_Smart_Class *sc;
230 unsigned int n = 0;
231
232 for (sc = s->smart_class; sc; sc = sc->parent)
233 {
234 const Evas_Smart_Cb_Description *d;
235 for (d = sc->callbacks; d && d->name; d++)
236 n++;
237 }
238
239 if (n == 0) return;
240 if (!evas_smart_cb_descriptions_resize(&s->callbacks, n)) return;
241 for (n = 0, sc = s->smart_class; sc; sc = sc->parent)
242 {
243 const Evas_Smart_Cb_Description *d;
244 for (d = sc->callbacks; d && d->name; d++)
245 s->callbacks.array[n++] = d;
246 }
247 evas_smart_cb_descriptions_fix(&s->callbacks);
248}
249
250static int
251_evas_smart_cb_description_cmp_search(const void *p1, const void *p2)
252{
253 const char *name = p1;
254 const Evas_Smart_Cb_Description **v = (const Evas_Smart_Cb_Description **)p2;
255 /* speed up string shares searches (same pointers) */
256 if (name == (*v)->name) return 0;
257 return strcmp(name, (*v)->name);
258}
259
260const Evas_Smart_Cb_Description *
261evas_smart_cb_description_find(const Evas_Smart_Cb_Description_Array *a, const char *name)
262{
263 if (!a->array) return NULL;
264 return bsearch(name, a->array, a->size, sizeof(Evas_Smart_Cb_Description *),
265 _evas_smart_cb_description_cmp_search);
266}