1 #define EFL_INPUT_EVENT_PROTECTED
2 
3 #include "evas_common_private.h"
4 #include "evas_private.h"
5 //#include "evas_cs.h"
6 
7 #include "evas_image_private.h"
8 #include "evas_polygon_private.h"
9 #include "evas_vg_private.h"
10 
11 #include "eo_internal.h"
12 
13 #ifdef _WIN32
14 # include <evil_private.h> /* evil_init evil_shutdown */
15 #endif
16 
17 #include <Ecore.h>
18 
19 #define MY_CLASS EVAS_CANVAS_CLASS
20 
21 #ifdef LKDEBUG
22 EAPI Eina_Bool lockdebug = EINA_FALSE;
23 EAPI int lockmax = 0;
24 #endif
25 
26 static int _evas_init_count = 0;
27 int _evas_log_dom_global = -1;
28 
29 EAPI Eina_Error EFL_GFX_IMAGE_LOAD_ERROR_NONE = 0;
30 EAPI Eina_Error EFL_GFX_IMAGE_LOAD_ERROR_GENERIC = 0;
31 EAPI Eina_Error EFL_GFX_IMAGE_LOAD_ERROR_DOES_NOT_EXIST = 0;
32 EAPI Eina_Error EFL_GFX_IMAGE_LOAD_ERROR_PERMISSION_DENIED = 0;
33 EAPI Eina_Error EFL_GFX_IMAGE_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED = 0;
34 EAPI Eina_Error EFL_GFX_IMAGE_LOAD_ERROR_CORRUPT_FILE = 0;
35 EAPI Eina_Error EFL_GFX_IMAGE_LOAD_ERROR_UNKNOWN_FORMAT = 0;
36 EAPI Eina_Error EFL_GFX_IMAGE_LOAD_ERROR_CANCELLED = 0;
37 EAPI Eina_Error EFL_GFX_IMAGE_LOAD_ERROR_INCOMPATIBLE_FILE = 0;
38 EAPI Eina_Error EFL_GFX_IMAGE_LOAD_ERROR_UNKNOWN_COLLECTION = 0;
39 EAPI Eina_Error EFL_GFX_IMAGE_LOAD_ERROR_RECURSIVE_REFERENCE = 0;
40 
41 #define NUM_ERRORS 11
42 
43 const char *efl_gfx_image_load_error_msgs[] = {
44  "No error on load" ,
45  "A non-specific error occurred" ,
46  "File (or file path) does not exist" ,
47  "Permission denied to an existing file (or path)" ,
48  "Allocation of resources failure prevented load" ,
49  "File corrupt (but was detected as a known format)" ,
50  "File is not a known format" ,
51  "Reading operation has been cancelled during decoding" ,
52  "(Edje only) The file pointed to is incompatible, i.e., it doesn't match the library's current version's format." ,
53  "(Edje only) The group/collection set to load from was not found in the file" ,
54  "(Edje only) The group/collection set to load from had recursive references on its components"
55 };
56 
57 static void
_efl_gfx_image_load_error_init(void)58 _efl_gfx_image_load_error_init(void)
59 {
60    Eina_Error *table[] = {
61      &EFL_GFX_IMAGE_LOAD_ERROR_NONE,
62      &EFL_GFX_IMAGE_LOAD_ERROR_GENERIC,
63      &EFL_GFX_IMAGE_LOAD_ERROR_DOES_NOT_EXIST,
64      &EFL_GFX_IMAGE_LOAD_ERROR_PERMISSION_DENIED,
65      &EFL_GFX_IMAGE_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED,
66      &EFL_GFX_IMAGE_LOAD_ERROR_CORRUPT_FILE,
67      &EFL_GFX_IMAGE_LOAD_ERROR_UNKNOWN_FORMAT,
68      &EFL_GFX_IMAGE_LOAD_ERROR_CANCELLED,
69      &EFL_GFX_IMAGE_LOAD_ERROR_INCOMPATIBLE_FILE,
70      &EFL_GFX_IMAGE_LOAD_ERROR_UNKNOWN_COLLECTION,
71      &EFL_GFX_IMAGE_LOAD_ERROR_RECURSIVE_REFERENCE
72      };
73    unsigned int i;
74 
75    if (EFL_GFX_IMAGE_LOAD_ERROR_GENERIC) return;
76    /* skip EFL_GFX_IMAGE_LOAD_ERROR_NONE: this should always be 0 */
77    for (i = 1; i < NUM_ERRORS; i++)
78      *(table[i]) = eina_error_msg_static_register(efl_gfx_image_load_error_msgs[i]);
79 #undef TABLE_ENTRY
80 }
81 
82 Eina_Error
_evas_load_error_to_efl_gfx_image_load_error(Evas_Load_Error err)83 _evas_load_error_to_efl_gfx_image_load_error(Evas_Load_Error err)
84 {
85 #define TABLE_ENTRY(NAME) [EVAS_LOAD_ERROR_##NAME] = &EFL_GFX_IMAGE_LOAD_ERROR_##NAME
86    Eina_Error *table[] = {
87      TABLE_ENTRY(NONE),
88      TABLE_ENTRY(GENERIC),
89      TABLE_ENTRY(DOES_NOT_EXIST),
90      TABLE_ENTRY(PERMISSION_DENIED),
91      TABLE_ENTRY(RESOURCE_ALLOCATION_FAILED),
92      TABLE_ENTRY(CORRUPT_FILE),
93      TABLE_ENTRY(UNKNOWN_FORMAT),
94      TABLE_ENTRY(CANCELLED),
95      //TABLE_ENTRY(INCOMPATIBLE_FILE),
96      //TABLE_ENTRY(UNKNOWN_COLLECTION),
97      //TABLE_ENTRY(RECURSIVE_REFERENCE)
98      };
99    if (err > EVAS_LOAD_ERROR_CANCELLED) return err;
100    return *table[err];
101 #undef TABLE_ENTRY
102 }
103 
104 Evas_Load_Error
_efl_gfx_image_load_error_to_evas_load_error(Eina_Error err)105 _efl_gfx_image_load_error_to_evas_load_error(Eina_Error err)
106 {
107     if (err && (err < EFL_GFX_IMAGE_LOAD_ERROR_GENERIC)) return EVAS_LOAD_ERROR_GENERIC;
108 #define CONVERT_ERR(NAME) if (err == EFL_GFX_IMAGE_LOAD_ERROR_##NAME) return EVAS_LOAD_ERROR_##NAME
109    CONVERT_ERR(NONE);
110    CONVERT_ERR(GENERIC);
111    CONVERT_ERR(DOES_NOT_EXIST);
112    CONVERT_ERR(PERMISSION_DENIED);
113    CONVERT_ERR(RESOURCE_ALLOCATION_FAILED);
114    CONVERT_ERR(CORRUPT_FILE);
115    CONVERT_ERR(UNKNOWN_FORMAT);
116    CONVERT_ERR(CANCELLED);
117    //CONVERT_ERR(INCOMPATIBLE_FILE);
118    //CONVERT_ERR(UNKNOWN_COLLECTION);
119    //CONVERT_ERR(RECURSIVE_REFERENCE);
120    return EVAS_LOAD_ERROR_GENERIC;
121 }
122 
123 static Eina_Content*
_markup_to_utf8(Eina_Content * from,const char * to_type)124 _markup_to_utf8(Eina_Content *from, const char *to_type)
125 {
126    Eina_Content *ret = NULL;
127    Eina_Slice slice = eina_content_data_get(from);
128    char *utf8 = evas_textblock_text_markup_to_utf8(NULL, slice.mem);
129    if (utf8)
130      {
131         ret = eina_content_new((Eina_Slice)EINA_SLICE_STR_FULL(utf8), to_type);
132         free(utf8);
133      }
134    return ret;
135 }
136 
137 static Eina_Content*
_utf8_to_markup(Eina_Content * from,const char * to_type)138 _utf8_to_markup(Eina_Content *from, const char *to_type)
139 {
140    Eina_Content *ret = NULL;
141    Eina_Slice slice = eina_content_data_get(from);
142    char *markup = evas_textblock_text_utf8_to_markup(NULL, slice.mem);
143    if (markup)
144      {
145         ret = eina_content_new((Eina_Slice)EINA_SLICE_STR_FULL(markup), to_type);
146         free(markup);
147      }
148    return ret;
149 }
150 
151 EAPI int
evas_init(void)152 evas_init(void)
153 {
154    if (++_evas_init_count != 1)
155      return _evas_init_count;
156 
157 #ifdef LKDEBUG
158    if (getenv("EVAS_LOCK_DEBUG"))
159       {
160          lockdebug = EINA_TRUE;
161          lockmax = atoi(getenv("EVAS_LOCK_DEBUG"));
162       }
163 #endif
164 
165 #ifdef _WIN32
166    if (!evil_init())
167      return --_evas_init_count;
168 #endif
169 
170    EINA_SAFETY_ON_FALSE_GOTO(eina_init(), shutdown_evil);
171 
172    EINA_SAFETY_ON_FALSE_GOTO(eet_init(), shutdown_eet);
173 #ifdef BUILD_LOADER_EET
174    /* additional init refcount; cannot fail */
175    eet_init();
176 #endif
177 
178    _evas_log_dom_global = eina_log_domain_register
179      ("evas_main", EVAS_DEFAULT_LOG_COLOR);
180    if (_evas_log_dom_global < 0)
181      {
182         EINA_LOG_ERR("Can not create a module log domain.");
183         goto shutdown_eina;
184      }
185 
186    EINA_SAFETY_ON_FALSE_GOTO(efl_object_init(), shutdown_eo);
187 
188    EINA_SAFETY_ON_FALSE_GOTO(ecore_init(), shutdown_ecore);
189 
190    evas_module_init();
191    EINA_SAFETY_ON_FALSE_GOTO(evas_async_events_init(), shutdown_module);
192    _evas_preload_thread_init();
193    evas_filter_init();
194    evas_cache_vg_init();
195 
196    EINA_SAFETY_ON_FALSE_GOTO(evas_thread_init(), shutdown_filter);
197 
198    evas_common_init();
199 
200    eina_log_timing(_evas_log_dom_global,
201 		   EINA_LOG_STATE_STOP,
202 		   EINA_LOG_STATE_INIT);
203 
204    _efl_gfx_mapping_init();
205    evas_focus_init();
206 
207    _efl_gfx_image_load_error_init();
208 
209    eina_content_converter_conversion_register("application/x-elementary-markup", "text/plain;charset=utf-8", _markup_to_utf8);
210    eina_content_converter_conversion_register("text/plain;charset=utf-8", "application/x-elementary-markup", _utf8_to_markup);
211 
212    return _evas_init_count;
213 
214  shutdown_filter:
215    evas_filter_shutdown();
216    _evas_preload_thread_shutdown();
217 shutdown_module:
218    evas_module_shutdown();
219 shutdown_ecore:
220    efl_object_shutdown();
221 shutdown_eo:
222    eina_log_domain_unregister(_evas_log_dom_global);
223 shutdown_eet:
224 #ifdef BUILD_LOADER_EET
225    eet_shutdown();
226 #endif
227    eet_shutdown();
228 shutdown_eina:
229    eina_shutdown();
230 shutdown_evil:
231 #ifdef _WIN32
232    evil_shutdown();
233 #endif
234 
235    return --_evas_init_count;
236 }
237 
238 EAPI int
evas_shutdown(void)239 evas_shutdown(void)
240 {
241    if (_evas_init_count <= 0)
242      {
243         EINA_LOG_ERR("Init count not greater than 0 in shutdown.");
244         return 0;
245      }
246    if (--_evas_init_count != 0)
247      return _evas_init_count;
248 
249    eina_log_timing(_evas_log_dom_global,
250                    EINA_LOG_STATE_START,
251                    EINA_LOG_STATE_SHUTDOWN);
252 
253    evas_focus_shutdown();
254 
255    evas_fonts_zero_free();
256 
257    evas_cache_vg_shutdown();
258 
259    evas_font_path_global_clear();
260 
261    evas_thread_shutdown();
262    _evas_preload_thread_shutdown();
263    evas_async_events_shutdown();
264 
265    ecore_shutdown();
266    evas_common_shutdown();
267 
268    evas_filter_shutdown();
269    evas_module_shutdown();
270 
271    _efl_gfx_mapping_shutdown();
272 
273    eina_cow_del(evas_object_proxy_cow);
274    eina_cow_del(evas_object_map_cow);
275    eina_cow_del(evas_object_state_cow);
276    evas_object_state_cow = NULL;
277    evas_object_map_cow = NULL;
278    evas_object_proxy_cow = NULL;
279 
280    eina_cow_del(evas_object_image_pixels_cow);
281    eina_cow_del(evas_object_image_load_opts_cow);
282    eina_cow_del(evas_object_image_state_cow);
283    evas_object_image_pixels_cow = NULL;
284    evas_object_image_load_opts_cow = NULL;
285    evas_object_image_state_cow = NULL;
286 
287    eina_cow_del(evas_object_mask_cow);
288    evas_object_mask_cow = NULL;
289 
290 #ifdef BUILD_LOADER_EET
291    eet_shutdown();
292 #endif
293    efl_object_shutdown();
294 
295    eina_log_domain_unregister(_evas_log_dom_global);
296 
297    eet_shutdown();
298 
299    eina_shutdown();
300 #ifdef _WIN32
301    evil_shutdown();
302 #endif
303 
304    return _evas_init_count;
305 }
306 
307 
308 EAPI Evas *
evas_new(void)309 evas_new(void)
310 {
311    Evas_Object *eo_obj = efl_add(EVAS_CANVAS_CLASS, efl_main_loop_get());
312    return eo_obj;
313 }
314 
315 static void
_evas_key_mask_free(void * data)316 _evas_key_mask_free(void *data)
317 {
318    free(data);
319 }
320 
321 static void
list_free(void * list)322 list_free(void *list)
323 {
324    eina_list_free(list);
325 }
326 
327 EOLIAN static Eo *
_evas_canvas_efl_object_constructor(Eo * eo_obj,Evas_Public_Data * e)328 _evas_canvas_efl_object_constructor(Eo *eo_obj, Evas_Public_Data *e)
329 {
330    eo_obj = efl_constructor(efl_super(eo_obj, MY_CLASS));
331 
332    e->evas = eo_obj;
333    e->output.render_method = RENDER_METHOD_INVALID;
334    e->viewport.w = 1;
335    e->viewport.h = 1;
336    e->framespace.x = 0;
337    e->framespace.y = 0;
338    e->framespace.w = 0;
339    e->framespace.h = 0;
340    e->hinting = EVAS_FONT_HINTING_BYTECODE;
341    e->current_event = EVAS_CALLBACK_LAST;
342    e->name_hash = eina_hash_string_superfast_new(list_free);
343    eina_clist_init(&e->calc_list);
344    eina_clist_init(&e->calc_done);
345 
346    efl_wref_add(efl_add(EFL_CANVAS_GESTURE_MANAGER_CLASS, eo_obj), &e->gesture_manager);
347    e->gmd = efl_data_scope_get(e->gesture_manager, EFL_CANVAS_GESTURE_MANAGER_CLASS);
348 
349 #define EVAS_ARRAY_SET(E, Array) \
350    eina_array_step_set(&E->Array, sizeof (E->Array), \
351                        ((1024 * sizeof (void*)) - sizeof (E->Array)) / sizeof (void*));
352 
353    EVAS_ARRAY_SET(e, delete_objects);
354    EVAS_ARRAY_SET(e, restack_objects);
355    EVAS_ARRAY_SET(e, render_objects);
356    EVAS_ARRAY_SET(e, pending_objects);
357    EVAS_ARRAY_SET(e, obscuring_objects);
358    EVAS_ARRAY_SET(e, temporary_objects);
359    EVAS_ARRAY_SET(e, snapshot_objects);
360    EVAS_ARRAY_SET(e, clip_changes);
361    EVAS_ARRAY_SET(e, scie_unref_queue);
362    EVAS_ARRAY_SET(e, image_unref_queue);
363    EVAS_ARRAY_SET(e, glyph_unref_queue);
364    EVAS_ARRAY_SET(e, texts_unref_queue);
365 
366    eina_array_step_set(&e->render_post_change_objects, sizeof(e->render_post_change_objects), 10);
367    eina_array_step_set(&e->map_clip_objects, sizeof(e->map_clip_objects), 64);
368 
369    e->active_objects.version = EINA_ARRAY_VERSION;
370    eina_inarray_step_set(&e->active_objects,
371                          sizeof(Eina_Inarray),
372                          sizeof(Evas_Active_Entry),
373                          256);
374 
375 #undef EVAS_ARRAY_SET
376    eina_lock_new(&(e->lock_objects));
377    eina_spinlock_new(&(e->render.lock));
378    eina_spinlock_new(&(e->post_render.lock));
379 
380    _evas_canvas_event_init(eo_obj, e);
381 
382    e->focused_objects = eina_hash_pointer_new(NULL);
383    e->locks.masks = eina_hash_pointer_new(_evas_key_mask_free);
384    e->modifiers.masks = eina_hash_pointer_new(_evas_key_mask_free);
385    e->locks.e = e->modifiers.e = e;
386 
387    return eo_obj;
388 }
389 
390 EAPI void
evas_free(Evas * eo_e)391 evas_free(Evas *eo_e)
392 {
393    if (!eo_e) return;
394    EVAS_TYPE_CHECK(eo_e);
395    if (efl_parent_get(eo_e))
396      efl_del(eo_e);
397    else
398      efl_unref(eo_e);
399 }
400 
401 typedef struct _Forced_Death Forced_Death;
402 struct _Forced_Death
403 {
404    Eina_Bool invalidated;
405    Eina_Bool noref;
406    Eina_Bool destroyed;
407 };
408 
409 static void
_object_invalidate(void * data,const Efl_Event * ev EINA_UNUSED)410 _object_invalidate(void *data, const Efl_Event *ev EINA_UNUSED)
411 {
412    Forced_Death *force = data;
413    force->invalidated = EINA_TRUE;
414 }
415 
416 static void
_object_del(void * data,const Efl_Event * ev EINA_UNUSED)417 _object_del(void *data, const Efl_Event *ev EINA_UNUSED)
418 {
419    Forced_Death *force = data;
420    force->destroyed = EINA_TRUE;
421 }
422 
423 static void
_object_noref(void * data,const Efl_Event * ev EINA_UNUSED)424 _object_noref(void *data, const Efl_Event *ev EINA_UNUSED)
425 {
426    Forced_Death *force = data;
427    force->noref = EINA_TRUE;
428 }
429 
430 EFL_CALLBACKS_ARRAY_DEFINE(_object_forced_death,
431                            { EFL_EVENT_DEL, _object_del },
432                            { EFL_EVENT_INVALIDATE, _object_invalidate },
433                            { EFL_EVENT_NOREF, _object_noref } );
434 
435 
436 EOLIAN static void
_evas_canvas_efl_object_invalidate(Eo * eo_e,Evas_Public_Data * e)437 _evas_canvas_efl_object_invalidate(Eo *eo_e, Evas_Public_Data *e)
438 {
439    Evas_Object_Protected_Data *o;
440    Evas_Layer *lay;
441    Eo *obj;
442    Eina_Array stash = { 0 };
443 
444    evas_sync(eo_e);
445 
446    evas_canvas_async_block(e);
447    evas_render_idle_flush(eo_e);
448 
449    efl_replace(&e->default_seat, NULL);
450    efl_replace(&e->default_mouse, NULL);
451    efl_replace(&e->default_keyboard, NULL);
452 
453    _evas_post_event_callback_free(eo_e);
454    _evas_canvas_event_shutdown(eo_e, e);
455 
456    e->cleanup = 1;
457 
458    eina_array_step_set(&stash, sizeof (Eina_Array), 16);
459 
460    // The first pass should destroy all object that are properly referenced
461    EINA_INLIST_FOREACH(e->layers, lay)
462      {
463         evas_layer_pre_free(lay);
464 
465         EINA_INLIST_FOREACH(lay->objects, o)
466           {
467              if (!o->delete_me)
468                eina_array_push(&stash, o->object);
469           }
470      }
471 
472    while ((obj = eina_array_pop(&stash)))
473      {
474         Evas_Object_Protected_Data *pd = efl_data_scope_get(obj, EFL_CANVAS_OBJECT_CLASS);
475 
476         // Properly destroy depending on the object being legacy or not
477         if (pd->legacy.ctor) evas_object_del(obj);
478         else efl_del(obj);
479      }
480 
481    // We are now potentially only facing zombies
482    EINA_INLIST_FOREACH(e->layers, lay)
483      {
484         evas_layer_pre_free(lay);
485         EINA_INLIST_FOREACH(lay->objects, o)
486           {
487              if (!o->delete_me)
488                eina_array_push(&stash, o->object);
489           }
490      }
491 
492    // Killing zombies now
493    while ((obj = eina_array_pop(&stash)))
494      {
495         Forced_Death force = {
496           efl_invalidated_get(obj),
497           efl_parent_get(obj) ? (efl_ref_count(obj) <= 1) : (efl_ref_count(obj) <= 0),
498           EINA_FALSE
499         };
500 
501         efl_event_callback_array_add(obj, _object_forced_death(), &force);
502 
503         ERR("Killing Zombie Object [%s:%i:%i]. Refs: %i:%i",
504             efl_debug_name_get(obj), force.invalidated, force.noref,
505             efl_ref_count(obj), ___efl_ref2_count(obj));
506         ___efl_ref2_reset(obj);
507         // This code explicitely bypass all refcounting to destroy them
508         if (!force.invalidated) efl_del(obj);
509         while (!force.destroyed) efl_unref(obj);
510 
511         if (!force.invalidated)
512           {
513              ERR("Zombie Object [%s] %s@%p could not be invalidated. "
514                  "It seems like the call to efl_invalidated() wasn't "
515                  "propagated to all the parent classes.",
516                  efl_debug_name_get(obj), efl_class_name_get(obj), obj);
517           }
518         if (!force.destroyed)
519           {
520              ERR("Zombie Object [%s] %s@%p could not be destroyed. "
521                  "It seems like the call to efl_destructor() wasn't "
522                  "propagated to all the parent classes.",
523                  efl_debug_name_get(obj), efl_class_name_get(obj), obj);
524           }
525 
526         // Forcefully remove the object from layers
527         EINA_INLIST_FOREACH(e->layers, lay)
528           EINA_INLIST_FOREACH(lay->objects, o)
529             if (o && (o->object == obj))
530               {
531                  ERR("Zombie Object [%s] %s@%p could not be removed "
532                      "from the canvas list of objects. Maybe this object "
533                      "was deleted but the call to efl_invalidated() "
534                      "was not propagated to all the parent classes? "
535                      "Forcibly removing it. This may leak! Refs: %i:%i",
536                      efl_debug_name_get(obj), efl_class_name_get(obj), obj,
537                      efl_ref_count(obj), ___efl_ref2_count(obj));
538                  lay->objects = (Evas_Object_Protected_Data *)
539                    eina_inlist_remove(EINA_INLIST_GET(lay->objects), EINA_INLIST_GET(o));
540                  goto next_zombie;
541               }
542 
543      next_zombie:
544         continue;
545      }
546 
547    eina_array_flush(&stash);
548 
549    // Destroying layers and their associated objects completely
550    EINA_INLIST_FOREACH(e->layers, lay)
551      evas_layer_free_objects(lay);
552    evas_layer_clean(eo_e);
553 
554    efl_invalidate(efl_super(eo_e, MY_CLASS));
555 }
556 
557 EOLIAN static void
_evas_canvas_efl_object_destructor(Eo * eo_e,Evas_Public_Data * e)558 _evas_canvas_efl_object_destructor(Eo *eo_e, Evas_Public_Data *e)
559 {
560    Eina_Rectangle *r;
561    Evas_Coord_Touch_Point *touch_point;
562    Evas_Post_Render_Job *job;
563    Evas_Layer *lay;
564    Efl_Canvas_Output *evo;
565    int i;
566 
567    if (e->layers)
568      {
569         // This should never happen as during invalidate we explicitely
570         // destroy all layers. If they survive, we have a zombie appocallypse.
571         Evas_Object_Protected_Data *o;
572 
573         CRI("The layers of %p are not empty !", eo_e);
574 
575         EINA_INLIST_FOREACH(e->layers, lay)
576           EINA_INLIST_FOREACH(lay->objects, o)
577             {
578                CRI("Zombie object [%s] %s@%p still present.",
579                    efl_debug_name_get(o->object), efl_class_name_get(o->object), o->object);
580             }
581      }
582 
583    evas_font_path_clear(eo_e);
584 
585    if (e->name_hash) eina_hash_free(e->name_hash);
586    e->name_hash = NULL;
587 
588    EINA_LIST_FREE(e->damages, r)
589       eina_rectangle_free(r);
590    EINA_LIST_FREE(e->obscures, r)
591       eina_rectangle_free(r);
592 
593    evas_fonts_zero_free();
594 
595    evas_event_callback_all_del(eo_e);
596    evas_event_callback_cleanup(eo_e);
597 
598    EINA_LIST_FREE(e->touch_points, touch_point)
599      free(touch_point);
600 
601    _evas_device_cleanup(eo_e);
602    e->focused_by = eina_list_free(e->focused_by);
603 
604    while (e->seats)
605      {
606         Evas_Pointer_Seat *pseat = EINA_INLIST_CONTAINER_GET(e->seats, Evas_Pointer_Seat);
607 
608         eina_list_free(pseat->object.in);
609         while (pseat->pointers)
610           {
611              Evas_Pointer_Data *pdata = EINA_INLIST_CONTAINER_GET(pseat->pointers, Evas_Pointer_Data);
612              pseat->pointers = eina_inlist_remove(pseat->pointers, pseat->pointers);
613              free(pdata);
614           }
615         e->seats = eina_inlist_remove(e->seats, e->seats);
616         free(pseat);
617      }
618 
619    /* Ector surface may require an existing output to finish its job */
620    if (e->engine.func)
621      e->engine.func->ector_destroy(_evas_engine_context(e), e->ector);
622    /* cleanup engine backend */
623    EINA_LIST_FREE(e->outputs, evo) efl_canvas_output_del(evo);
624    if (e->engine.func)
625      e->engine.func->engine_free(e->backend);
626 
627    for (i = 0; i < e->modifiers.mod.count; i++)
628      free(e->modifiers.mod.list[i]);
629    if (e->modifiers.mod.list) free(e->modifiers.mod.list);
630 
631    for (i = 0; i < e->locks.lock.count; i++)
632      free(e->locks.lock.list[i]);
633    if (e->locks.lock.list) free(e->locks.lock.list);
634 
635    if (e->engine.module) evas_module_unref(e->engine.module);
636 
637    eina_array_flush(&e->delete_objects);
638    eina_inarray_flush(&e->active_objects);
639    eina_array_flush(&e->restack_objects);
640    eina_array_flush(&e->render_objects);
641    eina_array_flush(&e->pending_objects);
642    eina_array_flush(&e->obscuring_objects);
643    eina_array_flush(&e->temporary_objects);
644    eina_array_flush(&e->snapshot_objects);
645    eina_array_flush(&e->clip_changes);
646    eina_array_flush(&e->scie_unref_queue);
647    eina_array_flush(&e->image_unref_queue);
648    eina_array_flush(&e->glyph_unref_queue);
649    eina_array_flush(&e->texts_unref_queue);
650    eina_array_flush(&e->map_clip_objects);
651    eina_hash_free(e->focused_objects);
652    eina_array_flush(&e->render_post_change_objects);
653 
654    SLKL(e->post_render.lock);
655    EINA_INLIST_FREE(e->post_render.jobs, job)
656      {
657         e->post_render.jobs = (Evas_Post_Render_Job *)
658               eina_inlist_remove(EINA_INLIST_GET(e->post_render.jobs), EINA_INLIST_GET(job));
659         free(job);
660      }
661    SLKU(e->post_render.lock);
662 
663    eina_lock_free(&(e->lock_objects));
664    eina_spinlock_free(&(e->render.lock));
665    eina_spinlock_free(&(e->post_render.lock));
666    eina_hash_free(e->locks.masks);
667    eina_hash_free(e->modifiers.masks);
668 
669    e->magic = 0;
670    efl_destructor(efl_super(eo_e, MY_CLASS));
671 }
672 
673 // It is now expected that the first output in the list is the default one
674 // manipulated by this set of legacy API
675 
676 EAPI Evas_Engine_Info *
evas_engine_info_get(const Evas * obj)677 evas_engine_info_get(const Evas *obj)
678 {
679    if (!obj) return NULL;
680 
681    Evas_Public_Data *e = efl_data_scope_get(obj, EVAS_CANVAS_CLASS);
682    Efl_Canvas_Output *output;
683 
684    output = eina_list_data_get(e->outputs);
685    if (!output)
686      {
687         output = efl_canvas_output_add((Evas*) obj);
688      }
689    if (!output) return NULL;
690    e->output.legacy = EINA_TRUE;
691 
692    return efl_canvas_output_engine_info_get(output);
693 }
694 
695 EAPI Eina_Bool
evas_engine_info_set(Evas * obj,Evas_Engine_Info * info)696 evas_engine_info_set(Evas *obj, Evas_Engine_Info *info)
697 {
698    if (!obj) return EINA_FALSE;
699 
700    Evas_Public_Data *e = efl_data_scope_get(obj, EVAS_CANVAS_CLASS);
701    Efl_Canvas_Output *output;
702 
703    output = eina_list_data_get(e->outputs);
704    if (!output) return EINA_FALSE;
705    if (!info) return EINA_FALSE;
706    efl_canvas_output_view_set(output, 0, 0,
707                               e->output.w, e->output.h);
708    return efl_canvas_output_engine_info_set(output, info);
709 }
710 
711 EOLIAN static Evas_Coord
_evas_canvas_coord_screen_x_to_world(const Eo * eo_e EINA_UNUSED,Evas_Public_Data * e,int x)712 _evas_canvas_coord_screen_x_to_world(const Eo *eo_e EINA_UNUSED, Evas_Public_Data *e, int x)
713 {
714    if (e->output.w == e->viewport.w) return e->viewport.x + x;
715    else return (long long)e->viewport.x + (((long long)x * (long long)e->viewport.w) / (long long)e->output.w);
716 }
717 
718 EOLIAN static Evas_Coord
_evas_canvas_coord_screen_y_to_world(const Eo * eo_e EINA_UNUSED,Evas_Public_Data * e,int y)719 _evas_canvas_coord_screen_y_to_world(const Eo *eo_e EINA_UNUSED, Evas_Public_Data *e, int y)
720 {
721    if (e->output.h == e->viewport.h) return e->viewport.y + y;
722    else return (long long)e->viewport.y + (((long long)y * (long long)e->viewport.h) / (long long)e->output.h);
723 }
724 
725 EOLIAN static int
_evas_canvas_coord_world_x_to_screen(const Eo * eo_e EINA_UNUSED,Evas_Public_Data * e,Evas_Coord x)726 _evas_canvas_coord_world_x_to_screen(const Eo *eo_e EINA_UNUSED, Evas_Public_Data *e, Evas_Coord x)
727 {
728    if (e->output.w == e->viewport.w) return x - e->viewport.x;
729    else return (int)((((long long)x - (long long)e->viewport.x) * (long long)e->output.w) /  (long long)e->viewport.w);
730 }
731 
732 EOLIAN static int
_evas_canvas_coord_world_y_to_screen(const Eo * eo_e EINA_UNUSED,Evas_Public_Data * e,Evas_Coord y)733 _evas_canvas_coord_world_y_to_screen(const Eo *eo_e EINA_UNUSED, Evas_Public_Data *e, Evas_Coord y)
734 {
735    if (e->output.h == e->viewport.h) return y - e->viewport.y;
736    else return (int)((((long long)y - (long long)e->viewport.y) * (long long)e->output.h) /  (long long)e->viewport.h);
737 }
738 
739 EOLIAN static Evas_Device *
_evas_canvas_default_device_get(const Eo * eo_e EINA_UNUSED,Evas_Public_Data * e,Evas_Device_Class klass)740 _evas_canvas_default_device_get(const Eo *eo_e EINA_UNUSED,
741                                 Evas_Public_Data *e,
742                                 Evas_Device_Class klass)
743 {
744    if (klass == (Evas_Device_Class)EFL_INPUT_DEVICE_TYPE_SEAT)
745      return e->default_seat;
746    if (klass == (Evas_Device_Class)EFL_INPUT_DEVICE_TYPE_MOUSE)
747      return e->default_mouse;
748    if (klass == (Evas_Device_Class)EFL_INPUT_DEVICE_TYPE_KEYBOARD)
749      return e->default_keyboard;
750    return NULL;
751 }
752 
753 EAPI int
evas_render_method_lookup(const char * name)754 evas_render_method_lookup(const char *name)
755 {
756    Evas_Module *em;
757 
758    if (!name) return RENDER_METHOD_INVALID;
759    /* search on the engines list for the name */
760    em = evas_module_find_type(EVAS_MODULE_TYPE_ENGINE, name);
761    if (!em) return RENDER_METHOD_INVALID;
762 
763    return em->id_engine;
764 }
765 
766 EAPI Eina_List *
evas_render_method_list(void)767 evas_render_method_list(void)
768 {
769    return evas_module_engine_list();
770 }
771 
772 EAPI void
evas_render_method_list_free(Eina_List * list)773 evas_render_method_list_free(Eina_List *list)
774 {
775    const char *s;
776 
777    EINA_LIST_FREE(list, s) eina_stringshare_del(s);
778 }
779 
780 EAPI Eina_Bool
evas_object_image_extension_can_load_get(const char * file)781 evas_object_image_extension_can_load_get(const char *file)
782 {
783    const char *tmp;
784    Eina_Bool result;
785 
786    tmp = eina_stringshare_add(file);
787    result = evas_common_extension_can_load_get(tmp);
788    eina_stringshare_del(tmp);
789 
790    return result;
791 }
792 
793 EAPI Eina_Bool
evas_object_image_extension_can_load_fast_get(const char * file)794 evas_object_image_extension_can_load_fast_get(const char *file)
795 {
796    return evas_common_extension_can_load_get(file);
797 }
798 
799 EOLIAN static void
_evas_canvas_pointer_output_xy_by_device_get(const Eo * eo_e EINA_UNUSED,Evas_Public_Data * e,Evas_Device * dev,int * x,int * y)800 _evas_canvas_pointer_output_xy_by_device_get(const Eo *eo_e EINA_UNUSED,
801                                              Evas_Public_Data *e,
802                                              Evas_Device *dev,
803                                              int *x, int *y)
804 {
805    Evas_Pointer_Data *pdata = _evas_pointer_data_by_device_get(e, dev);
806 
807    if (!pdata)
808      {
809         if (x) *x = 0;
810         if (y) *y = 0;
811      }
812    else
813      {
814         if (x) *x = pdata->seat->x;
815         if (y) *y = pdata->seat->y;
816      }
817 
818 }
819 
820 EOLIAN static void
_evas_canvas_pointer_canvas_xy_by_device_get(const Eo * eo_e EINA_UNUSED,Evas_Public_Data * e,Evas_Device * dev,int * x,int * y)821 _evas_canvas_pointer_canvas_xy_by_device_get(const Eo *eo_e EINA_UNUSED,
822                                              Evas_Public_Data *e,
823                                              Evas_Device *dev,
824                                              int *x, int *y)
825 {
826    Evas_Pointer_Data *pdata = _evas_pointer_data_by_device_get(e, dev);
827 
828    if (!pdata)
829      {
830         if (x) *x = 0;
831         if (y) *y = 0;
832      }
833    else
834      {
835         if (x) *x = pdata->seat->x;
836         if (y) *y = pdata->seat->y;
837      }
838 }
839 
840 EOLIAN static unsigned int
_evas_canvas_pointer_button_down_mask_by_device_get(const Eo * eo_e EINA_UNUSED,Evas_Public_Data * e,Evas_Device * dev)841 _evas_canvas_pointer_button_down_mask_by_device_get(const Eo *eo_e EINA_UNUSED,
842                                                     Evas_Public_Data *e,
843                                                     Evas_Device *dev)
844 {
845    Evas_Pointer_Data *pdata = _evas_pointer_data_by_device_get(e, dev);
846    if (!pdata) return 0;
847    return pdata->button;
848 }
849 
850 EOLIAN static Eina_Bool
_evas_canvas_efl_canvas_pointer_pointer_inside_get(const Eo * eo_e EINA_UNUSED,Evas_Public_Data * e,Evas_Device * dev)851 _evas_canvas_efl_canvas_pointer_pointer_inside_get(const Eo *eo_e EINA_UNUSED,
852                                                    Evas_Public_Data *e,
853                                                    Evas_Device *dev)
854 {
855    Evas_Pointer_Data *pdata = _evas_pointer_data_by_device_get(e, dev);
856    if (!pdata) return EINA_FALSE;
857    return pdata->seat->inside;
858 }
859 
860 EOLIAN static void
_evas_canvas_pointer_output_xy_get(const Eo * eo_e,Evas_Public_Data * e,int * x,int * y)861 _evas_canvas_pointer_output_xy_get(const Eo *eo_e, Evas_Public_Data *e, int *x, int *y)
862 {
863    return _evas_canvas_pointer_output_xy_by_device_get(eo_e, e, NULL, x, y);
864 }
865 
866 EOLIAN static void
_evas_canvas_pointer_canvas_xy_get(const Eo * eo_e,Evas_Public_Data * e,Evas_Coord * x,Evas_Coord * y)867 _evas_canvas_pointer_canvas_xy_get(const Eo *eo_e, Evas_Public_Data *e, Evas_Coord *x, Evas_Coord *y)
868 {
869    return _evas_canvas_pointer_canvas_xy_by_device_get(eo_e, e, NULL, x, y);
870 }
871 
872 EOLIAN static unsigned int
_evas_canvas_pointer_button_down_mask_get(const Eo * eo_e,Evas_Public_Data * e)873 _evas_canvas_pointer_button_down_mask_get(const Eo *eo_e, Evas_Public_Data *e)
874 {
875    return _evas_canvas_pointer_button_down_mask_by_device_get(eo_e, e, NULL);
876 }
877 
878 EOLIAN static void
_evas_canvas_data_attach_set(Eo * eo_e EINA_UNUSED,Evas_Public_Data * e,void * data)879 _evas_canvas_data_attach_set(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e, void *data)
880 {
881    e->attach_data = data;
882 }
883 
884 EOLIAN static void*
_evas_canvas_data_attach_get(const Eo * eo_e EINA_UNUSED,Evas_Public_Data * e)885 _evas_canvas_data_attach_get(const Eo *eo_e EINA_UNUSED, Evas_Public_Data *e)
886 {
887    return e->attach_data;
888 }
889 
890 static void
_evas_canvas_focus_inout_dispatch(Eo * eo_e,Evas_Device * seat EINA_UNUSED,Eina_Bool in)891 _evas_canvas_focus_inout_dispatch(Eo *eo_e, Evas_Device *seat EINA_UNUSED,
892                                   Eina_Bool in)
893 {
894    efl_event_callback_legacy_call(eo_e,
895                                   in ? EFL_CANVAS_SCENE_EVENT_SCENE_FOCUS_IN : EFL_CANVAS_SCENE_EVENT_SCENE_FOCUS_OUT,
896                                   NULL);
897 }
898 
899 EOLIAN static void
_evas_canvas_seat_focus_in(Eo * eo_e,Evas_Public_Data * e,Evas_Device * seat)900 _evas_canvas_seat_focus_in(Eo *eo_e, Evas_Public_Data *e,
901                            Evas_Device *seat)
902 {
903    if (!seat) seat = e->default_seat;
904    if (!seat || efl_input_device_type_get(seat) != EFL_INPUT_DEVICE_TYPE_SEAT) return;
905    _evas_canvas_focus_inout_dispatch(eo_e, seat, EINA_TRUE);
906 }
907 
908 EOLIAN static void
_evas_canvas_seat_focus_out(Eo * eo_e,Evas_Public_Data * e,Evas_Device * seat)909 _evas_canvas_seat_focus_out(Eo *eo_e, Evas_Public_Data *e,
910                             Evas_Device *seat)
911 {
912    if (!seat) seat = e->default_seat;
913    if (!seat || efl_input_device_type_get(seat) != EFL_INPUT_DEVICE_TYPE_SEAT) return;
914    _evas_canvas_focus_inout_dispatch(eo_e, seat, EINA_FALSE);
915 }
916 
917 EOLIAN static void
_evas_canvas_focus_in(Eo * eo_e,Evas_Public_Data * e)918 _evas_canvas_focus_in(Eo *eo_e, Evas_Public_Data *e)
919 {
920    _evas_canvas_seat_focus_in(eo_e, e, NULL);
921 }
922 
923 EOLIAN static void
_evas_canvas_focus_out(Eo * eo_e,Evas_Public_Data * e)924 _evas_canvas_focus_out(Eo *eo_e, Evas_Public_Data *e)
925 {
926    _evas_canvas_seat_focus_out(eo_e, e, NULL);
927 }
928 
929 EOLIAN static Eina_Bool
_evas_canvas_seat_focus_state_get(const Eo * eo_e EINA_UNUSED,Evas_Public_Data * e,Evas_Device * seat)930 _evas_canvas_seat_focus_state_get(const Eo *eo_e EINA_UNUSED, Evas_Public_Data *e,
931                                   Evas_Device *seat)
932 {
933    if (!seat) seat = e->default_seat;
934    return eina_list_data_find(e->focused_by, seat) ? EINA_TRUE : EINA_FALSE;
935 }
936 
937 EOLIAN static Eina_Bool
_evas_canvas_focus_state_get(const Eo * eo_e,Evas_Public_Data * e)938 _evas_canvas_focus_state_get(const Eo *eo_e, Evas_Public_Data *e)
939 {
940    return _evas_canvas_seat_focus_state_get(eo_e, e, NULL);
941 }
942 
943 EOLIAN static Eina_Bool
_evas_canvas_changed_get(const Eo * eo_e EINA_UNUSED,Evas_Public_Data * e)944 _evas_canvas_changed_get(const Eo *eo_e EINA_UNUSED, Evas_Public_Data *e)
945 {
946    return e->changed;
947 }
948 
949 EOLIAN static void
_evas_canvas_nochange_push(Eo * eo_e EINA_UNUSED,Evas_Public_Data * e)950 _evas_canvas_nochange_push(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e)
951 {
952    e->nochange++;
953 }
954 
955 EOLIAN static void
_evas_canvas_nochange_pop(Eo * eo_e EINA_UNUSED,Evas_Public_Data * e)956 _evas_canvas_nochange_pop(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e)
957 {
958    e->nochange--;
959 }
960 
961 void
_evas_walk(Evas_Public_Data * e)962 _evas_walk(Evas_Public_Data *e)
963 {
964    efl_ref(e->evas);
965 }
966 
967 void
_evas_unwalk(Evas_Public_Data * e)968 _evas_unwalk(Evas_Public_Data *e)
969 {
970    efl_unref(e->evas);
971 }
972 
973 EAPI const char *
evas_load_error_str(Evas_Load_Error error)974 evas_load_error_str(Evas_Load_Error error)
975 {
976    switch (error)
977      {
978       case EVAS_LOAD_ERROR_NONE:
979 	 return "No error on load";
980       case EVAS_LOAD_ERROR_GENERIC:
981 	 return "A non-specific error occurred";
982       case EVAS_LOAD_ERROR_DOES_NOT_EXIST:
983 	 return "File (or file path) does not exist";
984       case EVAS_LOAD_ERROR_PERMISSION_DENIED:
985 	 return "Permission deinied to an existing file (or path)";
986       case EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED:
987 	 return "Allocation of resources failure prevented load";
988       case EVAS_LOAD_ERROR_CORRUPT_FILE:
989 	 return "File corrupt (but was detected as a known format)";
990       case EVAS_LOAD_ERROR_UNKNOWN_FORMAT:
991 	 return "File is not a known format";
992       default:
993 	 return "Unknown error";
994      }
995 }
996 
997 EAPI void
evas_color_hsv_to_rgb(float h,float s,float v,int * r,int * g,int * b)998 evas_color_hsv_to_rgb(float h, float s, float v, int *r, int *g, int *b)
999 {
1000    evas_common_convert_color_hsv_to_rgb(h, s, v, r, g, b);
1001 }
1002 
1003 EAPI void
evas_color_rgb_to_hsv(int r,int g,int b,float * h,float * s,float * v)1004 evas_color_rgb_to_hsv(int r, int g, int b, float *h, float *s, float *v)
1005 {
1006    evas_common_convert_color_rgb_to_hsv(r, g, b, h, s, v);
1007 }
1008 
1009 EAPI void
evas_color_argb_premul(int a,int * r,int * g,int * b)1010 evas_color_argb_premul(int a, int *r, int *g, int *b)
1011 {
1012    evas_common_convert_color_argb_premul(a, r, g, b);
1013 }
1014 
1015 EAPI void
evas_color_argb_unpremul(int a,int * r,int * g,int * b)1016 evas_color_argb_unpremul(int a, int *r, int *g, int *b)
1017 {
1018    evas_common_convert_color_argb_unpremul(a, r, g, b);
1019 }
1020 
1021 EAPI void
evas_data_argb_premul(unsigned int * data,unsigned int len)1022 evas_data_argb_premul(unsigned int *data, unsigned int len)
1023 {
1024    if (!data || (len < 1)) return;
1025    evas_common_convert_argb_premul(data, len);
1026 }
1027 
1028 EAPI void
evas_data_argb_unpremul(unsigned int * data,unsigned int len)1029 evas_data_argb_unpremul(unsigned int *data, unsigned int len)
1030 {
1031    if (!data || (len < 1)) return;
1032    evas_common_convert_argb_unpremul(data, len);
1033 }
1034 
1035 EOLIAN static Eo *
_evas_canvas_efl_object_provider_find(const Eo * eo_e,Evas_Public_Data * e EINA_UNUSED,const Efl_Class * klass)1036 _evas_canvas_efl_object_provider_find(const Eo *eo_e,
1037                                       Evas_Public_Data *e EINA_UNUSED,
1038                                       const Efl_Class *klass)
1039 {
1040    if (klass == EVAS_CANVAS_CLASS)
1041      return (Eo *)eo_e;
1042    else if (klass == EFL_LOOP_CLASS)
1043      return efl_main_loop_get();
1044    else if (klass == EFL_CANVAS_GESTURE_MANAGER_CLASS)
1045      return e->gesture_manager;
1046    return efl_provider_find(efl_super(eo_e, MY_CLASS), klass);
1047 }
1048 
1049 EOLIAN static Efl_Loop *
_evas_canvas_efl_loop_consumer_loop_get(const Eo * eo_e EINA_UNUSED,Evas_Public_Data * e EINA_UNUSED)1050 _evas_canvas_efl_loop_consumer_loop_get(const Eo *eo_e EINA_UNUSED, Evas_Public_Data *e EINA_UNUSED)
1051 {
1052    return efl_main_loop_get();
1053 }
1054 
1055 Ector_Surface *
evas_ector_get(Evas_Public_Data * e)1056 evas_ector_get(Evas_Public_Data *e)
1057 {
1058    if (!e->ector)
1059      e->ector = e->engine.func->ector_create(_evas_engine_context(e));
1060    return e->ector;
1061 }
1062 
1063 EAPI Evas_BiDi_Direction
evas_language_direction_get(void)1064 evas_language_direction_get(void)
1065 {
1066    return evas_common_language_direction_get();
1067 }
1068 
1069 EAPI void
evas_language_reinit(void)1070 evas_language_reinit(void)
1071 {
1072    evas_common_language_reinit();
1073 }
1074 
1075 static void
_image_data_unset(Evas_Object_Protected_Data * obj,Eina_List ** list)1076 _image_data_unset(Evas_Object_Protected_Data *obj, Eina_List **list)
1077 {
1078    if (obj->is_smart)
1079      {
1080         Evas_Object_Protected_Data *obj2;
1081 
1082         EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj->object), obj2)
1083           _image_data_unset(obj2, list);
1084         return;
1085      }
1086 #define CHECK(TYPE, STRUCT, FREE) \
1087    if (efl_isa(obj->object, TYPE))\
1088      {\
1089         STRUCT *data = efl_data_scope_get(obj->object, TYPE);\
1090         FREE; \
1091         data->engine_data = NULL;\
1092      }
1093    CHECK(EFL_CANVAS_IMAGE_INTERNAL_CLASS, Evas_Image_Data,
1094          ENFN->image_free(ENC, data->engine_data))
1095    else CHECK(EFL_CANVAS_POLYGON_CLASS, Efl_Canvas_Polygon_Data,
1096         data->engine_data =
1097           obj->layer->evas->engine.func->polygon_points_clear(ENC,
1098                                                               data->engine_data))
1099    else return;
1100 #undef CHECK
1101    evas_object_ref(obj->object);
1102    *list = eina_list_append(*list, obj->object);
1103 }
1104 
1105 EAPI Eina_List *
_evas_canvas_image_data_unset(Evas * eo_e)1106 _evas_canvas_image_data_unset(Evas *eo_e)
1107 {
1108    Evas_Public_Data *e = efl_data_scope_get(eo_e, MY_CLASS);
1109    Evas_Layer *lay;
1110    Eina_List *list = NULL;
1111 
1112    EINA_INLIST_FOREACH(e->layers, lay)
1113      {
1114         Evas_Object_Protected_Data *o;
1115         EINA_INLIST_FOREACH(lay->objects, o)
1116           {
1117              if (!o->delete_me)
1118                _image_data_unset(o, &list);
1119           }
1120      }
1121    return list;
1122 }
1123 
1124 static void
_image_image_data_regenerate(Evas_Object * eo_obj,Evas_Object_Protected_Data * obj,Evas_Image_Data * data)1125 _image_image_data_regenerate(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, Evas_Image_Data *data)
1126 {
1127    unsigned int orient = data->cur->orient;
1128 
1129    _evas_image_load(eo_obj, obj, data);
1130    EINA_COW_IMAGE_STATE_WRITE_BEGIN(data, state_write)
1131      {
1132         state_write->has_alpha = !state_write->has_alpha;
1133         state_write->orient = -1;
1134      }
1135    EINA_COW_IMAGE_STATE_WRITE_END(data, state_write);
1136    evas_object_image_alpha_set(eo_obj, !data->cur->has_alpha);
1137    _evas_image_orientation_set(eo_obj, data, orient);
1138 }
1139 
1140 static void
_image_data_regenerate(Evas_Object * eo_obj)1141 _image_data_regenerate(Evas_Object *eo_obj)
1142 {
1143    Evas_Object_Protected_Data *obj;
1144 
1145    obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
1146    evas_object_change(eo_obj, obj);
1147 #define CHECK(TYPE, STRUCT, REGEN) \
1148    if (efl_isa(eo_obj, TYPE))\
1149      {\
1150         STRUCT *data = efl_data_scope_get(eo_obj, TYPE);\
1151         REGEN; \
1152      }
1153    CHECK(EFL_CANVAS_IMAGE_INTERNAL_CLASS, Evas_Image_Data, _image_image_data_regenerate(eo_obj, obj, data))
1154    else CHECK(EFL_CANVAS_IMAGE_CLASS, Evas_Image_Data, _image_image_data_regenerate(eo_obj, obj, data))
1155    //else CHECK(EFL_CANVAS_VG_OBJECT_CLASS, Efl_Canvas_Vg_Object_Data,)
1156    //else CHECK(EFL_CANVAS_POLYGON_CLASS, Efl_Canvas_Polygon_Data,)
1157 }
1158 
1159 EAPI void
_evas_canvas_image_data_regenerate(Eina_List * list)1160 _evas_canvas_image_data_regenerate(Eina_List *list)
1161 {
1162    Evas_Object *eo_obj;
1163 
1164    EINA_LIST_FREE(list, eo_obj)
1165      {
1166         _image_data_regenerate(eo_obj);
1167         evas_object_unref(eo_obj);
1168      }
1169 }
1170 
1171 
1172 EOLIAN void
_evas_canvas_image_cache_flush(Eo * eo_e EINA_UNUSED,Evas_Public_Data * e)1173 _evas_canvas_image_cache_flush(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e)
1174 {
1175    evas_canvas_async_block(e);
1176    evas_render_rendering_wait(e);
1177    if (_evas_engine_context(e))
1178      e->engine.func->image_cache_flush(_evas_engine_context(e));
1179 }
1180 
1181 EOLIAN void
_evas_canvas_image_cache_reload(Eo * eo_e,Evas_Public_Data * e)1182 _evas_canvas_image_cache_reload(Eo *eo_e, Evas_Public_Data *e)
1183 {
1184    Evas_Layer *layer;
1185 
1186    evas_canvas_async_block(e);
1187    evas_image_cache_flush(eo_e);
1188    EINA_INLIST_FOREACH(e->layers, layer)
1189      {
1190         Evas_Object_Protected_Data *obj;
1191 
1192         layer->walking_objects++;
1193         EINA_INLIST_FOREACH(layer->objects, obj)
1194           {
1195              if (efl_isa(obj->object, MY_CLASS))
1196                {
1197                   _evas_image_unload(obj->object, obj, 1);
1198                   evas_object_inform_call_image_unloaded(obj->object);
1199                }
1200           }
1201         layer->walking_objects--;
1202         _evas_layer_flush_removes(layer);
1203      }
1204    evas_image_cache_flush(eo_e);
1205    EINA_INLIST_FOREACH(e->layers, layer)
1206      {
1207         Evas_Object_Protected_Data *obj;
1208 
1209         layer->walking_objects++;
1210         EINA_INLIST_FOREACH(layer->objects, obj)
1211           {
1212              if (efl_isa(obj->object, MY_CLASS))
1213                {
1214                   Evas_Image_Data *o = efl_data_scope_get(obj->object, MY_CLASS);
1215                   _evas_image_load(obj->object, obj, o);
1216                   o->changed = EINA_TRUE;
1217                   evas_object_change(obj->object, obj);
1218                }
1219           }
1220         layer->walking_objects--;
1221         _evas_layer_flush_removes(layer);
1222      }
1223    evas_image_cache_flush(eo_e);
1224 }
1225 
1226 EOLIAN static void
_evas_canvas_image_cache_set(Eo * eo_e EINA_UNUSED,Evas_Public_Data * e,int size)1227 _evas_canvas_image_cache_set(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e, int size)
1228 {
1229    if (size < 0) size = 0;
1230    evas_canvas_async_block(e);
1231    evas_render_rendering_wait(e);
1232    if (_evas_engine_context(e))
1233      e->engine.func->image_cache_set(_evas_engine_context(e), size);
1234 }
1235 
1236 EOLIAN static int
_evas_canvas_image_cache_get(const Eo * eo_e EINA_UNUSED,Evas_Public_Data * e)1237 _evas_canvas_image_cache_get(const Eo *eo_e EINA_UNUSED, Evas_Public_Data *e)
1238 {
1239    if (_evas_engine_context(e))
1240      return e->engine.func->image_cache_get(_evas_engine_context(e));
1241    return -1;
1242 }
1243 
1244 EOLIAN static Eina_Bool
_evas_canvas_efl_canvas_scene_image_max_size_get(const Eo * eo_e EINA_UNUSED,Evas_Public_Data * e,Eina_Size2D * max)1245 _evas_canvas_efl_canvas_scene_image_max_size_get(const Eo *eo_e EINA_UNUSED, Evas_Public_Data *e, Eina_Size2D *max)
1246 {
1247    int w = 0, h = 0;
1248 
1249    if (max) *max = EINA_SIZE2D(0xffff, 0xffff);
1250    if (!e->engine.func->image_max_size_get) return EINA_FALSE;
1251    if (!max) return EINA_TRUE;
1252    e->engine.func->image_max_size_get(_evas_engine_context(e), &w, &h);
1253    *max = EINA_SIZE2D(w, h);
1254    return EINA_TRUE;
1255 }
1256 
1257 /* Legacy deprecated functions */
1258 
1259 EAPI void
evas_output_framespace_set(Evas * eo_e,Evas_Coord x,Evas_Coord y,Evas_Coord w,Evas_Coord h)1260 evas_output_framespace_set(Evas *eo_e, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
1261 {
1262    EVAS_TYPE_CHECK(eo_e);
1263 
1264    Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
1265 
1266    if ((x == e->framespace.x) && (y == e->framespace.y) &&
1267        (w == e->framespace.w) && (h == e->framespace.h)) return;
1268    evas_canvas_async_block(e);
1269    e->framespace.x = x;
1270    e->framespace.y = y;
1271    e->framespace.w = w;
1272    e->framespace.h = h;
1273    e->framespace.changed = 1;
1274    e->output_validity++;
1275    e->changed = 1;
1276 }
1277 
1278 EAPI void
evas_output_framespace_get(const Evas * eo_e,Evas_Coord * x,Evas_Coord * y,Evas_Coord * w,Evas_Coord * h)1279 evas_output_framespace_get(const Evas *eo_e, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
1280 {
1281    EVAS_TYPE_CHECK(eo_e);
1282 
1283    Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
1284 
1285    if (x) *x = e->framespace.x;
1286    if (y) *y = e->framespace.y;
1287    if (w) *w = e->framespace.w;
1288    if (h) *h = e->framespace.h;
1289 }
1290 
1291 EAPI void
evas_output_method_set(Evas * eo_e,int render_method)1292 evas_output_method_set(Evas *eo_e, int render_method)
1293 {
1294    EVAS_TYPE_CHECK(eo_e);
1295 
1296    Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
1297 
1298    Evas_Module *em;
1299 
1300    /* if our engine to set it to is invalid - abort */
1301    if (render_method == RENDER_METHOD_INVALID) return;
1302    /* if the engine is already set up - abort */
1303    if (e->output.render_method != RENDER_METHOD_INVALID) return;
1304    /* Request the right engine. */
1305    em = evas_module_engine_get(render_method);
1306    if (!em) return;
1307    if (em->id_engine != render_method) return;
1308    if (!evas_module_load(em)) return;
1309 
1310    evas_canvas_async_block(e);
1311    /* set the correct render */
1312    e->output.render_method = render_method;
1313    e->engine.func = (em->functions);
1314    evas_module_use(em);
1315    if (e->engine.module) evas_module_unref(e->engine.module);
1316    e->engine.module = em;
1317    evas_module_ref(em);
1318 
1319    /* Initialize the engine first */
1320    e->backend = e->engine.func->engine_new();
1321 
1322    /* get the engine info struct */
1323    if (e->engine.func->info_size)
1324      {
1325         Efl_Canvas_Output *output;
1326         Eina_List *l;
1327 
1328         EINA_LIST_FOREACH(e->outputs, l, output)
1329           efl_canvas_output_info_get(e, output);
1330      }
1331    else
1332      {
1333         CRI("Engine not up to date no info size provided.");
1334      }
1335 
1336    // Wayland/drm already handles seats.
1337    if (em->definition && (eina_streq(em->definition->name, "wayland_shm") ||
1338                           eina_streq(em->definition->name, "wayland_egl") ||
1339                           eina_streq(em->definition->name, "drm") ||
1340                           eina_streq(em->definition->name, "gl_drm")))
1341      {
1342         Evas_Pointer_Seat *pseat = calloc(1, sizeof(Evas_Pointer_Seat));
1343         e->seats = eina_inlist_append(e->seats, EINA_INLIST_GET(pseat));
1344         return;
1345      }
1346 
1347    e->default_seat = evas_device_add_full(eo_e, "default", "The default seat",
1348                                           NULL, NULL, EVAS_DEVICE_CLASS_SEAT,
1349                                           EVAS_DEVICE_SUBCLASS_NONE);
1350    evas_device_seat_id_set(e->default_seat, 1);
1351    e->default_mouse = evas_device_add_full(eo_e, "Mouse",
1352                                            "The default mouse",
1353                                            e->default_seat, NULL,
1354                                            EVAS_DEVICE_CLASS_MOUSE,
1355                                            EVAS_DEVICE_SUBCLASS_NONE);
1356    e->default_keyboard = evas_device_add_full(eo_e, "Keyboard",
1357                                               "The default keyboard",
1358                                               e->default_seat, NULL,
1359                                               EVAS_DEVICE_CLASS_KEYBOARD,
1360                                               EVAS_DEVICE_SUBCLASS_NONE);
1361 }
1362 
1363 EAPI int
evas_output_method_get(const Evas * eo_e)1364 evas_output_method_get(const Evas *eo_e)
1365 {
1366    EVAS_TYPE_CHECK(eo_e, RENDER_METHOD_INVALID);
1367 
1368    Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
1369 
1370    return e->output.render_method;
1371 }
1372 
1373 EAPI void
evas_output_size_set(Evas * eo_e,int w,int h)1374 evas_output_size_set(Evas *eo_e, int w, int h)
1375 {
1376    EVAS_TYPE_CHECK(eo_e);
1377 
1378    Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
1379 
1380    if ((w == e->output.w) && (h == e->output.h)) return;
1381    if (w < 1) w = 1;
1382    if (h < 1) h = 1;
1383 
1384    evas_canvas_async_block(e);
1385    e->output.w = w;
1386    e->output.h = h;
1387    e->output_validity++;
1388    e->changed = 1;
1389 
1390    if (e->output.legacy)
1391      {
1392         Efl_Canvas_Output *output;
1393 
1394         output = eina_list_data_get(e->outputs);
1395         efl_canvas_output_view_set(output, 0, 0, w, h);
1396      }
1397 
1398    evas_render_invalidate(eo_e);
1399 }
1400 
1401 EAPI void
evas_output_size_get(const Evas * eo_e,int * w,int * h)1402 evas_output_size_get(const Evas *eo_e, int *w, int *h)
1403 {
1404    EVAS_TYPE_CHECK(eo_e);
1405 
1406    Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
1407 
1408    if (w) *w = e->output.w;
1409    if (h) *h = e->output.h;
1410 }
1411 
1412 EAPI void
evas_output_viewport_set(Evas * eo_e,Evas_Coord x,Evas_Coord y,Evas_Coord w,Evas_Coord h)1413 evas_output_viewport_set(Evas *eo_e, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
1414 {
1415    EVAS_TYPE_CHECK(eo_e);
1416 
1417    Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
1418 
1419    if ((x == e->viewport.x) && (y == e->viewport.y) &&
1420        (w == e->viewport.w) && (h == e->viewport.h)) return;
1421    if (w <= 0) return;
1422    if (h <= 0) return;
1423    if ((x != 0) || (y != 0))
1424      {
1425 	ERR("Compat error. viewport x,y != 0,0 not supported");
1426 	x = 0;
1427 	y = 0;
1428      }
1429    evas_canvas_async_block(e);
1430    e->viewport.x = x;
1431    e->viewport.y = y;
1432    e->viewport.w = w;
1433    e->viewport.h = h;
1434    e->viewport.changed = 1;
1435    e->output_validity++;
1436    e->changed = 1;
1437    evas_event_callback_call(e->evas, EVAS_CALLBACK_CANVAS_VIEWPORT_RESIZE, NULL);
1438 }
1439 
1440 EAPI void
evas_output_viewport_get(const Evas * eo_e,Evas_Coord * x,Evas_Coord * y,Evas_Coord * w,Evas_Coord * h)1441 evas_output_viewport_get(const Evas *eo_e, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
1442 {
1443    EVAS_TYPE_CHECK(eo_e);
1444 
1445    Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
1446 
1447    if (x) *x = e->viewport.x;
1448    if (y) *y = e->viewport.y;
1449    if (w) *w = e->viewport.w;
1450    if (h) *h = e->viewport.h;
1451 }
1452 
1453 Evas_Pointer_Data *
_evas_pointer_data_by_device_get(Evas_Public_Data * edata,Evas_Device * pointer)1454 _evas_pointer_data_by_device_get(Evas_Public_Data *edata, Evas_Device *pointer)
1455 {
1456    Evas_Pointer_Data *pdata;
1457    Evas_Pointer_Seat *pseat;
1458    Eo *seat;
1459 
1460    if (!pointer)
1461      pointer = edata->default_mouse;
1462    if (!pointer) return NULL;
1463    seat = efl_input_device_seat_get(pointer);
1464    if (!seat) return NULL;
1465 
1466    EINA_INLIST_FOREACH(edata->seats, pseat)
1467      EINA_INLIST_FOREACH(pseat->pointers, pdata)
1468        {
1469           if (pointer == seat)
1470             {
1471                if (pseat->seat == seat) return pdata;
1472             }
1473           else if (pdata->pointer == pointer) return pdata;
1474        }
1475    return NULL;
1476 }
1477 
1478 Evas_Pointer_Data *
_evas_pointer_data_add(Evas_Public_Data * edata,Evas_Device * pointer)1479 _evas_pointer_data_add(Evas_Public_Data *edata, Evas_Device *pointer)
1480 {
1481    Evas_Pointer_Data *pdata;
1482    Evas_Pointer_Seat *pseat = NULL;
1483    Eo *seat;
1484 
1485    seat = efl_input_device_seat_get(pointer);
1486    EINA_SAFETY_ON_NULL_RETURN_VAL(seat, NULL);
1487    EINA_INLIST_FOREACH(edata->seats, pseat)
1488      if (pseat->seat == seat) break;
1489    if (!pseat)
1490      {
1491         pseat = calloc(1, sizeof(Evas_Pointer_Seat));
1492         EINA_SAFETY_ON_NULL_RETURN_VAL(pseat, NULL);
1493         pseat->seat = seat;
1494         edata->seats = eina_inlist_append(edata->seats, EINA_INLIST_GET(pseat));
1495      }
1496    pdata = calloc(1, sizeof(Evas_Pointer_Data));
1497    if (!pdata)
1498      {
1499         if (!pseat->pointers)
1500           {
1501              edata->seats = eina_inlist_remove(edata->seats, EINA_INLIST_GET(pseat));
1502              free(pseat);
1503           }
1504         ERR("alloc fail");
1505         return NULL;
1506      }
1507 
1508    pdata->pointer = pointer;
1509    pdata->seat = pseat;
1510    pseat->pointers = eina_inlist_append(pseat->pointers, EINA_INLIST_GET(pdata));
1511    return pdata;
1512 }
1513 
1514 void
_evas_pointer_data_remove(Evas_Public_Data * edata,Evas_Device * pointer,Eina_Bool nofree)1515 _evas_pointer_data_remove(Evas_Public_Data *edata, Evas_Device *pointer, Eina_Bool nofree)
1516 {
1517    Evas_Pointer_Data *pdata;
1518    Evas_Pointer_Seat *pseat;
1519    Evas_Pointer_Seat *hit = NULL;
1520 
1521    EINA_INLIST_FOREACH(edata->seats, pseat)
1522      {
1523         EINA_INLIST_FOREACH(pseat->pointers, pdata)
1524           if (pdata->pointer == pointer)
1525             {
1526                if (!nofree)
1527                  {
1528                     pseat->pointers = eina_inlist_remove(pseat->pointers, EINA_INLIST_GET(pdata));
1529                     free(pdata);
1530                  }
1531                hit = pseat;
1532                break;
1533             }
1534      }
1535    EINA_SAFETY_ON_NULL_RETURN(hit);
1536    if (hit->pointers) return;
1537    hit->object.in = eina_list_free(hit->object.in);
1538    if (!nofree)
1539      {
1540         edata->seats = eina_inlist_remove(edata->seats, EINA_INLIST_GET(hit));
1541         free(hit);
1542      }
1543 }
1544 
1545 Eina_List *
_evas_pointer_list_in_rect_get(Evas_Public_Data * edata,Evas_Object * obj,Evas_Object_Protected_Data * obj_data,int w,int h)1546 _evas_pointer_list_in_rect_get(Evas_Public_Data *edata, Evas_Object *obj,
1547                                Evas_Object_Protected_Data *obj_data,
1548                                int w, int h)
1549 {
1550    Eina_List *list = NULL;
1551    Evas_Pointer_Seat *pseat;
1552 
1553    EINA_INLIST_FOREACH(edata->seats, pseat)
1554      {
1555         Evas_Pointer_Data *pdata;
1556         if (!evas_object_is_in_output_rect(obj, obj_data, pseat->x, pseat->y, w, h)) continue;
1557         pdata = EINA_INLIST_CONTAINER_GET(pseat->pointers, Evas_Pointer_Data);
1558         if (pdata)
1559           list = eina_list_append(list, pdata);
1560      }
1561 
1562    return list;
1563 }
1564 
1565 static Eina_Inlist *
get_layer_objects(Evas_Layer * l)1566 get_layer_objects(Evas_Layer *l)
1567 {
1568    if ((!l) || (!l->objects)) return NULL;
1569    return (EINA_INLIST_GET(l->objects));
1570 }
1571 
1572 typedef struct _Efl_Canvas_Iterator
1573 {
1574    Eina_Iterator  iterator;
1575    Eina_List     *list;
1576    Eina_Iterator *real_iterator;
1577    Eo            *object;
1578 } Efl_Canvas_Iterator;
1579 
1580 /* this iterator is the same as efl_ui_box */
1581 static Eina_Bool
_efl_canvas_iterator_next(Efl_Canvas_Iterator * it,void ** data)1582 _efl_canvas_iterator_next(Efl_Canvas_Iterator *it, void **data)
1583 {
1584    Efl_Gfx_Entity *sub;
1585 
1586    if (!it->object) return EINA_FALSE;
1587    if (!eina_iterator_next(it->real_iterator, (void **) &sub))
1588      return EINA_FALSE;
1589 
1590    if (data) *data = sub;
1591    return EINA_TRUE;
1592 }
1593 
1594 static Eo *
_efl_canvas_iterator_get_container(Efl_Canvas_Iterator * it)1595 _efl_canvas_iterator_get_container(Efl_Canvas_Iterator *it)
1596 {
1597    return it->object;
1598 }
1599 
1600 static void
_efl_canvas_iterator_free(Efl_Canvas_Iterator * it)1601 _efl_canvas_iterator_free(Efl_Canvas_Iterator *it)
1602 {
1603    eina_iterator_free(it->real_iterator);
1604    efl_wref_del(it->object, &it->object);
1605    eina_list_free(it->list);
1606    free(it);
1607 }
1608 
1609 EAPI Eina_Iterator *
efl_canvas_iterator_create(Eo * obj,Eina_Iterator * real_iterator,Eina_List * list)1610 efl_canvas_iterator_create(Eo *obj, Eina_Iterator *real_iterator, Eina_List *list)
1611 {
1612    Efl_Canvas_Iterator *it;
1613 
1614    it = calloc(1, sizeof(*it));
1615    if (!it) return NULL;
1616 
1617    EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
1618 
1619    it->list = list;
1620    it->real_iterator = real_iterator;
1621    it->iterator.version = EINA_ITERATOR_VERSION;
1622    it->iterator.next = FUNC_ITERATOR_NEXT(_efl_canvas_iterator_next);
1623    it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_efl_canvas_iterator_get_container);
1624    it->iterator.free = FUNC_ITERATOR_FREE(_efl_canvas_iterator_free);
1625    efl_wref_add(obj, &it->object);
1626 
1627    return &it->iterator;
1628 }
1629 
1630 EOLIAN static Evas_Object*
_evas_canvas_efl_canvas_scene_object_top_at_xy_get(const Eo * eo_e EINA_UNUSED,Evas_Public_Data * e,Eina_Position2D pos,Eina_Bool include_pass_events_objects,Eina_Bool include_hidden_objects)1631 _evas_canvas_efl_canvas_scene_object_top_at_xy_get(const Eo *eo_e EINA_UNUSED, Evas_Public_Data *e, Eina_Position2D pos, Eina_Bool include_pass_events_objects, Eina_Bool include_hidden_objects)
1632 {
1633    Evas_Layer *lay;
1634    int xx, yy;
1635 
1636    xx = pos.x;
1637    yy = pos.y;
1638 ////   xx = evas_coord_world_x_to_screen(eo_e, x);
1639 ////   yy = evas_coord_world_y_to_screen(eo_e, y);
1640    EINA_INLIST_REVERSE_FOREACH((EINA_INLIST_GET(e->layers)), lay)
1641      {
1642         Evas_Object *eo_obj;
1643         Evas_Object_Protected_Data *obj;
1644 
1645         EINA_INLIST_REVERSE_FOREACH(get_layer_objects(lay), obj)
1646           {
1647              eo_obj = obj->object;
1648              if (obj->delete_me) continue;
1649              if ((!include_pass_events_objects) &&
1650                  (evas_event_passes_through(eo_obj, obj))) continue;
1651              if (evas_object_is_source_invisible(eo_obj, obj)) continue;
1652              if ((!include_hidden_objects) && (!obj->cur->visible)) continue;
1653              evas_object_clip_recalc(obj);
1654              if ((evas_object_is_in_output_rect(eo_obj, obj, xx, yy, 1, 1)) &&
1655                  (!obj->clip.clipees) &&
1656                  RECTS_INTERSECT(xx, yy, 1, 1,
1657                    obj->cur->geometry.x, obj->cur->geometry.y,
1658                    obj->cur->geometry.w, obj->cur->geometry.h))
1659                return eo_obj;
1660           }
1661      }
1662    return NULL;
1663 }
1664 
1665 EAPI Evas_Object*
evas_object_top_at_xy_get(Eo * eo_e,Evas_Coord x,Evas_Coord y,Eina_Bool include_pass_events_objects,Eina_Bool include_hidden_objects)1666 evas_object_top_at_xy_get(Eo *eo_e, Evas_Coord x, Evas_Coord y, Eina_Bool include_pass_events_objects, Eina_Bool include_hidden_objects)
1667 {
1668    Eina_Position2D pos = {x, y};
1669    return efl_canvas_scene_object_top_at_xy_get(eo_e, pos, include_pass_events_objects, include_hidden_objects);
1670 }
1671 
1672 EAPI Evas_Object *
evas_object_top_at_pointer_get(const Evas * eo_e)1673 evas_object_top_at_pointer_get(const Evas *eo_e)
1674 {
1675    Evas_Public_Data *e = efl_isa(eo_e, EVAS_CANVAS_CLASS) ?
1676             efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS) : NULL;
1677    if (!e) return NULL;
1678 
1679    Evas_Pointer_Data *pdata = _evas_pointer_data_by_device_get(e, NULL);
1680    EINA_SAFETY_ON_NULL_RETURN_VAL(pdata, NULL);
1681    return efl_canvas_scene_object_top_at_xy_get((Eo *)eo_e, EINA_POSITION2D(pdata->seat->x, pdata->seat->y), EINA_TRUE, EINA_TRUE);
1682 }
1683 
1684 EOLIAN Evas_Object*
_evas_canvas_efl_canvas_scene_object_top_in_rectangle_get(const Eo * eo_e EINA_UNUSED,Evas_Public_Data * e,Eina_Rect rect,Eina_Bool include_pass_events_objects,Eina_Bool include_hidden_objects)1685 _evas_canvas_efl_canvas_scene_object_top_in_rectangle_get(const Eo *eo_e EINA_UNUSED, Evas_Public_Data *e, Eina_Rect rect, Eina_Bool include_pass_events_objects, Eina_Bool include_hidden_objects)
1686 {
1687    Evas_Layer *lay;
1688    int xx, yy, ww, hh;
1689 
1690    xx = rect.x;
1691    yy = rect.y;
1692    ww = rect.w;
1693    hh = rect.h;
1694 ////   xx = evas_coord_world_x_to_screen(eo_e, x);
1695 ////   yy = evas_coord_world_y_to_screen(eo_e, y);
1696 ////   ww = evas_coord_world_x_to_screen(eo_e, w);
1697 ////   hh = evas_coord_world_y_to_screen(eo_e, h);
1698    if (ww < 1) ww = 1;
1699    if (hh < 1) hh = 1;
1700    EINA_INLIST_REVERSE_FOREACH((EINA_INLIST_GET(e->layers)), lay)
1701      {
1702         Evas_Object *eo_obj;
1703         Evas_Object_Protected_Data *obj;
1704 
1705         EINA_INLIST_REVERSE_FOREACH(get_layer_objects(lay), obj)
1706           {
1707              eo_obj = obj->object;
1708              if (obj->delete_me) continue;
1709              if ((!include_pass_events_objects) &&
1710                  (evas_event_passes_through(eo_obj, obj))) continue;
1711              if (evas_object_is_source_invisible(eo_obj, obj)) continue;
1712              if ((!include_hidden_objects) && (!obj->cur->visible)) continue;
1713              evas_object_clip_recalc(obj);
1714              if ((evas_object_is_in_output_rect(eo_obj, obj, xx, yy, ww, hh)) &&
1715                  (!obj->clip.clipees) &&
1716                  RECTS_INTERSECT(xx, yy, ww, hh,
1717                    obj->cur->geometry.x, obj->cur->geometry.y,
1718                    obj->cur->geometry.w, obj->cur->geometry.h)) return eo_obj;
1719           }
1720      }
1721    return NULL;
1722 }
1723 
1724 EAPI Evas_Object *
evas_object_top_in_rectangle_get(const Eo * obj,int x,int y,int w,int h,Eina_Bool include_pass_events_objects,Eina_Bool include_hidden_objects)1725 evas_object_top_in_rectangle_get(const Eo *obj, int x, int y, int w, int h, Eina_Bool include_pass_events_objects, Eina_Bool include_hidden_objects)
1726 {
1727    return efl_canvas_scene_object_top_in_rectangle_get(obj, EINA_RECT(x, y, w, h), include_pass_events_objects, include_hidden_objects);
1728 }
1729 
1730 static Eina_List *
_efl_canvas_evas_canvas_objects_at_xy_get_helper(Eo * eo_e EINA_UNUSED,Evas_Public_Data * e,int x,int y,Eina_Bool include_pass_events_objects,Eina_Bool include_hidden_objects)1731 _efl_canvas_evas_canvas_objects_at_xy_get_helper(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e, int x, int y, Eina_Bool include_pass_events_objects, Eina_Bool include_hidden_objects)
1732 {
1733    Eina_List *in = NULL;
1734    Evas_Layer *lay;
1735    int xx, yy;
1736 
1737    xx = x;
1738    yy = y;
1739 ////   xx = evas_coord_world_x_to_screen(eo_e, x);
1740 ////   yy = evas_coord_world_y_to_screen(eo_e, y);
1741    EINA_INLIST_REVERSE_FOREACH((EINA_INLIST_GET(e->layers)), lay)
1742      {
1743         Evas_Object *eo_obj;
1744         Evas_Object_Protected_Data *obj;
1745 
1746         EINA_INLIST_REVERSE_FOREACH(get_layer_objects(lay), obj)
1747           {
1748              eo_obj = obj->object;
1749              // FIXME - Daniel: we don't know yet how to handle the next line
1750              if (obj->delete_me) continue;
1751              if ((!include_pass_events_objects) &&
1752                    (evas_event_passes_through(eo_obj, obj))) continue;
1753              if (evas_object_is_source_invisible(eo_obj, obj)) continue;
1754              if ((!include_hidden_objects) && (!obj->cur->visible)) continue;
1755              evas_object_clip_recalc(obj);
1756              if ((evas_object_is_in_output_rect(eo_obj, obj, xx, yy, 1, 1)) &&
1757                  (!obj->clip.clipees))
1758                {
1759                   // evas_object_is_in_output_rect is based on the clip which
1760                   // may be larger than the geometry (bounding box)
1761                   if (!RECTS_INTERSECT(xx, yy, 1, 1,
1762                                        obj->cur->geometry.x,
1763                                        obj->cur->geometry.y,
1764                                        obj->cur->geometry.w,
1765                                        obj->cur->geometry.h))
1766                     continue;
1767                   in = eina_list_prepend(in, eo_obj);
1768                }
1769           }
1770      }
1771    return in;
1772 }
1773 
1774 EOLIAN static Eina_Iterator *
_evas_canvas_efl_canvas_scene_objects_at_xy_get(Eo * eo_e,Evas_Public_Data * e,Eina_Position2D pos,Eina_Bool include_pass_events_objects,Eina_Bool include_hidden_objects)1775 _evas_canvas_efl_canvas_scene_objects_at_xy_get(Eo *eo_e, Evas_Public_Data *e, Eina_Position2D pos, Eina_Bool include_pass_events_objects, Eina_Bool include_hidden_objects)
1776 {
1777    Eina_List *l = _efl_canvas_evas_canvas_objects_at_xy_get_helper(eo_e, e, pos.x, pos.y, include_pass_events_objects, include_hidden_objects);
1778    if (l) return efl_canvas_iterator_create(eo_e, eina_list_iterator_new(l), l);
1779    return NULL;
1780 }
1781 
1782 /**
1783  * Retrieves the objects in the given rectangle region
1784  * @param   eo_e The given evas object.
1785  * @param   x The horizontal coordinate.
1786  * @param   y The vertical coordinate.
1787  * @param   w The width size.
1788  * @param   h The height size.
1789  * @param   include_pass_events_objects Boolean Flag to include or not pass events objects
1790  * @param   include_hidden_objects Boolean Flag to include or not hidden objects
1791  * @return  The list of evas object in the rectangle region.
1792  *
1793  */
1794 static Eina_List*
_efl_canvas_objects_in_rectangle_get_helper(const Eo * eo_e EINA_UNUSED,Evas_Public_Data * e,Evas_Coord x,Evas_Coord y,Evas_Coord w,Evas_Coord h,Eina_Bool include_pass_events_objects,Eina_Bool include_hidden_objects)1795 _efl_canvas_objects_in_rectangle_get_helper(const Eo *eo_e EINA_UNUSED, Evas_Public_Data *e, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, Eina_Bool include_pass_events_objects, Eina_Bool include_hidden_objects)
1796 {
1797    Eina_List *in = NULL;
1798    Evas_Layer *lay;
1799    int xx, yy, ww, hh;
1800 
1801    xx = x;
1802    yy = y;
1803    ww = w;
1804    hh = h;
1805 ////   xx = evas_coord_world_x_to_screen(eo_e, x);
1806 ////   yy = evas_coord_world_y_to_screen(eo_e, y);
1807 ////   ww = evas_coord_world_x_to_screen(eo_e, w);
1808 ////   hh = evas_coord_world_y_to_screen(eo_e, h);
1809    if (ww < 1) ww = 1;
1810    if (hh < 1) hh = 1;
1811    EINA_INLIST_REVERSE_FOREACH((EINA_INLIST_GET(e->layers)), lay)
1812      {
1813         Evas_Object *eo_obj;
1814         Evas_Object_Protected_Data *obj;
1815 
1816         EINA_INLIST_REVERSE_FOREACH(get_layer_objects(lay), obj)
1817           {
1818              eo_obj = obj->object;
1819              // FIXME - Daniel: we don't know yet how to handle the next line
1820              if (obj->delete_me) continue;
1821              if ((!include_pass_events_objects) &&
1822                  (evas_event_passes_through(eo_obj, obj))) continue;
1823              if (evas_object_is_source_invisible(eo_obj, obj)) continue;
1824              if ((!include_hidden_objects) && (!obj->cur->visible)) continue;
1825              evas_object_clip_recalc(obj);
1826              if ((evas_object_is_in_output_rect(eo_obj, obj, xx, yy, ww, hh)) &&
1827                  (!obj->clip.clipees))
1828                {
1829                   if (!RECTS_INTERSECT(xx, yy, ww, hh,
1830                                        obj->cur->geometry.x,
1831                                        obj->cur->geometry.y,
1832                                        obj->cur->geometry.w,
1833                                        obj->cur->geometry.h))
1834                     continue;
1835                   in = eina_list_prepend(in, eo_obj);
1836                }
1837           }
1838      }
1839    return in;
1840 }
1841 
1842 
1843 EOLIAN static Eina_Iterator*
_evas_canvas_efl_canvas_scene_objects_in_rectangle_get(Eo * eo_e EINA_UNUSED,Evas_Public_Data * e,Eina_Rect rect,Eina_Bool include_pass_events_objects,Eina_Bool include_hidden_objects)1844 _evas_canvas_efl_canvas_scene_objects_in_rectangle_get(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e, Eina_Rect rect, Eina_Bool include_pass_events_objects, Eina_Bool include_hidden_objects)
1845 {
1846    Eina_List *l = _efl_canvas_objects_in_rectangle_get_helper(eo_e, e, rect.x, rect.y, rect.w, rect.h, include_pass_events_objects, include_hidden_objects);
1847    if (!l) return NULL;
1848    return efl_canvas_iterator_create(eo_e, eina_list_iterator_new(l), l);
1849 }
1850 
1851 EAPI Eina_List *
evas_objects_in_rectangle_get(const Evas_Canvas * eo_e,int x,int y,int w,int h,Eina_Bool include_pass_events_objects,Eina_Bool include_hidden_objects)1852 evas_objects_in_rectangle_get(const Evas_Canvas *eo_e, int x, int y, int w, int h, Eina_Bool include_pass_events_objects, Eina_Bool include_hidden_objects)
1853 {
1854    EVAS_LEGACY_API(eo_e, e, NULL);
1855    return _efl_canvas_objects_in_rectangle_get_helper(eo_e, e, x, y, w, h, include_pass_events_objects, include_hidden_objects);
1856 }
1857 
1858 /* font related api */
1859 
1860 EOLIAN static void
_evas_canvas_font_path_clear(Eo * eo_e EINA_UNUSED,Evas_Public_Data * evas)1861 _evas_canvas_font_path_clear(Eo *eo_e EINA_UNUSED, Evas_Public_Data *evas)
1862 {
1863    evas_canvas_async_block(evas);
1864    while (evas->font_path)
1865      {
1866   eina_stringshare_del(evas->font_path->data);
1867   evas->font_path = eina_list_remove(evas->font_path, evas->font_path->data);
1868      }
1869 }
1870 
1871 EOLIAN static void
_evas_canvas_font_path_append(Eo * eo_e EINA_UNUSED,Evas_Public_Data * e,const char * path)1872 _evas_canvas_font_path_append(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e, const char *path)
1873 {
1874    if (!path) return;
1875    evas_canvas_async_block(e);
1876    e->font_path = eina_list_append(e->font_path, eina_stringshare_add(path));
1877 }
1878 
1879 EOLIAN static void
_evas_canvas_font_path_prepend(Eo * eo_e EINA_UNUSED,Evas_Public_Data * e,const char * path)1880 _evas_canvas_font_path_prepend(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e, const char *path)
1881 {
1882    if (!path) return;
1883    evas_canvas_async_block(e);
1884    e->font_path = eina_list_prepend(e->font_path, eina_stringshare_add(path));
1885 }
1886 
1887 EOLIAN static const Eina_List*
_evas_canvas_font_path_list(const Eo * eo_e EINA_UNUSED,Evas_Public_Data * e)1888 _evas_canvas_font_path_list(const Eo *eo_e EINA_UNUSED, Evas_Public_Data *e)
1889 {
1890    return e->font_path;
1891 }
1892 
1893 EOLIAN static void
_evas_canvas_font_cache_flush(Eo * eo_e EINA_UNUSED,Evas_Public_Data * e)1894 _evas_canvas_font_cache_flush(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e)
1895 {
1896    evas_canvas_async_block(e);
1897    evas_render_rendering_wait(e);
1898    if (_evas_engine_context(e))
1899      e->engine.func->font_cache_flush(_evas_engine_context(e));
1900 }
1901 
1902 EOLIAN static void
_evas_canvas_font_cache_set(Eo * eo_e EINA_UNUSED,Evas_Public_Data * e,int size)1903 _evas_canvas_font_cache_set(Eo *eo_e EINA_UNUSED, Evas_Public_Data *e, int size)
1904 {
1905    if (size < 0) size = 0;
1906    evas_canvas_async_block(e);
1907    evas_render_rendering_wait(e);
1908    if (_evas_engine_context(e))
1909      e->engine.func->font_cache_set(_evas_engine_context(e), size);
1910 }
1911 
1912 EOLIAN static int
_evas_canvas_font_cache_get(const Eo * eo_e EINA_UNUSED,Evas_Public_Data * e)1913 _evas_canvas_font_cache_get(const Eo *eo_e EINA_UNUSED, Evas_Public_Data *e)
1914 {
1915    if (_evas_engine_context(e))
1916      return e->engine.func->font_cache_get(_evas_engine_context(e));
1917    return -1;
1918 }
1919 
1920 EOLIAN static Eina_List*
_evas_canvas_font_available_list(const Eo * eo_e EINA_UNUSED,Evas_Public_Data * pd)1921 _evas_canvas_font_available_list(const Eo *eo_e EINA_UNUSED, Evas_Public_Data *pd)
1922 {
1923    return evas_font_dir_available_list(pd->font_path);
1924 }
1925 
1926 static void
evas_font_object_rehint(Evas_Object * eo_obj)1927 evas_font_object_rehint(Evas_Object *eo_obj)
1928 {
1929    Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
1930    if (obj->is_smart)
1931      {
1932   EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(eo_obj), obj)
1933     evas_font_object_rehint(obj->object);
1934      }
1935    else
1936      {
1937   if (!strcmp(obj->type, "text"))
1938     _evas_object_text_rehint(eo_obj);
1939   if (!strcmp(obj->type, "textblock"))
1940     _evas_object_textblock_rehint(eo_obj);
1941      }
1942 }
1943 
1944 EAPI void
evas_font_hinting_set(Eo * eo_e,Evas_Font_Hinting_Flags hinting)1945 evas_font_hinting_set(Eo *eo_e, Evas_Font_Hinting_Flags hinting)
1946 {
1947    Evas_Layer *lay;
1948 
1949    EVAS_LEGACY_API(eo_e, e);
1950    evas_canvas_async_block(e);
1951    if (e->hinting == hinting) return;
1952    e->hinting = hinting;
1953 
1954    EINA_INLIST_FOREACH(e->layers, lay)
1955      {
1956   Evas_Object_Protected_Data *obj;
1957 
1958   EINA_INLIST_FOREACH(lay->objects, obj)
1959     evas_font_object_rehint(obj->object);
1960      }
1961 }
1962 
1963 EAPI Evas_Font_Hinting_Flags
evas_font_hinting_get(const Evas * eo_e)1964 evas_font_hinting_get(const Evas *eo_e)
1965 {
1966    EVAS_LEGACY_API(eo_e, e, EVAS_FONT_HINTING_NONE);
1967    return e->hinting;
1968 }
1969 
1970 EAPI Eina_Bool
evas_font_hinting_can_hint(const Evas * eo_e,Evas_Font_Hinting_Flags hinting)1971 evas_font_hinting_can_hint(const Evas *eo_e, Evas_Font_Hinting_Flags hinting)
1972 {
1973    EVAS_LEGACY_API(eo_e, e, EINA_FALSE);
1974    if (e->engine.func->font_hinting_can_hint && _evas_engine_context(e))
1975      return e->engine.func->font_hinting_can_hint(_evas_engine_context(e),
1976                                                   hinting);
1977    else return EINA_FALSE;
1978 }
1979 
1980 EAPI void
evas_font_available_list_free(Evas * eo_e,Eina_List * available)1981 evas_font_available_list_free(Evas *eo_e, Eina_List *available)
1982 {
1983    EVAS_TYPE_CHECK(eo_e);
1984 
1985    evas_font_dir_available_list_free(available);
1986 }
1987 
1988 
1989 EOLIAN static void
_evas_canvas_efl_canvas_scene_group_objects_calculate(Eo * eo_e,Evas_Public_Data * o EINA_UNUSED)1990 _evas_canvas_efl_canvas_scene_group_objects_calculate(Eo *eo_e, Evas_Public_Data *o EINA_UNUSED)
1991 {
1992    evas_call_smarts_calculate(eo_e);
1993 }
1994 
1995 EAPI void
evas_smart_objects_calculate(Eo * eo_e)1996 evas_smart_objects_calculate(Eo *eo_e)
1997 {
1998    EVAS_TYPE_CHECK(eo_e);
1999    evas_call_smarts_calculate(eo_e);
2000 }
2001 
2002 EOLIAN Eina_Bool
_evas_canvas_efl_canvas_scene_group_objects_calculating_get(const Eo * eo_e EINA_UNUSED,Evas_Public_Data * e)2003 _evas_canvas_efl_canvas_scene_group_objects_calculating_get(const Eo *eo_e EINA_UNUSED, Evas_Public_Data *e)
2004 {
2005    return !!e->in_smart_calc;
2006 }
2007 
2008 EAPI Eina_Bool
evas_smart_objects_calculating_get(const Eo * obj)2009 evas_smart_objects_calculating_get(const Eo *obj)
2010 {
2011    EVAS_TYPE_CHECK(obj, EINA_FALSE);
2012    return efl_canvas_scene_group_objects_calculating_get(obj);
2013 }
2014 
2015 EOLIAN int
_evas_canvas_smart_objects_calculate_count_get(const Eo * eo_e EINA_UNUSED,Evas_Public_Data * e)2016 _evas_canvas_smart_objects_calculate_count_get(const Eo *eo_e EINA_UNUSED, Evas_Public_Data *e)
2017 {
2018    return e->smart_calc_count;
2019 }
2020 /* Legacy EAPI */
2021 
2022 EAPI Eina_Bool
evas_pointer_inside_get(const Evas * obj)2023 evas_pointer_inside_get(const Evas *obj)
2024 {
2025    EVAS_TYPE_CHECK(obj, EINA_FALSE);
2026    return efl_canvas_pointer_inside_get(obj, NULL);
2027 }
2028 
2029 EAPI Eina_Bool
evas_pointer_inside_by_device_get(const Evas * obj,Eo * dev)2030 evas_pointer_inside_by_device_get(const Evas *obj, Eo *dev)
2031 {
2032    EVAS_TYPE_CHECK(obj, EINA_FALSE);
2033    return efl_canvas_pointer_inside_get(obj, dev);
2034 }
2035 
2036 EAPI Eina_List*
evas_objects_at_xy_get(Eo * eo_e,int x,int y,Eina_Bool include_pass_events_objects,Eina_Bool include_hidden_objects)2037 evas_objects_at_xy_get(Eo *eo_e, int x, int y, Eina_Bool include_pass_events_objects, Eina_Bool include_hidden_objects)
2038 {
2039    EVAS_TYPE_CHECK(eo_e, NULL);
2040    return _efl_canvas_evas_canvas_objects_at_xy_get_helper(eo_e, efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS), x, y, include_pass_events_objects, include_hidden_objects);
2041 }
2042 /* Internal EO APIs */
2043 
2044 EWAPI const Efl_Event_Description _EVAS_CANVAS_EVENT_RENDER_FLUSH_PRE =
2045    EFL_EVENT_DESCRIPTION("render,flush,pre");
2046 EWAPI const Efl_Event_Description _EVAS_CANVAS_EVENT_RENDER_FLUSH_POST =
2047    EFL_EVENT_DESCRIPTION("render,flush,post");
2048 EWAPI const Efl_Event_Description _EVAS_CANVAS_EVENT_AXIS_UPDATE =
2049    EFL_EVENT_DESCRIPTION("axis,update");
2050 EWAPI const Efl_Event_Description _EVAS_CANVAS_EVENT_VIEWPORT_RESIZE =
2051    EFL_EVENT_DESCRIPTION("viewport,resize");
2052 
2053 #define CHECK_ADD(var, ev, member) \
2054   if ((var) == (ev)) \
2055     { \
2056        e->member = EINA_TRUE; \
2057     }
2058 
2059 
2060 EOLIAN static Eina_Bool
_evas_canvas_efl_object_event_callback_priority_add(Eo * obj,Evas_Public_Data * e,const Efl_Event_Description * desc,Efl_Callback_Priority priority,Efl_Event_Cb func,const void * user_data)2061 _evas_canvas_efl_object_event_callback_priority_add(Eo *obj, Evas_Public_Data *e, const Efl_Event_Description *desc, Efl_Callback_Priority priority, Efl_Event_Cb func, const void *user_data)
2062 {
2063    CHECK_ADD(desc, EVAS_CANVAS_EVENT_RENDER_FLUSH_PRE, cb_render_flush_pre)
2064    else CHECK_ADD(desc, EVAS_CANVAS_EVENT_RENDER_FLUSH_POST, cb_render_flush_post)
2065    else CHECK_ADD(desc, EFL_CANVAS_SCENE_EVENT_RENDER_PRE, cb_render_pre)
2066    else CHECK_ADD(desc, EFL_CANVAS_SCENE_EVENT_RENDER_POST, cb_render_post)
2067 
2068    return efl_event_callback_priority_add(efl_super(obj, MY_CLASS), desc, priority, func, user_data);
2069 }
2070 
2071 EOLIAN static Eina_Bool
_evas_canvas_efl_object_event_callback_array_priority_add(Eo * obj,Evas_Public_Data * e,const Efl_Callback_Array_Item * array,Efl_Callback_Priority priority,const void * user_data)2072 _evas_canvas_efl_object_event_callback_array_priority_add(Eo *obj, Evas_Public_Data *e, const Efl_Callback_Array_Item *array, Efl_Callback_Priority priority, const void *user_data)
2073 {
2074    for (int i = 0; array[i].desc; ++i)
2075      {
2076         CHECK_ADD(array[i].desc, EVAS_CANVAS_EVENT_RENDER_FLUSH_PRE, cb_render_flush_pre)
2077         else CHECK_ADD(array[i].desc, EVAS_CANVAS_EVENT_RENDER_FLUSH_POST, cb_render_flush_post)
2078         else CHECK_ADD(array[i].desc, EFL_CANVAS_SCENE_EVENT_RENDER_PRE, cb_render_pre)
2079         else CHECK_ADD(array[i].desc, EFL_CANVAS_SCENE_EVENT_RENDER_POST, cb_render_post)
2080      }
2081    return efl_event_callback_array_priority_add(efl_super(obj, MY_CLASS), array, priority, user_data);
2082 }
2083 #undef CHECK_ADD
2084 #define EVAS_CANVAS_EXTRA_OPS \
2085    EFL_OBJECT_OP_FUNC(efl_event_callback_priority_add, _evas_canvas_efl_object_event_callback_priority_add), \
2086    EFL_OBJECT_OP_FUNC(efl_event_callback_array_priority_add, _evas_canvas_efl_object_event_callback_array_priority_add)
2087 
2088 
2089 #include "evas_stack.x"
2090 #include "canvas/evas_canvas_eo.c"
2091 #include "efl_canvas_pointer.eo.c"
2092 #include "efl_canvas_scene.eo.c"
2093