Imported Upstream version 1.7.1
[platform/upstream/edje.git] / src / lib / edje_script_only.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 typedef struct _Sinfo Sinfo;
51
52 struct _Sinfo
53 {
54    struct
55    {
56       Embryo_Function
57          obj_init, obj_shutdown, obj_show, obj_show_immediate,
58          obj_hide, obj_hide_immediate, obj_move, obj_move_immediate,
59          obj_resize, obj_resize_immediate, obj_message;
60    } fn;
61    struct
62    {
63       Ecore_Job * show, *hide, *move, *resize;
64    } job;
65    struct
66    {
67       int id;
68       Eina_Hash *hash;          // FIXME: hash -> bad. too big. one-way lookup etc.
69    } oid;
70 };
71
72 static void _call_fn(Edje * ed, const char *fname, Embryo_Function fn);
73
74 /* frankly - these make the code shorter to type and read - just sanity for
75  * development */
76 #define IFFN(func) if (si->fn.func != EMBRYO_FUNCTION_NONE)
77 #define IFNO(func) if (si->fn.func == EMBRYO_FUNCTION_NONE)
78 #define CLFN(func) IFFN(func) {_call_fn(ed, #func, si->fn.func);}
79 #define SI Sinfo *si; si = ed->script_only_data; if (!si) return
80 #define SI_RETURN(ret) Sinfo *si; si = ed->script_only_data; if (!si) return (ret)
81 #define PINT(val) embryo_parameter_cell_push(ed->collection->script, (Embryo_Cell)(val))
82 #define PSTR(val) embryo_parameter_string_push(ed->collection->script, val)
83 #define GTFN(func) si->fn.func = embryo_program_function_find(ed->collection->script, #func)
84 #define DELJ(type) if (si->job.type) ecore_job_del(si->job.type);
85 #define ADDJ(type, func) si->job.type = ecore_job_add(func, ed);
86 #define ZERJ(type) si->job.type = NULL;
87 #define IFNJ(type) if (!si->job.type)
88 #define EXPF(func) embryo_program_native_call_add(ed->collection->script, #func, _exp_##func)
89
90 typedef struct _Oid Oid;
91
92 struct _Oid
93 {
94    Edje *ed;
95    Evas_Object *obj;
96    Evas_Coord x, y, w, h;
97    int oid;
98 };
99
100 /* FIXME: using eina_hash and strings is just nasty! make a custom int hash */
101 static int
102 _oid_alloc(Edje * ed)
103 {
104    SI_RETURN(0);
105
106    si->oid.id++;
107    return si->oid.id;
108 }
109
110 static Oid *
111 _oid_track(Edje * ed, Evas_Object * o)
112 {
113    Oid *oi;
114
115    char buf[64];
116
117    SI_RETURN(NULL);
118
119    oi = calloc(1, sizeof(Oid));
120    if (!oi)
121       return NULL;
122    oi->oid = _oid_alloc(ed);
123    if (!oi->oid)
124      {
125         free(oi);
126         return NULL;
127      }
128    oi->ed = ed;
129    oi->obj = o;
130    evas_object_smart_member_add(oi->obj, oi->ed->obj);
131    evas_object_clip_set(oi->obj, oi->ed->base.clipper);
132    evas_object_geometry_get(oi->obj, &(oi->x), &(oi->y), &(oi->w), &(oi->h));
133    snprintf(buf, sizeof(buf), "%i", oi->oid);
134    if (!si->oid.hash)
135       si->oid.hash = eina_hash_string_superfast_new(NULL);
136    eina_hash_add(si->oid.hash, buf, oi);
137    return oi;
138 }
139
140 static Oid *
141 _oid_find(Edje * ed, int oid)
142 {
143    char buf[64];
144
145    SI_RETURN(NULL);
146
147    snprintf(buf, sizeof(buf), "%i", oid);
148    return eina_hash_find(si->oid.hash, buf);
149 }
150
151 static void
152 _oid_del(Edje * ed, int oid)
153 {
154    char buf[64];
155
156    SI;
157
158    snprintf(buf, sizeof(buf), "%i", oid);
159    eina_hash_del(si->oid.hash, buf, NULL);
160 }
161
162 static void
163 _oid_free(Oid * oid)
164 {
165    free(oid);
166 }
167
168 static Eina_Bool
169 _oid_freeall_cb(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata __UNUSED__)
170 {
171    Oid *oid = data;
172
173    evas_object_del(oid->obj);
174    free(oid);
175    return EINA_TRUE;
176 }
177
178 static void
179 _oid_freeall(Edje * ed)
180 {
181    SI;
182    if (!si->oid.hash)
183       return;
184    eina_hash_foreach(si->oid.hash, _oid_freeall_cb, ed);
185    eina_hash_free(si->oid.hash);
186    si->oid.hash = NULL;
187 }
188
189 static Eina_Bool
190 _oid_moveall_cb(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata __UNUSED__)
191 {
192    Oid *oid = data;
193
194    evas_object_move(oid->obj, oid->ed->x + oid->x, oid->ed->y + oid->y);
195    return EINA_TRUE;
196 }
197
198 static void
199 _oid_moveall(Edje * ed)
200 {
201    SI;
202    if (!si->oid.hash)
203       return;
204    eina_hash_foreach(si->oid.hash, _oid_moveall_cb, ed);
205 }
206
207 /**********/
208
209 static Embryo_Cell
210 _exp_e_obj_del(Embryo_Program * ep, Embryo_Cell * params)
211 {
212    Edje *ed = embryo_program_data_get(ep);
213
214    Oid *oid;
215
216    SI_RETURN(-1);
217
218    CHKPARAM(1);
219    if (!(oid = _oid_find(ed, params[1])))
220       return -1;
221    evas_object_del(oid->obj);
222    _oid_del(ed, oid->oid);
223    _oid_free(oid);
224    return 0;
225 }
226
227 static Embryo_Cell
228 _exp_e_obj_rect_add(Embryo_Program * ep, Embryo_Cell * params __UNUSED__)
229 {
230    Edje *ed = embryo_program_data_get(ep);
231
232    Evas_Object *o;
233
234    Oid *oid;
235
236    SI_RETURN(-1);
237
238    o = evas_object_rectangle_add(evas_object_evas_get(ed->obj));
239    if (!o)
240       return 0;
241    oid = _oid_track(ed, o);
242    if (oid)
243       return oid->oid;
244    return 0;
245 }
246
247 static Embryo_Cell
248 _exp_e_obj_show(Embryo_Program * ep, Embryo_Cell * params)
249 {
250    Edje *ed = embryo_program_data_get(ep);
251
252    Oid *oid;
253
254    SI_RETURN(-1);
255
256    CHKPARAM(1);
257    if (!(oid = _oid_find(ed, params[1])))
258       return -1;
259    evas_object_show(oid->obj);
260    return 0;
261 }
262
263 static Embryo_Cell
264 _exp_e_obj_hide(Embryo_Program * ep, Embryo_Cell * params)
265 {
266    Edje *ed = embryo_program_data_get(ep);
267
268    Oid *oid;
269
270    SI_RETURN(-1);
271
272    CHKPARAM(1);
273    if (!(oid = _oid_find(ed, params[1])))
274       return -1;
275    evas_object_hide(oid->obj);
276    return 0;
277 }
278
279 static Embryo_Cell
280 _exp_e_obj_move(Embryo_Program * ep, Embryo_Cell * params)
281 {
282    Edje *ed = embryo_program_data_get(ep);
283
284    Oid *oid;
285
286    SI_RETURN(-1);
287
288    CHKPARAM(3);
289    if (!(oid = _oid_find(ed, params[1])))
290       return -1;
291    if ((oid->x == params[2]) && (oid->y == params[3]))
292       return -1;
293    oid->x = params[2];
294    oid->y = params[3];
295    evas_object_move(oid->obj, ed->x + oid->x, ed->y + oid->y);
296    return 0;
297 }
298
299 static Embryo_Cell
300 _exp_e_obj_resize(Embryo_Program * ep, Embryo_Cell * params)
301 {
302    Edje *ed = embryo_program_data_get(ep);
303
304    Oid *oid;
305
306    SI_RETURN(-1);
307
308    CHKPARAM(3);
309    if (!(oid = _oid_find(ed, params[1])))
310       return -1;
311    if ((oid->w == params[2]) && (oid->h == params[3]))
312       return -1;
313    oid->w = params[2];
314    oid->h = params[3];
315    evas_object_resize(oid->obj, oid->w, oid->h);
316    return 0;
317 }
318
319 static Embryo_Cell
320 _exp_e_obj_geometry_set(Embryo_Program * ep, Embryo_Cell * params)
321 {
322    Edje *ed = embryo_program_data_get(ep);
323
324    Oid *oid;
325
326    SI_RETURN(-1);
327
328    CHKPARAM(5);
329    if (!(oid = _oid_find(ed, params[1])))
330       return -1;
331    if ((oid->x == params[2]) && (oid->y == params[3]) &&
332        (oid->w == params[4]) && (oid->h == params[5]))
333       return -1;
334    oid->x = params[2];
335    oid->y = params[3];
336    oid->w = params[4];
337    oid->h = params[5];
338    evas_object_move(oid->obj, ed->x + oid->x, ed->y + oid->y);
339    evas_object_resize(oid->obj, oid->w, oid->h);
340    return 0;
341 }
342
343 static Embryo_Cell
344 _exp_e_obj_geometry_get(Embryo_Program * ep, Embryo_Cell * params)
345 {
346    Edje *ed = embryo_program_data_get(ep);
347
348    Oid *oid;
349
350    SI_RETURN(-1);
351
352    CHKPARAM(5);
353    if (!(oid = _oid_find(ed, params[1])))
354       return -1;
355    SETINT(oid->x, params[2]);
356    SETINT(oid->y, params[3]);
357    SETINT(oid->w, params[4]);
358    SETINT(oid->h, params[5]);
359    return 0;
360 }
361
362 static Embryo_Cell
363 _exp_e_obj_color_set(Embryo_Program * ep, Embryo_Cell * params)
364 {
365    Edje *ed = embryo_program_data_get(ep);
366
367    Oid *oid;
368
369    SI_RETURN(-1);
370
371    CHKPARAM(5);
372    if (!(oid = _oid_find(ed, params[1])))
373       return -1;
374    evas_object_color_set(oid->obj, params[2], params[3], params[4], params[5]);
375    return 0;
376 }
377
378 static Embryo_Cell
379 _exp_e_obj_color_get(Embryo_Program * ep, Embryo_Cell * params)
380 {
381    Edje *ed = embryo_program_data_get(ep);
382
383    Oid *oid;
384
385    int r, g, b, a;
386
387    SI_RETURN(-1);
388
389    CHKPARAM(5);
390    if (!(oid = _oid_find(ed, params[1])))
391       return -1;
392    evas_object_color_get(oid->obj, &r, &g, &b, &a);
393    SETINT(r, params[2]);
394    SETINT(g, params[3]);
395    SETINT(b, params[4]);
396    SETINT(a, params[5]);
397    return 0;
398 }
399
400 static Embryo_Cell
401 _exp_e_signal_emit(Embryo_Program * ep, Embryo_Cell * params)
402 {
403    Edje *ed = embryo_program_data_get(ep);
404
405    char *sig = NULL, *src = NULL;
406
407    SI_RETURN(-1);
408
409    CHKPARAM(2);
410    GETSTR(sig, params[1]);
411    GETSTR(src, params[2]);
412    if ((!sig) || (!src))
413       return -1;
414    _edje_emit(ed, sig, src);
415    return 0;
416 }
417
418 /**********/
419
420 Eina_Bool
421 _edje_script_only(Edje * ed)
422 {
423    if ((ed->collection) && (ed->collection->script) &&
424        (ed->collection->script_only))
425       return EINA_TRUE;
426    return EINA_FALSE;
427 }
428
429 void
430 _edje_script_only_init(Edje * ed)
431 {
432    Sinfo *si;
433
434    si = calloc(1, sizeof(Sinfo));
435    if (!si)
436       return;
437    ed->script_only_data = si;
438
439    embryo_program_data_set(ed->collection->script, ed);
440
441    EXPF(e_obj_del);
442    EXPF(e_obj_rect_add);
443    EXPF(e_obj_show);
444    EXPF(e_obj_hide);
445    EXPF(e_obj_move);
446    EXPF(e_obj_resize);
447    EXPF(e_obj_geometry_set);
448    EXPF(e_obj_geometry_get);
449    EXPF(e_obj_color_set);
450    EXPF(e_obj_color_get);
451    EXPF(e_signal_emit);
452
453    embryo_program_vm_push(ed->collection->script);
454    embryo_program_max_cycle_run_set(ed->collection->script, 5000000);
455
456    GTFN(obj_init);
457    GTFN(obj_shutdown);
458    GTFN(obj_show);
459    GTFN(obj_show_immediate);
460    GTFN(obj_hide);
461    GTFN(obj_hide_immediate);
462    GTFN(obj_move);
463    GTFN(obj_move_immediate);
464    GTFN(obj_resize);
465    GTFN(obj_resize_immediate);
466    GTFN(obj_message);
467
468    CLFN(obj_init);
469    _edje_script_only_move(ed);
470 }
471
472 void
473 _edje_script_only_shutdown(Edje * ed)
474 {
475    SI;
476
477    CLFN(obj_shutdown);
478    DELJ(show);
479    DELJ(hide);
480    DELJ(move);
481    DELJ(resize);
482    _oid_freeall(ed);
483 }
484
485 static void
486 _show_job(void *data)
487 {
488    Edje *ed = data;
489
490    SI;
491
492    ZERJ(show);
493    CLFN(obj_show);
494 }
495 void
496 _edje_script_only_show(Edje * ed)
497 {
498    SI;
499
500    IFFN(obj_show)
501    {
502       IFNJ(hide)
503       {
504          DELJ(show);
505          ADDJ(show, _show_job);
506       }
507       else
508       {
509          DELJ(hide);
510       }
511    }
512    IFNO(obj_show_immediate) return;
513    CLFN(obj_show_immediate);
514 }
515
516 static void
517 _hide_job(void *data)
518 {
519    Edje *ed = data;
520
521    SI;
522
523    ZERJ(hide);
524    CLFN(obj_hide);
525 }
526 void
527 _edje_script_only_hide(Edje * ed)
528 {
529    SI;
530
531    IFFN(obj_hide)
532    {
533       IFNJ(show)
534       {
535          DELJ(hide);
536          ADDJ(hide, _hide_job);
537       }
538       else
539       {
540          DELJ(show);
541       }
542    }
543    IFNO(obj_hide_immediate) return;
544    CLFN(obj_hide_immediate);
545 }
546
547 static void
548 _move_job(void *data)
549 {
550    Edje *ed = data;
551
552    SI;
553
554    _oid_moveall(ed);
555    ZERJ(move);
556    IFNO(obj_move) return;
557    PINT(ed->x);
558    PINT(ed->y);
559    CLFN(obj_move);
560 }
561 void
562 _edje_script_only_move(Edje * ed)
563 {
564    SI;
565
566    DELJ(move);
567    ADDJ(move, _move_job);
568    IFNO(obj_move_immediate) return;
569    PINT(ed->x);
570    PINT(ed->y);
571    CLFN(obj_move_immediate);
572 }
573
574 static void
575 _resize_job(void *data)
576 {
577    Edje *ed = data;
578
579    SI;
580
581    ZERJ(resize);
582    PINT(ed->w);
583    PINT(ed->h);
584    CLFN(obj_resize);
585 }
586 void
587 _edje_script_only_resize(Edje * ed)
588 {
589    SI;
590
591    IFFN(obj_resize)
592    {
593       DELJ(resize);
594       ADDJ(resize, _resize_job);
595    }
596    PINT(ed->w);
597    PINT(ed->h);
598    CLFN(obj_resize_immediate);
599 }
600
601 void
602 _edje_script_only_message(Edje * ed, Edje_Message * em)
603 {
604    SI;
605
606    IFNO(obj_message) return;
607    _edje_message_parameters_push(em);
608    CLFN(obj_message);
609 }
610
611 /**************************************************/
612
613 static void
614 _call_fn(Edje * ed, const char *fname, Embryo_Function fn)
615 {
616    int ret;
617
618    ret = embryo_program_run(ed->collection->script, fn);
619    if (ret == EMBRYO_PROGRAM_FAIL)
620      {
621         ERR("ERROR with embryo script. "
622             "OBJECT NAME: '%s', "
623             "OBJECT FILE: '%s', "
624             "ENTRY POINT: '%s', "
625             "ERROR: '%s'",
626             ed->collection->part,
627             ed->file->path,
628             fname,
629             embryo_error_string_get(embryo_program_error_get(ed->collection->script)));
630      }
631    else if (ret == EMBRYO_PROGRAM_TOOLONG)
632      {
633         ERR("ERROR with embryo script. "
634             "OBJECT NAME: '%s', "
635             "OBJECT FILE: '%s', "
636             "ENTRY POINT: '%s', "
637             "ERROR: 'Script exceeded maximum allowed cycle count of %i'",
638             ed->collection->part,
639             ed->file->path,
640             fname, 
641             embryo_program_max_cycle_run_get(ed->collection->script));
642      }
643 }