1 #include "edje_private.h"
2 
3 static Eina_Bool _edje_var_timer_cb(void *data);
4 static Eina_Bool _edje_var_anim_cb(void *data);
5 
6 static Ecore_Animator *_edje_animator = NULL;
7 static Eina_List *_edje_anim_list = NULL;
8 
9 static Eina_Bool
_edje_var_timer_cb(void * data)10 _edje_var_timer_cb(void *data)
11 {
12    Edje_Var_Timer *et;
13    Edje *ed;
14    Embryo_Function fn;
15 
16    et = data;
17    if (!et) return ECORE_CALLBACK_CANCEL;
18    ed = et->edje;
19 //      _edje_embryo_script_reset(ed);
20    embryo_program_vm_push(ed->collection->script);
21    _edje_embryo_globals_init(ed);
22    embryo_parameter_cell_push(ed->collection->script, (Embryo_Cell)et->val);
23    ed->var_pool->timers = eina_inlist_remove(ed->var_pool->timers,
24                                              EINA_INLIST_GET(et));
25    fn = et->func;
26    free(et);
27    {
28       void *pdata;
29       int ret;
30 
31       pdata = embryo_program_data_get(ed->collection->script);
32       embryo_program_data_set(ed->collection->script, ed);
33       embryo_program_max_cycle_run_set(ed->collection->script, 5000000);
34       ret = embryo_program_run(ed->collection->script, fn);
35       if (ret == EMBRYO_PROGRAM_FAIL)
36         {
37            ERR("ERROR with embryo script (timer callback). "
38                "OBJECT NAME: '%s', "
39                "OBJECT FILE: '%s', "
40                "ERROR: '%s'",
41                ed->collection->part,
42                ed->file->path,
43                embryo_error_string_get(embryo_program_error_get(ed->collection->script)));
44         }
45       else if (ret == EMBRYO_PROGRAM_TOOLONG)
46         {
47            ERR("ERROR with embryo script (timer callback). "
48                "OBJECT NAME: '%s', "
49                "OBJECT FILE: '%s', "
50                "ERROR: 'Script exceeded maximum allowed cycle count of %i'",
51                ed->collection->part,
52                ed->file->path,
53                embryo_program_max_cycle_run_get(ed->collection->script));
54         }
55       embryo_program_data_set(ed->collection->script, pdata);
56       embryo_program_vm_pop(ed->collection->script);
57       _edje_recalc(ed);
58    }
59    return ECORE_CALLBACK_CANCEL;
60 }
61 
62 static Eina_Bool
_edje_var_anim_cb(void * data EINA_UNUSED)63 _edje_var_anim_cb(void *data EINA_UNUSED)
64 {
65    Eina_List *l, *tl = NULL;
66    double t;
67    const void *tmp;
68 
69    t = ecore_loop_time_get();
70    EINA_LIST_FOREACH(_edje_anim_list, l, tmp)
71      tl = eina_list_append(tl, tmp);
72    while (tl)
73      {
74         Edje *ed;
75         Eina_List *tl2;
76         Edje_Var_Animator *ea;
77 
78         ed = eina_list_data_get(tl);
79         _edje_ref(ed);
80         _edje_block(ed);
81         _edje_util_freeze(ed);
82         tl = eina_list_remove(tl, ed);
83         if (!ed->var_pool) continue;
84         tl2 = NULL;
85         EINA_LIST_FOREACH(ed->var_pool->animators, l, tmp)
86           tl2 = eina_list_append(tl2, tmp);
87         ed->var_pool->walking_list++;
88         while (tl2)
89           {
90              ea = eina_list_data_get(tl2);
91              if ((ed->var_pool) && (!ea->delete_me))
92                {
93                   if ((!ed->paused) && (!ed->delete_me))
94                     {
95                        Embryo_Function fn;
96                        float v;
97                        int ret;
98 
99                        v = (t - ea->start) / ea->len;
100                        if (v > 1.0) v = 1.0;
101 //		       _edje_embryo_script_reset(ed);
102                        embryo_program_vm_push(ed->collection->script);
103                        _edje_embryo_globals_init(ed);
104                        embryo_parameter_cell_push(ed->collection->script, (Embryo_Cell)ea->val);
105                        embryo_parameter_cell_push(ed->collection->script, EMBRYO_FLOAT_TO_CELL(v));
106                        fn = ea->func;
107                        {
108                           void *pdata;
109 
110                           pdata = embryo_program_data_get(ed->collection->script);
111                           embryo_program_data_set(ed->collection->script, ed);
112                           embryo_program_max_cycle_run_set(ed->collection->script, 5000000);
113                           ret = embryo_program_run(ed->collection->script, fn);
114                           if (ret == EMBRYO_PROGRAM_FAIL)
115                             {
116                                ERR("ERROR with embryo script (anim callback). "
117                                    "OBJECT NAME: '%s', "
118                                    "OBJECT FILE: '%s', "
119                                    "ERROR: '%s'",
120                                    ed->collection->part,
121                                    ed->file->path,
122                                    embryo_error_string_get(embryo_program_error_get(ed->collection->script)));
123                             }
124                           else if (ret == EMBRYO_PROGRAM_TOOLONG)
125                             {
126                                ERR("ERROR with embryo script (anim callback). "
127                                    "OBJECT NAME: '%s', "
128                                    "OBJECT FILE: '%s', "
129                                    "ERROR: 'Script exceeded maximum allowed cycle count of %i'",
130                                    ed->collection->part,
131                                    ed->file->path,
132                                    embryo_program_max_cycle_run_get(ed->collection->script));
133                             }
134                           embryo_program_data_set(ed->collection->script, pdata);
135                           embryo_program_vm_pop(ed->collection->script);
136                           _edje_recalc(ed);
137                        }
138                        if (EQ(v, FROM_INT(1))) ea->delete_me = 1;
139                     }
140                }
141              tl2 = eina_list_remove(tl2, ea);
142              if (ed->block_break)
143                {
144                   eina_list_free(tl2);
145                   break;
146                }
147           }
148         ed->var_pool->walking_list--;
149         EINA_LIST_FOREACH(ed->var_pool->animators, l, ea)
150           {
151              if (ea->delete_me)
152                {
153                   l = eina_list_next(l);
154                   ed->var_pool->animators = eina_list_remove(ed->var_pool->animators, ea);
155                   free(ea);
156                }
157              else
158                l = eina_list_next(l);
159           }
160         if (!ed->var_pool->animators)
161           _edje_anim_list = eina_list_remove(_edje_anim_list, ed);
162         _edje_unblock(ed);
163         _edje_util_thaw(ed);
164         _edje_unref(ed);
165      }
166    if (!_edje_anim_list)
167      {
168         if (_edje_animator)
169           {
170              ecore_animator_del(_edje_animator);
171              _edje_animator = NULL;
172           }
173      }
174    return !!_edje_animator;
175 }
176 
177 Edje_Var *
_edje_var_new(void)178 _edje_var_new(void)
179 {
180    return calloc(1, sizeof(Edje_Var));
181 }
182 
183 void
_edje_var_free(Edje_Var * var)184 _edje_var_free(Edje_Var *var)
185 {
186    if (var->type == EDJE_VAR_STRING)
187      {
188         if (var->data.s.v)
189           {
190              free(var->data.s.v);
191           }
192      }
193    free(var);
194 }
195 
196 void
_edje_var_init(Edje * ed)197 _edje_var_init(Edje *ed)
198 {
199    if (!ed) return;
200    if (!ed->collection) return;
201    if (!ed->collection->script) return;
202    if (ed->var_pool) return;
203    ed->var_pool = calloc(1, sizeof(Edje_Var_Pool));
204    if (!ed->var_pool) return;
205    embryo_program_vm_push(ed->collection->script);
206    ed->var_pool->size = embryo_program_variable_count_get(ed->collection->script);
207    embryo_program_vm_pop(ed->collection->script);
208    if (ed->var_pool->size > 0)
209      ed->var_pool->vars = calloc(1, sizeof(Edje_Var) * ed->var_pool->size);
210 }
211 
212 void
_edje_var_shutdown(Edje * ed)213 _edje_var_shutdown(Edje *ed)
214 {
215    Edje_Var_Timer *et;
216 
217    if (!ed->var_pool) return;
218    if (ed->var_pool->vars)
219      {
220         int i;
221 
222         for (i = 0; i < ed->var_pool->size; i++)
223           {
224              if (ed->var_pool->vars[i].type == EDJE_VAR_STRING)
225                {
226                   if (ed->var_pool->vars[i].data.s.v)
227                     {
228                        free(ed->var_pool->vars[i].data.s.v);
229                        ed->var_pool->vars[i].data.s.v = NULL;
230                     }
231                }
232              else if (ed->var_pool->vars[i].type == EDJE_VAR_LIST)
233                {
234                   while (ed->var_pool->vars[i].data.l.v)
235                     {
236                        _edje_var_free(eina_list_data_get(ed->var_pool->vars[i].data.l.v));
237                        ed->var_pool->vars[i].data.l.v = eina_list_remove_list(ed->var_pool->vars[i].data.l.v, ed->var_pool->vars[i].data.l.v);
238                     }
239                }
240           }
241         free(ed->var_pool->vars);
242      }
243    EINA_INLIST_FREE(ed->var_pool->timers, et)
244      {
245         ed->var_pool->timers = eina_inlist_remove(ed->var_pool->timers,
246                                                   EINA_INLIST_GET(et));
247         ecore_timer_del(et->timer);
248         free(et);
249      }
250    if (ed->var_pool->animators)
251      {
252         _edje_anim_list = eina_list_remove(_edje_anim_list, ed);
253         if (!_edje_anim_list)
254           {
255              if (_edje_animator)
256                {
257                   ecore_animator_del(_edje_animator);
258                   _edje_animator = NULL;
259                }
260           }
261      }
262    while (ed->var_pool->animators)
263      {
264         Edje_Var_Animator *ea;
265 
266         ea = eina_list_data_get(ed->var_pool->animators);
267         ed->var_pool->animators = eina_list_remove(ed->var_pool->animators, ea);
268         free(ea);
269      }
270    free(ed->var_pool);
271    ed->var_pool = NULL;
272 }
273 
274 int
_edje_var_string_id_get(Edje * ed,const char * string)275 _edje_var_string_id_get(Edje *ed, const char *string)
276 {
277    Embryo_Cell cell, *cptr;
278 
279    if (!ed) return 0;
280    if (!ed->collection) return 0;
281    if (!ed->collection->script) return 0;
282    if (!string) return 0;
283    cell = embryo_program_variable_find(ed->collection->script, (char *)string);
284    if (cell == EMBRYO_CELL_NONE) return 0;
285    cptr = embryo_data_address_get(ed->collection->script, cell);
286    if (!cptr) return 0;
287    return (int)(*cptr);
288 }
289 
290 int
_edje_var_var_int_get(Edje * ed EINA_UNUSED,Edje_Var * var)291 _edje_var_var_int_get(Edje *ed EINA_UNUSED, Edje_Var *var)
292 {
293    /* auto-cast */
294    if (var->type == EDJE_VAR_STRING)
295      {
296         if (var->data.s.v)
297           {
298              double f;
299 
300              f = atof(var->data.s.v);
301              free(var->data.s.v);
302              var->data.s.v = NULL;
303              var->data.i.v = (int)f;
304           }
305         var->type = EDJE_VAR_INT;
306      }
307    else if (var->type == EDJE_VAR_FLOAT)
308      {
309         int tmp = (int)(var->data.f.v);
310         var->data.i.v = tmp;
311         var->type = EDJE_VAR_INT;
312      }
313    else if (var->type == EDJE_VAR_NONE)
314      {
315         var->type = EDJE_VAR_INT;
316      }
317    else if (var->type == EDJE_VAR_LIST)
318      {
319         return 0;
320      }
321    else if (var->type == EDJE_VAR_HASH)
322      {
323         return 0;
324      }
325    return var->data.i.v;
326 }
327 
328 void
_edje_var_var_int_set(Edje * ed EINA_UNUSED,Edje_Var * var,int v)329 _edje_var_var_int_set(Edje *ed EINA_UNUSED, Edje_Var *var, int v)
330 {
331    /* auto-cast */
332    if (var->type == EDJE_VAR_STRING)
333      {
334         if (var->data.s.v)
335           {
336              free(var->data.s.v);
337              var->data.s.v = NULL;
338           }
339         var->type = EDJE_VAR_INT;
340      }
341    else if (var->type == EDJE_VAR_FLOAT)
342      {
343         var->type = EDJE_VAR_INT;
344      }
345    else if (var->type == EDJE_VAR_NONE)
346      {
347         var->type = EDJE_VAR_INT;
348      }
349    else if (var->type == EDJE_VAR_LIST)
350      {
351         return;
352      }
353    else if (var->type == EDJE_VAR_HASH)
354      {
355         return;
356      }
357    var->data.i.v = v;
358 }
359 
360 double
_edje_var_var_float_get(Edje * ed EINA_UNUSED,Edje_Var * var)361 _edje_var_var_float_get(Edje *ed EINA_UNUSED, Edje_Var *var)
362 {
363    /* auto-cast */
364    if (var->type == EDJE_VAR_STRING)
365      {
366         if (var->data.s.v)
367           {
368              double f;
369 
370              f = atof(var->data.s.v);
371              free(var->data.s.v);
372              var->data.s.v = NULL;
373              var->data.f.v = f;
374           }
375         var->type = EDJE_VAR_FLOAT;
376      }
377    else if (var->type == EDJE_VAR_INT)
378      {
379         double tmp = (double)(var->data.i.v);
380         var->data.f.v = tmp;
381         var->type = EDJE_VAR_FLOAT;
382      }
383    else if (var->type == EDJE_VAR_NONE)
384      {
385         var->type = EDJE_VAR_FLOAT;
386      }
387    else if (var->type == EDJE_VAR_LIST)
388      {
389         return 0.0;
390      }
391    else if (var->type == EDJE_VAR_HASH)
392      {
393         return 0.0;
394      }
395    return var->data.f.v;
396 }
397 
398 void
_edje_var_var_float_set(Edje * ed EINA_UNUSED,Edje_Var * var,double v)399 _edje_var_var_float_set(Edje *ed EINA_UNUSED, Edje_Var *var, double v)
400 {
401    /* auto-cast */
402    if (var->type == EDJE_VAR_STRING)
403      {
404         if (var->data.s.v)
405           {
406              free(var->data.s.v);
407              var->data.s.v = NULL;
408           }
409         var->type = EDJE_VAR_FLOAT;
410      }
411    else if (var->type == EDJE_VAR_INT)
412      {
413         var->data.f.v = 0;
414         var->type = EDJE_VAR_FLOAT;
415      }
416    else if (var->type == EDJE_VAR_NONE)
417      {
418         var->type = EDJE_VAR_FLOAT;
419      }
420    else if (var->type == EDJE_VAR_LIST)
421      {
422         return;
423      }
424    else if (var->type == EDJE_VAR_HASH)
425      {
426         return;
427      }
428    var->data.f.v = v;
429 }
430 
431 const char *
_edje_var_var_str_get(Edje * ed EINA_UNUSED,Edje_Var * var)432 _edje_var_var_str_get(Edje *ed EINA_UNUSED, Edje_Var *var)
433 {
434    /* auto-cast */
435    if (var->type == EDJE_VAR_INT)
436      {
437         char buf[64];
438 
439         snprintf(buf, sizeof(buf), "%i", var->data.i.v);
440         var->data.s.v = strdup(buf);
441         var->type = EDJE_VAR_STRING;
442      }
443    else if (var->type == EDJE_VAR_FLOAT)
444      {
445         char buf[64];
446 
447         snprintf(buf, sizeof(buf), "%f", var->data.f.v);
448         var->data.s.v = strdup(buf);
449         var->type = EDJE_VAR_STRING;
450      }
451    else if (var->type == EDJE_VAR_NONE)
452      {
453         var->data.s.v = strdup("");
454         var->type = EDJE_VAR_STRING;
455      }
456    else if (var->type == EDJE_VAR_LIST)
457      {
458         return NULL;
459      }
460    else if (var->type == EDJE_VAR_HASH)
461      {
462         return NULL;
463      }
464    return var->data.s.v;
465 }
466 
467 void
_edje_var_var_str_set(Edje * ed EINA_UNUSED,Edje_Var * var,const char * str)468 _edje_var_var_str_set(Edje *ed EINA_UNUSED, Edje_Var *var, const char *str)
469 {
470    /* auto-cast */
471    if (var->type == EDJE_VAR_STRING)
472      {
473         if (var->data.s.v)
474           {
475              free(var->data.s.v);
476              var->data.s.v = NULL;
477           }
478      }
479    else if (var->type == EDJE_VAR_INT)
480      {
481         var->type = EDJE_VAR_STRING;
482      }
483    else if (var->type == EDJE_VAR_FLOAT)
484      {
485         var->type = EDJE_VAR_STRING;
486      }
487    else if (var->type == EDJE_VAR_NONE)
488      {
489         var->type = EDJE_VAR_STRING;
490      }
491    else if (var->type == EDJE_VAR_LIST)
492      {
493         return;
494      }
495    else if (var->type == EDJE_VAR_HASH)
496      {
497         return;
498      }
499    var->data.s.v = strdup(str);
500 }
501 
502 int
_edje_var_int_get(Edje * ed,int id)503 _edje_var_int_get(Edje *ed, int id)
504 {
505    if (!ed) return 0;
506    if (!ed->var_pool) return 0;
507    id -= EDJE_VAR_MAGIC_BASE;
508    if ((id < 0) || (id >= ed->var_pool->size)) return 0;
509    return _edje_var_var_int_get(ed, &(ed->var_pool->vars[id]));
510 }
511 
512 void
_edje_var_int_set(Edje * ed,int id,int v)513 _edje_var_int_set(Edje *ed, int id, int v)
514 {
515    if (!ed) return;
516    if (!ed->var_pool) return;
517    id -= EDJE_VAR_MAGIC_BASE;
518    if ((id < 0) || (id >= ed->var_pool->size)) return;
519    _edje_var_var_int_set(ed, &(ed->var_pool->vars[id]), v);
520 }
521 
522 double
_edje_var_float_get(Edje * ed,int id)523 _edje_var_float_get(Edje *ed, int id)
524 {
525    if (!ed) return 0;
526    if (!ed->var_pool) return 0;
527    id -= EDJE_VAR_MAGIC_BASE;
528    if ((id < 0) || (id >= ed->var_pool->size)) return 0;
529    return _edje_var_var_float_get(ed, &(ed->var_pool->vars[id]));
530 }
531 
532 void
_edje_var_float_set(Edje * ed,int id,double v)533 _edje_var_float_set(Edje *ed, int id, double v)
534 {
535    if (!ed) return;
536    if (!ed->var_pool) return;
537    id -= EDJE_VAR_MAGIC_BASE;
538    if ((id < 0) || (id >= ed->var_pool->size)) return;
539    _edje_var_var_float_set(ed, &(ed->var_pool->vars[id]), v);
540 }
541 
542 const char *
_edje_var_str_get(Edje * ed,int id)543 _edje_var_str_get(Edje *ed, int id)
544 {
545    if (!ed) return NULL;
546    if (!ed->var_pool) return NULL;
547    id -= EDJE_VAR_MAGIC_BASE;
548    if ((id < 0) || (id >= ed->var_pool->size)) return NULL;
549    return _edje_var_var_str_get(ed, &(ed->var_pool->vars[id]));
550 }
551 
552 void
_edje_var_str_set(Edje * ed,int id,const char * str)553 _edje_var_str_set(Edje *ed, int id, const char *str)
554 {
555    if (!ed) return;
556    if (!ed->var_pool) return;
557    if (!str) return;
558    id -= EDJE_VAR_MAGIC_BASE;
559    if ((id < 0) || (id >= ed->var_pool->size)) return;
560    _edje_var_var_str_set(ed, &(ed->var_pool->vars[id]), str);
561 }
562 
563 /* list stuff */
564 
565 void
_edje_var_list_var_append(Edje * ed,int id,Edje_Var * var)566 _edje_var_list_var_append(Edje *ed, int id, Edje_Var *var)
567 {
568    if (!ed) return;
569    if (!ed->var_pool) return;
570    id -= EDJE_VAR_MAGIC_BASE;
571    if ((id < 0) || (id >= ed->var_pool->size)) return;
572    if (ed->var_pool->vars[id].type != EDJE_VAR_LIST) return;
573    ed->var_pool->vars[id].data.l.v = eina_list_append(ed->var_pool->vars[id].data.l.v, var);
574 }
575 
576 void
_edje_var_list_var_prepend(Edje * ed,int id,Edje_Var * var)577 _edje_var_list_var_prepend(Edje *ed, int id, Edje_Var *var)
578 {
579    if (!ed) return;
580    if (!ed->var_pool) return;
581    id -= EDJE_VAR_MAGIC_BASE;
582    if ((id < 0) || (id >= ed->var_pool->size)) return;
583    if (ed->var_pool->vars[id].type != EDJE_VAR_LIST) return;
584    ed->var_pool->vars[id].data.l.v = eina_list_prepend(ed->var_pool->vars[id].data.l.v, var);
585 }
586 
587 void
_edje_var_list_var_append_relative(Edje * ed,int id,Edje_Var * var,Edje_Var * relative)588 _edje_var_list_var_append_relative(Edje *ed, int id, Edje_Var *var, Edje_Var *relative)
589 {
590    if (!ed) return;
591    if (!ed->var_pool) return;
592    id -= EDJE_VAR_MAGIC_BASE;
593    if ((id < 0) || (id >= ed->var_pool->size)) return;
594    if (ed->var_pool->vars[id].type != EDJE_VAR_LIST) return;
595    ed->var_pool->vars[id].data.l.v = eina_list_append_relative(ed->var_pool->vars[id].data.l.v, var, relative);
596 }
597 
598 void
_edje_var_list_var_prepend_relative(Edje * ed,int id,Edje_Var * var,Edje_Var * relative)599 _edje_var_list_var_prepend_relative(Edje *ed, int id, Edje_Var *var, Edje_Var *relative)
600 {
601    if (!ed) return;
602    if (!ed->var_pool) return;
603    id -= EDJE_VAR_MAGIC_BASE;
604    if ((id < 0) || (id >= ed->var_pool->size)) return;
605    if (ed->var_pool->vars[id].type != EDJE_VAR_LIST) return;
606    ed->var_pool->vars[id].data.l.v = eina_list_prepend_relative(ed->var_pool->vars[id].data.l.v, var, relative);
607 }
608 
609 Edje_Var *
_edje_var_list_nth(Edje * ed,int id,int n)610 _edje_var_list_nth(Edje *ed, int id, int n)
611 {
612    if (!ed) return NULL;
613    if (!ed->var_pool) return NULL;
614    id -= EDJE_VAR_MAGIC_BASE;
615    if ((id < 0) || (id >= ed->var_pool->size)) return NULL;
616    if (ed->var_pool->vars[id].type != EDJE_VAR_LIST) return NULL;
617    return eina_list_nth(ed->var_pool->vars[id].data.l.v, n);
618 }
619 
620 int
_edje_var_list_count_get(Edje * ed,int id)621 _edje_var_list_count_get(Edje *ed, int id)
622 {
623    if (!ed) return 0;
624    if (!ed->var_pool) return 0;
625    id -= EDJE_VAR_MAGIC_BASE;
626    if ((id < 0) || (id >= ed->var_pool->size)) return 0;
627    if (ed->var_pool->vars[id].type == EDJE_VAR_NONE)
628      ed->var_pool->vars[id].type = EDJE_VAR_LIST;
629    else if (ed->var_pool->vars[id].type != EDJE_VAR_LIST)
630      return 0;
631    return eina_list_count(ed->var_pool->vars[id].data.l.v);
632 }
633 
634 void
_edje_var_list_remove_nth(Edje * ed,int id,int n)635 _edje_var_list_remove_nth(Edje *ed, int id, int n)
636 {
637    if (!ed) return;
638    if (!ed->var_pool) return;
639    id -= EDJE_VAR_MAGIC_BASE;
640    if ((id < 0) || (id >= ed->var_pool->size)) return;
641    if (ed->var_pool->vars[id].type == EDJE_VAR_NONE)
642      ed->var_pool->vars[id].type = EDJE_VAR_LIST;
643    else if (ed->var_pool->vars[id].type != EDJE_VAR_LIST)
644      return;
645    {
646       Eina_List *nth;
647 
648       nth = eina_list_nth_list(ed->var_pool->vars[id].data.l.v, n);
649       if (nth)
650         {
651            _edje_var_free(eina_list_data_get(nth));
652            ed->var_pool->vars[id].data.l.v = eina_list_remove_list(ed->var_pool->vars[id].data.l.v, nth);
653         }
654    }
655 }
656 
657 int
_edje_var_list_nth_int_get(Edje * ed,int id,int n)658 _edje_var_list_nth_int_get(Edje *ed, int id, int n)
659 {
660    if (!ed) return 0;
661    if (!ed->var_pool) return 0;
662    id -= EDJE_VAR_MAGIC_BASE;
663    if ((id < 0) || (id >= ed->var_pool->size)) return 0;
664    if (ed->var_pool->vars[id].type == EDJE_VAR_NONE)
665      ed->var_pool->vars[id].type = EDJE_VAR_LIST;
666    else if (ed->var_pool->vars[id].type != EDJE_VAR_LIST)
667      return 0;
668    {
669       Edje_Var *var;
670 
671       id += EDJE_VAR_MAGIC_BASE;
672       var = _edje_var_list_nth(ed, id, n);
673       if (!var) return 0;
674       return _edje_var_var_int_get(ed, var);
675    }
676 }
677 
678 void
_edje_var_list_nth_int_set(Edje * ed,int id,int n,int v)679 _edje_var_list_nth_int_set(Edje *ed, int id, int n, int v)
680 {
681    if (!ed) return;
682    if (!ed->var_pool) return;
683    id -= EDJE_VAR_MAGIC_BASE;
684    if ((id < 0) || (id >= ed->var_pool->size)) return;
685    if (ed->var_pool->vars[id].type == EDJE_VAR_NONE)
686      ed->var_pool->vars[id].type = EDJE_VAR_LIST;
687    else if (ed->var_pool->vars[id].type != EDJE_VAR_LIST)
688      return;
689    {
690       Edje_Var *var;
691 
692       id += EDJE_VAR_MAGIC_BASE;
693       var = _edje_var_list_nth(ed, id, n);
694       if (!var) return;
695       _edje_var_var_int_set(ed, var, v);
696    }
697 }
698 
699 void
_edje_var_list_int_append(Edje * ed,int id,int v)700 _edje_var_list_int_append(Edje *ed, int id, int v)
701 {
702    if (!ed) return;
703    if (!ed->var_pool) return;
704    id -= EDJE_VAR_MAGIC_BASE;
705    if ((id < 0) || (id >= ed->var_pool->size)) return;
706    if (ed->var_pool->vars[id].type == EDJE_VAR_NONE)
707      ed->var_pool->vars[id].type = EDJE_VAR_LIST;
708    else if (ed->var_pool->vars[id].type != EDJE_VAR_LIST)
709      return;
710    {
711       Edje_Var *var;
712 
713       var = _edje_var_new();
714       if (!var) return;
715       id += EDJE_VAR_MAGIC_BASE;
716       _edje_var_var_int_set(ed, var, v);
717       _edje_var_list_var_append(ed, id, var);
718    }
719 }
720 
721 void
_edje_var_list_int_prepend(Edje * ed,int id,int v)722 _edje_var_list_int_prepend(Edje *ed, int id, int v)
723 {
724    if (!ed) return;
725    if (!ed->var_pool) return;
726    id -= EDJE_VAR_MAGIC_BASE;
727    if ((id < 0) || (id >= ed->var_pool->size)) return;
728    if (ed->var_pool->vars[id].type == EDJE_VAR_NONE)
729      ed->var_pool->vars[id].type = EDJE_VAR_LIST;
730    else if (ed->var_pool->vars[id].type != EDJE_VAR_LIST)
731      return;
732    {
733       Edje_Var *var;
734 
735       var = _edje_var_new();
736       if (!var) return;
737       id += EDJE_VAR_MAGIC_BASE;
738       _edje_var_var_int_set(ed, var, v);
739       _edje_var_list_var_prepend(ed, id, var);
740    }
741 }
742 
743 void
_edje_var_list_int_insert(Edje * ed,int id,int n,int v)744 _edje_var_list_int_insert(Edje *ed, int id, int n, int v)
745 {
746    if (!ed) return;
747    if (!ed->var_pool) return;
748    id -= EDJE_VAR_MAGIC_BASE;
749    if ((id < 0) || (id >= ed->var_pool->size)) return;
750    if (ed->var_pool->vars[id].type == EDJE_VAR_NONE)
751      ed->var_pool->vars[id].type = EDJE_VAR_LIST;
752    else if (ed->var_pool->vars[id].type != EDJE_VAR_LIST)
753      return;
754    {
755       Edje_Var *var, *var_rel;
756 
757       var = _edje_var_new();
758       if (!var) return;
759       id += EDJE_VAR_MAGIC_BASE;
760       _edje_var_var_int_set(ed, var, v);
761       var_rel = _edje_var_list_nth(ed, id, n);
762       if (!var_rel)
763         _edje_var_list_var_append(ed, id, var);
764       else
765         _edje_var_list_var_prepend_relative(ed, id, var, var_rel);
766    }
767 }
768 
769 double
_edje_var_list_nth_float_get(Edje * ed,int id,int n)770 _edje_var_list_nth_float_get(Edje *ed, int id, int n)
771 {
772    if (!ed) return 0;
773    if (!ed->var_pool) return 0;
774    id -= EDJE_VAR_MAGIC_BASE;
775    if ((id < 0) || (id >= ed->var_pool->size)) return 0;
776    if (ed->var_pool->vars[id].type == EDJE_VAR_NONE)
777      ed->var_pool->vars[id].type = EDJE_VAR_LIST;
778    else if (ed->var_pool->vars[id].type != EDJE_VAR_LIST)
779      return 0;
780    {
781       Edje_Var *var;
782 
783       id += EDJE_VAR_MAGIC_BASE;
784       var = _edje_var_list_nth(ed, id, n);
785       if (!var) return 0;
786       return _edje_var_var_float_get(ed, var);
787    }
788 }
789 
790 void
_edje_var_list_nth_float_set(Edje * ed,int id,int n,double v)791 _edje_var_list_nth_float_set(Edje *ed, int id, int n, double v)
792 {
793    if (!ed) return;
794    if (!ed->var_pool) return;
795    id -= EDJE_VAR_MAGIC_BASE;
796    if ((id < 0) || (id >= ed->var_pool->size)) return;
797    if (ed->var_pool->vars[id].type == EDJE_VAR_NONE)
798      ed->var_pool->vars[id].type = EDJE_VAR_LIST;
799    else if (ed->var_pool->vars[id].type != EDJE_VAR_LIST)
800      return;
801    {
802       Edje_Var *var;
803 
804       id += EDJE_VAR_MAGIC_BASE;
805       var = _edje_var_list_nth(ed, id, n);
806       if (!var) return;
807       _edje_var_var_float_set(ed, var, v);
808    }
809 }
810 
811 void
_edje_var_list_float_append(Edje * ed,int id,double v)812 _edje_var_list_float_append(Edje *ed, int id, double v)
813 {
814    if (!ed) return;
815    if (!ed->var_pool) return;
816    id -= EDJE_VAR_MAGIC_BASE;
817    if ((id < 0) || (id >= ed->var_pool->size)) return;
818    if (ed->var_pool->vars[id].type == EDJE_VAR_NONE)
819      ed->var_pool->vars[id].type = EDJE_VAR_LIST;
820    else if (ed->var_pool->vars[id].type != EDJE_VAR_LIST)
821      return;
822    {
823       Edje_Var *var;
824 
825       var = _edje_var_new();
826       if (!var) return;
827       id += EDJE_VAR_MAGIC_BASE;
828       _edje_var_var_float_set(ed, var, v);
829       _edje_var_list_var_append(ed, id, var);
830    }
831 }
832 
833 void
_edje_var_list_float_prepend(Edje * ed,int id,double v)834 _edje_var_list_float_prepend(Edje *ed, int id, double v)
835 {
836    if (!ed) return;
837    if (!ed->var_pool) return;
838    id -= EDJE_VAR_MAGIC_BASE;
839    if ((id < 0) || (id >= ed->var_pool->size)) return;
840    if (ed->var_pool->vars[id].type == EDJE_VAR_NONE)
841      ed->var_pool->vars[id].type = EDJE_VAR_LIST;
842    else if (ed->var_pool->vars[id].type != EDJE_VAR_LIST)
843      return;
844    {
845       Edje_Var *var;
846 
847       var = _edje_var_new();
848       if (!var) return;
849       id += EDJE_VAR_MAGIC_BASE;
850       _edje_var_var_float_set(ed, var, v);
851       _edje_var_list_var_prepend(ed, id, var);
852    }
853 }
854 
855 void
_edje_var_list_float_insert(Edje * ed,int id,int n,double v)856 _edje_var_list_float_insert(Edje *ed, int id, int n, double v)
857 {
858    if (!ed) return;
859    if (!ed->var_pool) return;
860    id -= EDJE_VAR_MAGIC_BASE;
861    if ((id < 0) || (id >= ed->var_pool->size)) return;
862    if (ed->var_pool->vars[id].type == EDJE_VAR_NONE)
863      ed->var_pool->vars[id].type = EDJE_VAR_LIST;
864    else if (ed->var_pool->vars[id].type != EDJE_VAR_LIST)
865      return;
866    {
867       Edje_Var *var, *var_rel;
868 
869       var = _edje_var_new();
870       if (!var) return;
871       id += EDJE_VAR_MAGIC_BASE;
872       _edje_var_var_float_set(ed, var, v);
873       var_rel = _edje_var_list_nth(ed, id, n);
874       if (!var_rel)
875         _edje_var_list_var_append(ed, id, var);
876       else
877         _edje_var_list_var_prepend_relative(ed, id, var, var_rel);
878    }
879 }
880 
881 const char *
_edje_var_list_nth_str_get(Edje * ed,int id,int n)882 _edje_var_list_nth_str_get(Edje *ed, int id, int n)
883 {
884    if (!ed) return NULL;
885    if (!ed->var_pool) return NULL;
886    id -= EDJE_VAR_MAGIC_BASE;
887    if ((id < 0) || (id >= ed->var_pool->size)) return NULL;
888    if (ed->var_pool->vars[id].type == EDJE_VAR_NONE)
889      ed->var_pool->vars[id].type = EDJE_VAR_LIST;
890    else if (ed->var_pool->vars[id].type != EDJE_VAR_LIST)
891      return NULL;
892    {
893       Edje_Var *var;
894 
895       id += EDJE_VAR_MAGIC_BASE;
896       var = _edje_var_list_nth(ed, id, n);
897       if (!var) return NULL;
898       return _edje_var_var_str_get(ed, var);
899    }
900 }
901 
902 void
_edje_var_list_nth_str_set(Edje * ed,int id,int n,const char * v)903 _edje_var_list_nth_str_set(Edje *ed, int id, int n, const char *v)
904 {
905    if (!ed) return;
906    if (!ed->var_pool) return;
907    id -= EDJE_VAR_MAGIC_BASE;
908    if ((id < 0) || (id >= ed->var_pool->size)) return;
909    if (ed->var_pool->vars[id].type == EDJE_VAR_NONE)
910      ed->var_pool->vars[id].type = EDJE_VAR_LIST;
911    else if (ed->var_pool->vars[id].type != EDJE_VAR_LIST)
912      return;
913    {
914       Edje_Var *var;
915 
916       id += EDJE_VAR_MAGIC_BASE;
917       var = _edje_var_list_nth(ed, id, n);
918       if (!var) return;
919       _edje_var_var_str_set(ed, var, v);
920    }
921 }
922 
923 void
_edje_var_list_str_append(Edje * ed,int id,const char * v)924 _edje_var_list_str_append(Edje *ed, int id, const char *v)
925 {
926    if (!ed) return;
927    if (!ed->var_pool) return;
928    id -= EDJE_VAR_MAGIC_BASE;
929    if ((id < 0) || (id >= ed->var_pool->size)) return;
930    if (ed->var_pool->vars[id].type == EDJE_VAR_NONE)
931      ed->var_pool->vars[id].type = EDJE_VAR_LIST;
932    else if (ed->var_pool->vars[id].type != EDJE_VAR_LIST)
933      return;
934    {
935       Edje_Var *var;
936 
937       var = _edje_var_new();
938       if (!var) return;
939       id += EDJE_VAR_MAGIC_BASE;
940       _edje_var_var_str_set(ed, var, v);
941       _edje_var_list_var_append(ed, id, var);
942    }
943 }
944 
945 void
_edje_var_list_str_prepend(Edje * ed,int id,const char * v)946 _edje_var_list_str_prepend(Edje *ed, int id, const char *v)
947 {
948    if (!ed) return;
949    if (!ed->var_pool) return;
950    id -= EDJE_VAR_MAGIC_BASE;
951    if ((id < 0) || (id >= ed->var_pool->size)) return;
952    if (ed->var_pool->vars[id].type == EDJE_VAR_NONE)
953      ed->var_pool->vars[id].type = EDJE_VAR_LIST;
954    else if (ed->var_pool->vars[id].type != EDJE_VAR_LIST)
955      return;
956    {
957       Edje_Var *var;
958 
959       var = _edje_var_new();
960       if (!var) return;
961       id += EDJE_VAR_MAGIC_BASE;
962       _edje_var_var_str_set(ed, var, v);
963       _edje_var_list_var_prepend(ed, id, var);
964    }
965 }
966 
967 void
_edje_var_list_str_insert(Edje * ed,int id,int n,const char * v)968 _edje_var_list_str_insert(Edje *ed, int id, int n, const char *v)
969 {
970    if (!ed) return;
971    if (!ed->var_pool) return;
972    id -= EDJE_VAR_MAGIC_BASE;
973    if ((id < 0) || (id >= ed->var_pool->size)) return;
974    if (ed->var_pool->vars[id].type == EDJE_VAR_NONE)
975      ed->var_pool->vars[id].type = EDJE_VAR_LIST;
976    else if (ed->var_pool->vars[id].type != EDJE_VAR_LIST)
977      return;
978    {
979       Edje_Var *var, *var_rel;
980 
981       var = _edje_var_new();
982       if (!var) return;
983       id += EDJE_VAR_MAGIC_BASE;
984       _edje_var_var_str_set(ed, var, v);
985       var_rel = _edje_var_list_nth(ed, id, n);
986       if (!var_rel)
987         _edje_var_list_var_append(ed, id, var);
988       else
989         _edje_var_list_var_prepend_relative(ed, id, var, var_rel);
990    }
991 }
992 
993 int
_edje_var_timer_add(Edje * ed,double in,const char * fname,int val)994 _edje_var_timer_add(Edje *ed, double in, const char *fname, int val)
995 {
996    Edje_Var_Timer *et;
997    Embryo_Function fn;
998 
999    if (!ed->var_pool) return 0;
1000    fn = embryo_program_function_find(ed->collection->script, (char *)fname);
1001    if (fn == EMBRYO_FUNCTION_NONE) return 0;
1002    et = calloc(1, sizeof(Edje_Var_Timer));
1003    if (!et) return 0;
1004    et->id = ++ed->var_pool->id_count;
1005    et->edje = ed;
1006    et->func = fn;
1007    et->val = val;
1008    et->timer = ecore_timer_add(in, _edje_var_timer_cb, et);
1009    if (!et->timer)
1010      {
1011         free(et);
1012         return 0;
1013      }
1014    ed->var_pool->timers = eina_inlist_prepend(ed->var_pool->timers,
1015                                               EINA_INLIST_GET(et));
1016    return et->id;
1017 }
1018 
1019 static Edje_Var_Timer *
_edje_var_timer_find(Edje * ed,int id)1020 _edje_var_timer_find(Edje *ed, int id)
1021 {
1022    Edje_Var_Timer *et;
1023 
1024    if (!ed->var_pool) return NULL;
1025 
1026    EINA_INLIST_FOREACH(ed->var_pool->timers, et)
1027      if (et->id == id) return et;
1028 
1029    return NULL;
1030 }
1031 
1032 void
_edje_var_timer_del(Edje * ed,int id)1033 _edje_var_timer_del(Edje *ed, int id)
1034 {
1035    Edje_Var_Timer *et;
1036 
1037    et = _edje_var_timer_find(ed, id);
1038    if (!et) return;
1039 
1040    ed->var_pool->timers = eina_inlist_remove(ed->var_pool->timers,
1041                                               EINA_INLIST_GET(et));
1042    ecore_timer_del(et->timer);
1043    free(et);
1044 }
1045 
1046 void
_edje_var_timer_reset(Edje * ed,int id)1047 _edje_var_timer_reset(Edje *ed, int id)
1048 {
1049    Edje_Var_Timer *et;
1050 
1051    et = _edje_var_timer_find(ed, id);
1052    if (et)
1053      ecore_timer_reset(et->timer);
1054 }
1055 
1056 int
_edje_var_anim_add(Edje * ed,double len,const char * fname,int val)1057 _edje_var_anim_add(Edje *ed, double len, const char *fname, int val)
1058 {
1059    Edje_Var_Animator *ea;
1060    Embryo_Function fn;
1061 
1062    if (!ed->var_pool) return 0;
1063    if (len <= 0.0) return 0;
1064    fn = embryo_program_function_find(ed->collection->script, (char *)fname);
1065    if (fn == EMBRYO_FUNCTION_NONE) return 0;
1066    ea = calloc(1, sizeof(Edje_Var_Animator));
1067    if (!ea) return 0;
1068    ea->start = ecore_loop_time_get();
1069    ea->len = len;
1070    ea->id = ++ed->var_pool->id_count;
1071    ea->edje = ed;
1072    ea->func = fn;
1073    ea->val = val;
1074    if (!ed->var_pool->animators)
1075      _edje_anim_list = eina_list_append(_edje_anim_list, ed);
1076    ed->var_pool->animators = eina_list_prepend(ed->var_pool->animators, ea);
1077    if (!_edje_animator)
1078      _edje_animator = ecore_animator_add(_edje_var_anim_cb, NULL);
1079    return ea->id;
1080 }
1081 
1082 static Edje_Var_Animator *
_edje_var_anim_find(Edje * ed,int id)1083 _edje_var_anim_find(Edje *ed, int id)
1084 {
1085    Eina_List *l;
1086    Edje_Var_Animator *ea;
1087 
1088    if (!ed->var_pool) return NULL;
1089 
1090    EINA_LIST_FOREACH(ed->var_pool->animators, l, ea)
1091      if (ea->id == id) return ea;
1092 
1093    return NULL;
1094 }
1095 
1096 void
_edje_var_anim_del(Edje * ed,int id)1097 _edje_var_anim_del(Edje *ed, int id)
1098 {
1099    Edje_Var_Animator *ea;
1100 
1101    ea = _edje_var_anim_find(ed, id);
1102    if (!ea) return;
1103 
1104    if (ed->var_pool->walking_list)
1105      {
1106         ea->delete_me = 1;
1107         return;
1108      }
1109 
1110    ed->var_pool->animators = eina_list_remove(ed->var_pool->animators, ea);
1111    free(ea);
1112 
1113    if (ed->var_pool->animators) return;
1114 
1115    _edje_anim_list = eina_list_remove(_edje_anim_list, ed);
1116    if (!_edje_anim_list)
1117      {
1118         if (_edje_animator)
1119           {
1120              ecore_animator_del(_edje_animator);
1121              _edje_animator = NULL;
1122           }
1123      }
1124 }
1125 
1126