aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/lib/canvas/evas_object_smart.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libraries/evas/src/lib/canvas/evas_object_smart.c920
1 files changed, 920 insertions, 0 deletions
diff --git a/libraries/evas/src/lib/canvas/evas_object_smart.c b/libraries/evas/src/lib/canvas/evas_object_smart.c
new file mode 100644
index 0000000..a7dfcdf
--- /dev/null
+++ b/libraries/evas/src/lib/canvas/evas_object_smart.c
@@ -0,0 +1,920 @@
1#include "evas_common.h"
2#include "evas_private.h"
3
4typedef struct _Evas_Object_Smart Evas_Object_Smart;
5typedef struct _Evas_Smart_Callback Evas_Smart_Callback;
6
7struct _Evas_Object_Smart
8{
9 DATA32 magic;
10 void *engine_data;
11 void *data;
12 Eina_List *callbacks;
13 Eina_Inlist *contained;
14 Evas_Smart_Cb_Description_Array callbacks_descriptions;
15 int walking_list;
16 Eina_Bool deletions_waiting : 1;
17 Eina_Bool need_recalculate : 1;
18};
19
20struct _Evas_Smart_Callback
21{
22 const char *event;
23 Evas_Smart_Cb func;
24 void *func_data;
25 Evas_Callback_Priority priority;
26 char delete_me : 1;
27};
28
29/* private methods for smart objects */
30static void evas_object_smart_callbacks_clear(Evas_Object *obj);
31static void evas_object_smart_init(Evas_Object *obj);
32static void *evas_object_smart_new(void);
33static void evas_object_smart_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y);
34static void evas_object_smart_free(Evas_Object *obj);
35static void evas_object_smart_render_pre(Evas_Object *obj);
36static void evas_object_smart_render_post(Evas_Object *obj);
37
38static unsigned int evas_object_smart_id_get(Evas_Object *obj);
39static unsigned int evas_object_smart_visual_id_get(Evas_Object *obj);
40static void *evas_object_smart_engine_data_get(Evas_Object *obj);
41
42static const Evas_Object_Func object_func =
43{
44 /* methods (compulsory) */
45 evas_object_smart_free,
46 evas_object_smart_render,
47 evas_object_smart_render_pre,
48 evas_object_smart_render_post,
49 evas_object_smart_id_get,
50 evas_object_smart_visual_id_get,
51 evas_object_smart_engine_data_get,
52 /* these are optional. NULL = nothing */
53 NULL,
54 NULL,
55 NULL,
56 NULL,
57 NULL,
58 NULL,
59 NULL,
60 NULL,
61 NULL,
62 NULL,
63 NULL,
64 NULL,
65 NULL
66};
67
68EVAS_MEMPOOL(_mp_obj);
69EVAS_MEMPOOL(_mp_cb);
70
71/* public funcs */
72EAPI void
73evas_object_smart_data_set(Evas_Object *obj, void *data)
74{
75 Evas_Object_Smart *o;
76
77 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
78 return;
79 MAGIC_CHECK_END();
80 o = (Evas_Object_Smart *)(obj->object_data);
81 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
82 return;
83 MAGIC_CHECK_END();
84 o->data = data;
85}
86
87EAPI void *
88evas_object_smart_data_get(const Evas_Object *obj)
89{
90 Evas_Object_Smart *o;
91
92 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
93 return NULL;
94 MAGIC_CHECK_END();
95 o = (Evas_Object_Smart *)(obj->object_data);
96 if (!o) return NULL;
97 return o->data;
98}
99
100EAPI Evas_Smart *
101evas_object_smart_smart_get(const Evas_Object *obj)
102{
103 Evas_Object_Smart *o;
104
105 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
106 return NULL;
107 MAGIC_CHECK_END();
108 o = (Evas_Object_Smart *)(obj->object_data);
109 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
110 return NULL;
111 MAGIC_CHECK_END();
112 return obj->smart.smart;
113}
114
115EAPI void
116evas_object_smart_member_add(Evas_Object *obj, Evas_Object *smart_obj)
117{
118 Evas_Object_Smart *o;
119
120 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
121 return;
122 MAGIC_CHECK_END();
123 MAGIC_CHECK(smart_obj, Evas_Object, MAGIC_OBJ);
124 return;
125 MAGIC_CHECK_END();
126 o = (Evas_Object_Smart *)(smart_obj->object_data);
127 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
128 return;
129 MAGIC_CHECK_END();
130
131 if (obj->delete_me)
132 {
133 CRIT("Adding deleted object %p to smart obj %p", obj, smart_obj);
134 abort();
135 return;
136 }
137 if (smart_obj->delete_me)
138 {
139 CRIT("Adding object %p to deleted smart obj %p", obj, smart_obj);
140 abort();
141 return;
142 }
143 if (!smart_obj->layer)
144 {
145 CRIT("No evas surface associated with smart object (%p)", smart_obj);
146 abort();
147 return;
148 }
149 if ((obj->layer && smart_obj->layer) &&
150 (obj->layer->evas != smart_obj->layer->evas))
151 {
152 CRIT("Adding object %p from Evas (%p) from another Evas (%p)", obj, obj->layer->evas, smart_obj->layer->evas);
153 abort();
154 return;
155 }
156
157 if (obj->smart.parent == smart_obj) return;
158
159 if (obj->smart.parent) evas_object_smart_member_del(obj);
160
161 evas_object_release(obj, 1);
162 obj->layer = smart_obj->layer;
163 obj->cur.layer = obj->layer->layer;
164 obj->layer->usage++;
165 obj->smart.parent = smart_obj;
166 o->contained = eina_inlist_append(o->contained, EINA_INLIST_GET(obj));
167 evas_object_smart_member_cache_invalidate(obj, EINA_TRUE, EINA_TRUE);
168 obj->restack = 1;
169 evas_object_change(obj);
170 evas_object_mapped_clip_across_mark(obj);
171 if (smart_obj->smart.smart->smart_class->member_add)
172 smart_obj->smart.smart->smart_class->member_add(smart_obj, obj);
173}
174
175EAPI void
176evas_object_smart_member_del(Evas_Object *obj)
177{
178 Evas_Object_Smart *o;
179 Evas_Object *smart_obj;
180
181 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
182 return;
183 MAGIC_CHECK_END();
184
185 if (!obj->smart.parent) return;
186
187 smart_obj = obj->smart.parent;
188 if (smart_obj->smart.smart->smart_class->member_del)
189 smart_obj->smart.smart->smart_class->member_del(smart_obj, obj);
190
191 o = (Evas_Object_Smart *)(obj->smart.parent->object_data);
192 o->contained = eina_inlist_remove(o->contained, EINA_INLIST_GET(obj));
193 obj->smart.parent = NULL;
194 evas_object_smart_member_cache_invalidate(obj, EINA_TRUE, EINA_TRUE);
195 obj->layer->usage--;
196 obj->cur.layer = obj->layer->layer;
197 evas_object_inject(obj, obj->layer->evas);
198 obj->restack = 1;
199 evas_object_change(obj);
200 evas_object_mapped_clip_across_mark(obj);
201}
202
203EAPI Evas_Object *
204evas_object_smart_parent_get(const Evas_Object *obj)
205{
206 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
207 return NULL;
208 MAGIC_CHECK_END();
209
210 return obj->smart.parent;
211}
212
213EAPI Eina_Bool
214evas_object_smart_type_check(const Evas_Object *obj, const char *type)
215{
216 const Evas_Smart_Class *sc;
217
218 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
219 return EINA_FALSE;
220 MAGIC_CHECK_END();
221
222 if (!obj->smart.smart)
223 return EINA_FALSE;
224 sc = obj->smart.smart->smart_class;
225 while (sc)
226 {
227 if (!strcmp(sc->name, type))
228 return EINA_TRUE;
229 sc = sc->parent;
230 }
231
232 return EINA_FALSE;
233}
234
235EAPI Eina_Bool
236evas_object_smart_type_check_ptr(const Evas_Object *obj, const char *type)
237{
238 const Evas_Smart_Class *sc;
239
240 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
241 return EINA_FALSE;
242 MAGIC_CHECK_END();
243
244 if (!obj->smart.smart)
245 return EINA_FALSE;
246 sc = obj->smart.smart->smart_class;
247 while (sc)
248 {
249 if (sc->name == type)
250 return EINA_TRUE;
251 sc = sc->parent;
252 }
253
254 return EINA_FALSE;
255}
256
257EAPI Eina_List *
258evas_object_smart_members_get(const Evas_Object *obj)
259{
260 Evas_Object_Smart *o;
261 Eina_List *members;
262 Eina_Inlist *member;
263
264 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
265 return NULL;
266 MAGIC_CHECK_END();
267 o = (Evas_Object_Smart *)(obj->object_data);
268 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
269 return NULL;
270 MAGIC_CHECK_END();
271
272 members = NULL;
273 for (member = o->contained; member; member = member->next)
274 members = eina_list_append(members, member);
275
276 return members;
277}
278
279const Eina_Inlist *
280evas_object_smart_members_get_direct(const Evas_Object *obj)
281{
282 Evas_Object_Smart *o;
283
284 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
285 return NULL;
286 MAGIC_CHECK_END();
287 o = (Evas_Object_Smart *)(obj->object_data);
288 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
289 return NULL;
290 MAGIC_CHECK_END();
291 return o->contained;
292}
293
294void
295_evas_object_smart_members_all_del(Evas_Object *obj)
296{
297 Evas_Object_Smart *o = (Evas_Object_Smart *)(obj->object_data);
298 while (o->contained)
299 evas_object_del((Evas_Object *)(o->contained));
300}
301
302EAPI Evas_Object *
303evas_object_smart_add(Evas *e, Evas_Smart *s)
304{
305 Evas_Object *obj;
306
307 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
308 return NULL;
309 MAGIC_CHECK_END();
310 MAGIC_CHECK(s, Evas_Smart, MAGIC_SMART);
311 return NULL;
312 MAGIC_CHECK_END();
313
314 obj = evas_object_new(e);
315 if (!obj) return NULL;
316 obj->smart.smart = s;
317 obj->type = s->smart_class->name;
318 evas_object_smart_init(obj);
319 evas_object_inject(obj, e);
320
321 evas_object_smart_use(s);
322
323 if (s->smart_class->add) s->smart_class->add(obj);
324
325 return obj;
326}
327
328static int
329_callback_priority_cmp(const void *_a, const void *_b)
330{
331 const Evas_Smart_Callback *a, *b;
332 a = (const Evas_Smart_Callback *) _a;
333 b = (const Evas_Smart_Callback *) _b;
334 if (a->priority < b->priority)
335 return -1;
336 else
337 return 1;
338}
339
340EAPI void
341evas_object_smart_callback_add(Evas_Object *obj, const char *event, Evas_Smart_Cb func, const void *data)
342{
343 evas_object_smart_callback_priority_add(obj, event,
344 EVAS_CALLBACK_PRIORITY_DEFAULT, func, data);
345}
346
347EAPI void
348evas_object_smart_callback_priority_add(Evas_Object *obj, const char *event, Evas_Callback_Priority priority, Evas_Smart_Cb func, const void *data)
349{
350 Evas_Object_Smart *o;
351 Evas_Smart_Callback *cb;
352
353 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
354 return;
355 MAGIC_CHECK_END();
356 o = (Evas_Object_Smart *)(obj->object_data);
357 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
358 return;
359 MAGIC_CHECK_END();
360 if (!event) return;
361 if (!func) return;
362 EVAS_MEMPOOL_INIT(_mp_cb, "evas_smart_callback", Evas_Smart_Callback, 512, );
363 cb = EVAS_MEMPOOL_ALLOC(_mp_cb, Evas_Smart_Callback);
364 if (!cb) return;
365 EVAS_MEMPOOL_PREP(_mp_cb, cb, Evas_Smart_Callback);
366 cb->event = eina_stringshare_add(event);
367 cb->func = func;
368 cb->func_data = (void *)data;
369 cb->priority = priority;
370 o->callbacks = eina_list_sorted_insert(o->callbacks, _callback_priority_cmp,
371 cb);
372}
373
374EAPI void *
375evas_object_smart_callback_del(Evas_Object *obj, const char *event, Evas_Smart_Cb func)
376{
377 Evas_Object_Smart *o;
378 Eina_List *l;
379 Evas_Smart_Callback *cb;
380
381 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
382 return NULL;
383 MAGIC_CHECK_END();
384 o = (Evas_Object_Smart *)(obj->object_data);
385 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
386 return NULL;
387 MAGIC_CHECK_END();
388 if (!event) return NULL;
389 EINA_LIST_FOREACH(o->callbacks, l, cb)
390 {
391 if ((!strcmp(cb->event, event)) && (cb->func == func))
392 {
393 void *data;
394
395 data = cb->func_data;
396 cb->delete_me = 1;
397 o->deletions_waiting = 1;
398 evas_object_smart_callbacks_clear(obj);
399 return data;
400 }
401 }
402 return NULL;
403}
404
405EAPI void
406evas_object_smart_callback_call(Evas_Object *obj, const char *event, void *event_info)
407{
408 Evas_Object_Smart *o;
409 Eina_List *l;
410 Evas_Smart_Callback *cb;
411 const char *strshare;
412
413 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
414 return;
415 MAGIC_CHECK_END();
416 o = (Evas_Object_Smart *)(obj->object_data);
417 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
418 return;
419 MAGIC_CHECK_END();
420 if (!event) return;
421 if (obj->delete_me) return;
422 o->walking_list++;
423 strshare = eina_stringshare_add(event);
424 EINA_LIST_FOREACH(o->callbacks, l, cb)
425 {
426 if (!cb->delete_me)
427 {
428 if (cb->event == strshare)
429 cb->func(cb->func_data, obj, event_info);
430 }
431 if (obj->delete_me)
432 break;
433 }
434 eina_stringshare_del(strshare);
435 o->walking_list--;
436 evas_object_smart_callbacks_clear(obj);
437}
438
439EAPI Eina_Bool
440evas_object_smart_callbacks_descriptions_set(Evas_Object *obj, const Evas_Smart_Cb_Description *descriptions)
441{
442 const Evas_Smart_Cb_Description *d;
443 Evas_Object_Smart *o;
444 unsigned int i, count = 0;
445
446 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
447 return EINA_FALSE;
448 MAGIC_CHECK_END();
449 o = (Evas_Object_Smart *)(obj->object_data);
450 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
451 return EINA_FALSE;
452 MAGIC_CHECK_END();
453
454 if ((!descriptions) || (!descriptions->name))
455 {
456 evas_smart_cb_descriptions_resize(&o->callbacks_descriptions, 0);
457 return EINA_TRUE;
458 }
459
460 for (count = 0, d = descriptions; d->name; d++)
461 count++;
462
463 evas_smart_cb_descriptions_resize(&o->callbacks_descriptions, count);
464 if (count == 0) return EINA_TRUE;
465
466 for (i = 0, d = descriptions; i < count; d++, i++)
467 o->callbacks_descriptions.array[i] = d;
468
469 evas_smart_cb_descriptions_fix(&o->callbacks_descriptions);
470
471 return EINA_TRUE;
472}
473
474EAPI void
475evas_object_smart_callbacks_descriptions_get(const Evas_Object *obj, const Evas_Smart_Cb_Description ***class_descriptions, unsigned int *class_count, const Evas_Smart_Cb_Description ***instance_descriptions, unsigned int *instance_count)
476{
477 Evas_Object_Smart *o;
478
479 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
480 if (class_descriptions) *class_descriptions = NULL;
481 if (class_count) *class_count = 0;
482 if (instance_descriptions) *instance_descriptions = NULL;
483 if (instance_count) *instance_count = 0;
484 return;
485 MAGIC_CHECK_END();
486 o = (Evas_Object_Smart *)(obj->object_data);
487 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
488 if (class_descriptions) *class_descriptions = NULL;
489 if (class_count) *class_count = 0;
490 if (instance_descriptions) *instance_descriptions = NULL;
491 if (instance_count) *instance_count = 0;
492 return;
493 MAGIC_CHECK_END();
494
495 if (class_descriptions)
496 *class_descriptions = obj->smart.smart->callbacks.array;
497 if (class_count)
498 *class_count = obj->smart.smart->callbacks.size;
499
500 if (instance_descriptions)
501 *instance_descriptions = o->callbacks_descriptions.array;
502 if (instance_count)
503 *instance_count = o->callbacks_descriptions.size;
504}
505
506EAPI void
507evas_object_smart_callback_description_find(const Evas_Object *obj, const char *name, const Evas_Smart_Cb_Description **class_description, const Evas_Smart_Cb_Description **instance_description)
508{
509 Evas_Object_Smart *o;
510
511 if (!name)
512 {
513 if (class_description) *class_description = NULL;
514 if (instance_description) *instance_description = NULL;
515 return;
516 }
517
518 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
519 if (class_description) *class_description = NULL;
520 if (instance_description) *instance_description = NULL;
521 return;
522 MAGIC_CHECK_END();
523 o = (Evas_Object_Smart *)(obj->object_data);
524 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
525 if (class_description) *class_description = NULL;
526 if (instance_description) *instance_description = NULL;
527 return;
528 MAGIC_CHECK_END();
529
530 if (class_description)
531 *class_description = evas_smart_cb_description_find
532 (&obj->smart.smart->callbacks, name);
533
534 if (instance_description)
535 *instance_description = evas_smart_cb_description_find
536 (&o->callbacks_descriptions, name);
537}
538
539EAPI void
540evas_object_smart_need_recalculate_set(Evas_Object *obj, Eina_Bool value)
541{
542 Evas_Object_Smart *o;
543 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
544 return;
545 MAGIC_CHECK_END();
546 o = obj->object_data;
547 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
548 return;
549 MAGIC_CHECK_END();
550
551 // XXX: do i need this?
552 if (obj->delete_me) return;
553
554 /* remove this entry from calc_list or processed list */
555 if (eina_clist_element_is_linked(&obj->calc_entry))
556 eina_clist_remove(&obj->calc_entry);
557
558 value = !!value;
559 if (value)
560 eina_clist_add_tail(&obj->layer->evas->calc_list, &obj->calc_entry);
561 else
562 eina_clist_add_tail(&obj->layer->evas->calc_done, &obj->calc_entry);
563
564 if (o->need_recalculate == value) return;
565
566 if (obj->recalculate_cycle > 254)
567 {
568 ERR("Object %p is not stable during recalc loop", obj);
569 return;
570 }
571 if (obj->layer->evas->in_smart_calc) obj->recalculate_cycle++;
572 o->need_recalculate = value;
573}
574
575EAPI Eina_Bool
576evas_object_smart_need_recalculate_get(const Evas_Object *obj)
577{
578 Evas_Object_Smart *o;
579 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
580 return EINA_FALSE;
581 MAGIC_CHECK_END();
582 o = obj->object_data;
583 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
584 return EINA_FALSE;
585 MAGIC_CHECK_END();
586
587 return o->need_recalculate;
588}
589
590EAPI void
591evas_object_smart_calculate(Evas_Object *obj)
592{
593 Evas_Object_Smart *o;
594 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
595 return;
596 MAGIC_CHECK_END();
597 o = obj->object_data;
598 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
599 return;
600 MAGIC_CHECK_END();
601
602 if (!obj->smart.smart->smart_class->calculate)
603 return;
604
605 o->need_recalculate = 0;
606 obj->smart.smart->smart_class->calculate(obj);
607}
608
609EAPI void
610evas_smart_objects_calculate(Evas *e)
611{
612 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
613 return;
614 MAGIC_CHECK_END();
615 evas_call_smarts_calculate(e);
616}
617
618EAPI int
619evas_smart_objects_calculate_count_get(const Evas *e)
620{
621 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
622 return 0;
623 MAGIC_CHECK_END();
624 return e->smart_calc_count;
625}
626
627/**
628 * Call calculate() on all smart objects that need_recalculate.
629 *
630 * @internal
631 */
632void
633evas_call_smarts_calculate(Evas *e)
634{
635 Eina_Clist *elem;
636 Evas_Object *obj;
637
638// printf("+CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALC-----------v\n");
639 evas_event_freeze(e);
640 e->in_smart_calc++;
641
642 while (NULL != (elem = eina_clist_head(&e->calc_list)))
643 {
644 Evas_Object_Smart *o;
645
646 /* move the item to the processed list */
647 obj = EINA_CLIST_ENTRY(elem, Evas_Object, calc_entry);
648 eina_clist_remove(&obj->calc_entry);
649 if (obj->delete_me) continue;
650 eina_clist_add_tail(&e->calc_done, &obj->calc_entry);
651
652 o = obj->object_data;
653
654 if (o->need_recalculate)
655 {
656 o->need_recalculate = 0;
657 obj->smart.smart->smart_class->calculate(obj);
658 }
659 }
660
661 while (NULL != (elem = eina_clist_head(&e->calc_done)))
662 {
663 obj = EINA_CLIST_ENTRY(elem, Evas_Object, calc_entry);
664 obj->recalculate_cycle = 0;
665 eina_clist_remove(&obj->calc_entry);
666 }
667
668 e->in_smart_calc--;
669 if (e->in_smart_calc == 0) e->smart_calc_count++;
670 evas_event_thaw(e);
671 evas_event_thaw_eval(e);
672}
673
674EAPI void
675evas_object_smart_changed(Evas_Object *obj)
676{
677 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
678 return;
679 MAGIC_CHECK_END();
680 evas_object_change(obj);
681 evas_object_smart_need_recalculate_set(obj, 1);
682}
683
684/* internal calls */
685static void
686evas_object_smart_callbacks_clear(Evas_Object *obj)
687{
688 Evas_Object_Smart *o;
689 Eina_List *l;
690 Evas_Smart_Callback *cb;
691
692 o = (Evas_Object_Smart *)(obj->object_data);
693
694 if (o->walking_list) return;
695 if (!o->deletions_waiting) return;
696 for (l = o->callbacks; l;)
697 {
698 cb = eina_list_data_get(l);
699 l = eina_list_next(l);
700 if (cb->delete_me)
701 {
702 o->callbacks = eina_list_remove(o->callbacks, cb);
703 if (cb->event) eina_stringshare_del(cb->event);
704 EVAS_MEMPOOL_FREE(_mp_cb, cb);
705 }
706 }
707}
708
709void
710evas_object_smart_del(Evas_Object *obj)
711{
712 Evas_Smart *s;
713
714 if (obj->delete_me) return;
715 s = obj->smart.smart;
716 if ((s) && (s->smart_class->del)) s->smart_class->del(obj);
717 if (obj->smart.parent) evas_object_smart_member_del(obj);
718 if (s) evas_object_smart_unuse(s);
719}
720
721void
722evas_object_smart_cleanup(Evas_Object *obj)
723{
724 Evas_Object_Smart *o;
725
726 if (obj->smart.parent)
727 evas_object_smart_member_del(obj);
728
729 o = (Evas_Object_Smart *)(obj->object_data);
730 if (o->magic == MAGIC_OBJ_SMART)
731 {
732 if (obj->calc_entry.next)
733 eina_clist_remove(&obj->calc_entry);
734
735 while (o->contained)
736 evas_object_smart_member_del((Evas_Object *)o->contained);
737
738 while (o->callbacks)
739 {
740 Evas_Smart_Callback *cb = o->callbacks->data;
741 o->callbacks = eina_list_remove(o->callbacks, cb);
742 if (cb->event) eina_stringshare_del(cb->event);
743 EVAS_MEMPOOL_FREE(_mp_cb, cb);
744 }
745
746 evas_smart_cb_descriptions_resize(&o->callbacks_descriptions, 0);
747 o->data = NULL;
748 }
749
750 obj->smart.parent = NULL;
751 obj->smart.smart = NULL;
752}
753
754void
755evas_object_smart_member_cache_invalidate(Evas_Object *obj,
756 Eina_Bool pass_events,
757 Eina_Bool freeze_events)
758{
759 Evas_Object_Smart *o;
760 Evas_Object *member;
761
762 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
763 return;
764 MAGIC_CHECK_END();
765
766 if (pass_events)
767 obj->parent_cache.pass_events_valid = EINA_FALSE;
768 if (freeze_events)
769 obj->parent_cache.freeze_events_valid = EINA_FALSE;
770
771 o = obj->object_data;
772 if (o->magic != MAGIC_OBJ_SMART) return;
773
774 EINA_INLIST_FOREACH(o->contained, member)
775 evas_object_smart_member_cache_invalidate(member,
776 pass_events,
777 freeze_events);
778}
779
780void
781evas_object_smart_member_raise(Evas_Object *member)
782{
783 Evas_Object_Smart *o;
784
785 o = (Evas_Object_Smart *)(member->smart.parent->object_data);
786 o->contained = eina_inlist_demote(o->contained, EINA_INLIST_GET(member));
787}
788
789void
790evas_object_smart_member_lower(Evas_Object *member)
791{
792 Evas_Object_Smart *o;
793
794 o = (Evas_Object_Smart *)(member->smart.parent->object_data);
795 o->contained = eina_inlist_promote(o->contained, EINA_INLIST_GET(member));
796}
797
798void
799evas_object_smart_member_stack_above(Evas_Object *member, Evas_Object *other)
800{
801 Evas_Object_Smart *o;
802
803 o = (Evas_Object_Smart *)(member->smart.parent->object_data);
804 o->contained = eina_inlist_remove(o->contained, EINA_INLIST_GET(member));
805 o->contained = eina_inlist_append_relative(o->contained, EINA_INLIST_GET(member), EINA_INLIST_GET(other));
806}
807
808void
809evas_object_smart_member_stack_below(Evas_Object *member, Evas_Object *other)
810{
811 Evas_Object_Smart *o;
812
813 o = (Evas_Object_Smart *)(member->smart.parent->object_data);
814 o->contained = eina_inlist_remove(o->contained, EINA_INLIST_GET(member));
815 o->contained = eina_inlist_prepend_relative(o->contained, EINA_INLIST_GET(member), EINA_INLIST_GET(other));
816}
817
818/* all nice and private */
819static void
820evas_object_smart_init(Evas_Object *obj)
821{
822 /* alloc smart obj, setup methods and default values */
823 obj->object_data = evas_object_smart_new();
824 /* set up default settings for this kind of object */
825 obj->cur.color.r = 255;
826 obj->cur.color.g = 255;
827 obj->cur.color.b = 255;
828 obj->cur.color.a = 255;
829 obj->cur.geometry.x = 0;
830 obj->cur.geometry.y = 0;
831 obj->cur.geometry.w = 0;
832 obj->cur.geometry.h = 0;
833 obj->cur.layer = 0;
834 /* set up object-specific settings */
835 obj->prev = obj->cur;
836 /* set up methods (compulsory) */
837 obj->func = &object_func;
838}
839
840static void *
841evas_object_smart_new(void)
842{
843 Evas_Object_Smart *o;
844
845 /* alloc obj private data */
846 EVAS_MEMPOOL_INIT(_mp_obj, "evas_object_smart", Evas_Object_Smart, 256, NULL);
847 o = EVAS_MEMPOOL_ALLOC(_mp_obj, Evas_Object_Smart);
848 if (!o) return NULL;
849 EVAS_MEMPOOL_PREP(_mp_obj, o, Evas_Object_Smart);
850 o->magic = MAGIC_OBJ_SMART;
851 return o;
852}
853
854static void
855evas_object_smart_free(Evas_Object *obj)
856{
857 Evas_Object_Smart *o;
858
859 /* frees private object data. very simple here */
860 o = (Evas_Object_Smart *)(obj->object_data);
861 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
862 return;
863 MAGIC_CHECK_END();
864 /* free obj */
865 o->magic = 0;
866 EVAS_MEMPOOL_FREE(_mp_obj, o);
867}
868
869static void
870evas_object_smart_render(Evas_Object *obj __UNUSED__, void *output __UNUSED__, void *context __UNUSED__, void *surface __UNUSED__, int x __UNUSED__, int y __UNUSED__)
871{
872 return;
873}
874
875static void
876evas_object_smart_render_pre(Evas_Object *obj)
877{
878 if (obj->pre_render_done) return;
879 if ((obj->cur.map != obj->prev.map) ||
880 (obj->cur.usemap != obj->prev.usemap))
881 {
882 evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
883 goto done;
884 }
885done:
886 obj->pre_render_done = 1;
887}
888
889static void
890evas_object_smart_render_post(Evas_Object *obj)
891{
892 obj->prev = obj->cur;
893}
894
895static unsigned int evas_object_smart_id_get(Evas_Object *obj)
896{
897 Evas_Object_Smart *o;
898
899 o = (Evas_Object_Smart *)(obj->object_data);
900 if (!o) return 0;
901 return MAGIC_OBJ_SMART;
902}
903
904static unsigned int evas_object_smart_visual_id_get(Evas_Object *obj)
905{
906 Evas_Object_Smart *o;
907
908 o = (Evas_Object_Smart *)(obj->object_data);
909 if (!o) return 0;
910 return MAGIC_OBJ_CONTAINER;
911}
912
913static void *evas_object_smart_engine_data_get(Evas_Object *obj)
914{
915 Evas_Object_Smart *o;
916
917 o = (Evas_Object_Smart *)(obj->object_data);
918 if (!o) return NULL;
919 return o->engine_data;
920}