New embryo function: get_program_id
[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 /* get_program_id(program[]) */
832 static Embryo_Cell
833 _edje_embryo_fn_get_program_id(Embryo_Program *ep, Embryo_Cell *params)
834 {
835    Edje *ed;
836    Edje_Program **prog;
837    char *p;
838    int i;
839
840    CHKPARAM(1);
841    ed = embryo_program_data_get(ep);
842    GETSTR(p, params[1]);
843    if (!p) return -1;
844    prog = ed->table_programs;
845    if (!prog) return -1;
846    for (i = 0; i < ed->table_programs_size; i++, prog++)
847      {
848         if (!(*prog)->name) continue;
849         if (!strcmp((*prog)->name, p)) return (*prog)->id;
850      }
851    return -1;
852 }
853
854 static Embryo_Cell
855 _edje_embryo_fn_play_sample(Embryo_Program *ep, Embryo_Cell *params)
856 {
857    Edje *ed;
858    char *sample_name = NULL;
859    float speed = 1.0;
860
861    CHKPARAM(1);
862    ed = embryo_program_data_get(ep);
863    GETSTR(sample_name, params[1]);
864    if ((!sample_name)) return 0;
865    speed = EMBRYO_CELL_TO_FLOAT(params[2]);
866    _edje_multisense_internal_sound_sample_play(ed, sample_name, (double)speed);
867    return 0;
868 }
869
870 static Embryo_Cell
871 _edje_embryo_fn_play_tone(Embryo_Program *ep, Embryo_Cell *params)
872 {
873    Edje *ed;
874    char *tone_name = NULL;
875    float duration = 0.1;
876
877    CHKPARAM(2);
878    ed = embryo_program_data_get(ep);
879    GETSTR(tone_name, params[1]);
880    if ((!tone_name)) return 0;
881    duration = EMBRYO_CELL_TO_FLOAT(params[2]);
882    _edje_multisense_internal_sound_tone_play(ed, tone_name, (double) duration);
883    return 0;
884 }
885
886 /* set_state(part_id, state[], Float:state_val) */
887 static Embryo_Cell
888 _edje_embryo_fn_set_state(Embryo_Program *ep, Embryo_Cell *params)
889 {
890    Edje *ed;
891    char *state = NULL;
892    int part_id = 0;
893    float f = 0.0;
894    double value = 0.0;
895    Edje_Real_Part *rp;
896
897    if (!(HASNPARAMS(2) || HASNPARAMS(3))) return -1;
898
899    ed = embryo_program_data_get(ep);
900    GETSTR(state, params[2]);
901    if ((!state)) return 0;
902    part_id = params[1];
903    if (part_id < 0) return 0;
904    if (HASNPARAMS(3))
905      {
906         f = EMBRYO_CELL_TO_FLOAT(params[3]);
907         value = (double)f;
908      }
909    else
910      value = 0.0;
911    rp = ed->table_parts[part_id % ed->table_parts_size];
912    if (rp)
913      {
914         if (rp->program) _edje_program_end(ed, rp->program);
915         _edje_part_description_apply(ed, rp, state, value, NULL, 0.0);
916         _edje_part_pos_set(ed, rp, EDJE_TWEEN_MODE_LINEAR, ZERO, ZERO, ZERO);
917         _edje_recalc(ed);
918      }
919    return 0;
920 }
921
922 /* get_state(part_id, dst[], maxlen, &Float:val) */
923 static Embryo_Cell
924 _edje_embryo_fn_get_state(Embryo_Program *ep, Embryo_Cell *params)
925 {
926    Edje *ed;
927    int part_id = 0;
928    Edje_Real_Part *rp;
929    const char *s;
930
931    CHKPARAM(4);
932    ed = embryo_program_data_get(ep);
933    part_id = params[1];
934    if (part_id < 0) return 0;
935    rp = ed->table_parts[part_id % ed->table_parts_size];
936    if (rp->chosen_description)
937      {
938         SETFLOAT(rp->chosen_description->state.value, params[4]);
939         s = rp->chosen_description->state.name;
940         if (s)
941           {
942              if ((int) strlen(s) < params[3])
943                {
944                   SETSTR(s, params[2]);
945                }
946              else
947                {
948                   char *ss;
949
950                   ss = alloca(strlen(s) + 1);
951                   strcpy(ss, s);
952                   ss[params[3] - 1] = 0;
953                   SETSTR(ss, params[2]);
954                }
955           }
956         else
957           {
958              SETSTR("", params[2]);
959           }
960      }
961    else
962      {
963         SETFLOAT(0.0, params[4]);
964         SETSTR("", params[2]);
965      }
966    return 0;
967 }
968
969 /* set_tween_state(part_id, Float:tween, state1[], Float:state1_val, state2[], Float:state2_val) */
970 static Embryo_Cell
971 _edje_embryo_fn_set_tween_state(Embryo_Program *ep, Embryo_Cell *params)
972 {
973    Edje *ed;
974    char *state1 = NULL, *state2 = NULL;
975    int part_id = 0;
976    float f = 0.0;
977    double tween = 0.0, value1 = 0.0, value2 = 0.0;
978    Edje_Real_Part *rp;
979
980    CHKPARAM(6);
981    ed = embryo_program_data_get(ep);
982    GETSTR(state1, params[3]);
983    GETSTR(state2, params[5]);
984    if ((!state1) || (!state2)) return 0;
985    part_id = params[1];
986    if (part_id < 0) return 0;
987    f = EMBRYO_CELL_TO_FLOAT(params[2]);
988    tween = (double)f;
989    f = EMBRYO_CELL_TO_FLOAT(params[4]);
990    value1 = (double)f;
991    f = EMBRYO_CELL_TO_FLOAT(params[6]);
992    value2 = (double)f;
993    rp = ed->table_parts[part_id % ed->table_parts_size];
994    if (rp)
995      {
996         if (rp->program) _edje_program_end(ed, rp->program);
997         _edje_part_description_apply(ed, rp, state1, value1, state2, value2);
998         _edje_part_pos_set(ed, rp, EDJE_TWEEN_MODE_LINEAR, FROM_DOUBLE(tween), ZERO, ZERO);
999         _edje_recalc(ed);
1000      }
1001    return 0;
1002 }
1003
1004 /* run_program(program_id) */
1005 static Embryo_Cell
1006 _edje_embryo_fn_run_program(Embryo_Program *ep, Embryo_Cell *params)
1007 {
1008    Edje *ed;
1009    int program_id = 0;
1010    Edje_Program *pr;
1011
1012    CHKPARAM(1);
1013    ed = embryo_program_data_get(ep);
1014    program_id = params[1];
1015    if (program_id < 0) return 0;
1016    pr = ed->table_programs[program_id % ed->table_programs_size];
1017    if (pr)
1018      {
1019         _edje_program_run(ed, pr, 0, "", "");
1020      }
1021    return 0;
1022 }
1023
1024 /* get_drag_dir(part_id) */
1025 static Embryo_Cell
1026 _edje_embryo_fn_get_drag_dir(Embryo_Program *ep, Embryo_Cell *params)
1027 {
1028    Edje *ed;
1029    int part_id = 0;
1030    Edje_Real_Part *rp;
1031
1032    CHKPARAM(1);
1033    ed = embryo_program_data_get(ep);
1034    part_id = params[1];
1035    if (part_id < 0) return 0;
1036    rp = ed->table_parts[part_id % ed->table_parts_size];
1037    return edje_object_part_drag_dir_get(ed->obj, rp->part->name);
1038 }
1039
1040 /* get_drag(part_id, &Float:dx, &Float:dy) */
1041 static Embryo_Cell
1042 _edje_embryo_fn_get_drag(Embryo_Program *ep, Embryo_Cell *params)
1043 {
1044    Edje *ed;
1045    int part_id = 0;
1046    Edje_Real_Part *rp;
1047    double dx = 0.0, dy = 0.0;
1048
1049    CHKPARAM(3);
1050    ed = embryo_program_data_get(ep);
1051    part_id = params[1];
1052    if (part_id < 0) return 0;
1053    rp = ed->table_parts[part_id % ed->table_parts_size];
1054    edje_object_part_drag_value_get(ed->obj, rp->part->name, &dx, &dy);
1055    SETFLOAT(dx, params[2]);
1056    SETFLOAT(dy, params[3]);
1057
1058    return 0;
1059 }
1060
1061 /* set_drag(part_id, Float:dx, Float:dy) */
1062 static Embryo_Cell
1063 _edje_embryo_fn_set_drag(Embryo_Program *ep, Embryo_Cell *params)
1064 {
1065    Edje *ed;
1066    int part_id = 0;
1067    Edje_Real_Part *rp;
1068
1069    CHKPARAM(3);
1070    ed = embryo_program_data_get(ep);
1071    part_id = params[1];
1072    if (part_id < 0) return 0;
1073    rp = ed->table_parts[part_id % ed->table_parts_size];
1074    edje_object_part_drag_value_set(ed->obj, rp->part->name,
1075                                    (double)EMBRYO_CELL_TO_FLOAT(params[2]),
1076                                    (double)EMBRYO_CELL_TO_FLOAT(params[3]));
1077    return(0);
1078 }
1079
1080 /* get_drag_size(part_id, &Float:dx, &Float:dy) */
1081 static Embryo_Cell
1082 _edje_embryo_fn_get_drag_size(Embryo_Program *ep, Embryo_Cell *params)
1083 {
1084    Edje *ed;
1085    int part_id = 0;
1086    Edje_Real_Part *rp;
1087    double dx = 0.0, dy = 0.0;
1088
1089    CHKPARAM(3);
1090    ed = embryo_program_data_get(ep);
1091    part_id = params[1];
1092    if (part_id < 0) return 0;
1093    rp = ed->table_parts[part_id % ed->table_parts_size];
1094    edje_object_part_drag_size_get(ed->obj, rp->part->name, &dx, &dy);
1095    SETFLOAT(dx, params[2]);
1096    SETFLOAT(dy, params[3]);
1097
1098    return 0;
1099 }
1100
1101 /* set_drag_size(part_id, Float:dx, Float:dy) */
1102 static Embryo_Cell
1103 _edje_embryo_fn_set_drag_size(Embryo_Program *ep, Embryo_Cell *params)
1104 {
1105    Edje *ed;
1106    int part_id = 0;
1107    Edje_Real_Part *rp;
1108
1109    CHKPARAM(3);
1110    ed = embryo_program_data_get(ep);
1111    part_id = params[1];
1112    if (part_id < 0) return 0;
1113    rp = ed->table_parts[part_id % ed->table_parts_size];
1114    edje_object_part_drag_size_set(ed->obj, rp->part->name,
1115                                    (double)EMBRYO_CELL_TO_FLOAT(params[2]),
1116                                    (double)EMBRYO_CELL_TO_FLOAT(params[3]));
1117    return(0);
1118 }
1119
1120 /* set_text(part_id, str[]) */
1121 static Embryo_Cell
1122 _edje_embryo_fn_set_text(Embryo_Program *ep, Embryo_Cell *params)
1123 {
1124    Edje *ed;
1125    int part_id = 0;
1126    Edje_Real_Part *rp;
1127    char *s;
1128
1129    CHKPARAM(2);
1130    ed = embryo_program_data_get(ep);
1131    part_id = params[1];
1132    if (part_id < 0) return 0;
1133    rp = ed->table_parts[part_id % ed->table_parts_size];
1134    GETSTR(s, params[2]);
1135    if (s){
1136      edje_object_part_text_set(ed->obj, rp->part->name, s);
1137    }
1138    return(0);
1139 }
1140
1141 /* get_text(part_id, dst[], maxlen) */
1142 static Embryo_Cell
1143 _edje_embryo_fn_get_text(Embryo_Program *ep, Embryo_Cell *params)
1144 {
1145    Edje *ed;
1146    int part_id = 0;
1147    Edje_Real_Part *rp;
1148    char *s;
1149
1150    CHKPARAM(3);
1151    ed = embryo_program_data_get(ep);
1152    part_id = params[1];
1153    if (part_id < 0) return 0;
1154    rp = ed->table_parts[part_id % ed->table_parts_size];
1155    s = (char *)edje_object_part_text_get(ed->obj, rp->part->name);
1156    if (s)
1157      {
1158         if ((int) strlen(s) < params[3])
1159           {
1160              SETSTR(s, params[2]);
1161           }
1162         else
1163           {
1164              char *ss;
1165
1166              ss = alloca(strlen(s) + 1);
1167              strcpy(ss, s);
1168              ss[params[3] - 1] = 0;
1169              SETSTR(ss, params[2]);
1170           }
1171      }
1172    else
1173      {
1174         SETSTR("", params[2]);
1175      }
1176    return 0;
1177 }
1178
1179 /* get_min_size(&w, &h) */
1180 static Embryo_Cell
1181 _edje_embryo_fn_get_min_size(Embryo_Program *ep, Embryo_Cell *params)
1182 {
1183    Edje *ed;
1184    Evas_Coord w = 0, h = 0;
1185
1186    CHKPARAM(2);
1187    ed = embryo_program_data_get(ep);
1188    edje_object_size_min_get(ed->obj, &w, &h);
1189    SETINT(w, params[1]);
1190    SETINT(h, params[2]);
1191    return 0;
1192 }
1193
1194 /* get_max_size(&w, &h) */
1195 static Embryo_Cell
1196 _edje_embryo_fn_get_max_size(Embryo_Program *ep, Embryo_Cell *params)
1197 {
1198    Edje *ed;
1199    Evas_Coord w = 0, h = 0;
1200
1201    CHKPARAM(2);
1202    ed = embryo_program_data_get(ep);
1203    edje_object_size_max_get(ed->obj, &w, &h);
1204    SETINT(w, params[1]);
1205    SETINT(h, params[2]);
1206    return 0;
1207
1208 }
1209
1210 /* get_color_class(class[], &r, &g, &b, &a) */
1211 static Embryo_Cell
1212 _edje_embryo_fn_get_color_class(Embryo_Program *ep, Embryo_Cell *params)
1213 {
1214    Edje *ed;
1215    Edje_Color_Class *c_class;
1216    char *class;
1217
1218    CHKPARAM(5);
1219    ed = embryo_program_data_get(ep);
1220    GETSTR(class, params[1]);
1221    if (!class) return 0;
1222    c_class = _edje_color_class_find(ed, class);
1223    if (!c_class) return 0;
1224    SETINT(c_class->r, params[2]);
1225    SETINT(c_class->g, params[3]);
1226    SETINT(c_class->b, params[4]);
1227    SETINT(c_class->a, params[5]);
1228    return 0;
1229 }
1230
1231 /* set_color_class(class[], r, g, b, a) */
1232 static Embryo_Cell
1233 _edje_embryo_fn_set_color_class(Embryo_Program *ep, Embryo_Cell *params)
1234 {
1235    Edje *ed;
1236    char *class;
1237
1238    CHKPARAM(5);
1239    ed = embryo_program_data_get(ep);
1240    GETSTR(class, params[1]);
1241    if (!class) return 0;
1242    edje_object_color_class_set(ed->obj, class, params[2], params[3], params[4], params[5],
1243                                params[2], params[3], params[4], params[5],
1244                                params[2], params[3], params[4], params[5]);
1245    return 0;
1246 }
1247
1248 /* set_text_class(class[], font[], Float:size) */
1249 static Embryo_Cell
1250 _edje_embryo_fn_set_text_class(Embryo_Program *ep, Embryo_Cell *params)
1251 {
1252    Edje *ed;
1253    char *class, *font;
1254    Evas_Font_Size fsize;
1255
1256    CHKPARAM(3);
1257    ed = embryo_program_data_get(ep);
1258    GETSTR(class, params[1]);
1259    GETSTR(font, params[2]);
1260    if( !class || !font ) return 0;
1261    fsize = (Evas_Font_Size) EMBRYO_CELL_TO_FLOAT(params[3]);
1262    edje_object_text_class_set(ed->obj, class, font, fsize);
1263    return 0;
1264 }
1265
1266 /* get_text_class(class[], font[], &Float:size) */
1267 static Embryo_Cell
1268 _edje_embryo_fn_get_text_class(Embryo_Program *ep, Embryo_Cell *params)
1269 {
1270    Edje *ed;
1271    char *class;
1272    Edje_Text_Class *t_class;
1273
1274    CHKPARAM(3);
1275    ed = embryo_program_data_get(ep);
1276    GETSTR(class, params[1]);
1277    if (!class) return 0;
1278    t_class = _edje_text_class_find(ed, class);
1279    if (!t_class) return 0;
1280    SETSTR((char *)t_class->font, params[2]);
1281    SETFLOAT(t_class->size, params[3]);
1282    return 0;
1283 }
1284
1285 /* get_drag_step(part_id, &Float:dx, &Float:&dy) */
1286 static Embryo_Cell
1287 _edje_embryo_fn_get_drag_step(Embryo_Program *ep, Embryo_Cell *params)
1288 {
1289    Edje *ed;
1290    int part_id = 0;
1291    Edje_Real_Part *rp;
1292    double dx = 0.0, dy = 0.0;
1293
1294    CHKPARAM(3);
1295    ed = embryo_program_data_get(ep);
1296    part_id = params[1];
1297    if (part_id < 0) return 0;
1298    rp = ed->table_parts[part_id % ed->table_parts_size];
1299    edje_object_part_drag_step_get(ed->obj, rp->part->name, &dx, &dy);
1300    SETFLOAT(dx, params[2]);
1301    SETFLOAT(dy, params[3]);
1302
1303    return 0;
1304 }
1305
1306 /* set_drag_step(part_id, Float:dx, Float:dy) */
1307 static Embryo_Cell
1308 _edje_embryo_fn_set_drag_step(Embryo_Program *ep, Embryo_Cell *params)
1309 {
1310    Edje *ed;
1311    int part_id = 0;
1312    Edje_Real_Part *rp;
1313
1314    CHKPARAM(3);
1315    ed = embryo_program_data_get(ep);
1316    part_id = params[1];
1317    if (part_id < 0) return 0;
1318    rp = ed->table_parts[part_id % ed->table_parts_size];
1319    edje_object_part_drag_step_set(ed->obj, rp->part->name,
1320                                   (double)EMBRYO_CELL_TO_FLOAT(params[2]),
1321                                   (double)EMBRYO_CELL_TO_FLOAT(params[3]));
1322    return(0);
1323 }
1324
1325 /* get_drag_page(part_id, &Float:dx, &Float:&dy) */
1326 static Embryo_Cell
1327 _edje_embryo_fn_get_drag_page(Embryo_Program *ep, Embryo_Cell *params)
1328 {
1329    Edje *ed;
1330    int part_id = 0;
1331    Edje_Real_Part *rp;
1332    double dx = 0.0, dy = 0.0;
1333
1334    CHKPARAM(3);
1335    ed = embryo_program_data_get(ep);
1336    part_id = params[1];
1337    if (part_id < 0) return 0;
1338    rp = ed->table_parts[part_id % ed->table_parts_size];
1339    edje_object_part_drag_page_get(ed->obj, rp->part->name, &dx, &dy);
1340    SETFLOAT(dx, params[2]);
1341    SETFLOAT(dy, params[3]);
1342
1343    return 0;
1344 }
1345
1346 /* get_geometry(pard_id, &x, &y, &w, &h) */
1347 static Embryo_Cell
1348 _edje_embryo_fn_get_geometry(Embryo_Program *ep, Embryo_Cell *params)
1349 {
1350    Edje *ed;
1351    int part_id = 0;
1352    Edje_Real_Part *rp;
1353    Evas_Coord x = 0.0, y = 0.0, w = 0.0, h = 0.0;
1354
1355    CHKPARAM(5);
1356    ed = embryo_program_data_get(ep);
1357    part_id = params[1];
1358    if (part_id < 0) return 0;
1359    rp = ed->table_parts[part_id % ed->table_parts_size];
1360    edje_object_part_geometry_get(ed->obj, rp->part->name, &x, &y, &w, &h);
1361    SETINT(x, params[2]);
1362    SETINT(y, params[3]);
1363    SETINT(w, params[4]);
1364    SETINT(h, params[5]);
1365
1366    return 0;
1367 }
1368
1369 /* set_drag_page(part_id, Float:dx, Float:dy) */
1370 static Embryo_Cell
1371 _edje_embryo_fn_set_drag_page(Embryo_Program *ep, Embryo_Cell *params)
1372 {
1373    Edje *ed;
1374    int part_id = 0;
1375    Edje_Real_Part *rp;
1376
1377    CHKPARAM(3);
1378    ed = embryo_program_data_get(ep);
1379    part_id = params[1];
1380    if (part_id < 0) return 0;
1381    rp = ed->table_parts[part_id % ed->table_parts_size];
1382    edje_object_part_drag_page_set(ed->obj, rp->part->name,
1383                                   (double)EMBRYO_CELL_TO_FLOAT(params[2]),
1384                                   (double)EMBRYO_CELL_TO_FLOAT(params[3]));
1385    return(0);
1386 }
1387
1388 /* send_message(Msg_Type:type, id,...); */
1389 static Embryo_Cell
1390 _edje_embryo_fn_send_message(Embryo_Program *ep, Embryo_Cell *params)
1391 {
1392    Edje *ed;
1393    Edje_Message_Type type;
1394    int id, i, n;
1395    Embryo_Cell *ptr;
1396
1397    if (params[0] < (int) (sizeof(Embryo_Cell) * (2))) return 0;
1398    ed = embryo_program_data_get(ep);
1399    type = params[1];
1400    id = params[2];
1401    switch (type)
1402      {
1403       case EDJE_MESSAGE_NONE:
1404         _edje_message_send(ed, EDJE_QUEUE_APP, type, id, NULL);
1405         break;
1406       case EDJE_MESSAGE_SIGNAL:
1407         break;
1408       case EDJE_MESSAGE_STRING:
1409           {
1410              Embryo_Cell *cptr;
1411
1412              cptr = embryo_data_address_get(ep, params[3]);
1413              if (cptr)
1414                {
1415                   Edje_Message_String *emsg;
1416                   int l;
1417                   char *s;
1418
1419                   l = embryo_data_string_length_get(ep, cptr);
1420                   s = alloca(l + 1);
1421                   s[0] = 0;
1422                   embryo_data_string_get(ep, cptr, s);
1423                   emsg = alloca(sizeof(Edje_Message_String));
1424                   emsg->str = s;
1425                   _edje_message_send(ed, EDJE_QUEUE_APP, type, id, emsg);
1426                }
1427           }
1428         break;
1429       case EDJE_MESSAGE_INT:
1430           {
1431              Edje_Message_Int *emsg;
1432
1433              emsg = alloca(sizeof(Edje_Message_Int));
1434              ptr = embryo_data_address_get(ep, params[3]);
1435              if (ptr) emsg->val = (int)*ptr;
1436              else emsg->val = 0;
1437              _edje_message_send(ed, EDJE_QUEUE_APP, type, id, emsg);
1438           }
1439         break;
1440       case EDJE_MESSAGE_FLOAT:
1441           {
1442              Edje_Message_Float *emsg;
1443              float f;
1444
1445              emsg = alloca(sizeof(Edje_Message_Float));
1446              ptr = embryo_data_address_get(ep, params[3]);
1447              if (ptr)
1448                 {
1449                    f = EMBRYO_CELL_TO_FLOAT(*ptr);
1450                    emsg->val = (double)f;
1451                 }
1452              else
1453                 emsg->val = 0.0;
1454              _edje_message_send(ed, EDJE_QUEUE_APP, type, id, emsg);
1455           }
1456         break;
1457       case EDJE_MESSAGE_STRING_SET:
1458           {
1459              Edje_Message_String_Set *emsg;
1460
1461              n = (params[0] / sizeof(Embryo_Cell)) + 1;
1462              emsg = alloca(sizeof(Edje_Message_String_Set) + ((n - 3 - 1) * sizeof(char *)));
1463              emsg->count = n - 3;
1464              for (i = 3; i < n; i++)
1465                {
1466                   Embryo_Cell *cptr;
1467
1468                   cptr = embryo_data_address_get(ep, params[i]);
1469                   if (cptr)
1470                     {
1471                        int l;
1472                        char *s;
1473
1474                        l = embryo_data_string_length_get(ep, cptr);
1475                        s = alloca(l + 1);
1476                        s[0] = 0;
1477                        embryo_data_string_get(ep, cptr, s);
1478                        emsg->str[i - 3] = s;
1479                     }
1480                }
1481              _edje_message_send(ed, EDJE_QUEUE_APP, type, id, emsg);
1482           }
1483         break;
1484       case EDJE_MESSAGE_INT_SET:
1485           {
1486              Edje_Message_Int_Set *emsg;
1487
1488              n = (params[0] / sizeof(Embryo_Cell)) + 1;
1489              emsg = alloca(sizeof(Edje_Message_Int_Set) + ((n - 3 - 1) * sizeof(int)));
1490              emsg->count = n - 3;
1491              for (i = 3; i < n; i++)
1492                {
1493                   ptr = embryo_data_address_get(ep, params[i]);
1494                   if (ptr) emsg->val[i - 3] = (int)*ptr;
1495                   else emsg->val[i - 3] = 0;
1496                }
1497              _edje_message_send(ed, EDJE_QUEUE_APP, type, id, emsg);
1498           }
1499         break;
1500       case EDJE_MESSAGE_FLOAT_SET:
1501           {
1502              Edje_Message_Float_Set *emsg;
1503
1504              n = (params[0] / sizeof(Embryo_Cell)) + 1;
1505              emsg = alloca(sizeof(Edje_Message_Float_Set) + ((n - 3 - 1) * sizeof(double)));
1506              emsg->count = n - 3;
1507              for (i = 3; i < n; i++)
1508                {
1509                   float f;
1510
1511                   ptr = embryo_data_address_get(ep, params[i]);
1512                   if (ptr)
1513                      {
1514                         f = EMBRYO_CELL_TO_FLOAT(*ptr);
1515                         emsg->val[i - 3] = (double)f;
1516                      }
1517                   else
1518                      emsg->val[i - 3] = 0.0;
1519                }
1520              _edje_message_send(ed, EDJE_QUEUE_APP, type, id, emsg);
1521           }
1522         break;
1523       case EDJE_MESSAGE_STRING_INT:
1524           {
1525              Edje_Message_String_Int *emsg;
1526              Embryo_Cell *cptr;
1527
1528              cptr = embryo_data_address_get(ep, params[3]);
1529              if (cptr)
1530                {
1531                   int l;
1532                   char *s;
1533
1534                   l = embryo_data_string_length_get(ep, cptr);
1535                   s = alloca(l + 1);
1536                   s[0] = 0;
1537                   embryo_data_string_get(ep, cptr, s);
1538                   emsg = alloca(sizeof(Edje_Message_String_Int));
1539                   emsg->str = s;
1540                   ptr = embryo_data_address_get(ep, params[4]);
1541                   if (ptr) emsg->val = (int)*ptr;
1542                   else emsg->val = 0;
1543                   _edje_message_send(ed, EDJE_QUEUE_APP, type, id, emsg);
1544                }
1545           }
1546         break;
1547       case EDJE_MESSAGE_STRING_FLOAT:
1548           {
1549              Edje_Message_String_Float *emsg;
1550              Embryo_Cell *cptr;
1551
1552              cptr = embryo_data_address_get(ep, params[3]);
1553              if (cptr)
1554                {
1555                   int l;
1556                   char *s;
1557                   float f;
1558
1559                   l = embryo_data_string_length_get(ep, cptr);
1560                   s = alloca(l + 1);
1561                   s[0] = 0;
1562                   embryo_data_string_get(ep, cptr, s);
1563                   emsg = alloca(sizeof(Edje_Message_String_Float));
1564                   emsg->str = s;
1565                   ptr = embryo_data_address_get(ep, params[4]);
1566                   if (ptr)
1567                      {
1568                         f = EMBRYO_CELL_TO_FLOAT(*ptr);
1569                         emsg->val = (double)f;
1570                      }
1571                   else
1572                      emsg->val = 0.0;
1573                   _edje_message_send(ed, EDJE_QUEUE_APP, type, id, emsg);
1574                }
1575           }
1576         break;
1577       case EDJE_MESSAGE_STRING_INT_SET:
1578           {
1579              Edje_Message_String_Int_Set *emsg;
1580              Embryo_Cell *cptr;
1581
1582              cptr = embryo_data_address_get(ep, params[3]);
1583              if (cptr)
1584                {
1585                   int l;
1586                   char *s;
1587
1588                   l = embryo_data_string_length_get(ep, cptr);
1589                   s = alloca(l + 1);
1590                   s[0] = 0;
1591                   embryo_data_string_get(ep, cptr, s);
1592                   n = (params[0] / sizeof(Embryo_Cell)) + 1;
1593                   emsg = alloca(sizeof(Edje_Message_String_Int_Set) + ((n - 4 - 1) * sizeof(int)));
1594                   emsg->str = s;
1595                   emsg->count = n - 4;
1596                   for (i = 4; i < n; i++)
1597                     {
1598                        ptr = embryo_data_address_get(ep, params[i]);
1599                        if (ptr) emsg->val[i - 4] = (int)*ptr;
1600                        else emsg->val[i - 4] = 0;
1601                     }
1602                   _edje_message_send(ed, EDJE_QUEUE_APP, type, id, emsg);
1603                }
1604           }
1605         break;
1606       case EDJE_MESSAGE_STRING_FLOAT_SET:
1607           {
1608              Edje_Message_String_Float_Set *emsg;
1609              Embryo_Cell *cptr;
1610
1611              cptr = embryo_data_address_get(ep, params[3]);
1612              if (cptr)
1613                {
1614                   int l;
1615                   char *s;
1616
1617                   l = embryo_data_string_length_get(ep, cptr);
1618                   s = alloca(l + 1);
1619                   s[0] = 0;
1620                   embryo_data_string_get(ep, cptr, s);
1621                   n = (params[0] / sizeof(Embryo_Cell)) + 1;
1622                   emsg = alloca(sizeof(Edje_Message_String_Float_Set) + ((n - 4 - 1) * sizeof(double)));
1623                   emsg->str = s;
1624                   emsg->count = n - 4;
1625                   for (i = 4; i < n; i++)
1626                     {
1627                        float f;
1628
1629                        ptr = embryo_data_address_get(ep, params[i]);
1630                        if (ptr)
1631                          {
1632                             f = EMBRYO_CELL_TO_FLOAT(*ptr);
1633                             emsg->val[i - 4] = (double)f;
1634                          }
1635                        else
1636                           emsg->val[i - 4] = 0.0;
1637                     }
1638                   _edje_message_send(ed, EDJE_QUEUE_APP, type, id, emsg);
1639                }
1640           }
1641         break;
1642       default:
1643         break;
1644      }
1645    return(0);
1646 }
1647
1648 /* custom_state(part_id, state[], Float:state_val = 0.0) */
1649 static Embryo_Cell
1650 _edje_embryo_fn_custom_state(Embryo_Program *ep, Embryo_Cell *params)
1651 {
1652    Edje *ed = embryo_program_data_get(ep);
1653    Edje_Real_Part *rp;
1654    Edje_Part_Description_Common *parent, *d = NULL;
1655    char *name;
1656    float val;
1657
1658    CHKPARAM(3);
1659
1660    if (params[1] < 0)
1661      return 0;
1662
1663    if (!(rp = ed->table_parts[params[1] % ed->table_parts_size]))
1664      return 0;
1665
1666    /* check whether this part already has a "custom" state */
1667    if (rp->custom)
1668      return 0;
1669
1670    GETSTR(name, params[2]);
1671    if (!name)
1672      return 0;
1673
1674    val = EMBRYO_CELL_TO_FLOAT(params[3]);
1675
1676    if (!(parent = _edje_part_description_find(ed, rp, name, val)))
1677      return 0;
1678
1679    /* now create the custom state */
1680    switch (rp->part->type)
1681      {
1682 #define ALLOC_DESC(Short, Type, To)                                     \
1683         case EDJE_PART_TYPE_##Short: To = calloc(1, sizeof (Edje_Part_Description_##Type)); break;
1684
1685 #define ALLOC_COPY_DESC(Short, Type, To, Spec)                          \
1686         case EDJE_PART_TYPE_##Short:                                    \
1687           {                                                             \
1688              Edje_Part_Description_##Type *tmp;                         \
1689              Edje_Part_Description_##Type *new;                         \
1690                                                                         \
1691              tmp = (Edje_Part_Description_##Type *) parent;             \
1692                                                                         \
1693              new = calloc(1, sizeof (Edje_Part_Description_##Type));    \
1694              new->Spec = tmp->Spec;                                     \
1695              d = &new->common;                                          \
1696              break;                                                     \
1697           }
1698
1699         ALLOC_DESC(RECTANGLE, Common, d);
1700         ALLOC_DESC(SPACER, Common, d);
1701         ALLOC_DESC(SWALLOW, Common, d);
1702         ALLOC_DESC(GROUP, Common, d);
1703
1704         ALLOC_COPY_DESC(IMAGE, Image, d, image);
1705         ALLOC_COPY_DESC(PROXY, Proxy, d, proxy);
1706         ALLOC_COPY_DESC(TEXT, Text, d, text);
1707         ALLOC_COPY_DESC(TEXTBLOCK, Text, d, text);
1708         ALLOC_COPY_DESC(BOX, Box, d, box);
1709         ALLOC_COPY_DESC(TABLE, Table, d, table);
1710         ALLOC_COPY_DESC(EXTERNAL, External, d, external_params);
1711      }
1712
1713    if (!d) return 0;
1714
1715    rp->custom = eina_mempool_malloc(_edje_real_part_state_mp, sizeof (Edje_Real_Part_State));
1716    if (!rp->custom)
1717      {
1718         free(d);
1719         return 0;
1720      }
1721
1722    memset(rp->custom, 0, sizeof (Edje_Real_Part_State));
1723
1724    *d = *parent;
1725
1726    d->state.name = (char *)eina_stringshare_add("custom");
1727    d->state.value = 0.0;
1728
1729    /* make sure all the allocated memory is getting copied,
1730     * not just referenced
1731     */
1732    if (rp->part->type == EDJE_PART_TYPE_IMAGE)
1733      {
1734         Edje_Part_Description_Image *img_desc;
1735         Edje_Part_Description_Image *parent_img_desc;
1736
1737         img_desc = (Edje_Part_Description_Image*) d;
1738         parent_img_desc = (Edje_Part_Description_Image*) parent;
1739
1740         img_desc->image.tweens_count = parent_img_desc->image.tweens_count;
1741         img_desc->image.tweens = calloc(img_desc->image.tweens_count,
1742                                         sizeof(Edje_Part_Image_Id*));
1743         if (img_desc->image.tweens)
1744           {
1745              unsigned int i;
1746
1747              for (i = 0; i < parent_img_desc->image.tweens_count; ++i)
1748                {
1749                   Edje_Part_Image_Id *iid_new;
1750
1751                   iid_new = calloc(1, sizeof(Edje_Part_Image_Id));
1752                   if (!iid_new) continue;
1753
1754                   *iid_new = *parent_img_desc->image.tweens[i];
1755
1756                   img_desc->image.tweens[i] = iid_new;
1757                }
1758           }
1759      }
1760
1761 #define DUP(x) x ? (char *)eina_stringshare_add(x) : NULL
1762    d->color_class = DUP(d->color_class);
1763
1764    if (rp->part->type == EDJE_PART_TYPE_TEXT
1765        || rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
1766      {
1767         Edje_Part_Description_Text *text_desc;
1768
1769         text_desc = (Edje_Part_Description_Text*) d;
1770
1771         text_desc->text.text_class = DUP(text_desc->text.text_class);
1772         text_desc->text.text.str = DUP(edje_string_get(&text_desc->text.text));
1773         text_desc->text.text.id = 0;
1774         text_desc->text.font.str = DUP(edje_string_get(&text_desc->text.font));
1775         text_desc->text.font.id = 0;
1776         text_desc->text.style.str = DUP(edje_string_get(&text_desc->text.style));
1777         text_desc->text.style.id = 0;
1778      }
1779 #undef DUP
1780
1781    rp->custom->description = d;
1782
1783    return 0;
1784 }
1785
1786 /* set_state_val(part_id, State_Param:p, ...) */
1787 static Embryo_Cell
1788 _edje_embryo_fn_set_state_val(Embryo_Program *ep, Embryo_Cell *params)
1789 {
1790    Edje *ed = embryo_program_data_get(ep);
1791    Edje_Real_Part *rp;
1792    char *s;
1793
1794    /* we need at least 3 arguments */
1795    if (params[0] < (int) (sizeof(Embryo_Cell) * 3))
1796      return 0;
1797
1798    if (params[1] < 0)
1799      return 0;
1800
1801    if (!(rp = ed->table_parts[params[1] % ed->table_parts_size]))
1802      return 0;
1803
1804    /* check whether this part has a "custom" state */
1805    if (!rp->custom)
1806      return 0;
1807
1808    switch (params[2])
1809      {
1810       case EDJE_STATE_PARAM_ALIGNMENT:
1811          CHKPARAM(4);
1812
1813          GETFLOAT_T(rp->custom->description->align.x, params[3]);
1814          GETFLOAT_T(rp->custom->description->align.y, params[4]);
1815
1816          break;
1817       case EDJE_STATE_PARAM_MIN:
1818          CHKPARAM(4);
1819
1820          GETINT(rp->custom->description->min.w, params[3]);
1821          GETINT(rp->custom->description->min.h, params[4]);
1822
1823          break;
1824       case EDJE_STATE_PARAM_MAX:
1825          CHKPARAM(4);
1826
1827          GETINT(rp->custom->description->max.w, params[3]);
1828          GETINT(rp->custom->description->max.h, params[4]);
1829
1830          break;
1831       case EDJE_STATE_PARAM_STEP:
1832          CHKPARAM(4);
1833
1834          GETINT(rp->custom->description->step.x, params[3]);
1835          GETINT(rp->custom->description->step.y, params[4]);
1836
1837          break;
1838       case EDJE_STATE_PARAM_ASPECT:
1839          CHKPARAM(4);
1840
1841          GETFLOAT_T(rp->custom->description->aspect.min, params[3]);
1842          GETFLOAT_T(rp->custom->description->aspect.max, params[4]);
1843
1844          break;
1845       case EDJE_STATE_PARAM_ASPECT_PREF:
1846          CHKPARAM(3);
1847
1848          GETINT(rp->custom->description->aspect.prefer, params[3]);
1849
1850          break;
1851       case EDJE_STATE_PARAM_COLOR:
1852          CHKPARAM(6);
1853
1854          GETINT(rp->custom->description->color.r, params[3]);
1855          GETINT(rp->custom->description->color.g, params[4]);
1856          GETINT(rp->custom->description->color.b, params[5]);
1857          GETINT(rp->custom->description->color.a, params[6]);
1858
1859          break;
1860       case EDJE_STATE_PARAM_COLOR2:
1861          CHKPARAM(6);
1862
1863          GETINT(rp->custom->description->color2.r, params[3]);
1864          GETINT(rp->custom->description->color2.g, params[4]);
1865          GETINT(rp->custom->description->color2.b, params[5]);
1866          GETINT(rp->custom->description->color2.a, params[6]);
1867
1868          break;
1869       case EDJE_STATE_PARAM_COLOR3:
1870         {
1871            Edje_Part_Description_Text *text;
1872
1873            if ( (rp->part->type != EDJE_PART_TYPE_TEXT) &&
1874                 (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
1875              return 0;
1876
1877            CHKPARAM(6);
1878
1879            text = (Edje_Part_Description_Text*) rp->custom->description;
1880
1881            GETINT(text->text.color3.r, params[3]);
1882            GETINT(text->text.color3.g, params[4]);
1883            GETINT(text->text.color3.b, params[5]);
1884            GETINT(text->text.color3.a, params[6]);
1885            break;
1886         }
1887       case EDJE_STATE_PARAM_COLOR_CLASS:
1888          CHKPARAM(3);
1889
1890          GETSTR(s, params[3]);
1891          GETSTREVAS(s, rp->custom->description->color_class);
1892
1893          break;
1894       case EDJE_STATE_PARAM_REL1:
1895          CHKPARAM(4);
1896
1897          GETFLOAT_T(rp->custom->description->rel1.relative_x, params[3]);
1898          GETFLOAT_T(rp->custom->description->rel1.relative_y, params[4]);
1899
1900          break;
1901       case EDJE_STATE_PARAM_REL1_TO:
1902          CHKPARAM(4);
1903
1904          GETINT(rp->custom->description->rel1.id_x, params[3]);
1905          GETINT(rp->custom->description->rel1.id_y, params[4]);
1906
1907          if (rp->param1.description->rel1.id_x >= 0)
1908            rp->param1.rel1_to_x = ed->table_parts[rp->param1.description->rel1.id_x % ed->table_parts_size];
1909          if (rp->param1.description->rel1.id_y >= 0)
1910            rp->param1.rel1_to_y = ed->table_parts[rp->param1.description->rel1.id_y % ed->table_parts_size];
1911
1912          break;
1913       case EDJE_STATE_PARAM_REL1_OFFSET:
1914          CHKPARAM(4);
1915
1916          GETINT(rp->custom->description->rel1.offset_x, params[3]);
1917          GETINT(rp->custom->description->rel1.offset_y, params[4]);
1918
1919          break;
1920       case EDJE_STATE_PARAM_REL2:
1921          CHKPARAM(4);
1922
1923          GETFLOAT_T(rp->custom->description->rel2.relative_x, params[3]);
1924          GETFLOAT_T(rp->custom->description->rel2.relative_y, params[4]);
1925
1926          break;
1927       case EDJE_STATE_PARAM_REL2_TO:
1928          CHKPARAM(4);
1929
1930          GETINT(rp->custom->description->rel2.id_x, params[3]);
1931          GETINT(rp->custom->description->rel2.id_y, params[4]);
1932
1933          if (rp->param1.description->rel2.id_x >= 0)
1934            rp->param1.rel2_to_x = ed->table_parts[rp->param1.description->rel2.id_x % ed->table_parts_size];
1935          if (rp->param1.description->rel2.id_y >= 0)
1936            rp->param1.rel2_to_y = ed->table_parts[rp->param1.description->rel2.id_y % ed->table_parts_size];
1937
1938          break;
1939       case EDJE_STATE_PARAM_REL2_OFFSET:
1940          CHKPARAM(4);
1941
1942          GETINT(rp->custom->description->rel2.offset_x, params[3]);
1943          GETINT(rp->custom->description->rel2.offset_y, params[4]);
1944
1945          break;
1946       case EDJE_STATE_PARAM_IMAGE:
1947         {
1948            Edje_Part_Description_Image *img;
1949
1950            if ( (rp->part->type != EDJE_PART_TYPE_IMAGE) ) return 0;
1951            CHKPARAM(3);
1952
1953            img = (Edje_Part_Description_Image*) rp->custom->description;
1954            GETINT(img->image.id, params[3]);
1955
1956            break;
1957         }
1958       case EDJE_STATE_PARAM_BORDER:
1959         {
1960            Edje_Part_Description_Image *img;
1961
1962            if ( (rp->part->type != EDJE_PART_TYPE_IMAGE) ) return 0;
1963            CHKPARAM(6);
1964
1965            img = (Edje_Part_Description_Image*) rp->custom->description;
1966
1967            GETINT(img->image.border.l, params[3]);
1968            GETINT(img->image.border.r, params[4]);
1969            GETINT(img->image.border.t, params[5]);
1970            GETINT(img->image.border.b, params[6]);
1971
1972            break;
1973         }
1974       case EDJE_STATE_PARAM_FILL_SMOOTH:
1975         {
1976            Edje_Part_Description_Image *img;
1977
1978            if ( (rp->part->type != EDJE_PART_TYPE_IMAGE) ) return 0;
1979            CHKPARAM(3);
1980
1981            img = (Edje_Part_Description_Image*) rp->custom->description;
1982
1983            GETINT(img->image.fill.smooth, params[3]);
1984
1985            break;
1986         }
1987       case EDJE_STATE_PARAM_FILL_POS:
1988         {
1989            Edje_Part_Description_Image *img;
1990
1991            if ( (rp->part->type != EDJE_PART_TYPE_IMAGE) ) return 0;
1992            CHKPARAM(6);
1993
1994            img = (Edje_Part_Description_Image*) rp->custom->description;
1995
1996            GETFLOAT_T(img->image.fill.pos_rel_x, params[3]);
1997            GETFLOAT_T(img->image.fill.pos_rel_y, params[4]);
1998            GETINT(img->image.fill.pos_abs_x, params[5]);
1999            GETINT(img->image.fill.pos_abs_y, params[6]);
2000
2001            break;
2002         }
2003       case EDJE_STATE_PARAM_FILL_SIZE:
2004         {
2005            Edje_Part_Description_Image *img;
2006
2007            if ( (rp->part->type != EDJE_PART_TYPE_IMAGE) ) return 0;
2008            CHKPARAM(6);
2009
2010            img = (Edje_Part_Description_Image*) rp->custom->description;
2011
2012            GETFLOAT_T(img->image.fill.rel_x, params[3]);
2013            GETFLOAT_T(img->image.fill.rel_y, params[4]);
2014            GETINT(img->image.fill.abs_x, params[5]);
2015            GETINT(img->image.fill.abs_y, params[6]);
2016
2017            break;
2018         }
2019       case EDJE_STATE_PARAM_TEXT:
2020         {
2021            Edje_Part_Description_Text *text;
2022
2023            if ( (rp->part->type != EDJE_PART_TYPE_TEXT) &&
2024                 (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
2025              return 0;
2026            CHKPARAM(3);
2027
2028            GETSTR(s, params[3]);
2029
2030            text = (Edje_Part_Description_Text*) rp->custom->description;
2031            GETSTREVAS(s, text->text.text.str);
2032
2033            break;
2034         }
2035       case EDJE_STATE_PARAM_TEXT_CLASS:
2036         {
2037            Edje_Part_Description_Text *text;
2038
2039            if ( (rp->part->type != EDJE_PART_TYPE_TEXT) &&
2040                 (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
2041              return 0;
2042            CHKPARAM(3);
2043
2044            GETSTR(s, params[3]);
2045
2046            text = (Edje_Part_Description_Text*) rp->custom->description;
2047            GETSTREVAS(s, text->text.text_class);
2048
2049            break;
2050         }
2051       case EDJE_STATE_PARAM_TEXT_FONT:
2052         {
2053            Edje_Part_Description_Text *text;
2054
2055            if ((rp->part->type != EDJE_PART_TYPE_TEXT)) return 0;
2056            CHKPARAM(3);
2057
2058            GETSTR(s, params[3]);
2059
2060            text = (Edje_Part_Description_Text*) rp->custom->description;
2061            GETSTREVAS(s, text->text.font.str);
2062
2063            break;
2064         }
2065       case EDJE_STATE_PARAM_TEXT_STYLE:
2066         {
2067            Edje_Part_Description_Text *text;
2068
2069            if ((rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)) return 0;
2070            CHKPARAM(3);
2071
2072            GETSTR(s, params[3]);
2073
2074            text = (Edje_Part_Description_Text*) rp->custom->description;
2075            GETSTREVAS(s, text->text.style.str);
2076
2077            break;
2078         }
2079       case EDJE_STATE_PARAM_TEXT_SIZE:
2080         {
2081            Edje_Part_Description_Text *text;
2082
2083            if ((rp->part->type != EDJE_PART_TYPE_TEXT)) return 0;
2084            CHKPARAM(3);
2085
2086            text = (Edje_Part_Description_Text*) rp->custom->description;
2087            GETINT(text->text.size, params[3]);
2088
2089            break;
2090         }
2091       case EDJE_STATE_PARAM_TEXT_FIT:
2092         {
2093            Edje_Part_Description_Text *text;
2094
2095            if ((rp->part->type != EDJE_PART_TYPE_TEXT)) return 0;
2096            CHKPARAM(4);
2097
2098            text = (Edje_Part_Description_Text*) rp->custom->description;
2099
2100            GETINT(text->text.fit_x, params[3]);
2101            GETINT(text->text.fit_y, params[4]);
2102
2103            break;
2104         }
2105       case EDJE_STATE_PARAM_TEXT_MIN:
2106         {
2107            Edje_Part_Description_Text *text;
2108
2109            if ( (rp->part->type != EDJE_PART_TYPE_TEXT) &&
2110                 (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
2111              return 0;
2112            CHKPARAM(4);
2113
2114            text = (Edje_Part_Description_Text*) rp->custom->description;
2115
2116            GETINT(text->text.min_x, params[3]);
2117            GETINT(text->text.min_y, params[4]);
2118
2119            break;
2120         }
2121       case EDJE_STATE_PARAM_TEXT_MAX:
2122         {
2123            Edje_Part_Description_Text *text;
2124
2125            if ( (rp->part->type != EDJE_PART_TYPE_TEXT) &&
2126                 (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
2127              return 0;
2128            CHKPARAM(4);
2129
2130            text = (Edje_Part_Description_Text*) rp->custom->description;
2131
2132            GETINT(text->text.max_x, params[3]);
2133            GETINT(text->text.max_y, params[4]);
2134
2135            break;
2136         }
2137       case EDJE_STATE_PARAM_TEXT_ALIGN:
2138         {
2139            Edje_Part_Description_Text *text;
2140
2141            if ((rp->part->type != EDJE_PART_TYPE_TEXT)) return 0;
2142            CHKPARAM(4);
2143
2144            text = (Edje_Part_Description_Text*) rp->custom->description;
2145
2146            GETFLOAT_T(text->text.align.x, params[3]);
2147            GETFLOAT_T(text->text.align.y, params[4]);
2148
2149            break;
2150         }
2151       case EDJE_STATE_PARAM_VISIBLE:
2152          CHKPARAM(3);
2153
2154          GETINT(rp->custom->description->visible, params[3]);
2155
2156          break;
2157       case EDJE_STATE_PARAM_MAP_OM:
2158         CHKPARAM(3);
2159         
2160         GETINT(rp->custom->description->map.on, params[3]);
2161         
2162         break;
2163       case EDJE_STATE_PARAM_MAP_PERSP:
2164         CHKPARAM(3);
2165         
2166         GETINT(rp->custom->description->map.id_persp, params[3]);
2167         
2168         break;
2169       case EDJE_STATE_PARAM_MAP_LIGNT:
2170         CHKPARAM(3);
2171         
2172         GETINT(rp->custom->description->map.id_light, params[3]);
2173         
2174         break;
2175       case EDJE_STATE_PARAM_MAP_ROT_CENTER:
2176         CHKPARAM(3);
2177         
2178         GETINT(rp->custom->description->map.rot.id_center, params[3]);
2179         
2180         break;
2181       case EDJE_STATE_PARAM_MAP_ROT_X:
2182         CHKPARAM(3);
2183
2184         GETFLOAT_T(rp->custom->description->map.rot.x, params[3]);
2185
2186         break;
2187       case EDJE_STATE_PARAM_MAP_ROT_Y:
2188         CHKPARAM(3);
2189         
2190         GETFLOAT_T(rp->custom->description->map.rot.y, params[3]);
2191         
2192         break;
2193       case EDJE_STATE_PARAM_MAP_ROT_Z:
2194         CHKPARAM(3);
2195         
2196         GETFLOAT_T(rp->custom->description->map.rot.z, params[3]);
2197
2198         break;
2199       case EDJE_STATE_PARAM_MAP_BACK_CULL:
2200         CHKPARAM(3);
2201         
2202         GETINT(rp->custom->description->map.backcull, params[3]);
2203         
2204         break;
2205       case EDJE_STATE_PARAM_MAP_PERSP_ON:
2206         CHKPARAM(3);
2207         
2208         GETINT(rp->custom->description->map.persp_on, params[3]);
2209         
2210         break;
2211       case EDJE_STATE_PARAM_PERSP_ZPLANE:
2212         CHKPARAM(3);
2213         
2214         GETINT(rp->custom->description->persp.zplane, params[3]);
2215         
2216         break;
2217       case EDJE_STATE_PARAM_PERSP_FOCAL:
2218         CHKPARAM(3);
2219         
2220         GETINT(rp->custom->description->persp.focal, params[3]);
2221         
2222         break;
2223       default:
2224          break;
2225      }
2226
2227 #ifdef EDJE_CALC_CACHE
2228    rp->invalidate = 1;
2229 #endif
2230    ed->dirty=1;
2231    return 0;
2232 }
2233
2234 /* get_state_val(part_id, State_Param:p, ...) */
2235 static Embryo_Cell
2236 _edje_embryo_fn_get_state_val(Embryo_Program *ep, Embryo_Cell *params)
2237 {
2238    Edje *ed = embryo_program_data_get(ep);
2239    Edje_Real_Part *rp;
2240    char *s;
2241
2242    /* we need at least 3 arguments */
2243    if (params[0] < (int) (sizeof(Embryo_Cell) * 3))
2244      return 0;
2245
2246    if (params[1] < 0)
2247      return 0;
2248
2249    if (!(rp = ed->table_parts[params[1] % ed->table_parts_size]))
2250      return 0;
2251
2252    /* check whether this part has a "custom" state */
2253    if (!rp->custom)
2254      return 0;
2255
2256    switch (params[2])
2257      {
2258       case EDJE_STATE_PARAM_ALIGNMENT:
2259          CHKPARAM(4);
2260
2261          SETFLOAT_T(rp->custom->description->align.x, params[3]);
2262          SETFLOAT_T(rp->custom->description->align.y, params[4]);
2263
2264          break;
2265       case EDJE_STATE_PARAM_MIN:
2266          CHKPARAM(4);
2267
2268          SETINT(rp->custom->description->min.w, params[3]);
2269          SETINT(rp->custom->description->min.h, params[4]);
2270
2271          break;
2272       case EDJE_STATE_PARAM_MAX:
2273          CHKPARAM(4);
2274
2275          SETINT(rp->custom->description->max.w, params[3]);
2276          SETINT(rp->custom->description->max.h, params[4]);
2277
2278          break;
2279       case EDJE_STATE_PARAM_STEP:
2280          CHKPARAM(4);
2281
2282          SETINT(rp->custom->description->step.x, params[3]);
2283          SETINT(rp->custom->description->step.y, params[4]);
2284
2285          break;
2286       case EDJE_STATE_PARAM_ASPECT:
2287          CHKPARAM(4);
2288
2289          SETFLOAT_T(rp->custom->description->aspect.min, params[3]);
2290          SETFLOAT_T(rp->custom->description->aspect.max, params[4]);
2291
2292          break;
2293       case EDJE_STATE_PARAM_ASPECT_PREF:
2294          CHKPARAM(3);
2295
2296          SETINT(rp->custom->description->aspect.prefer, params[3]);
2297
2298          break;
2299       case EDJE_STATE_PARAM_COLOR:
2300          CHKPARAM(6);
2301
2302          SETINT(rp->custom->description->color.r, params[3]);
2303          SETINT(rp->custom->description->color.g, params[4]);
2304          SETINT(rp->custom->description->color.b, params[5]);
2305          SETINT(rp->custom->description->color.a, params[6]);
2306
2307          break;
2308       case EDJE_STATE_PARAM_COLOR2:
2309          CHKPARAM(6);
2310
2311          SETINT(rp->custom->description->color2.r, params[3]);
2312          SETINT(rp->custom->description->color2.g, params[4]);
2313          SETINT(rp->custom->description->color2.b, params[5]);
2314          SETINT(rp->custom->description->color2.a, params[6]);
2315
2316          break;
2317       case EDJE_STATE_PARAM_COLOR3:
2318         {
2319            Edje_Part_Description_Text *text;
2320
2321            if (rp->part->type == EDJE_PART_TYPE_TEXT
2322                || rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
2323              return 0;
2324
2325            CHKPARAM(6);
2326
2327            text = (Edje_Part_Description_Text*) rp->custom->description;
2328
2329            SETINT(text->text.color3.r, params[3]);
2330            SETINT(text->text.color3.g, params[4]);
2331            SETINT(text->text.color3.b, params[5]);
2332            SETINT(text->text.color3.a, params[6]);
2333
2334            break;
2335         }
2336       case EDJE_STATE_PARAM_COLOR_CLASS:
2337          CHKPARAM(4);
2338
2339          s = rp->custom->description->color_class;
2340          SETSTRALLOCATE(s);
2341
2342          break;
2343       case EDJE_STATE_PARAM_REL1:
2344          CHKPARAM(4);
2345
2346          SETFLOAT_T(rp->custom->description->rel1.relative_x, params[3]);
2347          SETFLOAT_T(rp->custom->description->rel1.relative_y, params[4]);
2348
2349          break;
2350       case EDJE_STATE_PARAM_REL1_TO:
2351          CHKPARAM(4);
2352
2353          SETINT(rp->custom->description->rel1.id_x, params[3]);
2354          SETINT(rp->custom->description->rel1.id_y, params[4]);
2355
2356          break;
2357       case EDJE_STATE_PARAM_REL1_OFFSET:
2358          CHKPARAM(4);
2359
2360          SETINT(rp->custom->description->rel1.offset_x, params[3]);
2361          SETINT(rp->custom->description->rel1.offset_y, params[4]);
2362
2363          break;
2364       case EDJE_STATE_PARAM_REL2:
2365          CHKPARAM(4);
2366
2367          SETFLOAT_T(rp->custom->description->rel2.relative_x, params[3]);
2368          SETFLOAT_T(rp->custom->description->rel2.relative_y, params[4]);
2369
2370          break;
2371       case EDJE_STATE_PARAM_REL2_TO:
2372          CHKPARAM(4);
2373
2374          SETINT(rp->custom->description->rel2.id_x, params[3]);
2375          SETINT(rp->custom->description->rel2.id_y, params[4]);
2376
2377          break;
2378       case EDJE_STATE_PARAM_REL2_OFFSET:
2379          CHKPARAM(4);
2380
2381          SETINT(rp->custom->description->rel2.offset_x, params[3]);
2382          SETINT(rp->custom->description->rel2.offset_y, params[4]);
2383
2384          break;
2385       case EDJE_STATE_PARAM_IMAGE:
2386         {
2387            Edje_Part_Description_Image *img;
2388
2389            if ( (rp->part->type != EDJE_PART_TYPE_IMAGE) ) return 0;
2390            CHKPARAM(3);
2391
2392            img = (Edje_Part_Description_Image*) rp->custom->description;
2393
2394            SETINT(img->image.id, params[3]);
2395
2396            break;
2397         }
2398       case EDJE_STATE_PARAM_BORDER:
2399         {
2400            Edje_Part_Description_Image *img;
2401
2402            if ( (rp->part->type != EDJE_PART_TYPE_IMAGE) ) return 0;
2403            CHKPARAM(6);
2404
2405            img = (Edje_Part_Description_Image*) rp->custom->description;
2406
2407            SETINT(img->image.border.l, params[3]);
2408            SETINT(img->image.border.r, params[4]);
2409            SETINT(img->image.border.t, params[5]);
2410            SETINT(img->image.border.b, params[6]);
2411
2412            break;
2413         }
2414       case EDJE_STATE_PARAM_FILL_SMOOTH:
2415         {
2416            Edje_Part_Description_Image *img;
2417
2418            if ( (rp->part->type != EDJE_PART_TYPE_IMAGE) ) return 0;
2419            CHKPARAM(3);
2420
2421            img = (Edje_Part_Description_Image*) rp->custom->description;
2422
2423            SETINT(img->image.fill.smooth, params[3]);
2424
2425            break;
2426         }
2427       case EDJE_STATE_PARAM_FILL_POS:
2428         {
2429            Edje_Part_Description_Image *img;
2430
2431            if ( (rp->part->type != EDJE_PART_TYPE_IMAGE) ) return 0;
2432            CHKPARAM(6);
2433
2434            img = (Edje_Part_Description_Image*) rp->custom->description;
2435
2436            SETFLOAT_T(img->image.fill.pos_rel_x, params[3]);
2437            SETFLOAT_T(img->image.fill.pos_rel_y, params[4]);
2438            SETINT(img->image.fill.pos_abs_x, params[5]);
2439            SETINT(img->image.fill.pos_abs_y, params[6]);
2440
2441            break;
2442         }
2443       case EDJE_STATE_PARAM_FILL_SIZE:
2444         {
2445            Edje_Part_Description_Image *img;
2446
2447            if ( (rp->part->type != EDJE_PART_TYPE_IMAGE) ) return 0;
2448            CHKPARAM(6);
2449
2450            img = (Edje_Part_Description_Image*) rp->custom->description;
2451
2452            SETFLOAT_T(img->image.fill.rel_x, params[3]);
2453            SETFLOAT_T(img->image.fill.rel_y, params[4]);
2454            SETINT(img->image.fill.abs_x, params[5]);
2455            SETINT(img->image.fill.abs_y, params[6]);
2456
2457            break;
2458         }
2459       case EDJE_STATE_PARAM_TEXT:
2460         {
2461            Edje_Part_Description_Text *text;
2462
2463            if (rp->part->type == EDJE_PART_TYPE_TEXT
2464                || rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
2465              return 0;
2466
2467            CHKPARAM(4);
2468
2469            text = (Edje_Part_Description_Text*) rp->custom->description;
2470
2471            s = (char *)text->text.text.str;
2472            SETSTRALLOCATE(s);
2473
2474            break;
2475         }
2476       case EDJE_STATE_PARAM_TEXT_CLASS:
2477         {
2478            Edje_Part_Description_Text *text;
2479
2480            if ( (rp->part->type != EDJE_PART_TYPE_TEXT) &&
2481                (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
2482              return 0;
2483
2484            CHKPARAM(4);
2485
2486            text = (Edje_Part_Description_Text*) rp->custom->description;
2487
2488            s = text->text.text_class;
2489            SETSTRALLOCATE(s);
2490
2491            break;
2492         }
2493       case EDJE_STATE_PARAM_TEXT_FONT:
2494         {
2495            Edje_Part_Description_Text *text;
2496
2497            if ((rp->part->type != EDJE_PART_TYPE_TEXT)) return 0;
2498
2499            CHKPARAM(4);
2500
2501            text = (Edje_Part_Description_Text*) rp->custom->description;
2502
2503            s = (char *)text->text.font.str;
2504            SETSTRALLOCATE(s);
2505
2506            break;
2507         }
2508       case EDJE_STATE_PARAM_TEXT_STYLE:
2509         {
2510            Edje_Part_Description_Text *text;
2511
2512            if ((rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)) return 0;
2513
2514            CHKPARAM(4);
2515
2516            text = (Edje_Part_Description_Text*) rp->custom->description;
2517
2518            s = (char *)text->text.style.str;
2519            SETSTRALLOCATE(s);
2520
2521            break;
2522         }
2523       case EDJE_STATE_PARAM_TEXT_SIZE:
2524         {
2525            Edje_Part_Description_Text *text;
2526
2527            if ((rp->part->type != EDJE_PART_TYPE_TEXT)) return 0;
2528
2529            CHKPARAM(3);
2530
2531            text = (Edje_Part_Description_Text*) rp->custom->description;
2532
2533            SETINT(text->text.size, params[3]);
2534
2535            break;
2536         }
2537       case EDJE_STATE_PARAM_TEXT_FIT:
2538         {
2539            Edje_Part_Description_Text *text;
2540
2541            if ((rp->part->type != EDJE_PART_TYPE_TEXT)) return 0;
2542            CHKPARAM(4);
2543
2544            text = (Edje_Part_Description_Text*) rp->custom->description;
2545
2546            SETINT(text->text.fit_x, params[3]);
2547            SETINT(text->text.fit_y, params[4]);
2548
2549            break;
2550         }
2551       case EDJE_STATE_PARAM_TEXT_MIN:
2552         {
2553            Edje_Part_Description_Text *text;
2554
2555            if ( (rp->part->type != EDJE_PART_TYPE_TEXT) &&
2556                 (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
2557              return 0;
2558
2559            CHKPARAM(4);
2560
2561            text = (Edje_Part_Description_Text*) rp->custom->description;
2562
2563            SETINT(text->text.min_x, params[3]);
2564            SETINT(text->text.min_y, params[4]);
2565
2566            break;
2567         }
2568       case EDJE_STATE_PARAM_TEXT_MAX:
2569         {
2570            Edje_Part_Description_Text *text;
2571
2572            if ( (rp->part->type != EDJE_PART_TYPE_TEXT) &&
2573                 (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK))
2574              return 0;
2575
2576            CHKPARAM(4);
2577
2578            text = (Edje_Part_Description_Text*) rp->custom->description;
2579
2580            SETINT(text->text.max_x, params[3]);
2581            SETINT(text->text.max_y, params[4]);
2582
2583            break;
2584         }
2585       case EDJE_STATE_PARAM_TEXT_ALIGN:
2586         {
2587            Edje_Part_Description_Text *text;
2588
2589            if ((rp->part->type != EDJE_PART_TYPE_TEXT)) return 0;
2590
2591            CHKPARAM(4);
2592
2593            text = (Edje_Part_Description_Text*) rp->custom->description;
2594
2595            SETFLOAT_T(text->text.align.x, params[3]);
2596            SETFLOAT_T(text->text.align.y, params[4]);
2597
2598            break;
2599         }
2600       case EDJE_STATE_PARAM_VISIBLE:
2601          CHKPARAM(3);
2602
2603          SETINT(rp->custom->description->visible, params[3]);
2604
2605          break;
2606       default:
2607          break;
2608      }
2609
2610    return 0;
2611 }
2612
2613 /* part_swallow(part_id, group_name) */
2614 static Embryo_Cell
2615 _edje_embryo_fn_part_swallow(Embryo_Program *ep, Embryo_Cell *params)
2616 {
2617    int part_id = 0;
2618    char* group_name = 0;
2619    Edje *ed;
2620    Edje_Real_Part *rp;
2621    Evas_Object *new_obj;
2622    
2623    CHKPARAM(2);
2624
2625    part_id = params[1];
2626    if (part_id < 0) return 0;
2627
2628    GETSTR(group_name, params[2]);
2629    if (!group_name) return 0;
2630
2631    ed = embryo_program_data_get(ep);
2632
2633    rp = ed->table_parts[part_id % ed->table_parts_size];
2634    if (!rp) return 0;
2635
2636    new_obj =  edje_object_add(ed->base.evas);
2637    if (!new_obj) return 0;
2638
2639    if (!edje_object_file_set(new_obj, ed->file->path, group_name)) 
2640      {
2641         evas_object_del(new_obj);
2642         return 0;
2643      }
2644    edje_object_part_swallow(ed->obj, rp->part->name, new_obj);
2645    _edje_subobj_register(ed, new_obj);
2646
2647    return 0;
2648 }
2649
2650 /* external_param_get_int(id, param_name[]) */
2651 static Embryo_Cell
2652 _edje_embryo_fn_external_param_get_int(Embryo_Program *ep, Embryo_Cell *params)
2653 {
2654    Edje *ed;
2655    int part_id;
2656    Edje_Real_Part *rp;
2657    Edje_External_Param eep;
2658    char *param_name;
2659
2660    CHKPARAM(2);
2661    ed = embryo_program_data_get(ep);
2662
2663    part_id = params[1];
2664    if (part_id < 0) return 0;
2665    rp = ed->table_parts[part_id % ed->table_parts_size];
2666
2667    GETSTR(param_name, params[2]);
2668    if (!param_name) return 0;
2669    eep.name = param_name;
2670    eep.type = EDJE_EXTERNAL_PARAM_TYPE_INT;
2671    eep.i = 0;
2672    _edje_external_param_get(NULL, rp, &eep);
2673    return eep.i;
2674 }
2675
2676 /* external_param_set_int(id, param_name[], val) */
2677 static Embryo_Cell
2678 _edje_embryo_fn_external_param_set_int(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
2686    CHKPARAM(3);
2687    ed = embryo_program_data_get(ep);
2688
2689    part_id = params[1];
2690    if (part_id < 0) return 0;
2691    rp = ed->table_parts[part_id % ed->table_parts_size];
2692
2693    GETSTR(param_name, params[2]);
2694    if (!param_name) return 0;
2695    eep.name = param_name;
2696    eep.type = EDJE_EXTERNAL_PARAM_TYPE_INT;
2697    eep.i = params[3];
2698    return _edje_external_param_set(NULL, rp, &eep);
2699 }
2700
2701 /* Float:external_param_get_float(id, param_name[]) */
2702 static Embryo_Cell
2703 _edje_embryo_fn_external_param_get_float(Embryo_Program *ep, Embryo_Cell *params)
2704 {
2705    Edje *ed;
2706    int part_id;
2707    Edje_Real_Part *rp;
2708    Edje_External_Param eep;
2709    char *param_name;
2710    float v;
2711
2712    CHKPARAM(2);
2713    ed = embryo_program_data_get(ep);
2714
2715    part_id = params[1];
2716    if (part_id < 0) return 0;
2717    rp = ed->table_parts[part_id % ed->table_parts_size];
2718
2719    GETSTR(param_name, params[2]);
2720    if (!param_name) return 0;
2721    eep.name = param_name;
2722    eep.type = EDJE_EXTERNAL_PARAM_TYPE_DOUBLE;
2723    eep.d = 0.0;
2724    _edje_external_param_get(NULL, rp, &eep);
2725    v = eep.d;
2726    return EMBRYO_FLOAT_TO_CELL(v);
2727 }
2728
2729 /* external_param_set_float(id, param_name[], Float:val) */
2730 static Embryo_Cell
2731 _edje_embryo_fn_external_param_set_float(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(3);
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_DOUBLE;
2750    eep.d = EMBRYO_CELL_TO_FLOAT(params[3]);
2751    return _edje_external_param_set(NULL, rp, &eep);
2752 }
2753
2754 /* external_param_get_strlen(id, param_name[]) */
2755 static Embryo_Cell
2756 _edje_embryo_fn_external_param_get_strlen(Embryo_Program *ep, Embryo_Cell *params)
2757 {
2758    Edje *ed;
2759    int part_id;
2760    Edje_Real_Part *rp;
2761    Edje_External_Param eep;
2762    char *param_name;
2763
2764    CHKPARAM(2);
2765    ed = embryo_program_data_get(ep);
2766
2767    part_id = params[1];
2768    if (part_id < 0) return 0;
2769    rp = ed->table_parts[part_id % ed->table_parts_size];
2770
2771    GETSTR(param_name, params[2]);
2772    if (!param_name) return 0;
2773    eep.name = param_name;
2774    eep.type = EDJE_EXTERNAL_PARAM_TYPE_STRING;
2775    eep.s = NULL;
2776    _edje_external_param_get(NULL, rp, &eep);
2777    if (!eep.s) return 0;
2778    return strlen(eep.s);
2779 }
2780
2781 /* external_param_get_str(id, param_name[], val[], val_maxlen) */
2782 static Embryo_Cell
2783 _edje_embryo_fn_external_param_get_str(Embryo_Program *ep, Embryo_Cell *params)
2784 {
2785    Edje *ed;
2786    int part_id;
2787    Edje_Real_Part *rp;
2788    Edje_External_Param eep;
2789    char *param_name;
2790    size_t src_len, dst_len;
2791
2792    CHKPARAM(4);
2793    dst_len = params[4];
2794    if (dst_len < 1) goto error;
2795
2796    ed = embryo_program_data_get(ep);
2797
2798    part_id = params[1];
2799    if (part_id < 0) goto error;
2800    rp = ed->table_parts[part_id % ed->table_parts_size];
2801
2802    GETSTR(param_name, params[2]);
2803    if (!param_name) return 0;
2804    eep.name = param_name;
2805    eep.type = EDJE_EXTERNAL_PARAM_TYPE_STRING;
2806    eep.s = NULL;
2807    _edje_external_param_get(NULL, rp, &eep);
2808    if (!eep.s) goto error;
2809    src_len = strlen(eep.s);
2810    if (src_len < dst_len)
2811      {
2812         SETSTR(eep.s, params[3]);
2813      }
2814    else
2815      {
2816         char *tmp = alloca(dst_len);
2817         memcpy(tmp, eep.s, dst_len - 1);
2818         tmp[dst_len-1] = '\0';
2819         SETSTR(tmp, params[3]);
2820      }
2821    return 1;
2822
2823  error:
2824    SETSTR("", params[3]);
2825    return 0;
2826 }
2827
2828 /* external_param_set_str(id, param_name[], val[]) */
2829 static Embryo_Cell
2830 _edje_embryo_fn_external_param_set_str(Embryo_Program *ep, Embryo_Cell *params)
2831 {
2832    Edje *ed;
2833    int part_id;
2834    Edje_Real_Part *rp;
2835    Edje_External_Param eep;
2836    char *param_name, *val;
2837
2838    CHKPARAM(3);
2839    ed = embryo_program_data_get(ep);
2840
2841    part_id = params[1];
2842    if (part_id < 0) return 0;
2843    rp = ed->table_parts[part_id % ed->table_parts_size];
2844
2845    GETSTR(param_name, params[2]);
2846    if (!param_name) return 0;
2847    eep.name = param_name;
2848    eep.type = EDJE_EXTERNAL_PARAM_TYPE_STRING;
2849    GETSTR(val, params[3]);
2850    if (!val) return 0;
2851    eep.s = val;
2852    return _edje_external_param_set(NULL, rp, &eep);
2853 }
2854
2855 /* external_param_get_choice_len(id, param_name[]) */
2856 static Embryo_Cell
2857 _edje_embryo_fn_external_param_get_choice_len(Embryo_Program *ep, Embryo_Cell *params)
2858 {
2859    Edje *ed;
2860    int part_id;
2861    Edje_Real_Part *rp;
2862    Edje_External_Param eep;
2863    char *param_name;
2864
2865    CHKPARAM(2);
2866    ed = embryo_program_data_get(ep);
2867
2868    part_id = params[1];
2869    if (part_id < 0) return 0;
2870    rp = ed->table_parts[part_id % ed->table_parts_size];
2871
2872    GETSTR(param_name, params[2]);
2873    if (!param_name) return 0;
2874    eep.name = param_name;
2875    eep.type = EDJE_EXTERNAL_PARAM_TYPE_CHOICE;
2876    eep.s = NULL;
2877    _edje_external_param_get(NULL, rp, &eep);
2878    if (!eep.s) return 0;
2879    return strlen(eep.s);
2880 }
2881
2882 /* external_param_get_choice(id, param_name[], val[], val_maxlen) */
2883 static Embryo_Cell
2884 _edje_embryo_fn_external_param_get_choice(Embryo_Program *ep, Embryo_Cell *params)
2885 {
2886    Edje *ed;
2887    int part_id;
2888    Edje_Real_Part *rp;
2889    Edje_External_Param eep;
2890    char *param_name;
2891    size_t src_len, dst_len;
2892
2893    CHKPARAM(4);
2894    dst_len = params[4];
2895    if (dst_len < 1) goto error;
2896
2897    ed = embryo_program_data_get(ep);
2898
2899    part_id = params[1];
2900    if (part_id < 0) goto error;
2901    rp = ed->table_parts[part_id % ed->table_parts_size];
2902
2903    GETSTR(param_name, params[2]);
2904    if (!param_name) return 0;
2905    eep.name = param_name;
2906    eep.type = EDJE_EXTERNAL_PARAM_TYPE_CHOICE;
2907    eep.s = NULL;
2908    _edje_external_param_get(NULL, rp, &eep);
2909    if (!eep.s) goto error;
2910    src_len = strlen(eep.s);
2911    if (src_len < dst_len)
2912      {
2913         SETSTR(eep.s, params[3]);
2914      }
2915    else
2916      {
2917         char *tmp = alloca(dst_len);
2918         memcpy(tmp, eep.s, dst_len - 1);
2919         tmp[dst_len-1] = '\0';
2920         SETSTR(tmp, params[3]);
2921      }
2922    return 1;
2923
2924  error:
2925    SETSTR("", params[3]);
2926    return 0;
2927 }
2928
2929 /* external_param_set_choice(id, param_name[], val[]) */
2930 static Embryo_Cell
2931 _edje_embryo_fn_external_param_set_choice(Embryo_Program *ep, Embryo_Cell *params)
2932 {
2933    Edje *ed;
2934    int part_id;
2935    Edje_Real_Part *rp;
2936    Edje_External_Param eep;
2937    char *param_name, *val;
2938
2939    CHKPARAM(3);
2940    ed = embryo_program_data_get(ep);
2941
2942    part_id = params[1];
2943    if (part_id < 0) return 0;
2944    rp = ed->table_parts[part_id % ed->table_parts_size];
2945
2946    GETSTR(param_name, params[2]);
2947    if (!param_name) return 0;
2948    eep.name = param_name;
2949    eep.type = EDJE_EXTERNAL_PARAM_TYPE_CHOICE;
2950    GETSTR(val, params[3]);
2951    if (!val) return 0;
2952    eep.s = val;
2953    return _edje_external_param_set(NULL, rp, &eep);
2954 }
2955
2956 /* external_param_get_bool(id, param_name[]) */
2957 static Embryo_Cell
2958 _edje_embryo_fn_external_param_get_bool(Embryo_Program *ep, Embryo_Cell *params)
2959 {
2960    Edje *ed;
2961    int part_id;
2962    Edje_Real_Part *rp;
2963    Edje_External_Param eep;
2964    char *param_name;
2965
2966    CHKPARAM(2);
2967    ed = embryo_program_data_get(ep);
2968
2969    part_id = params[1];
2970    if (part_id < 0) return 0;
2971    rp = ed->table_parts[part_id % ed->table_parts_size];
2972
2973    GETSTR(param_name, params[2]);
2974    if (!param_name) return 0;
2975    eep.name = param_name;
2976    eep.type = EDJE_EXTERNAL_PARAM_TYPE_BOOL;
2977    eep.i = 0;
2978    _edje_external_param_get(NULL, rp, &eep);
2979    return eep.i;
2980 }
2981
2982 /* external_param_set_bool(id, param_name[], val) */
2983 static Embryo_Cell
2984 _edje_embryo_fn_external_param_set_bool(Embryo_Program *ep, Embryo_Cell *params)
2985 {
2986    Edje *ed;
2987    int part_id;
2988    Edje_Real_Part *rp;
2989    Edje_External_Param eep;
2990    char *param_name;
2991
2992    CHKPARAM(3);
2993    ed = embryo_program_data_get(ep);
2994
2995    part_id = params[1];
2996    if (part_id < 0) return 0;
2997    rp = ed->table_parts[part_id % ed->table_parts_size];
2998
2999    GETSTR(param_name, params[2]);
3000    if (!param_name) return 0;
3001    eep.name = param_name;
3002    eep.type = EDJE_EXTERNAL_PARAM_TYPE_BOOL;
3003    eep.i = params[3];
3004    return _edje_external_param_set(NULL, rp, &eep);
3005 }
3006
3007 void
3008 _edje_embryo_script_init(Edje_Part_Collection *edc)
3009 {
3010    Embryo_Program *ep;
3011
3012    if (!edc) return;
3013    if (!edc->script) return;
3014    
3015    ep = edc->script;
3016    /* first advertise all the edje "script" calls */
3017    embryo_program_native_call_add(ep, "get_int", _edje_embryo_fn_get_int);
3018    embryo_program_native_call_add(ep, "set_int", _edje_embryo_fn_set_int);
3019    embryo_program_native_call_add(ep, "get_float", _edje_embryo_fn_get_float);
3020    embryo_program_native_call_add(ep, "set_float", _edje_embryo_fn_set_float);
3021    embryo_program_native_call_add(ep, "get_str", _edje_embryo_fn_get_str);
3022    embryo_program_native_call_add(ep, "get_strlen", _edje_embryo_fn_get_strlen);
3023    embryo_program_native_call_add(ep, "set_str", _edje_embryo_fn_set_str);
3024    embryo_program_native_call_add(ep, "count", _edje_embryo_fn_count);
3025    embryo_program_native_call_add(ep, "remove", _edje_embryo_fn_remove);
3026    embryo_program_native_call_add(ep, "append_int", _edje_embryo_fn_append_int);
3027    embryo_program_native_call_add(ep, "prepend_int", _edje_embryo_fn_prepend_int);
3028    embryo_program_native_call_add(ep, "insert_int", _edje_embryo_fn_insert_int);
3029    embryo_program_native_call_add(ep, "replace_int", _edje_embryo_fn_replace_int);
3030    embryo_program_native_call_add(ep, "fetch_int", _edje_embryo_fn_fetch_int);
3031    embryo_program_native_call_add(ep, "append_str", _edje_embryo_fn_append_str);
3032    embryo_program_native_call_add(ep, "prepend_str", _edje_embryo_fn_prepend_str);
3033    embryo_program_native_call_add(ep, "insert_str", _edje_embryo_fn_insert_str);
3034    embryo_program_native_call_add(ep, "replace_str", _edje_embryo_fn_replace_str);
3035    embryo_program_native_call_add(ep, "fetch_str", _edje_embryo_fn_fetch_str);
3036    embryo_program_native_call_add(ep, "append_float", _edje_embryo_fn_append_float);
3037    embryo_program_native_call_add(ep, "prepend_float", _edje_embryo_fn_prepend_float);
3038    embryo_program_native_call_add(ep, "insert_float", _edje_embryo_fn_insert_float);
3039    embryo_program_native_call_add(ep, "replace_float", _edje_embryo_fn_replace_float);
3040    embryo_program_native_call_add(ep, "fetch_float", _edje_embryo_fn_fetch_float);
3041
3042    embryo_program_native_call_add(ep, "timer", _edje_embryo_fn_timer);
3043    embryo_program_native_call_add(ep, "cancel_timer", _edje_embryo_fn_cancel_timer);
3044
3045    embryo_program_native_call_add(ep, "anim", _edje_embryo_fn_anim);
3046    embryo_program_native_call_add(ep, "cancel_anim", _edje_embryo_fn_cancel_anim);
3047
3048    embryo_program_native_call_add(ep, "emit", _edje_embryo_fn_emit);
3049    embryo_program_native_call_add(ep, "get_part_id", _edje_embryo_fn_get_part_id);
3050    embryo_program_native_call_add(ep, "get_program_id", _edje_embryo_fn_get_program_id);
3051    embryo_program_native_call_add(ep, "set_state", _edje_embryo_fn_set_state);
3052    embryo_program_native_call_add(ep, "get_state", _edje_embryo_fn_get_state);
3053    embryo_program_native_call_add(ep, "set_tween_state", _edje_embryo_fn_set_tween_state);
3054    embryo_program_native_call_add(ep, "run_program", _edje_embryo_fn_run_program);
3055    embryo_program_native_call_add(ep, "get_drag_dir", _edje_embryo_fn_get_drag_dir);
3056    embryo_program_native_call_add(ep, "get_drag", _edje_embryo_fn_get_drag);
3057    embryo_program_native_call_add(ep, "set_drag", _edje_embryo_fn_set_drag);
3058    embryo_program_native_call_add(ep, "get_drag_size", _edje_embryo_fn_get_drag_size);
3059    embryo_program_native_call_add(ep, "set_drag_size", _edje_embryo_fn_set_drag_size);
3060    embryo_program_native_call_add(ep, "set_text", _edje_embryo_fn_set_text);
3061    embryo_program_native_call_add(ep, "get_text", _edje_embryo_fn_get_text);
3062    embryo_program_native_call_add(ep, "get_min_size", _edje_embryo_fn_get_min_size);
3063    embryo_program_native_call_add(ep, "get_max_size", _edje_embryo_fn_get_max_size);
3064    embryo_program_native_call_add(ep, "get_color_class", _edje_embryo_fn_get_color_class);
3065    embryo_program_native_call_add(ep, "set_color_class", _edje_embryo_fn_set_color_class);
3066    embryo_program_native_call_add(ep, "set_text_class", _edje_embryo_fn_set_text_class);
3067    embryo_program_native_call_add(ep, "get_text_class", _edje_embryo_fn_get_text_class);
3068    embryo_program_native_call_add(ep, "get_drag_step", _edje_embryo_fn_get_drag_step);
3069    embryo_program_native_call_add(ep, "set_drag_step", _edje_embryo_fn_set_drag_step);
3070    embryo_program_native_call_add(ep, "get_drag_page", _edje_embryo_fn_get_drag_page);
3071    embryo_program_native_call_add(ep, "set_drag_page", _edje_embryo_fn_set_drag_page);
3072    embryo_program_native_call_add(ep, "get_mouse", _edje_embryo_fn_get_mouse);
3073    embryo_program_native_call_add(ep, "get_mouse_buttons", _edje_embryo_fn_get_mouse_buttons);
3074    embryo_program_native_call_add(ep, "stop_program", _edje_embryo_fn_stop_program);
3075    embryo_program_native_call_add(ep, "stop_programs_on", _edje_embryo_fn_stop_programs_on);
3076    embryo_program_native_call_add(ep, "set_min_size", _edje_embryo_fn_set_min_size);
3077    embryo_program_native_call_add(ep, "set_max_size", _edje_embryo_fn_set_max_size);
3078    embryo_program_native_call_add(ep, "play_sample", _edje_embryo_fn_play_sample);
3079    embryo_program_native_call_add(ep, "play_tone", _edje_embryo_fn_play_tone);
3080    embryo_program_native_call_add(ep, "send_message", _edje_embryo_fn_send_message);
3081    embryo_program_native_call_add(ep, "get_geometry", _edje_embryo_fn_get_geometry);
3082    embryo_program_native_call_add(ep, "custom_state", _edje_embryo_fn_custom_state);
3083    embryo_program_native_call_add(ep, "set_state_val", _edje_embryo_fn_set_state_val);
3084    embryo_program_native_call_add(ep, "get_state_val", _edje_embryo_fn_get_state_val);
3085
3086    embryo_program_native_call_add(ep, "part_swallow", _edje_embryo_fn_part_swallow);
3087
3088    embryo_program_native_call_add(ep, "external_param_get_int", _edje_embryo_fn_external_param_get_int);
3089    embryo_program_native_call_add(ep, "external_param_set_int", _edje_embryo_fn_external_param_set_int);
3090    embryo_program_native_call_add(ep, "external_param_get_float", _edje_embryo_fn_external_param_get_float);
3091    embryo_program_native_call_add(ep, "external_param_set_float", _edje_embryo_fn_external_param_set_float);
3092    embryo_program_native_call_add(ep, "external_param_get_strlen", _edje_embryo_fn_external_param_get_strlen);
3093    embryo_program_native_call_add(ep, "external_param_get_str", _edje_embryo_fn_external_param_get_str);
3094    embryo_program_native_call_add(ep, "external_param_set_str", _edje_embryo_fn_external_param_set_str);
3095    embryo_program_native_call_add(ep, "external_param_get_choice_len", _edje_embryo_fn_external_param_get_choice_len);
3096    embryo_program_native_call_add(ep, "external_param_get_choice", _edje_embryo_fn_external_param_get_choice);
3097    embryo_program_native_call_add(ep, "external_param_set_choice", _edje_embryo_fn_external_param_set_choice);
3098    embryo_program_native_call_add(ep, "external_param_get_bool", _edje_embryo_fn_external_param_get_bool);
3099    embryo_program_native_call_add(ep, "external_param_set_bool", _edje_embryo_fn_external_param_set_bool);
3100 }
3101
3102 void
3103 _edje_embryo_script_shutdown(Edje_Part_Collection *edc)
3104 {
3105    if (!edc) return;
3106    if (!edc->script) return;
3107    if (embryo_program_recursion_get(edc->script) > 0) return;
3108    embryo_program_free(edc->script);
3109    edc->script = NULL;
3110 }
3111
3112 void
3113 _edje_embryo_script_reset(Edje *ed)
3114 {
3115    if (!ed) return;
3116    if (!ed->collection) return;
3117    if (!ed->collection->script) return;
3118    if (embryo_program_recursion_get(ed->collection->script) > 0) return;
3119    embryo_program_vm_reset(ed->collection->script);
3120    _edje_embryo_globals_init(ed);
3121 }
3122
3123 /* this may change in future - thus "test_run" is its name */
3124 void
3125 _edje_embryo_test_run(Edje *ed, const char *fname, const char *sig, const char *src)
3126 {
3127    Embryo_Function fn;
3128
3129    if (!ed) return;
3130    if (!ed->collection) return;
3131    if (!ed->collection->script) return;
3132    embryo_program_vm_push(ed->collection->script);
3133    _edje_embryo_globals_init(ed);
3134
3135    //   _edje_embryo_script_reset(ed);
3136    fn = embryo_program_function_find(ed->collection->script, (char *)fname);
3137    if (fn != EMBRYO_FUNCTION_NONE)
3138      {
3139         void *pdata;
3140         int ret;
3141
3142         embryo_parameter_string_push(ed->collection->script, (char *)sig);
3143         embryo_parameter_string_push(ed->collection->script, (char *)src);
3144         pdata = embryo_program_data_get(ed->collection->script);
3145         embryo_program_data_set(ed->collection->script, ed);
3146         /* 5 million instructions is an arbitrary number. on my p4-2.6 here */
3147         /* IF embryo is ONLY running embryo stuff and NO native calls thats */
3148         /* about 0.016 seconds, and longer on slower cpu's. if a simple */
3149         /* embryo script snippet hasn't managed to do its work in 5 MILLION */
3150         /* embryo virtual machine instructions - something is wrong, or */
3151         /* embryo is simply being mis-used. Embryo is meant to be minimal */
3152         /* logic enhancment - not entire applications. this cycle count */
3153         /* does NOT include time spent in native function calls, that the */
3154         /* script may call to do the REAL work, so in terms of time this */
3155         /* will likely end up being much longer than 0.016 seconds - more */
3156         /* like 0.03 - 0.05 seconds or even more */
3157         embryo_program_max_cycle_run_set(ed->collection->script, 5000000);
3158         ret = embryo_program_run(ed->collection->script, fn);
3159         if (ret == EMBRYO_PROGRAM_FAIL)
3160           {
3161              ERR("ERROR with embryo script. "
3162                  "OBJECT NAME: '%s', "
3163                  "OBJECT FILE: '%s', "
3164                  "ENTRY POINT: '%s', "
3165                  "SIGNAL: '%s', "
3166                  "SOURCE: '%s', "
3167                  "ERROR: '%s'",
3168                  ed->collection->part,
3169                  ed->file->path,
3170                  fname,
3171                  sig, src,
3172                  embryo_error_string_get(embryo_program_error_get(ed->collection->script)));
3173           }
3174         else if (ret == EMBRYO_PROGRAM_TOOLONG)
3175           {
3176              ERR("ERROR with embryo script. "
3177                  "OBJECT NAME: '%s', "
3178                  "OBJECT FILE: '%s', "
3179                  "ENTRY POINT: '%s', "
3180                  "SIGNAL: '%s', "
3181                  "SOURCE: '%s', "
3182                  "ERROR: 'Script exceeded maximum allowed cycle count of %i'",
3183                  ed->collection->part,
3184                  ed->file->path,
3185                  fname,
3186                  sig, src,
3187                  embryo_program_max_cycle_run_get(ed->collection->script));
3188           }
3189         embryo_program_data_set(ed->collection->script, pdata);
3190      }
3191    embryo_program_vm_pop(ed->collection->script);
3192 }
3193
3194 void
3195 _edje_embryo_globals_init(Edje *ed)
3196 {
3197    int n, i;
3198    Embryo_Program *ep;
3199
3200    ep = ed->collection->script;
3201    n = embryo_program_variable_count_get(ep);
3202    for (i = 0; i < n; i++)
3203      {
3204         Embryo_Cell cell, *cptr;
3205
3206         cell = embryo_program_variable_get(ep, i);
3207         if (cell != EMBRYO_CELL_NONE)
3208           {
3209              cptr = embryo_data_address_get(ep, cell);
3210              if (cptr) *cptr = EDJE_VAR_MAGIC_BASE + i;
3211           }
3212      }
3213 }