cc7f02f29d1db3fe1e1330781cb9eb3d44bc91b3
[platform/upstream/efl.git] / src / lib / ecore_evas / ecore_evas.c
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 #define ECORE_EVAS_INTERNAL
6 #define EFL_INPUT_EVENT_PROTECTED
7
8 #include <stdlib.h>
9 #include <string.h>
10 #include <sys/types.h>
11 #include <errno.h>
12 #include <sys/stat.h>
13 #include <fcntl.h>
14
15 #ifndef _MSC_VER
16 # include <unistd.h>
17 #endif
18
19 #if defined(HAVE_SYS_MMAN_H) || defined(HAVE_EVIL)
20 # include <sys/mman.h>
21 #endif
22
23 #ifdef HAVE_EVIL
24 # include <Evil.h>
25 #endif
26
27 #include <Ecore.h>
28 #include "ecore_private.h"
29 #include <Ecore_Input.h>
30 #include <Ecore_Input_Evas.h>
31
32 #include "Ecore_Evas.h"
33 #include "ecore_evas_private.h"
34 #include "ecore_evas_x11.h"
35 #include "ecore_evas_wayland.h"
36 #include "ecore_evas_cocoa.h"
37 #include "ecore_evas_extn.h"
38 #include "ecore_evas_win32.h"
39
40 #define EFL_INTERNAL_UNSTABLE
41 #include "interfaces/efl_common_internal.h"
42
43 #ifndef O_BINARY
44 # define O_BINARY 0
45 #endif
46
47 #define ECORE_EVAS_CHECK(ee, ...) \
48    if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) \
49      { \
50         ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, __FUNCTION__); \
51         return __VA_ARGS__; \
52      }
53
54 EAPI Eina_Bool _ecore_evas_app_comp_sync = EINA_FALSE;
55 EAPI int _ecore_evas_log_dom = -1;
56 static int _ecore_evas_init_count = 0;
57 static Ecore_Fd_Handler *_ecore_evas_async_events_fd = NULL;
58 static Eina_Bool _ecore_evas_async_events_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
59
60 static Ecore_Idle_Enterer *ecore_evas_idle_enterer = NULL;
61 static Ecore_Evas *ecore_evases = NULL;
62 static int _ecore_evas_fps_debug = 0;
63
64 //RENDER_SYNC
65 static int _ecore_evas_render_sync = 1;
66 static Ecore_Animator *ecore_evas_animator = NULL;
67 static Eina_Bool ecore_evas_animator_ticked = EINA_FALSE;
68 static Eina_Bool ecore_evas_first = EINA_TRUE;
69 static int overtick = 0;
70
71 static Eina_Bool
72 _ecore_evas_animator(void *data EINA_UNUSED)
73 {
74    ecore_evas_animator_ticked = EINA_TRUE;
75    overtick--;
76    if (overtick == 0)
77      {
78         ecore_evas_animator = NULL;
79         return EINA_FALSE;
80      }
81    return EINA_TRUE;
82 }
83
84 static Eina_Bool
85 _ecore_evas_changes_get(Ecore_Evas *ee)
86 {
87    Eina_List *l;
88
89    if (evas_changed_get(ee->evas)) return EINA_TRUE;
90    EINA_LIST_FOREACH(ee->sub_ecore_evas, l, ee)
91      {
92         if (evas_changed_get(ee->evas)) return EINA_TRUE;
93      }
94    return EINA_FALSE;
95 }
96
97 static Eina_Bool
98 _ecore_evas_changes_check(void)
99 {
100    Ecore_Evas *ee;
101
102    EINA_INLIST_FOREACH(ecore_evases, ee)
103      {
104         if (_ecore_evas_changes_get(ee)) return EINA_TRUE;
105      }
106    return EINA_FALSE;
107 }
108
109 static Eina_Bool
110 _ecore_evas_idle_enter(void *data EINA_UNUSED)
111 {
112    Ecore_Evas *ee;
113    double t1 = 0.0;
114    double t2 = 0.0;
115    int rend = 0;
116 #ifdef ECORE_EVAS_ASYNC_RENDER_DEBUG
117    double now = ecore_loop_time_get();
118 #endif
119
120    if (!ecore_evases) return ECORE_CALLBACK_RENEW;
121
122    if (_ecore_evas_render_sync)
123      {
124         if (!ecore_evas_first)
125           {
126              if ((!ecore_evas_animator_ticked) &&
127                  (!ecore_main_loop_animator_ticked_get()))
128                {
129                   if (_ecore_evas_changes_check())
130                     {
131                        if (!ecore_evas_animator)
132                          {
133                             overtick = 1;
134                             ecore_evas_animator = ecore_animator_add(_ecore_evas_animator, NULL);
135                          }
136                     }
137                   return ECORE_CALLBACK_RENEW;
138                }
139              ecore_evas_animator_ticked = EINA_FALSE;
140           }
141         ecore_evas_first = EINA_FALSE;
142      }
143
144    if (_ecore_evas_fps_debug)
145      {
146         t1 = ecore_time_get();
147      }
148    EINA_INLIST_FOREACH(ecore_evases, ee)
149      {
150 #ifdef ECORE_EVAS_ASYNC_RENDER_DEBUG
151         if ((ee->in_async_render) && (now - ee->async_render_start > 2.0))
152           {
153              ERR("stuck async render: time=%f, ee=%p, engine=%s, geometry=(%d, %d, %d, %d), visible=%hhu, shaped=%hhu, alpha=%hhu, transparent=%hhu",
154                  now - ee->async_render_start, ee, ee->driver, ee->x, ee->y, ee->w, ee->h, ee->visible, ee->shaped, ee->alpha, ee->transparent);
155
156              ERR("delayed.avoid_damage=%hhu", ee->delayed.avoid_damage);
157              ERR("delayed.resize_shape=%hhu", ee->delayed.resize_shape);
158              ERR("delayed.shaped=%hhu", ee->delayed.shaped);
159              ERR("delayed.shaped_changed=%hhu", ee->delayed.shaped_changed);
160              ERR("delayed.alpha=%hhu", ee->delayed.alpha);
161              ERR("delayed.alpha_changed=%hhu", ee->delayed.alpha_changed);
162              ERR("delayed.transparent=%hhu", ee->delayed.transparent);
163              ERR("delayed.transparent_changed=%hhu", ee->delayed.transparent_changed);
164              ERR("delayed.rotation=%d", ee->delayed.rotation);
165              ERR("delayed.rotation_resize=%d", ee->delayed.rotation_resize);
166              ERR("delayed.rotation_changed=%d", ee->delayed.rotation_changed);
167
168              ERR("reset in_async_render of ee=%p", ee);
169              ee->in_async_render = EINA_FALSE;
170              ee->async_render_start = 0.0;
171
172           }
173         else if ((!ee->in_async_render) && (ee->async_render_start > 0.0))
174           {
175              DBG("--- async render %f ee=%p [%s] (%d, %d, %d, %d) visible=%hhu shaped=%hhu alpha=%hhu transparent=%hhu",
176                  now, ee, ee->driver, ee->x, ee->y, ee->w, ee->h, ee->visible, ee->shaped, ee->alpha, ee->transparent);
177              ee->async_render_start = 0.0;
178           }
179 #endif
180
181         if (!ee->manual_render)
182           {
183              if (ee->engine.func->fn_render)
184                rend |= ee->engine.func->fn_render(ee);
185               /*
186                * Some engines that generate their own ticks based on hardware
187                * events need to know that render has been considered, and
188                * whether it will actually generate a new image or not
189                */
190              if (ee->engine.func->fn_evas_changed)
191                ee->engine.func->fn_evas_changed(ee, rend);
192           }
193 #ifdef ECORE_EVAS_ASYNC_RENDER_DEBUG
194         if ((ee->in_async_render) && (ee->async_render_start <= 0.0))
195           {
196              DBG("+++ async render %f ee=%p [%s] (%d, %d, %d, %d) visible=%hhu shaped=%hhu alpha=%hhu transparent=%hhu",
197                  now, ee, ee->driver, ee->x, ee->y, ee->w, ee->h, ee->visible, ee->shaped, ee->alpha, ee->transparent);
198              ee->async_render_start = now;
199           }
200 #endif
201      }
202    if (_ecore_evas_fps_debug)
203      {
204         t2 = ecore_time_get();
205         if (rend)
206           _ecore_evas_fps_debug_rendertime_add(t2 - t1);
207      }
208    return ECORE_CALLBACK_RENEW;
209 }
210
211 EAPI Ecore_Evas_Interface *
212 _ecore_evas_interface_get(const Ecore_Evas *ee, const char *iname)
213 {
214    Eina_List *l;
215    Ecore_Evas_Interface *i;
216
217    EINA_SAFETY_ON_NULL_RETURN_VAL(ee, NULL);
218    EINA_SAFETY_ON_NULL_RETURN_VAL(iname, NULL);
219
220    EINA_LIST_FOREACH(ee->engine.ifaces, l, i)
221      {
222         if (!strcmp(i->name, iname))
223           return i;
224      }
225
226    CRI("Ecore_Evas %p (engine: %s) does not have interface '%s'",
227         ee, ee->driver, iname);
228
229    return NULL;
230 }
231
232 /**
233  * Query if a particular rendering engine target has support
234  * @param  engine The engine to check support for
235  * @return 1 if the particular engine is supported, 0 if it is not
236  *
237  * Query if engine @param engine is supported by ecore_evas. 1 is returned if
238  * it is, and 0 is returned if it is not supported.
239  */
240 EAPI int
241 ecore_evas_engine_type_supported_get(Ecore_Evas_Engine_Type engine)
242 {
243    /* It should be done reading the availables engines */
244
245    switch (engine)
246      {
247       case ECORE_EVAS_ENGINE_SOFTWARE_BUFFER:
248         return EINA_TRUE;
249
250       case ECORE_EVAS_ENGINE_SOFTWARE_XLIB:
251 #ifdef BUILD_ECORE_EVAS_SOFTWARE_XLIB
252         return EINA_TRUE;
253 #else
254         return EINA_FALSE;
255 #endif
256       case ECORE_EVAS_ENGINE_XRENDER_X11:
257         return EINA_FALSE;
258       case ECORE_EVAS_ENGINE_OPENGL_X11:
259 #ifdef BUILD_ECORE_EVAS_OPENGL_X11
260         return EINA_TRUE;
261 #else
262         return EINA_FALSE;
263 #endif
264       case ECORE_EVAS_ENGINE_SOFTWARE_XCB:
265 #ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB
266         return EINA_TRUE;
267 #else
268         return EINA_FALSE;
269 #endif
270       case ECORE_EVAS_ENGINE_XRENDER_XCB:
271         return EINA_FALSE;
272       case ECORE_EVAS_ENGINE_SOFTWARE_GDI:
273 #ifdef BUILD_ECORE_EVAS_SOFTWARE_GDI
274         return EINA_TRUE;
275 #else
276         return EINA_FALSE;
277 #endif
278       case ECORE_EVAS_ENGINE_SOFTWARE_DDRAW:
279 #ifdef BUILD_ECORE_EVAS_SOFTWARE_DDRAW
280         return EINA_TRUE;
281 #else
282         return EINA_FALSE;
283 #endif
284      case ECORE_EVAS_ENGINE_SOFTWARE_SDL:
285 #ifdef BUILD_ECORE_EVAS_SOFTWARE_SDL
286         return EINA_TRUE;
287 #else
288         return EINA_FALSE;
289 #endif
290      case ECORE_EVAS_ENGINE_OPENGL_SDL:
291 #ifdef BUILD_ECORE_EVAS_OPENGL_SDL
292         return EINA_TRUE;
293 #else
294         return EINA_FALSE;
295 #endif
296       case ECORE_EVAS_ENGINE_DIRECTFB:
297         return EINA_FALSE;
298       case ECORE_EVAS_ENGINE_SOFTWARE_FB:
299 #ifdef BUILD_ECORE_EVAS_FB
300         return EINA_TRUE;
301 #else
302         return EINA_FALSE;
303 #endif
304
305       case ECORE_EVAS_ENGINE_SOFTWARE_8_X11:
306         return EINA_FALSE;
307       case ECORE_EVAS_ENGINE_SOFTWARE_16_X11:
308         return EINA_FALSE;
309       case ECORE_EVAS_ENGINE_SOFTWARE_16_DDRAW:
310         return EINA_FALSE;
311       case ECORE_EVAS_ENGINE_SOFTWARE_16_WINCE:
312         return EINA_FALSE;
313       case ECORE_EVAS_ENGINE_DIRECT3D:
314         return EINA_FALSE;
315       case ECORE_EVAS_ENGINE_OPENGL_GLEW:
316         return EINA_FALSE;
317
318       case ECORE_EVAS_ENGINE_OPENGL_COCOA:
319 #ifdef BUILD_ECORE_EVAS_OPENGL_COCOA
320         return EINA_TRUE;
321 #else
322         return EINA_FALSE;
323 #endif
324       case ECORE_EVAS_ENGINE_EWS:
325 #ifdef BUILD_ECORE_EVAS_EWS
326         return EINA_TRUE;
327 #else
328         return EINA_FALSE;
329 #endif
330      case ECORE_EVAS_ENGINE_PSL1GHT:
331 #ifdef BUILD_ECORE_EVAS_PSL1GHT
332         return EINA_TRUE;
333 #else
334         return EINA_FALSE;
335 #endif
336      case ECORE_EVAS_ENGINE_WAYLAND_SHM:
337 #ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
338         return EINA_TRUE;
339 #else
340         return EINA_FALSE;
341 #endif
342      case ECORE_EVAS_ENGINE_WAYLAND_EGL:
343 #ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
344         return EINA_TRUE;
345 #else
346         return EINA_FALSE;
347 #endif
348      case ECORE_EVAS_ENGINE_DRM:
349 #ifdef BUILD_ECORE_EVAS_DRM
350         return EINA_TRUE;
351 #else
352         return EINA_FALSE;
353 #endif
354      case ECORE_EVAS_ENGINE_OPENGL_DRM:
355 #ifdef BUILD_ECORE_EVAS_GL_DRM
356         return EINA_TRUE;
357 #else
358         return EINA_FALSE;
359 #endif
360
361       default:
362         return EINA_FALSE;
363      };
364 }
365
366 static void
367 _ecore_evas_fork_cb(void *data EINA_UNUSED)
368 {
369    int fd;
370    
371    if (_ecore_evas_async_events_fd)
372      ecore_main_fd_handler_del(_ecore_evas_async_events_fd);
373    fd = evas_async_events_fd_get();
374    if (fd >= 0)
375      _ecore_evas_async_events_fd = 
376      ecore_main_fd_handler_add(fd, ECORE_FD_READ,
377                                _ecore_evas_async_events_fd_handler, NULL,
378                                NULL, NULL);
379 }
380
381 EAPI int
382 ecore_evas_init(void)
383 {
384    int fd;
385
386    if (++_ecore_evas_init_count != 1)
387      return _ecore_evas_init_count;
388
389    if (!evas_init())
390      return --_ecore_evas_init_count;
391
392    if (!ecore_init())
393      goto shutdown_evas;
394
395    _ecore_evas_log_dom = eina_log_domain_register
396      ("ecore_evas", ECORE_EVAS_DEFAULT_LOG_COLOR);
397    if(_ecore_evas_log_dom < 0)
398      {
399         EINA_LOG_ERR("Impossible to create a log domain for Ecore_Evas.");
400         goto shutdown_ecore;
401      }
402
403    ecore_fork_reset_callback_add(_ecore_evas_fork_cb, NULL);
404    fd = evas_async_events_fd_get();
405    if (fd >= 0)
406      _ecore_evas_async_events_fd = 
407      ecore_main_fd_handler_add(fd, ECORE_FD_READ,
408                                _ecore_evas_async_events_fd_handler, NULL,
409                                NULL, NULL);
410
411    ecore_evas_idle_enterer =
412      ecore_idle_enterer_add(_ecore_evas_idle_enter, NULL);
413    if (getenv("ECORE_EVAS_FPS_DEBUG")) _ecore_evas_fps_debug = 1;
414    if (getenv("ECORE_EVAS_RENDER_NOSYNC")) _ecore_evas_render_sync = 0;
415    if (_ecore_evas_fps_debug) _ecore_evas_fps_debug_init();
416
417 #ifdef BUILD_ECORE_EVAS_EWS
418    _ecore_evas_ews_events_init();
419 #endif
420
421    _ecore_evas_extn_init();
422
423    _ecore_evas_engine_init();
424
425    eina_log_timing(_ecore_evas_log_dom,
426                    EINA_LOG_STATE_STOP,
427                    EINA_LOG_STATE_INIT);
428
429    if (getenv("ECORE_EVAS_COMP_NOSYNC"))
430      _ecore_evas_app_comp_sync = EINA_FALSE;
431    else if (getenv("ECORE_EVAS_COMP_SYNC"))
432      _ecore_evas_app_comp_sync = EINA_TRUE;
433    return _ecore_evas_init_count;
434
435  shutdown_ecore:
436    ecore_shutdown();
437  shutdown_evas:
438    evas_shutdown();
439
440    return --_ecore_evas_init_count;
441 }
442
443 EAPI int
444 ecore_evas_shutdown(void)
445 {
446    if (--_ecore_evas_init_count != 0)
447      return _ecore_evas_init_count;
448
449    eina_log_timing(_ecore_evas_log_dom,
450                    EINA_LOG_STATE_START,
451                    EINA_LOG_STATE_SHUTDOWN);
452
453    while (ecore_evases) _ecore_evas_free(ecore_evases);
454
455    if (_ecore_evas_fps_debug) _ecore_evas_fps_debug_shutdown();
456    ecore_idle_enterer_del(ecore_evas_idle_enterer);
457    ecore_evas_idle_enterer = NULL;
458
459    if (_ecore_evas_render_sync)
460      {
461         if (ecore_evas_animator) ecore_animator_del(ecore_evas_animator);
462         ecore_evas_animator = NULL;
463      }
464
465    _ecore_evas_extn_shutdown();
466
467 #ifdef BUILD_ECORE_EVAS_EWS
468    while (_ecore_evas_ews_shutdown());
469 #endif
470    _ecore_evas_engine_shutdown();
471    if (_ecore_evas_async_events_fd)
472      ecore_main_fd_handler_del(_ecore_evas_async_events_fd);
473    
474    ecore_fork_reset_callback_del(_ecore_evas_fork_cb, NULL);
475
476    eina_log_domain_unregister(_ecore_evas_log_dom);
477    _ecore_evas_log_dom = -1;
478    ecore_shutdown();
479    evas_shutdown();
480
481    return _ecore_evas_init_count;
482 }
483
484 EAPI void
485 ecore_evas_app_comp_sync_set(Eina_Bool do_sync)
486 {
487    _ecore_evas_app_comp_sync = do_sync;
488 }
489
490 EAPI Eina_Bool
491 ecore_evas_app_comp_sync_get(void)
492 {
493    return _ecore_evas_app_comp_sync;
494 }
495
496 struct ecore_evas_engine {
497    const char *name;
498    Ecore_Evas *(*constructor)(int x, int y, int w, int h, const char *extra_options);
499 };
500
501 /* inline is just to avoid need to ifdef around it */
502 static inline const char *
503 _ecore_evas_parse_extra_options_str(const char *extra_options, const char *key, char **value)
504 {
505    int len = strlen(key);
506
507    while (extra_options)
508      {
509         const char *p;
510
511         if (strncmp(extra_options, key, len) != 0)
512           {
513              extra_options = strchr(extra_options, ';');
514              if (extra_options)
515                extra_options++;
516              continue;
517           }
518
519         extra_options += len;
520         p = strchr(extra_options, ';');
521         if (p)
522           {
523              len = p - extra_options;
524              *value = malloc(len + 1);
525              memcpy(*value, extra_options, len);
526              (*value)[len] = '\0';
527              extra_options = p + 1;
528           }
529         else
530           {
531              *value = strdup(extra_options);
532              extra_options = NULL;
533           }
534      }
535    return extra_options;
536 }
537
538 /* inline is just to avoid need to ifdef around it */
539 static inline const char *
540 _ecore_evas_parse_extra_options_uint(const char *extra_options, const char *key, unsigned int *value)
541 {
542    int len = strlen(key);
543
544    while (extra_options)
545      {
546         const char *p;
547
548         if (strncmp(extra_options, key, len) != 0)
549           {
550              extra_options = strchr(extra_options, ';');
551              if (extra_options)
552                extra_options++;
553              continue;
554           }
555
556         extra_options += len;
557         *value = strtol(extra_options, NULL, 0);
558
559         p = strchr(extra_options, ';');
560         if (p)
561           extra_options = p + 1;
562         else
563           extra_options = NULL;
564      }
565    return extra_options;
566 }
567
568 /* inline is just to avoid need to ifdef around it */
569 static inline const char *
570 _ecore_evas_parse_extra_options_x(const char *extra_options, char **disp_name, unsigned int *parent)
571 {
572    _ecore_evas_parse_extra_options_str(extra_options, "display=", disp_name);
573    _ecore_evas_parse_extra_options_uint(extra_options, "parent=", parent);
574    return extra_options;
575 }
576
577 static Ecore_Evas *
578 _ecore_evas_constructor_software_x11(int x, int y, int w, int h, const char *extra_options)
579 {
580    unsigned int parent = 0;
581    char *disp_name = NULL;
582    Ecore_Evas *ee;
583
584    _ecore_evas_parse_extra_options_x(extra_options, &disp_name, &parent);
585    ee = ecore_evas_software_x11_new(disp_name, parent, x, y, w, h);
586    free(disp_name);
587
588    return ee;
589 }
590
591 static Ecore_Evas *
592 _ecore_evas_constructor_cocoa(int x, int y, int w, int h, const char *extra_options)
593 {
594    char *name = NULL;
595    Ecore_Evas *ee;
596
597    _ecore_evas_parse_extra_options_str(extra_options, "name=", &name);
598    ee = ecore_evas_cocoa_new(NULL, x, y, w, h);
599    free(name);
600
601    if (ee) ecore_evas_move(ee, x, y);
602    return ee;
603 }
604
605 static Ecore_Evas *
606 _ecore_evas_constructor_opengl_x11(int x, int y, int w, int h, const char *extra_options)
607 {
608    Ecore_X_Window parent = 0;
609    char *disp_name = NULL;
610    Ecore_Evas *ee;
611
612    _ecore_evas_parse_extra_options_x(extra_options, &disp_name, &parent);
613    ee = ecore_evas_gl_x11_new(disp_name, parent, x, y, w, h);
614    free(disp_name);
615
616    return ee;
617 }
618
619 static Ecore_Evas *
620 _ecore_evas_constructor_sdl(int x EINA_UNUSED, int y EINA_UNUSED, int w, int h, const char *extra_options)
621 {
622    Ecore_Evas *ee;
623    unsigned int fullscreen = 0, hwsurface = 0, noframe = 0, alpha = 0;
624    char *name = NULL;
625
626    _ecore_evas_parse_extra_options_str(extra_options, "name=", &name);
627    _ecore_evas_parse_extra_options_uint(extra_options, "fullscreen=", &fullscreen);
628    _ecore_evas_parse_extra_options_uint(extra_options, "hwsurface=", &hwsurface);
629    _ecore_evas_parse_extra_options_uint(extra_options, "noframe=", &noframe);
630    _ecore_evas_parse_extra_options_uint(extra_options, "alpha=", &alpha);
631
632    ee = ecore_evas_sdl_new(name, w, h, fullscreen, hwsurface, noframe, alpha);
633    free(name);
634
635    return ee;
636 }
637 static Ecore_Evas *
638 _ecore_evas_constructor_opengl_sdl(int x EINA_UNUSED, int y EINA_UNUSED, int w, int h, const char *extra_options)
639 {
640    Ecore_Evas *ee;
641    unsigned int fullscreen = 0, noframe = 0;
642    char *name = NULL;
643
644    _ecore_evas_parse_extra_options_str(extra_options, "name=", &name);
645    _ecore_evas_parse_extra_options_uint(extra_options, "fullscreen=", &fullscreen);
646    _ecore_evas_parse_extra_options_uint(extra_options, "noframe=", &noframe);
647
648    ee = ecore_evas_gl_sdl_new(name, w, h, fullscreen, noframe);
649    free(name);
650
651    return ee;
652 }
653
654 static Ecore_Evas *
655 _ecore_evas_constructor_fb(int x EINA_UNUSED, int y EINA_UNUSED, int w, int h, const char *extra_options)
656 {
657    Ecore_Evas *ee;
658    char *disp_name = NULL;
659    unsigned int rotation = 0;
660
661    _ecore_evas_parse_extra_options_str(extra_options, "display=", &disp_name);
662    _ecore_evas_parse_extra_options_uint(extra_options, "rotation=", &rotation);
663
664    ee = ecore_evas_fb_new(disp_name, rotation, w, h);
665    free(disp_name);
666
667    return ee;
668 }
669
670 static Ecore_Evas *
671 _ecore_evas_constructor_psl1ght(int x EINA_UNUSED, int y EINA_UNUSED, int w, int h, const char *extra_options)
672 {
673    Ecore_Evas *ee;
674    char *name = NULL;
675
676    _ecore_evas_parse_extra_options_str(extra_options, "name=", &name);
677    ee = ecore_evas_psl1ght_new(name, w, h);
678    free(name);
679
680    if (ee) ecore_evas_move(ee, x, y);
681    return ee;
682 }
683
684 static Ecore_Evas *
685 _ecore_evas_constructor_wayland_shm(int x, int y, int w, int h, const char *extra_options)
686 {
687    char *disp_name = NULL;
688    unsigned int frame = 0, parent = 0;
689    Ecore_Evas *ee;
690
691    _ecore_evas_parse_extra_options_str(extra_options, "display=", &disp_name);
692    _ecore_evas_parse_extra_options_uint(extra_options, "frame=", &frame);
693    _ecore_evas_parse_extra_options_uint(extra_options, "parent=", &parent);
694    ee = ecore_evas_wayland_shm_new(disp_name, parent, x, y, w, h, frame);
695    free(disp_name);
696
697    return ee;
698 }
699
700 static Ecore_Evas *
701 _ecore_evas_constructor_wayland_egl(int x, int y, int w, int h, const char *extra_options)
702 {
703    char *disp_name = NULL;
704    unsigned int frame = 0, parent = 0;
705    Ecore_Evas *ee;
706
707    _ecore_evas_parse_extra_options_str(extra_options, "display=", &disp_name);
708    _ecore_evas_parse_extra_options_uint(extra_options, "frame=", &frame);
709    _ecore_evas_parse_extra_options_uint(extra_options, "parent=", &parent);
710    ee = ecore_evas_wayland_egl_new(disp_name, parent, x, y, w, h, frame);
711    free(disp_name);
712
713    return ee;
714 }
715
716 static Ecore_Evas *
717 _ecore_evas_constructor_drm(int x, int y, int w, int h, const char *extra_options)
718 {
719    char *device = NULL;
720    unsigned int parent = 0;
721    Ecore_Evas *ee;
722
723    _ecore_evas_parse_extra_options_str(extra_options, "device=", &device);
724    _ecore_evas_parse_extra_options_uint(extra_options, "parent=", &parent);
725    ee = ecore_evas_drm_new(device, parent, x, y, w, h);
726    free(device);
727
728    return ee;
729 }
730
731 static Ecore_Evas *
732 _ecore_evas_constructor_opengl_drm(int x, int y, int w, int h, const char *extra_options)
733 {
734    char *device = NULL;
735    unsigned int parent = 0;
736    Ecore_Evas *ee;
737
738    _ecore_evas_parse_extra_options_str(extra_options, "device=", &device);
739    _ecore_evas_parse_extra_options_uint(extra_options, "parent=", &parent);
740    ee = ecore_evas_gl_drm_new(device, parent, x, y, w, h);
741    free(device);
742
743    return ee;
744 }
745
746 static Ecore_Evas *
747 _ecore_evas_constructor_software_gdi(int x, int y, int w, int h,
748                                      const char *extra_options EINA_UNUSED)
749 {
750    return ecore_evas_software_gdi_new(NULL, x, y, w, h);
751 }
752
753 static Ecore_Evas *
754 _ecore_evas_constructor_software_ddraw(int x, int y, int w, int h,
755                                        const char *extra_options EINA_UNUSED)
756 {
757    return ecore_evas_software_ddraw_new(NULL, x, y, w, h);
758 }
759
760 static Ecore_Evas *
761 _ecore_evas_constructor_direct3d(int x, int y, int w, int h,
762                                  const char *extra_options EINA_UNUSED)
763 {
764    return ecore_evas_direct3d_new(NULL, x, y, w, h);
765 }
766
767 static Ecore_Evas *
768 _ecore_evas_constructor_opengl_glew(int x, int y, int w, int h,
769                                     const char *extra_options EINA_UNUSED)
770 {
771    return ecore_evas_gl_glew_new(NULL, x, y, w, h);
772 }
773
774 static Ecore_Evas *
775 _ecore_evas_constructor_buffer(int x EINA_UNUSED, int y EINA_UNUSED, int w, int h, const char *extra_options EINA_UNUSED)
776 {
777    return ecore_evas_buffer_new(w, h);
778 }
779
780 #ifdef BUILD_ECORE_EVAS_EWS
781 static Ecore_Evas *
782 _ecore_evas_constructor_ews(int x, int y, int w, int h, const char *extra_options EINA_UNUSED)
783 {
784    return ecore_evas_ews_new(x, y, w, h);
785 }
786 #endif
787
788 /* note: keep sorted by priority, highest first */
789 static const struct ecore_evas_engine _engines[] = {
790   /* unix */
791   {"software_x11", _ecore_evas_constructor_software_x11},
792   {"opengl_x11", _ecore_evas_constructor_opengl_x11},
793   {"fb", _ecore_evas_constructor_fb},
794   {"software_gdi", _ecore_evas_constructor_software_gdi},
795   {"software_ddraw", _ecore_evas_constructor_software_ddraw},
796   {"direct3d", _ecore_evas_constructor_direct3d},
797   {"opengl_glew", _ecore_evas_constructor_opengl_glew},
798   {"opengl_cocoa", _ecore_evas_constructor_cocoa},
799   {"psl1ght", _ecore_evas_constructor_psl1ght},
800   {"wayland_shm", _ecore_evas_constructor_wayland_shm},
801   {"wayland_egl", _ecore_evas_constructor_wayland_egl},
802   {"drm", _ecore_evas_constructor_drm},
803   {"gl_drm", _ecore_evas_constructor_opengl_drm},
804   {"opengl_sdl", _ecore_evas_constructor_opengl_sdl},
805   {"sdl", _ecore_evas_constructor_sdl},
806   {"buffer", _ecore_evas_constructor_buffer},
807 #ifdef BUILD_ECORE_EVAS_EWS
808   {"ews", _ecore_evas_constructor_ews},
809 #endif
810   {NULL, NULL}
811 };
812
813 EAPI Eina_List *
814 ecore_evas_engines_get(void)
815 {
816    return eina_list_clone(_ecore_evas_available_engines_get());
817 }
818
819 EAPI void
820 ecore_evas_engines_free(Eina_List *engines)
821 {
822    eina_list_free(engines);
823 }
824
825 static Ecore_Evas *
826 _ecore_evas_new_auto_discover(int x, int y, int w, int h, const char *extra_options)
827 {
828    const struct ecore_evas_engine *itr;
829
830    DBG("auto discover engine");
831
832    for (itr = _engines; itr->constructor; itr++)
833      {
834         Ecore_Evas *ee = itr->constructor(x, y, w, h, extra_options);
835         if (ee)
836           {
837              INF("auto discovered '%s'", itr->name);
838              return ee;
839           }
840      }
841
842    WRN("could not auto discover.");
843    return NULL;
844 }
845
846 EAPI Ecore_Evas *
847 ecore_evas_new(const char *engine_name, int x, int y, int w, int h, const char *extra_options)
848 {
849    const struct ecore_evas_engine *itr;
850
851    if (!engine_name)
852      {
853         engine_name = getenv("ECORE_EVAS_ENGINE");
854         if (engine_name)
855           DBG("no engine_name provided, using ECORE_EVAS_ENGINE='%s'",
856               engine_name);
857      }
858    if (!engine_name)
859      return _ecore_evas_new_auto_discover(x, y, w, h, extra_options);
860
861    for (itr = _engines; itr->name; itr++)
862      if (strcmp(itr->name, engine_name) == 0)
863        {
864           INF("using engine '%s', extra_options=%s",
865               engine_name, extra_options ? extra_options : "(null)");
866           return itr->constructor(x, y, w, h, extra_options);
867        }
868
869    WRN("unknown engine '%s'", engine_name);
870    return NULL;
871 }
872
873 EAPI const char *
874 ecore_evas_engine_name_get(const Ecore_Evas *ee)
875 {
876    if (!ee)
877      return NULL;
878    return ee->driver;
879 }
880
881 EAPI Ecore_Evas *
882 ecore_evas_ecore_evas_get(const Evas *e)
883 {
884    Ecore_Evas *ee = evas_data_attach_get(e);
885    if (!ee) return NULL;
886    ECORE_EVAS_CHECK(ee, NULL);
887    return ee;
888 }
889
890 EAPI void
891 ecore_evas_free(Ecore_Evas *ee)
892 {
893    if (!ee) return;
894    ECORE_EVAS_CHECK(ee);
895    _ecore_evas_free(ee);
896    return;
897 }
898
899 EAPI void *
900 ecore_evas_data_get(const Ecore_Evas *ee, const char *key)
901 {
902    ECORE_EVAS_CHECK(ee, NULL);
903
904    if (!key) return NULL;
905    if (!ee->data) return NULL;
906
907    return eina_hash_find(ee->data, key);
908 }
909
910 EAPI void
911 ecore_evas_data_set(Ecore_Evas *ee, const char *key, const void *data)
912 {
913    ECORE_EVAS_CHECK(ee);
914
915    if (!key) return;
916
917    if (ee->data)
918      eina_hash_del(ee->data, key, NULL);
919    if (data)
920      {
921        if (!ee->data)
922          ee->data = eina_hash_string_superfast_new(NULL);
923        eina_hash_add(ee->data, key, data);
924      }
925 }
926
927 EAPI Evas *
928 ecore_evas_object_evas_get(Evas_Object *obj)
929 {
930    Ecore_Evas *ee;
931
932    ee = evas_object_data_get(obj, "Ecore_Evas");
933    if (!ee) return NULL;
934
935    return ecore_evas_get(ee);
936 }
937
938 EAPI Ecore_Evas *
939 ecore_evas_object_ecore_evas_get(Evas_Object *obj)
940 {
941    return evas_object_data_get(obj, "Ecore_Evas");
942 }
943
944 #define IFC(_ee, _fn)  if (_ee->engine.func->_fn) {_ee->engine.func->_fn
945 #define IFE            return;}
946
947 EAPI void
948 ecore_evas_callback_resize_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
949 {
950    ECORE_EVAS_CHECK(ee);
951    IFC(ee, fn_callback_resize_set) (ee, func);
952    IFE;
953    ee->func.fn_resize = func;
954 }
955
956 EAPI void
957 ecore_evas_callback_move_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
958 {
959    ECORE_EVAS_CHECK(ee);
960    IFC(ee, fn_callback_move_set) (ee, func);
961    IFE;
962    ee->func.fn_move = func;
963 }
964
965 EAPI void
966 ecore_evas_callback_show_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
967 {
968    ECORE_EVAS_CHECK(ee);
969    IFC(ee, fn_callback_show_set) (ee, func);
970    IFE;
971    ee->func.fn_show = func;
972 }
973
974 EAPI void
975 ecore_evas_callback_hide_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
976 {
977    ECORE_EVAS_CHECK(ee);
978    IFC(ee, fn_callback_hide_set) (ee, func);
979    IFE;
980    ee->func.fn_hide = func;
981 }
982
983 EAPI void
984 ecore_evas_callback_delete_request_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
985 {
986    ECORE_EVAS_CHECK(ee);
987    IFC(ee, fn_callback_delete_request_set) (ee, func);
988    IFE;
989    ee->func.fn_delete_request = func;
990 }
991
992 EAPI void
993 ecore_evas_callback_destroy_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
994 {
995    ECORE_EVAS_CHECK(ee);
996    IFC(ee, fn_callback_destroy_set) (ee, func);
997    IFE;
998    ee->func.fn_destroy = func;
999 }
1000
1001 EAPI void
1002 ecore_evas_callback_focus_in_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
1003 {
1004    ECORE_EVAS_CHECK(ee);
1005    IFC(ee, fn_callback_focus_in_set) (ee, func);
1006    IFE;
1007    ee->func.fn_focus_in = func;
1008 }
1009
1010 EAPI void
1011 ecore_evas_callback_focus_out_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
1012 {
1013    ECORE_EVAS_CHECK(ee);
1014    IFC(ee, fn_callback_focus_out_set) (ee, func);
1015    IFE;
1016    ee->func.fn_focus_out = func;
1017 }
1018
1019 EAPI void
1020 ecore_evas_callback_sticky_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
1021 {
1022    ECORE_EVAS_CHECK(ee);
1023    IFC(ee, fn_callback_sticky_set) (ee, func);
1024    IFE;
1025    ee->func.fn_sticky = func;
1026 }
1027
1028 EAPI void
1029 ecore_evas_callback_unsticky_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
1030 {
1031    ECORE_EVAS_CHECK(ee);
1032    IFC(ee, fn_callback_unsticky_set) (ee, func);
1033    IFE;
1034    ee->func.fn_unsticky = func;
1035 }
1036
1037 EAPI void
1038 ecore_evas_callback_mouse_in_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
1039 {
1040    ECORE_EVAS_CHECK(ee);
1041    IFC(ee, fn_callback_mouse_in_set) (ee, func);
1042    IFE;
1043    ee->func.fn_mouse_in = func;
1044 }
1045
1046 EAPI void
1047 ecore_evas_callback_mouse_out_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
1048 {
1049    ECORE_EVAS_CHECK(ee);
1050    IFC(ee, fn_callback_mouse_out_set) (ee, func);
1051    IFE;
1052    ee->func.fn_mouse_out = func;
1053 }
1054
1055 EAPI void
1056 ecore_evas_callback_pre_render_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
1057 {
1058    ECORE_EVAS_CHECK(ee);
1059    IFC(ee, fn_callback_pre_render_set) (ee, func);
1060    IFE;
1061    ee->func.fn_pre_render = func;
1062 }
1063
1064 EAPI void
1065 ecore_evas_callback_post_render_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
1066 {
1067    ECORE_EVAS_CHECK(ee);
1068    IFC(ee, fn_callback_post_render_set) (ee, func);
1069    IFE;
1070    ee->func.fn_post_render = func;
1071 }
1072
1073 EAPI void
1074 ecore_evas_callback_pre_free_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
1075 {
1076    ECORE_EVAS_CHECK(ee);
1077    ee->func.fn_pre_free = func;
1078 }
1079
1080 EAPI void
1081 ecore_evas_callback_state_change_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
1082 {
1083    ECORE_EVAS_CHECK(ee);
1084    ee->func.fn_state_change = func;
1085 }
1086
1087 EAPI Evas *
1088 ecore_evas_get(const Ecore_Evas *ee)
1089 {
1090    ECORE_EVAS_CHECK(ee, NULL);
1091    return ee->evas;
1092 }
1093
1094 EAPI void
1095 ecore_evas_move(Ecore_Evas *ee, int x, int y)
1096 {
1097    ECORE_EVAS_CHECK(ee);
1098    if (ee->prop.fullscreen) return;
1099    IFC(ee, fn_move) (ee, x, y);
1100    IFE;
1101 }
1102
1103 EAPI void
1104 ecore_evas_managed_move(Ecore_Evas *ee, int x, int y)
1105 {
1106    ECORE_EVAS_CHECK(ee);
1107    IFC(ee, fn_managed_move) (ee, x, y);
1108    IFE;
1109 }
1110
1111 EAPI void
1112 ecore_evas_resize(Ecore_Evas *ee, int w, int h)
1113 {
1114    ECORE_EVAS_CHECK(ee);
1115    if (ee->prop.fullscreen) return;
1116    if (w < 1) w = 1;
1117    if (h < 1) h = 1;
1118    if (ECORE_EVAS_PORTRAIT(ee))
1119      {
1120         IFC(ee, fn_resize) (ee, w, h);
1121         IFE;
1122      }
1123    else
1124      {
1125         IFC(ee, fn_resize) (ee, h, w);
1126         IFE;
1127      }
1128 }
1129
1130 EAPI void
1131 ecore_evas_move_resize(Ecore_Evas *ee, int x, int y, int w, int h)
1132 {
1133    ECORE_EVAS_CHECK(ee);
1134    if (ee->prop.fullscreen) return;
1135    if (w < 1) w = 1;
1136    if (h < 1) h = 1;
1137    if (ECORE_EVAS_PORTRAIT(ee))
1138      {
1139         IFC(ee, fn_move_resize) (ee, x, y, w, h);
1140         IFE;
1141      }
1142    else
1143      {
1144         IFC(ee, fn_move_resize) (ee, x, y, h, w);
1145         IFE;
1146      }
1147 }
1148
1149 EAPI void
1150 ecore_evas_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h)
1151 {
1152    ECORE_EVAS_CHECK(ee);
1153    if (ECORE_EVAS_PORTRAIT(ee))
1154      {
1155         if (x) *x = ee->x;
1156         if (y) *y = ee->y;
1157         if (w) *w = ee->w;
1158         if (h) *h = ee->h;
1159      }
1160    else
1161      {
1162         if (x) *x = ee->x;
1163         if (y) *y = ee->y;
1164         if (w) *w = ee->h;
1165         if (h) *h = ee->w;
1166      }
1167 }
1168
1169 EAPI void
1170 ecore_evas_request_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h)
1171 {
1172    ECORE_EVAS_CHECK(ee);
1173    if (ECORE_EVAS_PORTRAIT(ee))
1174      {
1175         if (x) *x = ee->req.x;
1176         if (y) *y = ee->req.y;
1177         if (w) *w = ee->req.w;
1178         if (h) *h = ee->req.h;
1179      }
1180    else
1181      {
1182         if (x) *x = ee->req.x;
1183         if (y) *y = ee->req.y;
1184         if (w) *w = ee->req.h;
1185         if (h) *h = ee->req.w;
1186      }
1187 }
1188
1189 EAPI void
1190 ecore_evas_rotation_set(Ecore_Evas *ee, int rot)
1191 {
1192    ECORE_EVAS_CHECK(ee);
1193    rot = rot % 360;
1194    while (rot < 0) rot += 360;
1195    IFC(ee, fn_rotation_set) (ee, rot, 0);
1196    /* make sure everything gets redrawn */
1197    evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1198    evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
1199    IFE;
1200 }
1201
1202 EAPI void
1203 ecore_evas_rotation_with_resize_set(Ecore_Evas *ee, int rot)
1204 {
1205    ECORE_EVAS_CHECK(ee);
1206    rot = rot % 360;
1207    while (rot < 0) rot += 360;
1208    IFC(ee, fn_rotation_set) (ee, rot, 1);
1209    /* make sure everything gets redrawn */
1210    evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1211    evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
1212    IFE;
1213 }
1214
1215 EAPI int
1216 ecore_evas_rotation_get(const Ecore_Evas *ee)
1217 {
1218    ECORE_EVAS_CHECK(ee, 0);
1219    return ee->rotation;
1220 }
1221
1222 EAPI void
1223 ecore_evas_shaped_set(Ecore_Evas *ee, Eina_Bool shaped)
1224 {
1225    ECORE_EVAS_CHECK(ee);
1226    IFC(ee, fn_shaped_set) (ee, shaped);
1227    IFE;
1228 }
1229
1230 EAPI Eina_Bool
1231 ecore_evas_shaped_get(const Ecore_Evas *ee)
1232 {
1233    ECORE_EVAS_CHECK(ee, EINA_FALSE);
1234    return ee->shaped ? EINA_TRUE : EINA_FALSE;
1235 }
1236
1237 EAPI void
1238 ecore_evas_alpha_set(Ecore_Evas *ee, Eina_Bool alpha)
1239 {
1240    ECORE_EVAS_CHECK(ee);
1241    IFC(ee, fn_alpha_set) (ee, alpha);
1242    IFE;
1243 }
1244
1245 EAPI Eina_Bool
1246 ecore_evas_alpha_get(const Ecore_Evas *ee)
1247 {
1248    ECORE_EVAS_CHECK(ee, EINA_FALSE);
1249    return ee->alpha ? EINA_TRUE : EINA_FALSE;
1250 }
1251
1252 EAPI void
1253 ecore_evas_transparent_set(Ecore_Evas *ee, Eina_Bool transparent)
1254 {
1255    ECORE_EVAS_CHECK(ee);
1256    IFC(ee, fn_transparent_set) (ee, transparent);
1257    IFE;
1258 }
1259
1260 EAPI Eina_Bool
1261 ecore_evas_transparent_get(const Ecore_Evas *ee)
1262 {
1263    ECORE_EVAS_CHECK(ee, EINA_FALSE);
1264    return ee->transparent ? EINA_TRUE : 0;
1265 }
1266
1267 EAPI void
1268 ecore_evas_show(Ecore_Evas *ee)
1269 {
1270    ECORE_EVAS_CHECK(ee);
1271    IFC(ee, fn_show) (ee);
1272    IFE;
1273 }
1274
1275 EAPI void
1276 ecore_evas_hide(Ecore_Evas *ee)
1277 {
1278    ECORE_EVAS_CHECK(ee);
1279    IFC(ee, fn_hide) (ee);
1280    IFE;
1281 }
1282
1283  EAPI int
1284 ecore_evas_visibility_get(const Ecore_Evas *ee)
1285 {
1286    ECORE_EVAS_CHECK(ee, 0);
1287    return ee->visible ? 1:0;
1288 }
1289
1290 EAPI void
1291 ecore_evas_raise(Ecore_Evas *ee)
1292 {
1293    ECORE_EVAS_CHECK(ee);
1294    IFC(ee, fn_raise) (ee);
1295    IFE;
1296 }
1297
1298 EAPI void
1299 ecore_evas_lower(Ecore_Evas *ee)
1300 {
1301    ECORE_EVAS_CHECK(ee);
1302    IFC(ee, fn_lower) (ee);
1303    IFE;
1304 }
1305
1306 EAPI void
1307 ecore_evas_activate(Ecore_Evas *ee)
1308 {
1309    ECORE_EVAS_CHECK(ee);
1310    IFC(ee, fn_activate) (ee);
1311    IFE;
1312 }
1313
1314 EAPI void
1315 ecore_evas_title_set(Ecore_Evas *ee, const char *t)
1316 {
1317    ECORE_EVAS_CHECK(ee);
1318    IFC(ee, fn_title_set) (ee, t);
1319    IFE;
1320 }
1321
1322 EAPI const char *
1323 ecore_evas_title_get(const Ecore_Evas *ee)
1324 {
1325    ECORE_EVAS_CHECK(ee, NULL);
1326    return ee->prop.title;
1327 }
1328
1329 EAPI void
1330 ecore_evas_name_class_set(Ecore_Evas *ee, const char *n, const char *c)
1331 {
1332    ECORE_EVAS_CHECK(ee);
1333    IFC(ee, fn_name_class_set) (ee, n, c);
1334    IFE;
1335 }
1336
1337 EAPI void
1338 ecore_evas_name_class_get(const Ecore_Evas *ee, const char **n, const char **c)
1339 {
1340    if (n) *n = NULL;
1341    if (c) *c = NULL;
1342    ECORE_EVAS_CHECK(ee);
1343    if (n) *n = ee->prop.name;
1344    if (c) *c = ee->prop.clas;
1345 }
1346
1347 EAPI void
1348 ecore_evas_size_min_set(Ecore_Evas *ee, int w, int h)
1349 {
1350    ECORE_EVAS_CHECK(ee);
1351    if (w < 0) w = 0;
1352    if (h < 0) h = 0;
1353    if (ECORE_EVAS_PORTRAIT(ee))
1354      {
1355         IFC(ee, fn_size_min_set) (ee, w, h);
1356         IFE;
1357      }
1358    else
1359      {
1360         IFC(ee, fn_size_min_set) (ee, h, w);
1361         IFE;
1362      }
1363 }
1364
1365 EAPI void
1366 ecore_evas_size_min_get(const Ecore_Evas *ee, int *w, int *h)
1367 {
1368    if (w) *w = 0;
1369    if (h) *h = 0;
1370    ECORE_EVAS_CHECK(ee);
1371    if (ECORE_EVAS_PORTRAIT(ee))
1372      {
1373         if (w) *w = ee->prop.min.w;
1374         if (h) *h = ee->prop.min.h;
1375      }
1376    else
1377      {
1378         if (w) *w = ee->prop.min.h;
1379         if (h) *h = ee->prop.min.w;
1380      }
1381 }
1382
1383 EAPI void
1384 ecore_evas_size_max_set(Ecore_Evas *ee, int w, int h)
1385 {
1386    ECORE_EVAS_CHECK(ee);
1387    if (w < 0) w = 0;
1388    if (h < 0) h = 0;
1389    if (ECORE_EVAS_PORTRAIT(ee))
1390      {
1391         IFC(ee, fn_size_max_set) (ee, w, h);
1392         IFE;
1393      }
1394    else
1395      {
1396         IFC(ee, fn_size_max_set) (ee, h, w);
1397         IFE;
1398      }
1399 }
1400
1401 EAPI void
1402 ecore_evas_size_max_get(const Ecore_Evas *ee, int *w, int *h)
1403 {
1404    if (w) *w = 0;
1405    if (h) *h = 0;
1406    ECORE_EVAS_CHECK(ee);
1407    if (ECORE_EVAS_PORTRAIT(ee))
1408      {
1409         if (w) *w = ee->prop.max.w;
1410         if (h) *h = ee->prop.max.h;
1411      }
1412    else
1413      {
1414         if (w) *w = ee->prop.max.h;
1415         if (h) *h = ee->prop.max.w;
1416      }
1417 }
1418
1419 EAPI void
1420 ecore_evas_size_base_set(Ecore_Evas *ee, int w, int h)
1421 {
1422    ECORE_EVAS_CHECK(ee);
1423    if (w < 0) w = 0;
1424    if (h < 0) h = 0;
1425    if (ECORE_EVAS_PORTRAIT(ee))
1426      {
1427         IFC(ee, fn_size_base_set) (ee, w, h);
1428         IFE;
1429      }
1430    else
1431      {
1432         IFC(ee, fn_size_base_set) (ee, h, w);
1433         IFE;
1434      }
1435 }
1436
1437 EAPI void
1438 ecore_evas_size_base_get(const Ecore_Evas *ee, int *w, int *h)
1439 {
1440    ECORE_EVAS_CHECK(ee);
1441    if (ECORE_EVAS_PORTRAIT(ee))
1442      {
1443         if (w) *w = ee->prop.base.w;
1444         if (h) *h = ee->prop.base.h;
1445      }
1446    else
1447      {
1448         if (w) *w = ee->prop.base.h;
1449         if (h) *h = ee->prop.base.w;
1450      }
1451 }
1452
1453 EAPI void
1454 ecore_evas_size_step_set(Ecore_Evas *ee, int w, int h)
1455 {
1456    ECORE_EVAS_CHECK(ee);
1457    if (w < 0) w = 0;
1458    if (h < 0) h = 0;
1459    if (ECORE_EVAS_PORTRAIT(ee))
1460      {
1461         IFC(ee, fn_size_step_set) (ee, w, h);
1462         IFE;
1463      }
1464    else
1465      {
1466         IFC(ee, fn_size_step_set) (ee, h, w);
1467         IFE;
1468      }
1469 }
1470
1471 EAPI void
1472 ecore_evas_size_step_get(const Ecore_Evas *ee, int *w, int *h)
1473 {
1474    ECORE_EVAS_CHECK(ee);
1475    if (ECORE_EVAS_PORTRAIT(ee))
1476      {
1477         if (w) *w = ee->prop.step.w;
1478         if (h) *h = ee->prop.step.h;
1479      }
1480    else
1481      {
1482         if (w) *w = ee->prop.step.h;
1483         if (h) *h = ee->prop.step.w;
1484      }
1485 }
1486
1487 EAPI void
1488 ecore_evas_cursor_set(Ecore_Evas *ee, const char *file, int layer, int hot_x, int hot_y)
1489 {
1490    Evas_Object  *obj = NULL;
1491
1492    ECORE_EVAS_CHECK(ee);
1493
1494    if (file)
1495      {
1496         int x, y;
1497
1498         obj = evas_object_image_add(ee->evas);
1499         evas_object_image_file_set(obj, file, NULL);
1500         evas_object_image_size_get(obj, &x, &y);
1501         evas_object_resize(obj, x, y);
1502         evas_object_image_fill_set(obj, 0, 0, x, y);
1503      }
1504
1505    IFC(ee, fn_object_cursor_set) (ee, obj, layer, hot_x, hot_y);
1506    IFE;
1507 }
1508
1509 EAPI void
1510 ecore_evas_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y)
1511 {
1512    ECORE_EVAS_CHECK(ee);
1513    IFC(ee, fn_object_cursor_set) (ee, obj, layer, hot_x, hot_y);
1514    IFE;
1515 }
1516
1517 EAPI void
1518 ecore_evas_cursor_get(const Ecore_Evas *ee, Evas_Object **obj, int *layer, int *hot_x, int *hot_y)
1519 {
1520    ECORE_EVAS_CHECK(ee);
1521    if (obj) *obj = ee->prop.cursor.object;
1522    if (layer) *layer = ee->prop.cursor.layer;
1523    if (hot_x) *hot_x = ee->prop.cursor.hot.x;
1524    if (hot_y) *hot_y = ee->prop.cursor.hot.y;
1525 }
1526
1527 EAPI Evas_Object *
1528 ecore_evas_cursor_unset(Ecore_Evas *ee)
1529 {
1530    Evas_Object *obj;
1531
1532    ECORE_EVAS_CHECK(ee, NULL);
1533
1534    obj = ee->prop.cursor.object;
1535    IFC(ee, fn_object_cursor_unset) (ee);
1536    evas_object_hide(obj);
1537    ee->prop.cursor.object = NULL;
1538    }
1539
1540    return obj;
1541 }
1542
1543 EAPI void
1544 ecore_evas_layer_set(Ecore_Evas *ee, int layer)
1545 {
1546    ECORE_EVAS_CHECK(ee);
1547    IFC(ee, fn_layer_set) (ee, layer);
1548    IFE;
1549    ee->prop.layer = layer;
1550 }
1551
1552 EAPI int
1553 ecore_evas_layer_get(const Ecore_Evas *ee)
1554 {
1555    ECORE_EVAS_CHECK(ee, 0);
1556    return ee->prop.layer;
1557 }
1558
1559 EAPI void
1560 ecore_evas_focus_set(Ecore_Evas *ee, Eina_Bool on)
1561 {
1562    ECORE_EVAS_CHECK(ee);
1563    IFC(ee, fn_focus_set) (ee, on);
1564    IFE;
1565    if (on)
1566      {
1567         evas_focus_in(ee->evas);
1568         if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee);
1569      }
1570    else
1571      {
1572         evas_focus_out(ee->evas);
1573         if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee);
1574      }
1575    ee->prop.focused = !!on;
1576 }
1577
1578 EAPI Eina_Bool
1579 ecore_evas_focus_get(const Ecore_Evas *ee)
1580 {
1581    ECORE_EVAS_CHECK(ee, EINA_FALSE);
1582    return ee->prop.focused ? EINA_TRUE : EINA_FALSE;
1583 }
1584
1585 EAPI void
1586 ecore_evas_iconified_set(Ecore_Evas *ee, Eina_Bool on)
1587 {
1588    ECORE_EVAS_CHECK(ee);
1589    IFC(ee, fn_iconified_set) (ee, on);
1590    IFE;
1591    ee->prop.iconified = !!on;
1592 }
1593
1594 EAPI Eina_Bool
1595 ecore_evas_iconified_get(const Ecore_Evas *ee)
1596 {
1597    ECORE_EVAS_CHECK(ee, EINA_FALSE);
1598    return ee->prop.iconified ? EINA_TRUE : EINA_FALSE;
1599 }
1600
1601 EAPI void
1602 ecore_evas_borderless_set(Ecore_Evas *ee, Eina_Bool on)
1603 {
1604    ECORE_EVAS_CHECK(ee);
1605    IFC(ee, fn_borderless_set) (ee, on);
1606    IFE;
1607    ee->prop.borderless = !!on;
1608 }
1609
1610 EAPI Eina_Bool
1611 ecore_evas_borderless_get(const Ecore_Evas *ee)
1612 {
1613    ECORE_EVAS_CHECK(ee, EINA_FALSE);
1614    return ee->prop.borderless ? EINA_TRUE : EINA_FALSE;
1615 }
1616
1617 EAPI void
1618 ecore_evas_override_set(Ecore_Evas *ee, Eina_Bool on)
1619 {
1620    ECORE_EVAS_CHECK(ee);
1621    IFC(ee, fn_override_set) (ee, on);
1622    IFE;
1623    ee->prop.override = !!on;
1624 }
1625
1626 EAPI Eina_Bool
1627 ecore_evas_override_get(const Ecore_Evas *ee)
1628 {
1629    ECORE_EVAS_CHECK(ee, EINA_FALSE);
1630    return ee->prop.override ? EINA_TRUE : EINA_FALSE;
1631 }
1632
1633 EAPI void
1634 ecore_evas_maximized_set(Ecore_Evas *ee, Eina_Bool on)
1635 {
1636    ECORE_EVAS_CHECK(ee);
1637    IFC(ee, fn_maximized_set) (ee, on);
1638    IFE;
1639 }
1640
1641 EAPI Eina_Bool
1642 ecore_evas_maximized_get(const Ecore_Evas *ee)
1643 {
1644    ECORE_EVAS_CHECK(ee, EINA_FALSE);
1645    return ee->prop.maximized ? EINA_TRUE : EINA_FALSE;
1646 }
1647
1648 EAPI Eina_Bool
1649 ecore_evas_window_profile_supported_get(const Ecore_Evas *ee)
1650 {
1651    ECORE_EVAS_CHECK(ee, EINA_FALSE);
1652    return ee->profile_supported ? EINA_TRUE : EINA_FALSE;
1653 }
1654
1655 EAPI void
1656 ecore_evas_window_profile_set(Ecore_Evas *ee, const char *profile)
1657 {
1658    ECORE_EVAS_CHECK(ee);
1659    IFC(ee, fn_profile_set) (ee, profile);
1660    IFE;
1661 }
1662
1663 EAPI const char *
1664 ecore_evas_window_profile_get(const Ecore_Evas *ee)
1665 {
1666    ECORE_EVAS_CHECK(ee, NULL);
1667    return ee->prop.profile.name;
1668 }
1669
1670 EAPI void
1671 ecore_evas_window_available_profiles_set(Ecore_Evas *ee, const char **profiles, const unsigned int count)
1672 {
1673    ECORE_EVAS_CHECK(ee);
1674    IFC(ee, fn_profiles_set) (ee, profiles, count);
1675    IFE;
1676 }
1677
1678 EAPI Eina_Bool
1679 ecore_evas_window_available_profiles_get(Ecore_Evas *ee, char ***profiles, unsigned int *count)
1680 {
1681    ECORE_EVAS_CHECK(ee, EINA_FALSE);
1682
1683    if ((ee->prop.profile.available_list) &&
1684        (ee->prop.profile.count >= 1))
1685      {
1686         if (profiles) *profiles = ee->prop.profile.available_list;
1687         if (count) *count = ee->prop.profile.count;
1688         return EINA_TRUE;
1689      }
1690    else
1691      return EINA_FALSE;
1692 }
1693
1694 EAPI Eina_Bool
1695 ecore_evas_wm_rotation_supported_get(const Ecore_Evas *ee)
1696 {
1697    ECORE_EVAS_CHECK(ee, EINA_FALSE);
1698    return ee->prop.wm_rot.supported;
1699 }
1700
1701 EAPI void
1702 ecore_evas_wm_rotation_preferred_rotation_set(Ecore_Evas *ee, int rotation)
1703 {
1704    ECORE_EVAS_CHECK(ee);
1705    if (rotation != -1)
1706      {
1707         if (ee->prop.wm_rot.available_rots)
1708           {
1709              Eina_Bool found = EINA_FALSE;
1710              unsigned int i;
1711              for (i = 0; i < ee->prop.wm_rot.count; i++)
1712                {
1713                   if (ee->prop.wm_rot.available_rots[i] == rotation)
1714                     {
1715                        found = EINA_TRUE;
1716                        break;
1717                     }
1718                }
1719              if (!found) return;
1720           }
1721      }
1722    IFC(ee, fn_wm_rot_preferred_rotation_set) (ee, rotation);
1723    IFE;
1724 }
1725
1726 EAPI int
1727 ecore_evas_wm_rotation_preferred_rotation_get(const Ecore_Evas *ee)
1728 {
1729    ECORE_EVAS_CHECK(ee, -1);
1730    return ee->prop.wm_rot.preferred_rot;
1731 }
1732
1733 EAPI void
1734 ecore_evas_wm_rotation_available_rotations_set(Ecore_Evas *ee, const int *rotations, unsigned int count)
1735 {
1736    ECORE_EVAS_CHECK(ee);
1737    IFC(ee, fn_wm_rot_available_rotations_set) (ee, rotations, count);
1738    IFE;
1739 }
1740
1741 EAPI Eina_Bool
1742 ecore_evas_wm_rotation_available_rotations_get(const Ecore_Evas *ee, int **rotations, unsigned int *count)
1743 {
1744    ECORE_EVAS_CHECK(ee, EINA_FALSE);
1745    if ((!rotations) || (!count))
1746      return EINA_FALSE;
1747
1748    if ((!ee->prop.wm_rot.available_rots) || (ee->prop.wm_rot.count == 0))
1749      return EINA_FALSE;
1750
1751    *rotations = calloc(ee->prop.wm_rot.count, sizeof(int));
1752    if (!*rotations) return EINA_FALSE;
1753
1754    memcpy(*rotations, ee->prop.wm_rot.available_rots, sizeof(int) * ee->prop.wm_rot.count);
1755    *count = ee->prop.wm_rot.count;
1756
1757    return EINA_TRUE;
1758 }
1759
1760 EAPI void
1761 ecore_evas_wm_rotation_manual_rotation_done_set(Ecore_Evas *ee, Eina_Bool set)
1762 {
1763    ECORE_EVAS_CHECK(ee);
1764    if (!ee->prop.wm_rot.app_set)
1765      {
1766         return;
1767      }
1768
1769    IFC(ee, fn_wm_rot_manual_rotation_done_set) (ee, set);
1770    IFE;
1771 }
1772
1773 EAPI Eina_Bool
1774 ecore_evas_wm_rotation_manual_rotation_done_get(const Ecore_Evas *ee)
1775 {
1776    ECORE_EVAS_CHECK(ee, EINA_FALSE);
1777    if (!ee->prop.wm_rot.app_set)
1778      {
1779         return EINA_FALSE;
1780      }
1781
1782    return ee->prop.wm_rot.manual_mode.set;
1783 }
1784
1785 EAPI void
1786 ecore_evas_wm_rotation_manual_rotation_done(Ecore_Evas *ee)
1787 {
1788    ECORE_EVAS_CHECK(ee);
1789    if (!ee->prop.wm_rot.app_set)
1790      {
1791         return;
1792      }
1793
1794    IFC(ee, fn_wm_rot_manual_rotation_done) (ee);
1795    IFE;
1796 }
1797
1798 EAPI const Eina_List *
1799 ecore_evas_aux_hints_supported_get(const Ecore_Evas *ee)
1800 {
1801    ECORE_EVAS_CHECK(ee, NULL);
1802    return ee->prop.aux_hint.supported_list;
1803 }
1804
1805 EAPI Eina_List *
1806 ecore_evas_aux_hints_allowed_get(const Ecore_Evas *ee)
1807 {
1808    ECORE_EVAS_CHECK(ee, NULL);
1809
1810    Eina_List *list = NULL, *ll;
1811    Ecore_Evas_Aux_Hint *aux;
1812    EINA_LIST_FOREACH(ee->prop.aux_hint.hints, ll, aux)
1813      {
1814         if ((aux->allowed) && !(aux->notified))
1815           {
1816              list = eina_list_append(list, (void*)(uintptr_t)aux->id);
1817           }
1818      }
1819
1820    return list;
1821 }
1822
1823 EAPI int
1824 ecore_evas_aux_hint_add(Ecore_Evas *ee, const char *hint, const char *val)
1825 {
1826    ECORE_EVAS_CHECK(ee, -1);
1827
1828    Eina_List *ll;
1829    char *supported_hint;
1830    EINA_LIST_FOREACH(ee->prop.aux_hint.supported_list, ll, supported_hint)
1831      {
1832         if (!strncmp(supported_hint, hint, strlen(hint)))
1833           {
1834              Ecore_Evas_Aux_Hint *aux= (Ecore_Evas_Aux_Hint *)calloc(1, sizeof(Ecore_Evas_Aux_Hint));
1835              if (aux)
1836                {
1837                   aux->id = ee->prop.aux_hint.id;
1838                   aux->hint = eina_stringshare_add(hint);
1839                   aux->val = eina_stringshare_add(val);
1840
1841                   ee->prop.aux_hint.hints = eina_list_append(ee->prop.aux_hint.hints, aux);
1842
1843                   Eina_Strbuf *buf = _ecore_evas_aux_hints_string_get(ee);
1844                   if (buf)
1845                     {
1846                        if (ee->engine.func->fn_aux_hints_set)
1847                          ee->engine.func->fn_aux_hints_set(ee, eina_strbuf_string_get(buf));
1848
1849                        eina_strbuf_free(buf);
1850
1851                        ee->prop.aux_hint.id++;
1852
1853                        return aux->id;
1854                     }
1855
1856                   eina_stringshare_del(aux->hint);
1857                   eina_stringshare_del(aux->val);
1858                   free(aux);
1859                }
1860              break;
1861           }
1862      }
1863
1864    return -1;
1865 }
1866
1867 EAPI Eina_Bool
1868 ecore_evas_aux_hint_del(Ecore_Evas *ee, const int id)
1869 {
1870    ECORE_EVAS_CHECK(ee, EINA_FALSE);
1871
1872    Eina_List *ll;
1873    Ecore_Evas_Aux_Hint *aux;
1874    EINA_LIST_FOREACH(ee->prop.aux_hint.hints, ll, aux)
1875      {
1876         if (id == aux->id)
1877           {
1878              ee->prop.aux_hint.hints = eina_list_remove(ee->prop.aux_hint.hints, aux);
1879
1880              eina_stringshare_del(aux->hint);
1881              eina_stringshare_del(aux->val);
1882              free(aux);
1883
1884              Eina_Strbuf *buf = _ecore_evas_aux_hints_string_get(ee);
1885              if (buf)
1886                {
1887                   if (ee->engine.func->fn_aux_hints_set)
1888                     ee->engine.func->fn_aux_hints_set(ee, eina_strbuf_string_get(buf));
1889
1890                   eina_strbuf_free(buf);
1891
1892                   return EINA_TRUE;
1893                }
1894              break;
1895           }
1896      }
1897
1898    return EINA_FALSE;
1899 }
1900
1901 EAPI Eina_Bool
1902 ecore_evas_aux_hint_val_set(Ecore_Evas *ee, const int id, const char *val)
1903 {
1904    ECORE_EVAS_CHECK(ee, EINA_FALSE);
1905
1906    Eina_List *ll;
1907    Ecore_Evas_Aux_Hint *aux;
1908    EINA_LIST_FOREACH(ee->prop.aux_hint.hints, ll, aux)
1909      {
1910         if (id == aux->id)
1911           {
1912              eina_stringshare_del(aux->val);
1913              aux->val = eina_stringshare_add(val);
1914                          aux->allowed = 0;
1915                          aux->notified = 0;
1916
1917              Eina_Strbuf *buf = _ecore_evas_aux_hints_string_get(ee);
1918              if (buf)
1919                {
1920                   if (ee->engine.func->fn_aux_hints_set)
1921                     ee->engine.func->fn_aux_hints_set(ee, eina_strbuf_string_get(buf));
1922
1923                   eina_strbuf_free(buf);
1924
1925                   return EINA_TRUE;
1926                }
1927              break;
1928           }
1929      }
1930
1931    return EINA_TRUE;
1932 }
1933
1934 EAPI const char *
1935 ecore_evas_aux_hint_val_get(const Ecore_Evas *ee, int id)
1936 {
1937    ECORE_EVAS_CHECK(ee, NULL);
1938
1939    Eina_List *ll;
1940    Ecore_Evas_Aux_Hint *aux;
1941    EINA_LIST_FOREACH(ee->prop.aux_hint.hints, ll, aux)
1942      {
1943         if (id == aux->id) return aux->val;
1944      }
1945
1946    return NULL;
1947 }
1948
1949 EAPI int
1950 ecore_evas_aux_hint_id_get(const Ecore_Evas *ee, const char *hint)
1951 {
1952    ECORE_EVAS_CHECK(ee, -1);
1953
1954    Eina_List *ll;
1955    Ecore_Evas_Aux_Hint *aux;
1956    EINA_LIST_FOREACH(ee->prop.aux_hint.hints, ll, aux)
1957      {
1958         if (!strcmp(hint,aux->hint)) return aux->id;
1959      }
1960
1961    return -1;
1962 }
1963
1964 EAPI void
1965 ecore_evas_fullscreen_set(Ecore_Evas *ee, Eina_Bool on)
1966 {
1967    ECORE_EVAS_CHECK(ee);
1968    IFC(ee, fn_fullscreen_set) (ee, on);
1969    IFE;
1970 }
1971
1972 EAPI Eina_Bool
1973 ecore_evas_fullscreen_get(const Ecore_Evas *ee)
1974 {
1975    ECORE_EVAS_CHECK(ee, EINA_FALSE);
1976    return ee->prop.fullscreen ? EINA_TRUE : EINA_FALSE;
1977 }
1978
1979 EAPI void
1980 ecore_evas_avoid_damage_set(Ecore_Evas *ee, Ecore_Evas_Avoid_Damage_Type on)
1981 {
1982    ECORE_EVAS_CHECK(ee);
1983    IFC(ee, fn_avoid_damage_set) (ee, on);
1984    IFE;
1985 }
1986
1987 EAPI Ecore_Evas_Avoid_Damage_Type
1988 ecore_evas_avoid_damage_get(const Ecore_Evas *ee)
1989 {
1990    ECORE_EVAS_CHECK(ee, ECORE_EVAS_AVOID_DAMAGE_NONE);
1991    return ee->prop.avoid_damage;
1992 }
1993
1994 EAPI void
1995 ecore_evas_withdrawn_set(Ecore_Evas *ee, Eina_Bool withdrawn)
1996 {
1997    ECORE_EVAS_CHECK(ee);
1998    IFC(ee, fn_withdrawn_set) (ee, withdrawn);
1999    IFE;
2000 }
2001
2002 EAPI Eina_Bool
2003 ecore_evas_withdrawn_get(const Ecore_Evas *ee)
2004 {
2005    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2006    return ee->prop.withdrawn ? EINA_TRUE : EINA_FALSE;
2007 }
2008
2009 EAPI void
2010 ecore_evas_sticky_set(Ecore_Evas *ee, Eina_Bool on)
2011 {
2012    ECORE_EVAS_CHECK(ee);
2013    IFC(ee, fn_sticky_set) (ee, on);
2014    IFE;
2015 }
2016
2017 EAPI Eina_Bool
2018 ecore_evas_sticky_get(const Ecore_Evas *ee)
2019 {
2020    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2021    return ee->prop.sticky ? EINA_TRUE : EINA_FALSE;
2022 }
2023
2024 EAPI void
2025 ecore_evas_window_group_set(Ecore_Evas *ee, const Ecore_Evas *ee_group)
2026 {
2027    ECORE_EVAS_CHECK(ee);
2028    IFC(ee, fn_window_group_set) (ee, ee_group);
2029    IFE;
2030 }
2031
2032 EAPI const Ecore_Evas *
2033 ecore_evas_window_group_get(const Ecore_Evas *ee)
2034 {
2035    ECORE_EVAS_CHECK(ee, NULL);
2036    return ee->prop.group_ee;
2037 }
2038
2039 EAPI void
2040 ecore_evas_aspect_set(Ecore_Evas *ee, double aspect)
2041 {
2042    ECORE_EVAS_CHECK(ee);
2043    IFC(ee, fn_aspect_set) (ee, aspect);
2044    IFE;
2045 }
2046
2047 EAPI double
2048 ecore_evas_aspect_get(const Ecore_Evas *ee)
2049 {
2050    ECORE_EVAS_CHECK(ee, 0.0);
2051    return ee->prop.aspect;
2052 }
2053
2054 EAPI void
2055 ecore_evas_urgent_set(Ecore_Evas *ee, Eina_Bool on)
2056 {
2057    ECORE_EVAS_CHECK(ee);
2058    IFC(ee, fn_urgent_set) (ee, on);
2059    IFE;
2060 }
2061
2062 EAPI Eina_Bool
2063 ecore_evas_urgent_get(const Ecore_Evas *ee)
2064 {
2065    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2066    return ee->prop.urgent ? EINA_TRUE : EINA_FALSE;
2067 }
2068
2069 EAPI void
2070 ecore_evas_modal_set(Ecore_Evas *ee, Eina_Bool on)
2071 {
2072    ECORE_EVAS_CHECK(ee);
2073    IFC(ee, fn_modal_set) (ee, on);
2074    IFE;
2075 }
2076
2077 EAPI Eina_Bool
2078 ecore_evas_modal_get(const Ecore_Evas *ee)
2079 {
2080    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2081    return ee->prop.modal ? EINA_TRUE : EINA_FALSE;
2082 }
2083
2084 EAPI void
2085 ecore_evas_demand_attention_set(Ecore_Evas *ee, Eina_Bool on)
2086 {
2087    ECORE_EVAS_CHECK(ee);
2088    IFC(ee, fn_demands_attention_set) (ee, on);
2089    IFE;
2090 }
2091
2092 EAPI Eina_Bool
2093 ecore_evas_demand_attention_get(const Ecore_Evas *ee)
2094 {
2095    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2096    return ee->prop.demand_attention ? EINA_TRUE : EINA_FALSE;
2097 }
2098
2099 EAPI void
2100 ecore_evas_focus_skip_set(Ecore_Evas *ee, Eina_Bool on)
2101 {
2102    ECORE_EVAS_CHECK(ee);
2103    IFC(ee, fn_focus_skip_set) (ee, on);
2104    IFE;
2105 }
2106
2107 EAPI Eina_Bool
2108 ecore_evas_focus_skip_get(const Ecore_Evas *ee)
2109 {
2110    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2111    return ee->prop.focus_skip ? EINA_TRUE : EINA_FALSE;
2112 }
2113
2114 EAPI void
2115 ecore_evas_ignore_events_set(Ecore_Evas *ee, Eina_Bool ignore)
2116 {
2117    ECORE_EVAS_CHECK(ee);
2118    IFC(ee, fn_ignore_events_set) (ee, ignore);
2119    IFE;
2120 }
2121
2122 EAPI Eina_Bool
2123 ecore_evas_ignore_events_get(const Ecore_Evas *ee)
2124 {
2125    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2126    return ee->ignore_events ? EINA_TRUE : EINA_FALSE;
2127 }
2128
2129 EAPI void
2130 ecore_evas_manual_render_set(Ecore_Evas *ee, Eina_Bool manual_render)
2131 {
2132    ECORE_EVAS_CHECK(ee);
2133    ee->manual_render = manual_render;
2134 }
2135
2136 EAPI Eina_Bool
2137 ecore_evas_manual_render_get(const Ecore_Evas *ee)
2138 {
2139    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2140    return ee->manual_render ? EINA_TRUE : EINA_FALSE;
2141 }
2142
2143 EAPI void
2144 ecore_evas_manual_render(Ecore_Evas *ee)
2145 {
2146    ECORE_EVAS_CHECK(ee);
2147    if (ee->engine.func->fn_render)
2148      ee->engine.func->fn_render(ee);
2149 }
2150
2151 EAPI void
2152 ecore_evas_msg_parent_send(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size)
2153 {
2154    ECORE_EVAS_CHECK(ee);
2155    DBG("Msg(to parent): ee=%p msg_domain=%d msg_id=%d size=%d", ee, msg_domain, msg_id, size);
2156    IFC(ee, fn_msg_parent_send) (ee, msg_domain, msg_id, data, size);
2157    IFE;
2158 }
2159
2160 EAPI void
2161 ecore_evas_msg_send(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size)
2162 {
2163    ECORE_EVAS_CHECK(ee);
2164    DBG("Msg: ee=%p msg_domain=%d msg_id=%d size=%d", ee, msg_domain, msg_id, size);
2165    IFC(ee, fn_msg_send) (ee, msg_domain, msg_id, data, size);
2166    IFE;
2167 }
2168
2169 EAPI void
2170 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))
2171 {
2172    ECORE_EVAS_CHECK(ee);
2173    DBG("Msg Parent handle: ee=%p", ee);
2174    ee->func.fn_msg_parent_handle = func_parent_handle;
2175 }
2176
2177 EAPI void
2178 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))
2179 {
2180    ECORE_EVAS_CHECK(ee);
2181    DBG("Msg handle: ee=%p", ee);
2182    ee->func.fn_msg_handle = func_handle;
2183 }
2184
2185
2186 EAPI void
2187 ecore_evas_comp_sync_set(Ecore_Evas *ee, Eina_Bool do_sync)
2188 {
2189    ECORE_EVAS_CHECK(ee);
2190    ee->no_comp_sync = !do_sync;
2191 }
2192
2193 EAPI Eina_Bool
2194 ecore_evas_comp_sync_get(const Ecore_Evas *ee)
2195 {
2196    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2197    return !ee->no_comp_sync;
2198 }
2199
2200 EAPI Ecore_Window
2201 ecore_evas_window_get(const Ecore_Evas *ee)
2202 {
2203    ECORE_EVAS_CHECK(ee, 0);
2204    return ee->prop.window;
2205 }
2206
2207 EAPI void
2208 ecore_evas_screen_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h)
2209 {
2210    if (x) *x = 0;
2211    if (y) *y = 0;
2212    if (w) *w = 0;
2213    if (h) *h = 0;
2214    ECORE_EVAS_CHECK(ee);
2215    IFC(ee, fn_screen_geometry_get) (ee, x, y, w, h);
2216    IFE;
2217 }
2218
2219 EAPI void
2220 ecore_evas_screen_dpi_get(const Ecore_Evas *ee, int *xdpi, int *ydpi)
2221 {
2222    if (xdpi) *xdpi = 0;
2223    if (ydpi) *ydpi = 0;
2224    ECORE_EVAS_CHECK(ee);
2225    IFC(ee, fn_screen_dpi_get) (ee, xdpi, ydpi);
2226    IFE;
2227 }
2228
2229 EAPI void
2230 ecore_evas_draw_frame_set(Ecore_Evas *ee EINA_UNUSED, Eina_Bool draw_frame EINA_UNUSED)
2231 {
2232    WRN("Calling deprecated function %s (not implemented)", __FUNCTION__);
2233 }
2234
2235 EAPI Eina_Bool
2236 ecore_evas_draw_frame_get(const Ecore_Evas *ee EINA_UNUSED)
2237 {
2238    WRN("Calling deprecated function %s (not implemented)", __FUNCTION__);
2239    return EINA_FALSE;
2240 }
2241
2242 EAPI void 
2243 ecore_evas_pointer_xy_get(const Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y)
2244 {
2245    if (x) *x = 0;
2246    if (y) *y = 0;
2247    ECORE_EVAS_CHECK(ee);
2248    IFC(ee, fn_pointer_xy_get) (ee, x, y);
2249    IFE;
2250 }
2251
2252 EAPI Eina_Bool 
2253 ecore_evas_pointer_warp(const Ecore_Evas *ee, Evas_Coord x, Evas_Coord y)
2254 {
2255    ECORE_EVAS_CHECK(ee, EINA_FALSE);
2256    if (ee->engine.func->fn_pointer_warp)
2257      return ee->engine.func->fn_pointer_warp(ee, x, y);
2258
2259    return EINA_FALSE;
2260 }
2261
2262 EAPI void *
2263 ecore_evas_pixmap_visual_get(const Ecore_Evas *ee)
2264 {
2265    ECORE_EVAS_CHECK(ee, NULL);
2266
2267    if (!strcmp(ee->driver, "software_x11"))
2268      {
2269         Ecore_Evas_Interface_Software_X11 *iface;
2270         iface = (Ecore_Evas_Interface_Software_X11 *)_ecore_evas_interface_get(ee, "software_x11");
2271         EINA_SAFETY_ON_NULL_RETURN_VAL(iface, NULL);
2272
2273         if (iface->pixmap_visual_get)
2274           return iface->pixmap_visual_get(ee);
2275      }
2276    else if (!strcmp(ee->driver, "opengl_x11"))
2277      {
2278         Ecore_Evas_Interface_Gl_X11 *iface;
2279         iface = (Ecore_Evas_Interface_Gl_X11 *)_ecore_evas_interface_get(ee, "gl_x11");
2280         EINA_SAFETY_ON_NULL_RETURN_VAL(iface, NULL);
2281
2282         if (iface->pixmap_visual_get)
2283           return iface->pixmap_visual_get(ee);
2284      }
2285
2286    return NULL;
2287 }
2288
2289 EAPI unsigned long 
2290 ecore_evas_pixmap_colormap_get(const Ecore_Evas *ee)
2291 {
2292    ECORE_EVAS_CHECK(ee, 0);
2293
2294    if (!strcmp(ee->driver, "software_x11"))
2295      {
2296         Ecore_Evas_Interface_Software_X11 *iface;
2297         iface = (Ecore_Evas_Interface_Software_X11 *)_ecore_evas_interface_get(ee, "software_x11");
2298         EINA_SAFETY_ON_NULL_RETURN_VAL(iface, 0);
2299
2300         if (iface->pixmap_colormap_get)
2301           return iface->pixmap_colormap_get(ee);
2302      }
2303    else if (!strcmp(ee->driver, "opengl_x11"))
2304      {
2305         Ecore_Evas_Interface_Gl_X11 *iface;
2306         iface = (Ecore_Evas_Interface_Gl_X11 *)_ecore_evas_interface_get(ee, "gl_x11");
2307         EINA_SAFETY_ON_NULL_RETURN_VAL(iface, 0);
2308
2309         if (iface->pixmap_colormap_get)
2310           return iface->pixmap_colormap_get(ee);
2311      }
2312
2313    return 0;
2314 }
2315
2316 EAPI int 
2317 ecore_evas_pixmap_depth_get(const Ecore_Evas *ee)
2318 {
2319    ECORE_EVAS_CHECK(ee, 0);
2320
2321    if (!strcmp(ee->driver, "software_x11"))
2322      {
2323         Ecore_Evas_Interface_Software_X11 *iface;
2324         iface = (Ecore_Evas_Interface_Software_X11 *)_ecore_evas_interface_get(ee, "software_x11");
2325         EINA_SAFETY_ON_NULL_RETURN_VAL(iface, 0);
2326
2327         if (iface->pixmap_depth_get)
2328           return iface->pixmap_depth_get(ee);
2329      }
2330    else if (!strcmp(ee->driver, "opengl_x11"))
2331      {
2332         Ecore_Evas_Interface_Gl_X11 *iface;
2333         iface = (Ecore_Evas_Interface_Gl_X11 *)_ecore_evas_interface_get(ee, "gl_x11");
2334         EINA_SAFETY_ON_NULL_RETURN_VAL(iface, 0);
2335
2336         if (iface->pixmap_depth_get)
2337           return iface->pixmap_depth_get(ee);
2338      }
2339
2340    return 0;
2341 }
2342
2343 /* fps debug calls - for debugging how much time your app actually spends */
2344 /* rendering graphics... :) */
2345
2346 static int _ecore_evas_fps_debug_init_count = 0;
2347 static int _ecore_evas_fps_debug_fd = -1;
2348 unsigned int *_ecore_evas_fps_rendertime_mmap = NULL;
2349
2350 EAPI void
2351 _ecore_evas_fps_debug_init(void)
2352 {
2353    char buf[4096];
2354
2355    _ecore_evas_fps_debug_init_count++;
2356    if (_ecore_evas_fps_debug_init_count > 1) return;
2357
2358    snprintf(buf, sizeof(buf), "%s/.ecore_evas_fps_debug-%i",
2359             eina_environment_tmp_get(), (int)getpid());
2360    _ecore_evas_fps_debug_fd = open(buf, O_CREAT | O_BINARY | O_TRUNC | O_RDWR, 0644);
2361    if (_ecore_evas_fps_debug_fd < 0)
2362      {
2363         unlink(buf);
2364         _ecore_evas_fps_debug_fd = open(buf, O_CREAT | O_BINARY | O_TRUNC | O_RDWR, 0644);
2365      }
2366    if (_ecore_evas_fps_debug_fd >= 0)
2367      {
2368         unsigned int zero = 0;
2369         char *buf2 = (char *)&zero;
2370         ssize_t todo = sizeof(unsigned int);
2371
2372         while (todo > 0)
2373           {
2374              ssize_t r = write(_ecore_evas_fps_debug_fd, buf2, todo);
2375              if (r > 0)
2376                {
2377                   todo -= r;
2378                   buf2 += r;
2379                }
2380              else if ((r < 0) && (errno == EINTR))
2381                continue;
2382              else
2383                {
2384                   ERR("could not write to file '%s' fd %d: %s",
2385                       buf, _ecore_evas_fps_debug_fd, strerror(errno));
2386                   close(_ecore_evas_fps_debug_fd);
2387                   _ecore_evas_fps_debug_fd = -1;
2388                   return;
2389                }
2390           }
2391         _ecore_evas_fps_rendertime_mmap = mmap(NULL, sizeof(unsigned int),
2392                                                PROT_READ | PROT_WRITE,
2393                                                MAP_SHARED,
2394                                                _ecore_evas_fps_debug_fd, 0);
2395         if (_ecore_evas_fps_rendertime_mmap == MAP_FAILED)
2396           _ecore_evas_fps_rendertime_mmap = NULL;
2397      }
2398 }
2399
2400 EAPI void
2401 _ecore_evas_fps_debug_shutdown(void)
2402 {
2403    _ecore_evas_fps_debug_init_count--;
2404    if (_ecore_evas_fps_debug_init_count > 0) return;
2405    if (_ecore_evas_fps_debug_fd >= 0)
2406      {
2407         char buf[4096];
2408
2409         snprintf(buf, sizeof(buf), "%s/.ecore_evas_fps_debug-%i",
2410                  eina_environment_tmp_get(), (int)getpid());
2411         unlink(buf);
2412         if (_ecore_evas_fps_rendertime_mmap)
2413           {
2414              munmap(_ecore_evas_fps_rendertime_mmap, sizeof(int));
2415              _ecore_evas_fps_rendertime_mmap = NULL;
2416           }
2417         close(_ecore_evas_fps_debug_fd);
2418         _ecore_evas_fps_debug_fd = -1;
2419      }
2420 }
2421
2422 EAPI void
2423 _ecore_evas_fps_debug_rendertime_add(double t)
2424 {
2425    static double rtime = 0.0;
2426    static double rlapse = 0.0;
2427    static int frames = 0;
2428    static int flapse = 0;
2429    double tim;
2430
2431    tim = ecore_time_get();
2432    rtime += t;
2433    frames++;
2434    if (rlapse == 0.0)
2435      {
2436         rlapse = tim;
2437         flapse = frames;
2438      }
2439    else if ((tim - rlapse) >= 0.5)
2440      {
2441         printf("FRAME: %i, FPS: %3.1f, RTIME %3.0f%%\n",
2442                frames,
2443                (frames - flapse) / (tim - rlapse),
2444                (100.0 * rtime) / (tim - rlapse)
2445                );
2446         rlapse = tim;
2447         flapse = frames;
2448         rtime = 0.0;
2449      }
2450 }
2451
2452 static Ecore_Evas *_general_tick = NULL;
2453
2454 EAPI void
2455 ecore_evas_animator_tick(Ecore_Evas *ee, Eina_Rectangle *viewport)
2456 {
2457    Ecore_Evas *subee;
2458    Eina_List *l;
2459    Efl_Event_Animator_Tick a = { { 0, 0, 0, 0 } };
2460
2461    if (!viewport)
2462      {
2463         evas_output_size_get(ee->evas, &a.update_area.w, &a.update_area.h);
2464      }
2465    else
2466      {
2467         a.update_area = *viewport;
2468      }
2469
2470    efl_event_callback_legacy_call(ee->evas, EFL_EVENT_ANIMATOR_TICK, &a);
2471
2472    // FIXME: We do not support partial animator in the subcanvas
2473    EINA_LIST_FOREACH(ee->sub_ecore_evas, l, subee)
2474      {
2475         ecore_evas_animator_tick(subee, NULL);
2476      }
2477
2478    // We are the source of sync for general animator.
2479    if (_general_tick == ee)
2480      {
2481         // Check first we didn't tick during this loop
2482         if (!ecore_main_loop_animator_ticked_get())
2483           ecore_animator_custom_tick();
2484      }
2485
2486    DBG("Animator ticked on %p.", ee->evas);
2487 }
2488
2489 static void
2490 _ecore_evas_tick_source_find(void)
2491 {
2492    Ecore_Evas *ee;
2493
2494    _general_tick = NULL;
2495    EINA_INLIST_FOREACH(ecore_evases, ee)
2496      if (ee->anim_count &&
2497                 ee->engine.func->fn_animator_register &&
2498          ee->engine.func->fn_animator_unregister)
2499        {
2500           _general_tick = ee;
2501           break;
2502        }
2503
2504    if (!_general_tick)
2505      {
2506         ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER);
2507      }
2508    else
2509      {
2510         ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_CUSTOM);
2511      }
2512 }
2513
2514 static Eina_Bool
2515 _ecore_evas_animator_fallback(void *data)
2516 {
2517    ecore_evas_animator_tick(data, NULL);
2518    return EINA_TRUE;
2519 }
2520
2521 static void
2522 _check_animator_event_catcher_add(void *data, const Efl_Event *event)
2523 {
2524    const Efl_Callback_Array_Item *array = event->info;
2525    Ecore_Evas *ee = data;
2526    int i;
2527
2528    for (i = 0; array[i].desc != NULL; i++)
2529      {
2530         if (array[i].desc == EFL_EVENT_ANIMATOR_TICK)
2531           {
2532              if (ee->anim_count++ > 0) return;
2533              INF("Setting up animator for %p from '%s' with title '%s'.", ee->evas, ee->driver, ee->prop.title);
2534
2535              if (ee->engine.func->fn_animator_register &&
2536                  ee->engine.func->fn_animator_unregister)
2537                {
2538                   // Backend support per window vsync
2539                   ee->engine.func->fn_animator_register(ee);
2540                   if (!_general_tick) _general_tick = ee;
2541                }
2542              else
2543                {
2544                   // Backend doesn't support per window vsync, fallback to generic support
2545                   ee->anim = ecore_animator_add(_ecore_evas_animator_fallback, ee);
2546                }
2547
2548              // No need to walk more than once per array as you can not del
2549              // a partial array
2550              return;
2551           }
2552      }
2553 }
2554
2555 static void
2556 _check_animator_event_catcher_del(void *data, const Efl_Event *event)
2557 {
2558    const Efl_Callback_Array_Item *array = event->info;
2559    Ecore_Evas *ee = data;
2560    int i;
2561
2562    for (i = 0; array[i].desc != NULL; i++)
2563      {
2564         if (array[i].desc == EFL_EVENT_ANIMATOR_TICK)
2565           {
2566              if ((--ee->anim_count) > 0) return;
2567
2568              INF("Unsetting up animator for %p from '%s' titled '%s'.", ee->evas, ee->driver, ee->prop.title);
2569              if (ee->engine.func->fn_animator_register &&
2570                  ee->engine.func->fn_animator_unregister)
2571                {
2572                   // Backend support per window vsync
2573                   ee->engine.func->fn_animator_unregister(ee);
2574                   if (_general_tick == ee) _ecore_evas_tick_source_find();
2575                }
2576              else
2577                {
2578                   // Backend doesn't support per window vsync, fallback to generic support
2579                   ecore_animator_del(ee->anim);
2580                   ee->anim = NULL;
2581                }
2582              return;
2583           }
2584      }
2585 }
2586
2587 EFL_CALLBACKS_ARRAY_DEFINE(animator_watch,
2588                           { EFL_EVENT_CALLBACK_ADD, _check_animator_event_catcher_add },
2589                           { EFL_EVENT_CALLBACK_DEL, _check_animator_event_catcher_del });
2590
2591 EAPI void
2592 _ecore_evas_register_animators(Ecore_Evas *ee)
2593 {
2594    efl_event_callback_array_add(ee->evas, animator_watch(), ee);
2595 }
2596
2597 EAPI void
2598 _ecore_evas_register(Ecore_Evas *ee)
2599 {
2600    ee->registered = 1;
2601    ecore_evases = (Ecore_Evas *)eina_inlist_prepend
2602      (EINA_INLIST_GET(ecore_evases), EINA_INLIST_GET(ee));
2603
2604    _ecore_evas_register_animators(ee);
2605
2606    if (_ecore_evas_render_sync) ecore_evas_first = EINA_TRUE;
2607 }
2608
2609 EAPI void
2610 _ecore_evas_ref(Ecore_Evas *ee)
2611 {
2612    ee->refcount++;
2613 }
2614
2615 EAPI void
2616 _ecore_evas_unref(Ecore_Evas *ee)
2617 {
2618    ee->refcount--;
2619    if (ee->refcount == 0)
2620      {
2621         if (ee->deleted) _ecore_evas_free(ee);
2622      }
2623    else if (ee->refcount < -1)
2624      ERR("Ecore_Evas %p->refcount=%d < 0", ee, ee->refcount);
2625 }
2626
2627 static Eina_Bool
2628 _ecore_evas_vnc_stop(Ecore_Evas *ee)
2629 {
2630    Eina_Module *mod;
2631    void (*vnc_del)(void *);
2632
2633    mod = _ecore_evas_vnc_server_module_load();
2634    EINA_SAFETY_ON_NULL_RETURN_VAL(mod, EINA_FALSE);
2635
2636    vnc_del = eina_module_symbol_get(mod, "ecore_evas_vnc_server_del");
2637    EINA_SAFETY_ON_NULL_RETURN_VAL(vnc_del, EINA_FALSE);
2638
2639    vnc_del(ee->vnc_server);
2640    ee->vnc_server = NULL;
2641    return EINA_TRUE;
2642 }
2643
2644 EAPI void
2645 _ecore_evas_free(Ecore_Evas *ee)
2646 {
2647    Ecore_Evas_Interface *iface;
2648
2649    ee->deleted = EINA_TRUE;
2650    if (ee->refcount > 0) return;
2651
2652    // Stop all vsync first
2653    if (ee->engine.func->fn_animator_register &&
2654        ee->engine.func->fn_animator_unregister)
2655      {
2656         // Backend support per window vsync
2657         ee->engine.func->fn_animator_unregister(ee);
2658         if (_general_tick == ee) _ecore_evas_tick_source_find();
2659      }
2660    if (ee->anim)
2661      ecore_animator_del(ee->anim);
2662    ee->anim = NULL;
2663
2664    if (ee->func.fn_pre_free) ee->func.fn_pre_free(ee);
2665    if (ee->vnc_server) _ecore_evas_vnc_stop(ee);
2666    while (ee->sub_ecore_evas)
2667      {
2668         _ecore_evas_free(ee->sub_ecore_evas->data);
2669      }
2670    if (ee->data) eina_hash_free(ee->data);
2671    ee->data = NULL;
2672    if (ee->name) free(ee->name);
2673    ee->name = NULL;
2674    if (ee->prop.title) free(ee->prop.title);
2675    ee->prop.title = NULL;
2676    if (ee->prop.name) free(ee->prop.name);
2677    ee->prop.name = NULL;
2678    if (ee->prop.clas) free(ee->prop.clas);
2679    ee->prop.clas = NULL;
2680    _ecore_evas_window_profile_free(ee);
2681    ee->prop.profile.name = NULL;
2682    _ecore_evas_window_available_profiles_free(ee);
2683    ee->prop.profile.available_list = NULL;
2684    if (ee->prop.wm_rot.available_rots) free(ee->prop.wm_rot.available_rots);
2685    ee->prop.wm_rot.available_rots = NULL;
2686    if (ee->prop.wm_rot.manual_mode.timer)
2687      ecore_timer_del(ee->prop.wm_rot.manual_mode.timer);
2688    _ecore_evas_aux_hint_free(ee);
2689    ee->prop.wm_rot.manual_mode.timer = NULL;
2690    if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object);
2691    ee->prop.cursor.object = NULL;
2692    if (ee->evas) evas_free(ee->evas);
2693    ee->evas = NULL;
2694    ECORE_MAGIC_SET(ee, ECORE_MAGIC_NONE);
2695    ee->driver = NULL;
2696    if (ee->engine.idle_flush_timer)
2697      ecore_timer_del(ee->engine.idle_flush_timer);
2698    ee->engine.idle_flush_timer = NULL;
2699    if (ee->engine.func->fn_free) ee->engine.func->fn_free(ee);
2700    if (ee->registered)
2701      {
2702         ecore_evases = (Ecore_Evas *)eina_inlist_remove
2703           (EINA_INLIST_GET(ecore_evases), EINA_INLIST_GET(ee));
2704      }
2705
2706    EINA_LIST_FREE(ee->engine.ifaces, iface)
2707      free(iface);
2708
2709    ee->engine.ifaces = NULL;
2710    free(ee);
2711 }
2712
2713 static Eina_Bool
2714 _ecore_evas_cb_idle_flush(void *data)
2715 {
2716    Ecore_Evas *ee = data;
2717
2718    ee->engine.idle_flush_timer = NULL;
2719    evas_render_idle_flush(ee->evas);
2720    return ECORE_CALLBACK_CANCEL;
2721 }
2722
2723 static Eina_Bool
2724 _ecore_evas_async_events_fd_handler(void *data EINA_UNUSED, Ecore_Fd_Handler *fd_handler EINA_UNUSED)
2725 {
2726    evas_async_events_process();
2727
2728    return ECORE_CALLBACK_RENEW;
2729 }
2730
2731 EAPI void
2732 _ecore_evas_idle_timeout_update(Ecore_Evas *ee)
2733 {
2734    if (ee->engine.idle_flush_timer)
2735      ecore_timer_del(ee->engine.idle_flush_timer);
2736    ee->engine.idle_flush_timer = 
2737      ecore_timer_add(IDLE_FLUSH_TIME, _ecore_evas_cb_idle_flush, ee);
2738 }
2739
2740 static void
2741 _ecore_evas_mouse_move_process_internal(Ecore_Evas *ee, int x, int y, unsigned int timestamp, Eina_Bool feed)
2742 {
2743    int fx, fy, fw, fh;
2744    ee->mouse.x = x;
2745    ee->mouse.y = y;
2746
2747    evas_output_framespace_get(ee->evas, &fx, &fy, &fw, &fh);
2748
2749    if (ee->prop.cursor.object)
2750      {
2751         evas_object_show(ee->prop.cursor.object);
2752         if (ee->rotation == 0)
2753           evas_object_move(ee->prop.cursor.object,
2754                            x - fx - ee->prop.cursor.hot.x,
2755                            y - fy - ee->prop.cursor.hot.y);
2756         else if (ee->rotation == 90)
2757           evas_object_move(ee->prop.cursor.object,
2758                            ee->h + fw - y - fx - 1 - ee->prop.cursor.hot.x,
2759                            x - fy - ee->prop.cursor.hot.y);
2760         else if (ee->rotation == 180)
2761           evas_object_move(ee->prop.cursor.object,
2762                            ee->w + fw - x - fx - 1 - ee->prop.cursor.hot.x,
2763                            ee->h + fh - y - fy - 1 - ee->prop.cursor.hot.y);
2764         else if (ee->rotation == 270)
2765           evas_object_move(ee->prop.cursor.object,
2766                            y - fx - ee->prop.cursor.hot.x,
2767                            ee->w + fh - x - fy - 1 - ee->prop.cursor.hot.y);
2768      }
2769    if (!feed) return;
2770    if (ee->rotation == 0)
2771      evas_event_input_mouse_move(ee->evas, x, y, timestamp, NULL);
2772    else if (ee->rotation == 90)
2773      evas_event_input_mouse_move(ee->evas, ee->h + fw - y - 1, x, timestamp, NULL);
2774    else if (ee->rotation == 180)
2775      evas_event_input_mouse_move(ee->evas, ee->w + fw - x - 1, ee->h + fh - y - 1, timestamp, NULL);
2776    else if (ee->rotation == 270)
2777      evas_event_input_mouse_move(ee->evas, y, ee->w + fh - x - 1, timestamp, NULL);
2778 }
2779
2780 EAPI void
2781 _ecore_evas_mouse_move_process(Ecore_Evas *ee, int x, int y, unsigned int timestamp)
2782 {
2783    _ecore_evas_mouse_move_process_internal(ee, x, y, timestamp, EINA_TRUE);
2784 }
2785
2786 EAPI void
2787 _ecore_evas_mouse_multi_move_process(Ecore_Evas *ee, int device,
2788                                      int x, int y,
2789                                      double radius,
2790                                      double radius_x, double radius_y,
2791                                      double pressure,
2792                                      double angle,
2793                                      double mx, double my,
2794                                      unsigned int timestamp)
2795 {
2796    if (ee->rotation == 0)
2797      evas_event_input_multi_move(ee->evas, device,
2798                                  x, y,
2799                                  radius,
2800                                  radius_x, radius_y,
2801                                  pressure,
2802                                  angle - ee->rotation,
2803                                  mx, my,
2804                                  timestamp, NULL);
2805    else if (ee->rotation == 90)
2806      evas_event_input_multi_move(ee->evas, device,
2807                                  ee->h - y - 1, x,
2808                                  radius,
2809                                  radius_y, radius_x,
2810                                  pressure,
2811                                  angle - ee->rotation,
2812                                  ee->h - my - 1, mx,
2813                                  timestamp, NULL);
2814    else if (ee->rotation == 180)
2815      evas_event_input_multi_move(ee->evas, device,
2816                                  ee->w - x - 1, ee->h - y - 1,
2817                                  radius,
2818                                  radius_x, radius_y,
2819                                  pressure,
2820                                  angle - ee->rotation,
2821                                  ee->w - mx - 1, ee->h - my - 1,
2822                                  timestamp, NULL);
2823    else if (ee->rotation == 270)
2824      evas_event_input_multi_move(ee->evas, device,
2825                                  y, ee->w - x - 1,
2826                                  radius,
2827                                  radius_y, radius_x,
2828                                  pressure,
2829                                  angle - ee->rotation,
2830                                  my, ee->w - mx - 1,
2831                                  timestamp, NULL);
2832 }
2833
2834 EAPI void
2835 _ecore_evas_mouse_multi_down_process(Ecore_Evas *ee, int device,
2836                                      int x, int y,
2837                                      double radius,
2838                                      double radius_x, double radius_y,
2839                                      double pressure,
2840                                      double angle,
2841                                      double mx, double my,
2842                                      Evas_Button_Flags flags,
2843                                      unsigned int timestamp)
2844 {
2845    if (ee->rotation == 0)
2846      evas_event_input_multi_down(ee->evas, device,
2847                                  x, y,
2848                                  radius,
2849                                  radius_x, radius_y,
2850                                  pressure,
2851                                  angle - ee->rotation,
2852                                  mx, my,
2853                                  flags, timestamp, NULL);
2854    else if (ee->rotation == 90)
2855      evas_event_input_multi_down(ee->evas, device,
2856                                  ee->h - y - 1, x,
2857                                  radius,
2858                                  radius_y, radius_x,
2859                                  pressure,
2860                                  angle - ee->rotation,
2861                                  ee->h - my - 1, mx,
2862                                  flags, timestamp, NULL);
2863    else if (ee->rotation == 180)
2864      evas_event_input_multi_down(ee->evas, device,
2865                                  ee->w - x - 1, ee->h - y - 1,
2866                                  radius,
2867                                  radius_x, radius_y,
2868                                  pressure,
2869                                  angle - ee->rotation,
2870                                  ee->w - mx - 1, ee->h - my - 1,
2871                                  flags, timestamp, NULL);
2872    else if (ee->rotation == 270)
2873      evas_event_input_multi_down(ee->evas, device,
2874                                  y, ee->w - x - 1,
2875                                  radius,
2876                                  radius_y, radius_x,
2877                                  pressure,
2878                                  angle - ee->rotation,
2879                                  my, ee->w - mx - 1,
2880                                  flags, timestamp, NULL);
2881 }
2882
2883 EAPI void
2884 _ecore_evas_mouse_multi_up_process(Ecore_Evas *ee, int device,
2885                                    int x, int y,
2886                                    double radius,
2887                                    double radius_x, double radius_y,
2888                                    double pressure,
2889                                    double angle,
2890                                    double mx, double my,
2891                                    Evas_Button_Flags flags,
2892                                    unsigned int timestamp)
2893 {
2894    if (ee->rotation == 0)
2895      evas_event_input_multi_up(ee->evas, device,
2896                                x, y,
2897                                radius,
2898                                radius_x, radius_y,
2899                                pressure,
2900                                angle - ee->rotation,
2901                                mx, my,
2902                                flags, timestamp, NULL);
2903    else if (ee->rotation == 90)
2904      evas_event_input_multi_up(ee->evas, device,
2905                                ee->h - y - 1, x,
2906                                radius,
2907                                radius_y, radius_x,
2908                                pressure,
2909                                angle - ee->rotation,
2910                                ee->h - my - 1, mx,
2911                                flags, timestamp, NULL);
2912    else if (ee->rotation == 180)
2913      evas_event_input_multi_up(ee->evas, device,
2914                                ee->w - x - 1, ee->h - y - 1,
2915                                radius,
2916                                radius_x, radius_y,
2917                                pressure,
2918                                angle - ee->rotation,
2919                                ee->w - mx - 1, ee->h - my - 1,
2920                                flags, timestamp, NULL);
2921    else if (ee->rotation == 270)
2922      evas_event_input_multi_up(ee->evas, device,
2923                                y, ee->w - x - 1,
2924                                radius,
2925                                radius_y, radius_x,
2926                                pressure,
2927                                angle - ee->rotation,
2928                                my, ee->w - mx - 1,
2929                                flags, timestamp, NULL);
2930 }
2931
2932 EAPI void
2933 _ecore_evas_window_profile_free(Ecore_Evas *ee)
2934 {
2935    if (ee->prop.profile.name)
2936      eina_stringshare_del(ee->prop.profile.name);
2937 }
2938
2939 EAPI void
2940 _ecore_evas_window_available_profiles_free(Ecore_Evas *ee)
2941 {
2942    if (ee->prop.profile.available_list)
2943      {
2944         int i;
2945         for (i = 0; i < ee->prop.profile.count; i++)
2946           {
2947              if (ee->prop.profile.available_list[i])
2948                {
2949                   eina_stringshare_del(ee->prop.profile.available_list[i]);
2950                   ee->prop.profile.available_list[i] = NULL;
2951                }
2952           }
2953         free(ee->prop.profile.available_list);
2954      }
2955 }
2956
2957 EAPI Eina_List *
2958 ecore_evas_ecore_evas_list_get(void)
2959 {
2960    Ecore_Evas *ee;
2961    Eina_List *l = NULL;
2962
2963    EINA_INLIST_FOREACH(ecore_evases, ee)
2964      {
2965         l = eina_list_append(l, ee);
2966      }
2967
2968    return l;
2969 }
2970
2971 EAPI Eina_List *
2972 ecore_evas_sub_ecore_evas_list_get(const Ecore_Evas *ee)
2973 {
2974    ECORE_EVAS_CHECK(ee, NULL);
2975    return ee->sub_ecore_evas;
2976 }
2977
2978 EAPI void
2979 ecore_evas_input_event_register(Ecore_Evas *ee)
2980 {
2981    ecore_event_window_register((Ecore_Window)ee, ee, ee->evas,
2982                                (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
2983                                (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
2984                                (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
2985                                (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
2986    _ecore_event_window_direct_cb_set((Ecore_Window)ee, _ecore_evas_input_direct_cb);
2987 }
2988
2989 EAPI void
2990 ecore_evas_input_event_unregister(Ecore_Evas *ee)
2991 {
2992    ecore_event_window_unregister((Ecore_Window)ee);
2993 }
2994
2995 EAPI Eina_Strbuf *
2996 _ecore_evas_aux_hints_string_get(Ecore_Evas *ee)
2997 {
2998    Eina_Strbuf *buf = eina_strbuf_new();
2999    if (buf)
3000      {
3001         if (eina_list_count(ee->prop.aux_hint.hints) > 0)
3002           {
3003              Eina_List *l;
3004              Ecore_Evas_Aux_Hint *aux;
3005              int i = 0;
3006
3007              EINA_LIST_FOREACH(ee->prop.aux_hint.hints, l, aux)
3008                {
3009                   /* add delimiter */
3010                   if (i > 0) eina_strbuf_append_char(buf, ',');
3011                   eina_strbuf_append_printf(buf, "%d:%s:%s", aux->id, aux->hint, aux->val);
3012                   i++;
3013                }
3014           }
3015      }
3016    return buf;
3017 }
3018
3019 void
3020 _ecore_evas_aux_hint_free(Ecore_Evas *ee)
3021 {
3022    char *hint;
3023    EINA_LIST_FREE(ee->prop.aux_hint.supported_list, hint)
3024      {
3025         eina_stringshare_del(hint);
3026      }
3027
3028    Ecore_Evas_Aux_Hint *aux;
3029    EINA_LIST_FREE(ee->prop.aux_hint.hints, aux)
3030      {
3031         eina_stringshare_del(aux->hint);
3032         eina_stringshare_del(aux->val);
3033         free(aux);
3034      }
3035 }
3036
3037 EAPI Ecore_Evas *
3038 ecore_evas_fb_new(const char *disp_name, int rotation, int w, int h)
3039 {
3040    Ecore_Evas *(*new)(const char *, int, int, int);
3041    Eina_Module *m = _ecore_evas_engine_load("fb");
3042    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
3043
3044    new = eina_module_symbol_get(m, "ecore_evas_fb_new_internal");
3045    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
3046
3047    return new(disp_name, rotation, w, h);
3048 }
3049
3050 EAPI Ecore_Evas *
3051 ecore_evas_software_x11_new(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h)
3052 {
3053    Ecore_Evas *(*new)(const char *, Ecore_X_Window, int, int, int, int);
3054    Eina_Module *m = _ecore_evas_engine_load("x");
3055    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
3056
3057    new = eina_module_symbol_get(m, "ecore_evas_software_x11_new_internal");
3058    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
3059
3060    return new(disp_name, parent, x, y, w, h);
3061 }
3062
3063 EAPI Ecore_X_Window
3064 ecore_evas_software_x11_window_get(const Ecore_Evas *ee)
3065 {
3066    Ecore_Evas_Interface_Software_X11 *iface;
3067    iface = (Ecore_Evas_Interface_Software_X11 *)_ecore_evas_interface_get(ee, "software_x11");
3068    EINA_SAFETY_ON_NULL_RETURN_VAL(iface, 0);
3069
3070    return iface->window_get(ee);
3071 }
3072
3073 EAPI void
3074 ecore_evas_software_x11_direct_resize_set(Ecore_Evas *ee, Eina_Bool on)
3075 {
3076    Ecore_Evas_Interface_Software_X11 *iface;
3077    iface = (Ecore_Evas_Interface_Software_X11 *)_ecore_evas_interface_get(ee, "software_x11");
3078    EINA_SAFETY_ON_NULL_RETURN(iface);
3079
3080    iface->resize_set(ee, on);
3081 }
3082
3083 EAPI Eina_Bool
3084 ecore_evas_software_x11_direct_resize_get(const Ecore_Evas *ee)
3085 {
3086    Ecore_Evas_Interface_Software_X11 *iface;
3087    iface = (Ecore_Evas_Interface_Software_X11 *)_ecore_evas_interface_get(ee, "software_x11");
3088    EINA_SAFETY_ON_NULL_RETURN_VAL(iface, EINA_FALSE);
3089
3090    return iface->resize_get(ee);
3091 }
3092
3093 EAPI void
3094 ecore_evas_software_x11_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win)
3095 {
3096    Ecore_Evas_Interface_Software_X11 *iface;
3097    iface = (Ecore_Evas_Interface_Software_X11 *)_ecore_evas_interface_get(ee, "software_x11");
3098    EINA_SAFETY_ON_NULL_RETURN(iface);
3099
3100    iface->extra_event_window_add(ee, win);
3101 }
3102
3103 EAPI Ecore_Evas *
3104 ecore_evas_software_x11_pixmap_new(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h)
3105 {
3106    Ecore_Evas *(*new)(const char *, Ecore_X_Window, int, int, int, int);
3107    Eina_Module *m = _ecore_evas_engine_load("x");
3108    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
3109
3110    new = eina_module_symbol_get(m, "ecore_evas_software_x11_pixmap_new_internal");
3111    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
3112
3113    return new(disp_name, parent, x, y, w, h);
3114 }
3115
3116 EAPI Ecore_X_Pixmap 
3117 ecore_evas_software_x11_pixmap_get(const Ecore_Evas *ee)
3118 {
3119    Ecore_Evas_Interface_Software_X11 *iface;
3120    iface = (Ecore_Evas_Interface_Software_X11 *)_ecore_evas_interface_get(ee, "software_x11");
3121    EINA_SAFETY_ON_NULL_RETURN_VAL(iface, 0);
3122
3123    if (iface->pixmap_get)
3124      return iface->pixmap_get(ee);
3125
3126    return 0;
3127 }
3128
3129 EAPI Ecore_Evas *
3130 ecore_evas_gl_x11_new(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h)
3131 {
3132    Ecore_Evas *(*new)(const char *, Ecore_X_Window, int, int, int, int);
3133    Eina_Module *m = _ecore_evas_engine_load("x");
3134    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
3135
3136    new = eina_module_symbol_get(m, "ecore_evas_gl_x11_new_internal");
3137    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
3138
3139    return new(disp_name, parent, x, y, w, h);
3140 }
3141
3142 EAPI Ecore_Evas *
3143 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)
3144 {
3145    Ecore_Evas *(*new)(const char *, Ecore_X_Window, int, int, int, int, const int*);
3146    Eina_Module *m = _ecore_evas_engine_load("x");
3147    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
3148
3149    new = eina_module_symbol_get(m, "ecore_evas_gl_x11_options_new_internal");
3150    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
3151
3152    return new(disp_name, parent, x, y, w, h, opt);
3153 }
3154
3155 EAPI Ecore_Evas *
3156 ecore_evas_gl_x11_pixmap_new(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h)
3157 {
3158    Ecore_Evas *(*new)(const char *, Ecore_X_Window, int, int, int, int);
3159    Eina_Module *m = _ecore_evas_engine_load("x");
3160    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
3161
3162    new = eina_module_symbol_get(m, "ecore_evas_gl_x11_pixmap_new_internal");
3163    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
3164
3165    return new(disp_name, parent, x, y, w, h);
3166 }
3167
3168 EAPI Ecore_X_Pixmap 
3169 ecore_evas_gl_x11_pixmap_get(const Ecore_Evas *ee)
3170 {
3171    Ecore_Evas_Interface_Gl_X11 *iface;
3172    iface = (Ecore_Evas_Interface_Gl_X11 *)_ecore_evas_interface_get(ee, "gl_x11");
3173    EINA_SAFETY_ON_NULL_RETURN_VAL(iface, 0);
3174
3175    if (iface->pixmap_get)
3176      return iface->pixmap_get(ee);
3177
3178    return 0;
3179 }
3180
3181 EAPI Ecore_X_Window
3182 ecore_evas_gl_x11_window_get(const Ecore_Evas *ee)
3183 {
3184    Ecore_Evas_Interface_Gl_X11 *iface;
3185    iface = (Ecore_Evas_Interface_Gl_X11 *)_ecore_evas_interface_get(ee, "gl_x11");
3186    EINA_SAFETY_ON_NULL_RETURN_VAL(iface, 0);
3187
3188    return iface->window_get(ee);
3189 }
3190
3191 EAPI void
3192 ecore_evas_gl_x11_direct_resize_set(Ecore_Evas *ee, Eina_Bool on)
3193 {
3194    Ecore_Evas_Interface_Gl_X11 *iface;
3195    iface = (Ecore_Evas_Interface_Gl_X11 *)_ecore_evas_interface_get(ee, "gl_x11");
3196    EINA_SAFETY_ON_NULL_RETURN(iface);
3197
3198    iface->resize_set(ee, on);
3199 }
3200
3201 EAPI Eina_Bool
3202 ecore_evas_gl_x11_direct_resize_get(const Ecore_Evas *ee)
3203 {
3204    Ecore_Evas_Interface_Gl_X11 *iface;
3205    iface = (Ecore_Evas_Interface_Gl_X11 *)_ecore_evas_interface_get(ee, "gl_x11");
3206    EINA_SAFETY_ON_NULL_RETURN_VAL(iface, EINA_FALSE);
3207
3208    return iface->resize_get(ee);
3209 }
3210
3211 EAPI void
3212 ecore_evas_gl_x11_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win)
3213 {
3214    Ecore_Evas_Interface_Gl_X11 *iface;
3215    iface = (Ecore_Evas_Interface_Gl_X11 *)_ecore_evas_interface_get(ee, "gl_x11");
3216    EINA_SAFETY_ON_NULL_RETURN(iface);
3217
3218    iface->extra_event_window_add(ee, win);
3219 }
3220
3221 EAPI void
3222 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))
3223 {
3224    Ecore_Evas_Interface_Gl_X11 *iface;
3225    iface = (Ecore_Evas_Interface_Gl_X11 *)_ecore_evas_interface_get(ee, "gl_x11");
3226    EINA_SAFETY_ON_NULL_RETURN(iface);
3227
3228    iface->pre_post_swap_callback_set(ee, data, pre_cb, post_cb);
3229 }
3230
3231 EAPI void
3232 ecore_evas_x11_leader_set(Ecore_Evas *ee, Ecore_X_Window win)
3233 {
3234    Ecore_Evas_Interface_X11 *iface;
3235    iface = (Ecore_Evas_Interface_X11 *)_ecore_evas_interface_get(ee, "x11");
3236    EINA_SAFETY_ON_NULL_RETURN(iface);
3237
3238    iface->leader_set(ee, win);
3239 }
3240
3241 EAPI Ecore_X_Window
3242 ecore_evas_x11_leader_get(Ecore_Evas *ee)
3243 {
3244    Ecore_Evas_Interface_X11 *iface;
3245    iface = (Ecore_Evas_Interface_X11 *)_ecore_evas_interface_get(ee, "x11");
3246    EINA_SAFETY_ON_NULL_RETURN_VAL(iface, 0);
3247
3248    return iface->leader_get(ee);
3249 }
3250
3251 EAPI void
3252 ecore_evas_x11_leader_default_set(Ecore_Evas *ee)
3253 {
3254    Ecore_Evas_Interface_X11 *iface;
3255    iface = (Ecore_Evas_Interface_X11 *)_ecore_evas_interface_get(ee, "x11");
3256    EINA_SAFETY_ON_NULL_RETURN(iface);
3257
3258    iface->leader_default_set(ee);
3259 }
3260
3261 EAPI void
3262 ecore_evas_x11_shape_input_rectangle_set(Ecore_Evas *ee, int x, int y, int w, int h)
3263 {
3264    Ecore_Evas_Interface_X11 *iface;
3265    iface = (Ecore_Evas_Interface_X11 *)_ecore_evas_interface_get(ee, "x11");
3266    EINA_SAFETY_ON_NULL_RETURN(iface);
3267
3268    iface->shape_input_rectangle_set(ee, x, y, w, h);
3269 }
3270
3271 EAPI void
3272 ecore_evas_x11_shape_input_rectangle_add(Ecore_Evas *ee, int x, int y, int w, int h)
3273 {
3274    Ecore_Evas_Interface_X11 *iface;
3275    iface = (Ecore_Evas_Interface_X11 *)_ecore_evas_interface_get(ee, "x11");
3276    EINA_SAFETY_ON_NULL_RETURN(iface);
3277
3278    iface->shape_input_rectangle_add(ee, x, y, w, h);
3279 }
3280
3281 EAPI void
3282 ecore_evas_x11_shape_input_rectangle_subtract(Ecore_Evas *ee, int x, int y, int w, int h)
3283 {
3284    Ecore_Evas_Interface_X11 *iface;
3285    iface = (Ecore_Evas_Interface_X11 *)_ecore_evas_interface_get(ee, "x11");
3286    EINA_SAFETY_ON_NULL_RETURN(iface);
3287
3288    iface->shape_input_rectangle_subtract(ee, x, y, w, h);
3289 }
3290
3291 EAPI void
3292 ecore_evas_x11_shape_input_empty(Ecore_Evas *ee)
3293 {
3294    Ecore_Evas_Interface_X11 *iface;
3295    iface = (Ecore_Evas_Interface_X11 *)_ecore_evas_interface_get(ee, "x11");
3296    EINA_SAFETY_ON_NULL_RETURN(iface);
3297
3298    iface->shape_input_empty(ee);
3299 }
3300
3301 EAPI void
3302 ecore_evas_x11_shape_input_reset(Ecore_Evas *ee)
3303 {
3304    Ecore_Evas_Interface_X11 *iface;
3305    iface = (Ecore_Evas_Interface_X11 *)_ecore_evas_interface_get(ee, "x11");
3306    EINA_SAFETY_ON_NULL_RETURN(iface);
3307
3308    iface->shape_input_reset(ee);
3309 }
3310
3311 EAPI void
3312 ecore_evas_x11_shape_input_apply(Ecore_Evas *ee)
3313 {
3314    Ecore_Evas_Interface_X11 *iface;
3315    iface = (Ecore_Evas_Interface_X11 *)_ecore_evas_interface_get(ee, "x11");
3316    EINA_SAFETY_ON_NULL_RETURN(iface);
3317
3318    iface->shape_input_apply(ee);
3319 }
3320
3321 EAPI Eina_Bool
3322 ecore_evas_vnc_start(Ecore_Evas *ee, const char *addr, int port,
3323                      Ecore_Evas_Vnc_Client_Accept_Cb cb, void *data)
3324 {
3325    Eina_Module *mod;
3326    void *(*vnc_new)(Ecore_Evas *, int, const char *,
3327                     Ecore_Evas_Vnc_Client_Accept_Cb, void *);
3328
3329    EINA_SAFETY_ON_NULL_RETURN_VAL(ee, EINA_FALSE);
3330
3331    if (ee->vnc_server)
3332      return EINA_FALSE;
3333
3334    mod = _ecore_evas_vnc_server_module_load();
3335    EINA_SAFETY_ON_NULL_RETURN_VAL(mod, EINA_FALSE);
3336
3337    vnc_new = eina_module_symbol_get(mod, "ecore_evas_vnc_server_new");
3338    EINA_SAFETY_ON_NULL_RETURN_VAL(vnc_new, EINA_FALSE);
3339
3340    ee->vnc_server = vnc_new(ee, port, addr, cb, data);
3341    EINA_SAFETY_ON_NULL_RETURN_VAL(ee->vnc_server, EINA_FALSE);
3342    return EINA_TRUE;
3343 }
3344
3345 EAPI Eina_Bool
3346 ecore_evas_vnc_stop(Ecore_Evas *ee)
3347 {
3348    EINA_SAFETY_ON_NULL_RETURN_VAL(ee, EINA_FALSE);
3349    EINA_SAFETY_ON_FALSE_RETURN_VAL(ee->vnc_server, EINA_FALSE);
3350
3351    return _ecore_evas_vnc_stop(ee);
3352 }
3353
3354 EAPI Ecore_Evas *
3355 ecore_evas_extn_socket_new(int w, int h)
3356 {
3357    Ecore_Evas *(*new)(int, int);
3358    Eina_Module *m = _ecore_evas_engine_load("extn");
3359    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
3360
3361    new = eina_module_symbol_get(m, "ecore_evas_extn_socket_new_internal");
3362    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
3363
3364    return new(w, h);
3365 }
3366
3367 EAPI Eina_Bool
3368 ecore_evas_extn_socket_listen(Ecore_Evas *ee, const char *svcname, int svcnum, Eina_Bool svcsys)
3369 {
3370    Ecore_Evas_Interface_Extn *iface;
3371    iface = (Ecore_Evas_Interface_Extn *)_ecore_evas_interface_get(ee, "extn");
3372    EINA_SAFETY_ON_NULL_RETURN_VAL(iface, EINA_FALSE);
3373
3374    return iface->listen(ee, svcname, svcnum, svcsys);
3375 }
3376
3377 EAPI void
3378 ecore_evas_extn_socket_events_block_set(Ecore_Evas *ee, Eina_Bool events_block)
3379 {
3380    void (*set)(Ecore_Evas*, Eina_Bool);
3381    Eina_Module *m = _ecore_evas_engine_load("extn");
3382    EINA_SAFETY_ON_NULL_RETURN(m);
3383
3384    set = eina_module_symbol_get(m,
3385          "ecore_evas_extn_socket_events_block_set_internal");
3386    EINA_SAFETY_ON_NULL_RETURN(set);
3387
3388    set(ee, events_block);
3389 }
3390
3391 EAPI Eina_Bool
3392 ecore_evas_extn_socket_events_block_get(Ecore_Evas *ee)
3393 {
3394    Eina_Bool (*get)(Ecore_Evas*);
3395    Eina_Module *m = _ecore_evas_engine_load("extn");
3396    EINA_SAFETY_ON_NULL_RETURN_VAL(m, EINA_FALSE);
3397
3398    get = eina_module_symbol_get(m,
3399          "ecore_evas_extn_socket_events_block_get_internal");
3400    EINA_SAFETY_ON_NULL_RETURN_VAL(get, EINA_FALSE);
3401
3402    return get(ee);
3403 }
3404
3405 EAPI void
3406 ecore_evas_extn_plug_object_data_lock(Evas_Object *obj)
3407 {
3408    Ecore_Evas_Interface_Extn *iface;
3409    Ecore_Evas *ee;
3410
3411    ee = ecore_evas_object_ecore_evas_get(obj);
3412    EINA_SAFETY_ON_NULL_RETURN(ee);
3413
3414    iface = (Ecore_Evas_Interface_Extn *)_ecore_evas_interface_get(ee, "extn");
3415    EINA_SAFETY_ON_NULL_RETURN(iface);
3416
3417    iface->data_lock(ee);
3418 }
3419
3420 EAPI void
3421 ecore_evas_extn_plug_object_data_unlock(Evas_Object *obj)
3422 {
3423    Ecore_Evas_Interface_Extn *iface;
3424    Ecore_Evas *ee;
3425
3426    ee = ecore_evas_object_ecore_evas_get(obj);
3427    EINA_SAFETY_ON_NULL_RETURN(ee);
3428
3429    iface = (Ecore_Evas_Interface_Extn *)_ecore_evas_interface_get(ee, "extn");
3430    EINA_SAFETY_ON_NULL_RETURN(iface);
3431
3432    iface->data_unlock(ee);
3433 }
3434
3435 EAPI Evas_Object *
3436 ecore_evas_extn_plug_new(Ecore_Evas *ee_target)
3437 {
3438    Evas_Object *(*new)(Ecore_Evas *);
3439    Eina_Module *m = _ecore_evas_engine_load("extn");
3440    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
3441
3442    new = eina_module_symbol_get(m, "ecore_evas_extn_plug_new_internal");
3443    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
3444
3445    return new(ee_target);
3446 }
3447
3448 EAPI Eina_Bool
3449 ecore_evas_extn_plug_connect(Evas_Object *obj, const char *svcname, int svcnum, Eina_Bool svcsys)
3450 {
3451    Ecore_Evas_Interface_Extn *iface;
3452    Ecore_Evas *ee;
3453
3454    ee = ecore_evas_object_ecore_evas_get(obj);
3455    EINA_SAFETY_ON_NULL_RETURN_VAL(ee, EINA_FALSE);
3456
3457    iface = (Ecore_Evas_Interface_Extn *)_ecore_evas_interface_get(ee, "extn");
3458    EINA_SAFETY_ON_NULL_RETURN_VAL(iface, EINA_FALSE);
3459
3460    return iface->connect(ee, svcname, svcnum, svcsys);
3461 }
3462
3463 EAPI Ecore_Evas *
3464 ecore_evas_sdl_new(const char* name, int w, int h, int fullscreen,
3465                    int hwsurface, int noframe, int alpha)
3466 {
3467    Ecore_Evas *(*new)(const char *, int, int, int, int, int, int);
3468    Eina_Module *m = _ecore_evas_engine_load("sdl");
3469    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
3470
3471    new = eina_module_symbol_get(m, "ecore_evas_sdl_new_internal");
3472    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
3473
3474    return new(name, w, h, fullscreen, hwsurface, noframe, alpha);
3475 }
3476
3477 EAPI Ecore_Evas *
3478 ecore_evas_sdl16_new(const char* name, int w, int h, int fullscreen,
3479                      int hwsurface, int noframe, int alpha)
3480 {
3481    Ecore_Evas *(*new)(const char *, int, int, int, int, int, int);
3482    Eina_Module *m = _ecore_evas_engine_load("sdl");
3483    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
3484
3485    new = eina_module_symbol_get(m, "ecore_evas_sdl16_new_internal");
3486    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
3487
3488    return new(name, w, h, fullscreen, hwsurface, noframe, alpha);
3489 }
3490
3491 EAPI Ecore_Evas *
3492 ecore_evas_gl_sdl_new(const char* name, int w, int h, int fullscreen, int noframe)
3493 {
3494    Ecore_Evas *(*new)(const char *, int, int, int, int);
3495    Eina_Module *m = _ecore_evas_engine_load("sdl");
3496    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
3497
3498    new = eina_module_symbol_get(m, "ecore_evas_gl_sdl_new_internal");
3499    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
3500
3501    return new(name, w, h, fullscreen, noframe);
3502 }
3503
3504 EAPI Ecore_Evas *
3505 ecore_evas_wayland_shm_new(const char *disp_name, unsigned int parent,
3506                            int x, int y, int w, int h, Eina_Bool frame)
3507 {
3508    Ecore_Evas *(*new)(const char *, unsigned int, int, int, int, int, Eina_Bool);
3509    Eina_Module *m = _ecore_evas_engine_load("wayland");
3510    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
3511
3512    new = eina_module_symbol_get(m, "ecore_evas_wayland_shm_new_internal");
3513    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
3514
3515    return new(disp_name, parent, x, y, w, h, frame);
3516 }
3517
3518 EAPI Ecore_Evas *
3519 ecore_evas_wayland_egl_new(const char *disp_name, unsigned int parent,
3520                            int x, int y, int w, int h, Eina_Bool frame)
3521 {
3522    Ecore_Evas *(*new)(const char *, unsigned int, int, int, int, int, Eina_Bool);
3523    Eina_Module *m = _ecore_evas_engine_load("wayland");
3524    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
3525
3526    new = eina_module_symbol_get(m, "ecore_evas_wayland_egl_new_internal");
3527    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
3528
3529    return new(disp_name, parent, x, y, w, h, frame);
3530 }
3531
3532 EAPI void
3533 ecore_evas_wayland_resize(Ecore_Evas *ee, int location)
3534 {
3535    Ecore_Evas_Interface_Wayland *iface;
3536    iface = (Ecore_Evas_Interface_Wayland *)_ecore_evas_interface_get(ee, "wayland");
3537    EINA_SAFETY_ON_NULL_RETURN(iface);
3538
3539    iface->resize(ee, location);
3540 }
3541
3542 EAPI void
3543 ecore_evas_wayland_move(Ecore_Evas *ee, int x, int y)
3544 {
3545    Ecore_Evas_Interface_Wayland *iface;
3546    iface = (Ecore_Evas_Interface_Wayland *)_ecore_evas_interface_get(ee, "wayland");
3547    EINA_SAFETY_ON_NULL_RETURN(iface);
3548
3549    iface->move(ee, x, y);
3550 }
3551
3552 EAPI void
3553 ecore_evas_wayland_pointer_set(Ecore_Evas *ee, int hot_x, int hot_y)
3554 {
3555    Ecore_Evas_Interface_Wayland *iface;
3556    iface = (Ecore_Evas_Interface_Wayland *)_ecore_evas_interface_get(ee, "wayland");
3557    EINA_SAFETY_ON_NULL_RETURN(iface);
3558
3559    iface->pointer_set(ee, hot_x, hot_y);
3560 }
3561
3562 EAPI void
3563 ecore_evas_wayland_type_set(Ecore_Evas *ee, int type)
3564 {
3565    Ecore_Evas_Interface_Wayland *iface;
3566    iface = (Ecore_Evas_Interface_Wayland *)_ecore_evas_interface_get(ee, "wayland");
3567    EINA_SAFETY_ON_NULL_RETURN(iface);
3568
3569    iface->type_set(ee, type);
3570 }
3571
3572 EAPI Ecore_Wl_Window *
3573 ecore_evas_wayland_window_get(const Ecore_Evas *ee)
3574 {
3575    Ecore_Evas_Interface_Wayland *iface;
3576    iface = (Ecore_Evas_Interface_Wayland *)_ecore_evas_interface_get(ee, "wayland");
3577    EINA_SAFETY_ON_NULL_RETURN_VAL(iface, NULL);
3578
3579    return iface->window_get(ee);
3580 }
3581
3582 EAPI Ecore_Cocoa_Window *
3583 ecore_evas_cocoa_window_get(const Ecore_Evas *ee)
3584 {
3585    Ecore_Evas_Interface_Cocoa *iface;
3586    iface = (Ecore_Evas_Interface_Cocoa *)_ecore_evas_interface_get(ee, "opengl_cocoa");
3587    EINA_SAFETY_ON_NULL_RETURN_VAL(iface, NULL);
3588    return iface->window_get(ee);
3589 }
3590
3591 EAPI Ecore_Wl2_Window *
3592 ecore_evas_wayland2_window_get(const Ecore_Evas *ee)
3593 {
3594    Ecore_Evas_Interface_Wayland *iface;
3595    iface = (Ecore_Evas_Interface_Wayland *)_ecore_evas_interface_get(ee, "wayland");
3596    EINA_SAFETY_ON_NULL_RETURN_VAL(iface, NULL);
3597
3598    return iface->window2_get(ee);
3599 }
3600
3601 EAPI Ecore_Evas *
3602 ecore_evas_drm_new(const char *disp_name, unsigned int parent,
3603                    int x, int y, int w, int h)
3604 {
3605    Ecore_Evas *(*new)(const char *, unsigned int, int, int, int, int);
3606    Eina_Module *m = _ecore_evas_engine_load("drm");
3607    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
3608
3609    new = eina_module_symbol_get(m, "ecore_evas_drm_new_internal");
3610    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
3611
3612    return new(disp_name, parent, x, y, w, h);
3613 }
3614
3615 EAPI Ecore_Evas *
3616 ecore_evas_gl_drm_new(const char *disp_name, unsigned int parent,
3617                           int x, int y, int w, int h)
3618 {
3619    Ecore_Evas *(*new)(const char *, unsigned int, int, int, int, int);
3620    Eina_Module *m = _ecore_evas_engine_load("drm");
3621    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
3622
3623    new = eina_module_symbol_get(m, "ecore_evas_gl_drm_new_internal");
3624    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
3625
3626    return new(disp_name, parent, x, y, w, h);
3627 }
3628
3629 EAPI Ecore_Evas *
3630 ecore_evas_software_gdi_new(Ecore_Win32_Window *parent,
3631                             int                 x,
3632                             int                 y,
3633                             int                 width,
3634                             int                 height)
3635 {
3636    Ecore_Evas *(*new)(Ecore_Win32_Window *, int, int, int, int);
3637    Eina_Module *m = _ecore_evas_engine_load("win32");
3638    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
3639
3640    new = eina_module_symbol_get(m, "ecore_evas_software_gdi_new_internal");
3641    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
3642
3643    return new(parent, x, y, width, height);
3644 }
3645
3646 EAPI Ecore_Evas *
3647 ecore_evas_software_ddraw_new(Ecore_Win32_Window *parent,
3648                               int                 x,
3649                               int                 y,
3650                               int                 width,
3651                               int                 height)
3652 {
3653    Ecore_Evas *(*new)(Ecore_Win32_Window *, int, int, int, int);
3654    Eina_Module *m = _ecore_evas_engine_load("win32");
3655    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
3656
3657    new = eina_module_symbol_get(m, "ecore_evas_software_ddraw_new_internal");
3658    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
3659
3660    return new(parent, x, y, width, height);
3661 }
3662
3663 EAPI Ecore_Win32_Window *
3664 ecore_evas_win32_window_get(const Ecore_Evas *ee)
3665 {
3666    Ecore_Evas_Interface_Win32 *iface;
3667    iface = (Ecore_Evas_Interface_Win32 *)_ecore_evas_interface_get(ee, "win32");
3668    EINA_SAFETY_ON_NULL_RETURN_VAL(iface, NULL);
3669
3670    return iface->window_get(ee);
3671 }
3672
3673 EAPI Ecore_Evas *
3674 ecore_evas_cocoa_new(Ecore_Cocoa_Window *parent, int x, int y, int w, int h)
3675 {
3676    Ecore_Evas *(*new)(Ecore_Cocoa_Window *, int, int, int, int);
3677    Eina_Module *m = _ecore_evas_engine_load("cocoa");
3678    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
3679
3680    new = eina_module_symbol_get(m, "ecore_evas_cocoa_new_internal");
3681    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
3682
3683    return new(parent, x, y, w, h);
3684 }
3685
3686 EAPI Ecore_Evas *
3687 ecore_evas_psl1ght_new(const char* name, int w, int h)
3688 {
3689    Ecore_Evas *(*new)(const char*, int, int);
3690    Eina_Module *m = _ecore_evas_engine_load("psl1ght");
3691    EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL);
3692
3693    new = eina_module_symbol_get(m, "ecore_evas_psl1ght_new_internal");
3694    EINA_SAFETY_ON_NULL_RETURN_VAL(new, NULL);
3695
3696    return new(name, w, h);
3697 }
3698
3699
3700 /* new input model with eo:
3701  *  1. pass all events from ecore_input_evas through
3702  *     ecore_evas and send eo events from here
3703  *  2. those eo events can then be translated to legacy by evas
3704  *  3. let evas send legacy & eo events to the objects
3705  */
3706
3707 #define EVENT_XY_SET(EV, MX, MY, FX, FY) do { \
3708    EV->cur.x = (MX) - (FX); EV->cur.y = (MY) - (FY); \
3709    } while (0)
3710
3711 static inline void
3712 _pointer_position_set(Efl_Input_Pointer_Data *ev, Ecore_Evas *ee, int x, int y,
3713                       double mx, double my)
3714 {
3715    int fx, fy, fw, fh;
3716
3717    if (!mx && !my)
3718      {
3719         mx = x;
3720         my = y;
3721      }
3722
3723    evas_output_framespace_get(ee->evas, &fx, &fy, &fw, &fh);
3724    if (ee->rotation == 0)
3725      EVENT_XY_SET(ev, mx, my, fx, fy);
3726    else if (ee->rotation == 90)
3727      EVENT_XY_SET(ev, ee->h + fw - my - 1, mx, fx, fy);
3728    else if (ee->rotation == 180)
3729      EVENT_XY_SET(ev, ee->w + fw - mx - 1, ee->h + fh - my - 1, fx, fy);
3730    else if (ee->rotation == 270)
3731      EVENT_XY_SET(ev, my, ee->w + fh - mx - 1, fx, fy);
3732 }
3733
3734 static const Efl_Event_Description *
3735 _event_description_get(Efl_Pointer_Action action)
3736 {
3737    switch (action)
3738      {
3739       case EFL_POINTER_ACTION_MOVE:
3740         return EFL_EVENT_POINTER_MOVE;
3741       case EFL_POINTER_ACTION_DOWN:
3742         return EFL_EVENT_POINTER_DOWN;
3743       case EFL_POINTER_ACTION_UP:
3744         return EFL_EVENT_POINTER_UP;
3745       case EFL_POINTER_ACTION_CANCEL:
3746         return EFL_EVENT_POINTER_CANCEL;
3747       case EFL_POINTER_ACTION_IN:
3748         return EFL_EVENT_POINTER_IN;
3749       case EFL_POINTER_ACTION_OUT:
3750         return EFL_EVENT_POINTER_OUT;
3751       case EFL_POINTER_ACTION_WHEEL:
3752         return EFL_EVENT_POINTER_WHEEL;
3753       case EFL_POINTER_ACTION_AXIS:
3754         return EFL_EVENT_POINTER_AXIS;
3755       default: return NULL;
3756      }
3757 }
3758
3759 static Eina_Bool
3760 _direct_mouse_updown(Ecore_Evas *ee, const Ecore_Event_Mouse_Button *info, Efl_Pointer_Action action)
3761 {
3762    Efl_Input_Pointer_Data *ev;
3763    Efl_Input_Pointer *evt;
3764    Evas *e = ee->evas;
3765    Eina_Bool processed;
3766
3767    /* Unused information:
3768     * same_screen
3769     * root.{x,y}
3770     * root_window
3771     * event_window
3772     * same_screen
3773     * modifiers (already passed to evas, no need to do anything)
3774     */
3775
3776    evt = efl_input_instance_get(EFL_INPUT_POINTER_CLASS, e, (void **) &ev);
3777    if (!evt) return EINA_FALSE;
3778
3779    ev->action = action;
3780    ev->button = info->buttons;
3781    if (info->double_click) ev->button_flags |= EFL_POINTER_FLAGS_DOUBLE_CLICK;
3782    if (info->triple_click) ev->button_flags |= EFL_POINTER_FLAGS_TRIPLE_CLICK;
3783    ev->timestamp = info->timestamp;
3784    ev->tool = info->multi.device;
3785    _pointer_position_set(ev, ee, info->x, info->y, info->multi.x, info->multi.y);
3786    ev->radius = info->multi.radius;
3787    ev->radius_x = info->multi.radius_x;
3788    ev->radius_y = info->multi.radius_y;
3789    ev->pressure = info->multi.pressure;
3790    ev->angle = info->multi.angle - ee->rotation;
3791
3792    efl_event_callback_legacy_call(e, _event_description_get(ev->action), evt);
3793    processed = ev->evas_done;
3794    efl_del(evt);
3795
3796    return processed;
3797 }
3798
3799 static Eina_Bool
3800 _direct_mouse_down_cb(Ecore_Evas *ee, const Ecore_Event_Mouse_Button *info)
3801 {
3802    return _direct_mouse_updown(ee, info, EFL_POINTER_ACTION_DOWN);
3803 }
3804
3805 static Eina_Bool
3806 _direct_mouse_up_cb(Ecore_Evas *ee, const Ecore_Event_Mouse_Button *info)
3807 {
3808    return _direct_mouse_updown(ee, info, EFL_POINTER_ACTION_UP);
3809 }
3810
3811 static Eina_Bool
3812 _direct_mouse_cancel_cb(Ecore_Evas *ee, const Ecore_Event_Mouse_Button *info)
3813 {
3814    return _direct_mouse_updown(ee, info, EFL_POINTER_ACTION_CANCEL);
3815 }
3816
3817 static Eina_Bool
3818 _direct_mouse_move_cb(Ecore_Evas *ee, const Ecore_Event_Mouse_Move *info)
3819 {
3820    Efl_Input_Pointer_Data *ev;
3821    Efl_Input_Pointer *evt;
3822    Evas *e = ee->evas;
3823    Eina_Bool processed;
3824
3825    _ecore_evas_mouse_move_process_internal(ee, info->x, info->y, info->timestamp, EINA_FALSE);
3826
3827    /* Unused information:
3828     * same_screen
3829     * root.{x,y}
3830     * root_window
3831     * event_window
3832     * same_screen
3833     * modifiers (already passed to evas, no need to do anything)
3834     */
3835
3836    evt = efl_input_instance_get(EFL_INPUT_POINTER_CLASS, e, (void **) &ev);
3837    if (!evt) return EINA_FALSE;
3838
3839    ev->action = EFL_POINTER_ACTION_MOVE;
3840    ev->timestamp = info->timestamp;
3841    ev->tool = info->multi.device;
3842    _pointer_position_set(ev, ee, info->x, info->y, info->multi.x, info->multi.y);
3843
3844    ev->radius = info->multi.radius;
3845    ev->radius_x = info->multi.radius_x;
3846    ev->radius_y = info->multi.radius_y;
3847    ev->pressure = info->multi.pressure;
3848    ev->angle = info->multi.angle - ee->rotation;
3849
3850    efl_event_callback_legacy_call(e, _event_description_get(ev->action), evt);
3851    processed = ev->evas_done;
3852    efl_del(evt);
3853
3854    return processed;
3855 }
3856
3857 static Eina_Bool
3858 _direct_mouse_wheel_cb(Ecore_Evas *ee, const Ecore_Event_Mouse_Wheel *info)
3859 {
3860    Efl_Input_Pointer_Data *ev;
3861    Efl_Input_Pointer *evt;
3862    Evas *e = ee->evas;
3863    Eina_Bool processed;
3864
3865    /* Unused information:
3866     * same_screen
3867     * root.{x,y}
3868     * root_window
3869     * event_window
3870     * modifiers (already passed to evas, no need to do anything)
3871     */
3872
3873    evt = efl_input_instance_get(EFL_INPUT_POINTER_CLASS, e, (void **) &ev);
3874    if (!evt) return EINA_FALSE;
3875
3876    ev->action = EFL_POINTER_ACTION_WHEEL;
3877    ev->timestamp = info->timestamp;
3878    _pointer_position_set(ev, ee, info->x, info->y, info->x, info->y);
3879    ev->wheel.z = info->z;
3880    ev->wheel.dir = info->direction ? EFL_ORIENT_HORIZONTAL : EFL_ORIENT_VERTICAL;
3881
3882    efl_event_callback_legacy_call(e, _event_description_get(ev->action), evt);
3883    processed = ev->evas_done;
3884    efl_del(evt);
3885
3886    return processed;
3887 }
3888
3889 static Eina_Bool
3890 _direct_mouse_inout(Ecore_Evas *ee, const Ecore_Event_Mouse_IO *info, Efl_Pointer_Action action)
3891 {
3892    Efl_Input_Pointer_Data *ev;
3893    Efl_Input_Pointer *evt;
3894    Evas *e = ee->evas;
3895    Eina_Bool processed;
3896
3897    /* Unused information:
3898     * event_window
3899     * modifiers (already passed to evas, no need to do anything)
3900     */
3901
3902    evt = efl_input_instance_get(EFL_INPUT_POINTER_CLASS, e, (void **) &ev);
3903    if (!evt) return EINA_FALSE;
3904
3905    ev->action = action;
3906    ev->timestamp = info->timestamp;
3907    _pointer_position_set(ev, ee, info->x, info->y, info->x, info->y);
3908
3909    efl_event_callback_legacy_call(e, _event_description_get(ev->action), evt);
3910    processed = ev->evas_done;
3911    efl_del(evt);
3912
3913    return processed;
3914 }
3915
3916 static Eina_Bool
3917 _direct_mouse_in_cb(Ecore_Evas *ee, const Ecore_Event_Mouse_IO *info)
3918 {
3919    return _direct_mouse_inout(ee, info, EFL_POINTER_ACTION_IN);
3920 }
3921
3922 static Eina_Bool
3923 _direct_mouse_out_cb(Ecore_Evas *ee, const Ecore_Event_Mouse_IO *info)
3924 {
3925    return _direct_mouse_inout(ee, info, EFL_POINTER_ACTION_OUT);
3926 }
3927
3928 static Eina_Bool
3929 _direct_axis_update_cb(Ecore_Evas *ee, const Ecore_Event_Axis_Update *info)
3930 {
3931    Eina_Bool haswinx = 0, haswiny = 0;
3932    Efl_Input_Pointer_Data *ev;
3933    Efl_Input_Pointer *evt;
3934    Evas *e = ee->evas;
3935    Eina_Bool processed;
3936    double x = 0, y = 0;
3937    int n;
3938
3939    /* Unused information:
3940     * window, root_window, event_window
3941     */
3942
3943    evt = efl_input_instance_get(EFL_INPUT_POINTER_CLASS, e, (void **) &ev);
3944    if (!ev) return EINA_FALSE;
3945
3946    ev->action = EFL_POINTER_ACTION_AXIS;
3947    ev->timestamp = info->timestamp;
3948    ev->tool = info->toolid;
3949
3950    // see also evas_events.c
3951    for (n = 0; n < info->naxis; n++)
3952      {
3953         const Ecore_Axis *axis = &(info->axis[n]);
3954         switch (axis->label)
3955           {
3956            case EVAS_AXIS_LABEL_WINDOW_X:
3957              _efl_input_value_mark(ev, EFL_INPUT_VALUE_X);
3958              x = axis->value;
3959              haswinx = EINA_TRUE;
3960              break;
3961
3962            case EVAS_AXIS_LABEL_WINDOW_Y:
3963              _efl_input_value_mark(ev, EFL_INPUT_VALUE_Y);
3964              y = axis->value;
3965              haswiny = EINA_TRUE;
3966              break;
3967
3968            case EVAS_AXIS_LABEL_X:
3969              if (!haswinx)
3970                {
3971                   _efl_input_value_mark(ev, EFL_INPUT_VALUE_X);
3972                   x = axis->value;
3973                }
3974              ev->raw.x = axis->value;
3975              ev->has_raw = EINA_TRUE;
3976              break;
3977
3978            case EVAS_AXIS_LABEL_Y:
3979              if (!haswiny)
3980                {
3981                   _efl_input_value_mark(ev, EFL_INPUT_VALUE_Y);
3982                   y = axis->value;
3983                }
3984              ev->raw.y = axis->value;
3985              ev->has_raw = EINA_TRUE;
3986              break;
3987
3988            case EVAS_AXIS_LABEL_NORMAL_X:
3989              ev->norm.x = axis->value;
3990              ev->has_norm = EINA_TRUE;
3991              break;
3992
3993            case EVAS_AXIS_LABEL_NORMAL_Y:
3994              ev->norm.y = axis->value;
3995              ev->has_norm = EINA_TRUE;
3996              break;
3997
3998            case EVAS_AXIS_LABEL_PRESSURE:
3999              _efl_input_value_mark(ev, EFL_INPUT_VALUE_PRESSURE);
4000              ev->pressure = axis->value;
4001              break;
4002
4003            case EVAS_AXIS_LABEL_DISTANCE:
4004              _efl_input_value_mark(ev, EFL_INPUT_VALUE_DISTANCE);
4005              ev->distance = axis->value;
4006              break;
4007
4008            case EVAS_AXIS_LABEL_AZIMUTH:
4009              _efl_input_value_mark(ev, EFL_INPUT_VALUE_AZIMUTH);
4010              ev->azimuth = axis->value;
4011              break;
4012
4013            case EVAS_AXIS_LABEL_TILT:
4014              _efl_input_value_mark(ev, EFL_INPUT_VALUE_TILT);
4015              ev->tilt = axis->value;
4016              break;
4017
4018            case EVAS_AXIS_LABEL_TWIST:
4019              _efl_input_value_mark(ev, EFL_INPUT_VALUE_TWIST);
4020              ev->twist = axis->value;
4021              break;
4022
4023            case EVAS_AXIS_LABEL_UNKNOWN:
4024            case EVAS_AXIS_LABEL_TOUCH_WIDTH_MAJOR:
4025            case EVAS_AXIS_LABEL_TOUCH_WIDTH_MINOR:
4026            case EVAS_AXIS_LABEL_TOOL_WIDTH_MAJOR:
4027            case EVAS_AXIS_LABEL_TOOL_WIDTH_MINOR:
4028            default:
4029              DBG("Unsupported axis label %d, value %f (discarded)",
4030                  axis->label, axis->value);
4031              break;
4032           }
4033      }
4034    _pointer_position_set(ev, ee, x, y, x, y);
4035
4036    efl_event_callback_legacy_call(e, _event_description_get(ev->action), evt);
4037    processed = ev->evas_done;
4038    efl_del(evt);
4039
4040    return processed;
4041 }
4042
4043 static Eina_Bool
4044 _direct_key_updown_cb(Ecore_Evas *ee, const Ecore_Event_Key *info, Eina_Bool down)
4045 {
4046    Efl_Input_Key_Data *ev;
4047    Efl_Input_Key *evt;
4048    Evas *e = ee->evas;
4049    Eina_Bool processed;
4050
4051    /* Unused information:
4052     * window
4053     * root_window
4054     * event_window
4055     * same_screen
4056     * modifiers (already passed to evas, no need to do anything)
4057     */
4058
4059    evt = efl_input_instance_get(EFL_INPUT_KEY_CLASS, e, (void **) &ev);
4060    if (!evt || !ev) return EINA_FALSE;
4061
4062    ev->timestamp = info->timestamp;
4063    ev->pressed = down;
4064    eina_stringshare_replace(&ev->keyname, info->keyname);
4065    eina_stringshare_replace(&ev->key, info->key);
4066    eina_stringshare_replace(&ev->string, info->string);
4067    eina_stringshare_replace(&ev->compose, info->compose);
4068    ev->keycode = info->keycode;
4069    ev->data = info->data;
4070    ev->event_flags = 0;
4071    ev->device = NULL; /* FIXME */
4072
4073    if (down)
4074      efl_event_callback_legacy_call(e, EFL_EVENT_KEY_DOWN, evt);
4075    else
4076      efl_event_callback_legacy_call(e, EFL_EVENT_KEY_UP, evt);
4077
4078    processed = ev->evas_done;
4079    efl_del(evt);
4080
4081    return processed;
4082 }
4083
4084 EAPI Eina_Bool
4085 _ecore_evas_input_direct_cb(void *window, int type, const void *info)
4086 {
4087    Ecore_Evas *ee = window;
4088
4089    if (type == ECORE_EVENT_MOUSE_MOVE)
4090      return _direct_mouse_move_cb(ee, (const Ecore_Event_Mouse_Move *) info);
4091    else if (type == ECORE_EVENT_MOUSE_BUTTON_DOWN)
4092      return _direct_mouse_down_cb(ee, (const Ecore_Event_Mouse_Button *) info);
4093    else if (type == ECORE_EVENT_MOUSE_BUTTON_UP)
4094      return _direct_mouse_up_cb(ee, (const Ecore_Event_Mouse_Button *) info);
4095    else if (type == ECORE_EVENT_MOUSE_WHEEL)
4096      return _direct_mouse_wheel_cb(ee, (const Ecore_Event_Mouse_Wheel *) info);
4097    else if (type == ECORE_EVENT_MOUSE_IN)
4098      return _direct_mouse_in_cb(ee, (const Ecore_Event_Mouse_IO *) info);
4099    else if (type == ECORE_EVENT_MOUSE_OUT)
4100      return _direct_mouse_out_cb(ee, (const Ecore_Event_Mouse_IO *) info);
4101    else if (type == ECORE_EVENT_KEY_DOWN)
4102      return _direct_key_updown_cb(ee, (const Ecore_Event_Key *) info, EINA_TRUE);
4103    else if (type == ECORE_EVENT_KEY_UP)
4104      return _direct_key_updown_cb(ee, (const Ecore_Event_Key *) info, EINA_FALSE);
4105    else if (type == ECORE_EVENT_MOUSE_BUTTON_CANCEL)
4106      return _direct_mouse_cancel_cb(ee, (const Ecore_Event_Mouse_Button *) info);
4107    else if (type == ECORE_EVENT_AXIS_UPDATE)
4108      return _direct_axis_update_cb(ee, (const Ecore_Event_Axis_Update *) info);
4109    else
4110      {
4111         ERR("unhandled input event type %d", type);
4112         return EINA_FALSE;
4113      }
4114 }