Ecore: Add Ecore_Wayland (Wayland backend like ecore_x).
authordevilhorns <devilhorns@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 26 Dec 2011 23:27:20 +0000 (23:27 +0000)
committerdevilhorns <devilhorns@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 26 Dec 2011 23:27:20 +0000 (23:27 +0000)
Ecore_Evas: Add 'drame_frame' functions.
Add ecore_evas_wayland code (for creating ecore_evas' in wayland).

NB: Merry Christmas EFL !!, Here is you're gift :)

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/ecore@66542 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

16 files changed:
Makefile.am
configure.ac
ecore-wayland.pc.in [new file with mode: 0644]
src/lib/Makefile.am
src/lib/ecore_evas/Ecore_Evas.h
src/lib/ecore_evas/Makefile.am
src/lib/ecore_evas/ecore_evas.c
src/lib/ecore_evas/ecore_evas_fb.c
src/lib/ecore_evas/ecore_evas_private.h
src/lib/ecore_evas/ecore_evas_wayland_egl.c [new file with mode: 0644]
src/lib/ecore_evas/ecore_evas_wayland_shm.c [new file with mode: 0644]
src/lib/ecore_wayland/Ecore_Wayland.h [new file with mode: 0644]
src/lib/ecore_wayland/Makefile.am [new file with mode: 0644]
src/lib/ecore_wayland/ecore_wl.c [new file with mode: 0644]
src/lib/ecore_wayland/ecore_wl_private.h [new file with mode: 0644]
src/lib/ecore_wayland/ecore_wl_window.c [new file with mode: 0644]

index 3de7673..8a6ef9a 100644 (file)
@@ -106,6 +106,7 @@ ecore-cocoa.pc.in \
 ecore-psl1ght.pc.in \
 ecore-input.pc.in \
 ecore-wince.pc.in \
+ecore-wayland.pc.in \
 ecore.spec.in \
 ecore.spec \
 m4/ac_abstract_socket.m4 \
@@ -190,6 +191,10 @@ if BUILD_ECORE_PSL1GHT
 pkgconfig_DATA += ecore-psl1ght.pc
 endif
 
+if BUILD_ECORE_WAYLAND
+pkgconfig_DATA += ecore-wayland.pc
+endif
+
 .PHONY: doc
 
 # Documentation
index 7b92194..1b1ef5a 100644 (file)
@@ -133,6 +133,7 @@ want_ecore_psl1ght="no"
 want_ecore_fb="no"
 want_ecore_directfb="no"
 want_ecore_wince="no"
+want_ecore_wayland="no"
 
 # ecore_x options (both xlib and xcb)
 want_ecore_x_composite="yes"
@@ -173,6 +174,8 @@ want_ecore_evas_directfb="no"
 want_ecore_evas_fb="no"
 want_ecore_evas_software_16_wince="no"
 want_ecore_evas_ews="yes"
+want_ecore_evas_wayland_shm="no"
+want_ecore_evas_wayland_egl="no"
 
 # ecore_imf modules
 want_ecore_imf_xim="no"
@@ -225,6 +228,7 @@ case "$host_os" in
       want_ecore_fb="yes"
       want_ecore_imf="yes"
       want_ecore_x="yes"
+      want_ecore_wayland="yes"
       want_ecore_evas_software_x11="yes"
       want_ecore_evas_opengl_x11="yes"
       want_ecore_evas_software_16_x11="yes"
@@ -235,6 +239,8 @@ case "$host_os" in
       want_ecore_evas_gl_cocoa="no"
       want_ecore_evas_directfb="yes"
       want_ecore_evas_fb="yes"
+      want_ecore_evas_wayland_shm="yes"
+      want_ecore_evas_wayland_egl="yes"
       want_ecore_imf_xim="yes"
       want_ecore_imf_scim="yes"
       ;;
@@ -265,6 +271,7 @@ requirements_ecore_win32=""
 requirements_ecore_wince=""
 requirements_ecore_imf_xim=""
 requirements_ecore_imf_scim=""
+requirements_ecore_wayland=""
 
 AC_CHECK_DECL([MAXHOSTNAMELEN],[FOUND_MAXHOSTNAMELEN=yes])
 
@@ -1838,6 +1845,34 @@ ECORE_EVAS_CHECK_MODULE([psl1ght],
    [${have_ecore_psl1ght}],
    [requirements_ecore_evas="ecore-psl1ght >= 1.1.99 ${requirements_ecore_evas}"])
 
+### WAYLAND
+
+ecore_wayland_deps="no"
+have_wayland="no"
+if test "x${want_ecore_wayland}" = "xyes" ; then
+  PKG_CHECK_MODULES([WAYLAND], [wayland-client xkbcommon], [have_wayland="yes"], [have_wayland="no"])
+fi
+if test "x${have_ecore_input}" = "xyes" -a "x${have_wayland}" = "xyes" ; then
+  ecore_wayland_deps="yes"
+fi
+
+ECORE_CHECK_MODULE([wayland], [${want_ecore_wayland}], [Wayland], [${ecore_wayland_deps}])
+if test "x${have_ecore_wayland}" = "xyes" ; then
+  requirements_ecore_wayland="ecore-input >= 1.1.0 wayland-client xkbcommon ${requirements_ecore_wayland}"
+fi
+
+ECORE_EVAS_CHECK_MODULE_FULL([wayland-shm], [wayland-shm], 
+   [${want_ecore_evas_wayland_shm}],
+   [Wayland Shm],
+   [${have_ecore_wayland}],
+   [requirements_ecore_evas="ecore-wayland >= 1.1.0 ${requirements_ecore_evas}"])
+
+ECORE_EVAS_CHECK_MODULE_FULL([wayland-egl], [wayland-egl], 
+   [${want_ecore_evas_wayland_egl}],
+   [Wayland Egl],
+   [${have_ecore_wayland}],
+   [requirements_ecore_evas="ecore-wayland >= 1.1.0 ${requirements_ecore_evas}"])
+
 ### install and build examples
 
 EFL_CHECK_BUILD_EXAMPLES([enable_build_examples="yes"], [enable_build_examples="no"])
@@ -1865,6 +1900,7 @@ AC_SUBST(requirements_ecore_win32)
 AC_SUBST(requirements_ecore_wince)
 AC_SUBST(requirements_ecore_imf_xim)
 AC_SUBST(requirements_ecore_imf_scim)
+AC_SUBST(requirements_ecore_wayland)
 
 AC_CONFIG_FILES([
 Makefile
@@ -1885,6 +1921,7 @@ ecore-sdl.pc
 ecore-cocoa.pc
 ecore-psl1ght.pc
 ecore-wince.pc
+ecore-wayland.pc
 ecore.pc
 doc/ecore.dox
 doc/Makefile
@@ -1913,6 +1950,7 @@ src/lib/ecore_wince/Makefile
 src/lib/ecore_x/Makefile
 src/lib/ecore_x/xlib/Makefile
 src/lib/ecore_x/xcb/Makefile
+src/lib/ecore_wayland/Makefile
 src/examples/Makefile
 src/tests/Makefile
 src/modules/Makefile
@@ -2033,6 +2071,7 @@ fi
 echo "  Ecore_DirectFB...............: $have_ecore_directfb"
 echo "  Ecore_WinCE..................: $have_ecore_wince"
 echo "  Ecore_PSL1GHT................: $have_ecore_psl1ght"
+echo "  Ecore_Wayland................: $have_ecore_wayland"
 
 echo
 echo " Ecore Evas:"
@@ -2066,6 +2105,8 @@ if test "x${have_ecore_evas}" = "xyes" ; then
   echo "    Software 16bit DirectDraw..: $have_ecore_evas_software_16_ddraw"
   echo "    Software 16bit WinCE.......: $have_ecore_evas_software_16_wince"
   echo "    Sing.Proc. Windowing System: $have_ecore_evas_ews"
+  echo "    Wayland Shm................: $have_ecore_evas_wayland_shm"
+  echo "    Wayland Egl................: $have_ecore_evas_wayland_egl"
 fi
 echo
 echo "  Tests................: ${enable_tests}"
diff --git a/ecore-wayland.pc.in b/ecore-wayland.pc.in
new file mode 100644 (file)
index 0000000..f4f5cf3
--- /dev/null
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: ecore-wayland
+Description: E core library, Wayland module
+@pkgconfig_requires_private@: @requirements_ecore_wayland@
+Version: @VERSION@
+Libs: -L${libdir} -lecore_wayland
+Libs.private: -lwayland-client
+Cflags: -I${includedir}/ecore-@VMAJ@
index b13bc18..d43ad75 100644 (file)
@@ -46,6 +46,10 @@ if BUILD_ECORE_COCOA
 SUBDIRS += ecore_cocoa
 endif
 
+if BUILD_ECORE_WAYLAND
+SUBDIRS += ecore_wayland
+endif
+
 if BUILD_ECORE_IPC
 SUBDIRS += ecore_ipc
 endif
index 46aa867..2e398c2 100644 (file)
@@ -81,6 +81,8 @@ extern "C" {
 #define HAVE_ECORE_EVAS_WINCE 1
 #define HAVE_ECORE_EVAS_EWS 1
 #define HAVE_ECORE_EVAS_PSL1GHT 1
+#define HAVE_ECORE_EVAS_WAYLAND_SHM 1
+#define HAVE_ECORE_EVAS_WAYLAND_EGL 1
 
 typedef enum _Ecore_Evas_Engine_Type
 {
@@ -104,7 +106,9 @@ typedef enum _Ecore_Evas_Engine_Type
    ECORE_EVAS_ENGINE_SOFTWARE_16_WINCE,
    ECORE_EVAS_ENGINE_OPENGL_SDL,
    ECORE_EVAS_ENGINE_EWS,
-   ECORE_EVAS_ENGINE_PSL1GHT
+   ECORE_EVAS_ENGINE_PSL1GHT,
+   ECORE_EVAS_ENGINE_WAYLAND_SHM, 
+   ECORE_EVAS_ENGINE_WAYLAND_EGL
 } Ecore_Evas_Engine_Type;
 
 typedef enum _Ecore_Evas_Avoid_Damage_Type
@@ -144,6 +148,10 @@ typedef struct _Ecore_WinCE_Window Ecore_WinCE_Window;
 typedef struct _Ecore_Cocoa_Window Ecore_Cocoa_Window;
 #endif
 
+#ifndef _ECORE_WAYLAND_H_
+typedef struct _Ecore_Wl_Window Ecore_Wl_Window;
+#endif
+
 #ifndef _ECORE_EVAS_PRIVATE_H
 /* basic data types */
 typedef struct _Ecore_Evas Ecore_Evas;
@@ -689,6 +697,9 @@ EAPI Ecore_Evas     *ecore_evas_fb_new(const char *disp_name, int rotation, int
 EAPI Ecore_Evas     *ecore_evas_directfb_new(const char *disp_name, int windowed, int x, int y, int w, int h);
 EAPI Ecore_DirectFB_Window *ecore_evas_directfb_window_get(const Ecore_Evas *ee);
 
+EAPI Ecore_Evas     *ecore_evas_wayland_shm_new(const char *disp_name, int x, int y, int w, int h, int frame);
+//EAPI Ecore_Evas     *ecore_evas_wayland_egl_new(const char *disp_name, int x, int y, int w, int h, int frame);
+
 /**
  * @brief Create a new @c Ecore_Evas canvas bound to the Evas
  * @b buffer engine
@@ -1450,6 +1461,9 @@ EAPI Eina_Bool   ecore_evas_comp_sync_get(const Ecore_Evas *ee);
  */
 EAPI void        ecore_evas_screen_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h);
 
+EAPI void        ecore_evas_draw_frame_set(Ecore_Evas *ee, Eina_Bool draw_frame);
+EAPI Eina_Bool   ecore_evas_draw_frame_get(const Ecore_Evas *ee);
+
 /**
  * @brief Associate the given object to this ecore evas.
  *
index a3213b6..88f036f 100644 (file)
@@ -1,8 +1,8 @@
 MAINTAINERCLEANFILES = Makefile.in
 
 if BUILD_ECORE_X
-ECORE_X_INC = -I$(top_srcdir)/src/lib/ecore_x @x_cflags@ @ECORE_XCB_CFLAGS@
-ECORE_X_LIB = $(top_builddir)/src/lib/ecore_x/libecore_x.la @x_libs@ @ECORE_XCB_LIBS@
+ECORE_X_INC = -I$(top_srcdir)/src/lib/ecore_x @x_cflags@
+ECORE_X_LIB = $(top_builddir)/src/lib/ecore_x/libecore_x.la @x_libs@
 else
 ECORE_X_INC =
 ECORE_X_LIB =
@@ -66,6 +66,16 @@ ECORE_PSL1GHT_INC =
 ECORE_PSL1GHT_LIB =
 endif
 
+if BUILD_ECORE_WAYLAND
+ECORE_WAYLAND_INC = -I$(top_srcdir)/src/lib/ecore_wayland @WAYLAND_CFLAGS@
+ECORE_WAYLAND_LIB = $(top_builddir)/src/lib/ecore_wayland/libecore_wayland.la
+ECORE_WAYLAND_LIBADD = @WAYLAND_LIBS@ $(ECORE_WAYLAND_LIB)
+else
+ECORE_WAYLAND_INC =
+ECORE_WAYLAND_LIB =
+ECORE_WAYLAND_LIBADD =
+endif
+
 if BUILD_ECORE_IPC
 ECORE_IPC_INC= \
 -I$(top_srcdir)/src/lib/ecore_ipc \
@@ -92,6 +102,7 @@ $(ECORE_SDL_INC) \
 $(ECORE_COCOA_INC) \
 $(ECORE_WINCE_INC) \
 $(ECORE_PSL1GHT_INC) \
+$(ECORE_WAYLAND_INC) \
 $(ECORE_IPC_INC) \
 @EVAS_CFLAGS@ \
 @EINA_CFLAGS@ \
@@ -116,6 +127,7 @@ ecore_evas_cocoa.c \
 ecore_evas_wince.c \
 ecore_evas_ews.c \
 ecore_evas_psl1ght.c \
+ecore_evas_wayland_shm.c \
 ecore_evas_extn.c
 
 libecore_evas_la_LIBADD = \
@@ -129,6 +141,8 @@ $(ECORE_COCOA_LIB) \
 $(ECORE_WINCE_LIB) \
 $(ECORE_IPC_LIB) \
 $(ECORE_PSL1GHT_LIB) \
+$(ECORE_WAYLAND_LIB) \
+$(ECORE_WAYLAND_LIBADD) \
 $(top_builddir)/src/lib/ecore_input/libecore_input.la \
 $(top_builddir)/src/lib/ecore_input_evas/libecore_input_evas.la \
 $(top_builddir)/src/lib/ecore/libecore.la \
index 0735980..28c3e36 100644 (file)
@@ -201,6 +201,18 @@ ecore_evas_engine_type_supported_get(Ecore_Evas_Engine_Type engine)
 #else
         return EINA_FALSE;
 #endif
+     case ECORE_EVAS_ENGINE_WAYLAND_SHM:
+#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
+        return EINA_TRUE;
+#else
+        return EINA_FALSE;
+#endif
+     case ECORE_EVAS_ENGINE_WAYLAND_EGL:
+#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
+        return EINA_TRUE;
+#else
+        return EINA_FALSE;
+#endif
       default:
         return EINA_FALSE;
      };
@@ -293,6 +305,7 @@ ecore_evas_shutdown(void)
 #ifdef BUILD_ECORE_EVAS_SOFTWARE_16_WINCE
    while (_ecore_evas_wince_shutdown());
 #endif
+
    if (_ecore_evas_async_events_fd)
      ecore_main_fd_handler_del(_ecore_evas_async_events_fd);
 
@@ -588,6 +601,40 @@ _ecore_evas_constructor_psl1ght(int x __UNUSED__, int y __UNUSED__, int w, int h
 }
 #endif
 
+#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
+static Ecore_Evas *
+_ecore_evas_constructor_wayland_shm(int x, int y, int w, int h, const char *extra_options)
+{
+   char *disp_name = NULL;
+   unsigned int frame = 0;
+   Ecore_Evas *ee;
+
+   _ecore_evas_parse_extra_options_str(extra_options, "display=", &disp_name);
+   _ecore_evas_parse_extra_options_uint(extra_options, "frame=", &frame);
+   ee = ecore_evas_wayland_shm_new(disp_name, x, y, w, h, frame);
+   free(disp_name);
+
+   return ee;
+}
+#endif
+
+#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
+static Ecore_Evas *
+_ecore_evas_constructor_wayland_egl(int x, int y, int w, int h, const char *extra_options)
+{
+   char *disp_name = NULL;
+   unsigned int frame = 0;
+//   Ecore_Evas *ee;
+
+   _ecore_evas_parse_extra_options_str(extra_options, "display=", &disp_name);
+   _ecore_evas_parse_extra_options_uint(extra_options, "frame=", &frame);
+//   ee = ecore_evas_wayland_egl_new(disp_name, x, y, w, h, frame);
+   free(disp_name);
+
+   return NULL;
+}
+#endif
+
 #ifdef BUILD_ECORE_EVAS_SOFTWARE_GDI
 static Ecore_Evas *
 _ecore_evas_constructor_software_gdi(int x, int y, int w, int h, const char *extra_options)
@@ -725,7 +772,16 @@ static const struct ecore_evas_engine _engines[] = {
   {"psl1ght", _ecore_evas_constructor_psl1ght},
 #endif
 
-  /* Last chance to have a window */
+   /* Wayland */
+#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
+  {"wayland_shm", _ecore_evas_constructor_wayland_shm},
+#endif
+
+#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
+  {"wayland_egl", _ecore_evas_constructor_wayland_egl},
+#endif
+
+   /* Last chance to have a window */
 #ifdef BUILD_ECORE_EVAS_OPENGL_SDL
   {"opengl_sdl", _ecore_evas_constructor_opengl_sdl},
 #endif
@@ -2019,8 +2075,8 @@ ecore_evas_withdrawn_get(const Ecore_Evas *ee)
         ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
                          "ecore_evas_withdrawn_get");
         return EINA_FALSE;
-     } else
-     return ee->prop.withdrawn ? EINA_TRUE : EINA_FALSE;
+     }
+   return ee->prop.withdrawn ? EINA_TRUE : EINA_FALSE;
 }
 
 /**
@@ -2059,8 +2115,8 @@ ecore_evas_sticky_get(const Ecore_Evas *ee)
         ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
                          "ecore_evas_sticky_get");
         return EINA_FALSE;
-     } else
-     return ee->prop.sticky ? EINA_TRUE : EINA_FALSE;
+     }
+   return ee->prop.sticky ? EINA_TRUE : EINA_FALSE;
 }
 
 EAPI void
@@ -2181,6 +2237,28 @@ ecore_evas_screen_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int
    IFE;
 }
 
+EAPI void 
+ecore_evas_draw_frame_set(Ecore_Evas *ee, Eina_Bool draw_frame) 
+{
+   if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+     {
+        ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, "ecore_evas_draw_frame_set");
+        return;
+     }
+   ee->prop.draw_frame = draw_frame;
+}
+
+EAPI Eina_Bool 
+ecore_evas_draw_frame_get(const Ecore_Evas *ee) 
+{
+   if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+     {
+        ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, "ecore_evas_draw_frame_get");
+        return EINA_FALSE;
+     }
+   return ee->prop.draw_frame;
+}
+
 /* fps debug calls - for debugging how much time your app actually spends */
 /* rendering graphics... :) */
 
