ffcbc64bccddff4d662526b87d6c404ac72c8244
[platform/upstream/edje.git] / src / lib / edje_embryo.c
1 #include "edje_private.h"
2
3 /*
4  * ALREADY EXPORTED BY EMBRYO:
5  *
6  * enum Float_Round_Method {
7  *    ROUND, FLOOR, CEIL, TOZERO
8  * };
9  * enum Float_Angle_Mode {
10  *    RADIAN, DEGREES, GRADES
11  * };
12  *
13  * numargs();
14  * getarg(arg, index=0);
15  * setarg(arg, index=0, value);
16  *
17  * Float:atof(string[]);
18  * Float:fract(Float:value);
19  *       round(Float:value, Float_Round_Method:method=ROUND);
20  * Float:sqrt(Float:value);
21  * Float:pow(Float:value, Float:exponent);
22  * Float:log(Float:value, Float:base=10.0);
23  * Float:sin(Float:value, Float_Angle_Mode:mode=RADIAN);
24  * Float:cos(Float:value, Float_Angle_Mode:mode=RADIAN);
25  * Float:tan(Float:value, Float_Angle_Mode:mode=RADIAN);
26  * Float:abs(Float:value);
27  *       atoi(str[]);
28  *       fnmatch(glob[], str[]);
29  *       strcmp(str1[], str2[]);
30  *       strncmp(str1[], str2[]);
31  *       strcpy(dst[], src[]);
32  *       strncpy(dst[], src[], n);
33  *       strlen(str[]);
34  *       strcat(dst[], src[]);
35  *       strncat(dst[], src[], n);
36  *       strprep(dst[], src[]);
37  *       strnprep(dst[], src[], n);
38  *       strcut(dst[], str[], n, n2);
39  *       snprintf(dst[], dstn, fmt[], ...);
40  *       strstr(str[], ndl[]);
41  *       strchr(str[], ch[]);
42  *       strrchr(str[], ch[]);
43  *       rand();
44  * Float:randf();
45  * Float:seconds();
46  *       date(&year, &month, &day, &yearday, &weekday, &hr, &min, &Float:sec);
47  *
48  */
49
50 /* EDJE...
51  *
52  * implemented so far as examples:
53  *
54  * enum Msg_Type {
55  *    MSG_NONE, MSG_STRING, MSG_INT, MSG_FLOAT, MSG_STRING_SET, MSG_INT_SET,
56  *    MSG_FLOAT_SET, MSG_STRING_INT, MSG_INT_FLOAT, MSG_STRING_INT_SET,
57  *    MSG_INT_FLOAT_SET
58  * };
59  *
60  * get_int(id)
61  * set_int(id, v)
62  * Float:get_float (id)
63  * set_float(id, Float:v)
64  * get_strlen(id)
65  * get_str(id, dst[], maxlen)
66  * set_str(id, str[])
67  * timer(Float:in, fname[], val)
68  * cancel_timer(id)
69  * anim(Float:len, fname[], val)
70  * cancel_anim(id)
71  * emit(sig[], src[])
72  * set_state(part_id, state[], Float:state_val)
73  * get_state(part_id, dst[], maxlen, &Float:val)
74  * set_tween_state(part_id, Float:tween, state1[], Float:state1_val, state2[], Float:state2_val)
75  * play_sample(sample_name, speed)
76  * play_tone(tone_name, duration)
77  * run_program(program_id)
78  * Direction:get_drag_dir(part_id)
79  * get_drag(part_id, &Float:dx, &Float:&dy)
80  * set_drag(part_id, Float:dx, Float:dy)
81  * get_drag_size(part_id, &Float:dx, &Float:&dy)
82  * set_drag_size(part_id, Float:dx, Float:dy)
83  * set_text(part_id, str[])
84  * get_text(part_id, dst[], maxlen)
85  * get_min_size(w, h)
86  * get_max_size(w, h)
87  * set_color_class(class[], r, g, b, a)
88  * get_color_class(class[], &r, &g, &b, &a)
89  * set_text_class(class[], font[], Float:size)
90  * get_text_class(class[], font[], &Float:size)
91  * get_drag_step(part_id, &Float:dx, &Float:&dy)
92  * set_drag_step(part_id, Float:dx, Float:dy)
93  * get_drag_page(part_id, &Float:dx, &Float:&dy)
94  * set_drag_page(part_id, Float:dx, Float:dy)
95  * get_geometry(part_id, &Float:x, &Float:y, &Float:w, &Float:h)
96  * get_mouse(&x, &y)
97  * stop_program(program_id)
98  * stop_programs_on(part_id)
99  * set_min_size(w, h)
100  * set_max_size(w, h)
101  * send_message(Msg_Type:type, id, ...)
102  *
103  * count(id)
104  * remove(id, n)
105  *
106  * append_int(id, v)
107  * prepend_int(id, v)
108  * insert_int(id, n, v)
109  * replace_int(id, n, v)
110  * fetch_int(id, n)
111  *
112  * append_str(id, str[])
113  * prepend_str(id, str[])
114  * insert_str(id, n, str[])
115  * replace_str(id, n, str[])
116  * fetch_str(id, n, dst[], maxlen)
117  *
118  * append_float(id, Float:v)
119  * prepend_float(id, Float:v)
120  * insert_float(id, n, Float:v)
121  * replace_float(id, n, Float:v)
122  * Float:fetch_float(id, n)
123  *
124  * custom_state(part_id, state[], Float:state_val = 0.0)
125  * set_state_val(part_id, State_Param:param, ...)
126  * get_state_val(part_id, State_Param:param, ...)
127  *
128  * Supported parameters:
129  * align[Float:x, Float:y]
130  * min[w, h]
131  * max[w, h]
132  * step[x,y]
133  * aspect[Float:min, Float:max]
134  * color[r,g,b,a]
135  * color2[r,g,b,a]
136  * color3[r,g,b,a]
137  * aspect_preference
138  * rel1[relx,rely]
139  * rel1[part_id,part_id]
140  * rel1[offx,offy]
141  * rel2[relx,relyr]
142  * rel2[part_id,part_id]
143  * rel2[offx,offy]
144  * image[image_id] <- all images have an Id not name in the edje
145  * border[l,r,t,b]
146  * fill[smooth]
147  * fill[pos_relx,pos_rely,pos_offx,pos_offy]
148  * fill[sz_relx,sz_rely,sz_offx,sz_offy]
149  * color_class
150  * text[text]
151  * text[text_class]
152  * text[font]
153  * text[size]
154  * text[style]
155  * text[fit_x,fit_y]
156  * text[min_x,min_y]
157  * text[align_x,align_y]
158  * visible[on]
159  * map_on[on]
160  * map_persp[part_id]
161  * map_light[part_id]
162  * map_rot_center[part_id]
163  * map_rot_x[deg]
164  * map_rot_y[deg]
165  * map_rot_z[deg]
166  * map_back_cull[on]
167  * map_persp_on[on]
168  * persp_zplane[z]
169  * persp_focal[z]
170  *
171  * ** part_id and program_id need to be able to be "found" from strings
172  *
173  * get_drag_count(part_id, &Float:dx, &Float:&dy)
174  * set_drag_count(part_id, Float:dx, Float:dy)
175  * set_drag_confine(part_id, confine_part_id)
176  * get_size(&w, &h);
177  * resize_request(w, h)
178  * get_mouse_buttons()
179  * //set_type(part_id, Type:type)
180  * //set_effect(part_id, Effect:fx)
181  * set_mouse_events(part_id, ev)
182  * get_mouse_events(part_id)
183  * set_repeat_events(part_id, rep)
184  * get_repeat_events(part_id)
185  * set_clip(part_id, clip_part_id)
186  * get_clip(part_id)
187  *
188  * part_swallow(part_id, group_name)
189  *
190  * external_param_get_int(id, param_name[])
191  * external_param_set_int(id, param_name[], value)
192  * Float:external_param_get_float(id, param_name[])
193  * external_param_set_float(id, param_name[], Float:value)
194  * external_param_get_strlen(id, param_name[])
195  * external_param_get_str(id, param_name[], value[], value_maxlen)
196  * external_param_set_str(id, param_name[], value[])
197  * external_param_get_choice_len(id, param_name[])
198  * external_param_get_choice(id, param_name[], value[], value_maxlen)
199  * external_param_set_choice(id, param_name[], value[])
200  * external_param_get_bool(id, param_name[])
201  * external_param_set_bool(id, param_name[], value)
202  *
203  * ADD/DEL CUSTOM OBJECTS UNDER SOLE EMBRYO SCRIPT CONTROL
204  *
205  */
206
207 /* get_int(id) */
208 static Embryo_Cell
209 _edje_embryo_fn_get_int(Embryo_Program *ep, Embryo_Cell *params)
210 {
211    Edje *ed;
212
213    CHKPARAM(1);
214    ed = embryo_program_data_get(ep);
215    return (Embryo_Cell)_edje_var_int_get(ed, (int)params[1]);
216 }
217
218 /* set_int(id, v) */
219 static Embryo_Cell
220 _edje_embryo_fn_set_int(Embryo_Program *ep, Embryo_Cell *params)
221 {
222    Edje *ed;
223
224    CHKPARAM(2);
225    ed = embryo_program_data_get(ep);
226    _edje_var_int_set(ed, (int)params[1], (int)params[2]);
227    return 0;
228 }
229
230 /* get_float(id) */
231 static Embryo_Cell
232 _edje_embryo_fn_get_float(Embryo_Program *ep, Embryo_Cell *params)
233 {
234    Edje *ed;
235    float v;
236
237    CHKPARAM(1);
238    ed = embryo_program_data_get(ep);
239    v = (float)_edje_var_float_get(ed, params[1]);
240    return EMBRYO_FLOAT_TO_CELL(v);
241 }
242
243 /* set_float(id, v) */
244 static Embryo_Cell
245 _edje_embryo_fn_set_float(Embryo_Program *ep, Embryo_Cell *params)
246 {
247    Edje *ed;
248    float v;
249
250    CHKPARAM(2);
251    ed = embryo_program_data_get(ep);
252    v = EMBRYO_CELL_TO_FLOAT(params[2]);
253    _edje_var_float_set(ed, (int)params[1], (double)v);
254    return 0;
255 }
256
257 /* get_str(id, dst[], maxlen) */
258 static Embryo_Cell
259 _edje_embryo_fn_get_str(Embryo_Program *ep, Embryo_Cell *params)
260 {
261    Edje *ed;
262    char *s;
263
264    CHKPARAM(3);
265    if (params[3] < 1) return 0;
266    ed = embryo_program_data_get(ep);
267    s = (char *)_edje_var_str_get(ed, (int)params[1]);
268    if (s)
269      {
270         if ((int) strlen(s) < params[3])
271           {
272              SETSTR(s, params[2]);
273           }
274         else
275           {
276              char *ss;
277
278              ss = alloca(strlen(s) + 1);
279              strcpy(ss, s);
280              ss[params[3] - 1] = 0;
281              SETSTR(ss, params[2]);
282           }
283      }
284    else
285      {
286         SETSTR("", params[2]);
287      }
288    return 0;
289 }
290
291 /* get_strlen(id) */
292 static Embryo_Cell
293 _edje_embryo_fn_get_strlen(Embryo_Program *ep, Embryo_Cell *params)
294 {
295    Edje *ed;
296    char *s;
297
298    CHKPARAM(1);
299    ed = embryo_program_data_get(ep);
300    s = (char *)_edje_var_str_get(ed, (int)params[1]);
301    if (s)
302      {
303         return strlen(s);
304      }
305    return 0;
306 }
307
308 /* set_str(id, str[]) */
309 static Embryo_Cell
310 _edje_embryo_fn_set_str(Embryo_Program *ep, Embryo_Cell *params)
311 {
312    Edje *ed;
313    char *s;
314
315    CHKPARAM(2);
316    ed = embryo_program_data_get(ep);
317    GETSTR(s, params[2]);
318    if (s)
319      {
320         _edje_var_str_set(ed, (int)params[1], s);
321      }
322    return 0;
323 }
324
325 /* count(id) */
326 static Embryo_Cell
327 _edje_embryo_fn_count(Embryo_Program *ep, Embryo_Cell *params)
328 {
329    Edje *ed = embryo_program_data_get(ep);
330
331    CHKPARAM(1);
332
333    return (Embryo_Cell)_edje_var_list_count_get(ed, (int) params[1]);
334 }
335
336 /* remove(id, n) */
337 static Embryo_Cell
338 _edje_embryo_fn_remove(Embryo_Program *ep, Embryo_Cell *params)
339 {
340    Edje *ed = embryo_program_data_get(ep);
341
342    CHKPARAM(2);
343
344    _edje_var_list_remove_nth(ed, (int) params[1], (int) params[2]);
345
346    return 0;
347 }
348
349 /* append_int(id, var) */
350 static Embryo_Cell
351 _edje_embryo_fn_append_int(Embryo_Program *ep, Embryo_Cell *params)
352 {
353    Edje *ed = embryo_program_data_get(ep);
354
355    CHKPARAM(2);
356
357    _edje_var_list_int_append(ed, (int) params[1], (int) params[2]);
358
359    return 0;
360 }
361
362 /* prepend_int(id, var) */
363 static Embryo_Cell
364 _edje_embryo_fn_prepend_int(Embryo_Program *ep, Embryo_Cell *params)
365 {
366    Edje *ed = embryo_program_data_get(ep);
367
368    CHKPARAM(2);
369
370    _edje_var_list_int_prepend(ed, (int) params[1], (int) params[2]);
371
372    return 0;
373 }
374
375 /* insert_int(id, pos, var) */
376 static Embryo_Cell
377 _edje_embryo_fn_insert_int(Embryo_Program *ep, Embryo_Cell *params)
378 {
379    Edje *ed = embryo_program_data_get(ep);
380
381    CHKPARAM(3);
382
383    _edje_var_list_int_insert(ed, (int) params[1], (int) params[2],
384                              (int) params[3]);
385
386    return 0;
387 }
388
389 /* replace_int(id, pos, var) */
390 static Embryo_Cell
391 _edje_embryo_fn_replace_int(Embryo_Program *ep, Embryo_Cell *params)
392 {
393    Edje *ed = embryo_program_data_get(ep);
394
395    CHKPARAM(3);
396
397    _edje_var_list_nth_int_set(ed, (int) params[1], (int) params[2],
398                               (int) params[3]);
399
400    return 0;
401 }
402
403 /* fetch_int(id, pos) */
404 static Embryo_Cell
405 _edje_embryo_fn_fetch_int(Embryo_Program *ep, Embryo_Cell *params)
406 {
407    Edje *ed = embryo_program_data_get(ep);
408
409    CHKPARAM(2);
410
411    return _edje_var_list_nth_int_get(ed, (int) params[1],
412                                      (int) params[2]);
413 }
414
415 /* append_str(id, str[]) */
416 static Embryo_Cell
417 _edje_embryo_fn_append_str(Embryo_Program *ep, Embryo_Cell *params)
418 {
419    Edje *ed = embryo_program_data_get(ep);
420    char *s;
421
422    CHKPARAM(2);
423
424    GETSTR(s, params[2]);
425    if (s)
426      _edje_var_list_str_append(ed, (int) params[1], s);
427
428    return 0;
429 }
430
431 /* prepend_str(id, str[]) */
432 static Embryo_Cell
433 _edje_embryo_fn_prepend_str(Embryo_Program *ep, Embryo_Cell *params)
434 {
435    Edje *ed = embryo_program_data_get(ep);
436    char *s;
437
438    CHKPARAM(2);
439
440    GETSTR(s, params[2]);
441    if (s)
442      _edje_var_list_str_prepend(ed, (int) params[1], s);
443
444    return 0;
445 }
446
447 /* insert_str(id, pos, str[]) */
448 static Embryo_Cell
449 _edje_embryo_fn_insert_str(Embryo_Program *ep, Embryo_Cell *params)
450 {
451    Edje *ed = embryo_program_data_get(ep);
452    char *s;
453
454    CHKPARAM(3);
455
456    GETSTR(s, params[3]);
457    if (s)
458      _edje_var_list_str_insert(ed, (int) params[1], (int) params[2], s);
459
460    return 0;
461 }
462
463 /* replace_str(id, pos, str[]) */
464 static Embryo_Cell
465 _edje_embryo_fn_replace_str(Embryo_Program *ep, Embryo_Cell *params)
466 {
467    Edje *ed = embryo_program_data_get(ep);
468    char *s;
469
470    CHKPARAM(3);
471
472    GETSTR(s, params[3]);
473    if (s)
474         _edje_var_list_nth_str_set(ed, (int) params[1], (int) params[2], s);
475
476    return 0;
477 }
478
479
480 /* fetch_str(id, pos, dst[], maxlen) */
481 static Embryo_Cell
482 _edje_embryo_fn_fetch_str(Embryo_Program *ep, Embryo_Cell *params)
483 {
484    Edje *ed = embryo_program_data_get(ep);
485    char *s;
486
487    CHKPARAM(4);
488
489    s = (char *) _edje_var_list_nth_str_get(ed, (int) params[1],
490                                            (int) params[2]);
491    if (s)
492      {
493         if ((int) strlen(s) < params[4])
494           {
495              SETSTR(s, params[3]);
496           }
497         else
498           {
499              char *ss;
500
501              ss = alloca(strlen(s) + 1);
502              strcpy(ss, s);
503              ss[params[4] - 1] = 0;
504              SETSTR(ss, params[3]);
505           }
506      }
507    else
508      {
509         SETSTR("", params[3]);
510      }
511
512    return 0;
513 }
514
515 /* append_float(id, Float:f) */
516 static Embryo_Cell
517 _edje_embryo_fn_append_float(Embryo_Program *ep, Embryo_Cell *params)
518 {
519    Edje *ed = embryo_program_data_get(ep);
520    float f;
521
522    CHKPARAM(2);
523
524    f = EMBRYO_CELL_TO_FLOAT(params[2]);
525    _edje_var_list_float_append(ed, (int) params[1], f);
526
527    return 0;
528 }
529
530 /* prepend_float(id, Float:f) */
531 static Embryo_Cell
532 _edje_embryo_fn_prepend_float(Embryo_Program *ep, Embryo_Cell *params)
533 {
534    Edje *ed = embryo_program_data_get(ep);
535    float f;
536
537    CHKPARAM(2);
538
539    f = EMBRYO_CELL_TO_FLOAT(params[2]);
540    _edje_var_list_float_prepend(ed, (int) params[1], f);
541
542    return 0;
543 }
544
545 /* insert_float(id, pos, Float:f) */
546 static Embryo_Cell
547 _edje_embryo_fn_insert_float(Embryo_Program *ep, Embryo_Cell *params)
548 {
549    Edje *ed = embryo_program_data_get(ep);
550    float f;
551
552    CHKPARAM(3);
553
554    f = EMBRYO_CELL_TO_FLOAT(params[3]);
555    _edje_var_list_float_insert(ed, (int) params[1], (int) params[2], f);
556
557    return 0;
558 }
559
560 /* replace_float(id, pos, Float:f) */
561 static Embryo_Cell
562 _edje_embryo_fn_replace_float(Embryo_Program *ep, Embryo_Cell *params)
563 {
564    Edje *ed = embryo_program_data_get(ep);
565
566    CHKPARAM(3);
567
568    _edje_var_list_nth_float_set(ed, (int) params[1], (int) params[2],
569                                 EMBRYO_CELL_TO_FLOAT(params[3]));
570
571    return 0;
572 }
573
574 /* Float:fetch_float(id, pos) */
575 static Embryo_Cell
576 _edje_embryo_fn_fetch_float(Embryo_Program *ep, Embryo_Cell *params)
577 {
578    Edje *ed = embryo_program_data_get(ep);
579    float f;
580
581    CHKPARAM(2);
582
583    f = _edje_var_list_nth_float_get(ed, (int) params[1], (int) params[2]);
584
585    return EMBRYO_FLOAT_TO_CELL(f);
586 }
587
588 /* timer(Float:in, fname[], val) */
589 static Embryo_Cell
590 _edje_embryo_fn_timer(Embryo_Program *ep, Embryo_Cell *params)
591 {
592    Edje *ed;
593    char *fname = NULL;
594    float f;
595    double in;
596    int val;
597
598    CHKPARAM(3);
599    ed = embryo_program_data_get(ep);
600    GETSTR(fname, params[2]);
601    if ((!fname)) return 0;
602    f = EMBRYO_CELL_TO_FLOAT(params[1]);
603    in = (double)f;
604    val = params[3];
605    return _edje_var_timer_add(ed, in, fname, val);
606 }
607
608 /* cancel_timer(id) */
609 static Embryo_Cell
610 _edje_embryo_fn_cancel_timer(Embryo_Program *ep, Embryo_Cell *params)
611 {
612    Edje *ed;
613    int id;
614
615    CHKPARAM(1);
616    ed = embryo_program_data_get(ep);
617    id = params[1];
618    if (id <= 0) return 0;
619    _edje_var_timer_del(ed, id);
620    return 0;
621 }
622
623 /* anim(Float:len, fname[], val) */
624 static Embryo_Cell
625 _edje_embryo_fn_anim(Embryo_Program *ep, Embryo_Cell *params)
626 {
627    Edje *ed;
628    char *fname = NULL;
629    float f;
630    double len;
631    int val;
632
633    CHKPARAM(3);
634    ed = embryo_program_data_get(ep);
635    GETSTR(fname, params[2]);
636    if ((!fname)) return 0;
637    f = EMBRYO_CELL_TO_FLOAT(params[1]);
638    len = (double)f;
639    val = params[3];
640    return _edje_var_anim_add(ed, len, fname, val);
641 }
642
643 /* cancel_anim(id) */
644 static Embryo_Cell
645 _edje_embryo_fn_cancel_anim(Embryo_Program *ep, Embryo_Cell *params)
646 {
647    Edje *ed;
648    int id;
649
650    CHKPARAM(1);
651    ed = embryo_program_data_get(ep);
652    id = params[1];
653    if (id <= 0) return 0;
654    _edje_var_anim_del(ed, id);
655    return 0;
656 }
657
658 /* set_min_size(Float:w, Float:h) */
659 static Embryo_Cell
660 _edje_embryo_fn_set_min_size(Embryo_Program *ep, Embryo_Cell *params)
661 {
662     Edje *ed;
663    float f = 0.0;
664    double w = 0.0, h = 0.0;
665
666    CHKPARAM(2);
667    ed = embryo_program_data_get(ep);
668    f = EMBRYO_CELL_TO_FLOAT(params[1]);
669    w = (double)f;
670    f = EMBRYO_CELL_TO_FLOAT(params[2]);
671    h = (double)f;
672
673    if (w < 0.0) w = 0.0;
674    if (h < 0.0) h = 0.0;
675    ed->collection->prop.min.w = w;
676    ed->collection->prop.min.h = h;
677    ed->recalc_call = 1;
678    ed->dirty = 1;
679 #ifdef EDJE_CALC_CACHE
680    ed->all_part_change = 1;
681 #endif
682    _edje_recalc(ed);
683    return 0;
684 }
685
686 /* set_max_size(Float:w, Float:h) */
687 static Embryo_Cell
688 _edje_embryo_fn_set_max_size(Embryo_Program *ep, Embryo_Cell *params)
689 {
690    Edje *ed;
691    float f = 0.0;
692    double w = 0.0, h = 0.0;
693
694    CHKPARAM(2);
695    ed = embryo_program_data_get(ep);
696    f = EMBRYO_CELL_TO_FLOAT(params[1]);
697    w = (double)f;
698    f = EMBRYO_CELL_TO_FLOAT(params[2]);
699    h = (double)f;
700
701    if (w < 0.0) w = 0.0;
702    if (h < 0.0) h = 0.0;
703    ed->collection->prop.max.w = w;
704    ed->collection->prop.max.h = h;
705    ed->recalc_call = 1;
706    ed->dirty = 1;
707 #ifdef EDJE_CALC_CACHE
708    ed->all_part_change = 1;
709 #endif
710    _edje_recalc(ed);
711
712    return 0;
713 }
714
715 /* stop_program(program_id) */
716 static Embryo_Cell
717 _edje_embryo_fn_stop_program(Embryo_Program *ep, Embryo_Cell *params)
718 {
719    Edje *ed;
720    int program_id = 0;
721    Edje_Running_Program *runp;
722    Eina_List *l;
723
724    CHKPARAM(1);
725    ed = embryo_program_data_get(ep);
726    program_id = params[1];
727    if (program_id < 0) return 0;
728
729    ed->walking_actions = 1;
730
731    EINA_LIST_FOREACH(ed->actions, l, runp)
732      if (program_id == runp->program->id)
733        _edje_program_end(ed, runp);
734
735    ed->walking_actions = 0;
736
737    return 0;
738 }
739
740 /* stop_programs_on(part_id) */
741 static Embryo_Cell
742 _edje_embryo_fn_stop_programs_on(Embryo_Program *ep, Embryo_Cell *params)
743 {
744    Edje *ed;
745
746    int part_id = 0;
747    Edje_Real_Part *rp;
748
749    CHKPARAM(1);
750    ed = embryo_program_data_get(ep);
751    part_id = params[1];
752    if (part_id < 0) return 0;
753    rp = ed->table_parts[part_id % ed->table_parts_size];
754    if (rp)
755      {
756         /* there is only ever 1 program acting on a part at any time */
757         if (rp->program) _edje_program_end(ed, rp->program);
758      }
759    return 0;
760 }
761
762 /* get_mouse(&x, &y) */
763 static Embryo_Cell
764 _edje_embryo_fn_get_mouse(Embryo_Program *ep, Embryo_Cell *params)
765 {
766    Edje *ed;
767    Evas_Coord x = 0, y = 0;
768
769    CHKPARAM(2);
770    ed = embryo_program_data_get(ep);
771    evas_pointer_canvas_xy_get(ed->base.evas, &x, &y);
772    x -= ed->x;
773    y -= ed->y;
774    SETINT((int)x, params[1]);
775    SETINT((int)y, params[2]);
776    return 0;
777 }
778
779 /* get_mouse_buttons() */
780 static Embryo_Cell
781 _edje_embryo_fn_get_mouse_buttons(Embryo_Program *ep, Embryo_Cell *params)
782 {
783    Edje *ed;
784
785    CHKPARAM(0);
786    ed = embryo_program_data_get(ep);
787    return evas_pointer_button_down_mask_get(ed->base.evas);
788 }
789
790 /* emit(sig[], src[]) */
791 static Embryo_Cell
792 _edje_embryo_fn_emit(Embryo_Program *ep, Embryo_Cell *params)
793 {
794    Edje *ed;
795    char *sig = NULL, *src = NULL;
796
797    CHKPARAM(2);
798    ed = embryo_program_data_get(ep);
799    GETSTR(sig, params[1]);
800    GETSTR(src, params[2]);
801    if ((!sig) || (!src)) return 0;
802    _edje_emit(ed, sig, src);
803    return 0;
804 }
805
806 /* get_part_id(part[]) */
807 static Embryo_Cell
808 _edje_embryo_fn_get_part_id(Embryo_Program *ep, Embryo_Cell *params)
809 {
810    Edje *ed;
811    Edje_Part_Collection *col;
812    Edje_Part **part;
813    char *p;
814    unsigned int i;
815
816    CHKPARAM(1);
817    ed = embryo_program_data_get(ep);
818    GETSTR(p, params[1]);
819    if (!p) return -1;
820    col = ed->collection;
821    if (!col) return -1;
822    part = col->parts;
823    for (i = 0; i < col->parts_count; i++, part++)
824      {
825         if (!(*part)->name) continue;
826         if (!strcmp((*part)->name, p)) return (*part)->id;
827      }
828    return -1;
829 }
830
831 static Embryo_Cell
832 _edje_embryo_fn_play_sample(Embryo_Program *ep, Embryo_Cell *params)
833 {
834    Edje *ed;
835    char *sample_name = NULL;
836    float speed = 1.0;
837
838    CHKPARAM(1);
839    ed = embryo_program_data_get(ep);
840    GETSTR(sample_name, params[1]);
841    if ((!sample_name)) return 0;
842    speed = EMBRYO_CELL_TO_FLOAT(params[2]);
843    _edje_multisense_internal_sound_sample_play(ed, sample_name, (double)speed);
844    return 0;
845 }
846
847 static Embryo_Cell
848 _edje_embryo_fn_play_tone(Embryo_Program *ep, Embryo_Cell *params)
849 {
850    Edje *ed;
851    char *tone_name = NULL;
852    float duration = 0.1;
853
854    CHKPARAM(2);
855    ed = embryo_program_data_get(ep);
856    GETSTR(tone_name, params[1]);
857    if ((!tone_name)) return 0;
858    duration = EMBRYO_CELL_TO_FLOAT(params[2]);
859    _edje_multisense_internal_sound_tone_play(ed, tone_name, (double) duration);
860    return 0;
861 }
862
863 /* set_state(part_id, state[], Float:state_val) */
864 static Embryo_Cell
865 _edje_embryo_fn_set_state(Embryo_Program *ep, Embryo_Cell *params)
866 {
867    Edje *ed;
868    char *state = NULL;
869    int part_id = 0;
870    float f = 0.0;
871    double value = 0.0;
872    Edje_Real_Part *rp;
873
874    if (!(HASNPARAMS(2) || HASNPARAMS(3))) return -1;
875
876    ed = embryo_program_data_get(ep);
877    GETSTR(state, params[2]);
878    if ((!state)) return 0;
879    part_id = params[1];
880    if (part_id < 0) return 0;
881    if (HASNPARAMS(3))
882      {
883         f = EMBRYO_CELL_TO_FLOAT(params[3]);
884         value = (double)f;
885      }
886    else
887      value = 0.0;
888    rp = ed->table_parts[part_id % ed->table_parts_size];
889    if (rp)
890      {
891         if (rp->program) _edje_program_end(ed, rp->program);
892         _edje_part_description_apply(ed, rp, state, value, NULL, 0.0);
893         _edje_part_pos_set(ed, rp, EDJE_TWEEN_MODE_LINEAR, ZERO, ZERO, ZERO);
894         _edje_recalc(ed);
895      }
896    return 0;
897 }
898
899 /* get_state(part_id, dst[], maxlen, &Float:val) */
900 static Embryo_Cell
901 _edje_embryo_fn_get_state(Embryo_Program *ep, Embryo_Cell *params)
902 {
903    Edje *ed;
904    int part_id = 0;
905    Edje_Real_Part *rp;
906    const char *s;
907
908    CHKPARAM(4);
909    ed = embryo_program_data_get(ep);
910    part_id = params[1];
911    if (part_id < 0) return 0;
912    rp = ed->table_parts[part_id % ed->table_parts_size];
913    if (rp->chosen_description)
914      {
915         SETFLOAT(rp->chosen_description->state.value, params[4]);
916         s = rp->chosen_description->state.name;
917         if (s)
918           {
919              if ((int) strlen(s) < params[3])
920                {
921                   SETSTR(s, params[2]);
922                }
923              else
924                {
925                   char *ss;
926
927                   ss = alloca(strlen(s) + 1);
928                   strcpy(ss, s);
929                   ss[params[3] - 1] = 0;
930                   SETSTR(ss, params[2]);
931                }
932           }
933         else
934           {
935              SETSTR("", params[2]);
936           }
937      }
938    else
939      {
940         SETFLOAT(0.0, params[4]);
941         SETSTR("", params[2]);
942      }
943    return 0;
944 }
945
946 /* set_tween_state(part_id, Float:tween, state1[], Float:state1_val, state2[], Float:state2_val) */
947 static Embryo_Cell
948 _edje_embryo_fn_set_tween_state(Embryo_Program *ep, Embryo_Cell *params)
949 {
950    Edje *ed;
951    char *state1 = NULL, *state2 = NULL;
952    int part_id = 0;
953    float f = 0.0;
954    double tween = 0.0, value1 = 0.0, value2 = 0.0;
955    Edje_Real_Part *rp;
956
957    CHKPARAM(6);
958    ed = embryo_program_data_get(ep);
959    GETSTR(state1, params[3]);
960    GETSTR(state2, params[5]);
961    if ((!state1) || (!state2)) return 0;
962    part_id = params[1];
963    if (part_id < 0) return 0;
964    f = EMBRYO_CELL_TO_FLOAT(params[2]);
965    tween = (double)f;
966    f = EMBRYO_CELL_TO_FLOAT(params[4]);
967    value1 = (double)f;
968    f = EMBRYO_CELL_TO_FLOAT(params[6]);
969    value2 = (double)f;
970    rp = ed->table_parts[part_id % ed->table_parts_size];
971    if (rp)
972      {
973         if (rp->program) _edje_program_end(ed, rp->program);
974         _edje_part_description_apply(ed, rp, state1, value1, state2, value2);
975         _edje_part_pos_set(ed, rp, EDJE_TWEEN_MODE_LINEAR, FROM_DOUBLE(tween), ZERO, ZERO);
976         _edje_recalc(ed);
977      }
978    return 0;
979 }
980
981 /* run_program(program_id) */
982 static Embryo_Cell
983 _edje_embryo_fn_run_program(Embryo_Program *ep, Embryo_Cell *params)
984 {
985    Edje *ed;
986    int program_id = 0;
987    Edje_Program *pr;
988
989    CHKPARAM(1);
990    ed = embryo_program_data_get(ep);
991    program_id = params[1];
992    if (program_id < 0) return 0;
993    pr = ed->table_programs[program_id % ed->table_programs_size];
994    if (pr)
995      {
996         _edje_program_run(ed, pr, 0, "", "");
997      }
998    return 0;
999 }
1000
1001 /* get_drag_dir(part_id) */
1002 static Embryo_Cell
1003 _edje_embryo_fn_get_drag_dir(Embryo_Program *ep, Embryo_Cell *params)
1004 {
1005    Edje *ed;
1006    int part_id = 0;
1007    Edje_Real_Part *rp;
1008
1009    CHKPARAM(1);
1010    ed = embryo_program_data_get(ep);
1011    part_id = params[1];
1012    if (part_id < 0) return 0;
1013    rp = ed->table_parts[part_id % ed->table_parts_size];
1014    return edje_object_part_drag_dir_get(ed->obj, rp->part->name);
1015 }
1016
1017 /* get_drag(part_id, &Float:dx, &Float:dy) */
1018 static Embryo_Cell
1019 _edje_embryo_fn_get_drag(Embryo_Program *ep, Embryo_Cell *params)
1020 {
1021    Edje *ed;
1022    int part_id = 0;
1023    Edje_Real_Part *rp;
1024    double dx = 0.0, dy = 0.0;
1025
1026    CHKPARAM(3);
1027    ed = embryo_program_data_get(ep);
1028    part_id = params[1];
1029    if (part_id < 0) return 0;
1030    rp = ed->table_parts[part_id % ed->table_parts_size];
1031    edje_object_part_drag_value_get(ed->obj, rp->part->name, &dx, &dy);
1032    SETFLOAT(dx, params[2]);
1033    SETFLOAT(dy, params[3]);
1034
1035    return 0;
1036 }
1037
1038 /* set_drag(part_id, Float:dx, Float:dy) */
1039 static Embryo_Cell
1040 _edje_embryo_fn_set_drag(Embryo_Program *ep, Embryo_Cell *params)
1041 {
1042    Edje *ed;
1043    int part_id = 0;
1044    Edje_Real_Part *rp;
1045
1046    CHKPARAM(3);
1047    ed = embryo_program_data_get(ep);
1048    part_id = params[1];
1049    if (part_id < 0) return 0;
1050    rp = ed->table_parts[part_id % ed->table_parts_size];
1051    edje_object_part_drag_value_set(ed->obj, rp->part->name,
1052                                    (double)EMBRYO_CELL_TO_FLOAT(params[2]),
1053                                    (double)EMBRYO_CELL_TO_FLOAT(params[3]));
1054    return(0);
1055 }
1056
1057 /* get_drag_size(part_id, &Float:dx, &Float:dy) */
1058 static Embryo_Cell
1059 _edje_embryo_fn_get_drag_size(Embryo_Program *ep, Embryo_Cell *params)
1060 {
1061    Edje *ed;
1062    int part_id = 0;
1063    Edje_Real_Part *rp;
1064    double dx = 0.0, dy = 0.0;
1065
1066    CHKPARAM(3);
1067    ed = embryo_program_data_get(ep);
1068    part_id = params[1];
1069    if (part_id < 0) return 0;
1070    rp = ed->table_parts[part_id % ed->table_parts_size];
1071    edje_object_part_drag_size_get(ed->obj, rp->part->name, &dx, &dy);
1072    SETFLOAT(dx, params[2]);
1073    SETFLOAT(dy, params[3]);
1074
1075    return 0;
1076 }
1077
1078 /* set_drag_size(part_id, Float:dx, Float:dy) */
1079 static Embryo_Cell
1080 _edje_embryo_fn_set_drag_size(Embryo_Program *ep, Embryo_Cell *params)
1081 {
1082    Edje *ed;
1083    int part_id = 0;
1084    Edje_Real_Part *rp;
1085
1086    CHKPARAM(3);
1087    ed = embryo_program_data_get(ep);
1088    part_id = params[1];
1089    if (part_id < 0) return 0;
1090    rp = ed->table_parts[part_id % ed->table_parts_size];
1091    edje_object_part_drag_size_set(ed->obj, rp->part->name,
1092                                    (double)EMBRYO_CELL_TO_FLOAT(params[2]),
1093                                    (double)EMBRYO_CELL_TO_FLOAT(params[3]));
1094    return(0);
1095 }
1096
1097 /* set_text(part_id, str[]) */
1098 static Embryo_Cell
1099 _edje_embryo_fn_set_text(Embryo_Program *ep, Embryo_Cell *params)
1100 {
1101    Edje *ed;
1102    int part_id = 0;
1103    Edje_Real_Part *rp;
1104    char *s;
1105
1106    CHKPARAM(2);
1107    ed = embryo_program_data_get(ep);
1108    part_id = params[1];
1109    if (part_id < 0) return 0;
1110    rp = ed->table_parts[part_id % ed->table_parts_size];
1111    GETSTR(s, params[2]);
1112    if (s){
1113      edje_object_part_text_set(ed->obj, rp->part->name, s);
1114    }
1115    return(0);
1116 }
1117
1118 /* get_text(part_id, dst[], maxlen) */
1119 static Embryo_Cell
1120 _edje_embryo_fn_get_text(Embryo_Program *ep, Embryo_Cell *params)
1121 {
1122    Edje *ed;
1123    int part_id = 0;
1124    Edje_Real_Part *rp;
1125    char *s;
1126
1127    CHKPARAM(3);
1128    ed = embryo_program_data_get(ep);
1129    part_id = params[1];
1130    if (part_id < 0) return 0;
1131    rp = ed->table_parts[part_id % ed->table_parts_size];
1132    s = (char *)edje_object_part_text_get(ed->obj, rp->part->name);
1133    if (s)
1134      {
1135         if ((int) strlen(s) < params[3])
1136           {
1137              SETSTR(s, params[2]);
1138           }
1139         else
1140           {
1141              char *ss;
1142
1143              ss = alloca(strlen(s) + 1);
1144              strcpy(ss, s);
1145              ss[params[3] - 1] = 0;
1146              SETSTR(ss, params[2]);
1147           }
1148      }
1149    else
1150      {
1151         SETSTR("", params[2]);
1152      }
1153    return 0;
1154 }
1155
1156 /* get_min_size(&w, &h) */
1157 static Embryo_Cell
1158 _edje_embryo_fn_get_min_size(Embryo_Program *ep, Embryo_Cell *params)
1159 {
1160    Edje *ed;
1161    Evas_Coord w = 0, h = 0;
1162
1163    CHKPARAM(2);
1164    ed = embryo_program_data_get(ep);
1165    edje_object_size_min_get(ed->obj, &w, &h);
1166    SETINT(w, params[1]);
1167    SETINT(h, params[2]);
1168    return 0;
1169 }
1170
1171 /* get_max_size(&w, &h) */
1172 static Embryo_Cell
1173 _edje_embryo_fn_get_max_size(Embryo_Program *ep, Embryo_Cell *params)
1174 {
1175    Edje *ed;
1176    Evas_Coord w = 0, h = 0;
1177
1178    CHKPARAM(2);
1179    ed = embryo_program_data_get(ep);
1180    edje_object_size_max_get(ed->obj, &w, &h);
1181    SETINT(w, params[1]);
1182    SETINT(h, params[2]);
1183    return 0;
1184
1185 }
1186
1187 /* get_color_class(class[], &r, &g, &b, &a) */
1188 static Embryo_Cell
1189 _edje_embryo_fn_get_color_class(Embryo_Program *ep, Embryo_Cell *params)
1190 {
1191    Edje *ed;
1192    Edje_Color_Class *c_class;
1193    char *class;
1194
1195    CHKPARAM(5);
1196    ed = embryo_program_data_get(ep);
1197    GETSTR(class, params[1]);
1198    if (!class) return 0;
1199    c_class = _edje_color_class_find(ed, class);
1200    if (!c_class) return 0;
1201    SETINT(c_class->r, params[2]);
1202    SETINT(c_class->g, params[3]);
1203    SETINT(c_class->b, params[4]);
1204    SETINT(c_class->a, params[5]);
1205    return 0;
1206 }
1207
1208 /* set_color_class(class[], r, g, b, a) */
1209 static Embryo_Cell
1210 _edje_embryo_fn_set_color_class(Embryo_Program *ep, Embryo_Cell *params)
1211 {
1212    Edje *ed;
1213    char *class;
1214
1215    CHKPARAM(5);
1216    ed = embryo_program_data_get(ep);
1217    GETSTR(class, params[1]);
1218    if (!class) return 0;
1219    edje_object_color_class_set(ed->obj, class, params[2], params[3], params[4], params[5],
1220                                params[2], params[3], params[4], params[5],
1221                                params[2], params[3], params[4], params[5]);
1222    return 0;
1223 }
1224
1225 /* set_text_class(class[], font[], Float:size) */
1226 static Embryo_Cell
1227 _edje_embryo_fn_set_text_class(Embryo_Program *ep, Embryo_Cell *params)
1228 {
1229    Edje *ed;
1230    char *class, *font;
1231    Evas_Font_Size fsize;
1232
1233    CHKPARAM(3);
1234    ed = embryo_program_data_get(ep);
1235    GETSTR(class, params[1]);
1236    GETSTR(font, params[2]);
1237    if( !class || !font ) return 0;
1238    fsize = (Evas_Font_Size) EMBRYO_CELL_TO_FLOAT(params[3]);
1239    edje_object_text_class_set(ed->obj, class, font, fsize);
1240    return 0;
1241 }
1242
1243 /* get_text_class(class[], font[], &Float:size) */
1244 static Embryo_Cell
1245 _edje_embryo_fn_get_text_class(Embryo_Program *ep, Embryo_Cell *params)
1246 {
1247    Edje *ed;
1248    char *class;
1249    Edje_Text_Class *t_class;
1250
1251    CHKPARAM(3);
1252    ed = embryo_program_data_get(ep);
1253    GETSTR(class, params[1]);
1254    if (!class) return 0;
1255    t_class = _edje_text_class_find(ed, class);
1256    if (!t_class) return 0;
1257    SETSTR((char *)t_class->font, params[2]);
1258    SETFLOAT(t_class->size, params[3]);
1259    return 0;
1260 }
1261
1262 /* get_drag_step(part_id, &Float:dx, &Float:&dy) */
1263 static Embryo_Cell
1264 _edje_embryo_fn_get_drag_step(Embryo_Program *ep, Embryo_Cell *params)
1265 {
1266    Edje *ed;
1267    int part_id = 0;
1268    Edje_Real_Part *rp;
1269    double dx = 0.0, dy = 0.0;
1270
1271    CHKPARAM(3);
1272    ed = embryo_program_data_get(ep);
1273    part_id = params[1];
1274    if (part_id < 0) return 0;
1275    rp = ed->table_parts[part_id % ed->table_parts_size];
1276    edje_object_part_drag_step_get(ed->obj, rp->part->name, &dx, &dy);
1277    SETFLOAT(dx, params[2]);
1278    SETFLOAT(dy, params[3]);
1279
1280    return 0;
1281 }
1282
1283 /* set_drag_step(part_id, Float:dx, Float:dy) */
1284 static Embryo_Cell
1285 _edje_embryo_fn_set_drag_step(Embryo_Program *ep, Embryo_Cell *params)
1286 {
1287    Edje *ed;
1288    int part_id = 0;
1289    Edje_Real_Part *rp;
1290
1291    CHKPARAM(3);
1292    ed = embryo_program_data_get(ep);
1293    part_id = params[1];
1294    if (part_id < 0) return 0;
1295    rp = ed->table_parts[part_id % ed->table_parts_size];
1296    edje_object_part_drag_step_set(ed->obj, rp->part->name,
1297                                   (double)EMBRYO_CELL_TO_FLOAT(params[2]),
1298                                   (double)EMBRYO_CELL_TO_FLOAT(params[3]));
1299    return(0);
1300 }
1301
1302 /* get_drag_page(part_id, &Float:dx, &Float:&dy) */
1303 static Embryo_Cell
1304 _edje_embryo_fn_get_drag_page(Embryo_Program *ep, Embryo_Cell *params)
1305 {
1306    Edje *ed;
1307    int part_id = 0;
1308    Edje_Real_Part *rp;
1309    double dx = 0.0, dy = 0.0;
1310
1311    CHKPARAM(3);
1312    ed = embryo_program_data_get(ep);
1313    part_id = params[1];
1314    if (part_id < 0) return 0;
1315    rp = ed->table_parts[part_id % ed->table_parts_size];
1316    edje_object_part_drag_page_get(ed->obj, rp->part->name, &dx, &dy);
1317    SETFLOAT(dx, params[2]);
1318    SETFLOAT(dy, params[3]);
1319
1320    return 0;
1321 }
1322
1323 /* get_geometry(pard_id, &x, &y, &w, &h) */
1324 static Embryo_Cell
1325 _edje_embryo_fn_get_geometry(Embryo_Program *ep, Embryo_Cell *params)
1326 {
1327    Edje *ed;
1328    int part_id = 0;
1329    Edje_Real_Part *rp;
1330    Evas_Coord x = 0.0, y = 0.0, w = 0.0, h = 0.0;
1331
1332    CHKPARAM(5);
1333    ed = embryo_program_data_get(ep);
1334    part_id = params[1];
1335    if (part_id < 0) return 0;
1336    rp = ed->table_parts[part_id % ed->table_parts_size];
1337    edje_object_part_geometry_get(ed->obj, rp->part->name, &x, &y, &w, &h);
1338    SETINT(x, params[2]);
1339    SETINT(y, params[3]);
1340    SETINT(w, params[4]);
1341    SETINT(h, params[5]);
1342
1343    return 0;
1344 }
1345
1346 /* set_drag_page(part_id, Float:dx, Float:dy) */
1347 static Embryo_Cell
1348 _edje_embryo_fn_set_drag_page(Embryo_Program *ep, Embryo_Cell *params)
1349 {
1350    Edje *ed;
1351    int part_id = 0;
1352    Edje_Real_Part *rp;
1353
1354    CHKPARAM(3);
1355    ed = embryo_program_data_get(ep);
1356    part_id = params[1];
1357    if (part_id < 0) return 0;
1358    rp = ed->table_parts[part_id % ed->table_parts_size];
1359    edje_object_part_drag_page_set(ed->obj, rp->part->name,
1360                                   (double)EMBRYO_CELL_TO_FLOAT(params[2]),
1361                                   (double)EMBRYO_CELL_TO_FLOAT(params[3]));
1362    return(0);
1363 }
1364
1365 /* send_message(Msg_Type:type, id,...); */
1366 static Embryo_Cell
1367 _edje_embryo_fn_send_message(Embryo_Program *ep, Embryo_Cell *params)
1368 {
1369    Edje *ed;
1370    Edje_Message_Type type;
1371    int id, i, n;
1372    Embryo_Cell *ptr;
1373
1374    if (params[0] < (int) (sizeof(Embryo_Cell) * (2))) return 0;
1375    ed = embryo_program_data_get(ep);
1376    type = params[1];
1377    id = params[2];
1378    switch (type)
1379      {
1380       case EDJE_MESSAGE_NONE:
1381         _edje_message_send(ed, EDJE_QUEUE_APP, type, id, NULL);
1382         break;
1383       case EDJE_MESSAGE_SIGNAL:
1384         break;
1385       case EDJE_MESSAGE_STRING:
1386           {
1387              Embryo_Cell *cptr;
1388
1389              cptr = embryo_data_address_get(ep, params[3]);
1390              if (cptr)
1391                {
1392                   Edje_Message_String *emsg;
1393                   int l;
1394                   char *s;
1395
1396                   l = embryo_data_string_length_get(ep, cptr);
1397                   s = alloca(l + 1);
1398                   s[0] = 0;
1399                   embryo_data_string_get(ep, cptr, s);
1400                   emsg = alloca(sizeof(Edje_Message_String));
1401                   emsg->str = s;
1402                   _edje_message_send(ed, EDJE_QUEUE_APP, type, id, emsg);
1403                }
1404           }
1405         break;
1406       case EDJE_MESSAGE_INT:
1407           {
1408              Edje_Message_Int *emsg;
1409
1410              emsg = alloca(sizeof(Edje_Message_Int));
1411              ptr = embryo_data_address_get(ep, params[3]);
1412              if (ptr) emsg->val = (int)*ptr;
1413              else emsg->val = 0;
1414              _edje_message_send(ed, EDJE_QUEUE_APP, type, id, emsg);
1415           }
1416         break;
1417       case EDJE_MESSAGE_FLOAT:
1418           {
1419              Edje_Message_Float *emsg;
1420              float f;
1421
1422              emsg = alloca(sizeof(Edje_Message_Float));
1423              ptr = embryo_data_address_get(ep, params[3]);
1424              if (ptr)
1425                 {
1426                    f = EMBRYO_CELL_TO_FLOAT(*ptr);
1427                    emsg->val = (double)f;
1428                 }
1429              else
1430                 emsg->val = 0.0;
1431              _edje_message_send(ed, EDJE_QUEUE_APP, type, id, emsg);
1432           }
1433         break;
1434       case EDJE_MESSAGE_STRING_SET:
1435           {
1436              Edje_Message_String_Set *emsg;
1437
1438              n = (params[0] / sizeof(Embryo_Cell)) + 1;
1439              emsg = alloca(sizeof(Edje_Message_String_Set) + ((n - 3 - 1) * sizeof(char *)));
1440              emsg->count = n - 3;
1441              for (i = 3; i < n; i++)
1442                {
1443                   Embryo_Cell *cptr;
1444
1445                   cptr = embryo_data_address_get(ep, params[i]);
1446                   if (cptr)
1447                     {
1448                        int l;
1449                        char *s;
1450
1451                        l = embryo_data_string_length_get(ep, cptr);
1452                        s = alloca(l + 1);
1453                        s[0] = 0;
1454                        embryo_data_string_get(ep, cptr, s);
1455                        emsg->str[i - 3] = s;
1456                     }
1457                }
1458              _edje_message_send(ed, EDJE_QUEUE_APP, type, id, emsg);
1459           }
1460         break;
1461       case EDJE_MESSAGE_INT_SET:
1462           {
1463              Edje_Message_Int_Set *emsg;
1464
1465              n = (params[0] / sizeof(Embryo_Cell)) + 1;
1466              emsg = alloca(sizeof(Edje_Message_Int_Set) + ((n - 3 - 1) * sizeof(int)));
1467              emsg->count = n - 3;
1468              for (i = 3; i < n; i++)
1469                {
1470                   ptr = embryo_data_address_get(ep, params[i]);
1471                   if (ptr) emsg->val[i - 3] = (int)*ptr;
1472                   else emsg->val[i - 3] = 0;
1473                }
1474              _edje_message_send(ed, EDJE_QUEUE_APP, type, id, emsg);
1475           }
1476         break;
1477       case EDJE_MESSAGE_FLOAT_SET:
1478           {
1479              Edje_Message_Float_Set *emsg;
1480
1481              n = (params[0] / sizeof(Embryo_Cell)) + 1;
1482              emsg = alloca(sizeof(Edje_Message_Float_Set) + ((n - 3 - 1) * sizeof(double)));
1483              emsg->count = n - 3;
1484              for (i = 3; i < n; i++)
1485                {
1486                   float f;
1487
1488                   ptr = embryo_data_address_get(ep, params[i]);
1489                   if (ptr)
1490                      {
1491                         f = EMBRYO_CELL_TO_FLOAT(*ptr);
1492                         emsg->val[i - 3] = (double)f;
1493                      }
1494                   else
1495                      emsg->val[i - 3] = 0.0;
1496                }
1497              _edje_message_send(ed, EDJE_QUEUE_APP, type, id, emsg);
1498           }
1499         break;
1500       case EDJE_MESSAGE_STRING_INT:
1501           {
1502              Edje_Message_String_Int *emsg;
1503              Embryo_Cell *cptr;
1504
1505              cptr = embryo_data_address_get(ep, params[3]);
1506              if (cptr)
1507                {
1508                   int l;
1509                   char *s;
1510
1511                   l = embryo_data_string_length_get(ep, cptr);
1512                   s = alloca(l + 1);
1513                   s[0] = 0;
1514                   embryo_data_string_get(ep, cptr, s);
1515                   emsg = alloca(sizeof(Edje_Message_String_Int));
1516                   emsg->str = s;
1517                   ptr = embryo_data_address_get(ep, params[4]);
1518                   if (ptr) emsg->val = (int)*ptr;
1519                   else emsg->val = 0;
1520                   _edje_message_send(ed, EDJE_QUEUE_APP, type, id, emsg);
1521                }
1522           }
1523         break;
1524       case EDJE_MESSAGE_STRING_FLOAT:
1525           {
1526              Edje_Message_String_Float *emsg;
1527              Embryo_Cell *cptr;
1528
1529              cptr = embryo_data_address_get(ep, params[3]);
1530              if (cptr)
1531                {
1532                   int l;
1533                   char *s;
1534                   float f;
1535
1536                   l = embryo_data_string_length_get(ep, cptr);
1537                   s = alloca(l + 1);
1538                   s[0] = 0;
1539                   embryo_data_string_get(ep, cptr, s);
1540                   emsg = alloca(sizeof(Edje_Message_String_Float));
1541                   emsg->str = s;
1542                   ptr = embryo_data_address_get(ep, params[4]);
1543                   if (ptr)
1544                      {
1545                         f = EMBRYO_CELL_TO_FLOAT(*ptr);
1546                         emsg->val = (double)f;
1547                      }
1548                   else
1549                      emsg->val = 0.0;
1550                   _edje_message_send(ed, EDJE_QUEUE_APP, type, id, emsg);
1551                }
1552           }
1553         break;
1554       case EDJE_MESSAGE_STRING_INT_SET:
1555           {
1556              Edje_Message_String_Int_Set *emsg;
1557              Embryo_Cell *cptr;
1558
1559              cptr = embryo_data_address_get(ep, params[3]);
1560              if (cptr)
1561                {
1562                   int l;
1563                   char *s;
1564
1565                   l = embryo_data_string_length_get(ep, cptr);
1566                   s = alloca(l + 1);
1567                   s[0] = 0;
1568                   embryo_data_string_get(ep, cptr, s);
1569                   n = (params[0] / sizeof(Embryo_Cell)) + 1;
1570                   emsg = alloca(sizeof(Edje_Message_String_Int_Set) + ((n - 4 - 1) * sizeof(int)));
1571                   emsg->str = s;
1572                   emsg->count = n - 4;
1573                   for (i = 4; i < n; i++)
1574                     {
1575                        ptr = embryo_data_address_get(ep, params[i]);
1576                        if (ptr) emsg->val[i - 4] = (int)*ptr;
1577                        else emsg->val[i - 4] = 0;
1578                     }
1579                   _edje_message_send(ed, EDJE_QUEUE_APP, type, id, emsg);
1580                }
1581           }
1582         break;
1583       case EDJE_MESSAGE_STRING_FLOAT_SET:
1584           {
1585              Edje_Message_String_Float_Set *emsg;
1586              Embryo_Cell *cptr;
1587
1588              cptr = embryo_data_address_get(ep, params[3]);
1589              if (cptr)
1590                {
1591                   int l;
1592                   char *s;
1593
1594                   l = embryo_data_string_length_get(ep, cptr);
1595                   s = alloca(l + 1);
1596                   s[0] = 0;
1597                   embryo_data_string_get(ep, cptr, s);
1598                   n = (params[0] / sizeof(Embryo_Cell)) + 1;
1599                   emsg = alloca(sizeof(Edje_Message_String_Float_Set) + ((n - 4 - 1) * sizeof(double)));
1600                   emsg->str = s;
1601                   emsg->count = n - 4;
1602                   for (i = 4; i < n; i++)
1603                     {
1604                        float f;
1605
1606                        ptr = embryo_data_address_get(ep, params[i]);
1607                        if (ptr)
1608                          {
1609                             f = EMBRYO_CELL_TO_FLOAT(*ptr);
1610                             emsg->val[i - 4] = (double)f;
1611                          }
1612                        else
1613                           emsg->val[i - 4] = 0.0;
1614                     }
1615                   _edje_message_send(ed, EDJE_QUEUE_APP, type, id, emsg);
1616                }
1617           }
1618         break;
1619       default:
1620         break;
1621      }
1622    return(0);
1623 }
1624
1625 /* custom_state(part_id, state[], Float:state_val = 0.0) */
1626 static Embryo_Cell
1627 _edje_embryo_fn_custom_state(Embryo_Program *ep, Embryo_Cell *params)
1628 {
1629    Edje *ed = embryo_program_data_get(ep);
1630    Edje_Real_Part *rp;
1631    Edje_Part_Description_Common *parent, *d = NULL;
1632    char *name;
1633    float val;
1634
1635    CHKPARAM(3);
1636
1637    if (params[1] < 0)
1638      return 0;
1639
1640    if (!(rp = ed->table_parts[params[1] % ed->table_parts_size]))
1641      return 0;
1642
1643    /* check whether this part already has a "custom" state */
1644    if (rp->custom)
1645      return 0;
1646
1647    GETSTR(name, params[2]);
1648    if (!name)
1649      return 0;
1650
1651    val = EMBRYO_CELL_TO_FLOAT(params[3]);
1652
1653    if (!(parent = _edje_part_description_find(ed, rp, name, val)))
1654      return 0;
1655
1656    /* now create the custom state */
1657    switch (rp->part->type)
1658      {
1659 #define ALLOC_DESC(Short, Type, To)                                     \
1660         case EDJE_PART_TYPE_##Short: To = calloc(1, sizeof (Edje_Part_Description_##Type)); break;
1661
1662 #define ALLOC_COPY_DESC(Short, Type, To, Spec)                          \
1663         case EDJE_PART_TYPE_##Short:                                    \
1664           {                                                             \
1665              Edje_Part_Description_##Type *tmp;                         \
1666              Edje_Part_Description_##Type *new;                         \
1667                                                                         \
1668              tmp = (Edje_Part_Description_##Type *) parent;             \
1669                                                                         \
1670              new = calloc(1, sizeof (Edje_Part_Description_##Type));    \
1671              new->Spec = tmp->Spec;                                     \
1672              d = &new->common;                                          \
1673              break;                                                     \
1674           }
1675
1676         ALLOC_DESC(RECTANGLE, Common, d);
1677         ALLOC_DESC(SWALLOW, Common, d);
1678         ALLOC_DESC(GROUP, Common, d);
1679
1680         ALLOC_COPY_DESC(IMAGE, Image, d, image);
1681         ALLOC_COPY_DESC(TEXT, Text, d, text);
1682         ALLOC_COPY_DESC(TEXTBLOCK, Text, d, text);
1683         ALLOC_COPY_DESC(BOX, Box, d, box);
1684         ALLOC_COPY_DESC(TABLE, Table, d, table);
1685         ALLOC_COPY_DESC(EXTERNAL, External, d, external_params);
1686      }
1687
1688    if (!d) return 0;
1689
1690    rp->custom = eina_mempool_malloc(_edje_real_part_state_mp, sizeof (Edje_Real_Part_State));
1691    if (!rp->custom)
1692      {
1693         free(d);
1694         return 0;
1695      }
1696
1697    memset(rp->custom, 0, sizeof (Edje_Real_Part_State));
1698
1699    *d = *parent;
1700
1701    d->state.name = (char *)eina_stringshare_add("custom");
1702    d->state.value = 0.0;
1703
1704    /* make sure all the allocated memory is getting copied,
1705     * not just referenced
1706     */
1707    if (rp->part->type == EDJE_PART_TYPE_IMAGE)
1708      {
1709         Edje_Part_Description_Image *img_desc;
1710         Edje_Part_Description_Image *parent_img_desc;
1711
1712         img_desc = (Edje_Part_Description_Image*) d;
1713         parent_img_desc = (Edje_Part_Description_Image*) parent;
1714
1715         img_desc->image.tweens_count = parent_img_desc->image.tweens_count;
1716         img_desc->image.tweens = calloc(img_desc->image.tweens_count,
1717                                         sizeof(Edje_Part_Image_Id*));
1718         if (img_desc->image.tweens)
1719           {
1720              unsigned int i;
1721
1722              for (i = 0; i < parent_img_desc->image.tweens_count; ++i)
1723                {
1724                   Edje_Part_Image_Id *iid_new;
1725
1726                   iid_new = calloc(1, sizeof(Edje_Part_Image_Id));
1727                   if (!iid_new) continue;
1728
1729                   *iid_new = *parent_img_desc->image.tweens[i];
1730
1731                   img_desc->image.tweens[i] = iid_new;
1732                }
1733           }
1734      }
1735
1736 #define DUP(x) x ? (char *)eina_stringshare_add(x) : NULL
1737    d->color_class = DUP(d->color_class);
1738
1739    if (rp->part->type == EDJE_PART_TYPE_TEXT
1740        || rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
1741      {
1742         Edje_Part_Description_Text *text_desc;
1743
1744         text_desc = (Edje_Part_Description_Text*) d;
1745
1746         text_desc->text.text_class = DUP(text_desc->text.text_class);
1747         text_desc->text.text.str = DUP(edje_string_get(&text_desc->text.text));
1748         text_desc->text.text.id = 0;
1749         text_desc->text.font.str = DUP(edje_string_get(&text_desc->text.font));
1750         text_desc->text.font.id = 0;
1751         text_desc->text.style.str = DUP(edje_string_get(&text_desc->text.style));
1752         text_desc->text.style.id = 0;
1753      }
1754 #undef DUP
1755
1756    rp->custom->description = d;
1757
1758    return 0;
1759 }
1760
1761 /* set_state_val(part_id, State_Param:p, ...) */
1762 static Embryo_Cell
1763 _edje_embryo_fn_set_state_val(Embryo_Program *ep, Embryo_Cell *params)
1764 {
1765    Edje *ed = embryo_program_data_get(ep);
1766    Edje_Real_Part *rp;
1767    char *s;
1768
1769    /* we need at least 3 arguments */
1770    if (params[0] < (int) (sizeof(Embryo_Cell) * 3))
1771      return 0;
1772
1773    if (params[1] < 0)
1774      return 0;
1775
1776    if (!(rp = ed->table_parts[params[1] % ed->table_parts_size]))
1777      return 0;
1778
1779    /* check whether this part has a "custom" state */
1780    if (!rp->custom)
1781      return 0;
1782
1783    switch (params[2])
1784      {
1785       case EDJE_STATE_PARAM_ALIGNMENT:
1786          CHKPARAM(4);
1787
1788          GETFLOAT_T(rp->custom->description->align.x, params[3]);
1789          GETFLOAT_T(rp->custom->description->align.y, params[4]);
1790
1791          break;
1792       case EDJE_STATE_PARAM_MIN:
1793          CHKPARAM(4);
1794
1795          GETINT(rp->custom->description->min.w, params[3]);
1796          GETINT(rp->custom->description->min.h, params[4]);
1797
1798          break;
1799       case EDJE_STATE_PARAM_MAX:
1800          CHKPARAM(4);
1801
1802          GETINT(rp->custom->description->max.w, params[3]);
1803          GETINT(rp->custom->description->max.h, params[4]);
1804
1805          break;
1806       case EDJE_STATE_PARAM_STEP:
1807          CHKPARAM(4);
1808
1809          GETINT(rp->custom->description->step.x, params[3]);
1810          GETINT(rp->custom->description->step.y, params[4]);
1811
1812          break;
1813       case EDJE_STATE_PARAM_ASPECT:
1814          CHKPARAM(4);
1815
1816          GETFLOAT_T(rp->custom->description->aspect.min, params[3]);
1817          GETFLOAT_T(rp->custom->description->aspect.max, params[4]);
1818
1819          break;
1820       case EDJE_STATE_PARAM_ASPECT_PREF:
1821          CHKPARAM(3);
1822
1823          GETINT(rp->custom->description->aspect.prefer, params[3]);
1824
1825          break;
1826       case EDJE_STATE_PARAM_COLOR:
1827          CHKPARAM(6);
1828
1829          GETINT(rp->custom->description->color.r, params[3]);
1830          GETINT(rp->custom->description->color.g, params[4]);
1831          GETINT(rp->custom->description->color.b, params[5]);
1832          GETINT(rp->custom->description->color.a, params[6]);
1833
1834          break;
1835       case EDJE_STATE_PARAM_COLOR2:
1836          CHKPARAM(6);
1837
1838          GETINT(rp->custom->description->color2.r, params[3]);
1839          GETINT(rp->custom->description->color2.g, params[4]);
1840          GETINT(rp->custom->description->color2.b, params[5]);
1841          GETINT(rp->custom->description->color2.a, params[6]);
1842
1843          break;
1844       case EDJE_STATE_PARAM_COLOR3:
1845         {
1846            Edje_Part_Description_Text *text;
1847
1848            if ( (rp->part->type != EDJE_PART_TYPE_TEXT) &&
1849                 (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
1850              return 0;
1851
1852            CHKPARAM(6);
1853
1854            text = (Edje_Part_Description_Text*) rp->custom->description;
1855
1856            GETINT(text->text.color3.r, params[3]);
1857            GETINT(text->text.color3.g, params[4]);
1858            GETINT(text->text.color3.b, params[5]);
1859            GETINT(text->text.color3.a, params[6]);
1860            break;
1861         }
1862       case EDJE_STATE_PARAM_COLOR_CLASS:
1863          CHKPARAM(3);
1864
1865          GETSTR(s, params[3]);
1866          GETSTREVAS(s, rp->custom->description->color_class);
1867
1868          break;
1869       case EDJE_STATE_PARAM_REL1:
1870          CHKPARAM(4);
1871
1872          GETFLOAT_T(rp->custom->description->rel1.relative_x, params[3]);
1873          GETFLOAT_T(rp->custom->description->rel1.relative_y, params[4]);
1874
1875          break;
1876       case EDJE_STATE_PARAM_REL1_TO:
1877          CHKPARAM(4);
1878
1879          GETINT(rp->custom->description->rel1.id_x, params[3]);
1880          GETINT(rp->custom->description->rel1.id_y, params[4]);
1881
1882          if (rp->param1.description->rel1.id_x >= 0)
1883            rp->param1.rel1_to_x = ed->table_parts[rp->param1.description->rel1.id_x % ed->table_parts_size];
1884          if (rp->param1.description->rel1.id_y >= 0)
1885            rp->param1.rel1_to_y = ed->table_parts[rp->param1.description->rel1.id_y % ed->table_parts_size];
1886
1887          break;
1888       case EDJE_STATE_PARAM_REL1_OFFSET:
1889          CHKPARAM(4);
1890
1891          GETINT(rp->custom->description->rel1.offset_x, params[3]);
1892          GETINT(rp->custom->description->rel1.offset_y, params[4]);
1893
1894          break;
1895       case EDJE_STATE_PARAM_REL2:
1896          CHKPARAM(4);
1897
1898          GETFLOAT_T(rp->custom->description->rel2.relative_x, params[3]);
1899          GETFLOAT_T(rp->custom->description->rel2.relative_y, params[4]);
1900
1901          break;
1902       case EDJE_STATE_PARAM_REL2_TO:
1903          CHKPARAM(4);
1904
1905          GETINT(rp->custom->description->rel2.id_x, params[3]);
1906          GETINT(rp->custom->description->rel2.id_y, params[4]);
1907
1908          if (rp->param1.description->rel2.id_x >= 0)
1909            rp->param1.rel2_to_x = ed->table_parts[rp->param1.description->rel2.id_x % ed->table_parts_size];
1910          if (rp->param1.description->rel2.id_y >= 0)
1911            rp->param1.rel2_to_y = ed->table_parts[rp->param1.description->rel2.id_y % ed->table_parts_size];
1912
1913          break;
1914       case EDJE_STATE_PARAM_REL2_OFFSET:
1915          CHKPARAM(4);
1916
1917          GETINT(rp->custom->description->rel2.offset_x, params[3]);
1918          GETINT(rp->custom->description->rel2.offset_y, params[4]);
1919
1920          break;
1921       case EDJE_STATE_PARAM_IMAGE:
1922         {
1923            Edje_Part_Description_Image *img;
1924
1925            if ( (rp->part->type != EDJE_PART_TYPE_IMAGE) ) return 0;
1926            CHKPARAM(3);
1927
1928            img = (Edje_Part_Description_Image*) rp->custom->description;
1929            GETINT(img->image.id, params[3]);
1930
1931            break;
1932         }
1933       case EDJE_STATE_PARAM_BORDER:
1934         {
1935            Edje_Part_Description_Image *img;
1936
1937            if ( (rp->part->type != EDJE_PART_TYPE_IMAGE) ) return 0;
1938            CHKPARAM(6);
1939
1940            img = (Edje_Part_Description_Image*) rp->custom->description;
1941
1942            GETINT(img->image.border.l, params[3]);
1943            GETINT(img->image.border.r, params[4]);
1944            GETINT(img->image.border.t, params[5]);
1945            GETINT(img->image.border.b, params[6]);
1946
1947            break;
1948         }
1949       case EDJE_STATE_PARAM_FILL_SMOOTH:
1950         {
1951            Edje_Part_Description_Image *img;
1952
1953            if ( (rp->part->type != EDJE_PART_TYPE_IMAGE) ) return 0;
1954            CHKPARAM(3);
1955
1956            img = (Edje_Part_Description_Image*) rp->custom->description;
1957
1958            GETINT(img->image.fill.smooth, params[3]);
1959
1960            break;
1961         }
1962       case EDJE_STATE_PARAM_FILL_POS:
1963         {
1964            Edje_Part_Description_Image *img;
1965
1966            if ( (rp->part->type != EDJE_PART_TYPE_IMAGE) ) return 0;
1967            CHKPARAM(6);
1968
1969            img = (Edje_Part_Description_Image*) rp->custom->description;
1970
1971            GETFLOAT_T(img->image.fill.pos_rel_x, params[3]);
1972            GETFLOAT_T(img->image.fill.pos_rel_y, params[4]);
1973            GETINT(img->image.fill.pos_abs_x, params[5]);
1974            GETINT(img->image.fill.pos_abs_y, params[6]);
1975
1976            break;
1977         }
1978       case EDJE_STATE_PARAM_FILL_SIZE:
1979         {
1980            Edje_Part_Description_Image *img;
1981
1982            if ( (rp->part->type != EDJE_PART_TYPE_IMAGE) ) return 0;
1983            CHKPARAM(6);
1984
1985            img = (Edje_Part_Description_Image*) rp->custom->description;
1986
1987            GETFLOAT_T(img->image.fill.rel_x, params[3]);
1988            GETFLOAT_T(img->image.fill.rel_y, params[4]);
1989            GETINT(img->image.fill.abs_x, params[5]);
1990            GETINT(img->image.fill.abs_y, params[6]);
1991
1992            break;
1993         }
1994       case EDJE_STATE_PARAM_TEXT:
1995         {
1996            Edje_Part_Description_Text *text;
1997
1998            if ( (rp->part->type != EDJE_PART_TYPE_TEXT) &&
1999                 (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
2000              return 0;
2001            CHKPARAM(3);
2002
2003            GETSTR(s, params[3]);
2004
2005            text = (Edje_Part_Description_Text*) rp->custom->description;
2006            GETSTREVAS(s, text->text.text.str);
2007
2008            break;
2009         }
2010       case EDJE_STATE_PARAM_TEXT_CLASS:
2011         {
2012            Edje_Part_Description_Text *text;
2013
2014            if ( (rp->part->type != EDJE_PART_TYPE_TEXT) &&
2015                 (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
2016              return 0;
2017            CHKPARAM(3);
2018
2019            GETSTR(s, params[3]);
2020
2021            text = (Edje_Part_Description_Text*) rp->custom->description;
2022            GETSTREVAS(s, text->text.text_class);
2023
2024            break;
2025         }
2026       case EDJE_STATE_PARAM_TEXT_FONT:
2027         {
2028            Edje_Part_Description_Text *text;
2029
2030            if ((rp->part->type != EDJE_PART_TYPE_TEXT)) return 0;
2031            CHKPARAM(3);
2032
2033            GETSTR(s, params[3]);
2034
2035            text = (Edje_Part_Description_Text*) rp->custom->description;
2036            GETSTREVAS(s, text->text.font.str);
2037
2038            break;
2039         }
2040       case EDJE_STATE_PARAM_TEXT_STYLE:
2041         {
2042            Edje_Part_Description_Text *text;
2043
2044            if ((rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)) return 0;
2045            CHKPARAM(3);
2046
2047            GETSTR(s, params[3]);
2048
2049            text = (Edje_Part_Description_Text*) rp->custom->description;
2050            GETSTREVAS(s, text->text.style.str);
2051
2052            break;
2053         }
2054       case EDJE_STATE_PARAM_TEXT_SIZE:
2055         {
2056            Edje_Part_Description_Text *text;
2057
2058            if ((rp->part->type != EDJE_PART_TYPE_TEXT)) return 0;
2059            CHKPARAM(3);
2060
2061            text = (Edje_Part_Description_Text*) rp->custom->description;
2062            GETINT(text->text.size, params[3]);
2063
2064            break;
2065         }
2066       case EDJE_STATE_PARAM_TEXT_FIT:
2067         {
2068            Edje_Part_Description_Text *text;
2069
2070            if ((rp->part->type != EDJE_PART_TYPE_TEXT)) return 0;
2071            CHKPARAM(4);
2072
2073            text = (Edje_Part_Description_Text*) rp->custom->description;
2074
2075            GETINT(text->text.fit_x, params[3]);
2076            GETINT(text->text.fit_y, params[4]);
2077
2078            break;
2079         }
2080       case EDJE_STATE_PARAM_TEXT_MIN:
2081         {
2082            Edje_Part_Description_Text *text;
2083
2084            if ( (rp->part->type != EDJE_PART_TYPE_TEXT) &&
2085                 (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
2086              return 0;
2087            CHKPARAM(4);
2088
2089            text = (Edje_Part_Description_Text*) rp->custom->description;
2090
2091            GETINT(text->text.min_x, params[3]);
2092            GETINT(text->text.min_y, params[4]);
2093
2094            break;
2095         }
2096       case EDJE_STATE_PARAM_TEXT_MAX:
2097         {
2098            Edje_Part_Description_Text *text;
2099
2100            if ( (rp->part->type != EDJE_PART_TYPE_TEXT) &&
2101                 (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
2102              return 0;
2103            CHKPARAM(4);
2104
2105            text = (Edje_Part_Description_Text*) rp->custom->description;
2106
2107            GETINT(text->text.max_x, params[3]);
2108            GETINT(text->text.max_y, params[4]);
2109
2110            break;
2111         }
2112       case EDJE_STATE_PARAM_TEXT_ALIGN:
2113         {
2114            Edje_Part_Description_Text *text;
2115
2116            if ((rp->part->type != EDJE_PART_TYPE_TEXT)) return 0;
2117            CHKPARAM(4);
2118
2119            text = (Edje_Part_Description_Text*) rp->custom->description;
2120
2121            GETFLOAT_T(text->text.align.x, params[3]);
2122            GETFLOAT_T(text->text.align.y, params[4]);
2123
2124            break;
2125         }
2126       case EDJE_STATE_PARAM_VISIBLE:
2127          CHKPARAM(3);
2128
2129          GETINT(rp->custom->description->visible, params[3]);
2130
2131          break;
2132       case EDJE_STATE_PARAM_MAP_OM:
2133         CHKPARAM(3);
2134         
2135         GETINT(rp->custom->description->map.on, params[3]);
2136         
2137         break;
2138       case EDJE_STATE_PARAM_MAP_PERSP:
2139         CHKPARAM(3);
2140         
2141         GETINT(rp->custom->description->map.id_persp, params[3]);
2142         
2143         break;
2144       case EDJE_STATE_PARAM_MAP_LIGNT:
2145         CHKPARAM(3);
2146         
2147         GETINT(rp->custom->description->map.id_light, params[3]);
2148         
2149         break;
2150       case EDJE_STATE_PARAM_MAP_ROT_CENTER:
2151         CHKPARAM(3);
2152         
2153         GETINT(rp->custom->description->map.rot.id_center, params[3]);
2154         
2155         break;
2156       case EDJE_STATE_PARAM_MAP_ROT_X:
2157         CHKPARAM(3);
2158
2159         GETFLOAT_T(rp->custom->description->map.rot.x, params[3]);
2160
2161         break;
2162       case EDJE_STATE_PARAM_MAP_ROT_Y:
2163         CHKPARAM(3);
2164         
2165         GETFLOAT_T(rp->custom->description->map.rot.y, params[3]);
2166         
2167         break;
2168       case EDJE_STATE_PARAM_MAP_ROT_Z:
2169         CHKPARAM(3);
2170         
2171         GETFLOAT_T(rp->custom->description->map.rot.z, params[3]);
2172
2173         break;
2174       case EDJE_STATE_PARAM_MAP_BACK_CULL:
2175         CHKPARAM(3);
2176         
2177         GETINT(rp->custom->description->map.backcull, params[3]);
2178         
2179         break;
2180       case EDJE_STATE_PARAM_MAP_PERSP_ON:
2181         CHKPARAM(3);
2182         
2183         GETINT(rp->custom->description->map.persp_on, params[3]);
2184         
2185         break;
2186       case EDJE_STATE_PARAM_PERSP_ZPLANE:
2187         CHKPARAM(3);
2188         
2189         GETINT(rp->custom->description->persp.zplane, params[3]);
2190         
2191         break;
2192       case EDJE_STATE_PARAM_PERSP_FOCAL:
2193         CHKPARAM(3);
2194         
2195         GETINT(rp->custom->description->persp.focal, params[3]);
2196         
2197         break;
2198       default:
2199          break;
2200      }
2201
2202 #ifdef EDJE_CALC_CACHE
2203    rp->invalidate = 1;
2204 #endif
2205    ed->dirty=1;
2206    return 0;
2207 }
2208
2209 /* get_state_val(part_id, State_Param:p, ...) */
2210 static Embryo_Cell
2211 _edje_embryo_fn_get_state_val(Embryo_Program *ep, Embryo_Cell *params)
2212 {
2213    Edje *ed = embryo_program_data_get(ep);
2214    Edje_Real_Part *rp;
2215    char *s;
2216
2217    /* we need at least 3 arguments */
2218    if (params[0] < (int) (sizeof(Embryo_Cell) * 3))
2219      return 0;
2220
2221    if (params[1] < 0)
2222      return 0;
2223
2224    if (!(rp = ed->table_parts[params[1] % ed->table_parts_size]))
2225      return 0;
2226
2227    /* check whether this part has a "custom" state */
2228    if (!rp->custom)
2229      return 0;
2230
2231    switch (params[2])
2232      {
2233       case EDJE_STATE_PARAM_ALIGNMENT:
2234          CHKPARAM(4);
2235
2236          SETFLOAT_T(rp->custom->description->align.x, params[3]);
2237          SETFLOAT_T(rp->custom->description->align.y, params[4]);
2238
2239          break;
2240       case EDJE_STATE_PARAM_MIN:
2241          CHKPARAM(4);
2242
2243          SETINT(rp->custom->description->min.w, params[3]);
2244          SETINT(rp->custom->description->min.h, params[4]);
2245
2246          break;
2247       case EDJE_STATE_PARAM_MAX:
2248          CHKPARAM(4);
2249
2250          SETINT(rp->custom->description->max.w, params[3]);
2251          SETINT(rp->custom->description->max.h, params[4]);
2252
2253          break;
2254       case EDJE_STATE_PARAM_STEP:
2255          CHKPARAM(4);
2256
2257          SETINT(rp->custom->description->step.x, params[3]);
2258          SETINT(rp->custom->description->step.y, params[4]);
2259
2260          break;
2261       case EDJE_STATE_PARAM_ASPECT:
2262          CHKPARAM(4);
2263
2264          SETFLOAT_T(rp->custom->description->aspect.min, params[3]);
2265          SETFLOAT_T(rp->custom->description->aspect.max, params[4]);
2266
2267          break;
2268       case EDJE_STATE_PARAM_ASPECT_PREF:
2269          CHKPARAM(3);
2270
2271          SETINT(rp->custom->description->aspect.prefer, params[3]);
2272
2273          break;
2274       case EDJE_STATE_PARAM_COLOR:
2275          CHKPARAM(6);
2276
2277          SETINT(rp->custom->description->color.r, params[3]);
2278          SETINT(rp->custom->description->color.g, params[4]);
2279          SETINT(rp->custom->description->color.b, params[5]);
2280          SETINT(rp->custom->description->color.a, params[6]);
2281
2282          break;
2283       case EDJE_STATE_PARAM_COLOR2:
2284          CHKPARAM(6);
2285
2286          SETINT(rp->custom->description->color2.r, params[3]);
2287          SETINT(rp->custom->description->color2.g, params[4]);
2288          SETINT(rp->custom->description->color2.b, params[5]);
2289          SETINT(rp->custom->description->color2.a, params[6]);
2290
2291          break;
2292       case EDJE_STATE_PARAM_COLOR3:
2293         {
2294            Edje_Part_Description_Text *text;
2295
2296            if (rp->part->type == EDJE_PART_TYPE_TEXT
2297                || rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
2298              return 0;
2299
2300            CHKPARAM(6);
2301
2302            text = (Edje_Part_Description_Text*) rp->custom->description;
2303
2304            SETINT(text->text.color3.r, params[3]);
2305            SETINT(text->text.color3.g, params[4]);
2306            SETINT(text->text.color3.b, params[5]);
2307            SETINT(text->text.color3.a, params[6]);
2308
2309            break;
2310         }
2311       case EDJE_STATE_PARAM_COLOR_CLASS:
2312          CHKPARAM(4);
2313
2314          s = rp->custom->description->color_class;
2315          SETSTRALLOCATE(s);
2316
2317          break;
2318       case EDJE_STATE_PARAM_REL1:
2319          CHKPARAM(4);
2320
2321          SETFLOAT_T(rp->custom->description->rel1.relative_x, params[3]);
2322          SETFLOAT_T(rp->custom->description->rel1.relative_y, params[4]);
2323
2324          break;
2325       case EDJE_STATE_PARAM_REL1_TO:
2326          CHKPARAM(4);
2327
2328          SETINT(rp->custom->description->rel1.id_x, params[3]);
2329          SETINT(rp->custom->description->rel1.id_y, params[4]);
2330
2331          break;
2332       case EDJE_STATE_PARAM_REL1_OFFSET:
2333          CHKPARAM(4);
2334
2335          SETINT(rp->custom->description->rel1.offset_x, params[3]);
2336          SETINT(rp->custom->description->rel1.offset_y, params[4]);
2337
2338          break;
2339       case EDJE_STATE_PARAM_REL2:
2340          CHKPARAM(4);
2341
2342          SETFLOAT_T(rp->custom->description->rel2.relative_x, params[3]);
2343          SETFLOAT_T(rp->custom->description->rel2.relative_y, params[4]);
2344
2345          break;
2346       case EDJE_STATE_PARAM_REL2_TO:
2347          CHKPARAM(4);
2348
2349          SETINT(rp->custom->description->rel2.id_x, params[3]);
2350          SETINT(rp->custom->description->rel2.id_y, params[4]);
2351
2352          break;
2353       case EDJE_STATE_PARAM_REL2_OFFSET:
2354          CHKPARAM(4);
2355
2356          SETINT(rp->custom->description->rel2.offset_x, params[3]);
2357          SETINT(rp->custom->description->rel2.offset_y, params[4]);
2358
2359          break;
2360       case EDJE_STATE_PARAM_IMAGE:
2361         {
2362            Edje_Part_Description_Image *img;
2363
2364            if ( (rp->part->type != EDJE_PART_TYPE_IMAGE) ) return 0;
2365            CHKPARAM(3);
2366
2367            img = (Edje_Part_Description_Image*) rp->custom->description;
2368
2369            SETINT(img->image.id, params[3]);
2370
2371            break;
2372         }
2373       case EDJE_STATE_PARAM_BORDER:
2374         {
2375            Edje_Part_Description_Image *img;
2376
2377            if ( (rp->part->type != EDJE_PART_TYPE_IMAGE) ) return 0;
2378            CHKPARAM(6);
2379
2380            img = (Edje_Part_Description_Image*) rp->custom->description;
2381
2382            SETINT(img->image.border.l, params[3]);
2383            SETINT(img->image.border.r, params[4]);
2384            SETINT(img->image.border.t, params[5]);
2385            SETINT(img->image.border.b, params[6]);
2386
2387            break;
2388         }
2389       case EDJE_STATE_PARAM_FILL_SMOOTH:
2390         {
2391            Edje_Part_Description_Image *img;
2392
2393            if ( (rp->part->type != EDJE_PART_TYPE_IMAGE) ) return 0;
2394            CHKPARAM(3);
2395
2396            img = (Edje_Part_Description_Image*) rp->custom->description;
2397
2398            SETINT(img->image.fill.smooth, params[3]);
2399
2400            break;
2401         }
2402       case EDJE_STATE_PARAM_FILL_POS:
2403         {
2404            Edje_Part_Description_Image *img;
2405
2406            if ( (rp->part->type != EDJE_PART_TYPE_IMAGE) ) return 0;
2407            CHKPARAM(6);
2408
2409            img = (Edje_Part_Description_Image*) rp->custom->description;
2410
2411            SETFLOAT_T(img->image.fill.pos_rel_x, params[3]);
2412            SETFLOAT_T(img->image.fill.pos_rel_y, params[4]);
2413            SETINT(img->image.fill.pos_abs_x, params[5]);
2414            SETINT(img->image.fill.pos_abs_y, params[6]);
2415
2416            break;
2417         }
2418       case EDJE_STATE_PARAM_FILL_SIZE:
2419         {
2420            Edje_Part_Description_Image *img;
2421
2422            if ( (rp->part->type != EDJE_PART_TYPE_IMAGE) ) return 0;
2423            CHKPARAM(6);
2424
2425            img = (Edje_Part_Description_Image*) rp->custom->description;
2426
2427            SETFLOAT_T(img->image.fill.rel_x, params[3]);
2428            SETFLOAT_T(img->image.fill.rel_y, params[4]);
2429            SETINT(img->image.fill.abs_x, params[5]);
2430            SETINT(img->image.fill.abs_y, params[6]);
2431
2432            break;
2433         }
2434       case EDJE_STATE_PARAM_TEXT:
2435         {
2436            Edje_Part_Description_Text *text;
2437
2438            if (rp->part->type == EDJE_PART_TYPE_TEXT
2439                || rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
2440              return 0;
2441
2442            CHKPARAM(4);
2443
2444            text = (Edje_Part_Description_Text*) rp->custom->description;
2445
2446            s = (char *)text->text.text.str;
2447            SETSTRALLOCATE(s);
2448
2449            break;
2450         }
2451       case EDJE_STATE_PARAM_TEXT_CLASS:
2452         {
2453            Edje_Part_Description_Text *text;
2454
2455            if ( (rp->part->type != EDJE_PART_TYPE_TEXT) &&
2456                (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
2457              return 0;
2458
2459            CHKPARAM(4);
2460
2461            text = (Edje_Part_Description_Text*) rp->custom->description;
2462
2463            s = text->text.text_class;
2464            SETSTRALLOCATE(s);
2465
2466            break;
2467         }
2468       case EDJE_STATE_PARAM_TEXT_FONT:
2469         {
2470            Edje_Part_Description_Text *text;
2471
2472            if ((rp->part->type != EDJE_PART_TYPE_TEXT)) return 0;
2473
2474            CHKPARAM(4);
2475
2476            text = (Edje_Part_Description_Text*) rp->custom->description;
2477
2478            s = (char *)text->text.font.str;
2479            SETSTRALLOCATE(s);
2480
2481            break;
2482         }
2483       case EDJE_STATE_PARAM_TEXT_STYLE:
2484         {
2485            Edje_Part_Description_Text *text;
2486
2487            if ((rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)) return 0;
2488
2489            CHKPARAM(4);
2490
2491            text = (Edje_Part_Description_Text*) rp->custom->description;
2492
2493            s = (char *)text->text.style.str;
2494            SETSTRALLOCATE(s);
2495
2496            break;
2497         }
2498       case EDJE_STATE_PARAM_TEXT_SIZE:
2499         {
2500            Edje_Part_Description_Text *text;
2501
2502            if ((rp->part->type != EDJE_PART_TYPE_TEXT)) return 0;
2503
2504            CHKPARAM(3);
2505
2506            text = (Edje_Part_Description_Text*) rp->custom->description;
2507
2508            SETINT(text->text.size, params[3]);
2509
2510            break;
2511         }
2512       case EDJE_STATE_PARAM_TEXT_FIT:
2513         {
2514            Edje_Part_Description_Text *text;
2515
2516            if ((rp->part->type != EDJE_PART_TYPE_TEXT)) return 0;
2517            CHKPARAM(4);
2518
2519            text = (Edje_Part_Description_Text*) rp->custom->description;
2520
2521            SETINT(text->text.fit_x, params[3]);
2522            SETINT(text->text.fit_y, params[4]);
2523
2524            break;
2525         }
2526       case EDJE_STATE_PARAM_TEXT_MIN:
2527         {
2528            Edje_Part_Description_Text *text;
2529
2530            if ( (rp->part->type != EDJE_PART_TYPE_TEXT) &&
2531                 (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
2532              return 0;
2533
2534            CHKPARAM(4);
2535
2536            text = (Edje_Part_Description_Text*) rp->custom->description;
2537
2538            SETINT(text->text.min_x, params[3]);
2539            SETINT(text->text.min_y, params[4]);
2540
2541            break;
2542         }
2543       case EDJE_STATE_PARAM_TEXT_MAX:
2544         {
2545            Edje_Part_Description_Text *text;
2546
2547            if ( (rp->part->type != EDJE_PART_TYPE_TEXT) &&
2548                 (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
2549              return 0;
2550
2551            CHKPARAM(4);
2552
2553            text = (Edje_Part_Description_Text*) rp->custom->description;
2554
2555            SETINT(text->text.max_x, params[3]);
2556            SETINT(text->text.max_y, params[4]);
2557
2558            break;
2559         }
2560       case EDJE_STATE_PARAM_TEXT_ALIGN:
2561         {
2562            Edje_Part_Description_Text *text;
2563
2564            if ((rp->part->type != EDJE_PART_TYPE_TEXT)) return 0;
2565
2566            CHKPARAM(4);
2567
2568            text = (Edje_Part_Description_Text*) rp->custom->description;
2569
2570            SETFLOAT_T(text->text.align.x, params[3]);
2571            SETFLOAT_T(text->text.align.y, params[4]);
2572
2573            break;
2574         }
2575       case EDJE_STATE_PARAM_VISIBLE:
2576          CHKPARAM(3);
2577
2578          SETINT(rp->custom->description->visible, params[3]);
2579
2580          break;
2581       default:
2582          break;
2583      }
2584
2585    return 0;
2586 }
2587
2588 /* part_swallow(part_id, group_name) */
2589 static Embryo_Cell
2590 _edje_embryo_fn_part_swallow(Embryo_Program *ep, Embryo_Cell *params)
2591 {
2592    int part_id = 0;
2593    char* group_name = 0;
2594    Edje *ed;
2595    Edje_Real_Part *rp;
2596    Evas_Object *new_obj;
2597    
2598    CHKPARAM(2);
2599
2600    part_id = params[1];
2601    if (part_id < 0) return 0;
2602
2603    GETSTR(group_name, params[2]);
2604    if (!group_name) return 0;
2605
2606    ed = embryo_program_data_get(ep);
2607
2608    rp = ed->table_parts[part_id % ed->table_parts_size];
2609    if (!rp) return 0;
2610
2611    new_obj =  edje_object_add(ed->base.evas);
2612    if (!new_obj) return 0;
2613
2614    if (!edje_object_file_set(new_obj, ed->file->path, group_name)) 
2615      {
2616         evas_object_del(new_obj);
2617         return 0;
2618      }
2619    edje_object_part_swallow(ed->obj, rp->part->name, new_obj);
2620    _edje_subobj_register(ed, new_obj);
2621
2622    return 0;
2623 }
2624
2625 /* external_param_get_int(id, param_name[]) */
2626 static Embryo_Cell
2627 _edje_embryo_fn_external_param_get_int(Embryo_Program *ep, Embryo_Cell *params)
2628 {
2629    Edje *ed;
2630    int part_id;
2631    Edje_Real_Part *rp;
2632    Edje_External_Param eep;
2633    char *param_name;
2634
2635    CHKPARAM(2);
2636    ed = embryo_program_data_get(ep);
2637
2638    part_id = params[1];
2639    if (part_id < 0) return 0;
2640    rp = ed->table_parts[part_id % ed->table_parts_size];
2641
2642    GETSTR(param_name, params[2]);
2643    if (!param_name) return 0;
2644    eep.name = param_name;
2645    eep.type = EDJE_EXTERNAL_PARAM_TYPE_INT;
2646    eep.i = 0;
2647    _edje_external_param_get(NULL, rp, &eep);
2648    return eep.i;
2649 }
2650
2651 /* external_param_set_int(id, param_name[], val) */
2652 static Embryo_Cell
2653 _edje_embryo_fn_external_param_set_int(Embryo_Program *ep, Embryo_Cell *params)
2654 {
2655    Edje *ed;
2656    int part_id;
2657    Edje_Real_Part *rp;
2658    Edje_External_Param eep;
2659    char *param_name;
2660
2661    CHKPARAM(3);
2662    ed = embryo_program_data_get(ep);
2663
2664    part_id = params[1];
2665    if (part_id < 0) return 0;
2666    rp = ed->table_parts[part_id % ed->table_parts_size];
2667
2668    GETSTR(param_name, params[2]);
2669    if (!param_name) return 0;
2670    eep.name = param_name;
2671    eep.type = EDJE_EXTERNAL_PARAM_TYPE_INT;
2672    eep.i = params[3];
2673    return _edje_external_param_set(NULL, rp, &eep);
2674 }
2675
2676 /* Float:external_param_get_float(id, param_name[]) */
2677 static Embryo_Cell
2678 _edje_embryo_fn_external_param_get_float(Embryo_Program *ep, Embryo_Cell *params)
2679 {
2680    Edje *ed;
2681    int part_id;
2682    Edje_Real_Part *rp;
2683    Edje_External_Param eep;
2684    char *param_name;
2685    float v;
2686
2687    CHKPARAM(2);
2688    ed = embryo_program_data_get(ep);
2689
2690    part_id = params[1];
2691    if (part_id < 0) return 0;
2692    rp = ed->table_parts[part_id % ed->table_parts_size];
2693
2694    GETSTR(param_name, params[2]);
2695    if (!param_name) return 0;
2696    eep.name = param_name;
2697    eep.type = EDJE_EXTERNAL_PARAM_TYPE_DOUBLE;
2698    eep.d = 0.0;
2699    _edje_external_param_get(NULL, rp, &eep);
2700    v = eep.d;
2701    return EMBRYO_FLOAT_TO_CELL(v);
2702 }
2703
2704 /* external_param_set_float(id, param_name[], Float:val) */
2705 static Embryo_Cell
2706 _edje_embryo_fn_external_param_set_float(Embryo_Program *ep, Embryo_Cell *params)
2707 {
2708    Edje *ed;
2709    int part_id;
2710    Edje_Real_Part *rp;
2711    Edje_External_Param eep;
2712    char *param_name;
2713
2714    CHKPARAM(3);
2715    ed = embryo_program_data_get(ep);
2716
2717    part_id = params[1];
2718    if (part_id < 0) return 0;
2719    rp = ed->table_parts[part_id % ed->table_parts_size];
2720
2721    GETSTR(param_name, params[2]);
2722    if (!param_name) return 0;
2723    eep.name = param_name;
2724    eep.type = EDJE_EXTERNAL_PARAM_TYPE_DOUBLE;
2725    eep.d = EMBRYO_CELL_TO_FLOAT(params[3]);
2726    return _edje_external_param_set(NULL, rp, &eep);
2727 }
2728
2729 /* external_param_get_strlen(id, param_name[]) */
2730 static Embryo_Cell
2731 _edje_embryo_fn_external_param_get_strlen(Embryo_Program *ep, Embryo_Cell *params)
2732 {
2733    Edje *ed;
2734    int part_id;
2735    Edje_Real_Part *rp;
2736    Edje_External_Param eep;
2737    char *param_name;
2738
2739    CHKPARAM(2);
2740    ed = embryo_program_data_get(ep);
2741
2742    part_id = params[1];
2743    if (part_id < 0) return 0;
2744    rp = ed->table_parts[part_id % ed->table_parts_size];
2745
2746    GETSTR(param_name, params[2]);
2747    if (!param_name) return 0;
2748    eep.name = param_name;
2749    eep.type = EDJE_EXTERNAL_PARAM_TYPE_STRING;
2750    eep.s = NULL;
2751    _edje_external_param_get(NULL, rp, &eep);
2752    if (!eep.s) return 0;
2753    return strlen(eep.s);
2754 }
2755
2756 /* external_param_get_str(id, param_name[], val[], val_maxlen) */
2757 static Embryo_Cell
2758 _edje_embryo_fn_external_param_get_str(Embryo_Program *ep, Embryo_Cell *params)
2759 {
2760    Edje *ed;
2761    int part_id;
2762    Edje_Real_Part *rp;
2763    Edje_External_Param eep;
2764    char *param_name;
2765    size_t src_len, dst_len;
2766
2767    CHKPARAM(4);
2768    dst_len = params[4];
2769    if (dst_len < 1) goto error;
2770
2771    ed = embryo_program_data_get(ep);
2772
2773    part_id = params[1];
2774    if (part_id < 0) goto error;
2775    rp = ed->table_parts[part_id % ed->table_parts_size];
2776
2777    GETSTR(param_name, params[2]);
2778    if (!param_name) return 0;
2779    eep.name = param_name;
2780    eep.type = EDJE_EXTERNAL_PARAM_TYPE_STRING;
2781    eep.s = NULL;
2782    _edje_external_param_get(NULL, rp, &eep);
2783    if (!eep.s) goto error;
2784    src_len = strlen(eep.s);
2785    if (src_len < dst_len)
2786      {
2787         SETSTR(eep.s, params[3]);
2788      }
2789    else
2790      {
2791         char *tmp = alloca(dst_len);
2792         memcpy(tmp, eep.s, dst_len - 1);
2793         tmp[dst_len] = '\0';
2794         SETSTR(tmp, params[3]);
2795      }
2796    return 1;
2797
2798  error:
2799    SETSTR("", params[3]);
2800    return 0;
2801 }
2802
2803 /* external_param_set_str(id, param_name[], val[]) */
2804 static Embryo_Cell
2805 _edje_embryo_fn_external_param_set_str(Embryo_Program *ep, Embryo_Cell *params)
2806 {
2807    Edje *ed;
2808    int part_id;
2809    Edje_Real_Part *rp;
2810    Edje_External_Param eep;
2811    char *param_name, *val;
2812
2813    CHKPARAM(3);
2814    ed = embryo_program_data_get(ep);
2815
2816    part_id = params[1];
2817    if (part_id < 0) return 0;
2818    rp = ed->table_parts[part_id % ed->table_parts_size];
2819
2820    GETSTR(param_name, params[2]);
2821    if (!param_name) return 0;
2822    eep.name = param_name;
2823    eep.type = EDJE_EXTERNAL_PARAM_TYPE_STRING;
2824    GETSTR(val, params[3]);
2825    if (!val) return 0;
2826    eep.s = val;
2827    return _edje_external_param_set(NULL, rp, &eep);
2828 }
2829
2830 /* external_param_get_choice_len(id, param_name[]) */
2831 static Embryo_Cell
2832 _edje_embryo_fn_external_param_get_choice_len(Embryo_Program *ep, Embryo_Cell *params)
2833 {
2834    Edje *ed;
2835    int part_id;
2836    Edje_Real_Part *rp;
2837    Edje_External_Param eep;
2838    char *param_name;
2839
2840    CHKPARAM(2);
2841    ed = embryo_program_data_get(ep);
2842
2843    part_id = params[1];
2844    if (part_id < 0) return 0;
2845    rp = ed->table_parts[part_id % ed->table_parts_size];
2846
2847    GETSTR(param_name, params[2]);
2848    if (!param_name) return 0;
2849    eep.name = param_name;
2850    eep.type = EDJE_EXTERNAL_PARAM_TYPE_CHOICE;
2851    eep.s = NULL;
2852    _edje_external_param_get(NULL, rp, &eep);
2853    if (!eep.s) return 0;
2854    return strlen(eep.s);
2855 }
2856
2857 /* external_param_get_choice(id, param_name[], val[], val_maxlen) */
2858 static Embryo_Cell
2859 _edje_embryo_fn_external_param_get_choice(Embryo_Program *ep, Embryo_Cell *params)
2860 {
2861    Edje *ed;
2862    int part_id;
2863    Edje_Real_Part *rp;
2864    Edje_External_Param eep;
2865    char *param_name;
2866    size_t src_len, dst_len;
2867
2868    CHKPARAM(4);
2869    dst_len = params[4];
2870    if (dst_len < 1) goto error;
2871
2872    ed = embryo_program_data_get(ep);
2873
2874    part_id = params[1];
2875    if (part_id < 0) goto error;
2876    rp = ed->table_parts[part_id % ed->table_parts_size];
2877
2878    GETSTR(param_name, params[2]);
2879    if (!param_name) return 0;
2880    eep.name = param_name;
2881    eep.type = EDJE_EXTERNAL_PARAM_TYPE_CHOICE;
2882    eep.s = NULL;
2883    _edje_external_param_get(NULL, rp, &eep);
2884    if (!eep.s) goto error;
2885    src_len = strlen(eep.s);
2886    if (src_len < dst_len)
2887      {
2888         SETSTR(eep.s, params[3]);
2889      }
2890    else
2891      {
2892         char *tmp = alloca(dst_len);
2893         memcpy(tmp, eep.s, dst_len - 1);
2894         tmp[dst_len] = '\0';
2895         SETSTR(tmp, params[3]);
2896      }
2897    return 1;
2898
2899  error:
2900    SETSTR("", params[3]);
2901    return 0;
2902 }
2903
2904 /* external_param_set_choice(id, param_name[], val[]) */
2905 static Embryo_Cell
2906 _edje_embryo_fn_external_param_set_choice(Embryo_Program *ep, Embryo_Cell *params)
2907 {
2908    Edje *ed;
2909    int part_id;
2910    Edje_Real_Part *rp;
2911    Edje_External_Param eep;
2912    char *param_name, *val;
2913
2914    CHKPARAM(3);
2915    ed = embryo_program_data_get(ep);
2916
2917    part_id = params[1];
2918    if (part_id < 0) return 0;
2919    rp = ed->table_parts[part_id % ed->table_parts_size];
2920
2921    GETSTR(param_name, params[2]);
2922    if (!param_name) return 0;
2923    eep.name = param_name;
2924    eep.type = EDJE_EXTERNAL_PARAM_TYPE_CHOICE;
2925    GETSTR(val, params[3]);
2926    if (!val) return 0;
2927    eep.s = val;
2928    return _edje_external_param_set(NULL, rp, &eep);
2929 }
2930
2931 /* external_param_get_bool(id, param_name[]) */
2932 static Embryo_Cell
2933 _edje_embryo_fn_external_param_get_bool(Embryo_Program *ep, Embryo_Cell *params)
2934 {
2935    Edje *ed;
2936    int part_id;
2937    Edje_Real_Part *rp;
2938    Edje_External_Param eep;
2939    char *param_name;
2940
2941    CHKPARAM(2);
2942    ed = embryo_program_data_get(ep);
2943
2944    part_id = params[1];
2945    if (part_id < 0) return 0;
2946    rp = ed->table_parts[part_id % ed->table_parts_size];
2947
2948    GETSTR(param_name, params[2]);
2949    if (!param_name) return 0;
2950    eep.name = param_name;
2951    eep.type = EDJE_EXTERNAL_PARAM_TYPE_BOOL;
2952    eep.i = 0;
2953    _edje_external_param_get(NULL, rp, &eep);
2954    return eep.i;
2955 }
2956
2957 /* external_param_set_bool(id, param_name[], val) */
2958 static Embryo_Cell
2959 _edje_embryo_fn_external_param_set_bool(Embryo_Program *ep, Embryo_Cell *params)
2960 {
2961    Edje *ed;
2962    int part_id;
2963    Edje_Real_Part *rp;
2964    Edje_External_Param eep;
2965    char *param_name;
2966
2967    CHKPARAM(3);
2968    ed = embryo_program_data_get(ep);
2969
2970    part_id = params[1];
2971    if (part_id < 0) return 0;
2972    rp = ed->table_parts[part_id % ed->table_parts_size];
2973
2974    GETSTR(param_name, params[2]);
2975    if (!param_name) return 0;
2976    eep.name = param_name;
2977    eep.type = EDJE_EXTERNAL_PARAM_TYPE_BOOL;
2978    eep.i = params[3];
2979    return _edje_external_param_set(NULL, rp, &eep);
2980 }
2981
2982 void
2983 _edje_embryo_script_init(Edje_Part_Collection *edc)
2984 {
2985    Embryo_Program *ep;
2986
2987    if (!edc) return;
2988    if (!edc->script) return;
2989    
2990    ep = edc->script;
2991    /* first advertise all the edje "script" calls */
2992    embryo_program_native_call_add(ep, "get_int", _edje_embryo_fn_get_int);
2993    embryo_program_native_call_add(ep, "set_int", _edje_embryo_fn_set_int);
2994    embryo_program_native_call_add(ep, "get_float", _edje_embryo_fn_get_float);
2995    embryo_program_native_call_add(ep, "set_float", _edje_embryo_fn_set_float);
2996    embryo_program_native_call_add(ep, "get_str", _edje_embryo_fn_get_str);
2997    embryo_program_native_call_add(ep, "get_strlen", _edje_embryo_fn_get_strlen);
2998    embryo_program_native_call_add(ep, "set_str", _edje_embryo_fn_set_str);
2999    embryo_program_native_call_add(ep, "count", _edje_embryo_fn_count);
3000    embryo_program_native_call_add(ep, "remove", _edje_embryo_fn_remove);
3001    embryo_program_native_call_add(ep, "append_int", _edje_embryo_fn_append_int);
3002    embryo_program_native_call_add(ep, "prepend_int", _edje_embryo_fn_prepend_int);
3003    embryo_program_native_call_add(ep, "insert_int", _edje_embryo_fn_insert_int);
3004    embryo_program_native_call_add(ep, "replace_int", _edje_embryo_fn_replace_int);
3005    embryo_program_native_call_add(ep, "fetch_int", _edje_embryo_fn_fetch_int);
3006    embryo_program_native_call_add(ep, "append_str", _edje_embryo_fn_append_str);
3007    embryo_program_native_call_add(ep, "prepend_str", _edje_embryo_fn_prepend_str);
3008    embryo_program_native_call_add(ep, "insert_str", _edje_embryo_fn_insert_str);
3009    embryo_program_native_call_add(ep, "replace_str", _edje_embryo_fn_replace_str);
3010    embryo_program_native_call_add(ep, "fetch_str", _edje_embryo_fn_fetch_str);
3011    embryo_program_native_call_add(ep, "append_float", _edje_embryo_fn_append_float);
3012    embryo_program_native_call_add(ep, "prepend_float", _edje_embryo_fn_prepend_float);
3013    embryo_program_native_call_add(ep, "insert_float", _edje_embryo_fn_insert_float);
3014    embryo_program_native_call_add(ep, "replace_float", _edje_embryo_fn_replace_float);
3015    embryo_program_native_call_add(ep, "fetch_float", _edje_embryo_fn_fetch_float);
3016
3017    embryo_program_native_call_add(ep, "timer", _edje_embryo_fn_timer);
3018    embryo_program_native_call_add(ep, "cancel_timer", _edje_embryo_fn_cancel_timer);
3019
3020    embryo_program_native_call_add(ep, "anim", _edje_embryo_fn_anim);
3021    embryo_program_native_call_add(ep, "cancel_anim", _edje_embryo_fn_cancel_anim);
3022
3023    embryo_program_native_call_add(ep, "emit", _edje_embryo_fn_emit);
3024    embryo_program_native_call_add(ep, "get_part_id", _edje_embryo_fn_get_part_id);
3025    embryo_program_native_call_add(ep, "set_state", _edje_embryo_fn_set_state);
3026    embryo_program_native_call_add(ep, "get_state", _edje_embryo_fn_get_state);
3027    embryo_program_native_call_add(ep, "set_tween_state", _edje_embryo_fn_set_tween_state);
3028    embryo_program_native_call_add(ep, "run_program", _edje_embryo_fn_run_program);
3029    embryo_program_native_call_add(ep, "get_drag_dir", _edje_embryo_fn_get_drag_dir);
3030    embryo_program_native_call_add(ep, "get_drag", _edje_embryo_fn_get_drag);
3031    embryo_program_native_call_add(ep, "set_drag", _edje_embryo_fn_set_drag);
3032    embryo_program_native_call_add(ep, "get_drag_size", _edje_embryo_fn_get_drag_size);
3033    embryo_program_native_call_add(ep, "set_drag_size", _edje_embryo_fn_set_drag_size);
3034    embryo_program_native_call_add(ep, "set_text", _edje_embryo_fn_set_text);
3035    embryo_program_native_call_add(ep, "get_text", _edje_embryo_fn_get_text);
3036    embryo_program_native_call_add(ep, "get_min_size", _edje_embryo_fn_get_min_size);
3037    embryo_program_native_call_add(ep, "get_max_size", _edje_embryo_fn_get_max_size);
3038    embryo_program_native_call_add(ep, "get_color_class", _edje_embryo_fn_get_color_class);
3039    embryo_program_native_call_add(ep, "set_color_class", _edje_embryo_fn_set_color_class);
3040    embryo_program_native_call_add(ep, "set_text_class", _edje_embryo_fn_set_text_class);
3041    embryo_program_native_call_add(ep, "get_text_class", _edje_embryo_fn_get_text_class);
3042    embryo_program_native_call_add(ep, "get_drag_step", _edje_embryo_fn_get_drag_step);
3043    embryo_program_native_call_add(ep, "set_drag_step", _edje_embryo_fn_set_drag_step);
3044    embryo_program_native_call_add(ep, "get_drag_page", _edje_embryo_fn_get_drag_page);
3045    embryo_program_native_call_add(ep, "set_drag_page", _edje_embryo_fn_set_drag_page);
3046    embryo_program_native_call_add(ep, "get_mouse", _edje_embryo_fn_get_mouse);
3047    embryo_program_native_call_add(ep, "get_mouse_buttons", _edje_embryo_fn_get_mouse_buttons);
3048    embryo_program_native_call_add(ep, "stop_program", _edje_embryo_fn_stop_program);
3049    embryo_program_native_call_add(ep, "stop_programs_on", _edje_embryo_fn_stop_programs_on);
3050    embryo_program_native_call_add(ep, "set_min_size", _edje_embryo_fn_set_min_size);
3051    embryo_program_native_call_add(ep, "set_max_size", _edje_embryo_fn_set_max_size);
3052    embryo_program_native_call_add(ep, "play_sample", _edje_embryo_fn_play_sample);
3053    embryo_program_native_call_add(ep, "play_tone", _edje_embryo_fn_play_tone);
3054    embryo_program_native_call_add(ep, "send_message", _edje_embryo_fn_send_message);
3055    embryo_program_native_call_add(ep, "get_geometry", _edje_embryo_fn_get_geometry);
3056    embryo_program_native_call_add(ep, "custom_state", _edje_embryo_fn_custom_state);
3057    embryo_program_native_call_add(ep, "set_state_val", _edje_embryo_fn_set_state_val);
3058    embryo_program_native_call_add(ep, "get_state_val", _edje_embryo_fn_get_state_val);
3059
3060    embryo_program_native_call_add(ep, "part_swallow", _edje_embryo_fn_part_swallow);
3061
3062    embryo_program_native_call_add(ep, "external_param_get_int", _edje_embryo_fn_external_param_get_int);
3063    embryo_program_native_call_add(ep, "external_param_set_int", _edje_embryo_fn_external_param_set_int);
3064    embryo_program_native_call_add(ep, "external_param_get_float", _edje_embryo_fn_external_param_get_float);
3065    embryo_program_native_call_add(ep, "external_param_set_float", _edje_embryo_fn_external_param_set_float);
3066    embryo_program_native_call_add(ep, "external_param_get_strlen", _edje_embryo_fn_external_param_get_strlen);
3067    embryo_program_native_call_add(ep, "external_param_get_str", _edje_embryo_fn_external_param_get_str);
3068    embryo_program_native_call_add(ep, "external_param_set_str", _edje_embryo_fn_external_param_set_str);
3069    embryo_program_native_call_add(ep, "external_param_get_choice_len", _edje_embryo_fn_external_param_get_choice_len);
3070    embryo_program_native_call_add(ep, "external_param_get_choice", _edje_embryo_fn_external_param_get_choice);
3071    embryo_program_native_call_add(ep, "external_param_set_choice", _edje_embryo_fn_external_param_set_choice);
3072    embryo_program_native_call_add(ep, "external_param_get_bool", _edje_embryo_fn_external_param_get_bool);
3073    embryo_program_native_call_add(ep, "external_param_set_bool", _edje_embryo_fn_external_param_set_bool);
3074 }
3075
3076 void
3077 _edje_embryo_script_shutdown(Edje_Part_Collection *edc)
3078 {
3079    if (!edc) return;
3080    if (!edc->script) return;
3081    if (embryo_program_recursion_get(edc->script) > 0) return;
3082    embryo_program_free(edc->script);
3083    edc->script = NULL;
3084 }
3085
3086 void
3087 _edje_embryo_script_reset(Edje *ed)
3088 {
3089    if (!ed) return;
3090    if (!ed->collection) return;
3091    if (!ed->collection->script) return;
3092    if (embryo_program_recursion_get(ed->collection->script) > 0) return;
3093    embryo_program_vm_reset(ed->collection->script);
3094    _edje_embryo_globals_init(ed);
3095 }
3096
3097 /* this may change in future - thus "test_run" is its name */
3098 void
3099 _edje_embryo_test_run(Edje *ed, const char *fname, const char *sig, const char *src)
3100 {
3101    Embryo_Function fn;
3102
3103    if (!ed) return;
3104    if (!ed->collection) return;
3105    if (!ed->collection->script) return;
3106    embryo_program_vm_push(ed->collection->script);
3107    _edje_embryo_globals_init(ed);
3108
3109    //   _edje_embryo_script_reset(ed);
3110    fn = embryo_program_function_find(ed->collection->script, (char *)fname);
3111    if (fn != EMBRYO_FUNCTION_NONE)
3112      {
3113         void *pdata;
3114         int ret;
3115
3116         embryo_parameter_string_push(ed->collection->script, (char *)sig);
3117         embryo_parameter_string_push(ed->collection->script, (char *)src);
3118         pdata = embryo_program_data_get(ed->collection->script);
3119         embryo_program_data_set(ed->collection->script, ed);
3120         /* 5 million instructions is an arbitrary number. on my p4-2.6 here */
3121         /* IF embryo is ONLY running embryo stuff and NO native calls thats */
3122         /* about 0.016 seconds, and longer on slower cpu's. if a simple */
3123         /* embryo script snippet hasn't managed to do its work in 5 MILLION */
3124         /* embryo virtual machine instructions - something is wrong, or */
3125         /* embryo is simply being mis-used. Embryo is meant to be minimal */
3126         /* logic enhancment - not entire applications. this cycle count */
3127         /* does NOT include time spent in native function calls, that the */
3128         /* script may call to do the REAL work, so in terms of time this */
3129         /* will likely end up being much longer than 0.016 seconds - more */
3130         /* like 0.03 - 0.05 seconds or even more */
3131         embryo_program_max_cycle_run_set(ed->collection->script, 5000000);
3132         ret = embryo_program_run(ed->collection->script, fn);
3133         if (ret == EMBRYO_PROGRAM_FAIL)
3134           {
3135              ERR("ERROR with embryo script. "
3136                  "OBJECT NAME: '%s', "
3137                  "OBJECT FILE: '%s', "
3138                  "ENTRY POINT: '%s', "
3139                  "SIGNAL: '%s', "
3140                  "SOURCE: '%s', "
3141                  "ERROR: '%s'",
3142                  ed->collection->part,
3143                  ed->file->path,
3144                  fname,
3145                  sig, src,
3146                  embryo_error_string_get(embryo_program_error_get(ed->collection->script)));
3147           }
3148         else if (ret == EMBRYO_PROGRAM_TOOLONG)
3149           {
3150              ERR("ERROR with embryo script. "
3151                  "OBJECT NAME: '%s', "
3152                  "OBJECT FILE: '%s', "
3153                  "ENTRY POINT: '%s', "
3154                  "SIGNAL: '%s', "
3155                  "SOURCE: '%s', "
3156                  "ERROR: 'Script exceeded maximum allowed cycle count of %i'",
3157                  ed->collection->part,
3158                  ed->file->path,
3159                  fname,
3160                  sig, src,
3161                  embryo_program_max_cycle_run_get(ed->collection->script));
3162           }
3163         embryo_program_data_set(ed->collection->script, pdata);
3164      }
3165    embryo_program_vm_pop(ed->collection->script);
3166 }
3167
3168 void
3169 _edje_embryo_globals_init(Edje *ed)
3170 {
3171    int n, i;
3172    Embryo_Program *ep;
3173
3174    ep = ed->collection->script;
3175    n = embryo_program_variable_count_get(ep);
3176    for (i = 0; i < n; i++)
3177      {
3178         Embryo_Cell cell, *cptr;
3179
3180         cell = embryo_program_variable_get(ep, i);
3181         if (cell != EMBRYO_CELL_NONE)
3182           {
3183              cptr = embryo_data_address_get(ep, cell);
3184              if (cptr) *cptr = EDJE_VAR_MAGIC_BASE + i;
3185           }
3186      }
3187 }