aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/edje/src/lib/edje_load.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libraries/edje/src/lib/edje_load.c1549
1 files changed, 0 insertions, 1549 deletions
diff --git a/libraries/edje/src/lib/edje_load.c b/libraries/edje/src/lib/edje_load.c
deleted file mode 100644
index b63cd88..0000000
--- a/libraries/edje/src/lib/edje_load.c
+++ /dev/null
@@ -1,1549 +0,0 @@
1#include "edje_private.h"
2
3#ifdef EDJE_PROGRAM_CACHE
4static Eina_Bool _edje_collection_free_prog_cache_matches_free_cb(const Eina_Hash *hash, const void *key, void *data, void *fdata);
5#endif
6static void _edje_object_pack_item_hints_set(Evas_Object *obj, Edje_Pack_Element *it);
7static void _cb_signal_repeat(void *data, Evas_Object *obj, const char *signal, const char *source);
8
9static Eina_List *_edje_swallows_collect(Edje *ed);
10
11/************************** API Routines **************************/
12
13EAPI Eina_Bool
14edje_object_file_set(Evas_Object *obj, const char *file, const char *group)
15{
16 Eina_Bool ret;
17 Edje *ed;
18
19 ed = _edje_fetch(obj);
20 if (!ed)
21 return EINA_FALSE;
22 ret = ed->api->file_set(obj, file, group);
23 _edje_object_orientation_inform(obj);
24 return ret;
25}
26
27EAPI void
28edje_object_file_get(const Evas_Object *obj, const char **file, const char **group)
29{
30 Edje *ed;
31
32 ed = _edje_fetch(obj);
33 if (!ed)
34 {
35 if (file) *file = NULL;
36 if (group) *group = NULL;
37 return;
38 }
39 if (file) *file = ed->path;
40 if (group) *group = ed->group;
41}
42
43EAPI Edje_Load_Error
44edje_object_load_error_get(const Evas_Object *obj)
45{
46 Edje *ed;
47
48 ed = _edje_fetch(obj);
49 if (!ed) return EDJE_LOAD_ERROR_NONE;
50 return ed->load_error;
51}
52
53EAPI const char *
54edje_load_error_str(Edje_Load_Error error)
55{
56 switch (error)
57 {
58 case EDJE_LOAD_ERROR_NONE:
59 return "No Error";
60 case EDJE_LOAD_ERROR_GENERIC:
61 return "Generic Error";
62 case EDJE_LOAD_ERROR_DOES_NOT_EXIST:
63 return "File Does Not Exist";
64 case EDJE_LOAD_ERROR_PERMISSION_DENIED:
65 return "Permission Denied";
66 case EDJE_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED:
67 return "Resource Allocation Failed";
68 case EDJE_LOAD_ERROR_CORRUPT_FILE:
69 return "Corrupt File";
70 case EDJE_LOAD_ERROR_UNKNOWN_FORMAT:
71 return "Unknown Format";
72 case EDJE_LOAD_ERROR_INCOMPATIBLE_FILE:
73 return "Incompatible File";
74 case EDJE_LOAD_ERROR_UNKNOWN_COLLECTION:
75 return "Unknown Collection";
76 case EDJE_LOAD_ERROR_RECURSIVE_REFERENCE:
77 return "Recursive Reference";
78 default:
79 return "Unknown Error";
80 }
81}
82
83
84EAPI Eina_List *
85edje_file_collection_list(const char *file)
86{
87 Eina_List *lst = NULL;
88 Edje_File *edf;
89 int error_ret = 0;
90
91 if ((!file) || (!*file)) return NULL;
92 edf = _edje_cache_file_coll_open(file, NULL, &error_ret, NULL);
93 if (edf)
94 {
95 Eina_Iterator *i;
96 const char *key;
97
98 i = eina_hash_iterator_key_new(edf->collection);
99
100 EINA_ITERATOR_FOREACH(i, key)
101 lst = eina_list_append(lst, eina_stringshare_add(key));
102
103 eina_iterator_free(i);
104
105 _edje_cache_file_unref(edf);
106 }
107 return lst;
108}
109
110EAPI void
111edje_file_collection_list_free(Eina_List *lst)
112{
113 while (lst)
114 {
115 if (eina_list_data_get(lst)) eina_stringshare_del(eina_list_data_get(lst));
116 lst = eina_list_remove(lst, eina_list_data_get(lst));
117 }
118}
119
120EAPI Eina_Bool
121edje_file_group_exists(const char *file, const char *glob)
122{
123 Edje_File *edf;
124 int error_ret = 0;
125 Eina_Bool succeed = EINA_FALSE;
126 Eina_Bool is_glob = EINA_FALSE;
127 const char *p;
128
129 if ((!file) || (!*file))
130 return EINA_FALSE;
131
132 edf = _edje_cache_file_coll_open(file, NULL, &error_ret, NULL);
133 if (!edf)
134 return EINA_FALSE;
135
136 for (p = glob; *p; p++)
137 {
138 if ((*p == '*') || (*p == '?') || (*p == '['))
139 {
140 is_glob = EINA_TRUE;
141 break;
142 }
143 }
144
145 if (is_glob)
146 {
147 if (!edf->collection_patterns)
148 {
149 Edje_Part_Collection_Directory_Entry *ce;
150 Eina_Iterator *i;
151 Eina_List *l = NULL;
152
153 i = eina_hash_iterator_data_new(edf->collection);
154
155 EINA_ITERATOR_FOREACH(i, ce)
156 l = eina_list_append(l, ce);
157
158 eina_iterator_free(i);
159
160 edf->collection_patterns = edje_match_collection_dir_init(l);
161 eina_list_free(l);
162 }
163
164 succeed = edje_match_collection_dir_exec(edf->collection_patterns, glob);
165 if (edf->collection_patterns)
166 {
167 edje_match_patterns_free(edf->collection_patterns);
168 edf->collection_patterns = NULL;
169 }
170 }
171 else
172 {
173 if (eina_hash_find(edf->collection, glob)) succeed = EINA_TRUE;
174 }
175 _edje_cache_file_unref(edf);
176
177 INF("edje_file_group_exists: '%s', '%s': %i\n", file, glob, succeed);
178
179 return succeed;
180}
181
182
183EAPI char *
184edje_file_data_get(const char *file, const char *key)
185{
186 Edje_File *edf;
187 char *str = NULL;
188 int error_ret = 0;
189
190 if (key)
191 {
192 edf = _edje_cache_file_coll_open(file, NULL, &error_ret, NULL);
193 if (edf)
194 {
195 str = (char*) edje_string_get(eina_hash_find(edf->data, key));
196
197 if (str) str = strdup(str);
198
199 _edje_cache_file_unref(edf);
200 }
201 }
202 return str;
203}
204
205void
206_edje_programs_patterns_clean(Edje *ed)
207{
208 _edje_signals_sources_patterns_clean(&ed->patterns.programs);
209
210 eina_rbtree_delete(ed->patterns.programs.exact_match,
211 EINA_RBTREE_FREE_CB(edje_match_signal_source_free),
212 NULL);
213 ed->patterns.programs.exact_match = NULL;
214
215 free(ed->patterns.programs.u.programs.globing);
216 ed->patterns.programs.u.programs.globing = NULL;
217}
218
219void
220_edje_programs_patterns_init(Edje *ed)
221{
222 Edje_Signals_Sources_Patterns *ssp = &ed->patterns.programs;
223 Edje_Program **all;
224 unsigned int i, j;
225
226 if (ssp->signals_patterns)
227 return;
228
229 if (getenv("EDJE_DUMP_PROGRAMS"))
230 {
231 INF("Group '%s' programs:", ed->group);
232#define EDJE_DUMP_PROGRAM(Section) \
233 for (i = 0; i < ed->collection->programs.Section##_count; i++) \
234 INF(#Section" for ('%s', '%s')", ed->collection->programs.Section[i]->signal, ed->collection->programs.Section[i]->source);
235
236 EDJE_DUMP_PROGRAM(strcmp);
237 EDJE_DUMP_PROGRAM(strncmp);
238 EDJE_DUMP_PROGRAM(strrncmp);
239 EDJE_DUMP_PROGRAM(fnmatch);
240 EDJE_DUMP_PROGRAM(nocmp);
241 }
242
243 edje_match_program_hash_build(ed->collection->programs.strcmp,
244 ed->collection->programs.strcmp_count,
245 &ssp->exact_match);
246
247 j = ed->collection->programs.strncmp_count
248 + ed->collection->programs.strrncmp_count
249 + ed->collection->programs.fnmatch_count
250 + ed->collection->programs.nocmp_count;
251 if (j == 0) return ;
252
253 all = malloc(sizeof (Edje_Program *) * j);
254 if (!all) return ;
255 j = 0;
256
257 /* FIXME: Build specialized data type for each case */
258#define EDJE_LOAD_PROGRAMS_ADD(Array, Ed, It, Git, All) \
259 for (It = 0; It < Ed->collection->programs.Array##_count; ++It, ++Git) \
260 All[Git] = Ed->collection->programs.Array[It];
261
262 EDJE_LOAD_PROGRAMS_ADD(fnmatch, ed, i, j, all);
263 EDJE_LOAD_PROGRAMS_ADD(strncmp, ed, i, j, all);
264 EDJE_LOAD_PROGRAMS_ADD(strrncmp, ed, i, j, all);
265 /* FIXME: Do a special pass for that one */
266 EDJE_LOAD_PROGRAMS_ADD(nocmp, ed, i, j, all);
267
268 ssp->u.programs.globing = all;
269 ssp->u.programs.count = j;
270 ssp->signals_patterns = edje_match_programs_signal_init(all, j);
271 ssp->sources_patterns = edje_match_programs_source_init(all, j);
272}
273
274int
275_edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *group, const char *parent, Eina_List *group_path)
276{
277 Edje *ed;
278 Evas *tev;
279 Edje_Real_Part *rp;
280 Eina_List *textblocks = NULL;
281 Eina_List *sources = NULL;
282 Eina_List *externals = NULL;
283 Eina_List *old_swallows;
284 unsigned int n;
285 Eina_List *parts = NULL;
286 int group_path_started = 0;
287
288 ed = _edje_fetch(obj);
289 if (!ed) return 0;
290 if (!file) file = "";
291 if (!group) group = "";
292 if (((ed->path) && (!strcmp(file, ed->path))) &&
293 (ed->group) && (!strcmp(group, ed->group)))
294 return 1;
295
296 tev = evas_object_evas_get(obj);
297 evas_event_freeze(tev);
298 old_swallows = _edje_swallows_collect(ed);
299
300 if (_edje_script_only(ed)) _edje_script_only_shutdown(ed);
301 if (_edje_lua_script_only(ed)) _edje_lua_script_only_shutdown(ed);
302 _edje_file_del(ed);
303
304 eina_stringshare_replace(&ed->path, file);
305 eina_stringshare_replace(&ed->group, group);
306
307 ed->parent = eina_stringshare_add(parent);
308
309 ed->load_error = EDJE_LOAD_ERROR_NONE;
310 _edje_file_add(ed);
311 ed->block_break = 0;
312
313 if (ed->file && ed->file->external_dir)
314 {
315 unsigned int i;
316
317 for (i = 0; i < ed->file->external_dir->entries_count; ++i)
318 edje_module_load(ed->file->external_dir->entries[i].entry);
319 }
320
321 _edje_textblock_styles_add(ed);
322 _edje_textblock_style_all_update(ed);
323
324 ed->has_entries = EINA_FALSE;
325
326 if (ed->collection)
327 {
328 if (ed->collection->prop.orientation != EDJE_ORIENTATION_AUTO)
329 ed->is_rtl = (ed->collection->prop.orientation ==
330 EDJE_ORIENTATION_RTL);
331
332 if (ed->collection->script_only)
333 {
334 ed->load_error = EDJE_LOAD_ERROR_NONE;
335 _edje_script_only_init(ed);
336 }
337 else if (ed->collection->lua_script_only)
338 {
339 ed->load_error = EDJE_LOAD_ERROR_NONE;
340 _edje_lua_script_only_init(ed);
341 }
342 else
343 {
344 unsigned int i;
345
346 /* colorclass stuff */
347 for (i = 0; i < ed->collection->parts_count; ++i)
348 {
349 Edje_Part *ep;
350 unsigned int k;
351
352 ep = ed->collection->parts[i];
353
354 /* Register any color classes in this parts descriptions. */
355 if ((ep->default_desc) && (ep->default_desc->color_class))
356 _edje_color_class_member_add(ed, ep->default_desc->color_class);
357
358 for (k = 0; k < ep->other.desc_count; k++)
359 {
360 Edje_Part_Description_Common *desc;
361
362 desc = ep->other.desc[k];
363
364 if (desc->color_class)
365 _edje_color_class_member_add(ed, desc->color_class);
366 }
367 }
368 /* build real parts */
369 for (n = 0; n < ed->collection->parts_count; n++)
370 {
371 Edje_Part *ep;
372
373 ep = ed->collection->parts[n];
374 rp = eina_mempool_malloc(_edje_real_part_mp, sizeof(Edje_Real_Part));
375 if (!rp)
376 {
377 /* FIXME: destroy all allocated ressource, need to have a common exit point */
378 ed->load_error = EDJE_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
379 evas_event_thaw(tev);
380 evas_event_thaw_eval(tev);
381 return 0;
382 }
383
384 memset(rp, 0, sizeof (Edje_Real_Part));
385
386 if ((ep->dragable.x != 0) || (ep->dragable.y != 0))
387 {
388 rp->drag = calloc(1, sizeof (Edje_Real_Part_Drag));
389 if (!rp->drag)
390 {
391 ed->load_error = EDJE_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
392 eina_mempool_free(_edje_real_part_mp, rp);
393 evas_event_thaw(tev);
394 evas_event_thaw_eval(tev);
395 return 0;
396 }
397
398 rp->drag->step.x = FROM_INT(ep->dragable.step_x);
399 rp->drag->step.y = FROM_INT(ep->dragable.step_y);
400 }
401
402 rp->edje = ed;
403 _edje_ref(rp->edje);
404 rp->part = ep;
405 parts = eina_list_append(parts, rp);
406 rp->param1.description =
407 _edje_part_description_find(ed, rp, "default", 0.0);
408 rp->chosen_description = rp->param1.description;
409 if (!rp->param1.description)
410 ERR("no default part description!");
411
412 switch (ep->type)
413 {
414 case EDJE_PART_TYPE_RECTANGLE:
415 rp->object = evas_object_rectangle_add(ed->base.evas);
416 break;
417 case EDJE_PART_TYPE_PROXY:
418 case EDJE_PART_TYPE_IMAGE:
419 rp->object = evas_object_image_add(ed->base.evas);
420 break;
421 case EDJE_PART_TYPE_TEXT:
422 _edje_text_part_on_add(ed, rp);
423 rp->object = evas_object_text_add(ed->base.evas);
424 evas_object_text_font_source_set(rp->object, ed->path);
425 break;
426 case EDJE_PART_TYPE_GROUP:
427 sources = eina_list_append(sources, rp);
428 case EDJE_PART_TYPE_SWALLOW:
429 case EDJE_PART_TYPE_EXTERNAL:
430 if (ep->type == EDJE_PART_TYPE_EXTERNAL)
431 externals = eina_list_append(externals, rp);
432 rp->object = evas_object_rectangle_add(ed->base.evas);
433 evas_object_color_set(rp->object, 0, 0, 0, 0);
434 evas_object_pass_events_set(rp->object, 1);
435 evas_object_pointer_mode_set(rp->object, EVAS_OBJECT_POINTER_MODE_NOGRAB);
436 _edje_callbacks_focus_add(rp->object, ed, rp);
437 break;
438 case EDJE_PART_TYPE_TEXTBLOCK:
439 textblocks = eina_list_append(textblocks, rp);
440 rp->object = evas_object_textblock_add(ed->base.evas);
441 break;
442 case EDJE_PART_TYPE_BOX:
443 sources = eina_list_append(sources, rp);
444 rp->object = evas_object_box_add(ed->base.evas);
445 rp->anim = _edje_box_layout_anim_new(rp->object);
446 break;
447 case EDJE_PART_TYPE_TABLE:
448 sources = eina_list_append(sources, rp);
449 rp->object = evas_object_table_add(ed->base.evas);
450 break;
451 case EDJE_PART_TYPE_GRADIENT:
452 ERR("SPANK ! SPANK ! SPANK ! YOU ARE USING GRADIENT IN PART %s FROM GROUP %s INSIDE FILE %s !! THEY ARE NOW REMOVED !",
453 ep->name, group, file);
454 default:
455 ERR("wrong part type %i!", ep->type);
456 break;
457 }
458
459 if (rp->object)
460 {
461 evas_object_smart_member_add(rp->object, ed->obj);
462// evas_object_layer_set(rp->object, evas_object_layer_get(ed->obj));
463 if (ep->type != EDJE_PART_TYPE_SWALLOW && ep->type != EDJE_PART_TYPE_GROUP && ep->type != EDJE_PART_TYPE_EXTERNAL)
464 {
465 if (ep->mouse_events)
466 {
467 _edje_callbacks_add(rp->object, ed, rp);
468 if (ep->repeat_events)
469 evas_object_repeat_events_set(rp->object, 1);
470
471 if (ep->pointer_mode != EVAS_OBJECT_POINTER_MODE_AUTOGRAB)
472 evas_object_pointer_mode_set(rp->object, ep->pointer_mode);
473 }
474 else
475 {
476 evas_object_pass_events_set(rp->object, 1);
477 evas_object_pointer_mode_set(rp->object, EVAS_OBJECT_POINTER_MODE_NOGRAB);
478 }
479 if (ep->precise_is_inside)
480 evas_object_precise_is_inside_set(rp->object, 1);
481 }
482 if (rp->part->clip_to_id < 0)
483 evas_object_clip_set(rp->object, ed->base.clipper);
484 }
485 }
486 if (n > 0)
487 {
488 Eina_List *l;
489
490 ed->table_parts = malloc(sizeof(Edje_Real_Part *) * n);
491 ed->table_parts_size = n;
492 /* FIXME: check malloc return */
493 n = 0;
494 EINA_LIST_FOREACH(parts, l, rp)
495 {
496 ed->table_parts[n] = rp;
497 n++;
498 }
499 eina_list_free(parts);
500 for (i = 0; i < ed->table_parts_size; i++)
501 {
502 rp = ed->table_parts[i];
503 if (rp->param1.description) /* FIXME: prevent rel to gone radient part to go wrong. You may
504 be able to remove this when all theme are correctly rewritten. */
505 {
506 if (rp->param1.description->rel1.id_x >= 0)
507 rp->param1.rel1_to_x = ed->table_parts[rp->param1.description->rel1.id_x % ed->table_parts_size];
508 if (rp->param1.description->rel1.id_y >= 0)
509 rp->param1.rel1_to_y = ed->table_parts[rp->param1.description->rel1.id_y % ed->table_parts_size];
510 if (rp->param1.description->rel2.id_x >= 0)
511 rp->param1.rel2_to_x = ed->table_parts[rp->param1.description->rel2.id_x % ed->table_parts_size];
512 if (rp->param1.description->rel2.id_y >= 0)
513 rp->param1.rel2_to_y = ed->table_parts[rp->param1.description->rel2.id_y % ed->table_parts_size];
514 }
515 if (rp->part->clip_to_id >= 0)
516 {
517 rp->clip_to = ed->table_parts[rp->part->clip_to_id % ed->table_parts_size];
518 if (rp->clip_to)
519 {
520 evas_object_pass_events_set(rp->clip_to->object, 1);
521 evas_object_pointer_mode_set(rp->clip_to->object, EVAS_OBJECT_POINTER_MODE_NOGRAB);
522 evas_object_clip_set(rp->object, rp->clip_to->object);
523 }
524 }
525 if (rp->drag)
526 {
527 if (rp->part->dragable.confine_id >= 0)
528 rp->drag->confine_to = ed->table_parts[rp->part->dragable.confine_id % ed->table_parts_size];
529 }
530
531 /* replay events for dragable */
532 if (rp->part->dragable.event_id >= 0)
533 {
534 rp->events_to =
535 ed->table_parts[rp->part->dragable.event_id % ed->table_parts_size];
536 /* events_to may be used only with dragable */
537 if (!rp->events_to->part->dragable.x &&
538 !rp->events_to->part->dragable.y)
539 rp->events_to = NULL;
540 }
541
542 rp->swallow_params.min.w = 0;
543 rp->swallow_params.min.h = 0;
544 rp->swallow_params.max.w = -1;
545 rp->swallow_params.max.h = -1;
546
547 if (rp->part->type == EDJE_PART_TYPE_TEXT
548 || rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
549 {
550 Edje_Part_Description_Text *text;
551
552 text = (Edje_Part_Description_Text *) rp->param1.description;
553
554 if (ed->file->feature_ver < 1)
555 {
556 text->text.id_source = -1;
557 text->text.id_text_source = -1;
558 }
559
560 if (text->text.id_source >= 0)
561 rp->text.source = ed->table_parts[text->text.id_source % ed->table_parts_size];
562 if (text->text.id_text_source >= 0)
563 rp->text.text_source = ed->table_parts[text->text.id_text_source % ed->table_parts_size];
564 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
565 {
566 _edje_entry_real_part_init(rp);
567 if (!ed->has_entries)
568 ed->has_entries = EINA_TRUE;
569 }
570 }
571 }
572 }
573
574 _edje_programs_patterns_init(ed);
575
576 n = ed->collection->programs.fnmatch_count +
577 ed->collection->programs.strcmp_count +
578 ed->collection->programs.strncmp_count +
579 ed->collection->programs.strrncmp_count +
580 ed->collection->programs.nocmp_count;
581 if (n > 0)
582 {
583 Edje_Program *pr;
584
585 ed->table_programs = malloc(sizeof(Edje_Program *) * n);
586 if (ed->table_programs)
587 {
588 ed->table_programs_size = n;
589
590#define EDJE_LOAD_BUILD_TABLE(Array, Ed, It, Tmp) \
591 for (It = 0; It < Ed->collection->programs.Array##_count; ++It) \
592 { \
593 Tmp = Ed->collection->programs.Array[It]; \
594 Ed->table_programs[Tmp->id] = Tmp; \
595 }
596
597 EDJE_LOAD_BUILD_TABLE(fnmatch, ed, i, pr);
598 EDJE_LOAD_BUILD_TABLE(strcmp, ed, i, pr);
599 EDJE_LOAD_BUILD_TABLE(strncmp, ed, i, pr);
600 EDJE_LOAD_BUILD_TABLE(strrncmp, ed, i, pr);
601 EDJE_LOAD_BUILD_TABLE(nocmp, ed, i, pr);
602 }
603 }
604 _edje_ref(ed);
605 _edje_block(ed);
606 _edje_freeze(ed);
607// if (ed->collection->script) _edje_embryo_script_init(ed);
608 _edje_var_init(ed);
609 for (i = 0; i < ed->table_parts_size; i++)
610 {
611 rp = ed->table_parts[i];
612 evas_object_show(rp->object);
613 if (_edje_block_break(ed)) break;
614 if (rp->drag)
615 {
616 if (rp->part->dragable.x < 0) rp->drag->val.x = FROM_DOUBLE(1.0);
617 if (rp->part->dragable.y < 0) rp->drag->val.x = FROM_DOUBLE(1.0);
618 _edje_dragable_pos_set(ed, rp, rp->drag->val.x, rp->drag->val.y);
619 }
620 }
621 ed->recalc_call = 1;
622 ed->dirty = 1;
623#ifdef EDJE_CALC_CACHE
624 ed->all_part_change = 1;
625#endif
626 if ((evas_object_clipees_get(ed->base.clipper)) &&
627 (evas_object_visible_get(obj)))
628 evas_object_show(ed->base.clipper);
629
630 /* instantiate 'internal swallows' */
631 EINA_LIST_FREE(externals, rp)
632 {
633 Edje_Part_Description_External *external;
634 Evas_Object *child_obj;
635
636 external = (Edje_Part_Description_External *) rp->part->default_desc;
637 child_obj = _edje_external_type_add(rp->part->source,
638 evas_object_evas_get(ed->obj), ed->obj,
639 external->external_params, rp->part->name);
640 if (child_obj)
641 {
642 _edje_real_part_swallow(rp, child_obj, EINA_TRUE);
643 rp->param1.external_params = _edje_external_params_parse(child_obj,
644 external->external_params);
645 _edje_external_recalc_apply(ed, rp, NULL, rp->chosen_description);
646 }
647 }
648
649 EINA_LIST_FREE(sources, rp)
650 {
651 /* XXX: curr_item and pack_it don't require to be NULL since
652 * XXX: they are just used when source != NULL and type == BOX,
653 * XXX: and they're always set in this case, but GCC fails to
654 * XXX: notice that, so let's shut it up
655 */
656 Edje_Pack_Element **curr_item = NULL;
657 unsigned int item_count = 0;
658 Edje_Pack_Element *pack_it = NULL;
659 const char *source = NULL;
660
661 switch (rp->part->type)
662 {
663 case EDJE_PART_TYPE_GROUP:
664 source = rp->part->source;
665 break;
666 case EDJE_PART_TYPE_BOX:
667 case EDJE_PART_TYPE_TABLE:
668 if (rp->part->items)
669 {
670 curr_item = rp->part->items;
671 item_count = rp->part->items_count;
672 if (item_count > 0)
673 {
674 pack_it = *curr_item;
675 source = pack_it->source;
676 item_count--;
677 curr_item++;
678 }
679 }
680 break;
681 default:
682 /* This list should only be filled by group, box or table, nothing else. */
683 abort();
684 continue;
685 }
686
687 while (source)
688 {
689 Eina_List *l;
690 Evas_Object *child_obj;
691 const char *group_path_entry = eina_stringshare_add(source);
692 const char *data;
693
694 if (!group_path)
695 {
696 group_path = eina_list_append(NULL, eina_stringshare_add(group));
697 group_path_started = 1;
698 }
699 /* make sure that this group isn't already in the tree of parents */
700 EINA_LIST_FOREACH(group_path, l, data)
701 {
702 if (data == group_path_entry)
703 {
704 ERR("recursive loop group '%s' already included inside part '%s' of group '%s' from file '%s'",
705 group_path_entry, rp->part->name, group, file);
706 textblocks = eina_list_free(textblocks);
707 externals = eina_list_free(externals);
708 sources = eina_list_free(sources);
709 _edje_thaw(ed);
710 _edje_unblock(ed);
711 _edje_unref(ed);
712 _edje_file_del(ed);
713 eina_stringshare_del(group_path_entry);
714 if (group_path_started)
715 {
716 eina_stringshare_del(eina_list_data_get(group_path));
717 eina_list_free(group_path);
718 }
719 ed->load_error = EDJE_LOAD_ERROR_RECURSIVE_REFERENCE;
720 evas_event_thaw(tev);
721 evas_event_thaw_eval(tev);
722 return 0;
723 }
724 }
725
726 child_obj = edje_object_add(ed->base.evas);
727 group_path = eina_list_append(group_path, group_path_entry);
728 if (rp->part->type == EDJE_PART_TYPE_GROUP)
729 {
730 _edje_real_part_swallow(rp, child_obj, EINA_FALSE);
731 }
732
733 if (!_edje_object_file_set_internal(child_obj, file, source, rp->part->name, group_path))
734 {
735 ERR("impossible to set part '%s' of group '%s' from file '%s' to '%s'",
736 rp->part->name, group_path_entry, file, source);
737 textblocks = eina_list_free(textblocks);
738 externals = eina_list_free(externals);
739 sources = eina_list_free(sources);
740 _edje_thaw(ed);
741 _edje_unblock(ed);
742 _edje_unref(ed);
743 _edje_file_del(ed);
744
745 if (group_path_started)
746 {
747 while (group_path)
748 {
749 eina_stringshare_del(eina_list_data_get(group_path));
750 group_path = eina_list_remove_list(group_path, group_path);
751 }
752 }
753 ed->load_error = edje_object_load_error_get(child_obj);
754 evas_object_del(child_obj);
755 evas_event_thaw(tev);
756 evas_event_thaw_eval(tev);
757 return 0;
758 }
759
760 group_path = eina_list_remove(group_path, group_path_entry);
761 eina_stringshare_del(group_path_entry);
762
763 edje_object_propagate_callback_add(child_obj,
764 _cb_signal_repeat,
765 obj);
766 if (rp->part->type == EDJE_PART_TYPE_GROUP)
767 {
768 _edje_real_part_swallow(rp, child_obj, EINA_TRUE);
769 _edje_subobj_register(ed, child_obj);
770 source = NULL;
771 }
772 else
773 {
774 pack_it->parent = rp;
775
776 _edje_object_pack_item_hints_set(child_obj, pack_it);
777 if (pack_it->name)
778 evas_object_name_set(child_obj, pack_it->name);
779
780 if (rp->part->type == EDJE_PART_TYPE_BOX)
781 {
782 _edje_real_part_box_append(rp, child_obj);
783 evas_object_data_set(child_obj, "\377 edje.box_item", pack_it);
784 }
785 else if (rp->part->type == EDJE_PART_TYPE_TABLE)
786 {
787 _edje_real_part_table_pack(rp, child_obj, pack_it->col, pack_it->row, pack_it->colspan, pack_it->rowspan);
788 evas_object_data_set(child_obj, "\377 edje.table_item", pack_it);
789 }
790 _edje_subobj_register(ed, child_obj);
791 evas_object_show(child_obj);
792 rp->items = eina_list_append(rp->items, child_obj);
793
794 if (item_count > 0)
795 {
796 pack_it = *curr_item;
797 source = pack_it->source;
798 curr_item++;
799 item_count--;
800 }
801 else
802 {
803 source = NULL;
804 curr_item = NULL;
805 pack_it = NULL;
806 }
807 }
808 }
809 }
810
811 if (group_path_started)
812 {
813 const char *str;
814
815 EINA_LIST_FREE(group_path, str)
816 eina_stringshare_del(str);
817 }
818
819 /* reswallow any swallows that existed before setting the file */
820 if (old_swallows)
821 {
822 while (old_swallows)
823 {
824 const char *name;
825 Evas_Object *swallow;
826
827 name = eina_list_data_get(old_swallows);
828 old_swallows = eina_list_remove_list(old_swallows, old_swallows);
829
830 swallow = eina_list_data_get(old_swallows);
831 old_swallows = eina_list_remove_list(old_swallows, old_swallows);
832
833 edje_object_part_swallow(obj, name, swallow);
834 eina_stringshare_del(name);
835 }
836 }
837
838 _edje_recalc(ed);
839 _edje_thaw(ed);
840 _edje_unblock(ed);
841 _edje_unref(ed);
842 ed->load_error = EDJE_LOAD_ERROR_NONE;
843 _edje_emit(ed, "load", NULL);
844
845 /* instantiate 'internal textblock style' */
846 EINA_LIST_FREE(textblocks, rp)
847 if (rp->part->default_desc)
848 {
849 Edje_Part_Description_Text *text;
850 Edje_Style *stl = NULL;
851 const char *style;
852
853 text = (Edje_Part_Description_Text *) rp->part->default_desc;
854 style = edje_string_get(&text->text.style);
855 if (style)
856 {
857 Eina_List *l;
858
859 EINA_LIST_FOREACH(ed->file->styles, l, stl)
860 {
861 if ((stl->name) && (!strcmp(stl->name, style))) break;
862 stl = NULL;
863 }
864 }
865 if (stl)
866 {
867 if (evas_object_textblock_style_get(rp->object) != stl->style)
868 evas_object_textblock_style_set(rp->object, stl->style);
869 }
870 }
871 }
872 _edje_entry_init(ed);
873 evas_event_thaw(tev);
874 evas_event_thaw_eval(tev);
875 return 1;
876 }
877 else
878 {
879 evas_event_thaw(tev);
880 evas_event_thaw_eval(tev);
881 return 0;
882 }
883 ed->load_error = EDJE_LOAD_ERROR_NONE;
884 _edje_entry_init(ed);
885 evas_event_thaw(tev);
886 evas_event_thaw_eval(tev);
887 return 1;
888}
889
890void
891_edje_file_add(Edje *ed)
892{
893 if (!_edje_edd_edje_file) return;
894 ed->file = _edje_cache_file_coll_open(ed->path, ed->group,
895 &(ed->load_error),
896 &(ed->collection));
897
898 if (!ed->collection)
899 {
900 if (ed->file)
901 {
902 _edje_cache_file_unref(ed->file);
903 ed->file = NULL;
904 }
905 }
906}
907
908static Eina_List *
909_edje_swallows_collect(Edje *ed)
910{
911 Eina_List *swallows = NULL;
912 unsigned int i;
913
914 if (!ed->file || !ed->table_parts) return NULL;
915 for (i = 0; i < ed->table_parts_size; i++)
916 {
917 Edje_Real_Part *rp;
918
919 rp = ed->table_parts[i];
920 if (rp->part->type != EDJE_PART_TYPE_SWALLOW || !rp->swallowed_object) continue;
921 swallows = eina_list_append(swallows, eina_stringshare_add(rp->part->name));
922 swallows = eina_list_append(swallows, rp->swallowed_object);
923 }
924 return swallows;
925}
926
927void
928_edje_file_del(Edje *ed)
929{
930 Evas *tev = evas_object_evas_get(ed->obj);
931
932 evas_event_freeze(tev);
933 if (ed->freeze_calc)
934 {
935 _edje_freeze_calc_list = eina_list_remove(_edje_freeze_calc_list, ed);
936 ed->freeze_calc = 0;
937 _edje_freeze_calc_count--;
938 }
939 _edje_entry_shutdown(ed);
940 _edje_message_del(ed);
941 _edje_block_violate(ed);
942 _edje_var_shutdown(ed);
943 _edje_programs_patterns_clean(ed);
944// if (ed->collection)
945// {
946// if (ed->collection->script) _edje_embryo_script_shutdown(ed);
947// }
948
949 if (!((ed->file) && (ed->collection)))
950 {
951 evas_event_thaw(tev);
952 evas_event_thaw_eval(tev);
953 return;
954 }
955 if (ed->table_parts)
956 {
957 unsigned int i;
958 for (i = 0; i < ed->table_parts_size; i++)
959 {
960 Edje_Real_Part *rp;
961
962 rp = ed->table_parts[i];
963 if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
964 _edje_entry_real_part_shutdown(rp);
965 if (rp->object)
966 {
967 _edje_callbacks_del(rp->object, ed);
968 _edje_callbacks_focus_del(rp->object, ed);
969 evas_object_del(rp->object);
970 }
971 if (rp->swallowed_object)
972 {
973 _edje_real_part_swallow_clear(rp);
974 /* Objects swallowed by the app do not get deleted,
975 but those internally swallowed (GROUP type) do. */
976 switch (rp->part->type)
977 {
978 case EDJE_PART_TYPE_EXTERNAL:
979 _edje_external_parsed_params_free(rp->swallowed_object, rp->param1.external_params);
980 if (rp->param2)
981 _edje_external_parsed_params_free(rp->swallowed_object, rp->param2->external_params);
982 case EDJE_PART_TYPE_GROUP:
983 evas_object_del(rp->swallowed_object);
984 default:
985 break;
986 }
987 rp->swallowed_object = NULL;
988 }
989 if (rp->items)
990 {
991 /* evas_box/table handles deletion of objects */
992 rp->items = eina_list_free(rp->items);
993 }
994 if (rp->anim)
995 {
996 _edje_box_layout_free_data(rp->anim);
997 rp->anim = NULL;
998 }
999 if (rp->text.text) eina_stringshare_del(rp->text.text);
1000 if (rp->text.font) eina_stringshare_del(rp->text.font);
1001 if (rp->text.cache.in_str) eina_stringshare_del(rp->text.cache.in_str);
1002 if (rp->text.cache.out_str) eina_stringshare_del(rp->text.cache.out_str);
1003
1004 if (rp->custom)
1005 {
1006 // xxx: lua2
1007 _edje_collection_free_part_description_clean(rp->part->type,
1008 rp->custom->description,
1009 ed->file->free_strings);
1010 free(rp->custom->description);
1011 rp->custom->description = NULL;
1012 }
1013
1014 /* Cleanup optional part. */
1015 free(rp->drag);
1016 free(rp->param1.set);
1017
1018 if (rp->param2)
1019 free(rp->param2->set);
1020 eina_mempool_free(_edje_real_part_state_mp, rp->param2);
1021
1022 if (rp->custom)
1023 free(rp->custom->set);
1024 eina_mempool_free(_edje_real_part_state_mp, rp->custom);
1025
1026 _edje_unref(rp->edje);
1027 eina_mempool_free(_edje_real_part_mp, rp);
1028 }
1029 }
1030 if ((ed->file) && (ed->collection))
1031 {
1032 Edje_Part *ep;
1033 unsigned int i;
1034
1035 _edje_textblock_styles_del(ed);
1036 for (i = 0; i < ed->collection->parts_count; ++i)
1037 {
1038 ep = ed->collection->parts[i];
1039
1040 _edje_text_part_on_del(ed, ep);
1041 _edje_color_class_on_del(ed, ep);
1042 }
1043
1044 _edje_cache_coll_unref(ed->file, ed->collection);
1045 ed->collection = NULL;
1046 }
1047 if (ed->file)
1048 {
1049 _edje_cache_file_unref(ed->file);
1050 ed->file = NULL;
1051 }
1052 if (ed->actions)
1053 {
1054 Edje_Running_Program *runp;
1055
1056 EINA_LIST_FREE(ed->actions, runp)
1057 {
1058 _edje_anim_count--;
1059 free(runp);
1060 }
1061 }
1062 _edje_animators = eina_list_remove(_edje_animators, ed);
1063 if (ed->pending_actions)
1064 {
1065 Edje_Pending_Program *pp;
1066
1067 EINA_LIST_FREE(ed->pending_actions, pp)
1068 {
1069 ecore_timer_del(pp->timer);
1070 free(pp);
1071 }
1072 }
1073 if (ed->L) _edje_lua2_script_shutdown(ed);
1074 while (ed->subobjs) evas_object_del(ed->subobjs->data);
1075 if (ed->table_parts) free(ed->table_parts);
1076 ed->table_parts = NULL;
1077 ed->table_parts_size = 0;
1078 if (ed->table_programs) free(ed->table_programs);
1079 ed->table_programs = NULL;
1080 ed->table_programs_size = 0;
1081 ed->focused_part = NULL;
1082 evas_event_thaw(tev);
1083 evas_event_thaw_eval(tev);
1084}
1085
1086void
1087_edje_file_free(Edje_File *edf)
1088{
1089 Edje_Color_Class *ecc;
1090
1091#define HASH_FREE(Hash) \
1092 if (Hash) eina_hash_free(Hash); \
1093 Hash = NULL;
1094
1095 /* Clean cache before cleaning memory pool */
1096 if (edf->collection_cache) _edje_cache_coll_flush(edf);
1097
1098 HASH_FREE(edf->fonts);
1099 HASH_FREE(edf->collection);
1100 HASH_FREE(edf->data);
1101
1102 if (edf->image_dir)
1103 {
1104 unsigned int i;
1105
1106 if (edf->free_strings)
1107 {
1108 for (i = 0; i < edf->image_dir->entries_count; ++i)
1109 eina_stringshare_del(edf->image_dir->entries[i].entry);
1110 }
1111
1112 /* Sets have been added after edje received eet dictionnary support */
1113 for (i = 0; i < edf->image_dir->sets_count; ++i)
1114 {
1115 Edje_Image_Directory_Set_Entry *se;
1116
1117 EINA_LIST_FREE(edf->image_dir->sets[i].entries, se)
1118 free(se);
1119
1120 }
1121
1122 free(edf->image_dir->entries);
1123 free(edf->image_dir->sets);
1124 free(edf->image_dir);
1125 }
1126 if (edf->sound_dir)
1127 {
1128 unsigned int i;
1129
1130 if (edf->free_strings)
1131 {
1132 for (i = 0; i < edf->sound_dir->samples_count; ++i)
1133 {
1134 eina_stringshare_del(edf->sound_dir->samples[i].name);
1135 eina_stringshare_del(edf->sound_dir->samples[i].snd_src);
1136 }
1137
1138 for (i = 0; i < edf->sound_dir->tones_count; ++i)
1139 eina_stringshare_del(edf->sound_dir->tones[i].name);
1140 }
1141 free(edf->sound_dir->samples);
1142 free(edf->sound_dir->tones);
1143 free(edf->sound_dir);
1144 }
1145
1146 if (edf->external_dir)
1147 {
1148 if (edf->external_dir->entries) free(edf->external_dir->entries);
1149 free(edf->external_dir);
1150 }
1151
1152 EINA_LIST_FREE(edf->color_classes, ecc)
1153 {
1154 if (edf->free_strings && ecc->name) eina_stringshare_del(ecc->name);
1155 free(ecc);
1156 }
1157
1158 if (edf->collection_patterns) edje_match_patterns_free(edf->collection_patterns);
1159 if (edf->path) eina_stringshare_del(edf->path);
1160 if (edf->free_strings && edf->compiler) eina_stringshare_del(edf->compiler);
1161 _edje_textblock_style_cleanup(edf);
1162 if (edf->ef) eet_close(edf->ef);
1163 free(edf);
1164}
1165
1166static void
1167_edje_program_free(Edje_Program *pr, Eina_Bool free_strings)
1168{
1169 Edje_Program_Target *prt;
1170 Edje_Program_After *pa;
1171
1172 if (free_strings)
1173 {
1174 if (pr->name) eina_stringshare_del(pr->name);
1175 if (pr->signal) eina_stringshare_del(pr->signal);
1176 if (pr->source) eina_stringshare_del(pr->source);
1177 if (pr->filter.part) eina_stringshare_del(pr->filter.part);
1178 if (pr->filter.state) eina_stringshare_del(pr->filter.state);
1179 if (pr->state) eina_stringshare_del(pr->state);
1180 if (pr->state2) eina_stringshare_del(pr->state2);
1181 if (pr->sample_name) eina_stringshare_del(pr->sample_name);
1182 if (pr->tone_name) eina_stringshare_del(pr->tone_name);
1183 }
1184 EINA_LIST_FREE(pr->targets, prt)
1185 free(prt);
1186 EINA_LIST_FREE(pr->after, pa)
1187 free(pa);
1188 free(pr);
1189}
1190
1191void
1192_edje_collection_free(Edje_File *edf, Edje_Part_Collection *ec, Edje_Part_Collection_Directory_Entry *ce)
1193{
1194 unsigned int i;
1195
1196 _edje_embryo_script_shutdown(ec);
1197
1198#define EDJE_LOAD_PROGRAM_FREE(Array, Ec, It, FreeStrings) \
1199 for (It = 0; It < Ec->programs.Array##_count; ++It) \
1200 _edje_program_free(Ec->programs.Array[It], FreeStrings); \
1201 free(Ec->programs.Array);
1202
1203 EDJE_LOAD_PROGRAM_FREE(fnmatch, ec, i, edf->free_strings);
1204 EDJE_LOAD_PROGRAM_FREE(strcmp, ec, i, edf->free_strings);
1205 EDJE_LOAD_PROGRAM_FREE(strncmp, ec, i, edf->free_strings);
1206 EDJE_LOAD_PROGRAM_FREE(strrncmp, ec, i, edf->free_strings);
1207 EDJE_LOAD_PROGRAM_FREE(nocmp, ec, i, edf->free_strings);
1208
1209 for (i = 0; i < ec->parts_count; ++i)
1210 {
1211 Edje_Part *ep;
1212 unsigned int j;
1213
1214 ep = ec->parts[i];
1215
1216 if (edf->free_strings && ep->name) eina_stringshare_del(ep->name);
1217 if (ep->default_desc)
1218 {
1219 _edje_collection_free_part_description_clean(ep->type, ep->default_desc, edf->free_strings);
1220 ep->default_desc = NULL;
1221 }
1222 for (j = 0; j < ep->other.desc_count; ++j)
1223 _edje_collection_free_part_description_clean(ep->type, ep->other.desc[j], edf->free_strings);
1224
1225 free(ep->other.desc);
1226 /* Alloc for RTL objects in edje_calc.c:_edje_part_description_find() */
1227 if(ep->other.desc_rtl)
1228 free(ep->other.desc_rtl);
1229
1230 free(ep->items);
1231// technically need this - but we ASSUME we use "one_big" so everything gets
1232// freed in one go lower down when we del the mempool... but what if pool goes
1233// "over"?
1234 eina_mempool_free(ce->mp.part, ep);
1235 }
1236 free(ec->parts);
1237 ec->parts = NULL;
1238
1239 if (ec->data)
1240 {
1241 Eina_Iterator *it;
1242 Edje_String *es;
1243
1244 it = eina_hash_iterator_data_new(ec->data);
1245 EINA_ITERATOR_FOREACH(it, es)
1246 free(es);
1247 eina_iterator_free(it);
1248
1249 eina_hash_free(ec->data);
1250 }
1251#ifdef EDJE_PROGRAM_CACHE
1252 if (ec->prog_cache.no_matches) eina_hash_free(ec->prog_cache.no_matches);
1253 if (ec->prog_cache.matches)
1254 {
1255 eina_hash_foreach(ec->prog_cache.matches,
1256 _edje_collection_free_prog_cache_matches_free_cb,
1257 NULL);
1258 eina_hash_free(ec->prog_cache.matches);
1259 }
1260#endif
1261 if (ec->script) embryo_program_free(ec->script);
1262 _edje_lua2_script_unload(ec);
1263
1264 /* Destroy all part and description. */
1265 eina_mempool_del(ce->mp.RECTANGLE);
1266 eina_mempool_del(ce->mp.TEXT);
1267 eina_mempool_del(ce->mp.IMAGE);
1268 eina_mempool_del(ce->mp.PROXY);
1269 eina_mempool_del(ce->mp.SWALLOW);
1270 eina_mempool_del(ce->mp.TEXTBLOCK);
1271 eina_mempool_del(ce->mp.GROUP);
1272 eina_mempool_del(ce->mp.BOX);
1273 eina_mempool_del(ce->mp.TABLE);
1274 eina_mempool_del(ce->mp.EXTERNAL);
1275 eina_mempool_del(ce->mp.part);
1276 memset(&ce->mp, 0, sizeof (ce->mp));
1277
1278 eina_mempool_del(ce->mp_rtl.RECTANGLE);
1279 eina_mempool_del(ce->mp_rtl.TEXT);
1280 eina_mempool_del(ce->mp_rtl.IMAGE);
1281 eina_mempool_del(ce->mp_rtl.PROXY);
1282 eina_mempool_del(ce->mp_rtl.SWALLOW);
1283 eina_mempool_del(ce->mp_rtl.TEXTBLOCK);
1284 eina_mempool_del(ce->mp_rtl.GROUP);
1285 eina_mempool_del(ce->mp_rtl.BOX);
1286 eina_mempool_del(ce->mp_rtl.TABLE);
1287 eina_mempool_del(ce->mp_rtl.EXTERNAL);
1288 memset(&ce->mp_rtl, 0, sizeof (ce->mp_rtl));
1289 free(ec);
1290 ce->ref = NULL;
1291}
1292
1293void
1294_edje_collection_free_part_description_clean(int type, Edje_Part_Description_Common *desc, Eina_Bool free_strings)
1295{
1296 if (free_strings && desc->color_class) eina_stringshare_del(desc->color_class);
1297
1298 switch (type)
1299 {
1300 case EDJE_PART_TYPE_IMAGE:
1301 {
1302 Edje_Part_Description_Image *img;
1303 unsigned int i;
1304
1305 img = (Edje_Part_Description_Image *) desc;
1306
1307 for (i = 0; i < img->image.tweens_count; ++i)
1308 free(img->image.tweens[i]);
1309 free(img->image.tweens);
1310 break;
1311 }
1312 case EDJE_PART_TYPE_EXTERNAL:
1313 {
1314 Edje_Part_Description_External *external;
1315
1316 external = (Edje_Part_Description_External *) desc;
1317
1318 if (external->external_params)
1319 _edje_external_params_free(external->external_params, free_strings);
1320 break;
1321 }
1322 case EDJE_PART_TYPE_TEXT:
1323 case EDJE_PART_TYPE_TEXTBLOCK:
1324 if (free_strings)
1325 {
1326 Edje_Part_Description_Text *text;
1327
1328 text = (Edje_Part_Description_Text *) desc;
1329
1330 if (text->text.text.str) eina_stringshare_del(text->text.text.str);
1331 if (text->text.text_class) eina_stringshare_del(text->text.text_class);
1332 if (text->text.style.str) eina_stringshare_del(text->text.style.str);
1333 if (text->text.font.str) eina_stringshare_del(text->text.font.str);
1334 }
1335 break;
1336 }
1337}
1338
1339void
1340_edje_collection_free_part_description_free(int type,
1341 Edje_Part_Description_Common *desc,
1342 Edje_Part_Collection_Directory_Entry *ce,
1343 Eina_Bool free_strings)
1344{
1345#define FREE_POOL(Type, Ce, Desc) \
1346 case EDJE_PART_TYPE_##Type: eina_mempool_free(Ce->mp.Type, Desc); \
1347 ce->count.Type--; \
1348 break;
1349
1350 _edje_collection_free_part_description_clean(type, desc, free_strings);
1351
1352 switch (type)
1353 {
1354 FREE_POOL(RECTANGLE, ce, desc);
1355 FREE_POOL(TEXT, ce, desc);
1356 FREE_POOL(IMAGE, ce, desc);
1357 FREE_POOL(PROXY, ce, desc);
1358 FREE_POOL(SWALLOW, ce, desc);
1359 FREE_POOL(TEXTBLOCK, ce, desc);
1360 FREE_POOL(GROUP, ce, desc);
1361 FREE_POOL(BOX, ce, desc);
1362 FREE_POOL(TABLE, ce, desc);
1363 FREE_POOL(EXTERNAL, ce, desc);
1364 }
1365}
1366
1367#ifdef EDJE_PROGRAM_CACHE
1368static Eina_Bool
1369_edje_collection_free_prog_cache_matches_free_cb(const Eina_Hash *hash, const void *key, void *data, void *fdata)
1370{
1371 eina_list_free((Eina_List *)data);
1372 return EINA_TRUE;
1373 key = NULL;
1374 hash = NULL;
1375 fdata = NULL;
1376}
1377#endif
1378
1379static void
1380_edje_object_pack_item_hints_set(Evas_Object *obj, Edje_Pack_Element *it)
1381{
1382 Evas_Coord w = 0, h = 0, minw, minh;
1383
1384 minw = it->min.w;
1385 minh = it->min.h;
1386
1387 if ((minw <= 0) && (minh <= 0))
1388 {
1389 edje_object_size_min_get(obj, &w, &h);
1390 if ((w <= 0) && (h <= 0))
1391 edje_object_size_min_calc(obj, &w, &h);
1392 }
1393 else
1394 {
1395 w = minw;
1396 h = minh;
1397 }
1398 if (((minw <= 0) && (minh <= 0)) && ((w > 0) || (h > 0)))
1399 evas_object_size_hint_min_set(obj, w, h);
1400 else
1401 evas_object_size_hint_min_set(obj, minw, minh);
1402
1403 evas_object_size_hint_request_set(obj, it->prefer.w, it->prefer.h);
1404 evas_object_size_hint_max_set(obj, it->max.w, it->max.h);
1405 evas_object_size_hint_padding_set(obj, it->padding.l, it->padding.r, it->padding.t, it->padding.b);
1406 evas_object_size_hint_align_set(obj, it->align.x, it->align.y);
1407 evas_object_size_hint_weight_set(obj, it->weight.x, it->weight.y);
1408 evas_object_size_hint_aspect_set(obj, it->aspect.mode, it->aspect.w, it->aspect.h);
1409
1410 evas_object_resize(obj, w, h);
1411}
1412
1413static const char *
1414_edje_find_alias(Eina_Hash *aliased, char *src, int *length)
1415{
1416 const char *alias;
1417 char *search;
1418
1419 *length = strlen(src);
1420 if (*length == 0) return NULL;
1421
1422 alias = eina_hash_find(aliased, src);
1423 if (alias) return alias;
1424
1425 search = strrchr(src, EDJE_PART_PATH_SEPARATOR);
1426 if (search == NULL) return NULL;
1427
1428 *search = '\0';
1429 alias = _edje_find_alias(aliased, src, length);
1430 *search = EDJE_PART_PATH_SEPARATOR;
1431
1432 return alias;
1433}
1434
1435static void
1436_cb_signal_repeat(void *data, Evas_Object *obj, const char *sig, const char *source)
1437{
1438 Edje_Pack_Element *pack_it;
1439 Evas_Object *parent;
1440 Edje *ed;
1441 Edje *ed_parent;
1442 char new_src[4096]; /* XXX is this max reasonable? */
1443 size_t length_parent = 0;
1444 size_t length_index = 0;
1445 size_t length_source;
1446 int i = 0;
1447 const char *alias = NULL;
1448 Edje_Message_Signal emsg;
1449
1450 parent = data;
1451 ed = _edje_fetch(obj);
1452 if (!ed) return;
1453
1454 pack_it = evas_object_data_get(obj, "\377 edje.box_item");
1455 if (!pack_it) pack_it = evas_object_data_get(obj, "\377 edje.table_item");
1456 if (pack_it)
1457 {
1458 if (!pack_it->name)
1459 {
1460 Eina_List *child = NULL;
1461 Evas_Object *o;
1462
1463 if (pack_it->parent->part->type == EDJE_PART_TYPE_BOX)
1464 {
1465 child = evas_object_box_children_get(pack_it->parent->object);
1466 }
1467 else if (pack_it->parent->part->type == EDJE_PART_TYPE_TABLE)
1468 {
1469 child = evas_object_table_children_get(pack_it->parent->object);
1470 }
1471
1472 EINA_LIST_FREE(child, o)
1473 {
1474 if (o == obj) break;
1475 i++;
1476 }
1477
1478 eina_list_free(child);
1479
1480 length_index = 12;
1481 }
1482 else
1483 {
1484 length_index = strlen(pack_it->name) + 2;
1485 }
1486 }
1487
1488 /* Replace snprint("%s%c%s") == memcpy + *new_src + memcat */
1489 if (ed->parent)
1490 length_parent = strlen(ed->parent);
1491 length_source = strlen(source);
1492 if (length_source + length_parent + 2 + length_index > sizeof(new_src))
1493 return;
1494
1495 if (ed->parent)
1496 memcpy(new_src, ed->parent, length_parent);
1497 if (ed->parent && length_index)
1498 {
1499 new_src[length_parent++] = EDJE_PART_PATH_SEPARATOR_INDEXL;
1500 if (length_index == 12)
1501 length_parent += eina_convert_itoa(i, new_src + length_parent);
1502 else
1503 {
1504 memcpy(new_src + length_parent, pack_it->name, length_index);
1505 length_parent += length_index - 2;
1506 }
1507 new_src[length_parent++] = EDJE_PART_PATH_SEPARATOR_INDEXR;
1508 }
1509
1510 new_src[length_parent] = EDJE_PART_PATH_SEPARATOR;
1511 memcpy(new_src + length_parent + 1, source, length_source + 1);
1512
1513 /* Handle alias renaming */
1514 ed_parent = _edje_fetch(parent);
1515 if (ed_parent && ed_parent->collection && ed_parent->collection->aliased)
1516 {
1517 int length;
1518
1519 alias = _edje_find_alias(ed_parent->collection->aliased, new_src, &length);
1520
1521 if (alias)
1522 {
1523 int origin;
1524
1525 /* Add back the end of the source */
1526 origin = strlen(new_src);
1527 length ++; /* Remove the trailing ':' from the count */
1528 if (origin > length)
1529 {
1530 char *tmp;
1531 size_t alias_length;
1532
1533 alias_length = strlen(alias);
1534 tmp = alloca(alias_length + origin - length + 2);
1535 memcpy(tmp, alias, alias_length);
1536 tmp[alias_length] = EDJE_PART_PATH_SEPARATOR;
1537 memcpy(tmp + alias_length + 1, new_src + length, origin - length + 1);
1538
1539 alias = tmp;
1540 }
1541 }
1542 }
1543
1544 emsg.sig = sig;
1545 emsg.src = alias ? alias : new_src;
1546 emsg.data = NULL;
1547 _edje_message_send(ed_parent, EDJE_QUEUE_SCRIPT,
1548 EDJE_MESSAGE_SIGNAL, 0, &emsg);
1549}