diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/edje/src/lib/edje_program.c | 2090 |
1 files changed, 2090 insertions, 0 deletions
diff --git a/libraries/edje/src/lib/edje_program.c b/libraries/edje/src/lib/edje_program.c new file mode 100644 index 0000000..505b6a2 --- /dev/null +++ b/libraries/edje/src/lib/edje_program.c | |||
@@ -0,0 +1,2090 @@ | |||
1 | #include "edje_private.h" | ||
2 | |||
3 | static void _edje_emit_cb(Edje *ed, const char *sig, const char *src, Edje_Message_Signal_Data *data, Eina_Bool prop); | ||
4 | static void _edje_param_copy(Edje_Real_Part *src_part, const char *src_param, Edje_Real_Part *dst_part, const char *dst_param); | ||
5 | static void _edje_param_set(Edje_Real_Part *part, const char *param, const char *value); | ||
6 | |||
7 | int _edje_anim_count = 0; | ||
8 | Ecore_Animator *_edje_timer = NULL; | ||
9 | Eina_List *_edje_animators = NULL; | ||
10 | |||
11 | |||
12 | /*============================================================================* | ||
13 | * API * | ||
14 | *============================================================================*/ | ||
15 | |||
16 | EAPI void | ||
17 | edje_frametime_set(double t) | ||
18 | { | ||
19 | ecore_animator_frametime_set(t); | ||
20 | } | ||
21 | |||
22 | EAPI double | ||
23 | edje_frametime_get(void) | ||
24 | { | ||
25 | return ecore_animator_frametime_get(); | ||
26 | } | ||
27 | |||
28 | void | ||
29 | edje_object_propagate_callback_add(Evas_Object *obj, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source), void *data) | ||
30 | { | ||
31 | Edje *ed; | ||
32 | Edje_Signal_Callback *escb; | ||
33 | |||
34 | ed = _edje_fetch(obj); | ||
35 | if (!ed) return; | ||
36 | if (ed->delete_me) return; | ||
37 | escb = calloc(1, sizeof(Edje_Signal_Callback)); | ||
38 | escb->propagate = EINA_TRUE; | ||
39 | escb->signal = eina_stringshare_add("*"); | ||
40 | escb->source = eina_stringshare_add("*"); | ||
41 | escb->func = func; | ||
42 | escb->data = data; | ||
43 | ed->callbacks = eina_list_append(ed->callbacks, escb); | ||
44 | if (ed->walking_callbacks) | ||
45 | { | ||
46 | escb->just_added = 1; | ||
47 | ed->just_added_callbacks = 1; | ||
48 | } | ||
49 | else | ||
50 | _edje_callbacks_patterns_clean(ed); | ||
51 | } | ||
52 | |||
53 | EAPI void | ||
54 | edje_object_signal_callback_add(Evas_Object *obj, const char *emission, const char *source, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source), void *data) | ||
55 | { | ||
56 | Edje *ed; | ||
57 | Edje_Signal_Callback *escb; | ||
58 | |||
59 | if ((!emission) || (!source) || (!func)) return; | ||
60 | ed = _edje_fetch(obj); | ||
61 | if (!ed) return; | ||
62 | if (ed->delete_me) return; | ||
63 | escb = calloc(1, sizeof(Edje_Signal_Callback)); | ||
64 | if (emission[0]) | ||
65 | escb->signal = eina_stringshare_add(emission); | ||
66 | if (source[0]) | ||
67 | escb->source = eina_stringshare_add(source); | ||
68 | escb->func = func; | ||
69 | escb->data = data; | ||
70 | ed->callbacks = eina_list_append(ed->callbacks, escb); | ||
71 | if (ed->walking_callbacks) | ||
72 | { | ||
73 | escb->just_added = 1; | ||
74 | ed->just_added_callbacks = 1; | ||
75 | } | ||
76 | else | ||
77 | _edje_callbacks_patterns_clean(ed); | ||
78 | } | ||
79 | |||
80 | EAPI void * | ||
81 | edje_object_signal_callback_del(Evas_Object *obj, const char *emission, const char *source, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source)) | ||
82 | { | ||
83 | Edje *ed; | ||
84 | Eina_List *l; | ||
85 | Edje_Signal_Callback *escb; | ||
86 | |||
87 | if ((!emission) || (!source) || (!func)) return NULL; | ||
88 | ed = _edje_fetch(obj); | ||
89 | if (!ed) return NULL; | ||
90 | if (ed->delete_me) return NULL; | ||
91 | EINA_LIST_FOREACH(ed->callbacks, l, escb) | ||
92 | { | ||
93 | if ((escb->func == func) && | ||
94 | ((!escb->signal && !emission[0]) || | ||
95 | (escb->signal && !strcmp(escb->signal, emission))) && | ||
96 | ((!escb->source && !source[0]) || | ||
97 | (escb->source && !strcmp(escb->source, source)))) | ||
98 | { | ||
99 | void *data; | ||
100 | |||
101 | data = escb->data; | ||
102 | if (ed->walking_callbacks) | ||
103 | { | ||
104 | escb->delete_me = 1; | ||
105 | ed->delete_callbacks = 1; | ||
106 | } | ||
107 | else | ||
108 | { | ||
109 | _edje_callbacks_patterns_clean(ed); | ||
110 | |||
111 | ed->callbacks = eina_list_remove_list(ed->callbacks, l); | ||
112 | if (escb->signal) eina_stringshare_del(escb->signal); | ||
113 | if (escb->source) eina_stringshare_del(escb->source); | ||
114 | free(escb); | ||
115 | } | ||
116 | return data; | ||
117 | } | ||
118 | } | ||
119 | return NULL; | ||
120 | } | ||
121 | |||
122 | EAPI void * | ||
123 | edje_object_signal_callback_del_full(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func, void *data) | ||
124 | { | ||
125 | Edje *ed; | ||
126 | Eina_List *l; | ||
127 | Edje_Signal_Callback *escb; | ||
128 | |||
129 | if ((!emission) || (!source) || (!func)) return NULL; | ||
130 | ed = _edje_fetch(obj); | ||
131 | if (!ed) return NULL; | ||
132 | if (ed->delete_me) return NULL; | ||
133 | EINA_LIST_FOREACH(ed->callbacks, l, escb) | ||
134 | { | ||
135 | if ((escb->func == func) && (escb->data == data) && | ||
136 | ((!escb->signal && !emission[0]) || | ||
137 | (escb->signal && !strcmp(escb->signal, emission))) && | ||
138 | ((!escb->source && !source[0]) || | ||
139 | (escb->source && !strcmp(escb->source, source)))) | ||
140 | { | ||
141 | void *data2; | ||
142 | |||
143 | data2 = escb->data; | ||
144 | if (ed->walking_callbacks) | ||
145 | { | ||
146 | escb->delete_me = 1; | ||
147 | ed->delete_callbacks = 1; | ||
148 | } | ||
149 | else | ||
150 | { | ||
151 | _edje_callbacks_patterns_clean(ed); | ||
152 | |||
153 | ed->callbacks = eina_list_remove_list(ed->callbacks, l); | ||
154 | if (escb->signal) eina_stringshare_del(escb->signal); | ||
155 | if (escb->source) eina_stringshare_del(escb->source); | ||
156 | free(escb); | ||
157 | } | ||
158 | return data2; | ||
159 | } | ||
160 | } | ||
161 | return NULL; | ||
162 | } | ||
163 | |||
164 | EAPI void | ||
165 | edje_object_signal_emit(Evas_Object *obj, const char *emission, const char *source) | ||
166 | { | ||
167 | Edje *ed; | ||
168 | |||
169 | if ((!emission) || (!source)) return; | ||
170 | ed = _edje_fetch(obj); | ||
171 | if (!ed) return; | ||
172 | if (ed->delete_me) return; | ||
173 | _edje_emit(ed, (char *)emission, (char *)source); | ||
174 | } | ||
175 | |||
176 | /* FIXDOC: Verify/Expand */ | ||
177 | EAPI void | ||
178 | edje_object_play_set(Evas_Object *obj, Eina_Bool play) | ||
179 | { | ||
180 | Edje *ed; | ||
181 | double t; | ||
182 | Eina_List *l; | ||
183 | Edje_Running_Program *runp; | ||
184 | unsigned int i; | ||
185 | |||
186 | ed = _edje_fetch(obj); | ||
187 | if (!ed) return; | ||
188 | if (ed->delete_me) return; | ||
189 | if (play) | ||
190 | { | ||
191 | if (!ed->paused) return; | ||
192 | ed->paused = 0; | ||
193 | t = ecore_time_get() - ed->paused_at; | ||
194 | EINA_LIST_FOREACH(ed->actions, l, runp) | ||
195 | runp->start_time += t; | ||
196 | } | ||
197 | else | ||
198 | { | ||
199 | if (ed->paused) return; | ||
200 | ed->paused = EINA_TRUE; | ||
201 | ed->paused_at = ecore_time_get(); | ||
202 | } | ||
203 | |||
204 | for (i = 0; i < ed->table_parts_size; i++) | ||
205 | { | ||
206 | Edje_Real_Part *rp; | ||
207 | rp = ed->table_parts[i]; | ||
208 | if (rp->part->type == EDJE_PART_TYPE_GROUP && rp->swallowed_object) | ||
209 | edje_object_play_set(rp->swallowed_object, play); | ||
210 | } | ||
211 | } | ||
212 | |||
213 | EAPI Eina_Bool | ||
214 | edje_object_play_get(const Evas_Object *obj) | ||
215 | { | ||
216 | Edje *ed; | ||
217 | |||
218 | ed = _edje_fetch(obj); | ||
219 | if (!ed) return EINA_FALSE; | ||
220 | if (ed->delete_me) return EINA_FALSE; | ||
221 | if (ed->paused) return EINA_FALSE; | ||
222 | return EINA_TRUE; | ||
223 | } | ||
224 | |||
225 | /* FIXDOC: Verify/Expand */ | ||
226 | EAPI void | ||
227 | edje_object_animation_set(Evas_Object *obj, Eina_Bool on) | ||
228 | { | ||
229 | Edje *ed; | ||
230 | Eina_List *l; | ||
231 | unsigned int i; | ||
232 | |||
233 | ed = _edje_fetch(obj); | ||
234 | if (!ed) return; | ||
235 | if (ed->delete_me) return; | ||
236 | _edje_block(ed); | ||
237 | ed->no_anim = !on; | ||
238 | _edje_freeze(ed); | ||
239 | if (!on) | ||
240 | { | ||
241 | Eina_List *newl = NULL; | ||
242 | const void *data; | ||
243 | |||
244 | EINA_LIST_FOREACH(ed->actions, l, data) | ||
245 | newl = eina_list_append(newl, data); | ||
246 | while (newl) | ||
247 | { | ||
248 | Edje_Running_Program *runp; | ||
249 | |||
250 | runp = eina_list_data_get(newl); | ||
251 | newl = eina_list_remove(newl, eina_list_data_get(newl)); | ||
252 | _edje_program_run_iterate(runp, runp->start_time + TO_DOUBLE(runp->program->tween.time)); | ||
253 | if (_edje_block_break(ed)) | ||
254 | { | ||
255 | eina_list_free(newl); | ||
256 | goto break_prog; | ||
257 | } | ||
258 | } | ||
259 | } | ||
260 | else | ||
261 | { | ||
262 | _edje_emit(ed, "load", NULL); | ||
263 | if (evas_object_visible_get(obj)) | ||
264 | { | ||
265 | evas_object_hide(obj); | ||
266 | evas_object_show(obj); | ||
267 | } | ||
268 | } | ||
269 | break_prog: | ||
270 | |||
271 | for (i = 0; i < ed->table_parts_size; i++) | ||
272 | { | ||
273 | Edje_Real_Part *rp; | ||
274 | rp = ed->table_parts[i]; | ||
275 | if (rp->part->type == EDJE_PART_TYPE_GROUP && rp->swallowed_object) | ||
276 | edje_object_animation_set(rp->swallowed_object, on); | ||
277 | } | ||
278 | |||
279 | _edje_thaw(ed); | ||
280 | _edje_unblock(ed); | ||
281 | } | ||
282 | |||
283 | |||
284 | EAPI Eina_Bool | ||
285 | edje_object_animation_get(const Evas_Object *obj) | ||
286 | { | ||
287 | Edje *ed; | ||
288 | |||
289 | ed = _edje_fetch(obj); | ||
290 | if (!ed) return EINA_FALSE; | ||
291 | if (ed->delete_me) return EINA_FALSE; | ||
292 | if (ed->no_anim) return EINA_FALSE; | ||
293 | return EINA_TRUE; | ||
294 | } | ||
295 | |||
296 | /* Private Routines */ | ||
297 | |||
298 | Eina_Bool | ||
299 | _edje_program_run_iterate(Edje_Running_Program *runp, double tim) | ||
300 | { | ||
301 | FLOAT_T t, total; | ||
302 | Eina_List *l; | ||
303 | Edje *ed; | ||
304 | Edje_Program_Target *pt; | ||
305 | Edje_Real_Part *rp; | ||
306 | |||
307 | ed = runp->edje; | ||
308 | if (ed->delete_me) return EINA_FALSE; | ||
309 | _edje_block(ed); | ||
310 | _edje_ref(ed); | ||
311 | _edje_freeze(ed); | ||
312 | t = FROM_DOUBLE(tim - runp->start_time); | ||
313 | total = runp->program->tween.time; | ||
314 | t = DIV(t, total); | ||
315 | if (t > FROM_INT(1)) t = FROM_INT(1); | ||
316 | EINA_LIST_FOREACH(runp->program->targets, l, pt) | ||
317 | { | ||
318 | if (pt->id >= 0) | ||
319 | { | ||
320 | rp = ed->table_parts[pt->id % ed->table_parts_size]; | ||
321 | if (rp) _edje_part_pos_set(ed, rp, | ||
322 | runp->program->tween.mode, t, | ||
323 | runp->program->tween.v1, | ||
324 | runp->program->tween.v2); | ||
325 | } | ||
326 | } | ||
327 | if (t >= FROM_INT(1)) | ||
328 | { | ||
329 | Edje_Program_After *pa; | ||
330 | |||
331 | EINA_LIST_FOREACH(runp->program->targets, l, pt) | ||
332 | { | ||
333 | if (pt->id >= 0) | ||
334 | { | ||
335 | rp = ed->table_parts[pt->id % ed->table_parts_size]; | ||
336 | if (rp) | ||
337 | { | ||
338 | _edje_part_description_apply(ed, rp, | ||
339 | runp->program->state, | ||
340 | runp->program->value, | ||
341 | NULL, | ||
342 | 0.0); | ||
343 | _edje_part_pos_set(ed, rp, | ||
344 | runp->program->tween.mode, ZERO, | ||
345 | runp->program->tween.v1, | ||
346 | runp->program->tween.v2); | ||
347 | rp->program = NULL; | ||
348 | } | ||
349 | } | ||
350 | } | ||
351 | _edje_recalc(ed); | ||
352 | runp->delete_me = 1; | ||
353 | if (!ed->walking_actions) | ||
354 | { | ||
355 | _edje_anim_count--; | ||
356 | ed->actions = eina_list_remove(ed->actions, runp); | ||
357 | if (!ed->actions) | ||
358 | _edje_animators = eina_list_remove(_edje_animators, ed); | ||
359 | } | ||
360 | // _edje_emit(ed, "program,stop", runp->program->name); | ||
361 | if (_edje_block_break(ed)) | ||
362 | { | ||
363 | if (!ed->walking_actions) free(runp); | ||
364 | goto break_prog; | ||
365 | } | ||
366 | EINA_LIST_FOREACH(runp->program->after, l, pa) | ||
367 | { | ||
368 | Edje_Program *pr; | ||
369 | |||
370 | if (pa->id >= 0) | ||
371 | { | ||
372 | pr = ed->table_programs[pa->id % ed->table_programs_size]; | ||
373 | if (pr) _edje_program_run(ed, pr, 0, "", ""); | ||
374 | if (_edje_block_break(ed)) | ||
375 | { | ||
376 | if (!ed->walking_actions) free(runp); | ||
377 | goto break_prog; | ||
378 | } | ||
379 | } | ||
380 | } | ||
381 | _edje_thaw(ed); | ||
382 | _edje_unref(ed); | ||
383 | if (!ed->walking_actions) free(runp); | ||
384 | _edje_unblock(ed); | ||
385 | return EINA_FALSE; | ||
386 | } | ||
387 | break_prog: | ||
388 | _edje_recalc(ed); | ||
389 | _edje_thaw(ed); | ||
390 | _edje_unref(ed); | ||
391 | _edje_unblock(ed); | ||
392 | return EINA_TRUE; | ||
393 | } | ||
394 | |||
395 | void | ||
396 | _edje_program_end(Edje *ed, Edje_Running_Program *runp) | ||
397 | { | ||
398 | Eina_List *l; | ||
399 | Edje_Program_Target *pt; | ||
400 | // const char *pname = NULL; | ||
401 | int free_runp = 0; | ||
402 | |||
403 | if (ed->delete_me) return; | ||
404 | _edje_ref(ed); | ||
405 | _edje_freeze(ed); | ||
406 | EINA_LIST_FOREACH(runp->program->targets, l, pt) | ||
407 | { | ||
408 | Edje_Real_Part *rp; | ||
409 | |||
410 | if (pt->id >= 0) | ||
411 | { | ||
412 | rp = ed->table_parts[pt->id % ed->table_parts_size]; | ||
413 | if (rp) | ||
414 | { | ||
415 | _edje_part_description_apply(ed, rp, | ||
416 | runp->program->state, | ||
417 | runp->program->value, | ||
418 | NULL, | ||
419 | 0.0); | ||
420 | _edje_part_pos_set(ed, rp, | ||
421 | runp->program->tween.mode, ZERO, | ||
422 | runp->program->tween.v1, | ||
423 | runp->program->tween.v2); | ||
424 | rp->program = NULL; | ||
425 | } | ||
426 | } | ||
427 | } | ||
428 | _edje_recalc(ed); | ||
429 | runp->delete_me = 1; | ||
430 | // pname = runp->program->name; | ||
431 | if (!ed->walking_actions) | ||
432 | { | ||
433 | _edje_anim_count--; | ||
434 | ed->actions = eina_list_remove(ed->actions, runp); | ||
435 | free_runp = 1; | ||
436 | if (!ed->actions) | ||
437 | { | ||
438 | _edje_animators = eina_list_remove(_edje_animators, ed); | ||
439 | } | ||
440 | } | ||
441 | // _edje_emit(ed, "program,stop", pname); | ||
442 | _edje_thaw(ed); | ||
443 | _edje_unref(ed); | ||
444 | if (free_runp) free(runp); | ||
445 | } | ||
446 | |||
447 | void | ||
448 | _edje_program_run(Edje *ed, Edje_Program *pr, Eina_Bool force, const char *ssig, const char *ssrc) | ||
449 | { | ||
450 | Eina_List *l; | ||
451 | Edje_Real_Part *rp; | ||
452 | Edje_Program_Target *pt; | ||
453 | Edje_Program *pr2; | ||
454 | Edje_Program_After *pa; | ||
455 | /* limit self-feeding loops in programs to 64 levels */ | ||
456 | static int recursions = 0; | ||
457 | static int recursion_limit = 0; | ||
458 | |||
459 | if (ed->delete_me) return; | ||
460 | if ((pr->in.from > 0.0) && (pr->in.range >= 0.0) && (!force)) | ||
461 | { | ||
462 | Edje_Pending_Program *pp; | ||
463 | double r = 0.0; | ||
464 | |||
465 | pp = calloc(1, sizeof(Edje_Pending_Program)); | ||
466 | if (!pp) return; | ||
467 | if (pr->in.range > 0.0) r = ((double)rand() / RAND_MAX); | ||
468 | pp->timer = ecore_timer_add(pr->in.from + (pr->in.range * r), | ||
469 | _edje_pending_timer_cb, pp); | ||
470 | if (!pp->timer) | ||
471 | { | ||
472 | free(pp); | ||
473 | return; | ||
474 | } | ||
475 | pp->edje = ed; | ||
476 | pp->program = pr; | ||
477 | ed->pending_actions = eina_list_append(ed->pending_actions, pp); | ||
478 | return; | ||
479 | } | ||
480 | if ((recursions >= 64) || (recursion_limit)) | ||
481 | { | ||
482 | ERR("Programs recursing up to recursion limit of %i. Disabled.", | ||
483 | 64); | ||
484 | recursion_limit = 1; | ||
485 | return; | ||
486 | } | ||
487 | recursions++; | ||
488 | _edje_block(ed); | ||
489 | _edje_ref(ed); | ||
490 | _edje_freeze(ed); | ||
491 | switch (pr->action) | ||
492 | { | ||
493 | case EDJE_ACTION_TYPE_STATE_SET: | ||
494 | if ((pr->tween.time > ZERO) && (!ed->no_anim)) | ||
495 | { | ||
496 | Edje_Running_Program *runp; | ||
497 | |||
498 | runp = calloc(1, sizeof(Edje_Running_Program)); | ||
499 | EINA_LIST_FOREACH(pr->targets, l, pt) | ||
500 | { | ||
501 | if (pt->id >= 0) | ||
502 | { | ||
503 | rp = ed->table_parts[pt->id % ed->table_parts_size]; | ||
504 | if (rp) | ||
505 | { | ||
506 | if ((rp->object) && (pr->tween.mode & EDJE_TWEEN_MODE_OPT_FROM_CURRENT)) | ||
507 | { | ||
508 | Edje_Calc_Params *tmp; | ||
509 | |||
510 | tmp = calloc(1, sizeof(Edje_Calc_Params)); | ||
511 | if (!tmp) goto low_mem_current; | ||
512 | _edje_part_recalc(ed, rp, FLAG_XY, tmp); | ||
513 | |||
514 | if (rp->current) free(rp->current); | ||
515 | rp->current = tmp; | ||
516 | |||
517 | rp->current->x -= ed->x; | ||
518 | rp->current->y -= ed->y; | ||
519 | rp->current->map.center.x -= ed->x; | ||
520 | rp->current->map.center.y -= ed->y; | ||
521 | rp->current->map.light.x -= ed->x; | ||
522 | rp->current->map.light.y -= ed->y; | ||
523 | rp->current->map.persp.x -= ed->x; | ||
524 | rp->current->map.persp.y -= ed->y; | ||
525 | } | ||
526 | else | ||
527 | { | ||
528 | low_mem_current: | ||
529 | if (rp->current) free(rp->current); | ||
530 | rp->current = NULL; | ||
531 | } | ||
532 | |||
533 | if (rp->program) | ||
534 | _edje_program_end(ed, rp->program); | ||
535 | _edje_part_description_apply(ed, rp, | ||
536 | rp->param1.description->state.name, | ||
537 | rp->param1.description->state.value, | ||
538 | pr->state, | ||
539 | pr->value); | ||
540 | _edje_part_pos_set(ed, rp, pr->tween.mode, ZERO, | ||
541 | pr->tween.v1, | ||
542 | pr->tween.v2); | ||
543 | rp->program = runp; | ||
544 | } | ||
545 | } | ||
546 | } | ||
547 | // _edje_emit(ed, "program,start", pr->name); | ||
548 | if (_edje_block_break(ed)) | ||
549 | { | ||
550 | ed->actions = eina_list_append(ed->actions, runp); | ||
551 | goto break_prog; | ||
552 | } | ||
553 | if (!ed->actions) | ||
554 | _edje_animators = eina_list_append(_edje_animators, ed); | ||
555 | ed->actions = eina_list_append(ed->actions, runp); | ||
556 | runp->start_time = ecore_loop_time_get(); | ||
557 | runp->edje = ed; | ||
558 | runp->program = pr; | ||
559 | if (!_edje_timer) | ||
560 | _edje_timer = ecore_animator_add(_edje_timer_cb, NULL); | ||
561 | _edje_anim_count++; | ||
562 | } | ||
563 | else | ||
564 | { | ||
565 | EINA_LIST_FOREACH(pr->targets, l, pt) | ||
566 | { | ||
567 | if (pt->id >= 0) | ||
568 | { | ||
569 | rp = ed->table_parts[pt->id % ed->table_parts_size]; | ||
570 | if (rp) | ||
571 | { | ||
572 | if (rp->program) | ||
573 | _edje_program_end(ed, rp->program); | ||
574 | _edje_part_description_apply(ed, rp, | ||
575 | pr->state, | ||
576 | pr->value, | ||
577 | NULL, | ||
578 | 0.0); | ||
579 | _edje_part_pos_set(ed, rp, pr->tween.mode, ZERO, | ||
580 | pr->tween.v1, | ||
581 | pr->tween.v2); | ||
582 | } | ||
583 | } | ||
584 | } | ||
585 | // _edje_emit(ed, "program,start", pr->name); | ||
586 | if (_edje_block_break(ed)) goto break_prog; | ||
587 | // _edje_emit(ed, "program,stop", pr->name); | ||
588 | if (_edje_block_break(ed)) goto break_prog; | ||
589 | |||
590 | EINA_LIST_FOREACH(pr->after, l, pa) | ||
591 | { | ||
592 | if (pa->id >= 0) | ||
593 | { | ||
594 | pr2 = ed->table_programs[pa->id % ed->table_programs_size]; | ||
595 | if (pr2) _edje_program_run(ed, pr2, 0, "", ""); | ||
596 | if (_edje_block_break(ed)) goto break_prog; | ||
597 | } | ||
598 | } | ||
599 | _edje_recalc(ed); | ||
600 | } | ||
601 | break; | ||
602 | case EDJE_ACTION_TYPE_ACTION_STOP: | ||
603 | // _edje_emit(ed, "program,start", pr->name); | ||
604 | EINA_LIST_FOREACH(pr->targets, l, pt) | ||
605 | { | ||
606 | Eina_List *ll; | ||
607 | Edje_Running_Program *runp; | ||
608 | Edje_Pending_Program *pp; | ||
609 | |||
610 | for (ll = ed->actions; ll; ) | ||
611 | { | ||
612 | runp = ll->data; | ||
613 | ll = ll->next; | ||
614 | if (pt->id == runp->program->id) | ||
615 | { | ||
616 | _edje_program_end(ed, runp); | ||
617 | // goto done; | ||
618 | } | ||
619 | } | ||
620 | for (ll = ed->pending_actions; ll; ) | ||
621 | { | ||
622 | pp = ll->data; | ||
623 | ll = ll->next; | ||
624 | if (pt->id == pp->program->id) | ||
625 | { | ||
626 | ed->pending_actions = eina_list_remove(ed->pending_actions, pp); | ||
627 | ecore_timer_del(pp->timer); | ||
628 | free(pp); | ||
629 | // goto done; | ||
630 | } | ||
631 | } | ||
632 | // done: | ||
633 | // continue; | ||
634 | } | ||
635 | // _edje_emit(ed, "program,stop", pr->name); | ||
636 | if (_edje_block_break(ed)) goto break_prog; | ||
637 | break; | ||
638 | case EDJE_ACTION_TYPE_SIGNAL_EMIT: | ||
639 | // _edje_emit(ed, "program,start", pr->name); | ||
640 | if (_edje_block_break(ed)) goto break_prog; | ||
641 | _edje_emit(ed, pr->state, pr->state2); | ||
642 | if (_edje_block_break(ed)) goto break_prog; | ||
643 | // _edje_emit(ed, "program,stop", pr->name); | ||
644 | if (_edje_block_break(ed)) goto break_prog; | ||
645 | break; | ||
646 | case EDJE_ACTION_TYPE_DRAG_VAL_SET: | ||
647 | // _edje_emit(ed, "program,start", pr->name); | ||
648 | if (_edje_block_break(ed)) goto break_prog; | ||
649 | EINA_LIST_FOREACH(pr->targets, l, pt) | ||
650 | { | ||
651 | if (pt->id >= 0) | ||
652 | { | ||
653 | rp = ed->table_parts[pt->id % ed->table_parts_size]; | ||
654 | if ((rp) && (rp->drag) && (rp->drag->down.count == 0)) | ||
655 | { | ||
656 | rp->drag->val.x = pr->value; | ||
657 | rp->drag->val.y = pr->value2; | ||
658 | if (rp->drag->val.x < 0.0) rp->drag->val.x = 0.0; | ||
659 | else if (rp->drag->val.x > 1.0) rp->drag->val.x = 1.0; | ||
660 | if (rp->drag->val.y < 0.0) rp->drag->val.y = 0.0; | ||
661 | else if (rp->drag->val.y > 1.0) rp->drag->val.y = 1.0; | ||
662 | _edje_dragable_pos_set(ed, rp, rp->drag->val.x, rp->drag->val.y); | ||
663 | _edje_emit(ed, "drag,set", rp->part->name); | ||
664 | if (_edje_block_break(ed)) goto break_prog; | ||
665 | } | ||
666 | } | ||
667 | } | ||
668 | // _edje_emit(ed, "program,stop", pr->name); | ||
669 | if (_edje_block_break(ed)) goto break_prog; | ||
670 | break; | ||
671 | case EDJE_ACTION_TYPE_DRAG_VAL_STEP: | ||
672 | // _edje_emit(ed, "program,start", pr->name); | ||
673 | if (_edje_block_break(ed)) goto break_prog; | ||
674 | EINA_LIST_FOREACH(pr->targets, l, pt) | ||
675 | { | ||
676 | if (pt->id >= 0) | ||
677 | { | ||
678 | rp = ed->table_parts[pt->id % ed->table_parts_size]; | ||
679 | if ((rp) && (rp->drag) && (rp->drag->down.count == 0)) | ||
680 | { | ||
681 | rp->drag->val.x += pr->value * rp->drag->step.x * rp->part->dragable.x; | ||
682 | rp->drag->val.y += pr->value2 * rp->drag->step.y * rp->part->dragable.y; | ||
683 | if (rp->drag->val.x < 0.0) rp->drag->val.x = 0.0; | ||
684 | else if (rp->drag->val.x > 1.0) rp->drag->val.x = 1.0; | ||
685 | if (rp->drag->val.y < 0.0) rp->drag->val.y = 0.0; | ||
686 | else if (rp->drag->val.y > 1.0) rp->drag->val.y = 1.0; | ||
687 | _edje_dragable_pos_set(ed, rp, rp->drag->val.x, rp->drag->val.y); | ||
688 | _edje_emit(ed, "drag,step", rp->part->name); | ||
689 | if (_edje_block_break(ed)) goto break_prog; | ||
690 | } | ||
691 | } | ||
692 | } | ||
693 | // _edje_emit(ed, "program,stop", pr->name); | ||
694 | if (_edje_block_break(ed)) goto break_prog; | ||
695 | break; | ||
696 | case EDJE_ACTION_TYPE_DRAG_VAL_PAGE: | ||
697 | // _edje_emit(ed, "program,start", pr->name); | ||
698 | if (_edje_block_break(ed)) goto break_prog; | ||
699 | EINA_LIST_FOREACH(pr->targets, l, pt) | ||
700 | { | ||
701 | if (pt->id >= 0) | ||
702 | { | ||
703 | rp = ed->table_parts[pt->id % ed->table_parts_size]; | ||
704 | if ((rp) && (rp->drag) && (rp->drag->down.count == 0)) | ||
705 | { | ||
706 | rp->drag->val.x += pr->value * rp->drag->page.x * rp->part->dragable.x; | ||
707 | rp->drag->val.y += pr->value2 * rp->drag->page.y * rp->part->dragable.y; | ||
708 | if (rp->drag->val.x < 0.0) rp->drag->val.x = 0.0; | ||
709 | else if (rp->drag->val.x > 1.0) rp->drag->val.x = 1.0; | ||
710 | if (rp->drag->val.y < 0.0) rp->drag->val.y = 0.0; | ||
711 | else if (rp->drag->val.y > 1.0) rp->drag->val.y = 1.0; | ||
712 | _edje_dragable_pos_set(ed, rp, rp->drag->val.x, rp->drag->val.y); | ||
713 | _edje_emit(ed, "drag,page", rp->part->name); | ||
714 | if (_edje_block_break(ed)) goto break_prog; | ||
715 | } | ||
716 | } | ||
717 | } | ||
718 | // _edje_emit(ed, "program,stop", pr->name); | ||
719 | if (_edje_block_break(ed)) goto break_prog; | ||
720 | break; | ||
721 | case EDJE_ACTION_TYPE_SCRIPT: | ||
722 | { | ||
723 | char fname[128]; | ||
724 | |||
725 | // _edje_emit(ed, "program,start", pr->name); | ||
726 | if (_edje_block_break(ed)) goto break_prog; | ||
727 | snprintf(fname, sizeof(fname), "_p%i", pr->id); | ||
728 | _edje_embryo_test_run(ed, fname, ssig, ssrc); | ||
729 | // _edje_emit(ed, "program,stop", pr->name); | ||
730 | if (_edje_block_break(ed)) goto break_prog; | ||
731 | _edje_recalc_do(ed); | ||
732 | } | ||
733 | break; | ||
734 | case EDJE_ACTION_TYPE_FOCUS_SET: | ||
735 | if (!pr->targets) | ||
736 | ed->focused_part = NULL; | ||
737 | else | ||
738 | { | ||
739 | EINA_LIST_FOREACH(pr->targets, l, pt) | ||
740 | { | ||
741 | if (pt->id >= 0) | ||
742 | { | ||
743 | rp = ed->table_parts[pt->id % ed->table_parts_size]; | ||
744 | if (rp) | ||
745 | { | ||
746 | if (ed->focused_part != rp) | ||
747 | { | ||
748 | if (ed->focused_part) | ||
749 | _edje_emit(ed, "focus,part,out", | ||
750 | ed->focused_part->part->name); | ||
751 | ed->focused_part = rp; | ||
752 | _edje_emit(ed, "focus,part,in", | ||
753 | ed->focused_part->part->name); | ||
754 | } | ||
755 | } | ||
756 | } | ||
757 | } | ||
758 | } | ||
759 | break; | ||
760 | case EDJE_ACTION_TYPE_FOCUS_OBJECT: | ||
761 | if (!pr->targets) | ||
762 | { | ||
763 | Evas_Object *focused; | ||
764 | |||
765 | focused = evas_focus_get(evas_object_evas_get(ed->obj)); | ||
766 | if (focused) | ||
767 | { | ||
768 | unsigned int i; | ||
769 | |||
770 | /* Check if the current swallowed object is one of my child. */ | ||
771 | for (i = 0; i < ed->table_parts_size; ++i) | ||
772 | { | ||
773 | rp = ed->table_parts[i]; | ||
774 | if (rp && rp->swallowed_object == focused) | ||
775 | { | ||
776 | evas_object_focus_set(focused, EINA_FALSE); | ||
777 | break; | ||
778 | } | ||
779 | } | ||
780 | } | ||
781 | } | ||
782 | else | ||
783 | { | ||
784 | EINA_LIST_FOREACH(pr->targets, l, pt) | ||
785 | { | ||
786 | if (pt->id >= 0) | ||
787 | { | ||
788 | rp = ed->table_parts[pt->id % ed->table_parts_size]; | ||
789 | if (rp && rp->swallowed_object) | ||
790 | evas_object_focus_set(rp->swallowed_object, EINA_TRUE); | ||
791 | } | ||
792 | } | ||
793 | } | ||
794 | break; | ||
795 | case EDJE_ACTION_TYPE_SOUND_SAMPLE: | ||
796 | if (_edje_block_break(ed)) | ||
797 | goto break_prog; | ||
798 | _edje_multisense_internal_sound_sample_play(ed, pr->sample_name, pr->speed); | ||
799 | break; | ||
800 | case EDJE_ACTION_TYPE_SOUND_TONE: | ||
801 | if (_edje_block_break(ed)) | ||
802 | goto break_prog; | ||
803 | _edje_multisense_internal_sound_tone_play(ed, pr->tone_name, pr->duration); | ||
804 | break; | ||
805 | case EDJE_ACTION_TYPE_PARAM_COPY: | ||
806 | { | ||
807 | Edje_Real_Part *src_part, *dst_part; | ||
808 | |||
809 | // _edje_emit(ed, "program,start", pr->name); | ||
810 | if (_edje_block_break(ed)) goto break_prog; | ||
811 | |||
812 | src_part = ed->table_parts[pr->param.src % ed->table_parts_size]; | ||
813 | dst_part = ed->table_parts[pr->param.dst % ed->table_parts_size]; | ||
814 | _edje_param_copy(src_part, pr->state, dst_part, pr->state2); | ||
815 | |||
816 | if (_edje_block_break(ed)) goto break_prog; | ||
817 | // _edje_emit(ed, "program,stop", pr->name); | ||
818 | if (_edje_block_break(ed)) goto break_prog; | ||
819 | } | ||
820 | break; | ||
821 | case EDJE_ACTION_TYPE_PARAM_SET: | ||
822 | { | ||
823 | Edje_Real_Part *part; | ||
824 | |||
825 | // _edje_emit(ed, "program,start", pr->name); | ||
826 | if (_edje_block_break(ed)) goto break_prog; | ||
827 | |||
828 | part = ed->table_parts[pr->param.dst % ed->table_parts_size]; | ||
829 | _edje_param_set(part, pr->state, pr->state2); | ||
830 | |||
831 | if (_edje_block_break(ed)) goto break_prog; | ||
832 | // _edje_emit(ed, "program,stop", pr->name); | ||
833 | if (_edje_block_break(ed)) goto break_prog; | ||
834 | } | ||
835 | break; | ||
836 | default: | ||
837 | // _edje_emit(ed, "program,start", pr->name); | ||
838 | // _edje_emit(ed, "program,stop", pr->name); | ||
839 | break; | ||
840 | } | ||
841 | if (!((pr->action == EDJE_ACTION_TYPE_STATE_SET) | ||
842 | /* hmm this fucks somethgin up. must look into it later */ | ||
843 | /* && (pr->tween.time > ZERO) && (!ed->no_anim))) */ | ||
844 | )) | ||
845 | { | ||
846 | EINA_LIST_FOREACH(pr->after, l, pa) | ||
847 | { | ||
848 | if (pa->id >= 0) | ||
849 | { | ||
850 | pr2 = ed->table_programs[pa->id % ed->table_programs_size]; | ||
851 | if (pr2) _edje_program_run(ed, pr2, 0, "", ""); | ||
852 | if (_edje_block_break(ed)) goto break_prog; | ||
853 | } | ||
854 | } | ||
855 | } | ||
856 | break_prog: | ||
857 | _edje_thaw(ed); | ||
858 | _edje_unref(ed); | ||
859 | recursions--; | ||
860 | if (recursions == 0) recursion_limit = 0; | ||
861 | _edje_unblock(ed); | ||
862 | } | ||
863 | |||
864 | void | ||
865 | _edje_emit(Edje *ed, const char *sig, const char *src) | ||
866 | { | ||
867 | _edje_emit_full(ed, sig, src, NULL, NULL); | ||
868 | } | ||
869 | |||
870 | /* data should either be NULL or a malloc allocated data */ | ||
871 | void | ||
872 | _edje_emit_full(Edje *ed, const char *sig, const char *src, void *data, void (*free_func)(void *)) | ||
873 | { | ||
874 | Edje_Message_Signal emsg; | ||
875 | const char *sep; | ||
876 | |||
877 | if (ed->delete_me) return; | ||
878 | |||
879 | sep = strchr(sig, EDJE_PART_PATH_SEPARATOR); | ||
880 | |||
881 | /* If we are not sending the signal to a part of the child, the | ||
882 | * signal if for ourself | ||
883 | */ | ||
884 | if (sep) | ||
885 | { | ||
886 | Edje_Real_Part *rp = NULL; | ||
887 | const char *newsig; | ||
888 | Edje *ed2; | ||
889 | char *part; | ||
890 | char *idx; | ||
891 | size_t length; | ||
892 | |||
893 | /* the signal contains a colon, split the signal into "parts:signal" */ | ||
894 | length = sep - sig + 1; | ||
895 | part = alloca(length); | ||
896 | memcpy(part, sig, length - 1); | ||
897 | part[length - 1] = '\0'; | ||
898 | |||
899 | newsig = sep + 1; | ||
900 | |||
901 | /* lookup for alias */ | ||
902 | if (ed->collection && ed->collection->alias) | ||
903 | { | ||
904 | char *alias; | ||
905 | |||
906 | alias = eina_hash_find(ed->collection->alias, part); | ||
907 | if (alias) { | ||
908 | char *aliased; | ||
909 | int alien; | ||
910 | int nslen; | ||
911 | |||
912 | alien = strlen(alias); | ||
913 | nslen = strlen(newsig); | ||
914 | length = alien + nslen + 2; | ||
915 | |||
916 | aliased = alloca(length); | ||
917 | memcpy(aliased, alias, alien); | ||
918 | aliased[alien] = EDJE_PART_PATH_SEPARATOR; | ||
919 | memcpy(aliased + alien + 1, newsig, nslen + 1); | ||
920 | |||
921 | _edje_emit(ed, aliased, src); | ||
922 | return; | ||
923 | } | ||
924 | } | ||
925 | |||
926 | /* search for the index if present and remove it from the part */ | ||
927 | idx = strchr(part, EDJE_PART_PATH_SEPARATOR_INDEXL); | ||
928 | if (idx) | ||
929 | { | ||
930 | char *end; | ||
931 | |||
932 | end = strchr(idx + 1, EDJE_PART_PATH_SEPARATOR_INDEXR); | ||
933 | if (end && end != idx + 1) | ||
934 | { | ||
935 | char *tmp; | ||
936 | |||
937 | tmp = alloca(end - idx - 1); | ||
938 | memcpy(tmp, idx + 1, end - idx - 1); | ||
939 | tmp[end - idx - 1] = '\0'; | ||
940 | *idx = '\0'; | ||
941 | idx = tmp; | ||
942 | } | ||
943 | else | ||
944 | { | ||
945 | idx = NULL; | ||
946 | } | ||
947 | } | ||
948 | |||
949 | /* search for the right part now */ | ||
950 | rp = _edje_real_part_get(ed, part); | ||
951 | if (!rp) goto end; | ||
952 | |||
953 | switch (rp->part->type) | ||
954 | { | ||
955 | case EDJE_PART_TYPE_GROUP: | ||
956 | if (!rp->swallowed_object) goto end; | ||
957 | ed2 = _edje_fetch(rp->swallowed_object); | ||
958 | if (!ed2) goto end; | ||
959 | |||
960 | _edje_emit(ed2, newsig, src); | ||
961 | break; | ||
962 | |||
963 | case EDJE_PART_TYPE_EXTERNAL: | ||
964 | if (!rp->swallowed_object) break ; | ||
965 | |||
966 | if (!idx) | ||
967 | { | ||
968 | _edje_external_signal_emit(rp->swallowed_object, newsig, src); | ||
969 | } | ||
970 | else | ||
971 | { | ||
972 | Evas_Object *child; | ||
973 | |||
974 | child = _edje_children_get(rp, idx); | ||
975 | ed2 = _edje_fetch(child); | ||
976 | if (!ed2) goto end; | ||
977 | _edje_emit(ed2, newsig, src); | ||
978 | } | ||
979 | break ; | ||
980 | |||
981 | case EDJE_PART_TYPE_BOX: | ||
982 | case EDJE_PART_TYPE_TABLE: | ||
983 | if (idx) | ||
984 | { | ||
985 | Evas_Object *child; | ||
986 | |||
987 | child = _edje_children_get(rp, idx); | ||
988 | ed2 = _edje_fetch(child); | ||
989 | if (!ed2) goto end; | ||
990 | _edje_emit(ed2, newsig, src); | ||
991 | } | ||
992 | break ; | ||
993 | |||
994 | default: | ||
995 | fprintf(stderr, "SPANK SPANK SPANK !!!\nYou should never be here !\n"); | ||
996 | break; | ||
997 | } | ||
998 | } | ||
999 | |||
1000 | end: | ||
1001 | emsg.sig = sig; | ||
1002 | emsg.src = src; | ||
1003 | if (data) | ||
1004 | { | ||
1005 | emsg.data = calloc(1, sizeof(*(emsg.data))); | ||
1006 | emsg.data->ref = 1; | ||
1007 | emsg.data->data = data; | ||
1008 | emsg.data->free_func = free_func; | ||
1009 | } | ||
1010 | else | ||
1011 | { | ||
1012 | emsg.data = NULL; | ||
1013 | } | ||
1014 | /* new sends code */ | ||
1015 | edje_object_message_send(ed->obj, EDJE_MESSAGE_SIGNAL, 0, &emsg); | ||
1016 | /* old send code - use api now | ||
1017 | _edje_message_send(ed, EDJE_QUEUE_SCRIPT, EDJE_MESSAGE_SIGNAL, 0, &emsg); | ||
1018 | EINA_LIST_FOREACH(ed->subobjs, l, obj) | ||
1019 | { | ||
1020 | Edje *ed2; | ||
1021 | |||
1022 | ed2 = _edje_fetch(obj); | ||
1023 | if (!ed2) continue; | ||
1024 | if (ed2->delete_me) continue; | ||
1025 | _edje_message_send(ed2, EDJE_QUEUE_SCRIPT, EDJE_MESSAGE_SIGNAL, 0, &emsg); | ||
1026 | } | ||
1027 | */ | ||
1028 | if (emsg.data && (--(emsg.data->ref) == 0)) | ||
1029 | { | ||
1030 | if (emsg.data->free_func) | ||
1031 | { | ||
1032 | emsg.data->free_func(emsg.data->data); | ||
1033 | } | ||
1034 | free(emsg.data); | ||
1035 | } | ||
1036 | } | ||
1037 | |||
1038 | struct _Edje_Program_Data | ||
1039 | { | ||
1040 | #ifdef EDJE_PROGRAM_CACHE | ||
1041 | Eina_List *matches; | ||
1042 | int matched; | ||
1043 | #endif | ||
1044 | Edje *ed; | ||
1045 | const char *signal; | ||
1046 | const char *source; | ||
1047 | }; | ||
1048 | |||
1049 | static Eina_Bool _edje_glob_callback(Edje_Program *pr, void *dt) | ||
1050 | { | ||
1051 | struct _Edje_Program_Data *data = dt; | ||
1052 | Edje_Real_Part *rp = NULL; | ||
1053 | Eina_Bool exec = EINA_TRUE; | ||
1054 | |||
1055 | if (pr->filter.state) | ||
1056 | { | ||
1057 | rp = _edje_real_part_get(data->ed, pr->filter.part ? pr->filter.part : data->source); | ||
1058 | if (rp) | ||
1059 | exec = (rp->chosen_description->state.name == pr->filter.state); | ||
1060 | } | ||
1061 | |||
1062 | #ifdef EDJE_PROGRAM_CACHE | ||
1063 | data->matched++; | ||
1064 | #endif | ||
1065 | |||
1066 | if (exec) | ||
1067 | _edje_program_run(data->ed, pr, 0, data->signal, data->source); | ||
1068 | |||
1069 | if (_edje_block_break(data->ed)) | ||
1070 | { | ||
1071 | #ifdef EDJE_PROGRAM_CACHE | ||
1072 | eina_list_free(data->matches); | ||
1073 | data->matches = NULL; | ||
1074 | #endif | ||
1075 | return EINA_TRUE; | ||
1076 | } | ||
1077 | |||
1078 | #ifdef EDJE_PROGRAM_CACHE | ||
1079 | data->matches = eina_list_append(data->matches, pr); | ||
1080 | #endif | ||
1081 | |||
1082 | return EINA_FALSE; | ||
1083 | } | ||
1084 | |||
1085 | |||
1086 | void | ||
1087 | _edje_callbacks_patterns_clean(Edje *ed) | ||
1088 | { | ||
1089 | _edje_signals_sources_patterns_clean(&ed->patterns.callbacks); | ||
1090 | |||
1091 | eina_rbtree_delete(ed->patterns.callbacks.exact_match, | ||
1092 | EINA_RBTREE_FREE_CB(edje_match_signal_source_free), | ||
1093 | NULL); | ||
1094 | ed->patterns.callbacks.exact_match = NULL; | ||
1095 | |||
1096 | ed->patterns.callbacks.u.callbacks.globing = eina_list_free(ed->patterns.callbacks.u.callbacks.globing); | ||
1097 | } | ||
1098 | |||
1099 | static void | ||
1100 | _edje_callbacks_patterns_init(Edje *ed) | ||
1101 | { | ||
1102 | Edje_Signals_Sources_Patterns *ssp = &ed->patterns.callbacks; | ||
1103 | |||
1104 | if ((ssp->signals_patterns) || (ssp->sources_patterns) || | ||
1105 | (ssp->u.callbacks.globing) || (ssp->exact_match)) | ||
1106 | return; | ||
1107 | |||
1108 | ssp->u.callbacks.globing = edje_match_callback_hash_build(ed->callbacks, | ||
1109 | &ssp->exact_match); | ||
1110 | |||
1111 | ssp->signals_patterns = edje_match_callback_signal_init(ssp->u.callbacks.globing); | ||
1112 | ssp->sources_patterns = edje_match_callback_source_init(ssp->u.callbacks.globing); | ||
1113 | } | ||
1114 | |||
1115 | /* FIXME: what if we delete the evas object??? */ | ||
1116 | void | ||
1117 | _edje_emit_handle(Edje *ed, const char *sig, const char *src, | ||
1118 | Edje_Message_Signal_Data *sdata, Eina_Bool prop) | ||
1119 | { | ||
1120 | if (ed->delete_me) return; | ||
1121 | if (!sig) sig = ""; | ||
1122 | if (!src) src = ""; | ||
1123 | // printf("EDJE EMIT: (%p) signal: \"%s\" source: \"%s\"\n", ed, sig, src); | ||
1124 | _edje_block(ed); | ||
1125 | _edje_ref(ed); | ||
1126 | _edje_freeze(ed); | ||
1127 | |||
1128 | if (ed->collection && ed->L) | ||
1129 | _edje_lua2_script_func_signal(ed, sig, src); | ||
1130 | |||
1131 | if (ed->collection) | ||
1132 | { | ||
1133 | #ifdef EDJE_PROGRAM_CACHE | ||
1134 | Edje_Part_Collection *ec; | ||
1135 | char *tmps; | ||
1136 | int l1, l2; | ||
1137 | #endif | ||
1138 | int done; | ||
1139 | |||
1140 | #ifdef EDJE_PROGRAM_CACHE | ||
1141 | ec = ed->collection; | ||
1142 | l1 = strlen(sig); | ||
1143 | l2 = strlen(src); | ||
1144 | tmps = alloca(l1 + l2 + 3); /* \0, \337, \0 */ | ||
1145 | strcpy(tmps, sig); | ||
1146 | tmps[l1] = '\377'; | ||
1147 | strcpy(&(tmps[l1 + 1]), src); | ||
1148 | #endif | ||
1149 | done = 0; | ||
1150 | |||
1151 | #ifdef EDJE_PROGRAM_CACHE | ||
1152 | { | ||
1153 | Eina_List *matches; | ||
1154 | Eina_List *l; | ||
1155 | Edje_Program *pr; | ||
1156 | |||
1157 | if (eina_hash_find(ec->prog_cache.no_matches, tmps)) | ||
1158 | { | ||
1159 | done = 1; | ||
1160 | } | ||
1161 | else if ((matches = eina_hash_find(ec->prog_cache.matches, tmps))) | ||
1162 | { | ||
1163 | EINA_LIST_FOREACH(matches, l, pr) | ||
1164 | { | ||
1165 | Eina_Bool exec = EINA_TRUE; | ||
1166 | |||
1167 | if (pr->filter.state) | ||
1168 | { | ||
1169 | Edje_Real_Part *rp; | ||
1170 | |||
1171 | rp = _edje_real_part_get(ed, pr->filter.part ? pr->filter.part : src); | ||
1172 | if (rp) | ||
1173 | exec = (rp->chosen_description->state.name == pr->filter.state); | ||
1174 | } | ||
1175 | |||
1176 | if (exec) | ||
1177 | { | ||
1178 | _edje_program_run(ed, pr, 0, sig, src); | ||
1179 | if (_edje_block_break(ed)) | ||
1180 | { | ||
1181 | goto break_prog; | ||
1182 | } | ||
1183 | } | ||
1184 | } | ||
1185 | done = 1; | ||
1186 | } | ||
1187 | } | ||
1188 | #endif | ||
1189 | if (!done) | ||
1190 | { | ||
1191 | struct _Edje_Program_Data data; | ||
1192 | |||
1193 | data.ed = ed; | ||
1194 | data.source = src; | ||
1195 | data.signal = sig; | ||
1196 | #ifdef EDJE_PROGRAM_CACHE | ||
1197 | data.matched = 0; | ||
1198 | data.matches = NULL; | ||
1199 | #endif | ||
1200 | if (ed->table_programs_size > 0) | ||
1201 | { | ||
1202 | const Eina_List *match; | ||
1203 | const Eina_List *l; | ||
1204 | Edje_Program *pr; | ||
1205 | |||
1206 | if (ed->patterns.programs.u.programs.globing) | ||
1207 | if (edje_match_programs_exec(ed->patterns.programs.signals_patterns, | ||
1208 | ed->patterns.programs.sources_patterns, | ||
1209 | sig, | ||
1210 | src, | ||
1211 | ed->patterns.programs.u.programs.globing, | ||
1212 | _edje_glob_callback, | ||
1213 | &data, | ||
1214 | prop) == 0) | ||
1215 | goto break_prog; | ||
1216 | |||
1217 | match = edje_match_signal_source_hash_get(sig, src, | ||
1218 | ed->patterns.programs.exact_match); | ||
1219 | EINA_LIST_FOREACH(match, l, pr) | ||
1220 | _edje_glob_callback(pr, &data); | ||
1221 | } | ||
1222 | |||
1223 | #ifdef EDJE_PROGRAM_CACHE | ||
1224 | if (tmps) | ||
1225 | { | ||
1226 | if (data.matched == 0) | ||
1227 | { | ||
1228 | if (!ec->prog_cache.no_matches) | ||
1229 | ec->prog_cache.no_matches = eina_hash_string_superfast_new(NULL); | ||
1230 | eina_hash_add(ec->prog_cache.no_matches, tmps, ed); | ||
1231 | } | ||
1232 | else | ||
1233 | { | ||
1234 | if (!ec->prog_cache.matches) | ||
1235 | ec->prog_cache.matches = eina_hash_string_superfast_new(NULL); | ||
1236 | eina_hash_add(ec->prog_cache.matches, tmps, data.matches); | ||
1237 | } | ||
1238 | } | ||
1239 | #endif | ||
1240 | } | ||
1241 | _edje_emit_cb(ed, sig, src, sdata, prop); | ||
1242 | if (_edje_block_break(ed)) | ||
1243 | { | ||
1244 | goto break_prog; | ||
1245 | } | ||
1246 | } | ||
1247 | break_prog: | ||
1248 | _edje_thaw(ed); | ||
1249 | _edje_unref(ed); | ||
1250 | _edje_unblock(ed); | ||
1251 | } | ||
1252 | |||
1253 | /* Extra data for callbacks */ | ||
1254 | static void *callback_extra_data = NULL; | ||
1255 | |||
1256 | EAPI void * | ||
1257 | edje_object_signal_callback_extra_data_get(void) | ||
1258 | { | ||
1259 | return callback_extra_data; | ||
1260 | } | ||
1261 | |||
1262 | /* FIXME: what if we delete the evas object??? */ | ||
1263 | static void | ||
1264 | _edje_emit_cb(Edje *ed, const char *sig, const char *src, Edje_Message_Signal_Data *data, Eina_Bool prop) | ||
1265 | { | ||
1266 | Eina_List *l; | ||
1267 | |||
1268 | if (ed->delete_me) return; | ||
1269 | _edje_ref(ed); | ||
1270 | _edje_freeze(ed); | ||
1271 | _edje_block(ed); | ||
1272 | |||
1273 | if (ed->just_added_callbacks) | ||
1274 | _edje_callbacks_patterns_clean(ed); | ||
1275 | |||
1276 | ed->walking_callbacks = 1; | ||
1277 | |||
1278 | if (ed->callbacks) | ||
1279 | { | ||
1280 | Edje_Signal_Callback *escb; | ||
1281 | const Eina_List *match; | ||
1282 | const Eina_List *l2; | ||
1283 | int r = 1; | ||
1284 | callback_extra_data = (data) ? data->data : NULL; | ||
1285 | |||
1286 | _edje_callbacks_patterns_init(ed); | ||
1287 | if (ed->patterns.callbacks.u.callbacks.globing) | ||
1288 | r = edje_match_callback_exec(ed->patterns.callbacks.signals_patterns, | ||
1289 | ed->patterns.callbacks.sources_patterns, | ||
1290 | sig, | ||
1291 | src, | ||
1292 | ed->patterns.callbacks.u.callbacks.globing, | ||
1293 | ed, | ||
1294 | prop); | ||
1295 | |||
1296 | if (!r) | ||
1297 | goto break_prog; | ||
1298 | |||
1299 | match = edje_match_signal_source_hash_get(sig, src, | ||
1300 | ed->patterns.callbacks.exact_match); | ||
1301 | EINA_LIST_FOREACH(match, l2, escb) | ||
1302 | { | ||
1303 | if ((prop) && (escb->propagate)) continue; | ||
1304 | if ((!escb->just_added) && (!escb->delete_me)) | ||
1305 | { | ||
1306 | escb->func(escb->data, ed->obj, sig, src); | ||
1307 | if (_edje_block_break(ed)) | ||
1308 | goto break_prog; | ||
1309 | } | ||
1310 | } | ||
1311 | } | ||
1312 | break_prog: | ||
1313 | |||
1314 | ed->walking_callbacks = 0; | ||
1315 | if ((ed->delete_callbacks) || (ed->just_added_callbacks)) | ||
1316 | { | ||
1317 | ed->delete_callbacks = 0; | ||
1318 | ed->just_added_callbacks = 0; | ||
1319 | l = ed->callbacks; | ||
1320 | while (l) | ||
1321 | { | ||
1322 | Edje_Signal_Callback *escb = l->data; | ||
1323 | Eina_List *next_l = l->next; | ||
1324 | |||
1325 | if (escb->just_added) | ||
1326 | escb->just_added = 0; | ||
1327 | if (escb->delete_me) | ||
1328 | { | ||
1329 | ed->callbacks = eina_list_remove_list(ed->callbacks, l); | ||
1330 | if (escb->signal) eina_stringshare_del(escb->signal); | ||
1331 | if (escb->source) eina_stringshare_del(escb->source); | ||
1332 | free(escb); | ||
1333 | } | ||
1334 | l = next_l; | ||
1335 | } | ||
1336 | |||
1337 | _edje_callbacks_patterns_clean(ed); | ||
1338 | } | ||
1339 | _edje_unblock(ed); | ||
1340 | _edje_thaw(ed); | ||
1341 | _edje_unref(ed); | ||
1342 | } | ||
1343 | |||
1344 | static const Edje_External_Param_Info * | ||
1345 | _edje_external_param_info_get(const Evas_Object *obj, const char *name) | ||
1346 | { | ||
1347 | const Edje_External_Type *type; | ||
1348 | const Edje_External_Param_Info *info; | ||
1349 | |||
1350 | type = evas_object_data_get(obj, "Edje_External_Type"); | ||
1351 | if (!type) return NULL; | ||
1352 | for (info = type->parameters_info; info->name; info++) | ||
1353 | if (!strcmp(info->name, name)) return info; | ||
1354 | |||
1355 | return NULL; | ||
1356 | } | ||
1357 | |||
1358 | static Edje_External_Param * | ||
1359 | _edje_param_external_get(Edje_Real_Part *rp, const char *name, Edje_External_Param *param) | ||
1360 | { | ||
1361 | Evas_Object *swallowed_object = rp->swallowed_object; | ||
1362 | const Edje_External_Param_Info *info; | ||
1363 | |||
1364 | info = _edje_external_param_info_get(swallowed_object, name); | ||
1365 | if (!info) return NULL; | ||
1366 | |||
1367 | memset(param, 0, sizeof(*param)); | ||
1368 | param->name = info->name; | ||
1369 | param->type = info->type; | ||
1370 | if (!_edje_external_param_get(NULL, rp, param)) return NULL; | ||
1371 | return param; | ||
1372 | } | ||
1373 | |||
1374 | /* simulate external properties for native objects */ | ||
1375 | static Edje_External_Param * | ||
1376 | _edje_param_native_get(Edje_Real_Part *rp, const char *name, Edje_External_Param *param, void **free_ptr) | ||
1377 | { | ||
1378 | *free_ptr = NULL; | ||
1379 | if ((rp->part->type == EDJE_PART_TYPE_TEXT) || | ||
1380 | (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)) | ||
1381 | { | ||
1382 | if (!strcmp(name, "text")) | ||
1383 | { | ||
1384 | param->name = name; | ||
1385 | param->type = EDJE_EXTERNAL_PARAM_TYPE_STRING; | ||
1386 | |||
1387 | _edje_recalc_do(rp->edje); | ||
1388 | if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE) | ||
1389 | param->s = _edje_entry_text_get(rp); | ||
1390 | else if (rp->part->type == EDJE_PART_TYPE_TEXT) | ||
1391 | param->s = rp->text.text; | ||
1392 | else | ||
1393 | param->s = evas_object_textblock_text_markup_get(rp->object); | ||
1394 | return param; | ||
1395 | } | ||
1396 | if (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK) | ||
1397 | { | ||
1398 | if (!strcmp(name, "text_unescaped")) | ||
1399 | { | ||
1400 | param->name = name; | ||
1401 | param->type = EDJE_EXTERNAL_PARAM_TYPE_STRING; | ||
1402 | |||
1403 | _edje_recalc_do(rp->edje); | ||
1404 | if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE) | ||
1405 | { | ||
1406 | const char *tmp = _edje_entry_text_get(rp); | ||
1407 | char *unescaped = _edje_text_unescape(tmp); | ||
1408 | *free_ptr = unescaped; | ||
1409 | param->s = unescaped; | ||
1410 | } | ||
1411 | else if (rp->part->type == EDJE_PART_TYPE_TEXT) | ||
1412 | param->s = rp->text.text; | ||
1413 | else | ||
1414 | { | ||
1415 | const char *tmp; | ||
1416 | char *unescaped; | ||
1417 | |||
1418 | tmp = evas_object_textblock_text_markup_get(rp->object); | ||
1419 | unescaped = _edje_text_unescape(tmp); | ||
1420 | *free_ptr = unescaped; | ||
1421 | param->s = unescaped; | ||
1422 | } | ||
1423 | |||
1424 | return param; | ||
1425 | } | ||
1426 | |||
1427 | if ((rp->entry_data) && | ||
1428 | (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE) && | ||
1429 | (!strcmp(name, "select_allow"))) | ||
1430 | { | ||
1431 | param->name = name; | ||
1432 | param->type = EDJE_EXTERNAL_PARAM_TYPE_BOOL; | ||
1433 | param->i = _edje_entry_select_allow_get(rp); | ||
1434 | return param; | ||
1435 | } | ||
1436 | } | ||
1437 | } | ||
1438 | |||
1439 | if ((rp->drag) && (rp->drag->down.count == 0)) | ||
1440 | { | ||
1441 | if (!strncmp(name, "drag_", sizeof("drag_") - 1)) | ||
1442 | { | ||
1443 | const char *sub_name = name + sizeof("drag_") - 1; | ||
1444 | if (!strcmp(sub_name, "value_x")) | ||
1445 | { | ||
1446 | double d; | ||
1447 | |||
1448 | _edje_recalc_do(rp->edje); | ||
1449 | d = TO_DOUBLE(rp->drag->val.x); | ||
1450 | if (rp->part->dragable.x < 0) d = 1.0 - d; | ||
1451 | param->name = name; | ||
1452 | param->type = EDJE_EXTERNAL_PARAM_TYPE_DOUBLE; | ||
1453 | param->d = d; | ||
1454 | return param; | ||
1455 | } | ||
1456 | if (!strcmp(sub_name, "value_y")) | ||
1457 | { | ||
1458 | double d; | ||
1459 | |||
1460 | _edje_recalc_do(rp->edje); | ||
1461 | d = TO_DOUBLE(rp->drag->val.y); | ||
1462 | if (rp->part->dragable.y < 0) d = 1.0 - d; | ||
1463 | param->name = name; | ||
1464 | param->type = EDJE_EXTERNAL_PARAM_TYPE_DOUBLE; | ||
1465 | param->d = d; | ||
1466 | return param; | ||
1467 | } | ||
1468 | |||
1469 | if (!strcmp(sub_name, "size_w")) | ||
1470 | { | ||
1471 | _edje_recalc_do(rp->edje); | ||
1472 | param->name = name; | ||
1473 | param->type = EDJE_EXTERNAL_PARAM_TYPE_DOUBLE; | ||
1474 | param->d = TO_DOUBLE(rp->drag->size.x); | ||
1475 | return param; | ||
1476 | } | ||
1477 | if (!strcmp(sub_name, "size_h")) | ||
1478 | { | ||
1479 | _edje_recalc_do(rp->edje); | ||
1480 | param->name = name; | ||
1481 | param->type = EDJE_EXTERNAL_PARAM_TYPE_DOUBLE; | ||
1482 | param->d = TO_DOUBLE(rp->drag->size.y); | ||
1483 | return param; | ||
1484 | } | ||
1485 | |||
1486 | if (!strcmp(sub_name, "step_x")) | ||
1487 | { | ||
1488 | _edje_recalc_do(rp->edje); | ||
1489 | param->name = name; | ||
1490 | param->type = EDJE_EXTERNAL_PARAM_TYPE_DOUBLE; | ||
1491 | param->d = TO_DOUBLE(rp->drag->step.x); | ||
1492 | return param; | ||
1493 | } | ||
1494 | if (!strcmp(sub_name, "step_y")) | ||
1495 | { | ||
1496 | _edje_recalc_do(rp->edje); | ||
1497 | param->name = name; | ||
1498 | param->type = EDJE_EXTERNAL_PARAM_TYPE_DOUBLE; | ||
1499 | param->d = TO_DOUBLE(rp->drag->step.y); | ||
1500 | return param; | ||
1501 | } | ||
1502 | |||
1503 | if (!strcmp(sub_name, "page_x")) | ||
1504 | { | ||
1505 | _edje_recalc_do(rp->edje); | ||
1506 | param->name = name; | ||
1507 | param->type = EDJE_EXTERNAL_PARAM_TYPE_DOUBLE; | ||
1508 | param->d = TO_DOUBLE(rp->drag->page.x); | ||
1509 | return param; | ||
1510 | } | ||
1511 | if (!strcmp(sub_name, "page_y")) | ||
1512 | { | ||
1513 | _edje_recalc_do(rp->edje); | ||
1514 | param->name = name; | ||
1515 | param->type = EDJE_EXTERNAL_PARAM_TYPE_DOUBLE; | ||
1516 | param->d = TO_DOUBLE(rp->drag->page.y); | ||
1517 | return param; | ||
1518 | } | ||
1519 | |||
1520 | return NULL; | ||
1521 | } | ||
1522 | } | ||
1523 | |||
1524 | return NULL; | ||
1525 | } | ||
1526 | |||
1527 | static Eina_Bool | ||
1528 | _edje_param_native_set(Edje_Real_Part *rp, const char *name, const Edje_External_Param *param) | ||
1529 | { | ||
1530 | if ((rp->part->type == EDJE_PART_TYPE_TEXT) || | ||
1531 | (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)) | ||
1532 | { | ||
1533 | if (!strcmp(name, "text")) | ||
1534 | { | ||
1535 | if (param->type != EDJE_EXTERNAL_PARAM_TYPE_STRING) | ||
1536 | return EINA_FALSE; | ||
1537 | |||
1538 | _edje_object_part_text_raw_set | ||
1539 | (rp->edje->obj, rp, rp->part->name, param->s); | ||
1540 | return EINA_TRUE; | ||
1541 | } | ||
1542 | if (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK) | ||
1543 | { | ||
1544 | if (!strcmp(name, "text_unescaped")) | ||
1545 | { | ||
1546 | if (param->type != EDJE_EXTERNAL_PARAM_TYPE_STRING) | ||
1547 | return EINA_FALSE; | ||
1548 | |||
1549 | if (rp->part->type == EDJE_PART_TYPE_TEXT) | ||
1550 | _edje_object_part_text_raw_set | ||
1551 | (rp->edje->obj, rp, rp->part->name, param->s); | ||
1552 | else | ||
1553 | { | ||
1554 | char *escaped = _edje_text_escape(param->s); | ||
1555 | _edje_object_part_text_raw_set | ||
1556 | (rp->edje->obj, rp, rp->part->name, escaped); | ||
1557 | free(escaped); | ||
1558 | } | ||
1559 | |||
1560 | return EINA_TRUE; | ||
1561 | } | ||
1562 | |||
1563 | if ((rp->entry_data) && | ||
1564 | (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE) && | ||
1565 | (!strcmp(name, "select_allow"))) | ||
1566 | { | ||
1567 | if (param->type != EDJE_EXTERNAL_PARAM_TYPE_BOOL) | ||
1568 | return EINA_FALSE; | ||
1569 | _edje_entry_select_allow_set(rp, param->i); | ||
1570 | return EINA_TRUE; | ||
1571 | } | ||
1572 | } | ||
1573 | } | ||
1574 | |||
1575 | if ((rp->drag) && (rp->drag->down.count == 0)) | ||
1576 | { | ||
1577 | if (!strncmp(name, "drag_", sizeof("drag_") - 1)) | ||
1578 | { | ||
1579 | const char *sub_name = name + sizeof("drag_") - 1; | ||
1580 | if (!strcmp(sub_name, "value_x")) | ||
1581 | { | ||
1582 | double d; | ||
1583 | if (param->type != EDJE_EXTERNAL_PARAM_TYPE_DOUBLE) | ||
1584 | return EINA_FALSE; | ||
1585 | d = param->d; | ||
1586 | if (rp->part->dragable.confine_id != -1) | ||
1587 | d = CLAMP(d, 0.0, 1.0); | ||
1588 | if (rp->part->dragable.x < 0) d = 1.0 - d; | ||
1589 | if (rp->drag->val.x == FROM_DOUBLE(d)) return EINA_TRUE; | ||
1590 | rp->drag->val.x = FROM_DOUBLE(d); | ||
1591 | #ifdef EDJE_CALC_CACHE | ||
1592 | rp->invalidate = 1; | ||
1593 | #endif | ||
1594 | _edje_dragable_pos_set | ||
1595 | (rp->edje, rp, rp->drag->val.x, rp->drag->val.y); | ||
1596 | _edje_emit(rp->edje, "drag,set", rp->part->name); | ||
1597 | return EINA_TRUE; | ||
1598 | } | ||
1599 | if (!strcmp(sub_name, "value_y")) | ||
1600 | { | ||
1601 | double d; | ||
1602 | if (param->type != EDJE_EXTERNAL_PARAM_TYPE_DOUBLE) | ||
1603 | return EINA_FALSE; | ||
1604 | d = param->d; | ||
1605 | if (rp->part->dragable.confine_id != -1) | ||
1606 | d = CLAMP(d, 0.0, 1.0); | ||
1607 | if (rp->part->dragable.y < 0) d = 1.0 - d; | ||
1608 | if (rp->drag->val.y == FROM_DOUBLE(d)) return EINA_TRUE; | ||
1609 | rp->drag->val.y = FROM_DOUBLE(d); | ||
1610 | #ifdef EDJE_CALC_CACHE | ||
1611 | rp->invalidate = 1; | ||
1612 | #endif | ||
1613 | _edje_dragable_pos_set | ||
1614 | (rp->edje, rp, rp->drag->val.x, rp->drag->val.y); | ||
1615 | _edje_emit(rp->edje, "drag,set", rp->part->name); | ||
1616 | return EINA_TRUE; | ||
1617 | } | ||
1618 | |||
1619 | if (!strcmp(sub_name, "size_w")) | ||
1620 | { | ||
1621 | if (param->type != EDJE_EXTERNAL_PARAM_TYPE_DOUBLE) | ||
1622 | return EINA_FALSE; | ||
1623 | rp->drag->size.x = FROM_DOUBLE(CLAMP(param->d, 0.0, 1.0)); | ||
1624 | rp->edje->dirty = 1; | ||
1625 | #ifdef EDJE_CALC_CACHE | ||
1626 | rp->invalidate = 1; | ||
1627 | #endif | ||
1628 | _edje_recalc(rp->edje); | ||
1629 | return EINA_TRUE; | ||
1630 | } | ||
1631 | if (!strcmp(sub_name, "size_h")) | ||
1632 | { | ||
1633 | if (param->type != EDJE_EXTERNAL_PARAM_TYPE_DOUBLE) | ||
1634 | return EINA_FALSE; | ||
1635 | rp->drag->size.y = FROM_DOUBLE(CLAMP(param->d, 0.0, 1.0)); | ||
1636 | rp->edje->dirty = 1; | ||
1637 | #ifdef EDJE_CALC_CACHE | ||
1638 | rp->invalidate = 1; | ||
1639 | #endif | ||
1640 | _edje_recalc(rp->edje); | ||
1641 | return EINA_TRUE; | ||
1642 | } | ||
1643 | |||
1644 | if (!strcmp(sub_name, "step_x")) | ||
1645 | { | ||
1646 | if (param->type != EDJE_EXTERNAL_PARAM_TYPE_DOUBLE) | ||
1647 | return EINA_FALSE; | ||
1648 | rp->drag->step.x = FROM_DOUBLE(CLAMP(param->d, 0.0, 1.0)); | ||
1649 | #ifdef EDJE_CALC_CACHE | ||
1650 | rp->invalidate = 1; | ||
1651 | #endif | ||
1652 | return EINA_TRUE; | ||
1653 | } | ||
1654 | if (!strcmp(sub_name, "step_y")) | ||
1655 | { | ||
1656 | if (param->type != EDJE_EXTERNAL_PARAM_TYPE_DOUBLE) | ||
1657 | return EINA_FALSE; | ||
1658 | rp->drag->step.y = FROM_DOUBLE(CLAMP(param->d, 0.0, 1.0)); | ||
1659 | #ifdef EDJE_CALC_CACHE | ||
1660 | rp->invalidate = 1; | ||
1661 | #endif | ||
1662 | return EINA_TRUE; | ||
1663 | } | ||
1664 | |||
1665 | if (!strcmp(sub_name, "page_x")) | ||
1666 | { | ||
1667 | if (param->type != EDJE_EXTERNAL_PARAM_TYPE_DOUBLE) | ||
1668 | return EINA_FALSE; | ||
1669 | rp->drag->page.x = FROM_DOUBLE(CLAMP(param->d, 0.0, 1.0)); | ||
1670 | #ifdef EDJE_CALC_CACHE | ||
1671 | rp->invalidate = 1; | ||
1672 | #endif | ||
1673 | return EINA_TRUE; | ||
1674 | } | ||
1675 | if (!strcmp(sub_name, "page_y")) | ||
1676 | { | ||
1677 | if (param->type != EDJE_EXTERNAL_PARAM_TYPE_DOUBLE) | ||
1678 | return EINA_FALSE; | ||
1679 | rp->drag->page.y = FROM_DOUBLE(CLAMP(param->d, 0.0, 1.0)); | ||
1680 | #ifdef EDJE_CALC_CACHE | ||
1681 | rp->invalidate = 1; | ||
1682 | #endif | ||
1683 | return EINA_TRUE; | ||
1684 | } | ||
1685 | |||
1686 | return EINA_FALSE; | ||
1687 | } | ||
1688 | } | ||
1689 | |||
1690 | return EINA_FALSE; | ||
1691 | } | ||
1692 | |||
1693 | static const Edje_External_Param_Info * | ||
1694 | _edje_native_param_info_get(const Edje_Real_Part *rp, const char *name) | ||
1695 | { | ||
1696 | if ((rp->part->type == EDJE_PART_TYPE_TEXT) || | ||
1697 | (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)) | ||
1698 | { | ||
1699 | if (!strcmp(name, "text")) | ||
1700 | { | ||
1701 | static const Edje_External_Param_Info pi = | ||
1702 | EDJE_EXTERNAL_PARAM_INFO_STRING("text"); | ||
1703 | return π | ||
1704 | } | ||
1705 | if (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK) | ||
1706 | { | ||
1707 | if (!strcmp(name, "text_unescaped")) | ||
1708 | { | ||
1709 | static const Edje_External_Param_Info pi = | ||
1710 | EDJE_EXTERNAL_PARAM_INFO_STRING("text_unescaped"); | ||
1711 | return π | ||
1712 | } | ||
1713 | if (!strcmp(name, "select_allow")) | ||
1714 | { | ||
1715 | static const Edje_External_Param_Info pi = | ||
1716 | EDJE_EXTERNAL_PARAM_INFO_BOOL("text_unescaped"); | ||
1717 | return π | ||
1718 | } | ||
1719 | } | ||
1720 | } | ||
1721 | |||
1722 | if ((rp->drag) && (rp->drag->down.count == 0)) | ||
1723 | { | ||
1724 | if (!strncmp(name, "drag_", sizeof("drag_") - 1)) | ||
1725 | { | ||
1726 | name += sizeof("drag_") - 1; | ||
1727 | if (!strcmp(name, "value_x")) | ||
1728 | { | ||
1729 | static const Edje_External_Param_Info pi = | ||
1730 | EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_value_x"); | ||
1731 | return π | ||
1732 | } | ||
1733 | if (!strcmp(name, "value_y")) | ||
1734 | { | ||
1735 | static const Edje_External_Param_Info pi = | ||
1736 | EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_value_y"); | ||
1737 | return π | ||
1738 | } | ||
1739 | if (!strcmp(name, "size_w")) | ||
1740 | { | ||
1741 | static const Edje_External_Param_Info pi = | ||
1742 | EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_size_w"); | ||
1743 | return π | ||
1744 | } | ||
1745 | if (!strcmp(name, "size_h")) | ||
1746 | { | ||
1747 | static const Edje_External_Param_Info pi = | ||
1748 | EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_size_h"); | ||
1749 | return π | ||
1750 | } | ||
1751 | if (!strcmp(name, "step_x")) | ||
1752 | { | ||
1753 | static const Edje_External_Param_Info pi = | ||
1754 | EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_step_x"); | ||
1755 | return π | ||
1756 | } | ||
1757 | if (!strcmp(name, "step_y")) | ||
1758 | { | ||
1759 | static const Edje_External_Param_Info pi = | ||
1760 | EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_step_y"); | ||
1761 | return π | ||
1762 | } | ||
1763 | if (!strcmp(name, "page_x")) | ||
1764 | { | ||
1765 | static const Edje_External_Param_Info pi = | ||
1766 | EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_page_x"); | ||
1767 | return π | ||
1768 | } | ||
1769 | if (!strcmp(name, "page_y")) | ||
1770 | { | ||
1771 | static const Edje_External_Param_Info pi = | ||
1772 | EDJE_EXTERNAL_PARAM_INFO_DOUBLE("drag_page_y"); | ||
1773 | return π | ||
1774 | } | ||
1775 | |||
1776 | return NULL; | ||
1777 | } | ||
1778 | } | ||
1779 | |||
1780 | return NULL; | ||
1781 | } | ||
1782 | |||
1783 | static Edje_External_Param * | ||
1784 | _edje_param_convert(Edje_External_Param *param, const Edje_External_Param_Info *dst_info) | ||
1785 | { | ||
1786 | if (param->type == dst_info->type) return param; | ||
1787 | |||
1788 | switch (dst_info->type) | ||
1789 | { | ||
1790 | case EDJE_EXTERNAL_PARAM_TYPE_BOOL: | ||
1791 | case EDJE_EXTERNAL_PARAM_TYPE_INT: | ||
1792 | { | ||
1793 | int i; | ||
1794 | switch (param->type) | ||
1795 | { | ||
1796 | case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE: | ||
1797 | i = (int)param->d; | ||
1798 | break; | ||
1799 | case EDJE_EXTERNAL_PARAM_TYPE_STRING: | ||
1800 | case EDJE_EXTERNAL_PARAM_TYPE_CHOICE: | ||
1801 | i = (param->s) ? atoi(param->s) : 0; | ||
1802 | break; | ||
1803 | case EDJE_EXTERNAL_PARAM_TYPE_BOOL: | ||
1804 | case EDJE_EXTERNAL_PARAM_TYPE_INT: | ||
1805 | i = param->i; | ||
1806 | break; | ||
1807 | default: | ||
1808 | return NULL; | ||
1809 | } | ||
1810 | if (dst_info->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL) | ||
1811 | i = !!i; | ||
1812 | param->type = dst_info->type; | ||
1813 | param->i = i; | ||
1814 | return param; | ||
1815 | } | ||
1816 | |||
1817 | case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE: | ||
1818 | { | ||
1819 | double d; | ||
1820 | switch (param->type) | ||
1821 | { | ||
1822 | case EDJE_EXTERNAL_PARAM_TYPE_INT: | ||
1823 | d = (double)param->i; | ||
1824 | break; | ||
1825 | case EDJE_EXTERNAL_PARAM_TYPE_STRING: | ||
1826 | case EDJE_EXTERNAL_PARAM_TYPE_CHOICE: | ||
1827 | d = (param->s) ? atof(param->s) : 0.0; | ||
1828 | break; | ||
1829 | case EDJE_EXTERNAL_PARAM_TYPE_BOOL: | ||
1830 | d = (double)param->i; | ||
1831 | break; | ||
1832 | default: | ||
1833 | return NULL; | ||
1834 | } | ||
1835 | param->type = dst_info->type; | ||
1836 | param->d = d; | ||
1837 | return param; | ||
1838 | } | ||
1839 | |||
1840 | case EDJE_EXTERNAL_PARAM_TYPE_STRING: | ||
1841 | { | ||
1842 | static char s[64]; | ||
1843 | switch (param->type) | ||
1844 | { | ||
1845 | case EDJE_EXTERNAL_PARAM_TYPE_BOOL: | ||
1846 | case EDJE_EXTERNAL_PARAM_TYPE_INT: | ||
1847 | if (!snprintf(s, sizeof(s), "%i", param->i)) return NULL; | ||
1848 | break; | ||
1849 | case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE: | ||
1850 | if (!snprintf(s, sizeof(s), "%f", param->d)) return NULL; | ||
1851 | break; | ||
1852 | case EDJE_EXTERNAL_PARAM_TYPE_CHOICE: | ||
1853 | param->type = dst_info->type; | ||
1854 | return param; | ||
1855 | default: | ||
1856 | return NULL; | ||
1857 | } | ||
1858 | param->type = dst_info->type; | ||
1859 | param->s = s; | ||
1860 | return param; | ||
1861 | } | ||
1862 | |||
1863 | case EDJE_EXTERNAL_PARAM_TYPE_CHOICE: | ||
1864 | { | ||
1865 | static char s[64]; | ||
1866 | const char *val; | ||
1867 | switch (param->type) | ||
1868 | { | ||
1869 | case EDJE_EXTERNAL_PARAM_TYPE_BOOL: | ||
1870 | case EDJE_EXTERNAL_PARAM_TYPE_INT: | ||
1871 | if (!snprintf(s, sizeof(s), "%i", param->i)) return NULL; | ||
1872 | val = s; | ||
1873 | break; | ||
1874 | case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE: | ||
1875 | if (!snprintf(s, sizeof(s), "%f", param->d)) return NULL; | ||
1876 | val = s; | ||
1877 | break; | ||
1878 | case EDJE_EXTERNAL_PARAM_TYPE_STRING: | ||
1879 | val = param->s; | ||
1880 | break; | ||
1881 | default: | ||
1882 | return NULL; | ||
1883 | } | ||
1884 | |||
1885 | param->type = dst_info->type; | ||
1886 | if (param->s != val) param->s = val; | ||
1887 | return param; | ||
1888 | } | ||
1889 | |||
1890 | default: return NULL; | ||
1891 | } | ||
1892 | } | ||
1893 | |||
1894 | static Eina_Bool | ||
1895 | _edje_param_validate(const Edje_External_Param *param, const Edje_External_Param_Info *info) | ||
1896 | { | ||
1897 | switch (info->type) | ||
1898 | { | ||
1899 | case EDJE_EXTERNAL_PARAM_TYPE_BOOL: | ||
1900 | return ((param->i == 0) || (param->i == 1)); | ||
1901 | |||
1902 | case EDJE_EXTERNAL_PARAM_TYPE_INT: | ||
1903 | if ((info->info.i.min != EDJE_EXTERNAL_INT_UNSET) && | ||
1904 | (info->info.i.min > param->i)) | ||
1905 | return EINA_FALSE; | ||
1906 | |||
1907 | if ((info->info.i.max != EDJE_EXTERNAL_INT_UNSET) && | ||
1908 | (info->info.i.max < param->i)) | ||
1909 | return EINA_FALSE; | ||
1910 | |||
1911 | return EINA_TRUE; | ||
1912 | |||
1913 | case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE: | ||
1914 | if ((info->info.d.min != EDJE_EXTERNAL_DOUBLE_UNSET) && | ||
1915 | (info->info.d.min > param->d)) | ||
1916 | return EINA_FALSE; | ||
1917 | |||
1918 | if ((info->info.d.max != EDJE_EXTERNAL_DOUBLE_UNSET) && | ||
1919 | (info->info.d.max < param->d)) | ||
1920 | return EINA_FALSE; | ||
1921 | |||
1922 | return EINA_TRUE; | ||
1923 | |||
1924 | case EDJE_EXTERNAL_PARAM_TYPE_STRING: | ||
1925 | if (!param->s) return EINA_FALSE; | ||
1926 | if (info->info.s.accept_fmt) | ||
1927 | INF("string 'accept_fmt' validation not implemented."); | ||
1928 | if (info->info.s.deny_fmt) | ||
1929 | INF("string 'deny_fmt' validation not implemented."); | ||
1930 | return EINA_TRUE; | ||
1931 | |||
1932 | case EDJE_EXTERNAL_PARAM_TYPE_CHOICE: | ||
1933 | { | ||
1934 | const char **itr = info->info.c.choices; | ||
1935 | if (!itr) return EINA_FALSE; | ||
1936 | for (; *itr; itr++) | ||
1937 | if (!strcmp(*itr, param->s)) | ||
1938 | return EINA_TRUE; | ||
1939 | return EINA_FALSE; | ||
1940 | } | ||
1941 | |||
1942 | default: return EINA_FALSE; | ||
1943 | } | ||
1944 | } | ||
1945 | |||
1946 | static void | ||
1947 | _edje_param_copy(Edje_Real_Part *src_part, const char *src_param, Edje_Real_Part *dst_part, const char *dst_param) | ||
1948 | { | ||
1949 | Edje_External_Param val; | ||
1950 | const Edje_External_Param_Info *dst_info; | ||
1951 | void *free_ptr = NULL; | ||
1952 | |||
1953 | if ((!src_part) || (!src_param) || (!dst_part) || (!dst_param)) | ||
1954 | return; | ||
1955 | |||
1956 | if (dst_part->part->type == EDJE_PART_TYPE_EXTERNAL) | ||
1957 | dst_info = _edje_external_param_info_get | ||
1958 | (dst_part->swallowed_object, dst_param); | ||
1959 | else | ||
1960 | dst_info = _edje_native_param_info_get(dst_part, dst_param); | ||
1961 | |||
1962 | if (!dst_info) | ||
1963 | { | ||
1964 | ERR("cannot copy, invalid destination parameter '%s' of part '%s'", | ||
1965 | dst_param, dst_part->part->name); | ||
1966 | return; | ||
1967 | } | ||
1968 | |||
1969 | if (src_part->part->type == EDJE_PART_TYPE_EXTERNAL) | ||
1970 | { | ||
1971 | if (!_edje_param_external_get | ||
1972 | (src_part, src_param, &val)) | ||
1973 | { | ||
1974 | ERR("cannot get parameter '%s' of part '%s'", | ||
1975 | src_param, src_part->part->name); | ||
1976 | return; | ||
1977 | } | ||
1978 | } | ||
1979 | else | ||
1980 | { | ||
1981 | if (!_edje_param_native_get(src_part, src_param, &val, &free_ptr)) | ||
1982 | { | ||
1983 | ERR("cannot get parameter '%s' of part '%s'", | ||
1984 | src_param, src_part->part->name); | ||
1985 | return; | ||
1986 | } | ||
1987 | } | ||
1988 | |||
1989 | if (!_edje_param_convert(&val, dst_info)) | ||
1990 | { | ||
1991 | ERR("cannot convert parameter type %s to requested type %s", | ||
1992 | edje_external_param_type_str(val.type), | ||
1993 | edje_external_param_type_str(dst_info->type)); | ||
1994 | goto end; | ||
1995 | } | ||
1996 | |||
1997 | if (!_edje_param_validate(&val, dst_info)) | ||
1998 | { | ||
1999 | ERR("incorrect parameter value failed validation for type %s", | ||
2000 | edje_external_param_type_str(dst_info->type)); | ||
2001 | goto end; | ||
2002 | } | ||
2003 | |||
2004 | if (dst_part->part->type == EDJE_PART_TYPE_EXTERNAL) | ||
2005 | { | ||
2006 | val.name = dst_param; | ||
2007 | if (!_edje_external_param_set(NULL, dst_part, &val)) | ||
2008 | { | ||
2009 | ERR("failed to set parameter '%s' (%s) of part '%s'", | ||
2010 | dst_param, edje_external_param_type_str(dst_info->type), | ||
2011 | dst_part->part->name); | ||
2012 | goto end; | ||
2013 | } | ||
2014 | } | ||
2015 | else | ||
2016 | { | ||
2017 | if (!_edje_param_native_set(dst_part, dst_param, &val)) | ||
2018 | { | ||
2019 | ERR("failed to set parameter '%s' (%s) of part '%s'", | ||
2020 | dst_param, edje_external_param_type_str(dst_info->type), | ||
2021 | dst_part->part->name); | ||
2022 | goto end; | ||
2023 | } | ||
2024 | } | ||
2025 | |||
2026 | end: | ||
2027 | free(free_ptr); | ||
2028 | } | ||
2029 | |||
2030 | static void | ||
2031 | _edje_param_set(Edje_Real_Part *part, const char *param, const char *value) | ||
2032 | { | ||
2033 | Edje_External_Param val; | ||
2034 | const Edje_External_Param_Info *info; | ||
2035 | |||
2036 | if ((!part) || (!param) || (!value)) | ||
2037 | return; | ||
2038 | |||
2039 | if (part->part->type == EDJE_PART_TYPE_EXTERNAL) | ||
2040 | info = _edje_external_param_info_get(part->swallowed_object, param); | ||
2041 | else | ||
2042 | info = _edje_native_param_info_get(part, param); | ||
2043 | |||
2044 | if (!info) | ||
2045 | { | ||
2046 | ERR("cannot copy, invalid destination parameter '%s' of part '%s'", | ||
2047 | param, part->part->name); | ||
2048 | return; | ||
2049 | } | ||
2050 | |||
2051 | val.name = "(temp)"; | ||
2052 | val.type = EDJE_EXTERNAL_PARAM_TYPE_STRING; | ||
2053 | val.s = value; | ||
2054 | |||
2055 | if (!_edje_param_convert(&val, info)) | ||
2056 | { | ||
2057 | ERR("cannot convert parameter type STRING to requested type %s", | ||
2058 | edje_external_param_type_str(info->type)); | ||
2059 | return; | ||
2060 | } | ||
2061 | |||
2062 | if (!_edje_param_validate(&val, info)) | ||
2063 | { | ||
2064 | ERR("incorrect parameter value failed validation for type %s", | ||
2065 | edje_external_param_type_str(info->type)); | ||
2066 | return; | ||
2067 | } | ||
2068 | |||
2069 | if (part->part->type == EDJE_PART_TYPE_EXTERNAL) | ||
2070 | { | ||
2071 | val.name = param; | ||
2072 | if (!_edje_external_param_set(NULL, part, &val)) | ||
2073 | { | ||
2074 | ERR("failed to set parameter '%s' (%s) of part '%s'", | ||
2075 | param, edje_external_param_type_str(info->type), | ||
2076 | part->part->name); | ||
2077 | return; | ||
2078 | } | ||
2079 | } | ||
2080 | else | ||
2081 | { | ||
2082 | if (!_edje_param_native_set(part, param, &val)) | ||
2083 | { | ||
2084 | ERR("failed to set parameter '%s' (%s) of part '%s'", | ||
2085 | param, edje_external_param_type_str(info->type), | ||
2086 | part->part->name); | ||
2087 | return; | ||
2088 | } | ||
2089 | } | ||
2090 | } | ||