1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4 
5 #define ECORE_EVAS_INTERNAL
6 #define EFL_INPUT_EVENT_PROTECTED
7 #define IPA_YLNO_ESU_LANRETNI_MLE
8 
9 #include <stdlib.h>
10 #include <string.h>
11 #include <sys/types.h>
12 #include <errno.h>
13 #include <sys/stat.h>
14 #include <fcntl.h>
15 #include <unistd.h>
16 
17 #ifdef _WIN32
18 # include <evil_private.h> /* mmap */
19 #else
20 # include <sys/mman.h>
21 #endif
22 
23 #include <Ecore.h>
24 #include "ecore_private.h"
25 #include <Ecore_Input.h>
26 #include <Ecore_Input_Evas.h>
27 #define EFL_INTERNAL_UNSTABLE
28 #include <Evas_Internal.h>
29 
30 #include "Ecore_Evas.h"
31 #include "ecore_evas_private.h"
32 #include "ecore_evas_x11.h"
33 #include "ecore_evas_wayland.h"
34 #include "ecore_evas_cocoa.h"
35 #include "ecore_evas_extn.h"
36 #include "ecore_evas_win32.h"
37 
38 #include "ecore_private.h"
39 
40 #ifndef O_BINARY
41 # define O_BINARY 0
42 #endif
43 
44 #define ECORE_EVAS_CHECK(ee, ...) \
45    if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) \
46      { \
47         ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, __func__); \
48         return __VA_ARGS__; \
49      }
50 
51 #define ECORE_EVAS_CHECK_GOTO(_ee, _label) \
52   if (!ECORE_MAGIC_CHECK(_ee, ECORE_MAGIC_EVAS)) \
53     { \
54        ECORE_MAGIC_FAIL(_ee, ECORE_MAGIC_EVAS, __func__); \
55        goto _label; \
56     }
57 
58 EAPI Eina_Error ecore_evas_no_matching_type;
59 EAPI Eina_Error ecore_evas_no_selection;
60 EAPI Eina_Error ecore_evas_request_replaced;
61 
62 EAPI Eina_Bool _ecore_evas_app_comp_sync = EINA_FALSE;
63 EAPI int _ecore_evas_log_dom = -1;
64 static int _ecore_evas_init_count = 0;
65 
66 static Ecore_Idle_Exiter *ecore_evas_idle_exiter = NULL;
67 static Ecore_Idle_Enterer *ecore_evas_idle_enterer = NULL;
68 static Ecore_Evas *ecore_evases = NULL;
69 static int _ecore_evas_fps_debug = 0;
70 
71 static const Efl_Event_Description *_event_description_get(Efl_Pointer_Action action);
72 
73 //RENDER_SYNC
74 static int _ecore_evas_render_sync = 1;
75 
76 static void _ecore_evas_animator_flush(Ecore_Evas *ee);
77 
78 static Ecore_Animator *_ecore_evas_animator_timeline_add(void *evo, double runtime, Ecore_Timeline_Cb func, const void *data);
79 static Ecore_Animator *_ecore_evas_animator_add(void *evo, Ecore_Task_Cb func, const void *data);
80 static void _ecore_evas_animator_freeze(Ecore_Animator *animator);
81 static void _ecore_evas_animator_thaw(Ecore_Animator *animator);
82 static void *_ecore_evas_animator_del(Ecore_Animator *animator);
83 
84 static void _ecore_evas_event_del(void *data, const Efl_Event *ev EINA_UNUSED);
85 
86 static void
_ecore_evas_focus_out_dispatch(Ecore_Evas * ee,Efl_Input_Device * seat)87 _ecore_evas_focus_out_dispatch(Ecore_Evas *ee, Efl_Input_Device *seat)
88 {
89    evas_canvas_seat_focus_out(ee->evas, seat);
90    if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee);
91    if (ee->func.fn_focus_device_out) ee->func.fn_focus_device_out(ee, seat);
92 }
93 
94 static void
_ecore_evas_device_del_cb(void * data,const Efl_Event * ev)95 _ecore_evas_device_del_cb(void *data, const Efl_Event *ev)
96 {
97    Ecore_Evas *ee = data;
98 
99    ee->prop.focused_by = eina_list_remove(ee->prop.focused_by, ev->object);
100    _ecore_evas_focus_out_dispatch(ee, ev->object);
101 }
102 
103 static void
_ecore_evas_mouse_out_dispatch(Ecore_Evas * ee,Efl_Input_Device * mouse)104 _ecore_evas_mouse_out_dispatch(Ecore_Evas *ee, Efl_Input_Device *mouse)
105 {
106    if (ee->func.fn_mouse_out) ee->func.fn_mouse_out(ee);
107    if (ee->func.fn_device_mouse_out) ee->func.fn_device_mouse_out(ee, mouse);
108 }
109 
110 static void
_ecore_evas_mouse_del_cb(void * data,const Efl_Event * ev)111 _ecore_evas_mouse_del_cb(void *data, const Efl_Event *ev)
112 {
113    Ecore_Evas *ee = data;
114 
115    ee->mice_in = eina_list_remove(ee->mice_in, ev->object);
116    _ecore_evas_mouse_out_dispatch(ee, ev->object);
117 }
118 
119 static void
_ecore_evas_animator(void * data,const Efl_Event * ev EINA_UNUSED)120 _ecore_evas_animator(void *data, const Efl_Event *ev EINA_UNUSED)
121 {
122    Ecore_Evas *ee = data;
123 
124    ee->animator_ticked = EINA_TRUE;
125 }
126 
127 static Eina_Bool
_ecore_evas_changes_get(Ecore_Evas * ee)128 _ecore_evas_changes_get(Ecore_Evas *ee)
129 {
130    Eina_List *l;
131 
132    if (evas_changed_get(ee->evas)) return EINA_TRUE;
133    EINA_LIST_FOREACH(ee->sub_ecore_evas, l, ee)
134      {
135         if (evas_changed_get(ee->evas)) return EINA_TRUE;
136      }
137    return EINA_FALSE;
138 }
139 
140 static Eina_Bool
_ecore_evas_idle_exiter(void * data EINA_UNUSED)141 _ecore_evas_idle_exiter(void *data EINA_UNUSED)
142 {
143    Ecore_Evas *ee;
144 
145    EINA_INLIST_FOREACH(ecore_evases, ee)
146      ee->animator_ran = EINA_FALSE;
147 
148    return ECORE_CALLBACK_RENEW;
149 }
150 
151 EAPI void
ecore_evas_render_wait(Ecore_Evas * ee)152 ecore_evas_render_wait(Ecore_Evas *ee)
153 {
154    if (ee->in_async_render) evas_sync(ee->evas);
155 }
156 
157 EAPI Eina_Bool
ecore_evas_render(Ecore_Evas * ee)158 ecore_evas_render(Ecore_Evas *ee)
159 {
160    Eina_Bool rend = EINA_FALSE;
161 
162    if (!ee->evas) return EINA_FALSE;
163 
164    if (ee->in_async_render)
165      {
166         DBG("ee=%p is rendering, skip.", ee);
167         return EINA_FALSE;
168      }
169 
170    if (ee->engine.func->fn_prepare)
171      if (!ee->engine.func->fn_prepare(ee))
172        return EINA_FALSE;
173 
174    ecore_evas_render_prepare(ee);
175 
176    if (!ee->visible || ee->draw_block)
177      {
178         evas_norender(ee->evas);
179      }
180    else if (ee->can_async_render && !ee->manual_render)
181      {
182         rend |= !!evas_render_async(ee->evas);
183         if (rend) ee->in_async_render = 1;
184      }
185    else
186      {
187         Eina_List *updates;
188 
189         updates = evas_render_updates(ee->evas);
190         rend |= !!updates;
191         evas_render_updates_free(updates);
192      }
193 
194    return rend;
195 }
196 
197 static void
_evas_evas_buffer_rendered(void * data,Evas * e EINA_UNUSED,void * event_info EINA_UNUSED)198 _evas_evas_buffer_rendered(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
199 {
200    Ecore_Evas *ee = data;
201 
202    _ecore_evas_idle_timeout_update(ee);
203 
204    if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
205    ee->in_async_render = 0;
206 }
207 
208 static Eina_Bool
_ecore_evas_idle_enter(void * data EINA_UNUSED)209 _ecore_evas_idle_enter(void *data EINA_UNUSED)
210 {
211    Ecore_Evas *ee;
212    double t1 = 0.0;
213    double t2 = 0.0;
214    int rend = 0;
215 #ifdef ECORE_EVAS_ASYNC_RENDER_DEBUG
216    double now = ecore_loop_time_get();
217 #endif
218 
219    if (!ecore_evases) return ECORE_CALLBACK_RENEW;
220 
221    if (_ecore_evas_fps_debug)
222      {
223         t1 = ecore_time_get();
224      }
225    EINA_INLIST_FOREACH(ecore_evases, ee)
226      {
227         if (ee->ee_anim.deleted)
228           _ecore_evas_animator_flush(ee);
229 
230         if (ee->draw_block) continue;
231 
232         if (ee->manual_render)
233           {
234              if (ee->engine.func->fn_evas_changed)
235                ee->engine.func->fn_evas_changed(ee, EINA_FALSE);
236              continue;
237           }
238         if (_ecore_evas_render_sync)
239           {
240              if (!ee->first_frame)
241                {
242                   if ((!ee->animator_ticked) &&
243                       (!ee->animator_ran))
244                     {
245                        if (_ecore_evas_changes_get(ee))
246                          {
247                             if (!ee->animator_registered)
248                               {
249                                  efl_event_callback_add(ee->evas, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK, _ecore_evas_animator, ee);
250                                  ee->animator_registered = EINA_TRUE;
251                               }
252                          }
253                        continue ;
254                     }
255                   ee->animator_ticked = EINA_FALSE;
256                }
257              ee->first_frame = EINA_FALSE;
258           }
259 
260 #ifdef ECORE_EVAS_ASYNC_RENDER_DEBUG
261         if ((ee->in_async_render) && (now - ee->async_render_start > 2.0))
262           {
263              ERR("stuck async render: time=%f, ee=%p, engine=%s, geometry=(%d, %d, %d, %d), visible=%hhu, shaped=%hhu, alpha=%hhu, transparent=%hhu",
264                  now - ee->async_render_start, ee, ee->driver, ee->x, ee->y, ee->w, ee->h, ee->visible, ee->shaped, ee->alpha, ee->transparent);
265 
266              ERR("delayed.avoid_damage=%hhu", ee->delayed.avoid_damage);
267              ERR("delayed.resize_shape=%hhu", ee->delayed.resize_shape);
268              ERR("delayed.shaped=%hhu", ee->delayed.shaped);
269              ERR("delayed.shaped_changed=%hhu", ee->delayed.shaped_changed);
270              ERR("delayed.alpha=%hhu", ee->delayed.alpha);
271              ERR("delayed.alpha_changed=%hhu", ee->delayed.alpha_changed);
272              ERR("delayed.transparent=%hhu", ee->delayed.transparent);
273              ERR("delayed.transparent_changed=%hhu", ee->delayed.transparent_changed);
274              ERR("delayed.rotation=%d", ee->delayed.rotation);
275              ERR("delayed.rotation_resize=%d", ee->delayed.rotation_resize);
276              ERR("delayed.rotation_changed=%d", ee->delayed.rotation_changed);
277 
278              ERR("reset in_async_render of ee=%p", ee);
279              ee->in_async_render = EINA_FALSE;
280              ee->async_render_start = 0.0;
281 
282           }
283         else if ((!ee->in_async_render) && (ee->async_render_start > 0.0))
284           {
285              DBG("--- async render %f ee=%p [%s] (%d, %d, %d, %d) visible=%hhu shaped=%hhu alpha=%hhu transparent=%hhu",
286                  now, ee, ee->driver, ee->x, ee->y, ee->w, ee->h, ee->visible, ee->shaped, ee->alpha, ee->transparent);
287              ee->async_render_start = 0.0;
288           }
289 #endif
290 
291         Eina_Bool change = EINA_FALSE;
292 
293         if (ee->engine.func->fn_render)
294           {
295              change = ee->engine.func->fn_render(ee);
296           }
297         else
298           {
299              change = ecore_evas_render(ee);
300           }
301         rend |= change;
302          /*
303           * Some engines that generate their own ticks based on hardware
304           * events need to know that render has been considered, and
305           * whether it will actually generate a new image or not
306           */
307         if (ee->engine.func->fn_evas_changed)
308           ee->engine.func->fn_evas_changed(ee, change);
309 
310         if (!change)
311           {
312              efl_event_callback_del(ee->evas, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK, _ecore_evas_animator, ee);
313              ee->animator_registered = EINA_FALSE;
314           }
315 #ifdef ECORE_EVAS_ASYNC_RENDER_DEBUG
316         if ((ee->in_async_render) && (ee->async_render_start <= 0.0))
317           {
318              DBG("+++ async render %f ee=%p [%s] (%d, %d, %d, %d) visible=%hhu shaped=%hhu alpha=%hhu transparent=%hhu",
319                  now, ee, ee->driver, ee->x, ee->y, ee->w, ee->h, ee->visible, ee->shaped, ee->alpha, ee->transparent);
320              ee->async_render_start = now;
321           }
322 #endif
323      }
324    if (_ecore_evas_fps_debug)
325      {
326         t2 = ecore_time_get();
327         if (rend)
328           _ecore_evas_fps_debug_rendertime_add(t2 - t1);
329      }
330    return ECORE_CALLBACK_RENEW;
331 }
332 
333 static void
_ecore_evas_object_cursor_del(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)334 _ecore_evas_object_cursor_del(void *data, Evas *e EINA_UNUSED,
335                               Evas_Object *obj EINA_UNUSED,
336                               void *event_info EINA_UNUSED)
337 {
338    Ecore_Evas_Cursor *cursor = data;
339    cursor->object = NULL;
340 }
341 
342 static void
_ecore_evas_cursor_element_del(Ecore_Evas_Cursor * cursor)343 _ecore_evas_cursor_element_del(Ecore_Evas_Cursor *cursor)
344 {
345    if (cursor->object)
346      {
347         evas_object_event_callback_del_full(cursor->object, EVAS_CALLBACK_DEL,
348                                             _ecore_evas_object_cursor_del,
349                                             cursor);
350         evas_object_del(cursor->object);
351      }
352    free(cursor);
353 }
354 
355 static void
_ecore_evas_cursor_add(Ecore_Evas * ee,Efl_Input_Device * dev)356 _ecore_evas_cursor_add(Ecore_Evas *ee, Efl_Input_Device *dev)
357 {
358    Ecore_Evas_Cursor *cursor;
359    Eo *seat;
360 
361    seat = dev;
362    if (evas_device_class_get(dev) != EVAS_DEVICE_CLASS_SEAT)
363      seat = efl_input_device_seat_get(dev);
364    if (eina_hash_find(ee->prop.cursors, &seat)) return;
365    cursor = calloc(1, sizeof(Ecore_Evas_Cursor));
366    EINA_SAFETY_ON_NULL_RETURN(cursor);
367    eina_hash_add(ee->prop.cursors, &seat, cursor);
368    if (seat != evas_default_device_get(ee->evas, EVAS_DEVICE_CLASS_SEAT)) return;
369    if (ee->prop.cursor_cache.object)
370      {
371         ecore_evas_object_cursor_device_set(ee, dev,
372                                             ee->prop.cursor_cache.object,
373                                             ee->prop.cursor_cache.layer,
374                                             ee->prop.cursor_cache.hot.x,
375                                             ee->prop.cursor_cache.hot.y);
376         memset(&ee->prop.cursor_cache, 0, sizeof(Ecore_Evas_Cursor));
377      }
378 }
379 
380 static inline Eina_Bool
_is_pointer(Eo * dev)381 _is_pointer(Eo *dev)
382 {
383    Efl_Input_Device_Type c = efl_input_device_type_get(dev);
384    return (c == EFL_INPUT_DEVICE_TYPE_MOUSE) ||
385             (c == EFL_INPUT_DEVICE_TYPE_PEN) ||
386             (c == EFL_INPUT_DEVICE_TYPE_TOUCH) ||
387             (c == EFL_INPUT_DEVICE_TYPE_WAND);
388 }
389 
390 static void
_ecore_evas_dev_added_or_removed(void * data,const Efl_Event * event)391 _ecore_evas_dev_added_or_removed(void *data, const Efl_Event *event)
392 {
393    Ecore_Evas *ee = data;
394 
395    if (event->desc == EFL_CANVAS_SCENE_EVENT_DEVICE_ADDED)
396      {
397         if (_is_pointer(event->info))
398           _ecore_evas_cursor_add(ee, event->info);
399         else if (event->info == evas_default_device_get(ee->evas, EVAS_DEVICE_CLASS_SEAT))
400           {
401              if (ee->prop.focused)
402                _ecore_evas_focus_device_set(ee, event->info, 1);
403           }
404      }
405    else
406      {
407         Eina_Iterator *it;
408         Eina_Bool found = EINA_FALSE;
409         Eo *dev, *seat = efl_input_device_seat_get(event->info);
410 
411         it = efl_input_device_children_iterate(seat);
412         EINA_ITERATOR_FOREACH(it, dev)
413           if ((dev != event->info) && _is_pointer(dev))
414             {
415                found = EINA_TRUE;
416                break;
417             }
418         eina_iterator_free(it);
419         if (!found)
420           eina_hash_del_by_key(ee->prop.cursors, &seat);
421      }
422 }
423 
424 EFL_CALLBACKS_ARRAY_DEFINE(_ecore_evas_device_cbs,
425                            { EFL_CANVAS_SCENE_EVENT_DEVICE_ADDED, _ecore_evas_dev_added_or_removed },
426                            { EFL_CANVAS_SCENE_EVENT_DEVICE_REMOVED, _ecore_evas_dev_added_or_removed });
427 Eina_Bool
_ecore_evas_cursors_init(Ecore_Evas * ee)428 _ecore_evas_cursors_init(Ecore_Evas *ee)
429 {
430    const Eina_List *devs, *l;
431    Efl_Input_Device *dev;
432 
433    if (!ee) return EINA_FALSE;
434    ee->prop.cursors = eina_hash_pointer_new(EINA_FREE_CB(_ecore_evas_cursor_element_del));
435    EINA_SAFETY_ON_NULL_RETURN_VAL(ee->prop.cursors, EINA_FALSE);
436 
437    devs = evas_device_list(ee->evas, NULL);
438 
439    EINA_LIST_FOREACH(devs, l, dev)
440      {
441         if (_is_pointer(dev))
442           _ecore_evas_cursor_add(ee, dev);
443      }
444 
445    efl_event_callback_array_priority_add(ee->evas, _ecore_evas_device_cbs(),
446                                          EFL_CALLBACK_PRIORITY_BEFORE, ee);
447 
448    return EINA_TRUE;
449 }
450 
451 static Ecore_Evas_Interface *
_ecore_evas_interface_get_internal(const Ecore_Evas * ee,const char * iname,Eina_Bool cri)452 _ecore_evas_interface_get_internal(const Ecore_Evas *ee, const char *iname, Eina_Bool cri)
453 {
454    Eina_List *l;
455    Ecore_Evas_Interface *i;
456 
457    EINA_SAFETY_ON_NULL_RETURN_VAL(ee, NULL);
458    EINA_SAFETY_ON_NULL_RETURN_VAL(iname, NULL);
459 
460    EINA_LIST_FOREACH(ee->engine.ifaces, l, i)
461      {
462         if (!strcmp(i->name, iname))
463           return i;
464      }
465 
466    if (cri)
467      CRI("Ecore_Evas %p (engine: %s) does not have interface '%s'",
468           ee, ee->driver, iname);
469 
470    return NULL;
471 }
472 
473 EAPI Ecore_Evas_Interface *
_ecore_evas_interface_get(const Ecore_Evas * ee,const char * iname)474 _ecore_evas_interface_get(const Ecore_Evas *ee, const char *iname)
475 {
476    return _ecore_evas_interface_get_internal(ee, iname, 1);
477 }
478 
479 /**
480  * Query if a particular rendering engine target has support
481  * @param  engine The engine to check support for
482  * @return 1 if the particular engine is supported, 0 if it is not
483  *
484  * Query if engine @param engine is supported by ecore_evas. 1 is returned if
485  * it is, and 0 is returned if it is not supported.
486  */
487 EAPI int
ecore_evas_engine_type_supported_get(Ecore_Evas_Engine_Type engine)488 ecore_evas_engine_type_supported_get(Ecore_Evas_Engine_Type engine)
489 {
490    /* It should be done reading the availables engines */
491 
492    switch (engine)
493      {
494       case ECORE_EVAS_ENGINE_SOFTWARE_BUFFER:
495         return EINA_TRUE;
496 
497       case ECORE_EVAS_ENGINE_SOFTWARE_XLIB:
498 #ifdef BUILD_ECORE_EVAS_SOFTWARE_XLIB
499         return EINA_TRUE;
500 #else
501         return EINA_FALSE;
502 #endif
503       case ECORE_EVAS_ENGINE_XRENDER_X11:
504         return EINA_FALSE;
505       case ECORE_EVAS_ENGINE_OPENGL_X11:
506 #ifdef BUILD_ECORE_EVAS_OPENGL_X11
507         return EINA_TRUE;
508 #else
509         return EINA_FALSE;
510 #endif
511       case ECORE_EVAS_ENGINE_SOFTWARE_XCB: /* @deprecated */
512         return EINA_FALSE;
513       case ECORE_EVAS_ENGINE_XRENDER_XCB: /* @deprecated */
514         return EINA_FALSE;
515       case ECORE_EVAS_ENGINE_SOFTWARE_GDI:
516 #ifdef BUILD_ECORE_EVAS_SOFTWARE_GDI
517         return EINA_TRUE;
518 #else
519         return EINA_FALSE;
520 #endif
521       case ECORE_EVAS_ENGINE_SOFTWARE_DDRAW:
522 #ifdef BUILD_ECORE_EVAS_SOFTWARE_DDRAW
523         return EINA_TRUE;
524 #else
525         return EINA_FALSE;
526 #endif
527      case ECORE_EVAS_ENGINE_SOFTWARE_SDL:
528 #ifdef BUILD_ECORE_EVAS_SOFTWARE_SDL
529         return EINA_TRUE;
530 #else
531         return EINA_FALSE;
532 #endif
533      case ECORE_EVAS_ENGINE_OPENGL_SDL:
534 #ifdef BUILD_ECORE_EVAS_OPENGL_SDL
535         return EINA_TRUE;
536 #else
537         return EINA_FALSE;
538 #endif
539       case ECORE_EVAS_ENGINE_DIRECTFB:
540         return EINA_FALSE;
541       case ECORE_EVAS_ENGINE_SOFTWARE_FB:
542 #ifdef BUILD_ECORE_EVAS_FB
543         return EINA_TRUE;
544 #else
545         return EINA_FALSE;
546 #endif
547 
548       case ECORE_EVAS_ENGINE_SOFTWARE_8_X11:
549         return EINA_FALSE;
550       case ECORE_EVAS_ENGINE_SOFTWARE_16_X11:
551         return EINA_FALSE;
552       case ECORE_EVAS_ENGINE_SOFTWARE_16_DDRAW:
553         return EINA_FALSE;
554       case ECORE_EVAS_ENGINE_SOFTWARE_16_WINCE:
555         return EINA_FALSE;
556       case ECORE_EVAS_ENGINE_DIRECT3D:
557         return EINA_FALSE;
558       case ECORE_EVAS_ENGINE_OPENGL_GLEW:
559         return EINA_FALSE;
560 
561       case ECORE_EVAS_ENGINE_OPENGL_COCOA:
562 #ifdef BUILD_ECORE_EVAS_OPENGL_COCOA
563         return EINA_TRUE;
564 #else
565         return EINA_FALSE;
566 #endif
567       case ECORE_EVAS_ENGINE_EWS:
568 #ifdef BUILD_ECORE_EVAS_EWS
569         return EINA_TRUE;
570 #else
571         return EINA_FALSE;
572 #endif
573      case ECORE_EVAS_ENGINE_PSL1GHT:
574         return EINA_FALSE;
575      case ECORE_EVAS_ENGINE_WAYLAND_SHM:
576 #ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
577         return EINA_TRUE;
578 #else
579         return EINA_FALSE;
580 #endif
581      case ECORE_EVAS_ENGINE_WAYLAND_EGL:
582 #ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
583         return EINA_TRUE;
584 #else
585         return EINA_FALSE;
586 #endif
587      case ECORE_EVAS_ENGINE_DRM:
588 #ifdef BUILD_ECORE_EVAS_DRM
589         return EINA_TRUE;
590 #else
591         return EINA_FALSE;
592 #endif
593      case ECORE_EVAS_ENGINE_OPENGL_DRM:
594 #ifdef BUILD_ECORE_EVAS_GL_DRM
595         return EINA_TRUE;
596 #else
597         return EINA_FALSE;
598 #endif
599 
600       default:
601         return EINA_FALSE;
602      };
603 }
604 
605 EAPI int
ecore_evas_init(void)606 ecore_evas_init(void)
607 {
608    Ecore_Evas_Object_Animator_Interface iface;
609 
610    if (++_ecore_evas_init_count != 1)
611      return _ecore_evas_init_count;
612 
613    if (!ecore_init())
614      goto shutdown_evas;
615 
616    if (!evas_init())
617      return --_ecore_evas_init_count;
618 
619    _ecore_evas_log_dom = eina_log_domain_register
620      ("ecore_evas", ECORE_EVAS_DEFAULT_LOG_COLOR);
621    if(_ecore_evas_log_dom < 0)
622      {
623         EINA_LOG_ERR("Impossible to create a log domain for Ecore_Evas.");
624         goto shutdown_ecore;
625      }
626 
627    ecore_evas_idle_enterer =
628      ecore_idle_enterer_add(_ecore_evas_idle_enter, NULL);
629    ecore_evas_idle_exiter =
630      ecore_idle_exiter_add(_ecore_evas_idle_exiter, NULL);
631    if (getenv("ECORE_EVAS_FPS_DEBUG")) _ecore_evas_fps_debug = 1;
632    if (getenv("ECORE_EVAS_RENDER_NOSYNC")) _ecore_evas_render_sync = 0;
633    if (_ecore_evas_fps_debug) _ecore_evas_fps_debug_init();
634 
635 #ifdef BUILD_ECORE_EVAS_EWS
636    _ecore_evas_ews_events_init();
637 #endif
638 
639    _ecore_evas_extn_init();
640 
641    _ecore_evas_engine_init();
642 
643    eina_log_timing(_ecore_evas_log_dom,
644 		   EINA_LOG_STATE_STOP,
645 		   EINA_LOG_STATE_INIT);
646 
647    if (getenv("ECORE_EVAS_COMP_NOSYNC"))
648      _ecore_evas_app_comp_sync = EINA_FALSE;
649    else if (getenv("ECORE_EVAS_COMP_SYNC"))
650      _ecore_evas_app_comp_sync = EINA_TRUE;
651 
652    iface.add = _ecore_evas_animator_add;
653    iface.timeline_add = _ecore_evas_animator_timeline_add;
654    iface.freeze = _ecore_evas_animator_freeze;
655    iface.thaw = _ecore_evas_animator_thaw;
656    iface.del = _ecore_evas_animator_del;
657    ecore_evas_object_animator_init(&iface);
658 
659    ecore_evas_no_matching_type = eina_error_msg_register("No fitting type could be found");
660    ecore_evas_no_selection = eina_error_msg_register("No selection available");
661    ecore_evas_request_replaced = eina_error_msg_register("Selection request replaced");
662 
663    return _ecore_evas_init_count;
664 
665  shutdown_ecore:
666    ecore_shutdown();
667  shutdown_evas:
668    evas_shutdown();
669 
670    return --_ecore_evas_init_count;
671 }
672 
673 EAPI int
ecore_evas_shutdown(void)674 ecore_evas_shutdown(void)
675 {
676    if (--_ecore_evas_init_count != 0)
677      return _ecore_evas_init_count;
678 
679    eina_log_timing(_ecore_evas_log_dom,
680                    EINA_LOG_STATE_START,
681                    EINA_LOG_STATE_SHUTDOWN);
682 
683 #ifdef BUILD_ECORE_EVAS_EWS
684    _ecore_evas_ews_events_flush();
685 #endif
686 
687    while (ecore_evases) _ecore_evas_free(ecore_evases);
688 
689    if (_ecore_evas_fps_debug) _ecore_evas_fps_debug_shutdown();
690    ecore_idle_enterer_del(ecore_evas_idle_enterer);
691    ecore_evas_idle_enterer = NULL;
692    ecore_idle_exiter_del(ecore_evas_idle_exiter);
693    ecore_evas_idle_exiter = NULL;
694 
695    _ecore_evas_extn_shutdown();
696 
697 #ifdef BUILD_ECORE_EVAS_EWS
698    while (_ecore_evas_ews_shutdown());
699 #endif
700    _ecore_evas_engine_shutdown();
701 
702    eina_log_domain_unregister(_ecore_evas_log_dom);
703    _ecore_evas_log_dom = -1;
704    ecore_shutdown();
705    evas_shutdown();
706 
707    return _ecore_evas_init_count;
708 }
709 
710 EAPI void
ecore_evas_app_comp_sync_set(Eina_Bool do_sync)711 ecore_evas_app_comp_sync_set(Eina_Bool do_sync)
712 {
713    _ecore_evas_app_comp_sync = do_sync;
714 }
715 
716 EAPI Eina_Bool
ecore_evas_app_comp_sync_get(void)717 ecore_evas_app_comp_sync_get(void)
718 {
719    return _ecore_evas_app_comp_sync;
720 }
721 
722 struct ecore_evas_engine {
723    const char *name;
724    Ecore_Evas *(*constructor)(int x, int y, int w, int h, const char *extra_options);
725 };
726 
727 /* inline is just to avoid need to ifdef around it */
728 static inline const char *
_ecore_evas_parse_extra_options_str(const char * extra_options,const char * key,char ** value)729 _ecore_evas_parse_extra_options_str(const char *extra_options, const char *key, char **value)
730 {
731    int len = strlen(key);
732 
733    while (extra_options)
734      {
735         const char *p;
736 
737         if (strncmp(extra_options, key, len) != 0)
738           {
739              extra_options = strchr(extra_options, ';');
740              if (extra_options)
741                extra_options++;
742              continue;
743           }
744 
745         extra_options += len;
746         p = strchr(extra_options, ';');
747         if (p)
748           {
749              len = p - extra_options;
750              *value = malloc(len + 1);
751              memcpy(*value, extra_options, len);
752              (*value)[len] = '\0';
753              extra_options = p + 1;
754           }
755         else
756           {
757              *value = strdup(extra_options);
758              extra_options = NULL;
759           }
760      }
761    return extra_options;
762 }
763 
764 /* inline is just to avoid need to ifdef around it */
765 static inline const char *
_ecore_evas_parse_extra_options_uint(const char * extra_options,const char * key,unsigned int * value)766 _ecore_evas_parse_extra_options_uint(const char *extra_options, const char *key, unsigned int *value)
767 {
768    int len = strlen(key);
769 
770    while (extra_options)
771      {
772         const char *p;
773 
774         if (strncmp(extra_options, key, len) != 0)
775           {
776              extra_options = strchr(extra_options, ';');
777              if (extra_options)
778                extra_options++;
779              continue;
780           }
781 
782         extra_options += len;
783         *value = strtol(extra_options, NULL, 0);
784 
785         p = strchr(extra_options, ';');
786         if (p)
787           extra_options = p + 1;
788         else
789           extra_options = NULL;
790      }
791    return extra_options;
792 }
793 
794 /* inline is just to avoid need to ifdef around it */
795 static inline const char *
_ecore_evas_parse_extra_options_x(const char * extra_options,char ** disp_name,unsigned int * parent)796 _ecore_evas_parse_extra_options_x(const char *extra_options, char **disp_name, unsigned int *parent)
797 {
798    _ecore_evas_parse_extra_options_str(extra_options, "display=", disp_name);
799    _ecore_evas_parse_extra_options_uint(extra_options, "parent=", parent);
800    return extra_options;
801 }
802 
803 static Ecore_Evas *
_ecore_evas_constructor_software_x11(int x,int y,int w,int h,const char * extra_options)804 _ecore_evas_constructor_software_x11(int x, int y, int w, int h, const char *extra_options)
805 {
806    unsigned int parent = 0;
807    char *disp_name = NULL;
808    Ecore_Evas *ee;
809 
810    _ecore_evas_parse_extra_options_x(extra_options, &disp_name, &parent);
811    ee = ecore_evas_software_x11_new(disp_name, parent, x, y, w, h);
812    free(disp_name);
813 
814    return ee;
815 }
816 
817 static Ecore_Evas *
_ecore_evas_constructor_cocoa(int x,int y,int w,int h,const char * extra_options)818 _ecore_evas_constructor_cocoa(int x, int y, int w, int h, const char *extra_options)
819 {
820    char *name = NULL;
821    Ecore_Evas *ee;
822 
823    _ecore_evas_parse_extra_options_str(extra_options, "name=", &name);
824    ee = ecore_evas_cocoa_new(NULL, x, y, w, h);
825    free(name);
826 
827    if (ee) ecore_evas_move(ee, x, y);
828    return ee;
829 }
830 
831 static Ecore_Evas *
_ecore_evas_constructor_opengl_x11(int x,int y,int w,int h,const char * extra_options)832 _ecore_evas_constructor_opengl_x11(int x, int y, int w, int h, const char *extra_options)
833 {
834    Ecore_X_Window parent = 0;
835    char *disp_name = NULL;
836    Ecore_Evas *ee;
837 
838    _ecore_evas_parse_extra_options_x(extra_options, &disp_name, &parent);
839    ee = ecore_evas_gl_x11_new(disp_name, parent, x, y, w, h);
840    free(disp_name);
841 
842    return ee;
843 }
844 
845 static Ecore_Evas *
_ecore_evas_constructor_sdl(int x EINA_UNUSED,int y EINA_UNUSED,int w,int h,const char * extra_options)846 _ecore_evas_constructor_sdl(int x EINA_UNUSED, int y EINA_UNUSED, int w, int h, const char *extra_options)
847 {
848    Ecore_Evas *ee;
849    unsigned int fullscreen = 0, hwsurface = 0, noframe = 0, alpha = 0;
850    char *name = NULL;
851 
852    _ecore_evas_parse_extra_options_str(extra_options, "name=", &name);
853    _ecore_evas_parse_extra_options_uint(extra_options, "fullscreen=", &fullscreen);
854    _ecore_evas_parse_extra_options_uint(extra_options, "hwsurface=", &hwsurface);
855    _ecore_evas_parse_extra_options_uint(extra_options, "noframe=", &noframe);
856    _ecore_evas_parse_extra_options_uint(extra_options, "alpha=", &alpha);
857 
858    ee = ecore_evas_sdl_new(name, w, h, fullscreen, hwsurface, noframe, alpha);
859    free(name);
860 
861    return ee;
862 }
863 static Ecore_Evas *
_ecore_evas_constructor_opengl_sdl(int x EINA_UNUSED,int y EINA_UNUSED,int w,int h,const char * extra_options)864 _ecore_evas_constructor_opengl_sdl(int x EINA_UNUSED, int y EINA_UNUSED, int w, int h, const char *extra_options)
865 {
866    Ecore_Evas *ee;
867    unsigned int fullscreen = 0, noframe = 0;
868    char *name = NULL;
869 
870    _ecore_evas_parse_extra_options_str(extra_options, "name=", &name);
871    _ecore_evas_parse_extra_options_uint(extra_options, "fullscreen=", &fullscreen);
872    _ecore_evas_parse_extra_options_uint(extra_options, "noframe=", &noframe);
873 
874    ee = ecore_evas_gl_sdl_new(name, w, h, fullscreen, noframe);
875    free(name);
876 
877    return ee;
878 }
879 
880 static Ecore_Evas *
_ecore_evas_constructor_fb(int x EINA_UNUSED,int y EINA_UNUSED,int w,int h,const char * extra_options)881 _ecore_evas_constructor_fb(int x EINA_UNUSED, int y EINA_UNUSED, int w, int h, const char *extra_options)
882 {
883    Ecore_Evas *ee;
884    char *disp_name = NULL;
885    unsigned int rotation = 0;
886 
887    _ecore_evas_parse_extra_options_str(extra_options, "display=", &disp_name);
888    _ecore_evas_parse_extra_options_uint(extra_options, "rotation=", &rotation);
889 
890    ee = ecore_evas_fb_new(disp_name, rotation, w, h);
891    free(disp_name);
892 
893    return ee;
894 }
895 
896 static Ecore_Evas *
_ecore_evas_constructor_psl1ght(int x EINA_UNUSED,int y EINA_UNUSED,int w EINA_UNUSED,int h EINA_UNUSED,const char * extra_options EINA_UNUSED)897 _ecore_evas_constructor_psl1ght(int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED, const char *extra_options EINA_UNUSED)
898 {
899    return NULL;
900 }
901 
902 static Ecore_Evas *
_ecore_evas_constructor_wayland_shm(int x,int y,int w,int h,const char * extra_options)903 _ecore_evas_constructor_wayland_shm(int x, int y, int w, int h, const char *extra_options)
904 {
905    char *disp_name = NULL;
906    unsigned int frame = 0, parent = 0;
907    Ecore_Evas *ee;
908 
909    _ecore_evas_parse_extra_options_str(extra_options, "display=", &disp_name);
910    _ecore_evas_parse_extra_options_uint(extra_options, "frame=", &frame);
911    _ecore_evas_parse_extra_options_uint(extra_options, "parent=", &parent);
912    ee = ecore_evas_wayland_shm_new(disp_name, parent, x, y, w, h, frame);
913    free(disp_name);
914 
915    return ee;
916 }
917 
918 static Ecore_Evas *
_ecore_evas_constructor_wayland_egl(int x,int y,int w,int h,const char * extra_options)919 _ecore_evas_constructor_wayland_egl(int x, int y, int w, int h, const char *extra_options)
920 {
921    char *disp_name = NULL;
922    unsigned int frame = 0, parent = 0;
923    Ecore_Evas *ee;
924 
925    _ecore_evas_parse_extra_options_str(extra_options, "display=", &disp_name);
926    _ecore_evas_parse_extra_options_uint(extra_options, "frame=", &frame);
927    _ecore_evas_parse_extra_options_uint(extra_options, "parent=", &parent);
928    ee = ecore_evas_wayland_egl_new(disp_name, parent, x, y, w, h, frame);
929    free(disp_name);
930 
931    return ee;
932 }
933 
934 static Ecore_Evas *
_ecore_evas_constructor_drm(int x,int y,int w,int h,const char * extra_options)935 _ecore_evas_constructor_drm(int x, int y, int w, int h, const char *extra_options)
936 {
937    char *device = NULL;
938    unsigned int parent = 0;
939    Ecore_Evas *ee;
940 
941    _ecore_evas_parse_extra_options_str(extra_options, "device=", &device);
942    _ecore_evas_parse_extra_options_uint(extra_options, "parent=", &parent);
943    ee = ecore_evas_drm_new(device, parent, x, y, w, h);
944    free(device);
945 
946    return ee;
947 }
948 
949 static Ecore_Evas *
_ecore_evas_constructor_opengl_drm(int x,int y,int w,int h,const char * extra_options)950 _ecore_evas_constructor_opengl_drm(int x, int y, int w, int h, const char *extra_options)
951 {
952    char *device = NULL;
953    unsigned int parent = 0;
954    Ecore_Evas *ee;
955 
956    _ecore_evas_parse_extra_options_str(extra_options, "device=", &device);
957    _ecore_evas_parse_extra_options_uint(extra_options, "parent=", &parent);
958    ee = ecore_evas_gl_drm_new(device, parent, x, y, w, h);
959    free(device);
960 
961    return ee;
962 }
963 
964 static Ecore_Evas *
_ecore_evas_constructor_software_gdi(int x,int y,int w,int h,const char * extra_options EINA_UNUSED)965 _ecore_evas_constructor_software_gdi(int x, int y, int w, int h,
966 				     const char *extra_options EINA_UNUSED)
967 {
968    return ecore_evas_software_gdi_new(NULL, x, y, w, h);
969 }
970 
971 static Ecore_Evas *
_ecore_evas_constructor_software_ddraw(int x,int y,int w,int h,const char * extra_options EINA_UNUSED)972 _ecore_evas_constructor_software_ddraw(int x, int y, int w, int h,
973 				       const char *extra_options EINA_UNUSED)
974 {
975    return ecore_evas_software_ddraw_new(NULL, x, y, w, h);
976 }
977 
978 static Ecore_Evas *
_ecore_evas_constructor_direct3d(int x,int y,int w,int h,const char * extra_options EINA_UNUSED)979 _ecore_evas_constructor_direct3d(int x, int y, int w, int h,
980 				 const char *extra_options EINA_UNUSED)
981 {
982    return ecore_evas_direct3d_new(NULL, x, y, w, h);
983 }
984 
985 static Ecore_Evas *
_ecore_evas_constructor_opengl_glew(int x,int y,int w,int h,const char * extra_options EINA_UNUSED)986 _ecore_evas_constructor_opengl_glew(int x, int y, int w, int h,
987 				    const char *extra_options EINA_UNUSED)
988 {
989    return ecore_evas_gl_glew_new(NULL, x, y, w, h);
990 }
991 
992 static Ecore_Evas *
_ecore_evas_constructor_buffer(int x EINA_UNUSED,int y EINA_UNUSED,int w,int h,const char * extra_options EINA_UNUSED)993 _ecore_evas_constructor_buffer(int x EINA_UNUSED, int y EINA_UNUSED, int w, int h, const char *extra_options EINA_UNUSED)
994 {
995    return ecore_evas_buffer_new(w, h);
996 }
997 
998 #ifdef BUILD_ECORE_EVAS_EWS
999 static Ecore_Evas *
_ecore_evas_constructor_ews(int x,int y,int w,int h,const char * extra_options EINA_UNUSED)1000 _ecore_evas_constructor_ews(int x, int y, int w, int h, const char *extra_options EINA_UNUSED)
1001 {
1002    return ecore_evas_ews_new(x, y, w, h);
1003 }
1004 #endif
1005 
1006 /* note: keep sorted by priority, highest first */
1007 static const struct ecore_evas_engine _engines[] = {
1008   /* unix */
1009   {"software_x11", _ecore_evas_constructor_software_x11},
1010   {"opengl_x11", _ecore_evas_constructor_opengl_x11},
1011   {"fb", _ecore_evas_constructor_fb},
1012   {"software_gdi", _ecore_evas_constructor_software_gdi},
1013   {"software_ddraw", _ecore_evas_constructor_software_ddraw},
1014   {"direct3d", _ecore_evas_constructor_direct3d},
1015   {"opengl_glew", _ecore_evas_constructor_opengl_glew},
1016   {"opengl_cocoa", _ecore_evas_constructor_cocoa},
1017   {"psl1ght", _ecore_evas_constructor_psl1ght},
1018   {"wayland_shm", _ecore_evas_constructor_wayland_shm},
1019   {"wayland_egl", _ecore_evas_constructor_wayland_egl},
1020   {"drm", _ecore_evas_constructor_drm},
1021   {"gl_drm", _ecore_evas_constructor_opengl_drm},
1022   {"opengl_sdl", _ecore_evas_constructor_opengl_sdl},
1023   {"sdl", _ecore_evas_constructor_sdl},
1024   {"buffer", _ecore_evas_constructor_buffer},
1025 #ifdef BUILD_ECORE_EVAS_EWS
1026   {"ews", _ecore_evas_constructor_ews},
1027 #endif
1028   {NULL, NULL}
1029 };
1030 
1031 EAPI Eina_List *
ecore_evas_engines_get(void)1032 ecore_evas_engines_get(void)
1033 {
1034    return eina_list_clone(_ecore_evas_available_engines_get());
1035 }
1036 
1037 EAPI void
ecore_evas_engines_free(Eina_List * engines)1038 ecore_evas_engines_free(Eina_List *engines)
1039 {
1040    eina_list_free(engines);
1041 }
1042 
1043 static Ecore_Evas *
_ecore_evas_new_auto_discover(int x,int y,int w,int h,const char * extra_options)1044 _ecore_evas_new_auto_discover(int x, int y, int w, int h, const char *extra_options)
1045 {
1046    const struct ecore_evas_engine *itr;
1047 
1048    DBG("auto discover engine");
1049 
1050    for (itr = _engines; itr->constructor; itr++)
1051      {
1052         Ecore_Evas *ee = itr->constructor(x, y, w, h, extra_options);
1053         if (ee)
1054           {
1055              INF("auto discovered '%s'", itr->name);
1056              return ee;
1057           }
1058      }
1059 
1060    WRN("could not auto discover.");
1061    return NULL;
1062 }
1063 
1064 EAPI Ecore_Evas *
ecore_evas_new(const char * engine_name,int x,int y,int w,int h,const char * extra_options)1065 ecore_evas_new(const char *engine_name, int x, int y, int w, int h, const char *extra_options)
1066 {
1067    const struct ecore_evas_engine *itr;
1068 
1069    if (!engine_name)
1070      {
1071         engine_name = getenv("ECORE_EVAS_ENGINE");
1072         if (engine_name)
1073           DBG("no engine_name provided, using ECORE_EVAS_ENGINE='%s'",
1074               engine_name);
1075      }
1076    if (!engine_name)
1077      return _ecore_evas_new_auto_discover(x, y, w, h, extra_options);
1078 
1079    for (itr = _engines; itr->name; itr++)
1080      if (strcmp(itr->name, engine_name) == 0)
1081        {
1082           INF("using engine '%s', extra_options=%s",
1083               engine_name, extra_options ? extra_options : "(null)");
1084           return itr->constructor(x, y, w, h, extra_options);
1085        }
1086 
1087    WRN("unknown engine '%s'", engine_name);
1088    return NULL;
1089 }
1090 
1091 EAPI const char *
ecore_evas_engine_name_get(const Ecore_Evas * ee)1092 ecore_evas_engine_name_get(const Ecore_Evas *ee)
1093 {
1094    if (!ee)
1095      return NULL;
1096    return ee->driver;
1097 }
1098 
1099 EAPI Ecore_Evas *
ecore_evas_ecore_evas_get(const Evas * e)1100 ecore_evas_ecore_evas_get(const Evas *e)
1101 {
1102    Ecore_Evas *ee = evas_data_attach_get(e);
1103    if (!ee) return NULL;
1104    ECORE_EVAS_CHECK(ee, NULL);
1105    return ee;
1106 }
1107 
1108 EAPI void
ecore_evas_free(Ecore_Evas * ee)1109 ecore_evas_free(Ecore_Evas *ee)
1110 {
1111    if (!ee) return;
1112    ECORE_EVAS_CHECK(ee);
1113    _ecore_evas_free(ee);
1114    return;
1115 }
1116 
1117 EAPI void *
ecore_evas_data_get(const Ecore_Evas * ee,const char * key)1118 ecore_evas_data_get(const Ecore_Evas *ee, const char *key)
1119 {
1120    ECORE_EVAS_CHECK(ee, NULL);
1121 
1122    if (!key) return NULL;
1123    if (!ee->data) return NULL;
1124 
1125    return eina_hash_find(ee->data, key);
1126 }
1127 
1128 EAPI void
ecore_evas_data_set(Ecore_Evas * ee,const char * key,const void * data)1129 ecore_evas_data_set(Ecore_Evas *ee, const char *key, const void *data)
1130 {
1131    ECORE_EVAS_CHECK(ee);
1132 
1133    if (!key) return;
1134 
1135    if (ee->data)
1136      eina_hash_del(ee->data, key, NULL);
1137    if (data)
1138      {
1139        if (!ee->data)
1140          ee->data = eina_hash_string_superfast_new(NULL);
1141        eina_hash_add(ee->data, key, data);
1142      }
1143 }
1144 
1145 EAPI Evas *
ecore_evas_object_evas_get(Evas_Object * obj)1146 ecore_evas_object_evas_get(Evas_Object *obj)
1147 {
1148    Ecore_Evas *ee;
1149 
1150    ee = evas_object_data_get(obj, "Ecore_Evas");
1151    if (!ee) return NULL;
1152 
1153    return ecore_evas_get(ee);
1154 }
1155 
1156 EAPI Ecore_Evas *
ecore_evas_object_ecore_evas_get(Evas_Object * obj)1157 ecore_evas_object_ecore_evas_get(Evas_Object *obj)
1158 {
1159    return evas_object_data_get(obj, "Ecore_Evas");
1160 }
1161 
1162 #define IFC(_ee, _fn)  if (_ee->engine.func->_fn) {_ee->engine.func->_fn
1163 #define IFE            return;}
1164 
1165 EAPI void
ecore_evas_callback_resize_set(Ecore_Evas * ee,Ecore_Evas_Event_Cb func)1166 ecore_evas_callback_resize_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
1167 {
1168    ECORE_EVAS_CHECK(ee);
1169    IFC(ee, fn_callback_resize_set) (ee, func);
1170    IFE;
1171    ee->func.fn_resize = func;
1172 }
1173 
1174 EAPI void
ecore_evas_callback_move_set(Ecore_Evas * ee,Ecore_Evas_Event_Cb func)1175 ecore_evas_callback_move_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
1176 {
1177    ECORE_EVAS_CHECK(ee);
1178    IFC(ee, fn_callback_move_set) (ee, func);
1179    IFE;
1180    ee->func.fn_move = func;
1181 }
1182 
1183 EAPI void
ecore_evas_callback_show_set(Ecore_Evas * ee,Ecore_Evas_Event_Cb func)1184 ecore_evas_callback_show_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
1185 {
1186    ECORE_EVAS_CHECK(ee);
1187    IFC(ee, fn_callback_show_set) (ee, func);
1188    IFE;
1189    ee->func.fn_show = func;
1190 }
1191 
1192 EAPI void
ecore_evas_callback_hide_set(Ecore_Evas * ee,Ecore_Evas_Event_Cb func)1193 ecore_evas_callback_hide_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
1194 {
1195    ECORE_EVAS_CHECK(ee);
1196    IFC(ee, fn_callback_hide_set) (ee, func);
1197    IFE;
1198    ee->func.fn_hide = func;
1199 }
1200 
1201 EAPI void
ecore_evas_callback_delete_request_set(Ecore_Evas * ee,Ecore_Evas_Event_Cb func)1202 ecore_evas_callback_delete_request_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
1203 {
1204    ECORE_EVAS_CHECK(ee);
1205    IFC(ee, fn_callback_delete_request_set) (ee, func);
1206    IFE;
1207    ee->func.fn_delete_request = func;
1208 }
1209 
1210 EAPI void
ecore_evas_callback_destroy_set(Ecore_Evas * ee,Ecore_Evas_Event_Cb func)1211 ecore_evas_callback_destroy_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
1212 {
1213    ECORE_EVAS_CHECK(ee);
1214    IFC(ee, fn_callback_destroy_set) (ee, func);
1215    IFE;
1216    ee->func.fn_destroy = func;
1217 }
1218 
1219 EAPI void
ecore_evas_callback_focus_in_set(Ecore_Evas * ee,Ecore_Evas_Event_Cb func)1220 ecore_evas_callback_focus_in_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
1221 {
1222    ECORE_EVAS_CHECK(ee);
1223    IFC(ee, fn_callback_focus_in_set) (ee, func);
1224    IFE;
1225    ee->func.fn_focus_in = func;
1226 }
1227 
1228 EAPI void
ecore_evas_callback_focus_device_in_set(Ecore_Evas * ee,Ecore_Evas_Focus_Device_Event_Cb func)1229 ecore_evas_callback_focus_device_in_set(Ecore_Evas *ee,
1230                                         Ecore_Evas_Focus_Device_Event_Cb func)
1231 {
1232    ECORE_EVAS_CHECK(ee);
1233    IFC(ee, fn_callback_focus_device_in_set) (ee, func);
1234    IFE;
1235    ee->func.fn_focus_device_in = func;
1236 }
1237 
1238 EAPI void
ecore_evas_callback_focus_out_set(Ecore_Evas * ee,Ecore_Evas_Event_Cb func)1239 ecore_evas_callback_focus_out_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
1240 {
1241    ECORE_EVAS_CHECK(ee);
1242    IFC(ee, fn_callback_focus_out_set) (ee, func);
1243    IFE;
1244    ee->func.fn_focus_out = func;
1245 }
1246 
1247 EAPI void
ecore_evas_callback_focus_device_out_set(Ecore_Evas * ee,Ecore_Evas_Focus_Device_Event_Cb func)1248 ecore_evas_callback_focus_device_out_set(Ecore_Evas *ee,
1249                                          Ecore_Evas_Focus_Device_Event_Cb func)
1250 {
1251    ECORE_EVAS_CHECK(ee);
1252    IFC(ee, fn_callback_focus_device_out_set) (ee, func);
1253    IFE;
1254    ee->func.fn_focus_device_out = func;
1255 }
1256 
1257 EAPI void
ecore_evas_callback_sticky_set(Ecore_Evas * ee,Ecore_Evas_Event_Cb func)1258 ecore_evas_callback_sticky_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
1259 {
1260    ECORE_EVAS_CHECK(ee);
1261    IFC(ee, fn_callback_sticky_set) (ee, func);
1262    IFE;
1263    ee->func.fn_sticky = func;
1264 }
1265 
1266 EAPI void
ecore_evas_callback_unsticky_set(Ecore_Evas * ee,Ecore_Evas_Event_Cb func)1267 ecore_evas_callback_unsticky_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
1268 {
1269    ECORE_EVAS_CHECK(ee);
1270    IFC(ee, fn_callback_unsticky_set) (ee, func);
1271    IFE;
1272    ee->func.fn_unsticky = func;
1273 }
1274 
1275 EAPI void
ecore_evas_callback_mouse_in_set(Ecore_Evas * ee,Ecore_Evas_Event_Cb func)1276 ecore_evas_callback_mouse_in_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
1277 {
1278    ECORE_EVAS_CHECK(ee);
1279    IFC(ee, fn_callback_mouse_in_set) (ee, func);
1280    IFE;
1281    ee->func.fn_mouse_in = func;
1282 }
1283 
1284 EAPI void
ecore_evas_callback_mouse_out_set(Ecore_Evas * ee,Ecore_Evas_Event_Cb func)1285 ecore_evas_callback_mouse_out_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
1286 {
1287    ECORE_EVAS_CHECK(ee);
1288    IFC(ee, fn_callback_mouse_out_set) (ee, func);
1289    IFE;
1290    ee->func.fn_mouse_out = func;
1291 }
1292 
1293 EAPI void
ecore_evas_callback_pre_render_set(Ecore_Evas * ee,Ecore_Evas_Event_Cb func)1294 ecore_evas_callback_pre_render_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
1295 {
1296    ECORE_EVAS_CHECK(ee);
1297    IFC(ee, fn_callback_pre_render_set) (ee, func);
1298    IFE;
1299    ee->func.fn_pre_render = func;
1300 }
1301 
1302 EAPI void
ecore_evas_callback_post_render_set(Ecore_Evas * ee,Ecore_Evas_Event_Cb func)1303 ecore_evas_callback_post_render_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
1304 {
1305    ECORE_EVAS_CHECK(ee);
1306    IFC(ee, fn_callback_post_render_set) (ee, func);
1307    IFE;
1308    ee->func.fn_post_render = func;
1309 }
1310 
1311 EAPI void
ecore_evas_callback_pre_free_set(Ecore_Evas * ee,Ecore_Evas_Event_Cb func)1312 ecore_evas_callback_pre_free_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
1313 {
1314    ECORE_EVAS_CHECK(ee);
1315    ee->func.fn_pre_free = func;
1316 }
1317 
1318 EAPI void
ecore_evas_callback_state_change_set(Ecore_Evas * ee,Ecore_Evas_Event_Cb func)1319 ecore_evas_callback_state_change_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
1320 {
1321    ECORE_EVAS_CHECK(ee);
1322    ee->func.fn_state_change = func;
1323 }
1324 
1325 EAPI Evas *
ecore_evas_get(const Ecore_Evas * ee)1326 ecore_evas_get(const Ecore_Evas *ee)
1327 {
1328    ECORE_EVAS_CHECK(ee, NULL);
1329    return ee->evas;
1330 }
1331 
1332 EAPI void
ecore_evas_move(Ecore_Evas * ee,int x,int y)1333 ecore_evas_move(Ecore_Evas *ee, int x, int y)
1334 {
1335    ECORE_EVAS_CHECK(ee);
1336    if (ee->prop.fullscreen) return;
1337    IFC(ee, fn_move) (ee, x, y);
1338    IFE;
1339 }
1340 
1341 EAPI void
ecore_evas_managed_move(Ecore_Evas * ee,int x,int y)1342 ecore_evas_managed_move(Ecore_Evas *ee, int x, int y)
1343 {
1344    ECORE_EVAS_CHECK(ee);
1345    IFC(ee, fn_managed_move) (ee, x, y);
1346    IFE;
1347 }
1348 
1349 EAPI void
ecore_evas_resize(Ecore_Evas * ee,int w,int h)1350 ecore_evas_resize(Ecore_Evas *ee, int w, int h)
1351 {
1352    ECORE_EVAS_CHECK(ee);
1353    if (ee->prop.fullscreen) return;
1354    if (w < 1) w = 1;
1355    if (h < 1) h = 1;
1356    if (ECORE_EVAS_PORTRAIT(ee))
1357      {
1358         IFC(ee, fn_resize) (ee, w, h);
1359         IFE;
1360      }
1361    else
1362      {
1363         IFC(ee, fn_resize) (ee, h, w);
1364         IFE;
1365      }
1366 }
1367 
1368 EAPI void
ecore_evas_move_resize(Ecore_Evas * ee,int x,int y,int w,int h)1369 ecore_evas_move_resize(Ecore_Evas *ee, int x, int y, int w, int h)
1370 {
1371    ECORE_EVAS_CHECK(ee);
1372    if (ee->prop.fullscreen) return;
1373    if (w < 1) w = 1;
1374    if (h < 1) h = 1;
1375    if (ECORE_EVAS_PORTRAIT(ee))
1376      {
1377         IFC(ee, fn_move_resize) (ee, x, y, w, h);
1378         IFE;
1379      }
1380    else
1381      {
1382         IFC(ee, fn_move_resize) (ee, x, y, h, w);
1383         IFE;
1384      }
1385 }
1386 
1387 EAPI void
ecore_evas_geometry_get(const Ecore_Evas * ee,int * x,int * y,int * w,int * h)1388 ecore_evas_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h)
1389 {
1390    ECORE_EVAS_CHECK(ee);
1391    if (ECORE_EVAS_PORTRAIT(ee))
1392      {
1393         if (x) *x = ee->x;
1394         if (y) *y = ee->y;
1395         if (w) *w = ee->w;
1396         if (h) *h = ee->h;
1397      }
1398    else
1399      {
1400         if (x) *x = ee->x;
1401         if (y) *y = ee->y;
1402         if (w) *w = ee->h;
1403         if (h) *h = ee->w;
1404      }
1405 }
1406 
1407 EAPI void
ecore_evas_request_geometry_get(const Ecore_Evas * ee,int * x,int * y,int * w,int * h)1408 ecore_evas_request_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h)
1409 {
1410    ECORE_EVAS_CHECK(ee);
1411    if (ECORE_EVAS_PORTRAIT(ee))
1412      {
1413         if (x) *x = ee->req.x;
1414         if (y) *y = ee->req.y;
1415         if (w) *w = ee->req.w;
1416         if (h) *h = ee->req.h;
1417      }
1418    else
1419      {
1420         if (x) *x = ee->req.x;
1421         if (y) *y = ee->req.y;
1422         if (w) *w = ee->req.h;
1423         if (h) *h = ee->req.w;
1424      }
1425 }
1426 
1427 EAPI void
ecore_evas_rotation_set(Ecore_Evas * ee,int rot)1428 ecore_evas_rotation_set(Ecore_Evas *ee, int rot)
1429 {
1430    ECORE_EVAS_CHECK(ee);
1431    rot = rot % 360;
1432    while (rot < 0) rot += 360;
1433    IFC(ee, fn_rotation_set) (ee, rot, 0);
1434    /* make sure everything gets redrawn */
1435    evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1436    evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
1437    IFE;
1438 }
1439 
1440 EAPI void
ecore_evas_rotation_with_resize_set(Ecore_Evas * ee,int rot)1441 ecore_evas_rotation_with_resize_set(Ecore_Evas *ee, int rot)
1442 {
1443    ECORE_EVAS_CHECK(ee);
1444    rot = rot % 360;
1445    while (rot < 0) rot += 360;
1446    IFC(ee, fn_rotation_set) (ee, rot, 1);
1447    /* make sure everything gets redrawn */
1448    evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1449    evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
1450    IFE;
1451 }
1452 
1453 EAPI int
ecore_evas_rotation_get(const Ecore_Evas * ee)1454 ecore_evas_rotation_get(const Ecore_Evas *ee)
1455 {
1456    ECORE_EVAS_CHECK(ee, 0);
1457    return ee->rotation;
1458 }
1459 
1460 EAPI void
ecore_evas_shaped_set(Ecore_Evas * ee,Eina_Bool shaped)1461 ecore_evas_shaped_set(Ecore_Evas *ee, Eina_Bool shaped)
1462 {
1463    ECORE_EVAS_CHECK(ee);
1464    IFC(ee, fn_shaped_set) (ee, shaped);
1465    IFE;
1466 }
1467 
1468 EAPI Eina_Bool
ecore_evas_shaped_get(const Ecore_Evas * ee)1469 ecore_evas_shaped_get(const Ecore_Evas *ee)
1470 {
1471    ECORE_EVAS_CHECK(ee, EINA_FALSE);
1472    return ee->shaped ? EINA_TRUE : EINA_FALSE;
1473 }
1474 
1475 EAPI void
ecore_evas_alpha_set(Ecore_Evas * ee,Eina_Bool alpha)1476 ecore_evas_alpha_set(Ecore_Evas *ee, Eina_Bool alpha)
1477 {
1478    ECORE_EVAS_CHECK(ee);
1479    IFC(ee, fn_alpha_set) (ee, alpha);
1480    IFE;
1481 }
1482 
1483 EAPI Eina_Bool
ecore_evas_alpha_get(const Ecore_Evas * ee)1484 ecore_evas_alpha_get(const Ecore_Evas *ee)
1485 {
1486    ECORE_EVAS_CHECK(ee, EINA_FALSE);
1487    return ee->alpha ? EINA_TRUE : EINA_FALSE;
1488 }
1489 
1490 EAPI void
ecore_evas_transparent_set(Ecore_Evas * ee,Eina_Bool transparent)1491 ecore_evas_transparent_set(Ecore_Evas *ee, Eina_Bool transparent)
1492 {
1493    ECORE_EVAS_CHECK(ee);
1494    IFC(ee, fn_transparent_set) (ee, transparent);
1495    IFE;
1496 }
1497 
1498 EAPI Eina_Bool
ecore_evas_transparent_get(const Ecore_Evas * ee)1499 ecore_evas_transparent_get(const Ecore_Evas *ee)
1500 {
1501    ECORE_EVAS_CHECK(ee, EINA_FALSE);
1502    return ee->transparent ? EINA_TRUE : 0;
1503 }
1504 
1505 EAPI void
ecore_evas_show(Ecore_Evas * ee)1506 ecore_evas_show(Ecore_Evas *ee)
1507 {
1508    ECORE_EVAS_CHECK(ee);
1509    IFC(ee, fn_show) (ee);
1510    IFE;
1511 }
1512 
1513 EAPI void
ecore_evas_hide(Ecore_Evas * ee)1514 ecore_evas_hide(Ecore_Evas *ee)
1515 {
1516    ECORE_EVAS_CHECK(ee);
1517    IFC(ee, fn_hide) (ee);
1518    IFE;
1519 }
1520 
1521  EAPI int
ecore_evas_visibility_get(const Ecore_Evas * ee)1522 ecore_evas_visibility_get(const Ecore_Evas *ee)
1523 {
1524    ECORE_EVAS_CHECK(ee, 0);
1525    return ee->visible ? 1:0;
1526 }
1527 
1528 EAPI void
ecore_evas_raise(Ecore_Evas * ee)1529 ecore_evas_raise(Ecore_Evas *ee)
1530 {
1531    ECORE_EVAS_CHECK(ee);
1532    IFC(ee, fn_raise) (ee);
1533    IFE;
1534 }
1535 
1536 EAPI void
ecore_evas_lower(Ecore_Evas * ee)1537 ecore_evas_lower(Ecore_Evas *ee)
1538 {
1539    ECORE_EVAS_CHECK(ee);
1540    IFC(ee, fn_lower) (ee);
1541    IFE;
1542 }
1543 
1544 EAPI void
ecore_evas_activate(Ecore_Evas * ee)1545 ecore_evas_activate(Ecore_Evas *ee)
1546 {
1547    ECORE_EVAS_CHECK(ee);
1548    IFC(ee, fn_activate) (ee);
1549    IFE;
1550 }
1551 
1552 EAPI void
ecore_evas_title_set(Ecore_Evas * ee,const char * t)1553 ecore_evas_title_set(Ecore_Evas *ee, const char *t)
1554 {
1555    ECORE_EVAS_CHECK(ee);
1556    IFC(ee, fn_title_set) (ee, t);
1557    IFE;
1558 }
1559 
1560 EAPI const char *
ecore_evas_title_get(const Ecore_Evas * ee)1561 ecore_evas_title_get(const Ecore_Evas *ee)
1562 {
1563    ECORE_EVAS_CHECK(ee, NULL);
1564    return ee->prop.title;
1565 }
1566 
1567 EAPI void
ecore_evas_name_class_set(Ecore_Evas * ee,const char * n,const char * c)1568 ecore_evas_name_class_set(Ecore_Evas *ee, const char *n, const char *c)
1569 {
1570    ECORE_EVAS_CHECK(ee);
1571    IFC(ee, fn_name_class_set) (ee, n, c);
1572    IFE;
1573 }
1574 
1575 EAPI void
ecore_evas_name_class_get(const Ecore_Evas * ee,const char ** n,const char ** c)1576 ecore_evas_name_class_get(const Ecore_Evas *ee, const char **n, const char **c)
1577 {
1578    if (n) *n = NULL;
1579    if (c) *c = NULL;
1580    ECORE_EVAS_CHECK(ee);
1581    if (n) *n = ee->prop.name;
1582    if (c) *c = ee->prop.clas;
1583 }
1584 
1585 EAPI void
ecore_evas_size_min_set(Ecore_Evas * ee,int w,int h)1586 ecore_evas_size_min_set(Ecore_Evas *ee, int w, int h)
1587 {
1588    ECORE_EVAS_CHECK(ee);
1589    if (w < 0) w = 0;
1590    if (h < 0) h = 0;
1591    if (ECORE_EVAS_PORTRAIT(ee))
1592      {
1593         IFC(ee, fn_size_min_set) (ee, w, h);
1594         IFE;
1595      }
1596    else
1597      {
1598         IFC(ee, fn_size_min_set) (ee, h, w);
1599         IFE;
1600      }
1601 }
1602 
1603 EAPI void
ecore_evas_size_min_get(const Ecore_Evas * ee,int * w,int * h)1604 ecore_evas_size_min_get(const Ecore_Evas *ee, int *w, int *h)
1605 {
1606    if (w) *w = 0;
1607    if (h) *h = 0;
1608    ECORE_EVAS_CHECK(ee);
1609    if (ECORE_EVAS_PORTRAIT(ee))
1610      {
1611         if (w) *w = ee->prop.min.w;
1612         if (h) *h = ee->prop.min.h;
1613      }
1614    else
1615      {
1616         if (w) *w = ee->prop.min.h;
1617         if (h) *h = ee->prop.min.w;
1618      }
1619 }
1620 
1621 EAPI void
ecore_evas_size_max_set(Ecore_Evas * ee,int w,int h)1622 ecore_evas_size_max_set(Ecore_Evas *ee, int w, int h)
1623 {
1624    ECORE_EVAS_CHECK(ee);
1625    if (w < 0) w = 0;
1626    if (h < 0) h = 0;
1627    if (ECORE_EVAS_PORTRAIT(ee))
1628      {
1629         IFC(ee, fn_size_max_set) (ee, w, h);
1630         IFE;
1631      }
1632    else
1633      {
1634         IFC(ee, fn_size_max_set) (ee, h, w);
1635         IFE;
1636      }
1637 }
1638 
1639 EAPI void
ecore_evas_size_max_get(const Ecore_Evas * ee,int * w,int * h)1640 ecore_evas_size_max_get(const Ecore_Evas *ee, int *w, int *h)
1641 {
1642    if (w) *w = 0;
1643    if (h) *h = 0;
1644    ECORE_EVAS_CHECK(ee);
1645    if (ECORE_EVAS_PORTRAIT(ee))
1646      {
1647         if (w) *w = ee->prop.max.w;
1648         if (h) *h = ee->prop.max.h;
1649      }
1650    else
1651      {
1652         if (w) *w = ee->prop.max.h;
1653         if (h) *h = ee->prop.max.w;
1654      }
1655 }
1656 
1657 EAPI void
ecore_evas_size_base_set(Ecore_Evas * ee,int w,int h)1658 ecore_evas_size_base_set(Ecore_Evas *ee, int w, int h)
1659 {
1660    ECORE_EVAS_CHECK(ee);
1661    if (w < 0) w = 0;
1662    if (h < 0) h = 0;
1663    if (ECORE_EVAS_PORTRAIT(ee))
1664      {
1665         IFC(ee, fn_size_base_set) (ee, w, h);
1666         IFE;
1667      }
1668    else
1669      {
1670         IFC(ee, fn_size_base_set) (ee, h, w);
1671         IFE;
1672      }
1673 }
1674 
1675 EAPI void
ecore_evas_size_base_get(const Ecore_Evas * ee,int * w,int * h)1676 ecore_evas_size_base_get(const Ecore_Evas *ee, int *w, int *h)
1677 {
1678    ECORE_EVAS_CHECK(ee);
1679    if (ECORE_EVAS_PORTRAIT(ee))
1680      {
1681         if (w) *w = ee->prop.base.w;
1682         if (h) *h = ee->prop.base.h;
1683      }
1684    else
1685      {
1686         if (w) *w = ee->prop.base.h;
1687         if (h) *h = ee->prop.base.w;
1688      }
1689 }
1690 
1691 EAPI void
ecore_evas_size_step_set(Ecore_Evas * ee,int w,int h)1692 ecore_evas_size_step_set(Ecore_Evas *ee, int w, int h)
1693 {
1694    ECORE_EVAS_CHECK(ee);
1695    if (w < 0) w = 0;
1696    if (h < 0) h = 0;
1697    if (ECORE_EVAS_PORTRAIT(ee))
1698      {
1699         IFC(ee, fn_size_step_set) (ee, w, h);
1700         IFE;
1701      }
1702    else
1703      {
1704         IFC(ee, fn_size_step_set) (ee, h, w);
1705         IFE;
1706      }
1707 }
1708 
1709 EAPI void
ecore_evas_size_step_get(const Ecore_Evas * ee,int * w,int * h)1710 ecore_evas_size_step_get(const Ecore_Evas *ee, int *w, int *h)
1711 {
1712    ECORE_EVAS_CHECK(ee);
1713    if (ECORE_EVAS_PORTRAIT(ee))
1714      {
1715         if (w) *w = ee->prop.step.w;
1716         if (h) *h = ee->prop.step.h;
1717      }
1718    else
1719      {
1720         if (w) *w = ee->prop.step.h;
1721         if (h) *h = ee->prop.step.w;
1722      }
1723 }
1724 
1725 EAPI Evas_Object *
_ecore_evas_default_cursor_image_get(Ecore_Evas * ee)1726 _ecore_evas_default_cursor_image_get(Ecore_Evas *ee)
1727 {
1728    Efl_Input_Device *pointer;
1729    Ecore_Evas_Cursor *cursor;
1730 
1731    pointer = evas_default_device_get(ee->evas, EVAS_DEVICE_CLASS_SEAT);
1732    cursor = eina_hash_find(ee->prop.cursors, &pointer);
1733    EINA_SAFETY_ON_NULL_RETURN_VAL(cursor, NULL);
1734    return cursor->object;
1735 }
1736 
1737 EAPI void
_ecore_evas_default_cursor_hide(Ecore_Evas * ee)1738 _ecore_evas_default_cursor_hide(Ecore_Evas *ee)
1739 {
1740    Efl_Input_Device *pointer;
1741    Ecore_Evas_Cursor *cursor;
1742 
1743    pointer = evas_default_device_get(ee->evas, EVAS_DEVICE_CLASS_SEAT);
1744    cursor = eina_hash_find(ee->prop.cursors, &pointer);
1745    EINA_SAFETY_ON_NULL_RETURN(cursor);
1746    if (cursor->object)
1747      evas_object_hide(cursor->object);
1748 }
1749 
1750 static void
_ecore_evas_object_cursor_device_set(Ecore_Evas * ee,Efl_Input_Device * pointer,Evas_Object * obj,int layer,int hot_x,int hot_y)1751 _ecore_evas_object_cursor_device_set(Ecore_Evas *ee, Efl_Input_Device *pointer,
1752                                      Evas_Object *obj, int layer,
1753                                      int hot_x, int hot_y)
1754 {
1755    Ecore_Evas_Cursor *cursor;
1756    int x, y;
1757    Evas_Object *old;
1758    Efl_Input_Device *dpointer;
1759 
1760    ECORE_EVAS_CHECK(ee);
1761 
1762    dpointer = evas_default_device_get(ee->evas, EVAS_DEVICE_CLASS_SEAT);
1763    if (pointer)
1764      {
1765         if (efl_input_device_type_get(pointer) != EFL_INPUT_DEVICE_TYPE_SEAT)
1766           pointer = efl_input_device_seat_get(pointer);
1767         if (efl_input_device_type_get(pointer) != EFL_INPUT_DEVICE_TYPE_SEAT)
1768           {
1769              ERR("Could not find seat");
1770              return;
1771           }
1772      }
1773    else
1774      {
1775         pointer = dpointer;
1776         if (!pointer)
1777           {
1778              ee->prop.cursor_cache.object = obj;
1779              ee->prop.cursor_cache.layer = layer;
1780              ee->prop.cursor_cache.hot.x = hot_x;
1781              ee->prop.cursor_cache.hot.y = hot_y;
1782              return;
1783           }
1784      }
1785    if (pointer == dpointer)
1786      memset(&ee->prop.cursor_cache, 0, sizeof(Ecore_Evas_Cursor));
1787 
1788    if (obj && ee->engine.func->fn_object_cursor_set)
1789      ee->engine.func->fn_object_cursor_set(ee, obj, layer, hot_x, hot_y);
1790    else if (!obj && ee->engine.func->fn_object_cursor_unset)
1791      ee->engine.func->fn_object_cursor_unset(ee);
1792 
1793    cursor = eina_hash_find(ee->prop.cursors, &pointer);
1794    EINA_SAFETY_ON_NULL_RETURN(cursor);
1795    old = cursor->object;
1796    if (!obj)
1797      {
1798         cursor->object = NULL;
1799         cursor->layer = 0;
1800         cursor->hot.x = 0;
1801         cursor->hot.y = 0;
1802         goto end;
1803      }
1804 
1805    cursor->object = obj;
1806    cursor->layer = layer;
1807    cursor->hot.x = hot_x;
1808    cursor->hot.y = hot_y;
1809 
1810    evas_pointer_output_xy_get(ee->evas, &x, &y);
1811 
1812    if (obj != old)
1813      {
1814         evas_object_layer_set(cursor->object, cursor->layer);
1815         evas_object_pass_events_set(cursor->object, 1);
1816         if (evas_pointer_inside_get(ee->evas))
1817           evas_object_show(cursor->object);
1818         evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
1819                                        _ecore_evas_object_cursor_del, cursor);
1820      }
1821 
1822    evas_object_move(cursor->object, x - cursor->hot.x,
1823                     y - cursor->hot.y);
1824 
1825 end:
1826    if ((old) && (obj != old))
1827      {
1828         evas_object_event_callback_del_full
1829           (old, EVAS_CALLBACK_DEL, _ecore_evas_object_cursor_del, cursor);
1830         evas_object_del(old);
1831      }
1832 }
1833 
1834 EAPI void
ecore_evas_cursor_set(Ecore_Evas * ee,const char * file,int layer,int hot_x,int hot_y)1835 ecore_evas_cursor_set(Ecore_Evas *ee, const char *file,
1836                       int layer, int hot_x, int hot_y)
1837 {
1838    Evas_Object *obj = NULL;
1839 
1840    ECORE_EVAS_CHECK(ee);
1841 
1842    if (file)
1843      {
1844         int x, y;
1845 
1846         obj = evas_object_image_add(ee->evas);
1847         evas_object_image_file_set(obj, file, NULL);
1848         evas_object_image_size_get(obj, &x, &y);
1849         evas_object_resize(obj, x, y);
1850         evas_object_image_fill_set(obj, 0, 0, x, y);
1851      }
1852 
1853    _ecore_evas_object_cursor_device_set(ee, NULL, obj, layer, hot_x, hot_y);
1854 }
1855 
1856 EAPI void
ecore_evas_object_cursor_set(Ecore_Evas * ee,Evas_Object * obj,int layer,int hot_x,int hot_y)1857 ecore_evas_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj,
1858                              int layer, int hot_x, int hot_y)
1859 {
1860    _ecore_evas_object_cursor_device_set(ee, NULL, obj, layer, hot_x, hot_y);
1861 }
1862 
1863 EAPI void
ecore_evas_object_cursor_device_set(Ecore_Evas * ee,Efl_Input_Device * pointer,Evas_Object * obj,int layer,int hot_x,int hot_y)1864 ecore_evas_object_cursor_device_set(Ecore_Evas *ee, Efl_Input_Device *pointer,
1865                                     Evas_Object *obj, int layer,
1866                                     int hot_x, int hot_y)
1867 {
1868    _ecore_evas_object_cursor_device_set(ee, pointer, obj, layer, hot_x, hot_y);
1869 }
1870 
1871 EAPI Eina_Bool
ecore_evas_cursor_device_get(const Ecore_Evas * ee,Efl_Input_Device * pointer,Evas_Object ** obj,int * layer,int * hot_x,int * hot_y)1872 ecore_evas_cursor_device_get(const Ecore_Evas *ee, Efl_Input_Device *pointer,
1873                              Evas_Object **obj, int *layer,
1874                              int *hot_x, int *hot_y)
1875 {
1876    Ecore_Evas_Cursor *cursor;
1877 
1878    ECORE_EVAS_CHECK_GOTO(ee, err);
1879 
1880    if (pointer)
1881      {
1882         if (efl_input_device_type_get(pointer) != EFL_INPUT_DEVICE_TYPE_SEAT)
1883           pointer = efl_input_device_seat_get(pointer);
1884         if (efl_input_device_type_get(pointer) != EFL_INPUT_DEVICE_TYPE_SEAT)
1885           {
1886              ERR("Could not find seat");
1887              return EINA_FALSE;
1888           }
1889      }
1890    else
1891      pointer = evas_default_device_get(ee->evas, EVAS_DEVICE_CLASS_SEAT);
1892    if (pointer)
1893      {
1894         cursor = eina_hash_find(ee->prop.cursors, &pointer);
1895         if (cursor)
1896           {
1897              if (obj) *obj = cursor->object;
1898              if (layer) *layer = cursor->layer;
1899              if (hot_x) *hot_x = cursor->hot.x;
1900              if (hot_y) *hot_y = cursor->hot.y;
1901              return EINA_TRUE;
1902           }
1903      }
1904 
1905  err:
1906    if (obj) *obj = NULL;
1907    if (layer) *layer = 0;
1908    if (hot_x) *hot_x = 0;
1909    if (hot_y) *hot_y = 0;
1910    return EINA_FALSE;
1911 }
1912 
1913 EAPI void
ecore_evas_cursor_get(const Ecore_Evas * ee,Evas_Object ** obj,int * layer,int * hot_x,int * hot_y)1914 ecore_evas_cursor_get(const Ecore_Evas *ee, Evas_Object **obj, int *layer, int *hot_x, int *hot_y)
1915 {
1916    ecore_evas_cursor_device_get(ee, NULL, obj, layer, hot_x, hot_y);
1917 }
1918 
1919 EAPI Evas_Object *
ecore_evas_cursor_device_unset(Ecore_Evas * ee,Efl_Input_Device * pointer)1920 ecore_evas_cursor_device_unset(Ecore_Evas *ee, Efl_Input_Device *pointer)
1921 {
1922    Ecore_Evas_Cursor *cursor = NULL;
1923    Evas_Object *obj;
1924 
1925    ECORE_EVAS_CHECK(ee, NULL);
1926 
1927    if (pointer)
1928      {
1929         if (efl_input_device_type_get(pointer) != EFL_INPUT_DEVICE_TYPE_SEAT)
1930           pointer = efl_input_device_seat_get(pointer);
1931         if (efl_input_device_type_get(pointer) != EFL_INPUT_DEVICE_TYPE_SEAT)
1932           {
1933              ERR("Could not find seat");
1934              return NULL;
1935           }
1936      }
1937    else
1938      pointer = evas_default_device_get(ee->evas, EVAS_DEVICE_CLASS_SEAT);
1939    if (pointer)
1940      cursor = eina_hash_find(ee->prop.cursors, &pointer);
1941    if (!cursor) return NULL;
1942    obj = cursor->object;
1943    if (ee->engine.func->fn_object_cursor_unset)
1944      ee->engine.func->fn_object_cursor_unset(ee);
1945    evas_object_hide(obj);
1946    cursor->object = NULL;
1947    evas_object_event_callback_del_full(obj, EVAS_CALLBACK_DEL,
1948                                        _ecore_evas_object_cursor_del,
1949                                        cursor);
1950    return obj;
1951 }
1952 
1953 EAPI Evas_Object *
ecore_evas_cursor_unset(Ecore_Evas * ee)1954 ecore_evas_cursor_unset(Ecore_Evas *ee)
1955 {
1956    return ecore_evas_cursor_device_unset(ee, NULL);
1957 }
1958 
1959 EAPI void
ecore_evas_layer_set(Ecore_Evas * ee,int layer)1960 ecore_evas_layer_set(Ecore_Evas *ee, int layer)
1961 {
1962    ECORE_EVAS_CHECK(ee);
1963    IFC(ee, fn_layer_set) (ee, layer);
1964    IFE;
1965    ee->prop.layer = layer;
1966 }
1967 
1968 EAPI int
ecore_evas_layer_get(const Ecore_Evas * ee)1969 ecore_evas_layer_get(const Ecore_Evas *ee)
1970 {
1971    ECORE_EVAS_CHECK(ee, 0);
1972    return ee->prop.layer;
1973 }
1974 
1975 EAPI Eina_Bool
ecore_evas_focus_device_get(const Ecore_Evas * ee,Efl_Input_Device * seat)1976 ecore_evas_focus_device_get(const Ecore_Evas *ee, Efl_Input_Device *seat)
1977 {
1978    ECORE_EVAS_CHECK(ee, EINA_FALSE);
1979    if (!seat)
1980      seat = evas_default_device_get(ee->evas, EVAS_DEVICE_CLASS_SEAT);
1981    return eina_list_data_find(ee->prop.focused_by, seat) ? EINA_TRUE : EINA_FALSE;
1982 }
1983 
1984 EAPI void
_ecore_evas_focus_device_set(Ecore_Evas * ee,Efl_Input_Device * seat,Eina_Bool on)1985 _ecore_evas_focus_device_set(Ecore_Evas *ee, Efl_Input_Device *seat,
1986                              Eina_Bool on)
1987 {
1988    Eina_Bool present;
1989 
1990    if (!seat)
1991      seat = evas_default_device_get(ee->evas, EVAS_DEVICE_CLASS_SEAT);
1992    if ((!on) && (!seat)) return;
1993 
1994    if (seat && (efl_input_device_type_get(seat) != EFL_INPUT_DEVICE_TYPE_SEAT))
1995      {
1996         ERR("The Input device must be an seat");
1997         return;
1998      }
1999    ee->prop.focused = ee->prop.focused_by || on;
2000    if (!seat) return;
2001 
2002    present = ecore_evas_focus_device_get(ee, seat);
2003    if (on)
2004      {
2005         if (present) return;
2006         ee->prop.focused_by = eina_list_append(ee->prop.focused_by, seat);
2007         efl_event_callback_add(seat, EFL_EVENT_DEL,
2008                                _ecore_evas_device_del_cb, ee);
2009         evas_canvas_seat_focus_in(ee->evas, seat);
2010         if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee);
2011         if (ee->func.fn_focus_device_in) ee->func.fn_focus_device_in(ee, seat);
2012      }
2013    else
2014      {
2015         if (!present) return;
2016         ee->prop.focused_by = eina_list_remove(ee->prop.focused_by, seat);
2017         efl_event_callback_del(seat, EFL_EVENT_DEL,
2018                                _ecore_evas_device_del_cb, ee);
2019         _ecore_evas_focus_out_dispatch(ee, seat);
2020      }
2021 }
2022 
2023 EAPI void
ecore_evas_focus_device_set(Ecore_Evas * ee,Efl_Input_Device * seat,Eina_Bool on)2024 ecore_evas_focus_device_set(Ecore_Evas *ee, Efl_Input_Device *seat,
2025                             Eina_Bool on)
2026 {
2027    ECORE_EVAS_CHECK(ee);
2028    IFC(ee, fn_focus_device_set) (ee, seat, on);
2029    IFE;
2030    _ecore_evas_focus_device_set(ee, seat, on);
2031 }
2032 
2033 EAPI void
ecore_evas_focus_set(Ecore_Evas * ee,Eina_Bool on)2034 ecore_evas_focus_set(Ecore_Evas *ee, Eina_Bool on)
2035 {
2036    ECORE_EVAS_CHECK(ee);
2037    IFC(ee, fn_focus_set) (ee, on);
2038    IFE;
2039    ecore_evas_focus_device_set(ee, NULL, on);
2040 }
2041 
2042 EAPI Eina_Bool
ecore_evas_focus_get(const Ecore_Evas * ee)2043 ecore_evas_focus_get(const Ecore_Evas *ee)
2044 {
2045    return ecore_evas_focus_device_get(ee, NULL);
2046 }
2047 
2048 EAPI void
ecore_evas_iconified_set(Ecore_Evas * ee,Eina_Bool on)2049 ecore_evas_iconified_set(Ecore_Evas *ee, Eina_Bool on)
2050 {
2051    ECORE_EVAS_CHECK(ee);
2052    IFC(ee, fn_iconified_set) (ee, on);
2053    IFE;
2054    ee->prop.iconified = !!on;
2055 }
2056 
2057 EAPI Eina_Bool
ecore_evas_iconified_get(const Ecore_Evas * ee)2058 ecore_evas_iconified_get(const Ecore_Evas *ee)
2059 {
2060    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2061    return ee->prop.iconified ? EINA_TRUE : EINA_FALSE;
2062 }
2063 
2064 EAPI void
ecore_evas_borderless_set(Ecore_Evas * ee,Eina_Bool on)2065 ecore_evas_borderless_set(Ecore_Evas *ee, Eina_Bool on)
2066 {
2067    ECORE_EVAS_CHECK(ee);
2068    IFC(ee, fn_borderless_set) (ee, on);
2069    IFE;
2070    ee->prop.borderless = !!on;
2071 }
2072 
2073 EAPI Eina_Bool
ecore_evas_borderless_get(const Ecore_Evas * ee)2074 ecore_evas_borderless_get(const Ecore_Evas *ee)
2075 {
2076    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2077    return ee->prop.borderless ? EINA_TRUE : EINA_FALSE;
2078 }
2079 
2080 EAPI void
ecore_evas_override_set(Ecore_Evas * ee,Eina_Bool on)2081 ecore_evas_override_set(Ecore_Evas *ee, Eina_Bool on)
2082 {
2083    ECORE_EVAS_CHECK(ee);
2084    IFC(ee, fn_override_set) (ee, on);
2085    IFE;
2086    ee->prop.override = !!on;
2087 }
2088 
2089 EAPI Eina_Bool
ecore_evas_override_get(const Ecore_Evas * ee)2090 ecore_evas_override_get(const Ecore_Evas *ee)
2091 {
2092    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2093    return ee->prop.override ? EINA_TRUE : EINA_FALSE;
2094 }
2095 
2096 EAPI void
ecore_evas_maximized_set(Ecore_Evas * ee,Eina_Bool on)2097 ecore_evas_maximized_set(Ecore_Evas *ee, Eina_Bool on)
2098 {
2099    ECORE_EVAS_CHECK(ee);
2100    IFC(ee, fn_maximized_set) (ee, on);
2101    IFE;
2102 }
2103 
2104 EAPI Eina_Bool
ecore_evas_maximized_get(const Ecore_Evas * ee)2105 ecore_evas_maximized_get(const Ecore_Evas *ee)
2106 {
2107    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2108    return ee->prop.maximized ? EINA_TRUE : EINA_FALSE;
2109 }
2110 
2111 EAPI Eina_Bool
ecore_evas_window_profile_supported_get(const Ecore_Evas * ee)2112 ecore_evas_window_profile_supported_get(const Ecore_Evas *ee)
2113 {
2114    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2115    return ee->profile_supported ? EINA_TRUE : EINA_FALSE;
2116 }
2117 
2118 EAPI void
ecore_evas_window_profile_set(Ecore_Evas * ee,const char * profile)2119 ecore_evas_window_profile_set(Ecore_Evas *ee, const char *profile)
2120 {
2121    ECORE_EVAS_CHECK(ee);
2122    IFC(ee, fn_profile_set) (ee, profile);
2123    IFE;
2124 }
2125 
2126 EAPI const char *
ecore_evas_window_profile_get(const Ecore_Evas * ee)2127 ecore_evas_window_profile_get(const Ecore_Evas *ee)
2128 {
2129    ECORE_EVAS_CHECK(ee, NULL);
2130    return ee->prop.profile.name;
2131 }
2132 
2133 EAPI void
ecore_evas_window_available_profiles_set(Ecore_Evas * ee,const char ** profiles,const unsigned int count)2134 ecore_evas_window_available_profiles_set(Ecore_Evas *ee, const char **profiles, const unsigned int count)
2135 {
2136    ECORE_EVAS_CHECK(ee);
2137    IFC(ee, fn_profiles_set) (ee, profiles, count);
2138    IFE;
2139 }
2140 
2141 EAPI Eina_Bool
ecore_evas_window_available_profiles_get(Ecore_Evas * ee,char *** profiles,unsigned int * count)2142 ecore_evas_window_available_profiles_get(Ecore_Evas *ee, char ***profiles, unsigned int *count)
2143 {
2144    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2145 
2146    if ((ee->prop.profile.available_list) &&
2147        (ee->prop.profile.count >= 1))
2148      {
2149         if (profiles) *profiles = ee->prop.profile.available_list;
2150         if (count) *count = ee->prop.profile.count;
2151         return EINA_TRUE;
2152      }
2153    else
2154      return EINA_FALSE;
2155 }
2156 
2157 EAPI Eina_Bool
ecore_evas_wm_rotation_supported_get(const Ecore_Evas * ee)2158 ecore_evas_wm_rotation_supported_get(const Ecore_Evas *ee)
2159 {
2160    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2161    return ee->prop.wm_rot.supported;
2162 }
2163 
2164 EAPI void
ecore_evas_wm_rotation_preferred_rotation_set(Ecore_Evas * ee,int rotation)2165 ecore_evas_wm_rotation_preferred_rotation_set(Ecore_Evas *ee, int rotation)
2166 {
2167    ECORE_EVAS_CHECK(ee);
2168    if (rotation != -1)
2169      {
2170         if (ee->prop.wm_rot.available_rots)
2171           {
2172              Eina_Bool found = EINA_FALSE;
2173              unsigned int i;
2174              for (i = 0; i < ee->prop.wm_rot.count; i++)
2175                {
2176                   if (ee->prop.wm_rot.available_rots[i] == rotation)
2177                     {
2178                        found = EINA_TRUE;
2179                        break;
2180                     }
2181                }
2182              if (!found) return;
2183           }
2184      }
2185    IFC(ee, fn_wm_rot_preferred_rotation_set) (ee, rotation);
2186    IFE;
2187 }
2188 
2189 EAPI int
ecore_evas_wm_rotation_preferred_rotation_get(const Ecore_Evas * ee)2190 ecore_evas_wm_rotation_preferred_rotation_get(const Ecore_Evas *ee)
2191 {
2192    ECORE_EVAS_CHECK(ee, -1);
2193    return ee->prop.wm_rot.preferred_rot;
2194 }
2195 
2196 EAPI void
ecore_evas_wm_rotation_available_rotations_set(Ecore_Evas * ee,const int * rotations,unsigned int count)2197 ecore_evas_wm_rotation_available_rotations_set(Ecore_Evas *ee, const int *rotations, unsigned int count)
2198 {
2199    ECORE_EVAS_CHECK(ee);
2200    IFC(ee, fn_wm_rot_available_rotations_set) (ee, rotations, count);
2201    IFE;
2202 }
2203 
2204 EAPI Eina_Bool
ecore_evas_wm_rotation_available_rotations_get(const Ecore_Evas * ee,int ** rotations,unsigned int * count)2205 ecore_evas_wm_rotation_available_rotations_get(const Ecore_Evas *ee, int **rotations, unsigned int *count)
2206 {
2207    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2208    if ((!rotations) || (!count))
2209      return EINA_FALSE;
2210 
2211    if ((!ee->prop.wm_rot.available_rots) || (ee->prop.wm_rot.count == 0))
2212      return EINA_FALSE;
2213 
2214    *rotations = calloc(ee->prop.wm_rot.count, sizeof(int));
2215    if (!*rotations) return EINA_FALSE;
2216 
2217    memcpy(*rotations, ee->prop.wm_rot.available_rots, sizeof(int) * ee->prop.wm_rot.count);
2218    *count = ee->prop.wm_rot.count;
2219 
2220    return EINA_TRUE;
2221 }
2222 
2223 EAPI void
ecore_evas_wm_rotation_manual_rotation_done_set(Ecore_Evas * ee,Eina_Bool set)2224 ecore_evas_wm_rotation_manual_rotation_done_set(Ecore_Evas *ee, Eina_Bool set)
2225 {
2226    ECORE_EVAS_CHECK(ee);
2227    if (!ee->prop.wm_rot.app_set)
2228      {
2229         return;
2230      }
2231 
2232    IFC(ee, fn_wm_rot_manual_rotation_done_set) (ee, set);
2233    IFE;
2234 }
2235 
2236 EAPI Eina_Bool
ecore_evas_wm_rotation_manual_rotation_done_get(const Ecore_Evas * ee)2237 ecore_evas_wm_rotation_manual_rotation_done_get(const Ecore_Evas *ee)
2238 {
2239    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2240    if (!ee->prop.wm_rot.app_set)
2241      {
2242         return EINA_FALSE;
2243      }
2244 
2245    return ee->prop.wm_rot.manual_mode.set;
2246 }
2247 
2248 EAPI void
ecore_evas_wm_rotation_manual_rotation_done(Ecore_Evas * ee)2249 ecore_evas_wm_rotation_manual_rotation_done(Ecore_Evas *ee)
2250 {
2251    ECORE_EVAS_CHECK(ee);
2252    if (!ee->prop.wm_rot.app_set)
2253      {
2254         return;
2255      }
2256 
2257    IFC(ee, fn_wm_rot_manual_rotation_done) (ee);
2258    IFE;
2259 }
2260 
2261 EAPI const Eina_List *
ecore_evas_aux_hints_supported_get(const Ecore_Evas * ee)2262 ecore_evas_aux_hints_supported_get(const Ecore_Evas *ee)
2263 {
2264    ECORE_EVAS_CHECK(ee, NULL);
2265    return ee->prop.aux_hint.supported_list;
2266 }
2267 
2268 EAPI Eina_List *
ecore_evas_aux_hints_allowed_get(const Ecore_Evas * ee)2269 ecore_evas_aux_hints_allowed_get(const Ecore_Evas *ee)
2270 {
2271    ECORE_EVAS_CHECK(ee, NULL);
2272 
2273    Eina_List *list = NULL, *ll;
2274    Ecore_Evas_Aux_Hint *aux;
2275    EINA_LIST_FOREACH(ee->prop.aux_hint.hints, ll, aux)
2276      {
2277         if ((aux->allowed) && !(aux->notified))
2278           {
2279              list = eina_list_append(list, (void*)(uintptr_t)aux->id);
2280           }
2281      }
2282 
2283    return list;
2284 }
2285 
2286 EAPI int
ecore_evas_aux_hint_add(Ecore_Evas * ee,const char * hint,const char * val)2287 ecore_evas_aux_hint_add(Ecore_Evas *ee, const char *hint, const char *val)
2288 {
2289    ECORE_EVAS_CHECK(ee, -1);
2290 
2291    Eina_List *ll;
2292    char *supported_hint;
2293    EINA_LIST_FOREACH(ee->prop.aux_hint.supported_list, ll, supported_hint)
2294      {
2295         if (!strncmp(supported_hint, hint, strlen(hint)))
2296           {
2297              Ecore_Evas_Aux_Hint *aux= (Ecore_Evas_Aux_Hint *)calloc(1, sizeof(Ecore_Evas_Aux_Hint));
2298              if (aux)
2299                {
2300                   aux->id = ee->prop.aux_hint.id;
2301                   aux->hint = eina_stringshare_add(hint);
2302                   aux->val = eina_stringshare_add(val);
2303 
2304                   ee->prop.aux_hint.hints =
2305                     eina_list_append(ee->prop.aux_hint.hints, aux);
2306 
2307                   if (!strncmp(ee->driver, "wayland", 7))
2308                     {
2309                        Ecore_Evas_Interface_Wayland *iface;
2310 
2311                        iface = (Ecore_Evas_Interface_Wayland *)_ecore_evas_interface_get(ee, "wayland");
2312                        EINA_SAFETY_ON_NULL_RETURN_VAL(iface, -1);
2313 
2314                        if (iface->aux_hint_add)
2315                          iface->aux_hint_add(ee, aux->id, hint, val);
2316 
2317                        ee->prop.aux_hint.id++;
2318 
2319                        return aux->id;
2320                     }
2321                   else
2322                     {
2323                        Eina_Strbuf *buf = _ecore_evas_aux_hints_string_get(ee);
2324                        if (buf)
2325                          {
2326                             if (ee->engine.func->fn_aux_hints_set)
2327                               ee->engine.func->fn_aux_hints_set(ee, eina_strbuf_string_get(buf));
2328 
2329                             eina_strbuf_free(buf);
2330 
2331                             ee->prop.aux_hint.id++;
2332 
2333                             return aux->id;
2334                          }
2335                     }
2336 
2337                   eina_stringshare_del(aux->hint);
2338                   eina_stringshare_del(aux->val);
2339                   free(aux);
2340                }
2341              break;
2342           }
2343      }
2344 
2345    return -1;
2346 }
2347 
2348 EAPI Eina_Bool
ecore_evas_aux_hint_del(Ecore_Evas * ee,const int id)2349 ecore_evas_aux_hint_del(Ecore_Evas *ee, const int id)
2350 {
2351    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2352 
2353    Eina_List *ll;
2354    Ecore_Evas_Aux_Hint *aux;
2355    EINA_LIST_FOREACH(ee->prop.aux_hint.hints, ll, aux)
2356      {
2357         if (id == aux->id)
2358           {
2359              ee->prop.aux_hint.hints =
2360                eina_list_remove(ee->prop.aux_hint.hints, aux);
2361 
2362              eina_stringshare_del(aux->hint);
2363              eina_stringshare_del(aux->val);
2364              free(aux);
2365 
2366              if (!strncmp(ee->driver, "wayland", 7))
2367                {
2368                   Ecore_Evas_Interface_Wayland *iface;
2369 
2370                   iface = (Ecore_Evas_Interface_Wayland *)_ecore_evas_interface_get(ee, "wayland");
2371                   EINA_SAFETY_ON_NULL_RETURN_VAL(iface, EINA_FALSE);
2372 
2373                   if (iface->aux_hint_del)
2374                     iface->aux_hint_del(ee, id);
2375 
2376                   return EINA_TRUE;
2377                }
2378              else
2379                {
2380                   Eina_Strbuf *buf = _ecore_evas_aux_hints_string_get(ee);
2381                   if (buf)
2382                     {
2383                        if (ee->engine.func->fn_aux_hints_set)
2384                          ee->engine.func->fn_aux_hints_set(ee, eina_strbuf_string_get(buf));
2385 
2386                        eina_strbuf_free(buf);
2387 
2388                        return EINA_TRUE;
2389                     }
2390                }
2391 
2392              break;
2393           }
2394      }
2395 
2396    return EINA_FALSE;
2397 }
2398 
2399 EAPI Eina_Bool
ecore_evas_aux_hint_val_set(Ecore_Evas * ee,const int id,const char * val)2400 ecore_evas_aux_hint_val_set(Ecore_Evas *ee, const int id, const char *val)
2401 {
2402    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2403 
2404    Eina_List *ll;
2405    Ecore_Evas_Aux_Hint *aux;
2406    EINA_LIST_FOREACH(ee->prop.aux_hint.hints, ll, aux)
2407      {
2408         if (id == aux->id)
2409           {
2410              eina_stringshare_del(aux->val);
2411              aux->val = eina_stringshare_add(val);
2412              aux->allowed = 0;
2413              aux->notified = 0;
2414 
2415              if (!strncmp(ee->driver, "wayland", 7))
2416                {
2417                   Ecore_Evas_Interface_Wayland *iface;
2418 
2419                   iface = (Ecore_Evas_Interface_Wayland *)_ecore_evas_interface_get(ee, "wayland");
2420                   EINA_SAFETY_ON_NULL_RETURN_VAL(iface, EINA_FALSE);
2421 
2422                   if (iface->aux_hint_change)
2423                     iface->aux_hint_change(ee, id, val);
2424 
2425                   return EINA_TRUE;
2426                }
2427              else
2428                {
2429                   Eina_Strbuf *buf = _ecore_evas_aux_hints_string_get(ee);
2430                   if (buf)
2431                     {
2432                        if (ee->engine.func->fn_aux_hints_set)
2433                          ee->engine.func->fn_aux_hints_set(ee, eina_strbuf_string_get(buf));
2434 
2435                        eina_strbuf_free(buf);
2436 
2437                        return EINA_TRUE;
2438                     }
2439                }
2440 
2441              break;
2442           }
2443      }
2444 
2445    return EINA_FALSE;
2446 }
2447 
2448 EAPI const char *
ecore_evas_aux_hint_val_get(const Ecore_Evas * ee,int id)2449 ecore_evas_aux_hint_val_get(const Ecore_Evas *ee, int id)
2450 {
2451    ECORE_EVAS_CHECK(ee, NULL);
2452 
2453    Eina_List *ll;
2454    Ecore_Evas_Aux_Hint *aux;
2455    EINA_LIST_FOREACH(ee->prop.aux_hint.hints, ll, aux)
2456      {
2457         if (id == aux->id) return aux->val;
2458      }
2459 
2460    return NULL;
2461 }
2462 
2463 EAPI int
ecore_evas_aux_hint_id_get(const Ecore_Evas * ee,const char * hint)2464 ecore_evas_aux_hint_id_get(const Ecore_Evas *ee, const char *hint)
2465 {
2466    ECORE_EVAS_CHECK(ee, -1);
2467 
2468    Eina_List *ll;
2469    Ecore_Evas_Aux_Hint *aux;
2470    EINA_LIST_FOREACH(ee->prop.aux_hint.hints, ll, aux)
2471      {
2472         if (!strcmp(hint,aux->hint)) return aux->id;
2473      }
2474 
2475    return -1;
2476 }
2477 
2478 EAPI void
ecore_evas_fullscreen_set(Ecore_Evas * ee,Eina_Bool on)2479 ecore_evas_fullscreen_set(Ecore_Evas *ee, Eina_Bool on)
2480 {
2481    ECORE_EVAS_CHECK(ee);
2482    IFC(ee, fn_fullscreen_set) (ee, on);
2483    IFE;
2484 }
2485 
2486 EAPI Eina_Bool
ecore_evas_fullscreen_get(const Ecore_Evas * ee)2487 ecore_evas_fullscreen_get(const Ecore_Evas *ee)
2488 {
2489    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2490    return ee->prop.fullscreen ? EINA_TRUE : EINA_FALSE;
2491 }
2492 
2493 EAPI void
ecore_evas_avoid_damage_set(Ecore_Evas * ee,Ecore_Evas_Avoid_Damage_Type on)2494 ecore_evas_avoid_damage_set(Ecore_Evas *ee, Ecore_Evas_Avoid_Damage_Type on)
2495 {
2496    ECORE_EVAS_CHECK(ee);
2497    IFC(ee, fn_avoid_damage_set) (ee, on);
2498    IFE;
2499 }
2500 
2501 EAPI Ecore_Evas_Avoid_Damage_Type
ecore_evas_avoid_damage_get(const Ecore_Evas * ee)2502 ecore_evas_avoid_damage_get(const Ecore_Evas *ee)
2503 {
2504    ECORE_EVAS_CHECK(ee, ECORE_EVAS_AVOID_DAMAGE_NONE);
2505    return ee->prop.avoid_damage;
2506 }
2507 
2508 EAPI void
ecore_evas_withdrawn_set(Ecore_Evas * ee,Eina_Bool withdrawn)2509 ecore_evas_withdrawn_set(Ecore_Evas *ee, Eina_Bool withdrawn)
2510 {
2511    ECORE_EVAS_CHECK(ee);
2512    IFC(ee, fn_withdrawn_set) (ee, withdrawn);
2513    IFE;
2514 }
2515 
2516 EAPI Eina_Bool
ecore_evas_withdrawn_get(const Ecore_Evas * ee)2517 ecore_evas_withdrawn_get(const Ecore_Evas *ee)
2518 {
2519    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2520    return ee->prop.withdrawn ? EINA_TRUE : EINA_FALSE;
2521 }
2522 
2523 EAPI void
ecore_evas_sticky_set(Ecore_Evas * ee,Eina_Bool on)2524 ecore_evas_sticky_set(Ecore_Evas *ee, Eina_Bool on)
2525 {
2526    ECORE_EVAS_CHECK(ee);
2527    IFC(ee, fn_sticky_set) (ee, on);
2528    IFE;
2529 }
2530 
2531 EAPI Eina_Bool
ecore_evas_sticky_get(const Ecore_Evas * ee)2532 ecore_evas_sticky_get(const Ecore_Evas *ee)
2533 {
2534    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2535    return ee->prop.sticky ? EINA_TRUE : EINA_FALSE;
2536 }
2537 
2538 EAPI void
ecore_evas_window_group_set(Ecore_Evas * ee,const Ecore_Evas * ee_group)2539 ecore_evas_window_group_set(Ecore_Evas *ee, const Ecore_Evas *ee_group)
2540 {
2541    ECORE_EVAS_CHECK(ee);
2542    IFC(ee, fn_window_group_set) (ee, ee_group);
2543    IFE;
2544 }
2545 
2546 EAPI const Ecore_Evas *
ecore_evas_window_group_get(const Ecore_Evas * ee)2547 ecore_evas_window_group_get(const Ecore_Evas *ee)
2548 {
2549    ECORE_EVAS_CHECK(ee, NULL);
2550    return ee->prop.group_ee;
2551 }
2552 
2553 EAPI void
ecore_evas_aspect_set(Ecore_Evas * ee,double aspect)2554 ecore_evas_aspect_set(Ecore_Evas *ee, double aspect)
2555 {
2556    ECORE_EVAS_CHECK(ee);
2557    IFC(ee, fn_aspect_set) (ee, aspect);
2558    IFE;
2559 }
2560 
2561 EAPI double
ecore_evas_aspect_get(const Ecore_Evas * ee)2562 ecore_evas_aspect_get(const Ecore_Evas *ee)
2563 {
2564    ECORE_EVAS_CHECK(ee, 0.0);
2565    return ee->prop.aspect;
2566 }
2567 
2568 EAPI void
ecore_evas_urgent_set(Ecore_Evas * ee,Eina_Bool on)2569 ecore_evas_urgent_set(Ecore_Evas *ee, Eina_Bool on)
2570 {
2571    ECORE_EVAS_CHECK(ee);
2572    IFC(ee, fn_urgent_set) (ee, on);
2573    IFE;
2574 }
2575 
2576 EAPI Eina_Bool
ecore_evas_urgent_get(const Ecore_Evas * ee)2577 ecore_evas_urgent_get(const Ecore_Evas *ee)
2578 {
2579    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2580    return ee->prop.urgent ? EINA_TRUE : EINA_FALSE;
2581 }
2582 
2583 EAPI void
ecore_evas_modal_set(Ecore_Evas * ee,Eina_Bool on)2584 ecore_evas_modal_set(Ecore_Evas *ee, Eina_Bool on)
2585 {
2586    ECORE_EVAS_CHECK(ee);
2587    IFC(ee, fn_modal_set) (ee, on);
2588    IFE;
2589 }
2590 
2591 EAPI Eina_Bool
ecore_evas_modal_get(const Ecore_Evas * ee)2592 ecore_evas_modal_get(const Ecore_Evas *ee)
2593 {
2594    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2595    return ee->prop.modal ? EINA_TRUE : EINA_FALSE;
2596 }
2597 
2598 EAPI void
ecore_evas_demand_attention_set(Ecore_Evas * ee,Eina_Bool on)2599 ecore_evas_demand_attention_set(Ecore_Evas *ee, Eina_Bool on)
2600 {
2601    ECORE_EVAS_CHECK(ee);
2602    IFC(ee, fn_demands_attention_set) (ee, on);
2603    IFE;
2604 }
2605 
2606 EAPI Eina_Bool
ecore_evas_demand_attention_get(const Ecore_Evas * ee)2607 ecore_evas_demand_attention_get(const Ecore_Evas *ee)
2608 {
2609    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2610    return ee->prop.demand_attention ? EINA_TRUE : EINA_FALSE;
2611 }
2612 
2613 EAPI void
ecore_evas_focus_skip_set(Ecore_Evas * ee,Eina_Bool on)2614 ecore_evas_focus_skip_set(Ecore_Evas *ee, Eina_Bool on)
2615 {
2616    ECORE_EVAS_CHECK(ee);
2617    IFC(ee, fn_focus_skip_set) (ee, on);
2618    IFE;
2619 }
2620 
2621 EAPI Eina_Bool
ecore_evas_focus_skip_get(const Ecore_Evas * ee)2622 ecore_evas_focus_skip_get(const Ecore_Evas *ee)
2623 {
2624    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2625    return ee->prop.focus_skip ? EINA_TRUE : EINA_FALSE;
2626 }
2627 
2628 EAPI void
ecore_evas_ignore_events_set(Ecore_Evas * ee,Eina_Bool ignore)2629 ecore_evas_ignore_events_set(Ecore_Evas *ee, Eina_Bool ignore)
2630 {
2631    ECORE_EVAS_CHECK(ee);
2632    IFC(ee, fn_ignore_events_set) (ee, ignore);
2633    IFE;
2634 }
2635 
2636 EAPI Eina_Bool
ecore_evas_ignore_events_get(const Ecore_Evas * ee)2637 ecore_evas_ignore_events_get(const Ecore_Evas *ee)
2638 {
2639    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2640    return ee->ignore_events ? EINA_TRUE : EINA_FALSE;
2641 }
2642 
2643 EAPI void
ecore_evas_manual_render_set(Ecore_Evas * ee,Eina_Bool manual_render)2644 ecore_evas_manual_render_set(Ecore_Evas *ee, Eina_Bool manual_render)
2645 {
2646    ECORE_EVAS_CHECK(ee);
2647    manual_render = !!manual_render;
2648    if (ee->manual_render == manual_render) return;
2649    ee->manual_render = manual_render;
2650 
2651    if (manual_render) ecore_evas_render_wait(ee);
2652 
2653    if (!ee->animator_count) return;
2654    if (!ee->engine.func->fn_animator_register) return;
2655    if (!ee->engine.func->fn_animator_unregister) return;
2656 
2657    if (manual_render)
2658      ee->engine.func->fn_animator_unregister(ee);
2659    else
2660      ee->engine.func->fn_animator_register(ee);
2661 }
2662 
2663 EAPI Eina_Bool
ecore_evas_manual_render_get(const Ecore_Evas * ee)2664 ecore_evas_manual_render_get(const Ecore_Evas *ee)
2665 {
2666    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2667    return ee->manual_render ? EINA_TRUE : EINA_FALSE;
2668 }
2669 
2670 EAPI void
ecore_evas_manual_render(Ecore_Evas * ee)2671 ecore_evas_manual_render(Ecore_Evas *ee)
2672 {
2673    ECORE_EVAS_CHECK(ee);
2674 
2675    if (ee->manual_render)
2676      {
2677         double t = -1.0;
2678 
2679         if (ee->engine.func->fn_last_tick_get)
2680           t = ee->engine.func->fn_last_tick_get(ee);
2681         if (t < 0.0)
2682           t = ecore_loop_time_get();
2683 
2684         ecore_evas_animator_tick(ee, NULL, t);
2685      }
2686    else
2687      {
2688         /* We want to ensure a manual render actually takes place,
2689          * even if we were in the middle of an async render.  This
2690          * will ensure that any post render callbacks added
2691          * specifically for this manual render will fire.
2692          */
2693         ecore_evas_render_wait(ee);
2694      }
2695 
2696    if (ee->engine.func->fn_render)
2697      {
2698         ee->engine.func->fn_render(ee);
2699      }
2700    else
2701      {
2702         ecore_evas_render(ee);
2703         ecore_evas_render_wait(ee);
2704      }
2705 }
2706 
2707 EAPI void
ecore_evas_msg_parent_send(Ecore_Evas * ee,int msg_domain,int msg_id,void * data,int size)2708 ecore_evas_msg_parent_send(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size)
2709 {
2710    ECORE_EVAS_CHECK(ee);
2711    DBG("Msg(to parent): ee=%p msg_domain=%d msg_id=%d size=%d", ee, msg_domain, msg_id, size);
2712    IFC(ee, fn_msg_parent_send) (ee, msg_domain, msg_id, data, size);
2713    IFE;
2714 }
2715 
2716 EAPI void
ecore_evas_msg_send(Ecore_Evas * ee,int msg_domain,int msg_id,void * data,int size)2717 ecore_evas_msg_send(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size)
2718 {
2719    ECORE_EVAS_CHECK(ee);
2720    DBG("Msg: ee=%p msg_domain=%d msg_id=%d size=%d", ee, msg_domain, msg_id, size);
2721    IFC(ee, fn_msg_send) (ee, msg_domain, msg_id, data, size);
2722    IFE;
2723 }
2724 
2725 EAPI void
ecore_evas_callback_msg_parent_handle_set(Ecore_Evas * ee,void (* func_parent_handle)(Ecore_Evas * ee,int msg_domain,int msg_id,void * data,int size))2726 ecore_evas_callback_msg_parent_handle_set(Ecore_Evas *ee, void (*func_parent_handle)(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size))
2727 {
2728    ECORE_EVAS_CHECK(ee);
2729    DBG("Msg Parent handle: ee=%p", ee);
2730    ee->func.fn_msg_parent_handle = func_parent_handle;
2731 }
2732 
2733 EAPI void
ecore_evas_callback_msg_handle_set(Ecore_Evas * ee,void (* func_handle)(Ecore_Evas * ee,int msg_domain,int msg_id,void * data,int size))2734 ecore_evas_callback_msg_handle_set(Ecore_Evas *ee, void (*func_handle)(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size))
2735 {
2736    ECORE_EVAS_CHECK(ee);
2737    DBG("Msg handle: ee=%p", ee);
2738    ee->func.fn_msg_handle = func_handle;
2739 }
2740 
2741 
2742 EAPI void
ecore_evas_comp_sync_set(Ecore_Evas * ee,Eina_Bool do_sync)2743 ecore_evas_comp_sync_set(Ecore_Evas *ee, Eina_Bool do_sync)
2744 {
2745    ECORE_EVAS_CHECK(ee);
2746    ee->no_comp_sync = !do_sync;
2747 }
2748 
2749 EAPI Eina_Bool
ecore_evas_comp_sync_get(const Ecore_Evas * ee)2750 ecore_evas_comp_sync_get(const Ecore_Evas *ee)
2751 {
2752    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2753    return !ee->no_comp_sync;
2754 }
2755 
2756 EAPI Ecore_Window
ecore_evas_window_get(const Ecore_Evas * ee)2757 ecore_evas_window_get(const Ecore_Evas *ee)
2758 {
2759    ECORE_EVAS_CHECK(ee, 0);
2760    return ee->prop.window;
2761 }
2762 
2763 EAPI void
ecore_evas_screen_geometry_get(const Ecore_Evas * ee,int * x,int * y,int * w,int * h)2764 ecore_evas_screen_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h)
2765 {
2766    if (x) *x = 0;
2767    if (y) *y = 0;
2768    if (w) *w = 0;
2769    if (h) *h = 0;
2770    ECORE_EVAS_CHECK(ee);
2771    IFC(ee, fn_screen_geometry_get) (ee, x, y, w, h);
2772    IFE;
2773 }
2774 
2775 EAPI void
ecore_evas_screen_dpi_get(const Ecore_Evas * ee,int * xdpi,int * ydpi)2776 ecore_evas_screen_dpi_get(const Ecore_Evas *ee, int *xdpi, int *ydpi)
2777 {
2778    if (xdpi) *xdpi = 0;
2779    if (ydpi) *ydpi = 0;
2780    ECORE_EVAS_CHECK(ee);
2781    IFC(ee, fn_screen_dpi_get) (ee, xdpi, ydpi);
2782    IFE;
2783 }
2784 
2785 EAPI void
ecore_evas_draw_frame_set(Ecore_Evas * ee EINA_UNUSED,Eina_Bool draw_frame EINA_UNUSED)2786 ecore_evas_draw_frame_set(Ecore_Evas *ee EINA_UNUSED, Eina_Bool draw_frame EINA_UNUSED)
2787 {
2788    WRN("Calling deprecated function %s (not implemented)", __func__);
2789 }
2790 
2791 EAPI Eina_Bool
ecore_evas_draw_frame_get(const Ecore_Evas * ee EINA_UNUSED)2792 ecore_evas_draw_frame_get(const Ecore_Evas *ee EINA_UNUSED)
2793 {
2794    WRN("Calling deprecated function %s (not implemented)", __func__);
2795    return EINA_FALSE;
2796 }
2797 
2798 EAPI void
ecore_evas_shadow_geometry_set(Ecore_Evas * ee,int l,int r,int t,int b)2799 ecore_evas_shadow_geometry_set(Ecore_Evas *ee, int l, int r, int t, int b)
2800 {
2801    ECORE_EVAS_CHECK(ee);
2802    EINA_SAFETY_ON_TRUE_RETURN(l < 0);
2803    EINA_SAFETY_ON_TRUE_RETURN(r < 0);
2804    EINA_SAFETY_ON_TRUE_RETURN(t < 0);
2805    EINA_SAFETY_ON_TRUE_RETURN(b < 0);
2806    if ((ee->shadow.l == l) && (ee->shadow.r == r) &&
2807        (ee->shadow.t == t) && (ee->shadow.b == b)) return;
2808    ee->shadow.l = l;
2809    ee->shadow.r = r;
2810    ee->shadow.t = t;
2811    ee->shadow.b = b;
2812    ee->shadow.changed = EINA_TRUE;
2813 }
2814 
2815 EAPI void
ecore_evas_shadow_geometry_get(const Ecore_Evas * ee,int * l,int * r,int * t,int * b)2816 ecore_evas_shadow_geometry_get(const Ecore_Evas *ee, int *l, int *r, int *t, int *b)
2817 {
2818    if (l) *l = 0;
2819    if (r) *r = 0;
2820    if (t) *t = 0;
2821    if (b) *b = 0;
2822    ECORE_EVAS_CHECK(ee);
2823    if (l) *l = ee->shadow.l;
2824    if (r) *r = ee->shadow.r;
2825    if (t) *t = ee->shadow.t;
2826    if (b) *b = ee->shadow.b;
2827 }
2828 
2829 EAPI void
ecore_evas_pointer_xy_get(const Ecore_Evas * ee,Evas_Coord * x,Evas_Coord * y)2830 ecore_evas_pointer_xy_get(const Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y)
2831 {
2832    if (x) *x = 0;
2833    if (y) *y = 0;
2834    ECORE_EVAS_CHECK(ee);
2835    IFC(ee, fn_pointer_xy_get) (ee, x, y);
2836    IFE;
2837 }
2838 
2839 EAPI Eina_Bool
ecore_evas_pointer_warp(const Ecore_Evas * ee,Evas_Coord x,Evas_Coord y)2840 ecore_evas_pointer_warp(const Ecore_Evas *ee, Evas_Coord x, Evas_Coord y)
2841 {
2842    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2843    if (ee->engine.func->fn_pointer_warp)
2844      return ee->engine.func->fn_pointer_warp(ee, x, y);
2845 
2846    return EINA_FALSE;
2847 }
2848 
2849 EAPI void
ecore_evas_pointer_device_xy_get(const Ecore_Evas * ee,const Efl_Input_Device * pointer,Evas_Coord * x,Evas_Coord * y)2850 ecore_evas_pointer_device_xy_get(const Ecore_Evas *ee,
2851                                  const Efl_Input_Device *pointer,
2852                                  Evas_Coord *x, Evas_Coord *y)
2853 {
2854    ECORE_EVAS_CHECK(ee);
2855 
2856    if (pointer)
2857      {
2858         if (efl_input_device_type_get(pointer) != EFL_INPUT_DEVICE_TYPE_SEAT)
2859           pointer = efl_input_device_seat_get(pointer);
2860         if (efl_input_device_type_get(pointer) != EFL_INPUT_DEVICE_TYPE_SEAT)
2861           {
2862              ERR("Could not find seat");
2863              return;
2864           }
2865      }
2866    if ((!pointer) ||
2867        (pointer == evas_default_device_get(ee->evas, EVAS_DEVICE_CLASS_SEAT)))
2868      ecore_evas_pointer_xy_get(ee, x, y);
2869    else
2870      {
2871         static Eina_Bool (*pointer_xy_get)(const Evas_Object *, const Efl_Input_Device *, Evas_Coord *, Evas_Coord *y) = NULL;
2872         Eina_Module *mod;
2873 
2874         if (!pointer_xy_get && ee->vnc_server)
2875           {
2876              mod = _ecore_evas_vnc_server_module_load();
2877              EINA_SAFETY_ON_NULL_RETURN(mod);
2878 
2879              pointer_xy_get = eina_module_symbol_get(mod, "ecore_evas_vnc_server_pointer_xy_get");
2880              EINA_SAFETY_ON_NULL_RETURN(pointer_xy_get);
2881           }
2882 
2883         // FIXME: Handle matching of the efl_input_device with proper evas_object
2884 
2885         ecore_evas_pointer_xy_get(ee, x, y);
2886      }
2887 }
2888 
2889 EAPI void *
ecore_evas_pixmap_visual_get(const Ecore_Evas * ee)2890 ecore_evas_pixmap_visual_get(const Ecore_Evas *ee)
2891 {
2892    ECORE_EVAS_CHECK(ee, NULL);
2893 
2894    if (!strcmp(ee->driver, "software_x11"))
2895      {
2896         Ecore_Evas_Interface_Software_X11 *iface;
2897         iface = (Ecore_Evas_Interface_Software_X11 *)_ecore_evas_interface_get(ee, "software_x11");
2898         EINA_SAFETY_ON_NULL_RETURN_VAL(iface, NULL);
2899 
2900         if (iface->pixmap_visual_get)
2901           return iface->pixmap_visual_get(ee);
2902      }
2903    else if (!strcmp(ee->driver, "opengl_x11"))
2904      {
2905         Ecore_Evas_Interface_Gl_X11 *iface;
2906         iface = (Ecore_Evas_Interface_Gl_X11 *)_ecore_evas_interface_get(ee, "gl_x11");
2907         EINA_SAFETY_ON_NULL_RETURN_VAL(iface, NULL);
2908 
2909         if (iface->pixmap_visual_get)
2910           return iface->pixmap_visual_get(ee);
2911      }
2912 
2913    return NULL;
2914 }
2915 
2916 EAPI unsigned long
ecore_evas_pixmap_colormap_get(const Ecore_Evas * ee)2917 ecore_evas_pixmap_colormap_get(const Ecore_Evas *ee)
2918 {
2919    ECORE_EVAS_CHECK(ee, 0);
2920 
2921    if (!strcmp(ee->driver, "software_x11"))
2922      {
2923         Ecore_Evas_Interface_Software_X11 *iface;
2924         iface = (Ecore_Evas_Interface_Software_X11 *)_ecore_evas_interface_get(ee, "software_x11");
2925         EINA_SAFETY_ON_NULL_RETURN_VAL(iface, 0);
2926 
2927         if (iface->pixmap_colormap_get)
2928           return iface->pixmap_colormap_get(ee);
2929      }
2930    else if (!strcmp(ee->driver, "opengl_x11"))
2931      {
2932         Ecore_Evas_Interface_Gl_X11 *iface;
2933         iface = (Ecore_Evas_Interface_Gl_X11 *)_ecore_evas_interface_get(ee, "gl_x11");
2934         EINA_SAFETY_ON_NULL_RETURN_VAL(iface, 0);
2935 
2936         if (iface->pixmap_colormap_get)
2937           return iface->pixmap_colormap_get(ee);
2938      }
2939 
2940    return 0;
2941 }
2942 
2943 EAPI int
ecore_evas_pixmap_depth_get(const Ecore_Evas * ee)2944 ecore_evas_pixmap_depth_get(const Ecore_Evas *ee)
2945 {
2946    ECORE_EVAS_CHECK(ee, 0);
2947 
2948    if (!strcmp(ee->driver, "software_x11"))
2949      {
2950         Ecore_Evas_Interface_Software_X11 *iface;
2951         iface = (Ecore_Evas_Interface_Software_X11 *)_ecore_evas_interface_get(ee, "software_x11");
2952         EINA_SAFETY_ON_NULL_RETURN_VAL(iface, 0);
2953 
2954         if (iface->pixmap_depth_get)
2955           return iface->pixmap_depth_get(ee);
2956      }
2957    else if (!strcmp(ee->driver, "opengl_x11"))
2958      {
2959         Ecore_Evas_Interface_Gl_X11 *iface;
2960         iface = (Ecore_Evas_Interface_Gl_X11 *)_ecore_evas_interface_get(ee, "gl_x11");
2961         EINA_SAFETY_ON_NULL_RETURN_VAL(iface, 0);
2962 
2963         if (iface->pixmap_depth_get)
2964           return iface->pixmap_depth_get(ee);
2965      }
2966 
2967    return 0;
2968 }
2969 
2970 /* fps debug calls - for debugging how much time your app actually spends */
2971 /* rendering graphics... :) */
2972 
2973 static int _ecore_evas_fps_debug_init_count = 0;
2974 static int _ecore_evas_fps_debug_fd = -1;
2975 unsigned int *_ecore_evas_fps_rendertime_mmap = NULL;
2976 
2977 EAPI void
_ecore_evas_fps_debug_init(void)2978 _ecore_evas_fps_debug_init(void)
2979 {
2980    char buf[4096];
2981 
2982    _ecore_evas_fps_debug_init_count++;
2983    if (_ecore_evas_fps_debug_init_count > 1) return;
2984 
2985    snprintf(buf, sizeof(buf), "%s/.ecore_evas_fps_debug-%i",
2986             eina_environment_tmp_get(), (int)getpid());
2987    _ecore_evas_fps_debug_fd = open(buf, O_CREAT | O_BINARY | O_TRUNC | O_RDWR, 0644);
2988    if (_ecore_evas_fps_debug_fd < 0)
2989      {
2990         unlink(buf);
2991         _ecore_evas_fps_debug_fd = open(buf, O_CREAT | O_BINARY | O_TRUNC | O_RDWR, 0644);
2992      }
2993    if (_ecore_evas_fps_debug_fd >= 0)
2994      {
2995         unsigned int zero = 0;
2996         char *buf2 = (char *)&zero;
2997         ssize_t todo = sizeof(unsigned int);
2998 
2999         while (todo > 0)
3000           {
3001              ssize_t r = write(_ecore_evas_fps_debug_fd, buf2, todo);
3002              if (r > 0)
3003                {
3004                   todo -= r;
3005                   buf2 += r;
3006                }
3007              else if ((r < 0) && (errno == EINTR))
3008                continue;
3009              else
3010                {
3011                   ERR("could not write to file '%s' fd %d: %s",
3012                       buf, _ecore_evas_fps_debug_fd, strerror(errno));
3013                   close(_ecore_evas_fps_debug_fd);
3014                   _ecore_evas_fps_debug_fd = -1;
3015                   return;
3016                }
3017           }
3018         _ecore_evas_fps_rendertime_mmap = mmap(NULL, sizeof(unsigned int),
3019                                                PROT_READ | PROT_WRITE,
3020                                                MAP_SHARED,
3021                                                _ecore_evas_fps_debug_fd, 0);
3022         if (_ecore_evas_fps_rendertime_mmap == MAP_FAILED)
3023           _ecore_evas_fps_rendertime_mmap = NULL;
3024      }
3025 }
3026 
3027 EAPI void
_ecore_evas_fps_debug_shutdown(void)3028 _ecore_evas_fps_debug_shutdown(void)
3029 {
3030    _ecore_evas_fps_debug_init_count--;
3031    if (_ecore_evas_fps_debug_init_count > 0) return;
3032    if (_ecore_evas_fps_debug_fd >= 0)
3033      {
3034         char buf[4096];
3035 
3036         snprintf(buf, sizeof(buf), "%s/.ecore_evas_fps_debug-%i",
3037                  eina_environment_tmp_get(), (int)getpid());
3038         unlink(buf);
3039         if (_ecore_evas_fps_rendertime_mmap)
3040           {
3041              munmap(_ecore_evas_fps_rendertime_mmap, sizeof(int));
3042              _ecore_evas_fps_rendertime_mmap = NULL;
3043           }
3044         close(_ecore_evas_fps_debug_fd);
3045         _ecore_evas_fps_debug_fd = -1;
3046      }
3047 }
3048 
3049 EAPI void
_ecore_evas_fps_debug_rendertime_add(double t)3050 _ecore_evas_fps_debug_rendertime_add(double t)
3051 {
3052    static double rtime = 0.0;
3053    static double rlapse = 0.0;
3054    static int frames = 0;
3055    static int flapse = 0;
3056    double tim;
3057 
3058    tim = ecore_time_get();
3059    rtime += t;
3060    frames++;
3061    if (EINA_DBL_EQ(rlapse, 0.0))
3062      {
3063         rlapse = tim;
3064         flapse = frames;
3065      }
3066    else if ((tim - rlapse) >= 0.5)
3067      {
3068         printf("FRAME: %i, FPS: %3.1f, RTIME %3.0f%%\n",
3069                frames,
3070                (frames - flapse) / (tim - rlapse),
3071                (100.0 * rtime) / (tim - rlapse)
3072                );
3073         rlapse = tim;
3074         flapse = frames;
3075         rtime = 0.0;
3076      }
3077 }
3078 
3079 static void
_ecore_evas_animator_detach(Ecore_Animator * a)3080 _ecore_evas_animator_detach(Ecore_Animator *a)
3081 {
3082    Ecore_Evas *ee;
3083    Eina_Inlist *tmp;
3084 
3085    if (a->delete_me) return;
3086 
3087    tmp = EINA_INLIST_GET(a);
3088 
3089    ee = a->ee;
3090    if (a->suspended)
3091      ee->ee_anim.suspended = eina_inlist_remove(ee->ee_anim.suspended, EINA_INLIST_GET(a));
3092    else if ((!tmp->next) && (!tmp->prev) && (EINA_INLIST_GET(a) != ee->ee_anim.active))
3093      return;
3094    else
3095      ee->ee_anim.active = eina_inlist_remove(ee->ee_anim.active, EINA_INLIST_GET(a));
3096 
3097    a->suspended = EINA_FALSE;
3098 }
3099 
3100 static void
_ecore_evas_animators_do(Ecore_Evas * ee)3101 _ecore_evas_animators_do(Ecore_Evas *ee)
3102 {
3103    ee->ee_anim.run_list = ee->ee_anim.active;
3104    ee->ee_anim.active = NULL;
3105 
3106    while (ee->ee_anim.run_list)
3107      {
3108         Ecore_Animator *animator;
3109 
3110         animator = EINA_INLIST_CONTAINER_GET(ee->ee_anim.run_list, Ecore_Animator);
3111         ee->ee_anim.run_list = eina_inlist_remove(ee->ee_anim.run_list, EINA_INLIST_GET(animator));
3112 
3113         if (!_ecore_call_task_cb(animator->func, animator->data) || animator->delete_me)
3114           {
3115              if (animator->delete_me) continue;
3116 
3117              animator->delete_me = EINA_TRUE;
3118              ee->ee_anim.deleted = eina_inlist_append(ee->ee_anim.deleted, EINA_INLIST_GET(animator));
3119           }
3120         else
3121           {
3122              ee->ee_anim.active = eina_inlist_append(ee->ee_anim.active, EINA_INLIST_GET(animator));
3123           }
3124      }
3125 }
3126 
3127 EAPI void
ecore_evas_animator_tick(Ecore_Evas * ee,Eina_Rectangle * viewport,double loop_time)3128 ecore_evas_animator_tick(Ecore_Evas *ee, Eina_Rectangle *viewport, double loop_time)
3129 {
3130    Ecore_Evas *subee;
3131    Eina_List *l;
3132    Efl_Event_Animator_Tick a = { EINA_RECT_ZERO() };
3133 
3134    if (!viewport)
3135      {
3136         evas_output_size_get(ee->evas, &a.update_area.w, &a.update_area.h);
3137      }
3138    else
3139      {
3140         a.update_area.rect = *viewport;
3141      }
3142 
3143    ecore_loop_time_set(loop_time);
3144 
3145    ee->animator_ran = EINA_TRUE;
3146    efl_event_callback_call(ee->evas, EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK, &a);
3147 
3148    if (ee->ee_anim.active)
3149      _ecore_evas_animators_do(ee);
3150    // FIXME: We do not support partial animator in the subcanvas
3151    EINA_LIST_FOREACH(ee->sub_ecore_evas, l, subee)
3152      {
3153         if (subee->evas)
3154           ecore_evas_animator_tick(subee, NULL, loop_time);
3155      }
3156 
3157    // We are a source of sync for general animator.
3158    // Let's only trigger the animator once per rendering loop
3159    if (!ecore_main_loop_animator_ticked_get())
3160      {
3161         // FIXME: We might want to enforce also Ecore_Animatore frametime
3162         ecore_animator_custom_tick();
3163      }
3164 
3165    DBG("Animator ticked on %p.", ee->evas);
3166 }
3167 
3168 // Per Ecore_Evas ticking
3169 static void
ecore_evas_tick_begin(Ecore_Evas * ee)3170 ecore_evas_tick_begin(Ecore_Evas *ee)
3171 {
3172    if (ee->animator_count++ > 0) return;
3173 
3174    if (ee->manual_render)
3175      {
3176        DBG("Attempt to schedule tick for manually rendered canvas.");
3177        return;
3178      }
3179    ee->engine.func->fn_animator_register(ee);
3180 }
3181 
3182 static void
ecore_evas_tick_end(Ecore_Evas * ee)3183 ecore_evas_tick_end(Ecore_Evas *ee)
3184 {
3185    if ((--ee->animator_count) > 0) return;
3186 
3187    if (ee->manual_render) return;
3188 
3189    ee->engine.func->fn_animator_unregister(ee);
3190 }
3191 
3192 // Need all possible tick to tick for animator fallback as we don't
3193 // know if a window is the source of animator
3194 static void
_ecore_evas_custom_tick_begin(void * data EINA_UNUSED)3195 _ecore_evas_custom_tick_begin(void *data EINA_UNUSED)
3196 {
3197    Ecore_Evas *ee;
3198 
3199    EINA_INLIST_FOREACH(ecore_evases, ee)
3200      if (!ee->deleted &&
3201          ee->engine.func->fn_animator_register &&
3202          ee->engine.func->fn_animator_unregister)
3203        ecore_evas_tick_begin(ee);
3204 }
3205 
3206 static void
_ecore_evas_custom_tick_end(void * data EINA_UNUSED)3207 _ecore_evas_custom_tick_end(void *data EINA_UNUSED)
3208 {
3209    Ecore_Evas *ee;
3210 
3211    EINA_INLIST_FOREACH(ecore_evases, ee)
3212      if (!ee->deleted &&
3213          ee->engine.func->fn_animator_register &&
3214          ee->engine.func->fn_animator_unregister)
3215        ecore_evas_tick_end(ee);
3216 }
3217 
3218 static void
_ecore_evas_tick_source_find(void)3219 _ecore_evas_tick_source_find(void)
3220 {
3221    Ecore_Evas *ee;
3222    Eina_Bool source = EINA_FALSE;
3223    Eina_Bool have_x = EINA_FALSE;
3224 
3225    // Check if we do have a potential tick source for legacy
3226    EINA_INLIST_FOREACH(ecore_evases, ee)
3227      {
3228         if (!ee->deleted)
3229           {
3230              if ((ee->engine.func->fn_animator_register) &&
3231                  (ee->engine.func->fn_animator_unregister))
3232                {
3233                   source = EINA_TRUE;
3234                }
3235              if (ee->driver)
3236                {
3237                   if ((!strcmp(ee->driver, "software_x11")) ||
3238                       (!strcmp(ee->driver, "opengl_x11")))
3239                     have_x = EINA_TRUE;
3240                }
3241           }
3242      }
3243 
3244    // If just one source require fallback, we can't be sure that
3245    // we are not running enlightenment and that this source might
3246    // actually be the true tick source of all other window. In
3247    // that scenario, we have to forcefully fallback.
3248    EINA_INLIST_FOREACH(ecore_evases, ee)
3249      if (!ee->deleted &&
3250          (!ee->engine.func->fn_animator_register ||
3251           !ee->engine.func->fn_animator_unregister))
3252        {
3253           source = EINA_FALSE;
3254           break;
3255        }
3256 
3257    if (!source)
3258      {
3259         if (!have_x)
3260           {
3261              ecore_animator_custom_source_tick_begin_callback_set(NULL, NULL);
3262              ecore_animator_custom_source_tick_end_callback_set(NULL, NULL);
3263              ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER);
3264           }
3265      }
3266    else
3267      {
3268         // Source set will trigger the previous tick end registered and then the new begin.
3269         // As we don't what was in behind, better first begin and end after source is set.
3270         ecore_animator_custom_source_tick_begin_callback_set(_ecore_evas_custom_tick_begin, NULL);
3271         ecore_animator_custom_source_tick_end_callback_set(_ecore_evas_custom_tick_end, NULL);
3272         ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_CUSTOM);
3273     }
3274 }
3275 
3276 static Eina_Bool
_ecore_evas_animator_fallback(void * data)3277 _ecore_evas_animator_fallback(void *data)
3278 {
3279    ecore_evas_animator_tick(data, NULL, ecore_loop_time_get());
3280    return EINA_TRUE;
3281 }
3282 
3283 static void
_ticking_start(Ecore_Evas * ee)3284 _ticking_start(Ecore_Evas *ee)
3285 {
3286   if (!ee->animator_count)
3287     INF("Setting up animator for %p from '%s' with title '%s'.", ee->evas, ee->driver, ee->prop.title);
3288 
3289   if (ee->engine.func->fn_animator_register &&
3290       ee->engine.func->fn_animator_unregister)
3291      {
3292         // Backend support per window vsync
3293         ecore_evas_tick_begin(ee);
3294      }
3295   else
3296     {
3297        // Backend doesn't support per window vsync, fallback to generic support
3298        if (ee->animator_count++ > 0) return;
3299        if (!ee->anim)
3300          {
3301             ee->anim = ecore_animator_add(_ecore_evas_animator_fallback, ee);
3302          }
3303     }
3304 }
3305 
3306 static void
_ticking_stop(Ecore_Evas * ee)3307 _ticking_stop(Ecore_Evas *ee)
3308 {
3309    if (ee->animator_count == 1)
3310       INF("Unsetting up animator for %p from '%s' titled '%s'.", ee->evas, ee->driver, ee->prop.title);
3311 
3312    if (ee->engine.func->fn_animator_register &&
3313        ee->engine.func->fn_animator_unregister)
3314      {
3315         // Backend support per window vsync
3316         ecore_evas_tick_end(ee);
3317      }
3318    else
3319      {
3320         // Backend doesn't support per window vsync, fallback to generic support
3321         if (--ee->animator_count > 0) return;
3322         if (ee->anim)
3323           {
3324              ecore_animator_del(ee->anim);
3325              ee->anim = NULL;
3326           }
3327      }
3328 }
3329 
3330 static void
_check_animator_event_catcher_add(void * data,const Efl_Event * event)3331 _check_animator_event_catcher_add(void *data, const Efl_Event *event)
3332 {
3333    const Efl_Callback_Array_Item_Full *array = event->info;
3334    Ecore_Evas *ee = data;
3335    int i;
3336 
3337    for (i = 0; array[i].desc != NULL; i++)
3338      {
3339         if (array[i].desc == EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK)
3340           {
3341              _ticking_start(ee);
3342 
3343              // No need to walk more than once per array as you can not del
3344              // a partial array
3345              return;
3346           }
3347      }
3348 }
3349 
3350 static void
_check_animator_event_catcher_del(void * data,const Efl_Event * event)3351 _check_animator_event_catcher_del(void *data, const Efl_Event *event)
3352 {
3353    const Efl_Callback_Array_Item_Full *array = event->info;
3354    Ecore_Evas *ee = data;
3355    int i;
3356 
3357    for (i = 0; array[i].desc != NULL; i++)
3358      {
3359         if (array[i].desc == EFL_CANVAS_OBJECT_EVENT_ANIMATOR_TICK)
3360           {
3361              _ticking_stop(ee);
3362              return;
3363           }
3364      }
3365 }
3366 
3367 EFL_CALLBACKS_ARRAY_DEFINE(animator_watch,
3368                           { EFL_EVENT_CALLBACK_ADD, _check_animator_event_catcher_add },
3369                           { EFL_EVENT_CALLBACK_DEL, _check_animator_event_catcher_del });
3370 
3371 EAPI void
_ecore_evas_register_animators(Ecore_Evas * ee)3372 _ecore_evas_register_animators(Ecore_Evas *ee)
3373 {
3374    efl_event_callback_array_add(ee->evas, animator_watch(), ee);
3375 }
3376 
3377 EAPI void
_ecore_evas_register(Ecore_Evas * ee)3378 _ecore_evas_register(Ecore_Evas *ee)
3379 {
3380    if (ee->registered) return;
3381 
3382    ee->registered = 1;
3383    ecore_evases = (Ecore_Evas *)eina_inlist_prepend
3384      (EINA_INLIST_GET(ecore_evases), EINA_INLIST_GET(ee));
3385 
3386    _ecore_evas_register_animators(ee);
3387 
3388    _ecore_evas_tick_source_find();
3389    if (_ecore_evas_render_sync) ee->first_frame = EINA_TRUE;
3390    if (!ee->engine.func->fn_render)
3391      evas_event_callback_priority_add(ee->evas, EVAS_CALLBACK_RENDER_POST, EVAS_CALLBACK_PRIORITY_AFTER,
3392                                       _evas_evas_buffer_rendered, ee);
3393 }
3394 
3395 EAPI void
_ecore_evas_subregister(Ecore_Evas * ee_target,Ecore_Evas * ee)3396 _ecore_evas_subregister(Ecore_Evas *ee_target, Ecore_Evas *ee)
3397 {
3398    ee_target->sub_ecore_evas = eina_list_append(ee_target->sub_ecore_evas, ee);
3399 
3400    if (!ee->evas) return;
3401 
3402    _ecore_evas_register_animators(ee);
3403 
3404    if (!ee->engine.func->fn_render)
3405      evas_event_callback_priority_add(ee->evas, EVAS_CALLBACK_RENDER_POST, EVAS_CALLBACK_PRIORITY_AFTER,
3406                                       _evas_evas_buffer_rendered, ee);
3407 }
3408 
3409 EAPI void
_ecore_evas_ref(Ecore_Evas * ee)3410 _ecore_evas_ref(Ecore_Evas *ee)
3411 {
3412    ee->refcount++;
3413 }
3414 
3415 EAPI void
_ecore_evas_unref(Ecore_Evas * ee)3416 _ecore_evas_unref(Ecore_Evas *ee)
3417 {
3418    ee->refcount--;
3419    if (ee->refcount == 0)
3420      {
3421         if (ee->deleted) _ecore_evas_free(ee);
3422      }
3423    else if (ee->refcount < -1)
3424      ERR("Ecore_Evas %p->refcount=%d < 0", ee, ee->refcount);
3425 }
3426 
3427 static Eina_Bool
_ecore_evas_vnc_stop(Ecore_Evas * ee)3428 _ecore_evas_vnc_stop(Ecore_Evas *ee)
3429 {
3430    Evas_Object *obj;
3431    Eina_List *l;
3432 
3433    EINA_LIST_FOREACH(ee->vnc_server, l, obj)
3434      evas_object_del(obj);
3435 
3436    return EINA_TRUE;
3437 }
3438 
3439 EAPI void
_ecore_evas_free(Ecore_Evas * ee)3440 _ecore_evas_free(Ecore_Evas *ee)
3441 {
3442    Efl_Input_Device *dev;
3443    Ecore_Evas_Interface *iface;
3444 
3445    if (ee->self_del)
3446      {
3447         efl_event_callback_del(ee->evas, EFL_EVENT_INVALIDATE, _ecore_evas_event_del, ee);
3448         ee->self_del = EINA_FALSE;
3449      }
3450 
3451    ee->deleted = EINA_TRUE;
3452    if (ee->refcount > 0) return;
3453 
3454    // Stop all vsync first
3455    if (ee->animator_count > 0 &&
3456        ee->engine.func->fn_animator_register &&
3457        ee->engine.func->fn_animator_unregister)
3458      {
3459         // Backend support per window vsync
3460         ee->engine.func->fn_animator_unregister(ee);
3461         _ecore_evas_tick_source_find();
3462      }
3463    ee->animator_count = 0;
3464 
3465    /* not present in extn engine */
3466    if (ee->evas)
3467      {
3468         efl_event_callback_array_del(ee->evas, animator_watch(), ee);
3469         efl_event_callback_array_del(ee->evas, _ecore_evas_device_cbs(), ee);
3470      }
3471    if (ee->anim)
3472      ecore_animator_del(ee->anim);
3473    ee->anim = NULL;
3474 
3475    if (ee->func.fn_pre_free) ee->func.fn_pre_free(ee);
3476    if (ee->vnc_server) _ecore_evas_vnc_stop(ee);
3477    while (ee->sub_ecore_evas)
3478      {
3479         _ecore_evas_free(ee->sub_ecore_evas->data);
3480      }
3481    EINA_LIST_FREE(ee->prop.focused_by, dev)
3482      {
3483         efl_event_callback_del(dev, EFL_EVENT_DEL,
3484                                _ecore_evas_device_del_cb, ee);
3485      }
3486    EINA_LIST_FREE(ee->mice_in, dev)
3487      {
3488         efl_event_callback_del(dev, EFL_EVENT_DEL,
3489                                _ecore_evas_mouse_del_cb, ee);
3490      }
3491    if (ee->data) eina_hash_free(ee->data);
3492    ee->data = NULL;
3493    free(ee->name);
3494    ee->name = NULL;
3495    free(ee->prop.title);
3496    ee->prop.title = NULL;
3497    free(ee->prop.name);
3498    ee->prop.name = NULL;
3499    free(ee->prop.clas);
3500    ee->prop.clas = NULL;
3501    _ecore_evas_window_profile_free(ee);
3502    ee->prop.profile.name = NULL;
3503    _ecore_evas_window_available_profiles_free(ee);
3504    ee->prop.profile.available_list = NULL;
3505    free(ee->prop.wm_rot.available_rots);
3506    ee->prop.wm_rot.available_rots = NULL;
3507    if (ee->prop.wm_rot.manual_mode.timer)
3508      ecore_timer_del(ee->prop.wm_rot.manual_mode.timer);
3509    _ecore_evas_aux_hint_free(ee);
3510    ee->prop.wm_rot.manual_mode.timer = NULL;
3511    eina_hash_free(ee->prop.cursors);
3512    ee->prop.cursors = NULL;
3513    if (!ee->evas_dying)
3514      {
3515         ee->evas_dying = EINA_TRUE;
3516         evas_free(ee->evas);
3517      }
3518    ee->evas = NULL;
3519    ECORE_MAGIC_SET(ee, ECORE_MAGIC_NONE);
3520    ee->driver = NULL;
3521    if (ee->engine.idle_flush_timer)
3522      ecore_timer_del(ee->engine.idle_flush_timer);
3523    ee->engine.idle_flush_timer = NULL;
3524    if (ee->engine.func->fn_free) ee->engine.func->fn_free(ee);
3525    if (ee->registered)
3526      {
3527         ecore_evases = (Ecore_Evas *)eina_inlist_remove
3528           (EINA_INLIST_GET(ecore_evases), EINA_INLIST_GET(ee));
3529      }
3530 
3531    EINA_LIST_FREE(ee->engine.ifaces, iface)
3532      free(iface);
3533 
3534    ee->engine.ifaces = NULL;
3535 
3536    if (ee->fallback_interface)
3537      fallback_selection_shutdown(ee);
3538    free(ee);
3539 }
3540 
3541 static Eina_Bool
_ecore_evas_cb_idle_flush(void * data)3542 _ecore_evas_cb_idle_flush(void *data)
3543 {
3544    Ecore_Evas *ee = data;
3545 
3546    ee->engine.idle_flush_timer = NULL;
3547    evas_render_idle_flush(ee->evas);
3548    return ECORE_CALLBACK_CANCEL;
3549 }
3550 
3551 EAPI void
_ecore_evas_idle_timeout_update(Ecore_Evas * ee)3552 _ecore_evas_idle_timeout_update(Ecore_Evas *ee)
3553 {
3554    if (ee->engine.idle_flush_timer)
3555      ecore_timer_del(ee->engine.idle_flush_timer);
3556    ee->engine.idle_flush_timer =
3557      ecore_timer_loop_add(IDLE_FLUSH_TIME, _ecore_evas_cb_idle_flush, ee);
3558 }
3559 
3560 static void
_ecore_evas_mouse_move_process_internal(Ecore_Evas * ee,Efl_Input_Device * pointer,int x,int y,unsigned int timestamp,Eina_Bool feed)3561 _ecore_evas_mouse_move_process_internal(Ecore_Evas *ee,
3562                                         Efl_Input_Device *pointer,
3563                                         int x, int y, unsigned int timestamp,
3564                                         Eina_Bool feed)
3565 {
3566    Efl_Input_Pointer_Data *ev;
3567    Efl_Input_Pointer *evt;
3568    Eina_Bool send_event = EINA_TRUE;
3569    Ecore_Evas_Cursor *cursor;
3570    Eo *seat;
3571    int fx, fy, fw, fh, evt_x, evt_y;
3572 
3573    evas_output_framespace_get(ee->evas, &fx, &fy, &fw, &fh);
3574 
3575    if (pointer)
3576      {
3577         if (efl_input_device_type_get(pointer) != EFL_INPUT_DEVICE_TYPE_SEAT)
3578           seat = efl_input_device_seat_get(pointer);
3579         else seat = pointer;
3580      }
3581    else
3582      {
3583         pointer = evas_default_device_get(ee->evas, EVAS_DEVICE_CLASS_MOUSE);
3584         seat = efl_input_device_seat_get(pointer);
3585      }
3586    if (efl_input_device_type_get(seat) != EFL_INPUT_DEVICE_TYPE_SEAT)
3587      {
3588         ERR("Could not find seat");
3589         return;
3590      }
3591    cursor = eina_hash_find(ee->prop.cursors, &seat);
3592    if (cursor)
3593      {
3594         cursor->pos_x = x;
3595         cursor->pos_y = y;
3596         if (cursor->object)
3597           {
3598              evas_object_show(cursor->object);
3599              if (ee->rotation == 0)
3600                evas_object_move(cursor->object,
3601                                 x - fx - cursor->hot.x,
3602                                 y - fy - cursor->hot.y);
3603              else if (ee->rotation == 90)
3604                evas_object_move(cursor->object,
3605                                 ee->h + fw - y - fx - 1 - cursor->hot.x,
3606                                 x - fy - cursor->hot.y);
3607              else if (ee->rotation == 180)
3608                evas_object_move(cursor->object,
3609                                 ee->w + fw - x - fx - 1 - cursor->hot.x,
3610                                 ee->h + fh - y - fy - 1 - cursor->hot.y);
3611              else if (ee->rotation == 270)
3612                evas_object_move(cursor->object,
3613                                 y - fx - cursor->hot.x,
3614                                 ee->w + fh - x - fy - 1 - cursor->hot.y);
3615           }
3616      }
3617 
3618    if (!feed) return;
3619    if (ee->rotation == 0)
3620      {
3621         evt_x = x - fx;
3622         evt_y = y - fy;
3623      }
3624    else if (ee->rotation == 90)
3625      {
3626         evt_x = ee->h + fw - y - 1;
3627         evt_y = x;
3628      }
3629    else if (ee->rotation == 180)
3630      {
3631         evt_x = ee->w + fw - x - 1;
3632         evt_y = ee->h + fh - y - 1;
3633      }
3634    else if (ee->rotation == 270)
3635      {
3636         evt_x = y;
3637         evt_y = ee->w + fh - x - 1;
3638      }
3639    else
3640      send_event = EINA_FALSE;
3641 
3642    if (!send_event) return;
3643 
3644    evt = efl_input_pointer_instance_get( ee->evas, (void **) &ev);
3645    if (!evt) return;
3646 
3647    ev->action = EFL_POINTER_ACTION_MOVE;
3648    ev->device = efl_ref(pointer);
3649    ev->timestamp = timestamp;
3650    ev->cur.x = evt_x;
3651    ev->cur.y = evt_y;
3652    efl_input_pointer_finalize(evt);
3653 
3654    efl_event_callback_legacy_call(ee->evas,
3655                                   _event_description_get(ev->action), evt);
3656    efl_unref(evt);
3657 }
3658 
3659 EAPI void
_ecore_evas_mouse_move_process(Ecore_Evas * ee,int x,int y,unsigned int timestamp)3660 _ecore_evas_mouse_move_process(Ecore_Evas *ee, int x, int y, unsigned int timestamp)
3661 {
3662    _ecore_evas_mouse_move_process_internal(ee, NULL, x, y, timestamp,
3663                                            EINA_TRUE);
3664 }
3665 
3666 EAPI void
_ecore_evas_mouse_device_move_process(Ecore_Evas * ee,Efl_Input_Device * pointer,int x,int y,unsigned int timestamp)3667 _ecore_evas_mouse_device_move_process(Ecore_Evas *ee, Efl_Input_Device *pointer,
3668                                       int x, int y, unsigned int timestamp)
3669 {
3670    _ecore_evas_mouse_move_process_internal(ee, pointer, x, y, timestamp,
3671                                            EINA_TRUE);
3672 }
3673 
3674 EAPI void
_ecore_evas_mouse_multi_move_process(Ecore_Evas * ee,int device,int x,int y,double radius,double radius_x,double radius_y,double pressure,double angle,double mx,double my,unsigned int timestamp)3675 _ecore_evas_mouse_multi_move_process(Ecore_Evas *ee, int device,
3676                                      int x, int y,
3677                                      double radius,
3678                                      double radius_x, double radius_y,
3679                                      double pressure,
3680                                      double angle,
3681                                      double mx, double my,
3682                                      unsigned int timestamp)
3683 {
3684    if (ee->rotation == 0)
3685      evas_event_input_multi_move(ee->evas, device,
3686                                  x, y,
3687                                  radius,
3688                                  radius_x, radius_y,
3689                                  pressure,
3690                                  angle - ee->rotation,
3691                                  mx, my,
3692                                  timestamp, NULL);
3693    else if (ee->rotation == 90)
3694      evas_event_input_multi_move(ee->evas, device,
3695                                  ee->h - y - 1, x,
3696                                  radius,
3697                                  radius_y, radius_x,
3698                                  pressure,
3699                                  angle - ee->rotation,
3700                                  ee->h - my - 1, mx,
3701                                  timestamp, NULL);
3702    else if (ee->rotation == 180)
3703      evas_event_input_multi_move(ee->evas, device,
3704                                  ee->w - x - 1, ee->h - y - 1,
3705                                  radius,
3706                                  radius_x, radius_y,
3707                                  pressure,
3708                                  angle - ee->rotation,
3709                                  ee->w - mx - 1, ee->h - my - 1,
3710                                  timestamp, NULL);
3711    else if (ee->rotation == 270)
3712      evas_event_input_multi_move(ee->evas, device,
3713                                  y, ee->w - x - 1,
3714                                  radius,
3715                                  radius_y, radius_x,
3716                                  pressure,
3717                                  angle - ee->rotation,
3718                                  my, ee->w - mx - 1,
3719                                  timestamp, NULL);
3720 }
3721 
3722 EAPI void
_ecore_evas_mouse_multi_down_process(Ecore_Evas * ee,int device,int x,int y,double radius,double radius_x,double radius_y,double pressure,double angle,double mx,double my,Evas_Button_Flags flags,unsigned int timestamp)3723 _ecore_evas_mouse_multi_down_process(Ecore_Evas *ee, int device,
3724                                      int x, int y,
3725                                      double radius,
3726                                      double radius_x, double radius_y,
3727                                      double pressure,
3728                                      double angle,
3729                                      double mx, double my,
3730                                      Evas_Button_Flags flags,
3731                                      unsigned int timestamp)
3732 {
3733    if (ee->rotation == 0)
3734      evas_event_input_multi_down(ee->evas, device,
3735                                  x, y,
3736                                  radius,
3737                                  radius_x, radius_y,
3738                                  pressure,
3739                                  angle - ee->rotation,
3740                                  mx, my,
3741                                  flags, timestamp, NULL);
3742    else if (ee->rotation == 90)
3743      evas_event_input_multi_down(ee->evas, device,
3744                                  ee->h - y - 1, x,
3745                                  radius,
3746                                  radius_y, radius_x,
3747                                  pressure,
3748                                  angle - ee->rotation,
3749                                  ee->h - my - 1, mx,
3750                                  flags, timestamp, NULL);
3751    else if (ee->rotation == 180)
3752      evas_event_input_multi_down(ee->evas, device,
3753                                  ee->w - x - 1, ee->h - y - 1,
3754                                  radius,
3755                                  radius_x, radius_y,
3756                                  pressure,
3757                                  angle - ee->rotation,
3758                                  ee->w - mx - 1, ee->h - my - 1,
3759                                  flags, timestamp, NULL);
3760    else if (ee->rotation == 270)
3761      evas_event_input_multi_down(ee->evas, device,
3762                                  y, ee->w - x - 1,
3763                                  radius,
3764                                  radius_y, radius_x,
3765                                  pressure,
3766                                  angle - ee->rotation,
3767                                  my, ee->w - mx - 1,
3768                                  flags, timestamp, NULL);
3769 }
3770 
3771 EAPI void
_ecore_evas_mouse_multi_up_process(Ecore_Evas * ee,int device,int x,int y,double radius,double radius_x,double radius_y,double pressure,double angle,double mx,double my,Evas_Button_Flags flags,unsigned int timestamp)3772 _ecore_evas_mouse_multi_up_process(Ecore_Evas *ee, int device,
3773                                    int x, int y,
3774                                    double radius,
3775                                    double radius_x, double radius_y,
3776                                    double pressure,
3777                                    double angle,
3778                                    double mx, double my,
3779                                    Evas_Button_Flags flags,
3780                                    unsigned int timestamp)
3781 {
3782    if (ee->rotation == 0)
3783      evas_event_input_multi_up(ee->evas, device,
3784                                x, y,
3785                                radius,
3786                                radius_x, radius_y,
3787                                pressure,
3788                                angle - ee->rotation,
3789                                mx, my,
3790                                flags, timestamp, NULL);
3791    else if (ee->rotation == 90)
3792      evas_event_input_multi_up(ee->evas, device,
3793                                ee->h - y - 1, x,
3794                                radius,
3795                                radius_y, radius_x,
3796                                pressure,
3797                                angle - ee->rotation,
3798                                ee->h - my - 1, mx,
3799                                flags, timestamp, NULL);
3800    else if (ee->rotation == 180)
3801      evas_event_input_multi_up(ee->evas, device,
3802                                ee->w - x - 1, ee->h - y - 1,
3803                                radius,
3804                                radius_x, radius_y,
3805                                pressure,
3806                                angle - ee->rotation,
3807                                ee->w - mx - 1, ee->h - my - 1,
3808                                flags, timestamp, NULL);
3809    else if (ee->rotation == 270)
3810      evas_event_input_multi_up(ee->evas, device,
3811                                y, ee->w - x - 1,
3812                                radius,
3813                                radius_y, radius_x,
3814                                pressure,
3815                                angle - ee->rotation,
3816                                my, ee->w - mx - 1,
3817                                flags, timestamp, NULL);
3818 }
3819 
3820 EAPI void
_ecore_evas_window_profile_free(Ecore_Evas * ee)3821 _ecore_evas_window_profile_free(Ecore_Evas *ee)
3822 {
3823    if (ee->prop.profile.name)
3824      eina_stringshare_del(ee->prop.profile.name);
3825 }
3826 
3827 EAPI void
_ecore_evas_window_available_profiles_free(Ecore_Evas * ee)3828 _ecore_evas_window_available_profiles_free(Ecore_Evas *ee)
3829 {
3830    if (ee->prop.profile.available_list)
3831      {
3832         int i;
3833         for (i = 0; i < ee->prop.profile.count; i++)
3834           {
3835              if (ee->prop.profile.available_list[i])
3836                {
3837                   eina_stringshare_del(ee->prop.profile.available_list[i]);
3838                   ee->prop.profile.available_list[i] = NULL;
3839                }
3840           }
3841         free(ee->prop.profile.available_list);
3842      }
3843 }
3844 
3845 EAPI Eina_List *
ecore_evas_ecore_evas_list_get(void)3846 ecore_evas_ecore_evas_list_get(void)
3847 {
3848    Ecore_Evas *ee;
3849    Eina_List *l = NULL;
3850 
3851    EINA_INLIST_FOREACH(ecore_evases, ee)
3852      {
3853         l = eina_list_append(l, ee);
3854      }
3855 
3856    return l;
3857 }
3858 
3859 EAPI Eina_List *
ecore_evas_sub_ecore_evas_list_get(const Ecore_Evas * ee)3860 ecore_evas_sub_ecore_evas_list_get(const Ecore_Evas *ee)
3861 {
3862    ECORE_EVAS_CHECK(ee, NULL);
3863    return ee->sub_ecore_evas;
3864 }
3865 
3866 EAPI void
ecore_evas_input_event_register(Ecore_Evas * ee)3867 ecore_evas_input_event_register(Ecore_Evas *ee)
3868 {
3869    ecore_evas_done(ee, EINA_FALSE);
3870 }
3871 
3872 EAPI void
ecore_evas_input_event_unregister(Ecore_Evas * ee)3873 ecore_evas_input_event_unregister(Ecore_Evas *ee)
3874 {
3875    ecore_event_window_unregister(ee->prop.window);
3876 }
3877 
3878 EAPI Eina_Strbuf *
_ecore_evas_aux_hints_string_get(Ecore_Evas * ee)3879 _ecore_evas_aux_hints_string_get(Ecore_Evas *ee)
3880 {
3881    Eina_Strbuf *buf = eina_strbuf_new();
3882    if (buf)
3883      {
3884         if (eina_list_count(ee->prop.aux_hint.hints) > 0)
3885           {
3886              Eina_List *l;
3887              Ecore_Evas_Aux_Hint *aux;
3888              int i = 0;
3889 
3890              EINA_LIST_FOREACH(ee->prop.aux_hint.hints, l, aux)
3891                {
3892                   /* add delimiter */
3893                   if (i > 0) eina_strbuf_append_char(buf, ',');
3894                   eina_strbuf_append_printf(buf, "%d:%s:%s", aux->id, aux->hint, aux->val);
3895                   i++;
3896                }
3897           }
3898      }
3899    return buf;
3900 }
3901 
3902 void
_ecore_evas_aux_hint_free(Ecore_Evas * ee)3903 _ecore_evas_aux_hint_free(Ecore_Evas *ee)
3904 {
3905    char *hint;
3906    EINA_LIST_FREE(ee->prop.aux_hint.supported_list, hint)
3907      {
3908         eina_stringshare_del(hint);
3909      }
3910 
3911    Ecore_Evas_Aux_Hint *aux;
3912    EINA_LIST_FREE(ee->prop.aux_hint.hints, aux)
3913      {
3914         eina_stringshare_del(aux->hint);
3915         eina_stringshare_del(aux->val);
3916         free(aux);
3917      }
3918 }
3919 
3920 EAPI Ecore_Evas *
ecore_evas_fb_new(const char * disp_name,int rotation,int w,int h)3921 ecore_evas_fb_new(const char *disp_name, int rotation, int w, int h)
3922 {
3923    Ecore_Evas *ee;
3924    Ecore_Evas *(*new)(const char *, int, int, int);
3925    Eina_Module *m = _ecore_evas_engine_load("fb");
3926    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
3927 
3928    new = eina_module_symbol_get(m, "ecore_evas_fb_new_internal");
3929    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
3930 
3931    ee = new(disp_name, rotation, w, h);
3932    if (!_ecore_evas_cursors_init(ee))
3933      {
3934         ecore_evas_free(ee);
3935         return NULL;
3936      }
3937    return ee;
3938 }
3939 
3940 EAPI Ecore_Evas *
ecore_evas_software_x11_new(const char * disp_name,Ecore_X_Window parent,int x,int y,int w,int h)3941 ecore_evas_software_x11_new(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h)
3942 {
3943    Ecore_Evas *ee;
3944    Ecore_Evas *(*new)(const char *, Ecore_X_Window, int, int, int, int);
3945    Eina_Module *m = _ecore_evas_engine_load("x");
3946    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
3947 
3948    new = eina_module_symbol_get(m, "ecore_evas_software_x11_new_internal");
3949    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
3950 
3951    ee = new(disp_name, parent, x, y, w, h);
3952    if (!_ecore_evas_cursors_init(ee))
3953      {
3954         ecore_evas_free(ee);
3955         return NULL;
3956      }
3957    return ee;
3958 }
3959 
3960 EAPI Ecore_X_Window
ecore_evas_software_x11_window_get(const Ecore_Evas * ee)3961 ecore_evas_software_x11_window_get(const Ecore_Evas *ee)
3962 {
3963    Ecore_Evas_Interface_Software_X11 *iface;
3964    iface = (Ecore_Evas_Interface_Software_X11 *)_ecore_evas_interface_get_internal(ee, "software_x11", 0);
3965    if (!iface) return 0;
3966 
3967    return iface->window_get(ee);
3968 }
3969 
3970 EAPI void
ecore_evas_software_x11_direct_resize_set(Ecore_Evas * ee,Eina_Bool on)3971 ecore_evas_software_x11_direct_resize_set(Ecore_Evas *ee, Eina_Bool on)
3972 {
3973    Ecore_Evas_Interface_Software_X11 *iface;
3974    iface = (Ecore_Evas_Interface_Software_X11 *)_ecore_evas_interface_get(ee, "software_x11");
3975    EINA_SAFETY_ON_NULL_RETURN(iface);
3976 
3977    iface->resize_set(ee, on);
3978 }
3979 
3980 EAPI Eina_Bool
ecore_evas_software_x11_direct_resize_get(const Ecore_Evas * ee)3981 ecore_evas_software_x11_direct_resize_get(const Ecore_Evas *ee)
3982 {
3983    Ecore_Evas_Interface_Software_X11 *iface;
3984    iface = (Ecore_Evas_Interface_Software_X11 *)_ecore_evas_interface_get(ee, "software_x11");
3985    EINA_SAFETY_ON_NULL_RETURN_VAL(iface, EINA_FALSE);
3986 
3987    return iface->resize_get(ee);
3988 }
3989 
3990 EAPI void
ecore_evas_software_x11_extra_event_window_add(Ecore_Evas * ee,Ecore_X_Window win)3991 ecore_evas_software_x11_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win)
3992 {
3993    Ecore_Evas_Interface_Software_X11 *iface;
3994    iface = (Ecore_Evas_Interface_Software_X11 *)_ecore_evas_interface_get(ee, "software_x11");
3995    EINA_SAFETY_ON_NULL_RETURN(iface);
3996 
3997    iface->extra_event_window_add(ee, win);
3998 }
3999 
4000 EAPI Ecore_Evas *
ecore_evas_software_x11_pixmap_new(const char * disp_name,Ecore_X_Window parent,int x,int y,int w,int h)4001 ecore_evas_software_x11_pixmap_new(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h)
4002 {
4003    Ecore_Evas *ee;
4004    Ecore_Evas *(*new)(const char *, Ecore_X_Window, int, int, int, int);
4005    Eina_Module *m = _ecore_evas_engine_load("x");
4006    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
4007 
4008    new = eina_module_symbol_get(m, "ecore_evas_software_x11_pixmap_new_internal");
4009    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
4010 
4011    ee = new(disp_name, parent, x, y, w, h);
4012    if (!_ecore_evas_cursors_init(ee))
4013      {
4014         ecore_evas_free(ee);
4015         return NULL;
4016      }
4017    return ee;
4018 
4019 }
4020 
4021 EAPI Ecore_X_Pixmap
ecore_evas_software_x11_pixmap_get(const Ecore_Evas * ee)4022 ecore_evas_software_x11_pixmap_get(const Ecore_Evas *ee)
4023 {
4024    Ecore_Evas_Interface_Software_X11 *iface;
4025    iface = (Ecore_Evas_Interface_Software_X11 *)_ecore_evas_interface_get(ee, "software_x11");
4026    EINA_SAFETY_ON_NULL_RETURN_VAL(iface, 0);
4027 
4028    if (iface->pixmap_get)
4029      return iface->pixmap_get(ee);
4030 
4031    return 0;
4032 }
4033 
4034 EAPI Ecore_Evas *
ecore_evas_gl_x11_new(const char * disp_name,Ecore_X_Window parent,int x,int y,int w,int h)4035 ecore_evas_gl_x11_new(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h)
4036 {
4037    Ecore_Evas *ee;
4038    Ecore_Evas *(*new)(const char *, Ecore_X_Window, int, int, int, int);
4039    Eina_Module *m = _ecore_evas_engine_load("x");
4040    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
4041 
4042    new = eina_module_symbol_get(m, "ecore_evas_gl_x11_new_internal");
4043    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
4044 
4045    ee = new(disp_name, parent, x, y, w, h);
4046    if (!_ecore_evas_cursors_init(ee))
4047      {
4048         ecore_evas_free(ee);
4049         return NULL;
4050      }
4051    return ee;
4052 
4053 }
4054 
4055 EAPI Ecore_Evas *
ecore_evas_gl_x11_options_new(const char * disp_name,Ecore_X_Window parent,int x,int y,int w,int h,const int * opt)4056 ecore_evas_gl_x11_options_new(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h, const int *opt)
4057 {
4058    Ecore_Evas *ee;
4059    Ecore_Evas *(*new)(const char *, Ecore_X_Window, int, int, int, int, const int*);
4060    Eina_Module *m = _ecore_evas_engine_load("x");
4061    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
4062 
4063    new = eina_module_symbol_get(m, "ecore_evas_gl_x11_options_new_internal");
4064    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
4065 
4066    ee = new(disp_name, parent, x, y, w, h, opt);
4067    if (!_ecore_evas_cursors_init(ee))
4068      {
4069         ecore_evas_free(ee);
4070         return NULL;
4071      }
4072    return ee;
4073 }
4074 
4075 EAPI Ecore_Evas *
ecore_evas_gl_x11_pixmap_new(const char * disp_name,Ecore_X_Window parent,int x,int y,int w,int h)4076 ecore_evas_gl_x11_pixmap_new(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h)
4077 {
4078    Ecore_Evas *ee;
4079    Ecore_Evas *(*new)(const char *, Ecore_X_Window, int, int, int, int);
4080    Eina_Module *m = _ecore_evas_engine_load("x");
4081    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
4082 
4083    new = eina_module_symbol_get(m, "ecore_evas_gl_x11_pixmap_new_internal");
4084    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
4085 
4086    ee = new(disp_name, parent, x, y, w, h);
4087    if (!_ecore_evas_cursors_init(ee))
4088      {
4089         ecore_evas_free(ee);
4090         return NULL;
4091      }
4092    return ee;
4093 
4094 }
4095 
4096 EAPI Ecore_X_Pixmap
ecore_evas_gl_x11_pixmap_get(const Ecore_Evas * ee)4097 ecore_evas_gl_x11_pixmap_get(const Ecore_Evas *ee)
4098 {
4099    Ecore_Evas_Interface_Gl_X11 *iface;
4100    iface = (Ecore_Evas_Interface_Gl_X11 *)_ecore_evas_interface_get(ee, "gl_x11");
4101    EINA_SAFETY_ON_NULL_RETURN_VAL(iface, 0);
4102 
4103    if (iface->pixmap_get)
4104      return iface->pixmap_get(ee);
4105 
4106    return 0;
4107 }
4108 
4109 EAPI Ecore_X_Window
ecore_evas_gl_x11_window_get(const Ecore_Evas * ee)4110 ecore_evas_gl_x11_window_get(const Ecore_Evas *ee)
4111 {
4112    Ecore_Evas_Interface_Gl_X11 *iface;
4113    iface = (Ecore_Evas_Interface_Gl_X11 *)_ecore_evas_interface_get_internal(ee, "gl_x11", 0);
4114    if (!iface) return 0;
4115 
4116    return iface->window_get(ee);
4117 }
4118 
4119 EAPI void
ecore_evas_gl_x11_direct_resize_set(Ecore_Evas * ee,Eina_Bool on)4120 ecore_evas_gl_x11_direct_resize_set(Ecore_Evas *ee, Eina_Bool on)
4121 {
4122    Ecore_Evas_Interface_Gl_X11 *iface;
4123    iface = (Ecore_Evas_Interface_Gl_X11 *)_ecore_evas_interface_get(ee, "gl_x11");
4124    EINA_SAFETY_ON_NULL_RETURN(iface);
4125 
4126    iface->resize_set(ee, on);
4127 }
4128 
4129 EAPI Eina_Bool
ecore_evas_gl_x11_direct_resize_get(const Ecore_Evas * ee)4130 ecore_evas_gl_x11_direct_resize_get(const Ecore_Evas *ee)
4131 {
4132    Ecore_Evas_Interface_Gl_X11 *iface;
4133    iface = (Ecore_Evas_Interface_Gl_X11 *)_ecore_evas_interface_get(ee, "gl_x11");
4134    EINA_SAFETY_ON_NULL_RETURN_VAL(iface, EINA_FALSE);
4135 
4136    return iface->resize_get(ee);
4137 }
4138 
4139 EAPI void
ecore_evas_gl_x11_extra_event_window_add(Ecore_Evas * ee,Ecore_X_Window win)4140 ecore_evas_gl_x11_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win)
4141 {
4142    Ecore_Evas_Interface_Gl_X11 *iface;
4143    iface = (Ecore_Evas_Interface_Gl_X11 *)_ecore_evas_interface_get(ee, "gl_x11");
4144    EINA_SAFETY_ON_NULL_RETURN(iface);
4145 
4146    iface->extra_event_window_add(ee, win);
4147 }
4148 
4149 EAPI void
ecore_evas_gl_x11_pre_post_swap_callback_set(const Ecore_Evas * ee,void * data,void (* pre_cb)(void * data,Evas * e),void (* post_cb)(void * data,Evas * e))4150 ecore_evas_gl_x11_pre_post_swap_callback_set(const Ecore_Evas *ee, void *data, void (*pre_cb) (void *data, Evas *e), void (*post_cb) (void *data, Evas *e))
4151 {
4152    Ecore_Evas_Interface_Gl_X11 *iface;
4153    iface = (Ecore_Evas_Interface_Gl_X11 *)_ecore_evas_interface_get(ee, "gl_x11");
4154    EINA_SAFETY_ON_NULL_RETURN(iface);
4155 
4156    iface->pre_post_swap_callback_set(ee, data, pre_cb, post_cb);
4157 }
4158 
4159 EAPI void
ecore_evas_x11_leader_set(Ecore_Evas * ee,Ecore_X_Window win)4160 ecore_evas_x11_leader_set(Ecore_Evas *ee, Ecore_X_Window win)
4161 {
4162    Ecore_Evas_Interface_X11 *iface;
4163    iface = (Ecore_Evas_Interface_X11 *)_ecore_evas_interface_get(ee, "x11");
4164    EINA_SAFETY_ON_NULL_RETURN(iface);
4165 
4166    iface->leader_set(ee, win);
4167 }
4168 
4169 EAPI Ecore_X_Window
ecore_evas_x11_leader_get(Ecore_Evas * ee)4170 ecore_evas_x11_leader_get(Ecore_Evas *ee)
4171 {
4172    Ecore_Evas_Interface_X11 *iface;
4173    iface = (Ecore_Evas_Interface_X11 *)_ecore_evas_interface_get(ee, "x11");
4174    EINA_SAFETY_ON_NULL_RETURN_VAL(iface, 0);
4175 
4176    return iface->leader_get(ee);
4177 }
4178 
4179 EAPI void
ecore_evas_x11_leader_default_set(Ecore_Evas * ee)4180 ecore_evas_x11_leader_default_set(Ecore_Evas *ee)
4181 {
4182    Ecore_Evas_Interface_X11 *iface;
4183    iface = (Ecore_Evas_Interface_X11 *)_ecore_evas_interface_get(ee, "x11");
4184    EINA_SAFETY_ON_NULL_RETURN(iface);
4185 
4186    iface->leader_default_set(ee);
4187 }
4188 
4189 EAPI void
ecore_evas_x11_shape_input_rectangle_set(Ecore_Evas * ee,int x,int y,int w,int h)4190 ecore_evas_x11_shape_input_rectangle_set(Ecore_Evas *ee, int x, int y, int w, int h)
4191 {
4192    Ecore_Evas_Interface_X11 *iface;
4193    iface = (Ecore_Evas_Interface_X11 *)_ecore_evas_interface_get(ee, "x11");
4194    EINA_SAFETY_ON_NULL_RETURN(iface);
4195 
4196    iface->shape_input_rectangle_set(ee, x, y, w, h);
4197 }
4198 
4199 EAPI void
ecore_evas_x11_shape_input_rectangle_add(Ecore_Evas * ee,int x,int y,int w,int h)4200 ecore_evas_x11_shape_input_rectangle_add(Ecore_Evas *ee, int x, int y, int w, int h)
4201 {
4202    Ecore_Evas_Interface_X11 *iface;
4203    iface = (Ecore_Evas_Interface_X11 *)_ecore_evas_interface_get(ee, "x11");
4204    EINA_SAFETY_ON_NULL_RETURN(iface);
4205 
4206    iface->shape_input_rectangle_add(ee, x, y, w, h);
4207 }
4208 
4209 EAPI void
ecore_evas_x11_shape_input_rectangle_subtract(Ecore_Evas * ee,int x,int y,int w,int h)4210 ecore_evas_x11_shape_input_rectangle_subtract(Ecore_Evas *ee, int x, int y, int w, int h)
4211 {
4212    Ecore_Evas_Interface_X11 *iface;
4213    iface = (Ecore_Evas_Interface_X11 *)_ecore_evas_interface_get(ee, "x11");
4214    EINA_SAFETY_ON_NULL_RETURN(iface);
4215 
4216    iface->shape_input_rectangle_subtract(ee, x, y, w, h);
4217 }
4218 
4219 EAPI void
ecore_evas_x11_shape_input_empty(Ecore_Evas * ee)4220 ecore_evas_x11_shape_input_empty(Ecore_Evas *ee)
4221 {
4222    Ecore_Evas_Interface_X11 *iface;
4223    iface = (Ecore_Evas_Interface_X11 *)_ecore_evas_interface_get(ee, "x11");
4224    EINA_SAFETY_ON_NULL_RETURN(iface);
4225 
4226    iface->shape_input_empty(ee);
4227 }
4228 
4229 EAPI void
ecore_evas_x11_shape_input_reset(Ecore_Evas * ee)4230 ecore_evas_x11_shape_input_reset(Ecore_Evas *ee)
4231 {
4232    Ecore_Evas_Interface_X11 *iface;
4233    iface = (Ecore_Evas_Interface_X11 *)_ecore_evas_interface_get(ee, "x11");
4234    EINA_SAFETY_ON_NULL_RETURN(iface);
4235 
4236    iface->shape_input_reset(ee);
4237 }
4238 
4239 EAPI void
ecore_evas_x11_shape_input_apply(Ecore_Evas * ee)4240 ecore_evas_x11_shape_input_apply(Ecore_Evas *ee)
4241 {
4242    Ecore_Evas_Interface_X11 *iface;
4243    iface = (Ecore_Evas_Interface_X11 *)_ecore_evas_interface_get(ee, "x11");
4244    EINA_SAFETY_ON_NULL_RETURN(iface);
4245 
4246    iface->shape_input_apply(ee);
4247 }
4248 
4249 EAPI Evas_Object *
ecore_evas_vnc_start(Ecore_Evas * ee,const char * addr,int port,Ecore_Evas_Vnc_Client_Accept_Cb accept_cb,Ecore_Evas_Vnc_Client_Disconnected_Cb disc_cb,void * data)4250 ecore_evas_vnc_start(Ecore_Evas *ee, const char *addr, int port,
4251                      Ecore_Evas_Vnc_Client_Accept_Cb accept_cb,
4252                      Ecore_Evas_Vnc_Client_Disconnected_Cb disc_cb,
4253                      void *data)
4254 {
4255    static Evas_Object *(*vnc_new)(Ecore_Evas *, int, const char *,
4256                                   Ecore_Evas_Vnc_Client_Accept_Cb,
4257                                   Ecore_Evas_Vnc_Client_Disconnected_Cb,
4258                                   void *) = NULL;
4259    Evas_Object *r;
4260 
4261    EINA_SAFETY_ON_NULL_RETURN_VAL(ee, NULL);
4262 
4263    if (!vnc_new)
4264      {
4265         Eina_Module *mod;
4266 
4267         mod = _ecore_evas_vnc_server_module_load();
4268         EINA_SAFETY_ON_NULL_RETURN_VAL(mod, NULL);
4269 
4270         vnc_new = eina_module_symbol_get(mod, "ecore_evas_vnc_server_new");
4271         EINA_SAFETY_ON_NULL_RETURN_VAL(vnc_new, NULL);
4272      }
4273 
4274    r = vnc_new(ee, port, addr, accept_cb, disc_cb, data);
4275    if (!r) return NULL;
4276 
4277    ee->vnc_server = eina_list_append(ee->vnc_server, r);
4278    return r;
4279 }
4280 
4281 EAPI Ecore_Evas *
ecore_evas_extn_socket_new(int w,int h)4282 ecore_evas_extn_socket_new(int w, int h)
4283 {
4284    Ecore_Evas *ee;
4285    Ecore_Evas *(*new)(int, int);
4286    Eina_Module *m = _ecore_evas_engine_load("extn");
4287    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
4288 
4289    new = eina_module_symbol_get(m, "ecore_evas_extn_socket_new_internal");
4290    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
4291 
4292    ee = new(w, h);
4293    if (!_ecore_evas_cursors_init(ee))
4294      {
4295         ecore_evas_free(ee);
4296         return NULL;
4297      }
4298    return ee;
4299 
4300 }
4301 
4302 EAPI Eina_Bool
ecore_evas_extn_socket_listen(Ecore_Evas * ee,const char * svcname,int svcnum,Eina_Bool svcsys)4303 ecore_evas_extn_socket_listen(Ecore_Evas *ee, const char *svcname, int svcnum, Eina_Bool svcsys)
4304 {
4305    Ecore_Evas_Interface_Extn *iface;
4306    iface = (Ecore_Evas_Interface_Extn *)_ecore_evas_interface_get(ee, "extn");
4307    EINA_SAFETY_ON_NULL_RETURN_VAL(iface, EINA_FALSE);
4308 
4309    return iface->listen(ee, svcname, svcnum, svcsys);
4310 }
4311 
4312 EAPI void
ecore_evas_extn_socket_events_block_set(Ecore_Evas * ee,Eina_Bool events_block)4313 ecore_evas_extn_socket_events_block_set(Ecore_Evas *ee, Eina_Bool events_block)
4314 {
4315    void (*set)(Ecore_Evas*, Eina_Bool);
4316    Eina_Module *m = _ecore_evas_engine_load("extn");
4317    EINA_SAFETY_ON_NULL_RETURN(m);
4318 
4319    set = eina_module_symbol_get(m,
4320          "ecore_evas_extn_socket_events_block_set_internal");
4321    EINA_SAFETY_ON_NULL_RETURN(set);
4322 
4323    set(ee, events_block);
4324 }
4325 
4326 EAPI Eina_Bool
ecore_evas_extn_socket_events_block_get(Ecore_Evas * ee)4327 ecore_evas_extn_socket_events_block_get(Ecore_Evas *ee)
4328 {
4329    Eina_Bool (*get)(Ecore_Evas*);
4330    Eina_Module *m = _ecore_evas_engine_load("extn");
4331    EINA_SAFETY_ON_NULL_RETURN_VAL(m, EINA_FALSE);
4332 
4333    get = eina_module_symbol_get(m,
4334          "ecore_evas_extn_socket_events_block_get_internal");
4335    EINA_SAFETY_ON_NULL_RETURN_VAL(get, EINA_FALSE);
4336 
4337    return get(ee);
4338 }
4339 
4340 EAPI void
ecore_evas_extn_plug_object_data_lock(Evas_Object * obj)4341 ecore_evas_extn_plug_object_data_lock(Evas_Object *obj)
4342 {
4343    Ecore_Evas_Interface_Extn *iface;
4344    Ecore_Evas *ee;
4345 
4346    ee = ecore_evas_object_ecore_evas_get(obj);
4347    EINA_SAFETY_ON_NULL_RETURN(ee);
4348 
4349    iface = (Ecore_Evas_Interface_Extn *)_ecore_evas_interface_get(ee, "extn");
4350    EINA_SAFETY_ON_NULL_RETURN(iface);
4351 
4352    iface->data_lock(ee);
4353 }
4354 
4355 EAPI void
ecore_evas_extn_plug_object_data_unlock(Evas_Object * obj)4356 ecore_evas_extn_plug_object_data_unlock(Evas_Object *obj)
4357 {
4358    Ecore_Evas_Interface_Extn *iface;
4359    Ecore_Evas *ee;
4360 
4361    ee = ecore_evas_object_ecore_evas_get(obj);
4362    EINA_SAFETY_ON_NULL_RETURN(ee);
4363 
4364    iface = (Ecore_Evas_Interface_Extn *)_ecore_evas_interface_get(ee, "extn");
4365    EINA_SAFETY_ON_NULL_RETURN(iface);
4366 
4367    iface->data_unlock(ee);
4368 }
4369 
4370 EAPI Evas_Object *
ecore_evas_extn_plug_new(Ecore_Evas * ee_target)4371 ecore_evas_extn_plug_new(Ecore_Evas *ee_target)
4372 {
4373    Evas_Object *(*new)(Ecore_Evas *);
4374    Eina_Module *m = _ecore_evas_engine_load("extn");
4375    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
4376 
4377    new = eina_module_symbol_get(m, "ecore_evas_extn_plug_new_internal");
4378    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
4379 
4380    return new(ee_target);
4381 }
4382 
4383 EAPI Eina_Bool
ecore_evas_extn_plug_connect(Evas_Object * obj,const char * svcname,int svcnum,Eina_Bool svcsys)4384 ecore_evas_extn_plug_connect(Evas_Object *obj, const char *svcname, int svcnum, Eina_Bool svcsys)
4385 {
4386    Ecore_Evas_Interface_Extn *iface;
4387    Ecore_Evas *ee;
4388 
4389    ee = ecore_evas_object_ecore_evas_get(obj);
4390    EINA_SAFETY_ON_NULL_RETURN_VAL(ee, EINA_FALSE);
4391 
4392    iface = (Ecore_Evas_Interface_Extn *)_ecore_evas_interface_get(ee, "extn");
4393    EINA_SAFETY_ON_NULL_RETURN_VAL(iface, EINA_FALSE);
4394 
4395    return iface->connect(ee, svcname, svcnum, svcsys);
4396 }
4397 
4398 EAPI Ecore_Evas *
ecore_evas_sdl_new(const char * name,int w,int h,int fullscreen,int hwsurface,int noframe,int alpha)4399 ecore_evas_sdl_new(const char* name, int w, int h, int fullscreen,
4400 		   int hwsurface, int noframe, int alpha)
4401 {
4402    Ecore_Evas *ee;
4403    Ecore_Evas *(*new)(const char *, int, int, int, int, int, int);
4404    Eina_Module *m = _ecore_evas_engine_load("sdl");
4405    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
4406 
4407    new = eina_module_symbol_get(m, "ecore_evas_sdl_new_internal");
4408    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
4409 
4410    ee = new(name, w, h, fullscreen, hwsurface, noframe, alpha);
4411    if (!_ecore_evas_cursors_init(ee))
4412      {
4413         ecore_evas_free(ee);
4414         return NULL;
4415      }
4416    return ee;
4417 }
4418 
4419 EAPI Ecore_Evas *
ecore_evas_sdl16_new(const char * name,int w,int h,int fullscreen,int hwsurface,int noframe,int alpha)4420 ecore_evas_sdl16_new(const char* name, int w, int h, int fullscreen,
4421 		     int hwsurface, int noframe, int alpha)
4422 {
4423    Ecore_Evas *ee;
4424    Ecore_Evas *(*new)(const char *, int, int, int, int, int, int);
4425    Eina_Module *m = _ecore_evas_engine_load("sdl");
4426    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
4427 
4428    new = eina_module_symbol_get(m, "ecore_evas_sdl16_new_internal");
4429    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
4430 
4431    ee = new(name, w, h, fullscreen, hwsurface, noframe, alpha);
4432    if (!_ecore_evas_cursors_init(ee))
4433      {
4434         ecore_evas_free(ee);
4435         return NULL;
4436      }
4437    return ee;
4438 }
4439 
4440 EAPI Ecore_Evas *
ecore_evas_gl_sdl_new(const char * name,int w,int h,int fullscreen,int noframe)4441 ecore_evas_gl_sdl_new(const char* name, int w, int h, int fullscreen, int noframe)
4442 {
4443    Ecore_Evas *ee;
4444    Ecore_Evas *(*new)(const char *, int, int, int, int);
4445    Eina_Module *m = _ecore_evas_engine_load("sdl");
4446    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
4447 
4448    new = eina_module_symbol_get(m, "ecore_evas_gl_sdl_new_internal");
4449    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
4450 
4451    ee = new(name, w, h, fullscreen, noframe);
4452    if (!_ecore_evas_cursors_init(ee))
4453      {
4454         ecore_evas_free(ee);
4455         return NULL;
4456      }
4457    return ee;
4458 }
4459 
4460 EAPI Ecore_Evas *
ecore_evas_wayland_shm_new(const char * disp_name,unsigned int parent,int x,int y,int w,int h,Eina_Bool frame)4461 ecore_evas_wayland_shm_new(const char *disp_name, unsigned int parent,
4462 			   int x, int y, int w, int h, Eina_Bool frame)
4463 {
4464    Ecore_Evas *ee;
4465    Ecore_Evas *(*new)(const char *, Ecore_Window, int, int, int, int, Eina_Bool);
4466    Eina_Module *m = _ecore_evas_engine_load("wayland");
4467    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
4468 
4469    new = eina_module_symbol_get(m, "ecore_evas_wayland_shm_new_internal");
4470    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
4471 
4472    if (parent) ERR("Wayland windows with parents not supported through legacy API");
4473 
4474    ee = new(disp_name, 0, x, y, w, h, frame);
4475    if (!_ecore_evas_cursors_init(ee))
4476      {
4477         ecore_evas_free(ee);
4478         return NULL;
4479      }
4480    return ee;
4481 }
4482 
4483 EAPI Ecore_Evas *
ecore_evas_wayland_egl_new(const char * disp_name,unsigned int parent,int x,int y,int w,int h,Eina_Bool frame)4484 ecore_evas_wayland_egl_new(const char *disp_name, unsigned int parent,
4485 			   int x, int y, int w, int h, Eina_Bool frame)
4486 {
4487    Ecore_Evas *ee;
4488    Ecore_Evas *(*new)(const char *, Ecore_Window, int, int, int, int, Eina_Bool, const int*);
4489    Eina_Module *m = _ecore_evas_engine_load("wayland");
4490    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
4491 
4492    new = eina_module_symbol_get(m, "ecore_evas_wayland_egl_new_internal");
4493    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
4494 
4495    if (parent) ERR("Wayland windows with parents not supported through legacy API");
4496 
4497    ee = new(disp_name, 0, x, y, w, h, frame, NULL);
4498    if (!_ecore_evas_cursors_init(ee))
4499      {
4500         ecore_evas_free(ee);
4501         return NULL;
4502      }
4503    return ee;
4504 }
4505 
4506 Ecore_Evas *
_wayland_shm_new(const char * disp_name,Ecore_Window parent,int x,int y,int w,int h,Eina_Bool frame)4507 _wayland_shm_new(const char *disp_name, Ecore_Window parent,
4508                  int x, int y, int w, int h, Eina_Bool frame)
4509 {
4510    Ecore_Evas *ee;
4511    Ecore_Evas *(*new)(const char *, Ecore_Window, int, int, int, int, Eina_Bool);
4512    Eina_Module *m = _ecore_evas_engine_load("wayland");
4513    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
4514 
4515    new = eina_module_symbol_get(m, "ecore_evas_wayland_shm_new_internal");
4516    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
4517 
4518    ee = new(disp_name, parent, x, y, w, h, frame);
4519    if (!_ecore_evas_cursors_init(ee))
4520      {
4521         ecore_evas_free(ee);
4522         return NULL;
4523      }
4524    return ee;
4525 }
4526 
4527 Ecore_Evas *
_wayland_egl_new(const char * disp_name,Ecore_Window parent,int x,int y,int w,int h,Eina_Bool frame,const int * opt)4528 _wayland_egl_new(const char *disp_name, Ecore_Window parent,
4529                  int x, int y, int w, int h, Eina_Bool frame, const int *opt)
4530 {
4531    Ecore_Evas *ee;
4532    Ecore_Evas *(*new)(const char *, Ecore_Window, int, int, int, int, Eina_Bool, const int *);
4533    Eina_Module *m = _ecore_evas_engine_load("wayland");
4534    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
4535 
4536    new = eina_module_symbol_get(m, "ecore_evas_wayland_egl_new_internal");
4537    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
4538 
4539    ee = new(disp_name, parent, x, y, w, h, frame, opt);
4540    if (!_ecore_evas_cursors_init(ee))
4541      {
4542         ecore_evas_free(ee);
4543         return NULL;
4544      }
4545    return ee;
4546 }
4547 
4548 EAPI void
ecore_evas_wayland_resize(Ecore_Evas * ee,int location)4549 ecore_evas_wayland_resize(Ecore_Evas *ee, int location)
4550 {
4551    Ecore_Evas_Interface_Wayland *iface;
4552    iface = (Ecore_Evas_Interface_Wayland *)_ecore_evas_interface_get(ee, "wayland");
4553    EINA_SAFETY_ON_NULL_RETURN(iface);
4554 
4555    iface->resize(ee, location);
4556 }
4557 
4558 EAPI void
ecore_evas_wayland_move(Ecore_Evas * ee,int x,int y)4559 ecore_evas_wayland_move(Ecore_Evas *ee, int x, int y)
4560 {
4561    Ecore_Evas_Interface_Wayland *iface;
4562    iface = (Ecore_Evas_Interface_Wayland *)_ecore_evas_interface_get(ee, "wayland");
4563    EINA_SAFETY_ON_NULL_RETURN(iface);
4564 
4565    iface->move(ee, x, y);
4566 }
4567 
4568 EAPI void
ecore_evas_wayland_pointer_set(Ecore_Evas * ee,int hot_x,int hot_y)4569 ecore_evas_wayland_pointer_set(Ecore_Evas *ee, int hot_x, int hot_y)
4570 {
4571    Ecore_Evas_Interface_Wayland *iface;
4572    iface = (Ecore_Evas_Interface_Wayland *)_ecore_evas_interface_get(ee, "wayland");
4573    EINA_SAFETY_ON_NULL_RETURN(iface);
4574 
4575    iface->pointer_set(ee, hot_x, hot_y);
4576 }
4577 
4578 EAPI void
ecore_evas_wayland_type_set(Ecore_Evas * ee,int type)4579 ecore_evas_wayland_type_set(Ecore_Evas *ee, int type)
4580 {
4581    Ecore_Evas_Interface_Wayland *iface;
4582    iface = (Ecore_Evas_Interface_Wayland *)_ecore_evas_interface_get(ee, "wayland");
4583    EINA_SAFETY_ON_NULL_RETURN(iface);
4584 
4585    iface->type_set(ee, type);
4586 }
4587 
4588 EAPI Ecore_Wl_Window *
ecore_evas_wayland_window_get(const Ecore_Evas * ee)4589 ecore_evas_wayland_window_get(const Ecore_Evas *ee)
4590 {
4591    Ecore_Evas_Interface_Wayland *iface;
4592    iface = (Ecore_Evas_Interface_Wayland *)_ecore_evas_interface_get_internal(ee, "wayland", 0);
4593    if (!iface) return NULL;
4594 
4595    return iface->window_get(ee);
4596 }
4597 
4598 EAPI Ecore_Cocoa_Window *
ecore_evas_cocoa_window_get(const Ecore_Evas * ee)4599 ecore_evas_cocoa_window_get(const Ecore_Evas *ee)
4600 {
4601    Ecore_Evas_Interface_Cocoa *iface;
4602    iface = (Ecore_Evas_Interface_Cocoa *)_ecore_evas_interface_get(ee, "opengl_cocoa");
4603    if (!iface) return NULL;
4604    return iface->window_get(ee);
4605 }
4606 
4607 EAPI Ecore_Wl2_Window *
ecore_evas_wayland2_window_get(const Ecore_Evas * ee)4608 ecore_evas_wayland2_window_get(const Ecore_Evas *ee)
4609 {
4610    Ecore_Evas_Interface_Wayland *iface;
4611    iface = (Ecore_Evas_Interface_Wayland *)_ecore_evas_interface_get_internal(ee, "wayland", 0);
4612    if (!iface) return NULL;
4613 
4614    return iface->window2_get(ee);
4615 }
4616 
4617 EAPI Ecore_Evas *
ecore_evas_drm_new(const char * disp_name,unsigned int parent,int x,int y,int w,int h)4618 ecore_evas_drm_new(const char *disp_name, unsigned int parent,
4619                    int x, int y, int w, int h)
4620 {
4621    Ecore_Evas *ee;
4622    Ecore_Evas *(*new)(const char *, unsigned int, int, int, int, int);
4623    Eina_Module *m = _ecore_evas_engine_load("drm");
4624    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
4625 
4626    new = eina_module_symbol_get(m, "ecore_evas_drm_new_internal");
4627    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
4628 
4629    ee = new(disp_name, parent, x, y, w, h);
4630    if (!_ecore_evas_cursors_init(ee))
4631      {
4632         ecore_evas_free(ee);
4633         return NULL;
4634      }
4635    return ee;
4636 }
4637 
4638 EAPI Ecore_Evas *
ecore_evas_gl_drm_new(const char * disp_name,unsigned int parent,int x,int y,int w,int h)4639 ecore_evas_gl_drm_new(const char *disp_name, unsigned int parent,
4640                           int x, int y, int w, int h)
4641 {
4642    Ecore_Evas *ee;
4643    Ecore_Evas *(*new)(const char *, unsigned int, int, int, int, int);
4644    Eina_Module *m = _ecore_evas_engine_load("drm");
4645    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
4646 
4647    new = eina_module_symbol_get(m, "ecore_evas_gl_drm_new_internal");
4648    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
4649 
4650    ee = new(disp_name, parent, x, y, w, h);
4651    if (!_ecore_evas_cursors_init(ee))
4652      {
4653         ecore_evas_free(ee);
4654         return NULL;
4655      }
4656    return ee;
4657 
4658 }
4659 
4660 EAPI Ecore_Evas *
ecore_evas_software_gdi_new(Ecore_Win32_Window * parent,int x,int y,int width,int height)4661 ecore_evas_software_gdi_new(Ecore_Win32_Window *parent,
4662 			    int                 x,
4663 			    int                 y,
4664 			    int                 width,
4665 			    int                 height)
4666 {
4667    Ecore_Evas *ee;
4668    Ecore_Evas *(*new)(Ecore_Win32_Window *, int, int, int, int);
4669    Eina_Module *m = _ecore_evas_engine_load("win32");
4670    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
4671 
4672    new = eina_module_symbol_get(m, "ecore_evas_software_gdi_new_internal");
4673    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
4674 
4675    ee = new(parent, x, y, width, height);
4676    if (!_ecore_evas_cursors_init(ee))
4677      {
4678         ecore_evas_free(ee);
4679         return NULL;
4680      }
4681    return ee;
4682 
4683 }
4684 
4685 EAPI Ecore_Evas *
ecore_evas_software_ddraw_new(Ecore_Win32_Window * parent,int x,int y,int width,int height)4686 ecore_evas_software_ddraw_new(Ecore_Win32_Window *parent,
4687 			      int                 x,
4688 			      int                 y,
4689 			      int                 width,
4690 			      int                 height)
4691 {
4692    Ecore_Evas *ee;
4693    Ecore_Evas *(*new)(Ecore_Win32_Window *, int, int, int, int);
4694    Eina_Module *m = _ecore_evas_engine_load("win32");
4695    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
4696 
4697    new = eina_module_symbol_get(m, "ecore_evas_software_ddraw_new_internal");
4698    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
4699 
4700    ee = new(parent, x, y, width, height);
4701    if (!_ecore_evas_cursors_init(ee))
4702      {
4703         ecore_evas_free(ee);
4704         return NULL;
4705      }
4706    return ee;
4707 }
4708 
4709 EAPI Ecore_Win32_Window *
ecore_evas_win32_window_get(const Ecore_Evas * ee)4710 ecore_evas_win32_window_get(const Ecore_Evas *ee)
4711 {
4712    Ecore_Evas_Interface_Win32 *iface;
4713    iface = (Ecore_Evas_Interface_Win32 *)_ecore_evas_interface_get(ee, "win32");
4714    if (!iface) return NULL;
4715 
4716    return iface->window_get(ee);
4717 }
4718 
4719 EAPI Ecore_Evas *
ecore_evas_cocoa_new(Ecore_Cocoa_Window * parent,int x,int y,int w,int h)4720 ecore_evas_cocoa_new(Ecore_Cocoa_Window *parent, int x, int y, int w, int h)
4721 {
4722    Ecore_Evas *ee;
4723    Ecore_Evas *(*new)(Ecore_Cocoa_Window *, int, int, int, int);
4724    Eina_Module *m = _ecore_evas_engine_load("cocoa");
4725    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
4726 
4727    new = eina_module_symbol_get(m, "ecore_evas_cocoa_new_internal");
4728    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
4729 
4730    ee = new(parent, x, y, w, h);
4731    if (!_ecore_evas_cursors_init(ee))
4732      {
4733         ecore_evas_free(ee);
4734         return NULL;
4735      }
4736    return ee;
4737 }
4738 
4739 EAPI Ecore_Evas *
ecore_evas_psl1ght_new(const char * name,int w,int h)4740 ecore_evas_psl1ght_new(const char* name, int w, int h)
4741 {
4742    Ecore_Evas *ee;
4743    Ecore_Evas *(*new)(const char*, int, int);
4744    Eina_Module *m = _ecore_evas_engine_load("psl1ght");
4745    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
4746 
4747    new = eina_module_symbol_get(m, "ecore_evas_psl1ght_new_internal");
4748    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
4749 
4750    ee = new(name, w, h);
4751    if (!_ecore_evas_cursors_init(ee))
4752      {
4753         ecore_evas_free(ee);
4754         return NULL;
4755      }
4756    return ee;
4757 }
4758 
4759 
4760 /* new input model with eo:
4761  *  1. pass all events from ecore_input_evas through
4762  *     ecore_evas and send eo events from here
4763  *  2. those eo events can then be translated to legacy by evas
4764  *  3. let evas send legacy & eo events to the objects
4765  */
4766 
4767 #define EVENT_XY_SET(EV, MX, MY, FX, FY) do { \
4768    EV->cur.x = (MX) - (FX); EV->cur.y = (MY) - (FY); \
4769    } while (0)
4770 
4771 static inline void
_pointer_position_set(Efl_Input_Pointer_Data * ev,Ecore_Evas * ee,int x,int y,double mx,double my)4772 _pointer_position_set(Efl_Input_Pointer_Data *ev, Ecore_Evas *ee, int x, int y,
4773                       double mx, double my)
4774 {
4775    int fx, fy, fw, fh;
4776 
4777    if ((EINA_DBL_EQ(mx, 0.0)) &&
4778        (EINA_DBL_EQ(my, 0.0)))
4779      {
4780         mx = x;
4781         my = y;
4782      }
4783 
4784    evas_output_framespace_get(ee->evas, &fx, &fy, &fw, &fh);
4785    if (ee->rotation == 0)
4786      EVENT_XY_SET(ev, mx, my, fx, fy);
4787    else if (ee->rotation == 90)
4788      EVENT_XY_SET(ev, ee->h + fw - my - 1, mx, fx, fy);
4789    else if (ee->rotation == 180)
4790      EVENT_XY_SET(ev, ee->w + fw - mx - 1, ee->h + fh - my - 1, fx, fy);
4791    else if (ee->rotation == 270)
4792      EVENT_XY_SET(ev, my, ee->w + fh - mx - 1, fx, fy);
4793 }
4794 
4795 static const Efl_Event_Description *
_event_description_get(Efl_Pointer_Action action)4796 _event_description_get(Efl_Pointer_Action action)
4797 {
4798    switch (action)
4799      {
4800       case EFL_POINTER_ACTION_MOVE:
4801         return EFL_EVENT_POINTER_MOVE;
4802       case EFL_POINTER_ACTION_DOWN:
4803         return EFL_EVENT_POINTER_DOWN;
4804       case EFL_POINTER_ACTION_UP:
4805         return EFL_EVENT_POINTER_UP;
4806       case EFL_POINTER_ACTION_CANCEL:
4807         return EFL_EVENT_POINTER_CANCEL;
4808       case EFL_POINTER_ACTION_IN:
4809         return EFL_EVENT_POINTER_IN;
4810       case EFL_POINTER_ACTION_OUT:
4811         return EFL_EVENT_POINTER_OUT;
4812       case EFL_POINTER_ACTION_WHEEL:
4813         return EFL_EVENT_POINTER_WHEEL;
4814       case EFL_POINTER_ACTION_AXIS:
4815         return EFL_EVENT_POINTER_AXIS;
4816       default: return NULL;
4817      }
4818 }
4819 
4820 static Eina_Bool
_direct_mouse_updown(Ecore_Evas * ee,const Ecore_Event_Mouse_Button * info,Efl_Pointer_Action action)4821 _direct_mouse_updown(Ecore_Evas *ee, const Ecore_Event_Mouse_Button *info, Efl_Pointer_Action action)
4822 {
4823    Efl_Input_Pointer_Data *ev;
4824    Efl_Input_Pointer *evt;
4825    Evas *e = ee->evas;
4826    Eina_Bool processed;
4827 
4828    /* Unused information:
4829     * same_screen
4830     * root.{x,y}
4831     * root_window
4832     * event_window
4833     * same_screen
4834     * modifiers (already passed to evas, no need to do anything)
4835     */
4836 
4837    evt = efl_input_pointer_instance_get( e, (void **) &ev);
4838    if (!evt) return EINA_FALSE;
4839 
4840    ev->action = action;
4841    ev->button = info->buttons;
4842    if (info->double_click) ev->button_flags |= EFL_POINTER_FLAGS_DOUBLE_CLICK;
4843    if (info->triple_click) ev->button_flags |= EFL_POINTER_FLAGS_TRIPLE_CLICK;
4844    ev->timestamp = info->timestamp;
4845    ev->touch_id = info->multi.device;
4846    _pointer_position_set(ev, ee, info->x, info->y, info->multi.x, info->multi.y);
4847    ev->radius = info->multi.radius;
4848    ev->radius_x = info->multi.radius_x;
4849    ev->radius_y = info->multi.radius_y;
4850    ev->pressure = info->multi.pressure;
4851    ev->angle = info->multi.angle - ee->rotation;
4852    if (info->dev) ev->device = efl_ref(info->dev);
4853    else ev->device = efl_ref(evas_default_device_get(e, EVAS_DEVICE_CLASS_MOUSE));
4854    efl_input_pointer_finalize(evt);
4855 
4856    efl_event_callback_legacy_call(e, _event_description_get(ev->action), evt);
4857    processed = ev->evas_done;
4858    efl_unref(evt);
4859 
4860    return processed;
4861 }
4862 
4863 static Eina_Bool
_direct_mouse_down_cb(Ecore_Evas * ee,const Ecore_Event_Mouse_Button * info)4864 _direct_mouse_down_cb(Ecore_Evas *ee, const Ecore_Event_Mouse_Button *info)
4865 {
4866    return _direct_mouse_updown(ee, info, EFL_POINTER_ACTION_DOWN);
4867 }
4868 
4869 static Eina_Bool
_direct_mouse_up_cb(Ecore_Evas * ee,const Ecore_Event_Mouse_Button * info)4870 _direct_mouse_up_cb(Ecore_Evas *ee, const Ecore_Event_Mouse_Button *info)
4871 {
4872    return _direct_mouse_updown(ee, info, EFL_POINTER_ACTION_UP);
4873 }
4874 
4875 static Eina_Bool
_direct_mouse_cancel_cb(Ecore_Evas * ee,const Ecore_Event_Mouse_Button * info)4876 _direct_mouse_cancel_cb(Ecore_Evas *ee, const Ecore_Event_Mouse_Button *info)
4877 {
4878    return _direct_mouse_updown(ee, info, EFL_POINTER_ACTION_CANCEL);
4879 }
4880 
4881 static Eina_Bool
_direct_mouse_move_cb(Ecore_Evas * ee,const Ecore_Event_Mouse_Move * info)4882 _direct_mouse_move_cb(Ecore_Evas *ee, const Ecore_Event_Mouse_Move *info)
4883 {
4884    Efl_Input_Pointer_Data *ev;
4885    Efl_Input_Pointer *evt;
4886    Evas *e = ee->evas;
4887    Eina_Bool processed;
4888 
4889    _ecore_evas_mouse_move_process_internal(ee, info->dev, info->x, info->y,
4890                                            info->timestamp, EINA_FALSE);
4891 
4892    /* Unused information:
4893     * same_screen
4894     * root.{x,y}
4895     * root_window
4896     * event_window
4897     * same_screen
4898     * modifiers (already passed to evas, no need to do anything)
4899     */
4900 
4901    evt = efl_input_pointer_instance_get( e, (void **) &ev);
4902    if (!evt) return EINA_FALSE;
4903 
4904    ev->action = EFL_POINTER_ACTION_MOVE;
4905    ev->timestamp = info->timestamp;
4906    ev->touch_id = info->multi.device;
4907    _pointer_position_set(ev, ee, info->x, info->y, info->multi.x, info->multi.y);
4908 
4909    ev->radius = info->multi.radius;
4910    ev->radius_x = info->multi.radius_x;
4911    ev->radius_y = info->multi.radius_y;
4912    ev->pressure = info->multi.pressure;
4913    ev->angle = info->multi.angle - ee->rotation;
4914    if (info->dev) ev->device = efl_ref(info->dev);
4915    else ev->device = efl_ref(evas_default_device_get(e, EVAS_DEVICE_CLASS_MOUSE));
4916    efl_input_pointer_finalize(evt);
4917 
4918    efl_event_callback_legacy_call(e, _event_description_get(ev->action), evt);
4919    processed = ev->evas_done;
4920    efl_unref(evt);
4921 
4922    return processed;
4923 }
4924 
4925 static Eina_Bool
_direct_mouse_wheel_cb(Ecore_Evas * ee,const Ecore_Event_Mouse_Wheel * info)4926 _direct_mouse_wheel_cb(Ecore_Evas *ee, const Ecore_Event_Mouse_Wheel *info)
4927 {
4928    Efl_Input_Pointer_Data *ev;
4929    Efl_Input_Pointer *evt;
4930    Evas *e = ee->evas;
4931    Eina_Bool processed;
4932 
4933    /* Unused information:
4934     * same_screen
4935     * root.{x,y}
4936     * root_window
4937     * event_window
4938     * modifiers (already passed to evas, no need to do anything)
4939     */
4940 
4941    evt = efl_input_pointer_instance_get( e, (void **) &ev);
4942    if (!evt) return EINA_FALSE;
4943 
4944    ev->action = EFL_POINTER_ACTION_WHEEL;
4945    ev->timestamp = info->timestamp;
4946    _pointer_position_set(ev, ee, info->x, info->y, info->x, info->y);
4947    ev->wheel.z = info->z;
4948    ev->wheel.horizontal = !!info->direction;
4949    if (info->dev) ev->device = efl_ref(info->dev);
4950    else ev->device = efl_ref(evas_default_device_get(e, EVAS_DEVICE_CLASS_MOUSE));
4951    efl_input_pointer_finalize(evt);
4952 
4953    efl_event_callback_legacy_call(e, _event_description_get(ev->action), evt);
4954    processed = ev->evas_done;
4955    efl_unref(evt);
4956 
4957    return processed;
4958 }
4959 
4960 static Eina_Bool
_direct_mouse_inout(Ecore_Evas * ee,const Ecore_Event_Mouse_IO * info,Efl_Pointer_Action action)4961 _direct_mouse_inout(Ecore_Evas *ee, const Ecore_Event_Mouse_IO *info, Efl_Pointer_Action action)
4962 {
4963    Efl_Input_Pointer_Data *ev;
4964    Efl_Input_Pointer *evt;
4965    Evas *e = ee->evas;
4966    Eina_Bool processed;
4967 
4968    /* Unused information:
4969     * event_window
4970     * modifiers (already passed to evas, no need to do anything)
4971     */
4972 
4973    evt = efl_input_pointer_instance_get( e, (void **) &ev);
4974    if (!evt) return EINA_FALSE;
4975 
4976    ev->action = action;
4977    ev->timestamp = info->timestamp;
4978    _pointer_position_set(ev, ee, info->x, info->y, info->x, info->y);
4979    if (info->dev) ev->device = efl_ref(info->dev);
4980    else ev->device = efl_ref(evas_default_device_get(e, EVAS_DEVICE_CLASS_MOUSE));
4981    efl_input_pointer_finalize(evt);
4982 
4983    efl_event_callback_legacy_call(e, _event_description_get(ev->action), evt);
4984    processed = ev->evas_done;
4985    efl_unref(evt);
4986 
4987    return processed;
4988 }
4989 
4990 static Eina_Bool
_direct_mouse_in_cb(Ecore_Evas * ee,const Ecore_Event_Mouse_IO * info)4991 _direct_mouse_in_cb(Ecore_Evas *ee, const Ecore_Event_Mouse_IO *info)
4992 {
4993    return _direct_mouse_inout(ee, info, EFL_POINTER_ACTION_IN);
4994 }
4995 
4996 static Eina_Bool
_direct_mouse_out_cb(Ecore_Evas * ee,const Ecore_Event_Mouse_IO * info)4997 _direct_mouse_out_cb(Ecore_Evas *ee, const Ecore_Event_Mouse_IO *info)
4998 {
4999    return _direct_mouse_inout(ee, info, EFL_POINTER_ACTION_OUT);
5000 }
5001 
5002 static Eina_Bool
_direct_axis_update_cb(Ecore_Evas * ee,const Ecore_Event_Axis_Update * info)5003 _direct_axis_update_cb(Ecore_Evas *ee, const Ecore_Event_Axis_Update *info)
5004 {
5005    Eina_Bool haswinx = 0, haswiny = 0;
5006    Efl_Input_Pointer_Data *ev;
5007    Efl_Input_Pointer *evt;
5008    Evas *e = ee->evas;
5009    Eina_Bool processed;
5010    double x = 0, y = 0;
5011    int n;
5012 
5013    /* Unused information:
5014     * window, root_window, event_window
5015     */
5016 
5017    evt = efl_input_pointer_instance_get( e, (void **) &ev);
5018    if (!ev) return EINA_FALSE;
5019 
5020    ev->action = EFL_POINTER_ACTION_AXIS;
5021    ev->timestamp = info->timestamp;
5022    ev->touch_id = info->toolid;
5023 
5024    // see also evas_events.c
5025    for (n = 0; n < info->naxis; n++)
5026      {
5027         const Ecore_Axis *axis = &(info->axis[n]);
5028         switch (axis->label)
5029           {
5030            case ECORE_AXIS_LABEL_WINDOW_X:
5031              _efl_input_value_mark(ev, EFL_INPUT_VALUE_X);
5032              x = axis->value;
5033              haswinx = EINA_TRUE;
5034              break;
5035 
5036            case ECORE_AXIS_LABEL_WINDOW_Y:
5037              _efl_input_value_mark(ev, EFL_INPUT_VALUE_Y);
5038              y = axis->value;
5039              haswiny = EINA_TRUE;
5040              break;
5041 
5042            case ECORE_AXIS_LABEL_X:
5043              if (!haswinx)
5044                {
5045                   _efl_input_value_mark(ev, EFL_INPUT_VALUE_X);
5046                   x = axis->value;
5047                }
5048              ev->raw.x = axis->value;
5049              ev->has_raw = EINA_TRUE;
5050              break;
5051 
5052            case ECORE_AXIS_LABEL_Y:
5053              if (!haswiny)
5054                {
5055                   _efl_input_value_mark(ev, EFL_INPUT_VALUE_Y);
5056                   y = axis->value;
5057                }
5058              ev->raw.y = axis->value;
5059              ev->has_raw = EINA_TRUE;
5060              break;
5061 
5062            case ECORE_AXIS_LABEL_NORMAL_X:
5063              ev->norm.x = axis->value;
5064              ev->has_norm = EINA_TRUE;
5065              break;
5066 
5067            case ECORE_AXIS_LABEL_NORMAL_Y:
5068              ev->norm.y = axis->value;
5069              ev->has_norm = EINA_TRUE;
5070              break;
5071 
5072            case ECORE_AXIS_LABEL_PRESSURE:
5073              _efl_input_value_mark(ev, EFL_INPUT_VALUE_PRESSURE);
5074              ev->pressure = axis->value;
5075              break;
5076 
5077            case ECORE_AXIS_LABEL_DISTANCE:
5078              _efl_input_value_mark(ev, EFL_INPUT_VALUE_DISTANCE);
5079              ev->distance = axis->value;
5080              break;
5081 
5082            case ECORE_AXIS_LABEL_AZIMUTH:
5083              _efl_input_value_mark(ev, EFL_INPUT_VALUE_AZIMUTH);
5084              ev->azimuth = axis->value;
5085              break;
5086 
5087            case ECORE_AXIS_LABEL_TILT:
5088              _efl_input_value_mark(ev, EFL_INPUT_VALUE_TILT);
5089              ev->tilt = axis->value;
5090              break;
5091 
5092            case ECORE_AXIS_LABEL_TWIST:
5093              _efl_input_value_mark(ev, EFL_INPUT_VALUE_TWIST);
5094              ev->twist = axis->value;
5095              break;
5096 
5097            case ECORE_AXIS_LABEL_UNKNOWN:
5098            case ECORE_AXIS_LABEL_TOUCH_WIDTH_MAJOR:
5099            case ECORE_AXIS_LABEL_TOUCH_WIDTH_MINOR:
5100            case ECORE_AXIS_LABEL_TOOL_WIDTH_MAJOR:
5101            case ECORE_AXIS_LABEL_TOOL_WIDTH_MINOR:
5102            default:
5103              DBG("Unsupported axis label %d, value %f (discarded)",
5104                  axis->label, axis->value);
5105              break;
5106           }
5107      }
5108    _pointer_position_set(ev, ee, x, y, x, y);
5109    if (info->dev) ev->device = efl_ref(info->dev);
5110    else ev->device = efl_ref(evas_default_device_get(e, EVAS_DEVICE_CLASS_MOUSE));
5111    efl_input_pointer_finalize(evt);
5112 
5113    efl_event_callback_legacy_call(e, _event_description_get(ev->action), evt);
5114    processed = ev->evas_done;
5115    efl_unref(evt);
5116 
5117    return processed;
5118 }
5119 
5120 static Eina_Bool
_direct_key_updown_cb(Ecore_Evas * ee,const Ecore_Event_Key * info,Eina_Bool down)5121 _direct_key_updown_cb(Ecore_Evas *ee, const Ecore_Event_Key *info, Eina_Bool down)
5122 {
5123    Efl_Input_Key_Data *ev;
5124    Efl_Input_Key *evt;
5125    Evas *e = ee->evas;
5126    Eina_Bool processed;
5127 
5128    /* Unused information:
5129     * window
5130     * root_window
5131     * event_window
5132     * same_screen
5133     * modifiers (already passed to evas, no need to do anything)
5134     */
5135 
5136    evt = efl_input_key_instance_get( e, (void **) &ev);
5137    if (!evt || !ev) return EINA_FALSE;
5138 
5139    ev->timestamp = info->timestamp;
5140    ev->pressed = down;
5141    eina_stringshare_replace(&ev->keyname, info->keyname);
5142    eina_stringshare_replace(&ev->key, info->key);
5143    eina_stringshare_replace(&ev->string, info->string);
5144    eina_stringshare_replace(&ev->compose, info->compose);
5145    ev->keycode = info->keycode;
5146    ev->data = info->data;
5147    ev->event_flags = 0;
5148    if (info->dev) ev->device = efl_ref(info->dev);
5149    else ev->device = efl_ref(evas_default_device_get(e, EVAS_DEVICE_CLASS_KEYBOARD));
5150 
5151    if (down)
5152      efl_event_callback_legacy_call(e, EFL_EVENT_KEY_DOWN, evt);
5153    else
5154      efl_event_callback_legacy_call(e, EFL_EVENT_KEY_UP, evt);
5155 
5156    processed = ev->evas_done;
5157    efl_unref(evt);
5158 
5159    return processed;
5160 }
5161 
5162 EAPI Eina_Bool
_ecore_evas_input_direct_cb(void * window,int type,const void * info)5163 _ecore_evas_input_direct_cb(void *window, int type, const void *info)
5164 {
5165    Ecore_Evas *ee = window;
5166 
5167    if (type == ECORE_EVENT_MOUSE_MOVE)
5168      return _direct_mouse_move_cb(ee, (const Ecore_Event_Mouse_Move *) info);
5169    else if (type == ECORE_EVENT_MOUSE_BUTTON_DOWN)
5170      return _direct_mouse_down_cb(ee, (const Ecore_Event_Mouse_Button *) info);
5171    else if (type == ECORE_EVENT_MOUSE_BUTTON_UP)
5172      return _direct_mouse_up_cb(ee, (const Ecore_Event_Mouse_Button *) info);
5173    else if (type == ECORE_EVENT_MOUSE_WHEEL)
5174      return _direct_mouse_wheel_cb(ee, (const Ecore_Event_Mouse_Wheel *) info);
5175    else if (type == ECORE_EVENT_MOUSE_IN)
5176      return _direct_mouse_in_cb(ee, (const Ecore_Event_Mouse_IO *) info);
5177    else if (type == ECORE_EVENT_MOUSE_OUT)
5178      return _direct_mouse_out_cb(ee, (const Ecore_Event_Mouse_IO *) info);
5179    else if (type == ECORE_EVENT_KEY_DOWN)
5180      return _direct_key_updown_cb(ee, (const Ecore_Event_Key *) info, EINA_TRUE);
5181    else if (type == ECORE_EVENT_KEY_UP)
5182      return _direct_key_updown_cb(ee, (const Ecore_Event_Key *) info, EINA_FALSE);
5183    else if (type == ECORE_EVENT_MOUSE_BUTTON_CANCEL)
5184      return _direct_mouse_cancel_cb(ee, (const Ecore_Event_Mouse_Button *) info);
5185    else if (type == ECORE_EVENT_AXIS_UPDATE)
5186      return _direct_axis_update_cb(ee, (const Ecore_Event_Axis_Update *) info);
5187    else
5188      {
5189         ERR("unhandled input event type %d", type);
5190         return EINA_FALSE;
5191      }
5192 }
5193 
5194 EAPI void
_ecore_evas_mouse_inout_set(Ecore_Evas * ee,Efl_Input_Device * mouse,Eina_Bool in,Eina_Bool force_out)5195 _ecore_evas_mouse_inout_set(Ecore_Evas *ee, Efl_Input_Device *mouse,
5196                             Eina_Bool in, Eina_Bool force_out)
5197 {
5198    Eina_List *present;
5199 
5200    if (!mouse)
5201      mouse = evas_default_device_get(ee->evas, EVAS_DEVICE_CLASS_MOUSE);
5202 
5203    EINA_SAFETY_ON_NULL_RETURN(mouse);
5204    present = eina_list_data_find_list(ee->mice_in, mouse);
5205 
5206    if (in)
5207      {
5208         if (present) return;
5209         ee->mice_in = eina_list_append(ee->mice_in, mouse);
5210         efl_event_callback_add(mouse, EFL_EVENT_DEL,
5211                                _ecore_evas_mouse_del_cb, ee);
5212         if (ee->func.fn_mouse_in) ee->func.fn_mouse_in(ee);
5213      }
5214    else
5215      {
5216         if (present) ee->mice_in = eina_list_remove_list(ee->mice_in, present);
5217         else if (!present && !force_out) return;
5218         efl_event_callback_del(mouse, EFL_EVENT_DEL,
5219                                _ecore_evas_mouse_del_cb, ee);
5220         _ecore_evas_mouse_out_dispatch(ee, mouse);
5221      }
5222 }
5223 
5224 EAPI Eina_Bool
_ecore_evas_mouse_in_check(Ecore_Evas * ee,Efl_Input_Device * mouse)5225 _ecore_evas_mouse_in_check(Ecore_Evas *ee, Efl_Input_Device *mouse)
5226 {
5227    if (!mouse)
5228      mouse = evas_default_device_get(ee->evas, EVAS_DEVICE_CLASS_MOUSE);
5229    EINA_SAFETY_ON_NULL_RETURN_VAL(mouse, EINA_FALSE);
5230    return eina_list_data_find(ee->mice_in, mouse) ? EINA_TRUE : EINA_FALSE;
5231 }
5232 
5233 EAPI void
ecore_evas_callback_device_mouse_out_set(Ecore_Evas * ee,Ecore_Evas_Mouse_IO_Cb func)5234 ecore_evas_callback_device_mouse_out_set(Ecore_Evas *ee,
5235                                          Ecore_Evas_Mouse_IO_Cb func)
5236 {
5237    ECORE_EVAS_CHECK(ee);
5238    IFC(ee, fn_callback_device_mouse_out_set) (ee, func);
5239    IFE;
5240    ee->func.fn_device_mouse_out = func;
5241 }
5242 
5243 EAPI void
ecore_evas_callback_device_mouse_in_set(Ecore_Evas * ee,Ecore_Evas_Mouse_IO_Cb func)5244 ecore_evas_callback_device_mouse_in_set(Ecore_Evas *ee,
5245                                         Ecore_Evas_Mouse_IO_Cb func)
5246 {
5247    ECORE_EVAS_CHECK(ee);
5248    IFC(ee, fn_callback_device_mouse_in_set) (ee, func);
5249    IFE;
5250    ee->func.fn_device_mouse_in = func;
5251 }
5252 
5253 static Evas *(*replacement_new)(int w, int h) = NULL;
5254 
5255 EAPI void
ecore_evas_callback_new_set(Evas * (* func)(int w,int h))5256 ecore_evas_callback_new_set(Evas *(*func)(int w, int h))
5257 {
5258    replacement_new = func;
5259 }
5260 
5261 EAPI Evas *
ecore_evas_evas_new(Ecore_Evas * ee,int w,int h)5262 ecore_evas_evas_new(Ecore_Evas *ee, int w, int h)
5263 {
5264    Evas *e;
5265 
5266    if (ee->evas) return ee->evas;
5267 
5268    if (replacement_new) e = replacement_new(w, h);
5269    else e = evas_new();
5270    if (!e) return NULL;
5271 
5272    ee->evas = e;
5273    evas_data_attach_set(e, ee);
5274 
5275    if (ECORE_EVAS_PORTRAIT(ee))
5276      {
5277         evas_output_size_set(e, w, h);
5278         evas_output_viewport_set(e, 0, 0, w, h);
5279      }
5280    else
5281      {
5282         evas_output_size_set(e, h, w);
5283         evas_output_viewport_set(e, 0, 0, h, w);
5284      }
5285 
5286    return e;
5287 }
5288 
5289 static void
_ecore_evas_event_del(void * data,const Efl_Event * ev EINA_UNUSED)5290 _ecore_evas_event_del(void *data, const Efl_Event *ev EINA_UNUSED)
5291 {
5292    Ecore_Evas *ee = data;
5293    if (ee->evas_dying) return;
5294 
5295    ee->evas_dying = EINA_TRUE;
5296    ecore_evas_free(ee);
5297 }
5298 
5299 EAPI void
ecore_evas_done(Ecore_Evas * ee,Eina_Bool single_window)5300 ecore_evas_done(Ecore_Evas *ee, Eina_Bool single_window)
5301 {
5302    _ecore_evas_register(ee);
5303    ecore_event_window_register(ee->prop.window, ee, ee->evas,
5304                                (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
5305                                (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
5306                                (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
5307                                (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
5308    _ecore_event_window_direct_cb_set(ee->prop.window, _ecore_evas_input_direct_cb);
5309 
5310    if (single_window)
5311      evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
5312 
5313    efl_event_callback_add(ee->evas, EFL_EVENT_INVALIDATE, _ecore_evas_event_del, ee);
5314    ee->self_del = EINA_TRUE;
5315 }
5316 
5317 static Ecore_Animator *
_ecore_evas_animator_add(void * evo,Ecore_Task_Cb func,const void * data)5318 _ecore_evas_animator_add(void *evo, Ecore_Task_Cb func, const void *data)
5319 {
5320    Ecore_Evas *ee;
5321    Ecore_Animator *animator;
5322 
5323    EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
5324 
5325    if (!func)
5326      {
5327         ERR("callback function must be set up for an Ecore_Animator object.");
5328         return NULL;
5329      }
5330 
5331    ee = ecore_evas_ecore_evas_get(evas_object_evas_get(evo));
5332    if (!ee) return NULL;
5333 
5334    /* If we don't have back-end specific ticks, fallback to old animators */
5335    if (!ee->engine.func->fn_animator_register) return NULL;
5336 
5337    animator = calloc(1, sizeof(Ecore_Animator));
5338    if (!animator) return NULL;
5339 
5340    animator->func = func;
5341    animator->data = (void *)data;
5342    animator->ee = ee;
5343    ee->ee_anim.active = eina_inlist_append(ee->ee_anim.active, EINA_INLIST_GET(animator));
5344    _ticking_start(ee);
5345 
5346    return animator;
5347 }
5348 
5349 static Eina_Bool
_ecore_evas_animator_run(void * data)5350 _ecore_evas_animator_run(void *data)
5351 {
5352    Ecore_Animator *animator = data;
5353    double pos = 0.0, t;
5354    Eina_Bool run_ret;
5355 
5356    t = ecore_loop_time_get();
5357    if (animator->run > 0.0)
5358      {
5359         pos = (t - animator->start) / animator->run;
5360         if (pos > 1.0) pos = 1.0;
5361         else if (pos < 0.0)
5362           pos = 0.0;
5363      }
5364    run_ret = animator->run_func(animator->run_data, pos);
5365    if (eina_dbl_exact(pos, 1.0)) run_ret = EINA_FALSE;
5366    return run_ret;
5367 }
5368 
5369 static Ecore_Animator *
_ecore_evas_animator_timeline_add(void * evo,double runtime,Ecore_Timeline_Cb func,const void * data)5370 _ecore_evas_animator_timeline_add(void             *evo,
5371                                   double            runtime,
5372                                   Ecore_Timeline_Cb func,
5373                                   const void       *data)
5374 {
5375    Ecore_Animator *animator;
5376 
5377    if (runtime <= 0.0) runtime = 0.0;
5378 
5379    animator = _ecore_evas_animator_add(evo, _ecore_evas_animator_run, NULL);
5380    if (!animator) return NULL;
5381 
5382    animator->data = animator;
5383    animator->run_func = func;
5384    animator->run_data = (void *)data;
5385    animator->start = ecore_loop_time_get();
5386    animator->run = runtime;
5387 
5388    return animator;
5389 }
5390 
5391 static void *
_ecore_evas_animator_del(Ecore_Animator * in)5392 _ecore_evas_animator_del(Ecore_Animator *in)
5393 {
5394    Ecore_Animator *animator = in;
5395    Ecore_Evas *ee;
5396    void *data = NULL;
5397 
5398    if (animator->delete_me)
5399      return animator->data;
5400    ee = animator->ee;
5401 
5402    _ecore_evas_animator_detach(animator);
5403 
5404    ee->ee_anim.deleted = eina_inlist_append(ee->ee_anim.deleted, EINA_INLIST_GET(animator));
5405    animator->delete_me = EINA_TRUE;
5406 
5407    if (animator->run_func)
5408      data = animator->run_data;
5409    else
5410      data = animator->data;
5411 
5412    _ticking_stop(ee);
5413    return data;
5414 }
5415 
5416 static void
_ecore_evas_animator_flush(Ecore_Evas * ee)5417 _ecore_evas_animator_flush(Ecore_Evas *ee)
5418 {
5419    Ecore_Animator *l;
5420 
5421    EINA_INLIST_FREE(ee->ee_anim.deleted, l)
5422      {
5423         ee->ee_anim.deleted = eina_inlist_remove(ee->ee_anim.deleted, EINA_INLIST_GET(l));
5424         free(l);
5425      }
5426 }
5427 
5428 void
_ecore_evas_animator_freeze(Ecore_Animator * in)5429 _ecore_evas_animator_freeze(Ecore_Animator *in)
5430 {
5431    Ecore_Animator *animator = in;
5432    Ecore_Evas *ee;
5433 
5434    ee = animator->ee;
5435    _ecore_evas_animator_detach(animator);
5436 
5437    ee->ee_anim.suspended = eina_inlist_append(ee->ee_anim.suspended, EINA_INLIST_GET(animator));
5438 
5439    animator->suspended = EINA_TRUE;
5440    _ticking_stop(ee);
5441 }
5442 
5443 void
_ecore_evas_animator_thaw(Ecore_Animator * in)5444 _ecore_evas_animator_thaw(Ecore_Animator *in)
5445 {
5446    Ecore_Animator *animator = in;
5447    Ecore_Evas *ee;
5448 
5449    EINA_MAIN_LOOP_CHECK_RETURN;
5450    if (!animator) return;
5451    if (animator->delete_me) return;
5452    if (!animator->suspended) return;
5453 
5454    ee = animator->ee;
5455    ee->ee_anim.suspended = eina_inlist_remove(ee->ee_anim.suspended,
5456                                               EINA_INLIST_GET(animator));
5457    animator->suspended = EINA_FALSE;
5458    ee->ee_anim.active = eina_inlist_append(ee->ee_anim.active,
5459                                            EINA_INLIST_GET(animator));
5460    _ticking_start(ee);
5461 }
5462 
5463 EAPI void
ecore_evas_callback_selection_changed_set(Ecore_Evas * ee,Ecore_Evas_Selection_Changed_Cb func)5464 ecore_evas_callback_selection_changed_set(Ecore_Evas *ee, Ecore_Evas_Selection_Changed_Cb func)
5465 {
5466    ECORE_EVAS_CHECK(ee);
5467    ee->func.fn_selection_changed = func;
5468 }
5469 
5470 static Ecore_Evas_Selection_Seat_Buffers*
_fetch_selection_buffers_of_seat(Ecore_Evas * ee,unsigned int seat,Eina_Bool create)5471 _fetch_selection_buffers_of_seat(Ecore_Evas *ee, unsigned int seat, Eina_Bool create)
5472 {
5473    Ecore_Evas_Selection_Seat_Buffers *buffers;
5474    if (!ee->selection_buffers)
5475      ee->selection_buffers = eina_hash_int32_new(free);
5476 
5477    buffers = eina_hash_find(ee->selection_buffers, &seat);
5478 
5479    if (!buffers && create)
5480      {
5481         buffers = calloc(1, sizeof(Ecore_Evas_Selection_Seat_Buffers));
5482         buffers->seat = seat;
5483         eina_hash_add(ee->selection_buffers, &seat, buffers);
5484      }
5485    return buffers;
5486 }
5487 
5488 static Eina_Bool
_deliver_cb(Ecore_Evas * ee,unsigned int seat,Ecore_Evas_Selection_Buffer buffer,const char * type,Eina_Rw_Slice * slice)5489 _deliver_cb(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer buffer, const char *type, Eina_Rw_Slice *slice)
5490 {
5491    Ecore_Evas_Selection_Seat_Buffers *buffers;
5492    Eina_Content *content = NULL;
5493    Eina_Content *converted = NULL;
5494    Eina_Bool result = EINA_FALSE;
5495 
5496    INF("Delivery request on seat %d in buffer %d", seat, buffer);
5497 
5498    buffers = _fetch_selection_buffers_of_seat(ee, seat, EINA_FALSE);
5499    EINA_SAFETY_ON_NULL_GOTO(buffers, free_everything);
5500    content = buffers->selection_buffer[buffer];
5501    EINA_SAFETY_ON_NULL_GOTO(content, free_everything);
5502    if (!eina_streq(type, eina_content_type_get(content)))
5503      converted = eina_content_convert(content, type);
5504    else
5505      converted = content;
5506 
5507    EINA_SAFETY_ON_NULL_GOTO(converted, free_everything);
5508    *slice = eina_slice_dup(eina_content_data_get(converted));
5509    result = EINA_TRUE;
5510 
5511    if (buffer == ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER)
5512      {
5513         ee->drag.accepted = EINA_TRUE;
5514      }
5515 
5516 free_everything:
5517    if (converted && content && !eina_streq(type, eina_content_type_get(content)))
5518      eina_content_free(converted);
5519 
5520    return result;
5521 }
5522 
5523 static void
_cancel_cb(Ecore_Evas * ee,unsigned int seat,Ecore_Evas_Selection_Buffer buffer)5524 _cancel_cb(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer buffer)
5525 {
5526    Ecore_Evas_Selection_Seat_Buffers *buffers;
5527 
5528    INF("Cancel request on seat %d in buffer %d", seat, buffer);
5529 
5530    buffers = _fetch_selection_buffers_of_seat(ee, seat, EINA_FALSE);
5531    EINA_SAFETY_ON_FALSE_RETURN(buffers);
5532    EINA_SAFETY_ON_FALSE_RETURN(buffers->selection_buffer[buffer]);
5533    eina_content_free(buffers->selection_buffer[buffer]);
5534    buffers->selection_buffer[buffer] = NULL;
5535 
5536    if (buffer == ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER)
5537      {
5538         ee->drag.rep = NULL;
5539         if (ee->drag.free)
5540           ee->drag.free(ee, seat, ee->drag.data, EINA_FALSE);
5541         ee->drag.free = NULL;
5542      }
5543 }
5544 
5545 #define CALL(call)  (ee->engine.func->fn_ ##call ? : fallback_ ##call)
5546 
5547 static Eina_Array*
_iterator_to_array(Eina_Iterator * iter,const char * existing_type)5548 _iterator_to_array(Eina_Iterator *iter, const char *existing_type)
5549 {
5550    Eina_Array *ret = eina_array_new(10);
5551    const char *type;
5552 
5553    if (existing_type)
5554      eina_array_push(ret, existing_type);
5555 
5556    EINA_ITERATOR_FOREACH(iter, type)
5557      {
5558         eina_array_push(ret, type);
5559      }
5560    eina_iterator_free(iter);
5561 
5562    return ret;
5563 }
5564 
5565 EAPI Eina_Bool
ecore_evas_selection_set(Ecore_Evas * ee,unsigned int seat,Ecore_Evas_Selection_Buffer buffer,Eina_Content * content)5566 ecore_evas_selection_set(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer buffer, Eina_Content *content)
5567 {
5568    EINA_SAFETY_ON_NULL_RETURN_VAL(ee, EINA_FALSE);
5569    EINA_SAFETY_ON_FALSE_RETURN_VAL(buffer >= 0 && buffer < ECORE_EVAS_SELECTION_BUFFER_LAST, EINA_FALSE);
5570    Eina_Iterator *available_type = NULL;
5571    Eina_Bool success;
5572    Ecore_Evas_Selection_Seat_Buffers *buffers;
5573 
5574    INF("Selection set on seat %d in buffer %d", seat, buffer);
5575 
5576    if (buffer == ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER)
5577      {
5578         ERR("You cannot set a selection with this API, please use the API to start a drag operation");
5579         return EINA_FALSE;
5580      }
5581 
5582    buffers = _fetch_selection_buffers_of_seat(ee, seat, EINA_TRUE);
5583 
5584    if (content)
5585      available_type = eina_content_possible_conversions(content);
5586 
5587    success = CALL(selection_claim)(ee, seat, buffer, _iterator_to_array(available_type, content ? eina_content_type_get(content) : NULL), content ? _deliver_cb : NULL, content ? _cancel_cb : NULL);
5588    if (success)
5589      {
5590         EINA_SAFETY_ON_FALSE_RETURN_VAL(buffers->selection_buffer[buffer] == NULL, EINA_FALSE);
5591         //keep this after the claim, the claim might call cancel, which would overwrite this.
5592         buffers->selection_buffer[buffer] = content;
5593      }
5594    else if (content)
5595      {
5596         eina_content_free(content);
5597      }
5598 
5599    return success;
5600 }
5601 
5602 EAPI Eina_Bool
ecore_evas_selection_exists(Ecore_Evas * ee,unsigned int seat,Ecore_Evas_Selection_Buffer buffer)5603 ecore_evas_selection_exists(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer buffer)
5604 {
5605    EINA_SAFETY_ON_NULL_RETURN_VAL(ee, EINA_FALSE);
5606    EINA_SAFETY_ON_FALSE_RETURN_VAL(buffer >= 0 && buffer < ECORE_EVAS_SELECTION_BUFFER_LAST, EINA_FALSE);
5607    Ecore_Evas_Selection_Seat_Buffers *buffers;
5608 
5609    INF("Exists request on seat %d in buffer %d", seat, buffer);
5610 
5611    buffers = _fetch_selection_buffers_of_seat(ee, seat, EINA_TRUE);
5612    if (buffers->selection_buffer[buffer])
5613      return EINA_TRUE;
5614    else
5615      {
5616         return CALL(selection_has_owner)(ee, seat, buffer);
5617      }
5618 }
5619 
5620 static Eina_Array*
_iterator_to_array_stringshared(Eina_Iterator * iter)5621 _iterator_to_array_stringshared(Eina_Iterator *iter)
5622 {
5623    Eina_Array *ret = eina_array_new(10);
5624    const char *type;
5625 
5626    EINA_ITERATOR_FOREACH(iter, type)
5627      {
5628         eina_array_push(ret, eina_stringshare_add(type));
5629      }
5630    eina_iterator_free(iter);
5631 
5632    return ret;
5633 }
5634 
5635 EAPI Eina_Future*
ecore_evas_selection_get(Ecore_Evas * ee,unsigned int seat,Ecore_Evas_Selection_Buffer buffer,Eina_Iterator * acceptable_types)5636 ecore_evas_selection_get(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer buffer, Eina_Iterator *acceptable_types)
5637 {
5638    EINA_SAFETY_ON_NULL_RETURN_VAL(ee, NULL);
5639    EINA_SAFETY_ON_FALSE_RETURN_VAL(buffer >= 0 && buffer < ECORE_EVAS_SELECTION_BUFFER_LAST, NULL);
5640 
5641    INF("Selection get request on seat %d in buffer %d", seat, buffer);
5642 
5643    return CALL(selection_request)(ee, seat, buffer, _iterator_to_array_stringshared(acceptable_types));
5644 }
5645 
5646 EAPI Eina_Bool
ecore_evas_drag_start(Ecore_Evas * ee,unsigned int seat,Eina_Content * content,Ecore_Evas * drag_rep,const char * action,Ecore_Evas_Drag_Finished_Cb terminate_cb,void * data)5647 ecore_evas_drag_start(Ecore_Evas *ee, unsigned int seat, Eina_Content *content, Ecore_Evas *drag_rep, const char* action, Ecore_Evas_Drag_Finished_Cb terminate_cb, void *data)
5648 {
5649    EINA_SAFETY_ON_NULL_RETURN_VAL(ee, EINA_FALSE);
5650    EINA_SAFETY_ON_NULL_RETURN_VAL(content, EINA_FALSE);
5651    Eina_Iterator *available_type = eina_content_possible_conversions(content);
5652    Eina_Bool success;
5653    Ecore_Evas_Selection_Seat_Buffers *buffers;
5654 
5655    INF("Drag start on seat %d", seat);
5656 
5657    buffers = _fetch_selection_buffers_of_seat(ee, seat, EINA_TRUE);
5658    success = CALL(dnd_start)(ee, seat, _iterator_to_array(available_type, eina_content_type_get(content)), drag_rep, _deliver_cb, _cancel_cb, action);
5659    EINA_SAFETY_ON_FALSE_RETURN_VAL(buffers->selection_buffer[ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER] == NULL, EINA_FALSE);
5660    //keep this after the claim, the claim might call cancel, which would overwrite this.
5661    buffers->selection_buffer[ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER] = content;
5662 
5663    ee->drag.rep = drag_rep;
5664    ee->drag.free = terminate_cb;
5665    ee->drag.data = data;
5666    ee->drag.accepted = EINA_FALSE;
5667 
5668    return success;
5669 }
5670 
5671 EAPI Eina_Bool
ecore_evas_drag_cancel(Ecore_Evas * ee,unsigned int seat)5672 ecore_evas_drag_cancel(Ecore_Evas *ee, unsigned int seat)
5673 {
5674    EINA_SAFETY_ON_NULL_RETURN_VAL(ee, EINA_FALSE);
5675 
5676    INF("Drag cancel on seat %d", seat);
5677 
5678    return CALL(dnd_stop)(ee, seat);
5679 }
5680 
5681 EAPI void
ecore_evas_callback_drop_motion_set(Ecore_Evas * ee,Ecore_Evas_Drag_Motion_Cb cb)5682 ecore_evas_callback_drop_motion_set(Ecore_Evas *ee, Ecore_Evas_Drag_Motion_Cb cb)
5683 {
5684    ECORE_EVAS_CHECK(ee);
5685    ee->func.fn_dnd_motion = cb;
5686 }
5687 
5688 EAPI void
ecore_evas_callback_drop_state_changed_set(Ecore_Evas * ee,Ecore_Evas_Drag_State_Changed_Cb cb)5689 ecore_evas_callback_drop_state_changed_set(Ecore_Evas *ee, Ecore_Evas_Drag_State_Changed_Cb cb)
5690 {
5691    ECORE_EVAS_CHECK(ee);
5692    ee->func.fn_dnd_state_change = cb;
5693 }
5694 
5695 EAPI void
ecore_evas_callback_drop_drop_set(Ecore_Evas * ee,Ecore_Evas_Drop_Cb cb)5696 ecore_evas_callback_drop_drop_set(Ecore_Evas *ee, Ecore_Evas_Drop_Cb cb)
5697 {
5698    ECORE_EVAS_CHECK(ee);
5699    ee->func.fn_dnd_drop = cb;
5700 }
5701 
5702 typedef struct {
5703    Eina_Array *available_mime_types;
5704    Eina_Position2D pos;
5705    Eina_Bool last_motion_was_used;
5706 } Ecore_Evas_Active_Dnd;
5707 
5708 static void
_ecore_evas_active_dnd_free(Ecore_Evas_Active_Dnd * dnd)5709 _ecore_evas_active_dnd_free(Ecore_Evas_Active_Dnd *dnd)
5710 {
5711    eina_array_free(dnd->available_mime_types);
5712    free(dnd);
5713 }
5714 
5715 EAPI void
ecore_evas_dnd_enter(Ecore_Evas * ee,unsigned int seat,Eina_Iterator * available_types,Eina_Position2D pos)5716 ecore_evas_dnd_enter(Ecore_Evas *ee, unsigned int seat, Eina_Iterator *available_types, Eina_Position2D pos)
5717 {
5718    Eina_Stringshare *s;
5719    Ecore_Evas_Active_Dnd *dnd;
5720 
5721    ECORE_EVAS_CHECK(ee);
5722    if (!ee->active_drags)
5723      {
5724         ee->active_drags = eina_hash_int32_new((Eina_Free_Cb)_ecore_evas_active_dnd_free);
5725      }
5726 
5727    dnd = calloc(1, sizeof(Ecore_Evas_Active_Dnd));
5728    dnd->available_mime_types = eina_array_new(5);
5729    eina_hash_add(ee->active_drags, &seat, dnd);
5730 
5731    EINA_ITERATOR_FOREACH(available_types, s)
5732      {
5733         eina_array_push(dnd->available_mime_types, s);
5734      }
5735    eina_iterator_free(available_types);
5736 
5737    if (ee->func.fn_dnd_state_change)
5738      ee->func.fn_dnd_state_change(ee, seat, pos, EINA_TRUE);
5739 }
5740 
5741 EAPI Eina_Bool
ecore_evas_dnd_position_set(Ecore_Evas * ee,unsigned int seat,Eina_Position2D pos)5742 ecore_evas_dnd_position_set(Ecore_Evas *ee, unsigned int seat, Eina_Position2D pos)
5743 {
5744    Ecore_Evas_Active_Dnd *dnd;
5745 
5746    ECORE_EVAS_CHECK_GOTO(ee, err);
5747    EINA_SAFETY_ON_NULL_GOTO(ee->active_drags, err);
5748    dnd = eina_hash_find(ee->active_drags, &seat);
5749    EINA_SAFETY_ON_NULL_GOTO(dnd, err);
5750    dnd->pos = pos;
5751    dnd->last_motion_was_used = EINA_FALSE;
5752    if (ee->func.fn_dnd_motion)
5753      ee->func.fn_dnd_motion(ee, seat, pos);
5754    return dnd->last_motion_was_used;
5755 err:
5756    return EINA_FALSE;
5757 }
5758 
5759 EAPI void
ecore_evas_dnd_mark_motion_used(Ecore_Evas * ee,unsigned int seat)5760 ecore_evas_dnd_mark_motion_used(Ecore_Evas *ee, unsigned int seat)
5761 {
5762    Ecore_Evas_Active_Dnd *dnd;
5763 
5764    ECORE_EVAS_CHECK(ee);
5765    EINA_SAFETY_ON_NULL_RETURN(ee->active_drags);
5766    dnd = eina_hash_find(ee->active_drags, &seat);
5767    EINA_SAFETY_ON_NULL_RETURN(dnd);
5768    dnd->last_motion_was_used = EINA_TRUE;
5769 }
5770 
5771 EAPI void
ecore_evas_dnd_leave(Ecore_Evas * ee,unsigned int seat,Eina_Position2D pos)5772 ecore_evas_dnd_leave(Ecore_Evas *ee, unsigned int seat, Eina_Position2D pos)
5773 {
5774    Ecore_Evas_Active_Dnd *dnd;
5775 
5776    ECORE_EVAS_CHECK(ee);
5777    EINA_SAFETY_ON_NULL_RETURN(ee->active_drags);
5778    dnd = eina_hash_find(ee->active_drags, &seat);
5779    EINA_SAFETY_ON_NULL_RETURN(dnd);
5780 
5781    if (ee->func.fn_dnd_state_change)
5782      ee->func.fn_dnd_state_change(ee, seat, pos, EINA_FALSE);
5783    eina_hash_del(ee->active_drags, &seat, dnd);
5784    if (eina_hash_population(ee->active_drags) == 0)
5785      {
5786         eina_hash_free(ee->active_drags);
5787         ee->active_drags = NULL;
5788      }
5789 }
5790 
5791 EAPI Eina_Position2D
ecore_evas_dnd_pos_get(Ecore_Evas * ee,unsigned int seat)5792 ecore_evas_dnd_pos_get(Ecore_Evas *ee, unsigned int seat)
5793 {
5794    Ecore_Evas_Active_Dnd *dnd;
5795 
5796    ECORE_EVAS_CHECK_GOTO(ee, err);
5797    EINA_SAFETY_ON_NULL_RETURN_VAL(ee->active_drags, EINA_POSITION2D(0, 0));
5798    dnd = eina_hash_find(ee->active_drags, &seat);
5799    EINA_SAFETY_ON_NULL_RETURN_VAL(dnd, EINA_POSITION2D(0, 0));
5800 
5801    return dnd->pos;
5802 err:
5803    return EINA_POSITION2D(0, 0);
5804 }
5805 
5806 EAPI Eina_Accessor*
ecore_evas_drop_available_types_get(Ecore_Evas * ee,unsigned int seat)5807 ecore_evas_drop_available_types_get(Ecore_Evas *ee, unsigned int seat)
5808 {
5809    Ecore_Evas_Active_Dnd *dnd;
5810 
5811    ECORE_EVAS_CHECK_GOTO(ee, err);
5812    EINA_SAFETY_ON_NULL_RETURN_VAL(ee->active_drags, NULL);
5813    dnd = eina_hash_find(ee->active_drags, &seat);
5814    EINA_SAFETY_ON_NULL_RETURN_VAL(dnd, NULL);
5815 
5816    return eina_array_accessor_new(dnd->available_mime_types);
5817 err:
5818    return NULL;
5819 }
5820