index e85d9d8..1e7efad 100644 (file)
@@ -155,9 +155,9 @@ _ecore_evas_fb_render(Ecore_Evas *ee)
    if (ee->visible)
      {
         Eina_List *updates;
-
         Eina_List *ll;
         Ecore_Evas *ee2;
+
         if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
 
         EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2)
index b77a171..e3f8681 100644 (file)
 # include <Evas_Engine_Gl_Cocoa.h>
 #endif
 
-/**
-   Log domain macros and variable
- **/
+#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
+# include "Ecore_Wayland.h"
+# include <Evas_Engine_Wayland_Shm.h>
+#endif
+
+#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
+# include "Ecore_Wayland.h"
+# include <Evas_Engine_Wayland_Egl.h>
+#endif
+
+/** Log domain macros and variables **/
 
 extern int _ecore_evas_log_dom;
 
@@ -260,6 +268,20 @@ struct _Ecore_Evas_Engine
    } ews;
 #endif
 
+#if defined(BUILD_ECORE_EVAS_WAYLAND_SHM) || defined(BUILD_ECORE_EVAS_WAYLAND_EGL)
+   struct 
+     {
+        Evas_Object *frame;
+
+# ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
+        struct wl_surface *surface;
+        struct wl_shell_surface *shell_surface;
+        struct wl_buffer *buffer;
+# endif
+
+     } wl;
+#endif
+
    Ecore_Timer *idle_flush_timer;
 };
 
@@ -322,6 +344,7 @@ struct _Ecore_Evas
       char            withdrawn    : 1;
       char            sticky       : 1;
       char            request_pos  : 1;
+      char            draw_frame   : 1;
    } prop;
 
    struct {
diff --git a/src/lib/ecore_evas/ecore_evas_wayland_egl.c b/src/lib/ecore_evas/ecore_evas_wayland_egl.c
new file mode 100644 (file)
index 0000000..f33b933
--- /dev/null
@@ -0,0 +1,342 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+# define LOGFNS 1
+
+# ifdef LOGFNS
+#  include <stdio.h>
+#  define LOGFN(fl, ln, fn) \
+   printf("-ECORE_EVAS-WL: %25s: %5i - %s\n", fl, ln, fn);
+# else
+#  define LOGFN(fl, ln, fn)
+# endif
+# include <stdlib.h>
+# include <string.h>
+# include <unistd.h>
+# include <sys/types.h>
+# include <sys/mman.h>
+
+# include <Eina.h>
+# include <Evas.h>
+# include <Ecore.h>
+
+# include "ecore_evas_private.h"
+# include "Ecore_Evas.h"
+
+#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
+# include <Evas_Engine_Wayland_Egl.h>
+# include <Ecore_Wayland.h>
+#endif
+
+#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
+/* local function prototypes */
+static int _ecore_evas_wl_init(Ecore_Evas *ee);
+static int _ecore_evas_wl_shutdown(void);
+static void _ecore_evas_wl_free(Ecore_Evas *ee);
+static void _ecore_evas_wl_move(Ecore_Evas *ee, int x, int y);
+static void _ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h);
+static void _ecore_evas_wl_show(Ecore_Evas *ee);
+static int _ecore_evas_wl_render(Ecore_Evas *ee);
+
+/* local variables */
+static int _ecore_evas_init_count = 0;
+
+static Ecore_Evas_Engine_Func _ecore_wl_engine_func = 
+{
+   _ecore_evas_wl_free, 
+   NULL, // _ecore_evas_wl_callback_resize_set, 
+   NULL, // _ecore_evas_wl_callback_move_set, 
+   NULL, // callback show set
+   NULL, // callback hide set
+   NULL, // _ecore_evas_wl_callback_delete_request_set, 
+   NULL, // callback destroy set
+   NULL, // _ecore_evas_wl_callback_focus_in_set, 
+   NULL, // _ecore_evas_wl_callback_focus_out_set, 
+   NULL, // callback mouse in set
+   NULL, // callback mouse out set
+   NULL, // callback sticky set
+   NULL, // callback unsticky set
+   NULL, // callback pre render set
+   NULL, // callback post render set
+   _ecore_evas_wl_move, 
+   NULL, // func managed move
+   _ecore_evas_wl_resize, 
+   NULL, // _ecore_evas_wl_move_resize, 
+   NULL, // func rotation set
+   NULL, // func shaped set
+   _ecore_evas_wl_show, 
+   NULL, // _ecore_evas_wl_hide, 
+   NULL, // _ecore_evas_wl_raise, 
+   NULL, // _ecore_evas_wl_lower, 
+   NULL, // _ecore_evas_wl_activate, 
+   NULL, // _ecore_evas_wl_title_set, 
+   NULL, // _ecore_evas_wl_name_class_set, 
+   NULL, // _ecore_evas_wl_size_min_set, 
+   NULL, // _ecore_evas_wl_size_max_set, 
+   NULL, // _ecore_evas_wl_size_base_set, 
+   NULL, // _ecore_evas_wl_size_step_set, 
+   NULL, // _ecore_evas_wl_object_cursor_set, 
+   NULL, // _ecore_evas_wl_layer_set, 
+   NULL, // _ecore_evas_wl_focus_set, 
+   NULL, // func iconified set
+   NULL, // func borderless set
+   NULL, // func override set
+   NULL, // func maximized set
+   NULL, // func fullscreen set
+   NULL, // _ecore_evas_wl_avoid_damage_set, 
+   NULL, // func withdrawn set
+   NULL, // func sticky set
+   NULL, // func ignore events set
+   NULL, // func alpha set
+   NULL, // func transparent set
+   _ecore_evas_wl_render, 
+   NULL // _ecore_evas_wl_screen_geometry_get
+};
+
+#endif
+
+#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
+EAPI Ecore_Evas *
+ecore_evas_wayland_egl_new(const char *disp_name, int x, int y, int w, int h, int frame) 
+{
+   Evas_Engine_Info_Wayland_Egl *einfo;
+   Ecore_Evas *ee;
+   int method = 0;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(method = evas_render_method_lookup("wayland_egl"))) 
+     {
+        ERR("Render method lookup failed for Wayland Egl");
+        return NULL;
+     }
+
+   if (!ecore_wl_init(disp_name)) 
+     {
+        ERR("Failed to initialize Ecore Wayland");
+        return NULL;
+     }
+
+   if (!(ee = calloc(1, sizeof(Ecore_Evas)))) return NULL;
+
+   ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
+
+   _ecore_evas_wl_init(ee);
+
+   ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_wl_engine_func;
+
+   ee->driver = "wayland_egl";
+   if (disp_name) ee->name = strdup(disp_name);
+
+   if (w < 1) w = 1;
+   if (h < 1) h = 1;
+   ee->x = x;
+   ee->y = y;
+   ee->w = w;
+   ee->h = h;
+   ee->req.x = ee->x;
+   ee->req.y = ee->y;
+   ee->req.w = ee->w;
+   ee->req.h = ee->h;
+   ee->prop.max.w = 32767;
+   ee->prop.max.h = 32767;
+   ee->prop.layer = 4;
+   ee->prop.request_pos = 0;
+   ee->prop.sticky = 0;
+   ee->prop.draw_frame = frame;
+   ee->rotation = 0;
+
+   ee->engine.wl.win = 
+     ecore_wl_window_new(ECORE_WL_WINDOW_TYPE_EGL, x, y, w, h);
+   ee->prop.window = ee->engine.wl.win->id;
+
+   ee->evas = evas_new();
+   evas_data_attach_set(ee->evas, ee);
+   evas_output_method_set(ee->evas, method);
+   evas_output_size_set(ee->evas, ee->w, ee->h);
+   evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+
+   if (ee->prop.draw_frame) evas_output_framespace_set(ee->evas, 4, 18, 8, 22);
+
+   if ((einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas))) 
+     {
+        einfo->info.disp = ecore_wl_display_get();
+        einfo->info.comp = ecore_wl_compositor_get();
+        einfo->info.shell = ecore_wl_shell_get();
+        einfo->info.rotation = ee->rotation;
+        einfo->info.debug = EINA_FALSE;
+        if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) 
+          {
+             ERR("Failed to set Evas Engine Info for '%s'.", ee->driver);
+             ecore_evas_free(ee);
+             return NULL;
+          }
+     }
+   else 
+     {
+        ERR("Failed to get Evas Engine Info for '%s'.", ee->driver);
+        ecore_evas_free(ee);
+        return NULL;
+     }
+
+   ecore_evas_input_event_register(ee);
+   _ecore_evas_register(ee);
+
+   ecore_event_window_register(ee->prop.window, ee, ee->evas, 
+                               (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process, 
+                               (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, 
+                               (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, 
+                               (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
+
+   evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
+
+   return ee;
+}
+#else
+EAPI Ecore_Evas *
+ecore_evas_wayland_egl_new(const char *disp_name __UNUSED__, int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__, int frame __UNUSED__) 
+{
+   return NULL;
+}
+#endif
+
+#ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
+/* local functions */
+static int 
+_ecore_evas_wl_init(Ecore_Evas *ee) 
+{
+   _ecore_evas_init_count++;
+
+   /* TODO: Add handlers */
+
+   if (_ecore_evas_init_count > 1) return _ecore_evas_init_count;
+   ecore_event_evas_init();
+
+   return _ecore_evas_init_count;
+}
+
+static int 
+_ecore_evas_wl_shutdown(void) 
+{
+   _ecore_evas_init_count--;
+   if (_ecore_evas_init_count == 0) 
+     {
+        /* TODO: Delete handlers */
+     }
+   if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
+   return _ecore_evas_init_count;
+}
+
+static void 
+_ecore_evas_wl_free(Ecore_Evas *ee) 
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (ee) 
+     {
+        if (ee->engine.wl.win) ecore_wl_window_free(ee->engine.wl.win);
+        ecore_event_window_unregister(ee->prop.window);
+        ecore_evas_input_event_unregister(ee);
+     }
+   _ecore_evas_wl_shutdown();
+   ecore_wl_shutdown();
+}
+
+static void 
+_ecore_evas_wl_move(Ecore_Evas *ee, int x, int y) 
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!ee) return;
+   ee->req.x = x;
+   ee->req.y = y;
+   if ((ee->x == x) && (ee->y == y)) return;
+   ee->x = x;
+   ee->y = y;
+   /* TODO: Actually move this window */
+   if (!ee->should_be_visible) ee->prop.request_pos = 1;
+   if (ee->func.fn_move) ee->func.fn_move(ee);
+}
+
+static void 
+_ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h) 
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!ee) return;
+   ee->req.w = w;
+   ee->req.h = h;
+   if ((ee->w == w) && (ee->h == h)) return;
+
+   ee->w = w;
+   ee->h = h;
+   ecore_wl_window_resize(ee->engine.wl.win, w, h);
+
+   if ((ee->rotation == 90) || (ee->rotation == 270)) 
+     {
+        evas_output_size_set(ee->evas, h, w);
+        evas_output_viewport_set(ee->evas, 0, 0, h, w);
+        evas_damage_rectangle_add(ee->evas, 0, 0, h, w);
+     }
+   else 
+     {
+        evas_output_size_set(ee->evas, w, h);
+        evas_output_viewport_set(ee->evas, 0, 0, w, h);
+        evas_damage_rectangle_add(ee->evas, 0, 0, w, h);
+     }
+
+   if (ee->func.fn_resize) ee->func.fn_resize(ee);
+}
+
+static void 
+_ecore_evas_wl_show(Ecore_Evas *ee) 
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!ee) return;
+   ee->visible = 1;
+   ee->should_be_visible = 1;
+
+   if (ee->func.fn_show) ee->func.fn_show(ee);
+}
+
+static int 
+_ecore_evas_wl_render(Ecore_Evas *ee) 
+{
+   int rend = 0;
+
+   if (!ee) return 0;
+   if (ee->visible) 
+     {
+        Eina_List *updates = NULL, *ll = NULL;
+        Ecore_Evas *ee2;
+
+        EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2) 
+          {
+             if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
+             if (ee2->engine.func->fn_render)
+               rend |= ee2->engine.func->fn_render(ee2);
+             if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
+          }
+
+        if ((updates = evas_render_updates(ee->evas))) 
+          {
+             if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
+
+             evas_render_updates_free(updates);
+             _ecore_evas_idle_timeout_update(ee);
+             rend = 1;
+
+             if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
+          }
+        else
+          evas_norender(ee->evas);
+     }
+   else
+     evas_norender(ee->evas);
+
+   return rend;
+}
+
+#endif
diff --git a/src/lib/ecore_evas/ecore_evas_wayland_shm.c b/src/lib/ecore_evas/ecore_evas_wayland_shm.c
new file mode 100644 (file)
index 0000000..970cbb7
--- /dev/null
@@ -0,0 +1,727 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#define LOGFNS 1
+
+#ifdef LOGFNS
+# include <stdio.h>
+# define LOGFN(fl, ln, fn) \
+   printf("-ECORE_EVAS-WL: %25s: %5i - %s\n", fl, ln, fn);
+#else
+# define LOGFN(fl, ln, fn)
+#endif
+
+# include <stdlib.h>
+# include <string.h>
+# include <unistd.h>
+# include <sys/types.h>
+# include <sys/mman.h>
+
+# include <Eina.h>
+# include <Evas.h>
+# include <Ecore.h>
+
+# include "ecore_evas_private.h"
+# include "Ecore_Evas.h"
+
+#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
+# include <Evas_Engine_Wayland_Shm.h>
+# include <Ecore_Wayland.h>
+#endif
+
+#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
+/* local function prototypes */
+static int _ecore_evas_wl_init(void);
+static int _ecore_evas_wl_shutdown(void);
+static void _ecore_evas_wl_pre_free(Ecore_Evas *ee);
+static void _ecore_evas_wl_free(Ecore_Evas *ee);
+static void _ecore_evas_wl_callback_resize_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee));
+static void _ecore_evas_wl_callback_move_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee));
+static void _ecore_evas_wl_callback_delete_request_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee));
+static void _ecore_evas_wl_callback_focus_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee));
+static void _ecore_evas_wl_callback_focus_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee));
+static void _ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h);
+static void _ecore_evas_wl_show(Ecore_Evas *ee);
+static int _ecore_evas_wl_render(Ecore_Evas *ee);
+static void _ecore_evas_wl_screen_geometry_get(const Ecore_Evas *ee __UNUSED__, int *x, int *y, int *w, int *h);
+static void _ecore_evas_wl_buffer_new(Ecore_Evas *ee, void **dest);
+
+static Eina_Bool _ecore_evas_wl_event_mouse_down(void *data __UNUSED__, int type __UNUSED__, void *event);
+static Eina_Bool _ecore_evas_wl_event_mouse_up(void *data __UNUSED__, int type __UNUSED__, void *event);
+static Eina_Bool _ecore_evas_wl_event_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *event);
+static Eina_Bool _ecore_evas_wl_event_mouse_wheel(void *data __UNUSED__, int type __UNUSED__, void *event);
+static Eina_Bool _ecore_evas_wl_event_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event);
+static Eina_Bool _ecore_evas_wl_event_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event);
+static Eina_Bool _ecore_evas_wl_event_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event);
+static Eina_Bool _ecore_evas_wl_event_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event);
+
+/* local variables */
+static int _ecore_evas_wl_init_count = 0;
+static Ecore_Event_Handler *_ecore_evas_wl_event_handlers[8];
+
+static Ecore_Evas_Engine_Func _ecore_wl_engine_func = 
+{
+   _ecore_evas_wl_free, 
+   _ecore_evas_wl_callback_resize_set, 
+   _ecore_evas_wl_callback_move_set, 
+   NULL, // callback show set
+   NULL, // callback hide set
+   _ecore_evas_wl_callback_delete_request_set, 
+   NULL, // callback destroy set
+   _ecore_evas_wl_callback_focus_in_set, 
+   _ecore_evas_wl_callback_focus_out_set, 
+   NULL, // callback mouse in set
+   NULL, // callback mouse out set
+   NULL, // callback sticky set
+   NULL, // callback unsticky set
+   NULL, // callback pre render set
+   NULL, // callback post render set
+   NULL, // func move
+   NULL, // func managed move
+   _ecore_evas_wl_resize, 
+   NULL, // func move_resize
+   NULL, // func rotation set
+   NULL, // func shaped set
+   _ecore_evas_wl_show, 
+   NULL, // func hide
+   NULL, // func raise
+   NULL, // func lower
+   NULL, // func activate
+   NULL, // func title set
+   NULL, // func name_class set
+   NULL, // func size min set
+   NULL, // func size max set
+   NULL, // func size base set
+   NULL, // func size step set
+   NULL, // func object cursor set
+   NULL, // func layer set
+   NULL, // func focus set
+   NULL, // func iconified set
+   NULL, // func borderless set
+   NULL, // func override set
+   NULL, // func maximized set
+   NULL, // func fullscreen set
+   NULL, // func avoid_damage set
+   NULL, // func withdrawn set
+   NULL, // func sticky set
+   NULL, // func ignore_events set
+   NULL, // func alpha set
+   NULL, // func transparent set
+   _ecore_evas_wl_render, 
+   _ecore_evas_wl_screen_geometry_get
+};
+
+/* external variables */
+#endif
+
+#ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
+EAPI Ecore_Evas *
+ecore_evas_wayland_shm_new(const char *disp_name, int x, int y, int w, int h, int frame)
+{
+   Evas_Engine_Info_Wayland_Shm *einfo;
+   Ecore_Evas *ee;
+   int method = 0;
+   static int _win_id = 1;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(method = evas_render_method_lookup("wayland_shm"))) 
+     {
+        ERR("Render method lookup failed.");
+        return NULL;
+     }
+
+   if (!(ecore_wl_init(disp_name))) 
+     {
+        ERR("Failed to initialize Ecore Wayland.");
+        return NULL;
+     }
+
+   if (!(ee = calloc(1, sizeof(Ecore_Evas)))) 
+     {
+        ERR("Failed to allocate Ecore_Evas.");
+        ecore_wl_shutdown();
+        return NULL;
+     }
+
+   ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
+
+   _ecore_evas_wl_init();
+
+   ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_wl_engine_func;
+
+   ee->driver = "wayland_shm";
+   if (disp_name) ee->name = strdup(disp_name);
+
+   if (w < 1) w = 1;
+   if (h < 1) h = 1;
+
+   ee->req.x = ee->x = x;
+   ee->req.y = ee->y = y;
+   ee->req.w = ee->w = w;
+   ee->req.h = ee->h = h;
+   ee->rotation = 0;
+   ee->prop.max.w = ee->prop.max.h = 32767;
+   ee->prop.layer = 4;
+   ee->prop.request_pos = 0;
+   ee->prop.sticky = 0;
+   ee->prop.draw_frame = frame;
+   ee->prop.window = _win_id++;
+
+   ee->evas = evas_new();
+   evas_data_attach_set(ee->evas, ee);
+   evas_output_method_set(ee->evas, method);
+   evas_output_size_set(ee->evas, ee->w, ee->h);
+   evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+
+   if (ee->prop.draw_frame) 
+     evas_output_framespace_set(ee->evas, 4, 18, 8, 22);
+
+   if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas))) 
+     {
+        einfo->info.rotation = ee->rotation;
+        einfo->info.debug = EINA_FALSE;
+        if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) 
+          {
+             ERR("Failed to set Evas Engine Info for '%s'.", ee->driver);
+             ecore_evas_free(ee);
+             return NULL;
+          }
+     }
+   else 
+     {
+        ERR("Failed to get Evas Engine Info for '%s'.", ee->driver);
+        ecore_evas_free(ee);
+        return NULL;
+     }
+
+   /* NB: we need to be notified before 'free' so we can munmap the evas 
+    * engine destination */
+   ecore_evas_callback_pre_free_set(ee, _ecore_evas_wl_pre_free);
+
+   ecore_evas_input_event_register(ee);
+   _ecore_evas_register(ee);
+
+   ecore_event_window_register(ee->prop.window, ee, ee->evas, 
+                               (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process, 
+                               (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, 
+                               (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, 
+                               (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
+
+   evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
+
+   return ee;
+}
+
+/* local functions */
+static int 
+_ecore_evas_wl_init(void)
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (++_ecore_evas_wl_init_count != 1)
+     return _ecore_evas_wl_init_count;
+
+   _ecore_evas_wl_event_handlers[0] = 
+     ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, 
+                             _ecore_evas_wl_event_mouse_down, NULL);
+   _ecore_evas_wl_event_handlers[1] = 
+     ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, 
+                             _ecore_evas_wl_event_mouse_up, NULL);
+   _ecore_evas_wl_event_handlers[2] = 
+     ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, 
+                             _ecore_evas_wl_event_mouse_move, NULL);
+   _ecore_evas_wl_event_handlers[3] = 
+     ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL, 
+                             _ecore_evas_wl_event_mouse_wheel, NULL);
+   _ecore_evas_wl_event_handlers[4] = 
+     ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_IN, 
+                             _ecore_evas_wl_event_mouse_in, NULL);
+   _ecore_evas_wl_event_handlers[5] = 
+     ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_OUT, 
+                             _ecore_evas_wl_event_mouse_out, NULL);
+   _ecore_evas_wl_event_handlers[6] = 
+     ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN, 
+                             _ecore_evas_wl_event_focus_in, NULL);
+   _ecore_evas_wl_event_handlers[7] = 
+     ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT, 
+                             _ecore_evas_wl_event_focus_out, NULL);
+
+   ecore_event_evas_init();
+
+   return _ecore_evas_wl_init_count;
+}
+
+static int 
+_ecore_evas_wl_shutdown(void)
+{
+   unsigned int i = 0;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (--_ecore_evas_wl_init_count != 0)
+     return _ecore_evas_wl_init_count;
+
+   for (i = 0; i < sizeof(_ecore_evas_wl_event_handlers) / sizeof(Ecore_Event_Handler *); i++) 
+     {
+        if (_ecore_evas_wl_event_handlers[i])
+          ecore_event_handler_del(_ecore_evas_wl_event_handlers[i]);
+     }
+
+   ecore_event_evas_shutdown();
+
+   return _ecore_evas_wl_init_count;
+}
+
+static void 
+_ecore_evas_wl_pre_free(Ecore_Evas *ee)
+{
+   Evas_Engine_Info_Wayland_Shm *einfo;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   /* get engine info */
+   einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas);
+   if ((einfo) && (einfo->info.dest))
+     {
+        int ret = 0;
+
+        /* munmap previous engine destination */
+        ret = munmap(einfo->info.dest, ((ee->w * sizeof(int)) * ee->h));
+     }
+}
+
+static void 
+_ecore_evas_wl_free(Ecore_Evas *ee)
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   /* destroy buffer */
+   if (ee->engine.wl.buffer) wl_buffer_destroy(ee->engine.wl.buffer);
+   ee->engine.wl.buffer = NULL;
+
+   /* destroy shell surface */
+   if (ee->engine.wl.shell_surface)
+     wl_shell_surface_destroy(ee->engine.wl.shell_surface);
+   ee->engine.wl.shell_surface = NULL;
+
+   /* destroy surface */
+   if (ee->engine.wl.surface) wl_surface_destroy(ee->engine.wl.surface);
+   ee->engine.wl.surface = NULL;
+
+   ecore_event_window_unregister(ee->prop.window);
+
+   _ecore_evas_wl_shutdown();
+   ecore_wl_shutdown();
+}
+
+static void 
+_ecore_evas_wl_callback_resize_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!ee) return;
+   ee->func.fn_resize = func;
+}
+
+static void 
+_ecore_evas_wl_callback_move_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!ee) return;
+   ee->func.fn_move = func;
+}
+
+static void 
+_ecore_evas_wl_callback_delete_request_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!ee) return;
+   ee->func.fn_delete_request = func;
+}
+
+static void 
+_ecore_evas_wl_callback_focus_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!ee) return;
+   ee->func.fn_focus_in = func;
+}
+
+static void 
+_ecore_evas_wl_callback_focus_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!ee) return;
+   ee->func.fn_focus_out = func;
+}
+
+static void 
+_ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h)
+{
+   Evas_Engine_Info_Wayland_Shm *einfo;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!ee) return;
+   if (w < 1) w = 1;
+   if (h < 1) h = 1;
+   ee->req.w = w;
+   ee->req.h = h;
+   if ((ee->w == w) && (ee->h == h)) return;
+
+   /* get engine info */
+   einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas);
+   if (einfo->info.dest)
+     {
+        int ret = 0;
+
+        /* munmap previous engine destination */
+        ret = munmap(einfo->info.dest, ((ee->w * sizeof(int)) * ee->h));
+     }
+
+   /* free old buffer */
+   if (ee->engine.wl.buffer) wl_buffer_destroy(ee->engine.wl.buffer);
+   ee->engine.wl.buffer = NULL;
+
+   ee->w = w;
+   ee->h = h;
+
+   /* create buffer @ new size (also mmaps the new destination) */
+   _ecore_evas_wl_buffer_new(ee, &einfo->info.dest);
+
+   /* change evas output & viewport sizes */
+   evas_output_size_set(ee->evas, ee->w, ee->h);
+   evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+
+   /* set new engine destination */
+   evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+
+   /* flush new buffer fd */
+   ecore_wl_flush();
+
+   /* damage buffer */
+   wl_buffer_damage(ee->engine.wl.buffer, 0, 0, ee->w, ee->h);
+
+   if (ee->visible) 
+     {
+        /* if visible, attach to surface */
+        wl_surface_attach(ee->engine.wl.surface, ee->engine.wl.buffer, 0, 0);
+
+        /* damage surface */
+        wl_surface_damage(ee->engine.wl.surface, 0, 0, ee->w, ee->h);
+     }
+
+   if (ee->func.fn_resize) ee->func.fn_resize(ee);
+}
+
+static void 
+_ecore_evas_wl_show(Ecore_Evas *ee)
+{
+   Evas_Engine_Info_Wayland_Shm *einfo;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!ee) return;
+   if (ee->visible) return;
+
+   /* get engine info */
+   einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas);
+
+   /* create new surface */
+   ee->engine.wl.surface = 
+     wl_compositor_create_surface(ecore_wl_compositor_get());
+   wl_surface_set_user_data(ee->engine.wl.surface, (void *)ee->prop.window);
+
+   /* get new shell surface */
+   ee->engine.wl.shell_surface = 
+     wl_shell_get_shell_surface(ecore_wl_shell_get(), ee->engine.wl.surface);
+
+   /* set toplevel */
+   wl_shell_surface_set_toplevel(ee->engine.wl.shell_surface);
+
+   /* create buffer @ new size (also mmaps the new destination) */
+   _ecore_evas_wl_buffer_new(ee, &einfo->info.dest);
+
+   /* set new engine destination */
+   evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
+
+   /* flush new buffer fd */
+   ecore_wl_flush();
+
+   /* attach buffer to surface */
+   wl_surface_attach(ee->engine.wl.surface, ee->engine.wl.buffer, 0, 0);
+
+   /* NB: No need to do a damage here. If we do, we end up w/ screen 
+    * artifacts in the compositor */
+   /* wl_surface_damage(ee->engine.wl.surface, 0, 0, ee->w, ee->h); */
+
+   ee->visible = 1;
+   if (ee->func.fn_show) ee->func.fn_show(ee);
+}
+
+static int 
+_ecore_evas_wl_render(Ecore_Evas *ee)
+{
+   int rend = 0;
+
+   if (!ee) return 0;
+   if (!ee->visible) 
+     evas_norender(ee->evas);
+   else 
+     {
+        Eina_List *ll = NULL, *updates = NULL;
+        Ecore_Evas *ee2 = NULL;
+
+        if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
+
+        EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2) 
+          {
+             if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
+             if (ee2->engine.func->fn_render)
+               rend |= ee2->engine.func->fn_render(ee2);
+             if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
+          }
+
+        if ((updates = evas_render_updates(ee->evas))) 
+          {
+             Eina_List *l = NULL;
+             Eina_Rectangle *r;
+
+             EINA_LIST_FOREACH(updates, l, r) 
+               {
+                  if (ee->engine.wl.buffer)
+                    wl_buffer_damage(ee->engine.wl.buffer, 
+                                     r->x, r->y, r->w, r->h);
+
+                  if (ee->engine.wl.surface)
+                    wl_surface_damage(ee->engine.wl.surface, 
+                                      r->x, r->y, r->w, r->h);
+               }
+
+             evas_render_updates_free(updates);
+             _ecore_evas_idle_timeout_update(ee);
+             rend = 1;
+          }
+
+        if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
+     }
+
+   return rend;
+}
+
+static void 
+_ecore_evas_wl_screen_geometry_get(const Ecore_Evas *ee __UNUSED__, int *x, int *y, int *w, int *h)
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (x) *x = 0;
+   if (y) *y = 0;
+   ecore_wl_screen_size_get(w, h);
+}
+
+static Eina_Bool 
+_ecore_evas_wl_event_mouse_down(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+   Ecore_Evas *ee;
+   Ecore_Event_Mouse_Button *ev;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   ev = event;
+   ee = ecore_event_window_match(ev->window);
+   if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
+   if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
+   /* printf("Mouse Down: %d %d\t%d %d\n",  */
+   /*        ev->x, ev->y, ev->root.x, ev->root.y); */
+   evas_event_feed_mouse_down(ee->evas, ev->buttons, ev->modifiers, 
+                              ev->timestamp, NULL);
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool 
+_ecore_evas_wl_event_mouse_up(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+   Ecore_Evas *ee;
+   Ecore_Event_Mouse_Button *ev;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   ev = event;
+   ee = ecore_event_window_match(ev->window);
+   if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
+   if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
+   evas_event_feed_mouse_up(ee->evas, ev->buttons, ev->modifiers, 
+                            ev->timestamp, NULL);
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool 
+_ecore_evas_wl_event_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+   Ecore_Evas *ee;
+   Ecore_Event_Mouse_Move *ev;
+
+   ev = event;
+   ee = ecore_event_window_match(ev->window);
+   if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
+   if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
+   ee->mouse.x = ev->x;
+   ee->mouse.y = ev->y;
+   evas_event_feed_mouse_move(ee->evas, ev->x, ev->y, ev->timestamp, NULL);
+   _ecore_evas_mouse_move_process(ee, ev->x, ev->y, ev->timestamp);
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool 
+_ecore_evas_wl_event_mouse_wheel(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+   Ecore_Evas *ee;
+   Ecore_Event_Mouse_Wheel *ev;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   ev = event;
+   ee = ecore_event_window_match(ev->window);
+   if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
+   if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
+   evas_event_feed_mouse_wheel(ee->evas, ev->direction, ev->z, 
+                               ev->timestamp, NULL);
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool 
+_ecore_evas_wl_event_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+   Ecore_Evas *ee;
+   Ecore_Wl_Event_Mouse_In *ev;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   ev = event;
+   ee = ecore_event_window_match(ev->window);
+   if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
+   if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
+   if (ee->func.fn_mouse_in) ee->func.fn_mouse_in(ee);
+   ecore_event_evas_modifier_lock_update(ee->evas, ev->modifiers);
+   evas_event_feed_mouse_in(ee->evas, ev->time, NULL);
+   _ecore_evas_mouse_move_process(ee, ev->x, ev->y, ev->time);
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool 
+_ecore_evas_wl_event_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+   Ecore_Evas *ee;
+   Ecore_Wl_Event_Mouse_Out *ev;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   ev = event;
+   ee = ecore_event_window_match(ev->window);
+   if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
+   if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
+   ecore_event_evas_modifier_lock_update(ee->evas, ev->modifiers);
+   _ecore_evas_mouse_move_process(ee, ev->x, ev->y, ev->time);
+   evas_event_feed_mouse_out(ee->evas, ev->time, NULL);
+   if (ee->func.fn_mouse_out) ee->func.fn_mouse_out(ee);
+   if (ee->prop.cursor.object) evas_object_hide(ee->prop.cursor.object);
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool 
+_ecore_evas_wl_event_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+   Ecore_Evas *ee;
+   Ecore_Wl_Event_Focus_In *ev;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   ev = event;
+   ee = ecore_event_window_match(ev->window);
+   if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
+   if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
+   ee->prop.focused = 1;
+   evas_focus_in(ee->evas);
+   if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee);
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool 
+_ecore_evas_wl_event_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event)
+{
+   Ecore_Evas *ee;
+   Ecore_Wl_Event_Focus_Out *ev;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   ev = event;
+   ee = ecore_event_window_match(ev->window);
+   if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
+   if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
+   evas_focus_out(ee->evas);
+   ee->prop.focused = 0;
+   if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee);
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static void 
+_ecore_evas_wl_buffer_new(Ecore_Evas *ee, void **dest)
+{
+   static unsigned int format;
+   char tmp[PATH_MAX];
+   int fd = -1, stride = 0, size = 0;
+   void *ret;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (dest) *dest = NULL;
+
+   if (!format) format = ecore_wl_format_get();
+
+   strcpy(tmp, "/tmp/ecore-wayland_shm-XXXXXX");
+   if ((fd = mkstemp(tmp)) < 0) 
+     {
+        ERR("Could not create temporary file.");
+        return;
+     }
+
+   stride = (ee->w * sizeof(int));
+   size = (stride * ee->h);
+   if (ftruncate(fd, size) < 0) 
+     {
+        ERR("Could not truncate temporary file.");
+        close(fd);
+        return;
+     }
+
+   ret = mmap(NULL, size, (PROT_READ | PROT_WRITE), MAP_SHARED, fd, 0);
+   unlink(tmp);
+
+   if (ret == MAP_FAILED) 
+     {
+        ERR("mmap of temporary file failed.");
+        close(fd);
+        return;
+     }
+
+   if (dest) *dest = ret;
+
+   ee->engine.wl.buffer = 
+     wl_shm_create_buffer(ecore_wl_shm_get(), fd, ee->w, ee->h, stride, format);
+
+   close(fd);
+}
+
+#else
+EAPI Ecore_Evas *
+ecore_evas_wayland_shm_new(const char *disp_name __UNUSED__, int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__, int frame __UNUSED__)
+{
+   return NULL;
+}
+#endif
diff --git a/src/lib/ecore_wayland/Ecore_Wayland.h b/src/lib/ecore_wayland/Ecore_Wayland.h
new file mode 100644 (file)
index 0000000..63d78ed
--- /dev/null
@@ -0,0 +1,134 @@
+#ifndef _ECORE_WAYLAND_H_
+# define _ECORE_WAYLAND_H_
+
+# include <Eina.h>
+# include <wayland-client.h>
+
+# ifdef EAPI
+#  undef EAPI
+# endif
+
+# ifdef __GNUC__
+#  if __GNUC__ >= 4
+#   define EAPI __attribute__ ((visibility("default")))
+#  else
+#   define EAPI
+#  endif
+# else
+#  define EAPI
+# endif
+
+typedef enum _Ecore_Wl_Window_Type Ecore_Wl_Window_Type;
+typedef struct _Ecore_Wl_Window Ecore_Wl_Window;
+typedef struct _Ecore_Wl_Event_Mouse_In Ecore_Wl_Event_Mouse_In;
+typedef struct _Ecore_Wl_Event_Mouse_Out Ecore_Wl_Event_Mouse_Out;
+typedef struct _Ecore_Wl_Event_Focus_In Ecore_Wl_Event_Focus_In;
+typedef struct _Ecore_Wl_Event_Focus_Out Ecore_Wl_Event_Focus_Out;
+
+enum _Ecore_Wl_Window_Type 
+{
+   ECORE_WL_WINDOW_TYPE_SHM, 
+   ECORE_WL_WINDOW_TYPE_EGL
+};
+
+struct _Ecore_Wl_Window 
+{
+   int id;
+   int x, y, w, h;
+   Ecore_Wl_Window_Type type;
+   Eina_Bool synced : 1;
+
+   struct wl_surface *surface;
+   struct wl_shell_surface *shell_surface;
+
+   struct wl_callback *callback;
+};
+
+struct _Ecore_Wl_Event_Mouse_In 
+{
+   int modifiers;
+   int x, y;
+
+   struct 
+     {
+        int x, y;
+     } root;
+
+   unsigned int window;
+
+   unsigned int time;
+};
+
+struct _Ecore_Wl_Event_Mouse_Out 
+{
+   int modifiers;
+   int x, y;
+
+   struct 
+     {
+        int x, y;
+     } root;
+
+   unsigned int window;
+
+   unsigned int time;
+};
+
+struct _Ecore_Wl_Event_Focus_In 
+{
+   unsigned int window;
+   /* TODO: mode & detail */
+   unsigned int time;
+};
+
+struct _Ecore_Wl_Event_Focus_Out 
+{
+   unsigned int window;
+   /* TODO: mode & detail */
+   unsigned int time;
+};
+
+/**
+ * @file
+ * @brief Ecore functions for dealing with the Wayland window system
+ * 
+ * Ecore_Wl provides a wrapper and convenience functions for using the 
+ * Wayland window system. Function groups for this part of the library 
+ * include the following:
+ * @li @ref Ecore_Wl_Init_Group
+ */
+
+EAPI int ecore_wl_init(const char *name);
+EAPI int ecore_wl_shutdown(void);
+
+EAPI struct wl_display *ecore_wl_display_get(void);
+EAPI struct wl_shm *ecore_wl_shm_get(void);
+EAPI struct wl_compositor *ecore_wl_compositor_get(void);
+EAPI struct wl_shell *ecore_wl_shell_get(void);
+EAPI struct wl_input_device *ecore_wl_input_device_get(void);
+EAPI void ecore_wl_screen_size_get(int *w, int *h);
+EAPI unsigned int ecore_wl_format_get(void);
+EAPI void ecore_wl_sync(void);
+EAPI void ecore_wl_flush(void);
+
+EAPI Ecore_Wl_Window *ecore_wl_window_new(Ecore_Wl_Window_Type type, int x, int y, int w, int h);
+EAPI void ecore_wl_window_free(Ecore_Wl_Window *win);
+EAPI void ecore_wl_window_move(Ecore_Wl_Window *win, int x, int y);
+EAPI void ecore_wl_window_resize(Ecore_Wl_Window *win, int w, int h);
+EAPI void ecore_wl_window_show(Ecore_Wl_Window *win);
+EAPI void ecore_wl_window_hide(Ecore_Wl_Window *win);
+EAPI void ecore_wl_window_raise(Ecore_Wl_Window *win);
+EAPI void ecore_wl_window_lower(Ecore_Wl_Window *win);
+EAPI void ecore_wl_window_activate(Ecore_Wl_Window *win);
+EAPI void ecore_wl_window_focus(Ecore_Wl_Window *win);
+EAPI void ecore_wl_window_fullscreen(Ecore_Wl_Window *win);
+EAPI void ecore_wl_window_attach(Ecore_Wl_Window *win, struct wl_buffer *buffer);
+EAPI void ecore_wl_window_damage(Ecore_Wl_Window *win, int x, int y, int w, int h);
+EAPI void ecore_wl_window_sync(Ecore_Wl_Window *win);
+
+EAPI extern int ECORE_WL_EVENT_MOUSE_IN;
+EAPI extern int ECORE_WL_EVENT_MOUSE_OUT;
+EAPI extern int ECORE_WL_EVENT_FOCUS_IN;
+EAPI extern int ECORE_WL_EVENT_FOCUS_OUT;
+
+#endif
diff --git a/src/lib/ecore_wayland/Makefile.am b/src/lib/ecore_wayland/Makefile.am
new file mode 100644 (file)
index 0000000..ea005b2
--- /dev/null
@@ -0,0 +1,31 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I$(top_srcdir)/src/lib/ecore \
+-I$(top_srcdir)/src/lib/ecore_input \
+-I$(top_builddir)/src/lib/ecore \
+-I$(top_builddir)/src/lib/ecore_input \
+@WAYLAND_CFLAGS@ \
+@EVAS_CFLAGS@ \
+@EINA_CFLAGS@
+
+lib_LTLIBRARIES = libecore_wayland.la
+includes_HEADERS = Ecore_Wayland.h
+includesdir = $(includedir)/ecore-@VMAJ@
+
+libecore_wayland_la_SOURCES = \
+ecore_wl.c
+
+## ecore_wl_window.c
+
+libecore_wayland_la_LIBADD = \
+$(top_builddir)/src/lib/ecore/libecore.la \
+$(top_builddir)/src/lib/ecore_input/libecore_input.la \
+@WAYLAND_LIBS@ \
+@EVAS_LIBS@ \
+@EINA_LIBS@
+
+libecore_wayland_la_LDFLAGS = -version-info @version_info@ @release_info@
+libecore_wayland_la_DEPENDENCIES = $(top_builddir)/src/lib/ecore/libecore.la
+
+EXTRA_DIST = ecore_wl_private.h
diff --git a/src/lib/ecore_wayland/ecore_wl.c b/src/lib/ecore_wayland/ecore_wl.c
new file mode 100644 (file)
index 0000000..d473b23
--- /dev/null
@@ -0,0 +1,679 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "Ecore_Input.h"
+#include "ecore_wl_private.h"
+#include "Ecore_Wayland.h"
+
+/* FIXME: This gives BTN_LEFT/RIGHT/MIDDLE for linux systems ... 
+ *        What about other OSs ?? */
+#ifdef __linux__
+# include <linux/input.h>
+#else
+# define BTN_LEFT 0x110
+# define BTN_RIGHT 0x111
+# define BTN_MIDDLE 0x112
+# define BTN_SIDE 0x113
+# define BTN_EXTRA 0x114
+# define BTN_FORWARD 0x115
+# define BTN_BACK 0x116
+#endif
+
+#include <X11/extensions/XKBcommon.h>
+
+/* local function prototypes */
+static Eina_Bool _ecore_wl_shutdown(Eina_Bool close_display);
+static void _ecore_wl_cb_disp_handle_global(struct wl_display *disp, uint32_t id, const char *interface, uint32_t version __UNUSED__, void *data __UNUSED__);
+static int _ecore_wl_cb_disp_event_mask_update(uint32_t mask, void *data __UNUSED__);
+static void _ecore_wl_cb_shm_format_iterate(void *data __UNUSED__, struct wl_shm *shm __UNUSED__, uint32_t format);
+static void _ecore_wl_cb_disp_handle_geometry(void *data __UNUSED__, struct wl_output *output __UNUSED__, int x, int y, int pw __UNUSED__, int ph __UNUSED__, int subpixel __UNUSED__, const char *make __UNUSED__, const char *model __UNUSED__);
+static void _ecore_wl_cb_disp_handle_mode(void *data __UNUSED__, struct wl_output *output __UNUSED__, uint32_t flags, int w, int h, int refresh __UNUSED__);
+static Eina_Bool _ecore_wl_cb_fd_handle(void *data, Ecore_Fd_Handler *hdl __UNUSED__);
+static void _ecore_wl_cb_handle_motion(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t, int32_t x, int32_t y, int32_t sx, int32_t sy);
+static void _ecore_wl_cb_handle_button(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t, uint32_t btn, uint32_t state);
+static void _ecore_wl_cb_handle_key(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t __UNUSED__, uint32_t key, uint32_t state);
+static void _ecore_wl_cb_handle_pointer_focus(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t __UNUSED__, struct wl_surface *surface, int32_t x, int32_t y, int32_t sx, int32_t sy);
+static void _ecore_wl_cb_handle_keyboard_focus(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t __UNUSED__, struct wl_surface *surface, struct wl_array *keys);
+static void _ecore_wl_mouse_out_send(void);
+static void _ecore_wl_mouse_in_send(void);
+static void _ecore_wl_focus_out_send(void);
+static void _ecore_wl_focus_in_send(void);
+
+/* local variables */
+static int _ecore_wl_init_count = 0;
+static struct wl_display *_ecore_wl_disp = NULL;
+static uint32_t _ecore_wl_disp_mask = 0;
+static uint32_t _ecore_wl_disp_format = WL_SHM_FORMAT_PREMULTIPLIED_ARGB32;
+static Eina_Rectangle _ecore_wl_screen;
+static Ecore_Fd_Handler *_ecore_wl_fd_hdl = NULL;
+static int _ecore_wl_input_x = 0;
+static int _ecore_wl_input_y = 0;
+static int _ecore_wl_input_sx = 0;
+static int _ecore_wl_input_sy = 0;
+static int _ecore_wl_input_modifiers = 0;
+static struct xkb_desc *_ecore_wl_xkb;
+
+static struct wl_compositor *_ecore_wl_comp;
+static struct wl_shm *_ecore_wl_shm;
+static struct wl_shell *_ecore_wl_shell;
+static struct wl_output *_ecore_wl_output;
+static struct wl_input_device *_ecore_wl_input;
+static struct wl_surface *_ecore_wl_input_surface;
+static const struct wl_shm_listener _ecore_wl_shm_listener = 
+{
+   _ecore_wl_cb_shm_format_iterate
+};
+static const struct wl_output_listener _ecore_wl_output_listener = 
+{
+   _ecore_wl_cb_disp_handle_geometry, 
+   _ecore_wl_cb_disp_handle_mode
+};
+static const struct wl_input_device_listener _ecore_wl_input_listener = 
+{
+   _ecore_wl_cb_handle_motion, 
+   _ecore_wl_cb_handle_button, 
+   _ecore_wl_cb_handle_key, 
+   _ecore_wl_cb_handle_pointer_focus, 
+   _ecore_wl_cb_handle_keyboard_focus, 
+   NULL, // touch down
+   NULL, // touch up
+   NULL, // touch motion
+   NULL, // touch frame
+   NULL, // touch cancel
+};
+
+/* external variables */
+int _ecore_wl_log_dom = -1;
+EAPI int ECORE_WL_EVENT_MOUSE_IN = 0;
+EAPI int ECORE_WL_EVENT_MOUSE_OUT = 0;
+EAPI int ECORE_WL_EVENT_FOCUS_IN = 0;
+EAPI int ECORE_WL_EVENT_FOCUS_OUT = 0;
+
+EAPI int 
+ecore_wl_init(const char *name) 
+{
+   struct xkb_rule_names xkb_names;
+   int fd = 0;
+
+   if (++_ecore_wl_init_count != 1)
+     return _ecore_wl_init_count;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!eina_init()) return --_ecore_wl_init_count;
+
+   _ecore_wl_log_dom = 
+     eina_log_domain_register("ecore_wl", ECORE_WL_DEFAULT_LOG_COLOR);
+   if (_ecore_wl_log_dom < 0) 
+     {
+        EINA_LOG_ERR("Cannot create a log domain for Ecore Wayland.");
+        eina_shutdown();
+        return --_ecore_wl_init_count;
+     }
+
+   if (!ecore_init()) 
+     {
+        eina_log_domain_unregister(_ecore_wl_log_dom);
+        _ecore_wl_log_dom = -1;
+        eina_shutdown();
+        return --_ecore_wl_init_count;
+     }
+
+   if (!ecore_event_init()) 
+     {
+        eina_log_domain_unregister(_ecore_wl_log_dom);
+        _ecore_wl_log_dom = -1;
+        ecore_shutdown();
+        eina_shutdown();
+        return --_ecore_wl_init_count;
+     }
+
+   if (!ECORE_WL_EVENT_MOUSE_IN) 
+     {
+        ECORE_WL_EVENT_MOUSE_IN = ecore_event_type_new();
+        ECORE_WL_EVENT_MOUSE_OUT = ecore_event_type_new();
+        ECORE_WL_EVENT_FOCUS_IN = ecore_event_type_new();
+        ECORE_WL_EVENT_FOCUS_OUT = ecore_event_type_new();
+     }
+
+   /* init xkb */
+   /* FIXME: Somehow make this portable to other languages/countries */
+   xkb_names.rules = "evdev";
+   xkb_names.model = "evdev";
+   xkb_names.layout = "us";
+   xkb_names.variant = "";
+   xkb_names.options = "";
+   if (!(_ecore_wl_xkb = xkb_compile_keymap_from_rules(&xkb_names))) 
+     {
+        ERR("Could not compile keymap");
+        eina_log_domain_unregister(_ecore_wl_log_dom);
+        _ecore_wl_log_dom = -1;
+        ecore_event_shutdown();
+        ecore_shutdown();
+        eina_shutdown();
+        return --_ecore_wl_init_count;
+     }
+
+   /* connect to the wayland display */
+   if (!(_ecore_wl_disp = wl_display_connect(name))) 
+     {
+        eina_log_domain_unregister(_ecore_wl_log_dom);
+        _ecore_wl_log_dom = -1;
+        ecore_event_shutdown();
+        ecore_shutdown();
+        eina_shutdown();
+        return --_ecore_wl_init_count;
+     }
+
+   /* setup handler for wayland interfaces */
+   wl_display_add_global_listener(_ecore_wl_disp, 
+                                  _ecore_wl_cb_disp_handle_global, NULL);
+
+   /* process connection events */
+   wl_display_iterate(_ecore_wl_disp, WL_DISPLAY_READABLE);
+
+   fd = wl_display_get_fd(_ecore_wl_disp, 
+                          _ecore_wl_cb_disp_event_mask_update, NULL);
+
+   /* NB: DO NOT TOUCH THIS OR YOU WILL PAY THE PRICE OF FAILURE !! */
+   /* Without a ECORE_FD_WRITE, then animators/timers break */
+   _ecore_wl_fd_hdl = 
+     ecore_main_fd_handler_add(fd, ECORE_FD_READ | ECORE_FD_WRITE, 
+                               _ecore_wl_cb_fd_handle, _ecore_wl_disp, 
+                               NULL, NULL);
+   if (!_ecore_wl_fd_hdl) 
+     {
+        wl_display_destroy(_ecore_wl_disp);
+        _ecore_wl_disp = NULL;
+        eina_log_domain_unregister(_ecore_wl_log_dom);
+        _ecore_wl_log_dom = -1;
+        ecore_event_shutdown();
+        ecore_shutdown();
+        eina_shutdown();
+        return --_ecore_wl_init_count;
+     }
+
+   return _ecore_wl_init_count;
+}
+
+EAPI int 
+ecore_wl_shutdown(void) 
+{
+   return _ecore_wl_shutdown(EINA_TRUE);
+}
+
+EAPI struct wl_display *
+ecore_wl_display_get(void) 
+{
+   return _ecore_wl_disp;
+}
+
+EAPI struct wl_shm *
+ecore_wl_shm_get(void) 
+{
+   return _ecore_wl_shm;
+}
+
+EAPI struct wl_compositor *
+ecore_wl_compositor_get(void) 
+{
+   return _ecore_wl_comp;
+}
+
+EAPI struct wl_shell *
+ecore_wl_shell_get(void) 
+{
+   return _ecore_wl_shell;
+}
+
+EAPI struct wl_input_device *
+ecore_wl_input_device_get(void) 
+{
+   return _ecore_wl_input;
+}
+
+EAPI void 
+ecore_wl_screen_size_get(int *w, int *h) 
+{
+   if (w) *w = _ecore_wl_screen.w;
+   if (h) *h = _ecore_wl_screen.h;
+}
+
+EAPI unsigned int 
+ecore_wl_format_get(void) 
+{
+   return _ecore_wl_disp_format;
+}
+
+EAPI void 
+ecore_wl_flush(void) 
+{
+   wl_display_flush(_ecore_wl_disp);
+   /* if (_ecore_wl_disp_mask & WL_DISPLAY_WRITABLE) */
+   /*   wl_display_iterate(_ecore_wl_disp, WL_DISPLAY_WRITABLE); */
+}
+
+EAPI void 
+ecore_wl_sync(void) 
+{
+   wl_display_iterate(_ecore_wl_disp, WL_DISPLAY_READABLE);
+}
+
+/* local functions */
+static Eina_Bool 
+_ecore_wl_shutdown(Eina_Bool close_display) 
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (--_ecore_wl_init_count != 0)
+     return _ecore_wl_init_count;
+
+   if (!_ecore_wl_disp) return _ecore_wl_init_count;
+
+   if (_ecore_wl_xkb) free(_ecore_wl_xkb);
+
+   if (_ecore_wl_fd_hdl) ecore_main_fd_handler_del(_ecore_wl_fd_hdl);
+   _ecore_wl_fd_hdl = NULL;
+
+   if (close_display) 
+     {
+        if (_ecore_wl_shm) wl_shm_destroy(_ecore_wl_shm);
+        if (_ecore_wl_comp) wl_compositor_destroy(_ecore_wl_comp);
+        if (_ecore_wl_disp) wl_display_destroy(_ecore_wl_disp);
+        _ecore_wl_disp = NULL;
+     }
+
+   eina_log_domain_unregister(_ecore_wl_log_dom);
+   _ecore_wl_log_dom = -1;
+
+   ecore_event_shutdown();
+   ecore_shutdown();
+   eina_shutdown();
+
+   return _ecore_wl_init_count;
+}
+
+static void 
+_ecore_wl_cb_disp_handle_global(struct wl_display *disp, uint32_t id, const char *interface, uint32_t version __UNUSED__, void *data __UNUSED__) 
+{
+//   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (disp != _ecore_wl_disp) return;
+   if (!strcmp(interface, "wl_compositor")) 
+     {
+        _ecore_wl_comp = 
+          wl_display_bind(_ecore_wl_disp, id, &wl_compositor_interface);
+     }
+   else if (!strcmp(interface, "wl_shm")) 
+     {
+        _ecore_wl_shm = 
+          wl_display_bind(_ecore_wl_disp, id, &wl_shm_interface);
+        wl_shm_add_listener(_ecore_wl_shm, &_ecore_wl_shm_listener, NULL);
+     }
+   else if (!strcmp(interface, "wl_output")) 
+     {
+        _ecore_wl_output = 
+          wl_display_bind(_ecore_wl_disp, id, &wl_output_interface);
+        wl_output_add_listener(_ecore_wl_output, 
+                               &_ecore_wl_output_listener, NULL);
+     }
+   else if (!strcmp(interface, "wl_shell")) 
+     {
+        _ecore_wl_shell = 
+          wl_display_bind(_ecore_wl_disp, id, &wl_shell_interface);
+     }
+   else if (!strcmp(interface, "wl_input_device")) 
+     {
+        _ecore_wl_input = 
+          wl_display_bind(_ecore_wl_disp, id, &wl_input_device_interface);
+        wl_input_device_add_listener(_ecore_wl_input, 
+                                     &_ecore_wl_input_listener, NULL);
+     }
+}
+
+static int 
+_ecore_wl_cb_disp_event_mask_update(uint32_t mask, void *data __UNUSED__) 
+{
+//   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   _ecore_wl_disp_mask = mask;
+   return 0;
+}
+
+static void 
+_ecore_wl_cb_shm_format_iterate(void *data __UNUSED__, struct wl_shm *shm __UNUSED__, uint32_t format) 
+{
+//   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (_ecore_wl_disp_format < 2) return;
+   switch (format) 
+     {
+      case WL_SHM_FORMAT_ARGB32:
+        /* NB: Ignore argb32. We prefer premul */
+        break;
+      case WL_SHM_FORMAT_PREMULTIPLIED_ARGB32:
+        _ecore_wl_disp_format = format;
+        break;
+      case WL_SHM_FORMAT_XRGB32:
+        _ecore_wl_disp_format = format;
+        break;
+      default:
+        break;
+     }
+}
+
+static void 
+_ecore_wl_cb_disp_handle_geometry(void *data __UNUSED__, struct wl_output *output __UNUSED__, int x, int y, int pw __UNUSED__, int ph __UNUSED__, int subpixel __UNUSED__, const char *make __UNUSED__, const char *model __UNUSED__) 
+{
+   _ecore_wl_screen.x = x;
+   _ecore_wl_screen.y = y;
+}
+
+static void 
+_ecore_wl_cb_disp_handle_mode(void *data __UNUSED__, struct wl_output *output __UNUSED__, uint32_t flags, int w, int h, int refresh __UNUSED__) 
+{
+   if (flags & WL_OUTPUT_MODE_CURRENT) 
+     {
+        _ecore_wl_screen.w = w;
+        _ecore_wl_screen.h = h;
+     }
+}
+
+static Eina_Bool 
+_ecore_wl_cb_fd_handle(void *data, Ecore_Fd_Handler *hdl __UNUSED__) 
+{
+   struct wl_display *disp;
+
+   if (!(disp = data)) return ECORE_CALLBACK_RENEW;
+   if (disp != _ecore_wl_disp) return ECORE_CALLBACK_RENEW;
+
+//   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   /* NB: This handles iterate for writable AND readable.
+    * DO NOT TOUCH THIS OR YOU WILL PAY THE PRICE OF FAILURE !!
+    * Without this, animators/timers die */
+   if (_ecore_wl_disp_mask & (WL_DISPLAY_READABLE | WL_DISPLAY_WRITABLE))
+     wl_display_roundtrip(_ecore_wl_disp);
+
+   return ECORE_CALLBACK_RENEW;
+}
+
+static void 
+_ecore_wl_cb_handle_motion(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t, int32_t x, int32_t y, int32_t sx, int32_t sy) 
+{
+   Ecore_Event_Mouse_Move *ev;
+
+   if (dev != _ecore_wl_input) return;
+   if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Move)))) return;
+
+   _ecore_wl_input_x = x;
+   _ecore_wl_input_y = y;
+   _ecore_wl_input_sx = sx;
+   _ecore_wl_input_sy = sy;
+
+   ev->timestamp = t;
+   ev->x = sx;
+   ev->y = sy;
+   ev->root.x = x;
+   ev->root.y = y;
+
+   if (_ecore_wl_input_surface) 
+     {
+        unsigned int id = 0;
+
+        if ((id = (unsigned int)wl_surface_get_user_data(_ecore_wl_input_surface)))
+          {
+             ev->window = id;
+             ev->event_window = id;
+          }
+     }
+
+   ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, NULL, NULL);
+}
+
+static void 
+_ecore_wl_cb_handle_button(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t, uint32_t btn, uint32_t state) 
+{
+   if (dev != _ecore_wl_input) return;
+
+   if ((btn >= BTN_SIDE) && (btn <= BTN_BACK))
+     {
+        Ecore_Event_Mouse_Wheel *ev;
+
+        if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Wheel)))) return;
+
+        ev->timestamp = t;
+        ev->x = _ecore_wl_input_sx;
+        ev->y = _ecore_wl_input_sy;
+        ev->root.x = _ecore_wl_input_x;
+        ev->root.y = _ecore_wl_input_y;
+        ev->modifiers = _ecore_wl_input_modifiers;
+        ev->direction = 0;
+
+        if (_ecore_wl_input_surface) 
+          {
+             unsigned int id = 0;
+
+             if ((id = (unsigned int)wl_surface_get_user_data(_ecore_wl_input_surface)))
+               {
+                  ev->window = id;
+                  ev->event_window = id;
+               }
+          }
+
+        /* NB: (FIXME) Currently Wayland provides no measure of how much the 
+         * wheel has scrolled (read: delta of movement). So for now, we will 
+         * just assume that the amount scrolled is 1 */
+        if ((btn == BTN_EXTRA) || (btn == BTN_FORWARD)) // down
+          ev->z = 1;
+        else if ((btn == BTN_SIDE) || (btn == BTN_BACK)) // up
+          ev->z = -1;
+
+        ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, ev, NULL, NULL);
+     }
+   else 
+     {
+        Ecore_Event_Mouse_Button *ev;
+
+        if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Button)))) return;
+
+        if (btn == BTN_LEFT)
+          ev->buttons = 1;
+        else if (btn == BTN_MIDDLE)
+          ev->buttons = 2;
+        else if (btn == BTN_RIGHT)
+          ev->buttons = 3;
+
+        ev->timestamp = t;
+        ev->x = _ecore_wl_input_sx;
+        ev->y = _ecore_wl_input_sy;
+        ev->root.x = _ecore_wl_input_x;
+        ev->root.y = _ecore_wl_input_y;
+        ev->modifiers = _ecore_wl_input_modifiers;
+
+        if (_ecore_wl_input_surface) 
+          {
+             unsigned int id = 0;
+
+             if ((id = (unsigned int)wl_surface_get_user_data(_ecore_wl_input_surface))) 
+               {
+                  ev->window = id;
+                  ev->event_window = id;
+               }
+          }
+
+        if (state)
+          ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL);
+        else
+          ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL);
+     }
+}
+
+static void 
+_ecore_wl_cb_handle_key(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t __UNUSED__, uint32_t key, uint32_t state) 
+{
+   unsigned int keycode = 0;
+
+   if (dev != _ecore_wl_input) return;
+
+   keycode = key + _ecore_wl_xkb->min_key_code;
+
+   if (state)
+     _ecore_wl_input_modifiers |= _ecore_wl_xkb->map->modmap[keycode];
+   else
+     _ecore_wl_input_modifiers &= ~_ecore_wl_xkb->map->modmap[keycode];
+}
+
+static void 
+_ecore_wl_cb_handle_pointer_focus(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t __UNUSED__, struct wl_surface *surface, int32_t x, int32_t y, int32_t sx, int32_t sy) 
+{
+   if (dev != _ecore_wl_input) return;
+
+   _ecore_wl_input_x = x;
+   _ecore_wl_input_y = y;
+   _ecore_wl_input_sx = sx;
+   _ecore_wl_input_sy = sy;
+
+   if (surface) 
+     {
+        if (_ecore_wl_input_surface) 
+          {
+             if (_ecore_wl_input_surface != surface) 
+               {
+                  /* NB: Pointer focus in different window. Send mouse & focus 
+                   * out events for previous window */
+                  _ecore_wl_mouse_out_send();
+                  _ecore_wl_focus_out_send();
+
+                  /* NB: Send mouse & focus in events for new window */
+                  _ecore_wl_input_surface = surface;
+                  _ecore_wl_mouse_in_send();
+                  _ecore_wl_focus_in_send();
+               }
+          }
+        else 
+          {
+             _ecore_wl_input_surface = surface;
+             _ecore_wl_mouse_in_send();
+             _ecore_wl_focus_in_send();
+             /* printf("\tPointer Focus In New Window\n"); */
+          }
+     }
+   else 
+     {
+        if (_ecore_wl_input_surface) 
+          {
+             _ecore_wl_mouse_out_send();
+             _ecore_wl_focus_out_send();
+             /* printf("\tPointer Focus Not On a Window\n"); */
+          }
+        else
+          printf("\tUnhandled Pointer Focus Case !!!\n");
+        _ecore_wl_input_surface = NULL;
+     }
+}
+
+static void 
+_ecore_wl_cb_handle_keyboard_focus(void *data __UNUSED__, struct wl_input_device *dev, uint32_t t __UNUSED__, struct wl_surface *surface, struct wl_array *keys) 
+{
+   unsigned int *keyend = 0, *i = 0;
+
+   if (dev != _ecore_wl_input) return;
+
+   if ((surface) && (surface != _ecore_wl_input_surface)) 
+     _ecore_wl_input_surface = surface;
+   else if (!surface) 
+     _ecore_wl_input_surface = NULL;
+
+   keyend = keys->data + keys->size;
+   _ecore_wl_input_modifiers = 0;
+   for (i = keys->data; i < keyend; i++)
+     _ecore_wl_input_modifiers |= _ecore_wl_xkb->map->modmap[*i];
+}
+
+static void 
+_ecore_wl_mouse_out_send(void) 
+{
+   Ecore_Wl_Event_Mouse_Out *ev;
+
+   if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Mouse_Out)))) return;
+
+   ev->x = _ecore_wl_input_sx;
+   ev->y = _ecore_wl_input_sy;
+   ev->root.x = _ecore_wl_input_x;
+   ev->root.y = _ecore_wl_input_y;
+   ev->modifiers = _ecore_wl_input_modifiers;
+   ev->time = ecore_time_get();
+
+   if (_ecore_wl_input_surface) 
+     {
+        unsigned int id = 0;
+
+        if ((id = (unsigned int)wl_surface_get_user_data(_ecore_wl_input_surface))) 
+          ev->window = id;
+     }
+
+   ecore_event_add(ECORE_WL_EVENT_MOUSE_OUT, ev, NULL, NULL);
+}
+
+static void 
+_ecore_wl_mouse_in_send(void) 
+{
+   Ecore_Wl_Event_Mouse_In *ev;
+
+   if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Mouse_In)))) return;
+
+   ev->x = _ecore_wl_input_sx;
+   ev->y = _ecore_wl_input_sy;
+   ev->root.x = _ecore_wl_input_x;
+   ev->root.y = _ecore_wl_input_y;
+   ev->modifiers = _ecore_wl_input_modifiers;
+   ev->time = ecore_time_get();
+
+   if (_ecore_wl_input_surface) 
+     {
+        unsigned int id = 0;
+
+        if ((id = (unsigned int)wl_surface_get_user_data(_ecore_wl_input_surface))) 
+          ev->window = id;
+     }
+
+   ecore_event_add(ECORE_WL_EVENT_MOUSE_IN, ev, NULL, NULL);
+}
+
+static void 
+_ecore_wl_focus_out_send(void) 
+{
+   Ecore_Wl_Event_Focus_Out *ev;
+
+   if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Focus_Out)))) return;
+   ev->time = ecore_time_get();
+   if (_ecore_wl_input_surface) 
+     {
+        unsigned int id = 0;
+
+        if ((id = (unsigned int)wl_surface_get_user_data(_ecore_wl_input_surface))) 
+          ev->window = id;
+     }
+   ecore_event_add(ECORE_WL_EVENT_FOCUS_OUT, ev, NULL, NULL);
+}
+
+static void 
+_ecore_wl_focus_in_send(void) 
+{
+   Ecore_Wl_Event_Focus_In *ev;
+
+   if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Focus_In)))) return;
+   ev->time = ecore_time_get();
+   if (_ecore_wl_input_surface) 
+     {
+        unsigned int id = 0;
+
+        if ((id = (unsigned int)wl_surface_get_user_data(_ecore_wl_input_surface))) 
+          ev->window = id;
+     }
+   ecore_event_add(ECORE_WL_EVENT_FOCUS_IN, ev, NULL, NULL);
+}
diff --git a/src/lib/ecore_wayland/ecore_wl_private.h b/src/lib/ecore_wayland/ecore_wl_private.h
new file mode 100644 (file)
index 0000000..3beeac5
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef _ECORE_WAYLAND_PRIVATE_H
+# define _ECORE_WAYLAND_PRIVATE_H
+
+# include <limits.h>
+
+# define LOGFNS 1
+
+# ifdef LOGFNS
+#  include <stdio.h>
+#  define LOGFN(fl, ln, fn) printf("-ECORE-WL: %25s: %5i - %s\n", fl, ln, fn);
+# else
+#  define LOGFN(fl, ln, fn)
+# endif
+
+extern int _ecore_wl_log_dom;
+
+# ifdef ECORE_WL_DEFAULT_LOG_COLOR
+#  undef ECORE_WL_DEFAULT_LOG_COLOR
+# endif
+# define ECORE_WL_DEFAULT_LOG_COLOR EINA_COLOR_BLUE
+
+# ifdef ERR
+#  undef ERR
+# endif
+# define ERR(...) EINA_LOG_DOM_ERR(_ecore_wl_log_dom, __VA_ARGS__)
+
+# ifdef DBG
+#  undef DBG
+# endif
+# define DBG(...) EINA_LOG_DOM_DBG(_ecore_wl_log_dom, __VA_ARGS__)
+
+# ifdef INF
+#  undef INF
+# endif
+# define INF(...) EINA_LOG_DOM_INFO(_ecore_wl_log_dom, __VA_ARGS__)
+
+# ifdef WRN
+#  undef WRN
+# endif
+# define WRN(...) EINA_LOG_DOM_WARN(_ecore_wl_log_dom, __VA_ARGS__)
+
+# ifdef CRIT
+#  undef CRIT
+# endif
+# define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_wl_log_dom, __VA_ARGS__)
+
+#endif
diff --git a/src/lib/ecore_wayland/ecore_wl_window.c b/src/lib/ecore_wayland/ecore_wl_window.c
new file mode 100644 (file)
index 0000000..faa660a
--- /dev/null
@@ -0,0 +1,196 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "Ecore_Wayland.h"
+#include "ecore_wl_private.h"
+
+/* local function prototypes */
+static void _ecore_wl_window_cb_frame(void *data, struct wl_callback *cb __UNUSED__, uint32_t tm __UNUSED__);
+
+/* local variables */
+static const struct wl_callback_listener _ecore_wl_window_frame_listener = 
+{
+   _ecore_wl_window_cb_frame
+};
+
+EAPI Ecore_Wl_Window *
+ecore_wl_window_new(Ecore_Wl_Window_Type type, int x, int y, int w, int h) 
+{
+   static int _win_id = 1;
+   Ecore_Wl_Window *win;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(win = calloc(1, sizeof(Ecore_Wl_Window)))) return NULL;
+
+   win->id = _win_id++;
+   printf("Ecore_Wl Window Id: %d\n", win->id);
+   win->x = x;
+   win->y = y;
+   win->w = w;
+   win->h = h;
+   win->synced = EINA_TRUE;
+   win->type = type;
+
+   return win;
+}
+
+EAPI void 
+ecore_wl_window_free(Ecore_Wl_Window *win) 
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!win) return;
+//   ecore_wl_window_hide(win);
+   free(win);
+}
+
+EAPI void 
+ecore_wl_window_move(Ecore_Wl_Window *win, int x, int y) 
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!win) return;
+   if ((win->x == x) && (win->y == y)) return;
+   win->x = x;
+   win->y = y;
+}
+
+EAPI void 
+ecore_wl_window_resize(Ecore_Wl_Window *win, int w, int h) 
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!win) return;
+   if ((win->w == w) && (win->h == h)) return;
+   win->w = w;
+   win->h = h;
+}
+
+EAPI void 
+ecore_wl_window_show(Ecore_Wl_Window *win) 
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!win) return;
+
+   win->surface = wl_compositor_create_surface(ecore_wl_compositor_get());
+
+   win->shell_surface = 
+     wl_shell_get_shell_surface(ecore_wl_shell_get(), win->surface);
+   wl_shell_surface_set_toplevel(win->shell_surface);
+}
+
+EAPI void 
+ecore_wl_window_hide(Ecore_Wl_Window *win) 
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!win) return;
+   if (win->callback) wl_callback_destroy(win->callback);
+   if (win->shell_surface) wl_shell_surface_destroy(win->shell_surface);
+   if (win->surface) wl_surface_destroy(win->surface);
+}
+
+EAPI void 
+ecore_wl_window_raise(Ecore_Wl_Window *win) 
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!win) return;
+   if (!win->shell_surface) return;
+   wl_shell_surface_set_toplevel(win->shell_surface);
+}
+
+EAPI void 
+ecore_wl_window_lower(Ecore_Wl_Window *win) 
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!win) return;
+}
+
+EAPI void 
+ecore_wl_window_activate(Ecore_Wl_Window *win) 
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!win) return;
+   if (!win->shell_surface) return;
+   wl_shell_surface_set_toplevel(win->shell_surface);
+}
+
+EAPI void 
+ecore_wl_window_focus(Ecore_Wl_Window *win) 
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!win) return;
+   if (!win->shell_surface) return;
+   wl_shell_surface_set_toplevel(win->shell_surface);
+}
+
+EAPI void 
+ecore_wl_window_fullscreen(Ecore_Wl_Window *win) 
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!win) return;
+   if (!win->shell_surface) return;
+   wl_shell_surface_set_fullscreen(win->shell_surface);
+}
+
+EAPI void 
+ecore_wl_window_attach(Ecore_Wl_Window *win, struct wl_buffer *buffer) 
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!win) return;
+   if ((win->surface) && (buffer))
+     wl_surface_attach(win->surface, buffer, 0, 0);
+}
+
+EAPI void 
+ecore_wl_window_damage(Ecore_Wl_Window *win, int x, int y, int w, int h) 
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!win) return;
+   if (!win->surface) return;
+   if (win->synced) 
+     {
+        if (win->callback) wl_callback_destroy(win->callback);
+        win->callback = wl_surface_frame(win->surface);
+        wl_callback_add_listener(win->callback, 
+                                 &_ecore_wl_window_frame_listener, win);
+        win->synced = EINA_FALSE;
+     }
+   wl_surface_damage(win->surface, x, y, w, h);
+}
+
+EAPI void 
+ecore_wl_window_sync(Ecore_Wl_Window *win) 
+{
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!win) return;
+   ecore_wl_flush();
+   while (!win->synced)
+     ecore_wl_sync();
+}
+
+/* local functions */
+static void 
+_ecore_wl_window_cb_frame(void *data, struct wl_callback *cb __UNUSED__, uint32_t tm __UNUSED__) 
+{
+   Ecore_Wl_Window *win;
+
+   if (!(win = data)) return;
+   win->synced = EINA_TRUE;
+   if (win->callback) wl_callback_destroy(win->callback);
+   win->callback = NULL;
+   wl_surface_damage(win->surface, 0, 0, win->w, win->h);
+}