Welcome EWS - Ecore+Evas Single Process Windowing System.
authorbarbieri <barbieri@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Wed, 5 Oct 2011 22:11:00 +0000 (22:11 +0000)
committerbarbieri <barbieri@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Wed, 5 Oct 2011 22:11:00 +0000 (22:11 +0000)
EWS is a new Ecor_Evas engine that builds on top of other engines. It
will create a backing store Ecore_Evas and ecore_evas_ews_new()
windows are created in it as images, but transparent to the outside
users (similar to buffer's ecore_evas_object_image_new()).

It provides a basic windowing system, with a known background object
that can be changed to your pleasure, and issue Ecore_Events to notify
of new windows and changes like movement, etc. Then you can write a
simple window manager based on it. (See example, Elementary will
contain one as well).

Backing store is determined by your best engine (as in
ecore_evas_new()) or specified with ecore_evas_ews_engine_set() or
environment variable $ECORE_EVAS_EWS (format:
engine-name:x:y:w:h:options). The size can be set with
ecore_evas_ews_setup().

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

16 files changed:
configure.ac
m4/ecore_check_module.m4
src/examples/Makefile.am
src/examples/ecore_evas_ews_example.c [new file with mode: 0644]
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_buffer.c
src/lib/ecore_evas/ecore_evas_directfb.c
src/lib/ecore_evas/ecore_evas_ews.c [new file with mode: 0644]
src/lib/ecore_evas/ecore_evas_fb.c
src/lib/ecore_evas/ecore_evas_private.h
src/lib/ecore_evas/ecore_evas_sdl.c
src/lib/ecore_evas/ecore_evas_win32.c
src/lib/ecore_evas/ecore_evas_wince.c
src/lib/ecore_evas/ecore_evas_x.c

index 8cced13..369749c 100644 (file)
@@ -162,6 +162,7 @@ want_ecore_evas_gl_sdl="no"
 want_ecore_evas_directfb="no"
 want_ecore_evas_fb="no"
 want_ecore_evas_software_16_wince="no"
+want_ecore_evas_ews="yes"
 
 # ecore_imf modules
 want_ecore_imf_xim="no"
@@ -1697,6 +1698,13 @@ ECORE_EVAS_CHECK_MODULE([software-16-wince],
    [${have_ecore_wince}],
    [requirements_ecore_evas="ecore-wince >= 1.0.0 ${requirements_ecore_evas}"])
 
+# ecore_evas_ews
+
+ECORE_EVAS_CHECK_MODULE_FULL([ews], [software-buffer],
+   [${want_ecore_evas_ews}],
+   [Ecore Evas Single Process Windowing System],
+   [yes], [])
+
 ### install and build examples
 
 EFL_CHECK_BUILD_EXAMPLES([enable_build_examples="yes"], [enable_build_examples="no"])
@@ -1913,6 +1921,7 @@ if test "x${have_ecore_evas}" = "xyes" ; then
   echo "    Software 16bit X11.........: $have_ecore_evas_software_16_x11"
   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"
 fi
 echo
 echo "  Tests................: ${enable_tests}"
index 1679b34..658b42e 100644 (file)
@@ -48,19 +48,19 @@ m4_popdef([UP])
 m4_popdef([DOWN])
 ])
 
-dnl use: ECORE_EVAS_CHECK_MODULE(foo-bar, want, description, backend[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
-AC_DEFUN([ECORE_EVAS_CHECK_MODULE],
+dnl use: ECORE_EVAS_CHECK_MODULE_FULL(foo-bar, evas-module, want, description, backend[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+AC_DEFUN([ECORE_EVAS_CHECK_MODULE_FULL],
 [
 m4_pushdef([UP], m4_translit([[$1]], [-a-z], [_A-Z]))dnl
 m4_pushdef([DOWN], m4_translit([[$1]], [-A-Z], [_a-z]))dnl
 
 have_ecore_evas_[]m4_defn([DOWN])="no"
-want_module="$2"
+want_module="$3"
 
 AC_ARG_ENABLE(ecore-evas-$1,
    [AC_HELP_STRING(
        [--enable-ecore-evas-$1],
-       [enable $3 support in the ecore_evas module.])],
+       [enable $4 support in the ecore_evas module.])],
    [
     if test "x${enableval}" = "xyes" ; then
        want_module="yes"
@@ -70,24 +70,28 @@ AC_ARG_ENABLE(ecore-evas-$1,
    ],
    [])
 
-AC_MSG_CHECKING([whether ecore_evas $3 support is to be built])
+AC_MSG_CHECKING([whether ecore_evas $4 support is to be built])
 AC_MSG_RESULT([${want_module}])
 
-if test "x$4" = "xyes" -a \
+if test "x$5" = "xyes" -a \
         "x$have_ecore_evas" = "xyes" -a \
         "x$want_module" = "xyes" ; then
-   PKG_CHECK_EXISTS([evas-$1],
+   PKG_CHECK_EXISTS([evas-$2],
       [
-       AC_DEFINE([BUILD_ECORE_EVAS_]m4_defn([UP]), [1], [Support for $3 Engine in Ecore_Evas])
+       AC_DEFINE([BUILD_ECORE_EVAS_]m4_defn([UP]), [1], [Support for $4 Engine in Ecore_Evas])
        have_ecore_evas_[]m4_defn([DOWN])="yes"
       ])
 fi
 
-AC_MSG_CHECKING([whether ecore_evas $3 support is built])
+AC_MSG_CHECKING([whether ecore_evas $4 support is built])
 AC_MSG_RESULT([$have_ecore_evas_]m4_defn([DOWN]))
 
-AS_IF([test "x$have_ecore_evas_[]m4_defn([DOWN])" = "xyes"], [$5], [$6])
+AS_IF([test "x$have_ecore_evas_[]m4_defn([DOWN])" = "xyes"], [$6], [$7])
 
 m4_popdef([UP])
 m4_popdef([DOWN])
 ])
+
+dnl use: ECORE_EVAS_CHECK_MODULE(foo-bar, want, description, backend[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+AC_DEFUN([ECORE_EVAS_CHECK_MODULE],
+[ECORE_EVAS_CHECK_MODULE_FULL([$1], [$1], [$2], [$3], [$4], [$5], [$6])])
index 48eab32..282adce 100644 (file)
@@ -53,7 +53,8 @@ SRCS = \
        ecore_evas_object_example.c \
        ecore_evas_basics_example.c \
        ecore_evas_buffer_example_01.c \
-       ecore_evas_buffer_example_02.c
+       ecore_evas_buffer_example_02.c \
+       ecore_evas_ews_example.c
 
 EXTRA_DIST = $(SRCS) \
        $(srcdir)/red.png
@@ -89,7 +90,8 @@ pkglib_PROGRAMS += \
        ecore_evas_object_example \
        ecore_evas_basics_example \
        ecore_evas_buffer_example_01 \
-       ecore_evas_buffer_example_02
+       ecore_evas_buffer_example_02 \
+       ecore_evas_ews_example
 
 ecore_con_lookup_example_LDADD = $(ECOREBASELDADD) $(top_builddir)/src/lib/ecore_con/libecore_con.la
 ecore_con_url_headers_example_LDADD = $(ECOREBASELDADD) $(top_builddir)/src/lib/ecore_con/libecore_con.la
diff --git a/src/examples/ecore_evas_ews_example.c b/src/examples/ecore_evas_ews_example.c
new file mode 100644 (file)
index 0000000..9be725a
--- /dev/null
@@ -0,0 +1,253 @@
+/**
+ * Ecore example illustrating the ews of ecore evas usage.
+ *
+ * You'll need at least one Evas engine built for it (excluding the
+ * buffer one). See stdout/stderr for output.
+ *
+ * @verbatim
+ * gcc -o ecore_evas_ews_example ecore_evas_ews_example.c `pkg-config --libs --cflags ecore-evas`
+ * @endverbatim
+ */
+
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <ctype.h>
+
+static Eina_Bool
+_wm_win_add(void *data, int type, void *event_info)
+{
+   Ecore_Evas *ee = event_info;
+   printf("WM: new window=%p\n", ee);
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_wm_win_move(void *data, int type, void *event_info)
+{
+   Ecore_Evas *ee = event_info;
+   int x, y;
+   ecore_evas_geometry_get(ee, &x, &y, NULL, NULL);
+   printf("WM: window=%p moved to %d,%d\n", ee, x, y);
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_wm_win_resize(void *data, int type, void *event_info)
+{
+   Ecore_Evas *ee = event_info;
+   int w, h;
+   ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
+   printf("WM: window=%p resized to %dx%d\n", ee, w, h);
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_wm_win_show(void *data, int type, void *event_info)
+{
+   Ecore_Evas *ee = event_info;
+   printf("WM: show window=%p\n", ee);
+   return EINA_TRUE;
+}
+
+static void
+optional_ews_window_manager_setup(void)
+{
+   ecore_event_handler_add(ECORE_EVAS_EWS_EVENT_ADD, _wm_win_add, NULL);
+   ecore_event_handler_add(ECORE_EVAS_EWS_EVENT_MOVE, _wm_win_move, NULL);
+   ecore_event_handler_add(ECORE_EVAS_EWS_EVENT_RESIZE, _wm_win_resize, NULL);
+   ecore_event_handler_add(ECORE_EVAS_EWS_EVENT_SHOW, _wm_win_show, NULL);
+
+   /* one may use any known unique identifier, like an app function pointer */
+   ecore_evas_ews_manager_set(optional_ews_window_manager_setup);
+}
+
+static void
+optional_ews_setup(void)
+{
+   Evas_Object *bg;
+   Evas *e;
+
+   ecore_evas_ews_setup(0, 0, 800, 600); /* "screen" size */
+   e = ecore_evas_ews_evas_get(); /* forces "screen" to be allocated */
+
+   bg = evas_object_rectangle_add(e);
+   evas_object_color_set(bg, 128, 32, 32, 255);
+   ecore_evas_ews_background_set(bg);
+}
+
+static Eina_Bool
+_stdin_cb(void *data, Ecore_Fd_Handler *handler)
+{
+   const Eina_List *l;
+   Ecore_Evas *ee;
+   char c = getchar();
+
+   if (c == EOF)
+     {
+        ecore_main_loop_quit();
+        return EINA_FALSE;
+     }
+
+   switch (c) {
+    case 'h':
+       printf("hide all windows\n");
+       EINA_LIST_FOREACH(ecore_evas_ews_children_get(), l, ee)
+         ecore_evas_hide(ee);
+       break;
+    case 's':
+       printf("show all windows\n");
+       EINA_LIST_FOREACH(ecore_evas_ews_children_get(), l, ee)
+         ecore_evas_show(ee);
+       break;
+    case 'l':
+       printf("move all windows left\n");
+       EINA_LIST_FOREACH(ecore_evas_ews_children_get(), l, ee)
+         {
+            int x, y;
+            ecore_evas_geometry_get(ee, &x, &y, NULL, NULL);
+            ecore_evas_move(ee, x - 10, y);
+         }
+       break;
+    case 'r':
+       printf("move all windows right\n");
+       EINA_LIST_FOREACH(ecore_evas_ews_children_get(), l, ee)
+         {
+            int x, y;
+            ecore_evas_geometry_get(ee, &x, &y, NULL, NULL);
+            ecore_evas_move(ee, x + 10, y);
+         }
+       break;
+    case 't':
+       printf("move all windows top\n");
+       EINA_LIST_FOREACH(ecore_evas_ews_children_get(), l, ee)
+         {
+            int x, y;
+            ecore_evas_geometry_get(ee, &x, &y, NULL, NULL);
+            ecore_evas_move(ee, x, y - 10);
+         }
+       break;
+    case 'b':
+       printf("move all windows bottom\n");
+       EINA_LIST_FOREACH(ecore_evas_ews_children_get(), l, ee)
+         {
+            int x, y;
+            ecore_evas_geometry_get(ee, &x, &y, NULL, NULL);
+            ecore_evas_move(ee, x, y + 10);
+         }
+       break;
+    case 'S':
+       printf("make all windows smaller\n");
+       EINA_LIST_FOREACH(ecore_evas_ews_children_get(), l, ee)
+         {
+            int w, h;
+            ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
+            ecore_evas_resize(ee, w - 10, h - 10);
+         }
+       break;
+    case 'B':
+       printf("make all windows bigger\n");
+       EINA_LIST_FOREACH(ecore_evas_ews_children_get(), l, ee)
+         {
+            int w, h;
+            ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
+            ecore_evas_resize(ee, w + 10, h + 10);
+         }
+       break;
+    case 'm':
+       printf("make all windows unmaximized\n");
+       EINA_LIST_FOREACH(ecore_evas_ews_children_get(), l, ee)
+            ecore_evas_maximized_set(ee, EINA_FALSE);
+       break;
+    case 'M':
+       printf("make all windows maximized\n");
+       EINA_LIST_FOREACH(ecore_evas_ews_children_get(), l, ee)
+            ecore_evas_maximized_set(ee, EINA_TRUE);
+       break;
+    case 'i':
+       printf("make all windows uniconified\n");
+       EINA_LIST_FOREACH(ecore_evas_ews_children_get(), l, ee)
+            ecore_evas_iconified_set(ee, EINA_FALSE);
+       break;
+    case 'I':
+       printf("make all windows iconified\n");
+       EINA_LIST_FOREACH(ecore_evas_ews_children_get(), l, ee)
+            ecore_evas_iconified_set(ee, EINA_TRUE);
+       break;
+    case 'f':
+       printf("make all windows unfullscreen\n");
+       EINA_LIST_FOREACH(ecore_evas_ews_children_get(), l, ee)
+            ecore_evas_fullscreen_set(ee, EINA_FALSE);
+       break;
+    case 'F':
+       printf("make all windows fullscreen\n");
+       EINA_LIST_FOREACH(ecore_evas_ews_children_get(), l, ee)
+            ecore_evas_fullscreen_set(ee, EINA_TRUE);
+       break;
+    case 'q':
+       printf("quit\n");
+       ecore_main_loop_quit();
+       break;
+    default:
+       if (!isspace(c))
+         printf("Unknown command: %c\n", c);
+   }
+   return ECORE_CALLBACK_RENEW;
+}
+
+static void
+_on_delete(Ecore_Evas *ee)
+{
+   free(ecore_evas_data_get(ee, "key"));
+   ecore_main_loop_quit();
+}
+
+int
+main(void)
+{
+   Ecore_Evas *ee;
+   Evas *canvas;
+   Evas_Object *bg;
+
+   if (ecore_evas_init() <= 0)
+      return 1;
+
+   optional_ews_setup();
+   optional_ews_window_manager_setup();
+
+   /* everything should look similar to ecore_evas_basic_example */
+   ee = ecore_evas_ews_new(0, 0, 200, 200);
+   ecore_evas_title_set(ee, "Ecore Evas EWS Example");
+   ecore_evas_show(ee);
+
+   ecore_evas_data_set(ee, "key", strdup("hello"));
+   ecore_evas_callback_delete_request_set(ee, _on_delete);
+
+   printf("Using %s engine!\n", ecore_evas_engine_name_get(ee));
+
+   canvas = ecore_evas_get(ee);
+   if(ecore_evas_ecore_evas_get(canvas) == ee)
+      printf("Everything is sane!\n");
+
+   bg = evas_object_rectangle_add(canvas);
+   evas_object_color_set(bg, 0, 0, 255, 255);
+   evas_object_resize(bg, 200, 200);
+   evas_object_show(bg);
+   ecore_evas_object_associate(ee, bg, ECORE_EVAS_OBJECT_ASSOCIATE_BASE);
+
+   /* moving the window should move it in the screen */
+   ecore_evas_move(ee, 50, 50);
+
+   ecore_main_fd_handler_add(STDIN_FILENO,
+              ECORE_FD_READ | ECORE_FD_ERROR,
+              _stdin_cb,
+              NULL, NULL, NULL);
+
+   ecore_main_loop_begin();
+
+   ecore_evas_free(ee);
+   ecore_evas_shutdown();
+
+   return 0;
+}
index 6a6da20..b26b8d6 100644 (file)
@@ -79,6 +79,7 @@ extern "C" {
 #define HAVE_ECORE_EVAS_COCOA 1
 #define HAVE_ECORE_EVAS_SDL 1
 #define HAVE_ECORE_EVAS_WINCE 1
+#define HAVE_ECORE_EVAS_EWS 1
 
 typedef enum _Ecore_Evas_Engine_Type
 {
@@ -100,7 +101,8 @@ typedef enum _Ecore_Evas_Engine_Type
    ECORE_EVAS_ENGINE_SOFTWARE_16_X11,
    ECORE_EVAS_ENGINE_SOFTWARE_16_DDRAW,
    ECORE_EVAS_ENGINE_SOFTWARE_16_WINCE,
-   ECORE_EVAS_ENGINE_OPENGL_SDL
+   ECORE_EVAS_ENGINE_OPENGL_SDL,
+   ECORE_EVAS_ENGINE_EWS
 } Ecore_Evas_Engine_Type;
 
 typedef enum _Ecore_Evas_Avoid_Damage_Type
@@ -735,6 +737,56 @@ EAPI Ecore_Evas     *ecore_evas_buffer_allocfunc_new(int w, int h, void *(*alloc
 EAPI const void     *ecore_evas_buffer_pixels_get(Ecore_Evas *ee);
 
 /**
+ * @brief Create a new @c Ecore_Evas canvas bound to the Evas
+ * @b ews (Ecore + Evas Single Process Windowing System) engine
+ *
+ * EWS is a simple single process windowing system. The backing store
+ * is also an @c Ecore_Evas that can be setup with
+ * ecore_evas_ews_setup() and retrieved with
+ * ecore_evas_ews_ecore_evas_get(). It will allow window management
+ * using events prefixed with @c ECORE_EVAS_EVENT_EWS_.
+ *
+ * The EWS windows (returned by this function or
+ * ecore_evas_new("ews"...)) will all be software buffer windows
+ * automatic rendered to the backing store.
+ *
+ * @param x horizontal position of window, in pixels
+ * @param y vertical position of window, in pixels
+ * @param w The width of the canvas, in pixels
+ * @param h The height of the canvas, in pixels
+ * @return A new @c Ecore_Evas instance or @c NULL, on failure
+ *
+ * @see ecore_evas_ews_setup()
+ * @see ecore_evas_ews_ecore_evas_get()
+ *
+ * @since 1.1
+ */
+EAPI Ecore_Evas     *ecore_evas_ews_new(int x, int y, int w, int h);
+
+
+/**
+ * Returns the backing store image object that represents the given
+ * window in EWS.
+ *
+ * @note This should not be modified anyhow, but may be helpful to
+ *       determine stacking and geometry of it for window managers
+ *       that decorate windows.
+ *
+ * @see ecore_evas_ews_manager_set()
+ * @see ecore_evas_ews_evas_get()
+ * @since 1.1
+ */
+EAPI Evas_Object *ecore_evas_ews_backing_store_get(const Ecore_Evas *ee);
+
+/**
+ * Calls the window to be deleted (freed), but can let user decide to
+ * forbid it by using ecore_evas_callback_delete_request_set()
+ *
+ * @since 1.1
+ */
+EAPI void ecore_evas_ews_delete_request(Ecore_Evas *ee);
+
+/**
  * @brief Create an Evas image object with image data <b>bound to an
  * own, internal @c Ecore_Evas canvas wrapper<b>
  *
@@ -1423,6 +1475,122 @@ EAPI void           ecore_evas_x11_shape_input_reset(Ecore_Evas *ee);
 EAPI void           ecore_evas_x11_shape_input_apply(Ecore_Evas *ee);
 
 /**
+ * @defgroup Ecore_Evas_Ews Ecore_Evas Single Process Windowing System.
+ *
+ * These are global scope functions to manage the EWS to be used by
+ * ecore_evas_ews_new().
+ *
+ * @since 1.1
+ * @{
+ */
+
+/**
+ * Sets the engine to be used by the backing store engine.
+ *
+ * @return EINA_TRUE on success, EINA_FALSE if ews is already in use.
+ * @since 1.1
+ */
+EAPI Eina_Bool ecore_evas_ews_engine_set(const char *engine, const char *options);
+
+/**
+ * Reconfigure the backing store used.
+ * @since 1.1
+ */
+EAPI Eina_Bool ecore_evas_ews_setup(int x, int y, int w, int h);
+
+/**
+ * Return the internal backing store in use.
+ *
+ * @note this will foced it to be created, making future calls to
+ * ecore_evas_ews_engine_set() void.
+ *
+ * @see ecore_evas_ews_evas_get()
+ * @since 1.1
+ */
+EAPI Ecore_Evas *ecore_evas_ews_ecore_evas_get(void);
+
+/**
+ * Return the internal backing store in use.
+ *
+ * @note this will foced it to be created, making future calls to
+ * ecore_evas_ews_engine_set() void.
+ *
+ * @see ecore_evas_ews_ecore_evas_get()
+ * @since 1.1
+ */
+EAPI Evas *ecore_evas_ews_evas_get(void);
+
+/**
+ * Get the current background.
+ */
+EAPI Evas_Object *ecore_evas_ews_background_get(void);
+
+/**
+ * Set the current background, must be created at evas ecore_evas_ews_evas_get()
+ *
+ * It will be kept at lowest layer (EVAS_LAYER_MIN) and below
+ * everything else. You can set any object, default is a black
+ * rectangle.
+ *
+ * @note previous object will be deleted!
+ */
+EAPI void ecore_evas_ews_background_set(Evas_Object *o);
+
+/**
+ * Return all Ecore_Evas* created by EWS.
+ *
+ * @note do not change the returned list or its contents.
+ * @since 1.1
+ */
+EAPI const Eina_List *ecore_evas_ews_children_get(void);
+
+/**
+ * Set the identifier of the manager taking care of internal windows.
+ *
+ * The ECORE_EVAS_EWS_EVENT_MANAGER_CHANGE event is issued. Consider
+ * handling it to know if you should stop handling events yourself
+ * (ie: another manager took over)
+ *
+ * @param manager any unique identifier address.
+ *
+ * @see ecore_evas_ews_manager_get()
+ * @since 1.1
+ */
+EAPI void        ecore_evas_ews_manager_set(const void *manager);
+
+/**
+ * Get the identifier of the manager taking care of internal windows.
+ *
+ * @return the value set by ecore_evas_ews_manager_set()
+ * @since 1.1
+ */
+EAPI const void *ecore_evas_ews_manager_get(void);
+
+EAPI extern int ECORE_EVAS_EWS_EVENT_MANAGER_CHANGE; /**< manager was changed */
+EAPI extern int ECORE_EVAS_EWS_EVENT_ADD; /**< window was created */
+EAPI extern int ECORE_EVAS_EWS_EVENT_DEL; /**< window was deleted, pointer is already invalid but may be used as reference for further cleanup work. */
+EAPI extern int ECORE_EVAS_EWS_EVENT_RESIZE; /**< window was resized */
+EAPI extern int ECORE_EVAS_EWS_EVENT_MOVE; /**< window was moved */
+EAPI extern int ECORE_EVAS_EWS_EVENT_SHOW; /**< window become visible */
+EAPI extern int ECORE_EVAS_EWS_EVENT_HIDE; /**< window become hidden */
+EAPI extern int ECORE_EVAS_EWS_EVENT_FOCUS; /**< window was focused */
+EAPI extern int ECORE_EVAS_EWS_EVENT_UNFOCUS; /**< window lost focus */
+EAPI extern int ECORE_EVAS_EWS_EVENT_RAISE; /**< window was raised */
+EAPI extern int ECORE_EVAS_EWS_EVENT_LOWER; /**< window was lowered */
+EAPI extern int ECORE_EVAS_EWS_EVENT_ACTIVATE; /**< window was activated */
+
+EAPI extern int ECORE_EVAS_EWS_EVENT_ICONIFIED_CHANGE; /**< window minimized/iconified changed */
+EAPI extern int ECORE_EVAS_EWS_EVENT_MAXIMIZED_CHANGE; /**< window maximized changed */
+EAPI extern int ECORE_EVAS_EWS_EVENT_LAYER_CHANGE; /**< window layer changed */
+EAPI extern int ECORE_EVAS_EWS_EVENT_FULLSCREEN_CHANGE; /**< window fullscreen changed */
+EAPI extern int ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE; /**< some other window property changed (title, name, class, alpha, transparent, shaped...) */
+
+/**
+ * @}
+ */
+
+
+/**
  * @}
  */
 
index d646a46..f0aaea9 100644 (file)
@@ -85,7 +85,8 @@ ecore_evas_buffer.c \
 ecore_evas_directfb.c \
 ecore_evas_win32.c \
 ecore_evas_sdl.c \
-ecore_evas_wince.c
+ecore_evas_wince.c \
+ecore_evas_ews.c
 
 libecore_evas_la_LIBADD = \
 $(ECORE_X_LIB) \
index 0d6bc54..a7afc0d 100644 (file)
@@ -181,6 +181,14 @@ ecore_evas_engine_type_supported_get(Ecore_Evas_Engine_Type engine)
 #else
         return EINA_FALSE;
 #endif
+
+      case ECORE_EVAS_ENGINE_EWS:
+#ifdef BUILD_ECORE_EVAS_EWS
+        return EINA_TRUE;
+#else
+        return EINA_FALSE;
+#endif
+
       default:
         return EINA_FALSE;
      };
@@ -220,6 +228,10 @@ ecore_evas_init(void)
    if (getenv("ECORE_EVAS_FPS_DEBUG")) _ecore_evas_fps_debug = 1;
    if (_ecore_evas_fps_debug) _ecore_evas_fps_debug_init();
 
+#ifdef BUILD_ECORE_EVAS_EWS
+   _ecore_evas_ews_events_init();
+#endif
+
    return _ecore_evas_init_count;
 
  shutdown_ecore:
@@ -251,6 +263,9 @@ ecore_evas_shutdown(void)
 #ifdef BUILD_ECORE_EVAS_FB
    while (_ecore_evas_fb_shutdown());
 #endif
+#ifdef BUILD_ECORE_EVAS_EWS
+   while (_ecore_evas_ews_shutdown());
+#endif
 #ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
    while (_ecore_evas_buffer_shutdown());
 #endif
@@ -614,6 +629,14 @@ _ecore_evas_constructor_buffer(int x __UNUSED__, int y __UNUSED__, int w, int h,
 }
 #endif
 
+#ifdef BUILD_ECORE_EVAS_EWS
+static Ecore_Evas *
+_ecore_evas_constructor_ews(int x, int y, int w, int h, const char *extra_options __UNUSED__)
+{
+   return ecore_evas_ews_new(x, y, w, h);
+}
+#endif
+
 /* note: keep sorted by priority, highest first */
 static const struct ecore_evas_engine _engines[] = {
   /* unix */
@@ -678,6 +701,10 @@ static const struct ecore_evas_engine _engines[] = {
 #ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
   {"buffer", _ecore_evas_constructor_buffer},
 #endif
+
+#ifdef BUILD_ECORE_EVAS_EWS
+  {"ews", _ecore_evas_constructor_ews},
+#endif
   {NULL, NULL}
 };
 
@@ -2213,8 +2240,29 @@ _ecore_evas_register(Ecore_Evas *ee)
 }
 
 void
+_ecore_evas_ref(Ecore_Evas *ee)
+{
+   ee->refcount++;
+}
+
+void
+_ecore_evas_unref(Ecore_Evas *ee)
+{
+   ee->refcount--;
+   if (ee->refcount == 0)
+     {
+        if (ee->deleted) _ecore_evas_free(ee);
+     }
+   else if (ee->refcount < -1)
+     ERR("Ecore_Evas %p->refcount=%d < 0", ee, ee->refcount);
+}
+
+void
 _ecore_evas_free(Ecore_Evas *ee)
 {
+   ee->deleted = EINA_TRUE;
+   if (ee->refcount > 0) return;
+
    if (ee->func.fn_pre_free) ee->func.fn_pre_free(ee);
    while (ee->sub_ecore_evas)
      {
index d086ea4..43c7652 100644 (file)
@@ -2,6 +2,8 @@
 # include <config.h>
 #endif
 
+// NOTE: if you fix this, consider fixing ecore_evas_ews.c as it is similar!
+
 #include <Ecore.h>
 #include "ecore_private.h"
 #include <Ecore_Input.h>
@@ -137,6 +139,7 @@ _ecore_evas_buffer_render(Ecore_Evas *ee)
    return updates ? 1 : rend;
 }
 
+// NOTE: if you fix this, consider fixing ecore_evas_ews.c as it is similar!
 static void
 _ecore_evas_buffer_coord_translate(Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y)
 {
@@ -525,6 +528,7 @@ ecore_evas_buffer_new(int w, int h)
 EAPI Ecore_Evas *
 ecore_evas_buffer_allocfunc_new(int w, int h, void *(*alloc_func) (void *data, int size), void (*free_func) (void *data, void *pix), const void *data)
 {
+// NOTE: if you fix this, consider fixing ecore_evas_ews.c as it is similar!
 #ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
    Evas_Engine_Info_Buffer *einfo;
    Ecore_Evas *ee;
@@ -651,6 +655,7 @@ ecore_evas_object_ecore_evas_get(Evas_Object *obj)
 EAPI Evas_Object *
 ecore_evas_object_image_new(Ecore_Evas *ee_target)
 {
+// NOTE: if you fix this, consider fixing ecore_evas_ews.c as it is similar!
 #ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
    Evas_Object *o;
    Evas_Engine_Info_Buffer *einfo;
index 94ff51a..a71fb44 100644 (file)
@@ -26,14 +26,13 @@ _ecore_evas_directfb_render(Ecore_Evas *ee)
    Ecore_Evas *ee2;
    int rend = 0;
 
-#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
    EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2)
      {
         if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
         rend |= _ecore_evas_buffer_render(ee2);
         if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
      }
-#endif
+
    if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
    updates = evas_render_updates(ee->evas);
    if (updates)
diff --git a/src/lib/ecore_evas/ecore_evas_ews.c b/src/lib/ecore_evas/ecore_evas_ews.c
new file mode 100644 (file)
index 0000000..f8e4948
--- /dev/null
@@ -0,0 +1,1352 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <Ecore.h>
+#include "ecore_private.h"
+#include <Ecore_Input.h>
+
+#include "ecore_evas_private.h"
+#include "Ecore_Evas.h"
+
+EAPI int ECORE_EVAS_EWS_EVENT_MANAGER_CHANGE = 0;
+EAPI int ECORE_EVAS_EWS_EVENT_ADD = 0;
+EAPI int ECORE_EVAS_EWS_EVENT_DEL = 0;
+EAPI int ECORE_EVAS_EWS_EVENT_RESIZE = 0;
+EAPI int ECORE_EVAS_EWS_EVENT_MOVE = 0;
+EAPI int ECORE_EVAS_EWS_EVENT_SHOW = 0;
+EAPI int ECORE_EVAS_EWS_EVENT_HIDE = 0;
+EAPI int ECORE_EVAS_EWS_EVENT_FOCUS = 0;
+EAPI int ECORE_EVAS_EWS_EVENT_UNFOCUS = 0;
+EAPI int ECORE_EVAS_EWS_EVENT_RAISE = 0;
+EAPI int ECORE_EVAS_EWS_EVENT_LOWER = 0;
+EAPI int ECORE_EVAS_EWS_EVENT_ACTIVATE = 0;
+
+EAPI int ECORE_EVAS_EWS_EVENT_ICONIFIED_CHANGE = 0;
+EAPI int ECORE_EVAS_EWS_EVENT_MAXIMIZED_CHANGE = 0;
+EAPI int ECORE_EVAS_EWS_EVENT_LAYER_CHANGE = 0;
+EAPI int ECORE_EVAS_EWS_EVENT_FULLSCREEN_CHANGE = 0;
+EAPI int ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE = 0;
+
+#ifdef BUILD_ECORE_EVAS_EWS
+static int _ecore_evas_init_count = 0;
+
+static Ecore_Evas *_ews_ee = NULL;
+static Evas_Object *_ews_bg = NULL;
+static Eina_List *_ews_children = NULL;
+static const void *_ews_manager = NULL;
+static char *_ews_engine = NULL;
+static char *_ews_options = NULL;
+static int _ews_x = 0;
+static int _ews_y = 0;
+static int _ews_w = 1024;
+static int _ews_h = 768;
+static Eina_Bool _ews_defaults_engine = EINA_TRUE;
+static Eina_Bool _ews_defaults_geo = EINA_TRUE;
+
+static const char EWS_ENGINE_NAME[] = "ews";
+
+static void
+_ecore_evas_ews_pre_free(Ecore_Evas *ee __UNUSED__)
+{
+   DBG("EWS backing store free'd");
+   _ews_children = eina_list_free(_ews_children);
+   _ews_ee = NULL;
+   _ews_bg = NULL;
+}
+
+static void
+_ecore_evas_ews_del_request(Ecore_Evas *ee __UNUSED__)
+{
+   INF("EWS backing store deletion is forbidden!");
+}
+
+static Ecore_Evas *
+_ecore_evas_ews_ee_new(void)
+{
+   Ecore_Evas *ee = ecore_evas_new(_ews_engine, _ews_x, _ews_y, _ews_w, _ews_h,
+                                   _ews_options);
+   if (!ee)
+     ERR("Failed: ecore_evas_new(%s, %d, %d, %d, %d, %s)",
+         _ews_engine, _ews_x, _ews_y, _ews_w, _ews_h, _ews_options);
+   else
+     {
+        ecore_evas_callback_pre_free_set(ee, _ecore_evas_ews_pre_free);
+        ecore_evas_callback_delete_request_set(ee, _ecore_evas_ews_del_request);
+        ecore_evas_name_class_set(ee, "ecore_evas_ews", "ews");
+        ecore_evas_title_set
+          (ee, "EWS: Ecore + Evas Single Process Windowing System");
+        ecore_evas_show(ee);
+     }
+
+   return ee;
+}
+
+static void
+_ecore_evas_ews_env_setup(void)
+{
+   const char *env = getenv("ECORE_EVAS_EWS");
+   char *p, *n, *tmp;
+
+   if (_ews_defaults_engine)
+     {
+        free(_ews_engine);
+        _ews_engine = NULL;
+        free(_ews_options);
+        _ews_options = NULL;
+     }
+   if (_ews_defaults_geo)
+     {
+        _ews_x = 0;
+        _ews_y = 0;
+        _ews_w = 1024;
+        _ews_h = 768;
+     }
+
+   if ((!env) || (!*env)) return;
+
+   p = tmp = strdup(env);
+   if (!tmp) return;
+
+   n = strchr(p, ':');
+   if (n) *n = '\0';
+   if (_ews_defaults_engine) _ews_engine = strdup(p);
+   if (!n) goto end;
+
+   p = n + 1;
+   n = strchr(p, ':');
+   if (!n) goto end;
+   *n = '\0';
+   if (_ews_defaults_geo) _ews_x = atoi(p);
+
+   p = n + 1;
+   n = strchr(p, ':');
+   if (!n) goto end;
+   *n = '\0';
+   if (_ews_defaults_geo) _ews_y = atoi(p);
+
+   p = n + 1;
+   n = strchr(p, ':');
+   if (!n) goto end;
+   *n = '\0';
+   if (_ews_defaults_geo) _ews_w = atoi(p);
+
+   p = n + 1;
+   n = strchr(p, ':');
+   if (n) *n = '\0';
+   if (_ews_defaults_geo) _ews_h = atoi(p);
+   if (!n) goto end;
+
+   p = n + 1;
+   if (_ews_defaults_engine) _ews_options = strdup(p);
+
+ end:
+   free(tmp);
+}
+
+static void
+_ecore_evas_ews_event_free(void *data __UNUSED__, void *ev)
+{
+   Ecore_Evas *ee = ev;
+   _ecore_evas_unref(ee);
+}
+
+static void
+_ecore_evas_ews_event(Ecore_Evas *ee, int event)
+{
+   _ecore_evas_ref(ee);
+   ecore_event_add(event, ee, _ecore_evas_ews_event_free, NULL);
+}
+
+static void
+_ecore_evas_ews_event_free_del(void *data __UNUSED__, void *ev __UNUSED__)
+{
+   _ecore_evas_ews_shutdown();
+}
+
+static void
+_ecore_evas_ews_free(Ecore_Evas *ee)
+{
+   evas_object_del(ee->engine.ews.image);
+   _ews_ee->sub_ecore_evas = eina_list_remove(_ews_ee->sub_ecore_evas, ee);
+
+   ecore_event_add(ECORE_EVAS_EWS_EVENT_DEL, ee, _ecore_evas_ews_event_free_del, NULL);
+}
+
+static void
+_ecore_evas_ews_move(Ecore_Evas *ee, int x, int y)
+{
+   if ((x == ee->x) && (y == ee->y)) return;
+   ee->x = x;
+   ee->y = y;
+   evas_object_move(ee->engine.ews.image, x, y);
+   if (ee->func.fn_move) ee->func.fn_move(ee);
+
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_MOVE);
+}
+
+static void
+_ecore_evas_ews_managed_move(Ecore_Evas *ee, int x, int y)
+{
+   if ((x == ee->x) && (y == ee->y)) return;
+   ee->x = x;
+   ee->y = y;
+   if (ee->func.fn_move) ee->func.fn_move(ee);
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_MOVE);
+}
+
+static void
+_ecore_evas_ews_resize_internal(Ecore_Evas *ee, int w, int h)
+{
+   Evas_Engine_Info_Buffer *einfo;
+   void *pixels;
+   int stride;
+
+   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);
+
+   evas_object_image_size_set(ee->engine.ews.image, w, h);
+   evas_object_image_fill_set(ee->engine.ews.image, 0, 0, w, h);
+   evas_object_resize(ee->engine.ews.image, w, h);
+
+   pixels = evas_object_image_data_get(ee->engine.ews.image, 1);
+   evas_object_image_data_set(ee->engine.ews.image, pixels); // refcount
+   stride = evas_object_image_stride_get(ee->engine.ews.image);
+
+   einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas);
+   EINA_SAFETY_ON_NULL_RETURN(einfo);
+
+   einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32;
+   einfo->info.dest_buffer = pixels;
+   einfo->info.dest_buffer_row_bytes = stride;
+   einfo->info.use_color_key = 0;
+   einfo->info.alpha_threshold = 0;
+   einfo->info.func.new_update_region = NULL;
+   einfo->info.func.free_update_region = NULL;
+   if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+     {
+        ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
+     }
+}
+
+static void
+_ecore_evas_ews_resize(Ecore_Evas *ee, int w, int h)
+{
+   if (w < 1) w = 1;
+   if (h < 1) h = 1;
+   if ((w == ee->w) && (h == ee->h)) return;
+   ee->w = w;
+   ee->h = h;
+   _ecore_evas_ews_resize_internal(ee, w, h);
+   if (ee->func.fn_resize) ee->func.fn_resize(ee);
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_RESIZE);
+}
+
+static void
+_ecore_evas_ews_move_resize(Ecore_Evas *ee, int x, int y, int w, int h)
+{
+   _ecore_evas_ews_move(ee, x, y);
+   _ecore_evas_ews_resize(ee, w, h);
+}
+
+static void
+_ecore_evas_ews_rotation_set(Ecore_Evas *ee, int rot, int resize)
+{
+   if (ee->rotation == rot) return;
+   ee->rotation = rot;
+
+   ERR("TODO: rot=%d, resize=%d", rot, resize);
+
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE);
+}
+
+static void
+_ecore_evas_ews_shaped_set(Ecore_Evas *ee, int val)
+{
+   if (ee->shaped == val) return;
+   ee->shaped = val;
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE);
+}
+
+static void
+_ecore_evas_ews_show(Ecore_Evas *ee)
+{
+   ee->should_be_visible = EINA_TRUE;
+   evas_object_show(ee->engine.ews.image);
+   if (ee->prop.fullscreen)
+     evas_object_focus_set(ee->engine.ews.image, EINA_TRUE);
+
+   if (ee->func.fn_show) ee->func.fn_show(ee);
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_SHOW);
+}
+
+static void
+_ecore_evas_ews_hide(Ecore_Evas *ee)
+{
+   ee->should_be_visible = EINA_FALSE;
+   evas_object_hide(ee->engine.ews.image);
+
+   if (ee->func.fn_hide) ee->func.fn_hide(ee);
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_HIDE);
+}
+
+static void
+_ecore_evas_ews_raise(Ecore_Evas *ee)
+{
+   evas_object_raise(ee->engine.ews.image);
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_RAISE);
+}
+
+static void
+_ecore_evas_ews_lower(Ecore_Evas *ee)
+{
+   evas_object_lower(ee->engine.ews.image);
+   evas_object_lower(_ews_bg);
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_LOWER);
+}
+
+static void
+_ecore_evas_ews_activate(Ecore_Evas *ee)
+{
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_ACTIVATE);
+}
+
+static void
+_ecore_evas_ews_title_set(Ecore_Evas *ee, const char *t)
+{
+   if (ee->prop.title) free(ee->prop.title);
+   ee->prop.title = NULL;
+   if (t) ee->prop.title = strdup(t);
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE);
+}
+
+static void
+_ecore_evas_ews_name_class_set(Ecore_Evas *ee, const char *n, const char *c)
+{
+   if (ee->prop.name) free(ee->prop.name);
+   if (ee->prop.clas) free(ee->prop.clas);
+   ee->prop.name = NULL;
+   ee->prop.clas = NULL;
+   if (n) ee->prop.name = strdup(n);
+   if (c) ee->prop.clas = strdup(c);
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE);
+}
+
+static void
+_ecore_evas_ews_size_min_set(Ecore_Evas *ee, int w, int h)
+{
+   if (w < 0) w = 0;
+   if (h < 0) h = 0;
+   if ((ee->prop.min.w == w) && (ee->prop.min.h == h)) return;
+   ee->prop.min.w = w;
+   ee->prop.min.h = h;
+   evas_object_size_hint_min_set(ee->engine.ews.image, w, h);
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE);
+}
+
+static void
+_ecore_evas_ews_size_max_set(Ecore_Evas *ee, int w, int h)
+{
+   if (w < 0) w = 0;
+   if (h < 0) h = 0;
+   if ((ee->prop.max.w == w) && (ee->prop.max.h == h)) return;
+   ee->prop.max.w = w;
+   ee->prop.max.h = h;
+   evas_object_size_hint_max_set(ee->engine.ews.image, w, h);
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE);
+}
+
+static void
+_ecore_evas_ews_size_base_set(Ecore_Evas *ee, int w, int h)
+{
+   if (w < 0) w = 0;
+   if (h < 0) h = 0;
+   if ((ee->prop.base.w == w) && (ee->prop.base.h == h)) return;
+   ee->prop.base.w = w;
+   ee->prop.base.h = h;
+   evas_object_size_hint_request_set(ee->engine.ews.image, w, h);
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE);
+}
+
+static void
+_ecore_evas_ews_size_step_set(Ecore_Evas *ee, int w, int h)
+{
+   if (w < 1) w = 1;
+   if (h < 1) h = 1;
+   if ((ee->prop.step.w == w) && (ee->prop.step.h == h)) return;
+   ee->prop.step.w = w;
+   ee->prop.step.h = h;
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE);
+}
+
+static void
+_ecore_evas_ews_object_cursor_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Ecore_Evas *ee = data;
+   ee->prop.cursor.object = NULL;
+}
+
+static void
+_ecore_evas_ews_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y)
+{
+   int x, y;
+
+   if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object);
+
+   if (!obj)
+     {
+        ee->prop.cursor.object = NULL;
+        ee->prop.cursor.layer = 0;
+        ee->prop.cursor.hot.x = 0;
+        ee->prop.cursor.hot.y = 0;
+        return;
+     }
+
+   ee->prop.cursor.object = obj;
+   ee->prop.cursor.layer = layer;
+   ee->prop.cursor.hot.x = hot_x;
+   ee->prop.cursor.hot.y = hot_y;
+   evas_pointer_output_xy_get(ee->evas, &x, &y);
+   evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer);
+   evas_object_move(ee->prop.cursor.object,
+                    x - ee->prop.cursor.hot.x,
+                    y - ee->prop.cursor.hot.y);
+   evas_object_pass_events_set(ee->prop.cursor.object, 1);
+   if (evas_pointer_inside_get(ee->evas))
+     evas_object_show(ee->prop.cursor.object);
+
+   evas_object_event_callback_add
+     (obj, EVAS_CALLBACK_DEL, _ecore_evas_ews_object_cursor_del, ee);
+
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE);
+}
+
+static void
+_ecore_evas_ews_layer_set(Ecore_Evas *ee, int layer)
+{
+   if (layer < EVAS_LAYER_MIN + 1)
+     layer = EVAS_LAYER_MIN + 1;
+   else if (layer > EVAS_LAYER_MAX)
+     layer = EVAS_LAYER_MAX;
+
+   if (ee->prop.layer == layer) return;
+   ee->prop.layer = layer;
+   evas_object_layer_set(ee->engine.ews.image, layer);
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_LAYER_CHANGE);
+}
+
+static void
+_ecore_evas_ews_focus_set(Ecore_Evas *ee, int val)
+{
+   evas_object_focus_set(ee->engine.ews.image, val);
+   if (val)
+     {
+        if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee);
+        _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_FOCUS);
+     }
+   else
+     {
+        if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee);
+        _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_UNFOCUS);
+     }
+}
+
+static void
+_ecore_evas_ews_iconified_set(Ecore_Evas *ee, int val)
+{
+   if (ee->prop.iconified == val) return;
+   ee->prop.iconified = val;
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_ICONIFIED_CHANGE);
+}
+
+static void
+_ecore_evas_ews_borderless_set(Ecore_Evas *ee, int val)
+{
+   if (ee->prop.borderless == val) return;
+   ee->prop.borderless = val;
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE);
+}
+
+static void
+_ecore_evas_ews_override_set(Ecore_Evas *ee, int val)
+{
+   if (ee->prop.override == val) return;
+   if (ee->visible) evas_object_show(ee->engine.ews.image);
+   if (ee->prop.focused) evas_object_focus_set(ee->engine.ews.image, EINA_TRUE);
+   ee->prop.override = val;
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE);
+}
+
+static void
+_ecore_evas_ews_maximized_set(Ecore_Evas *ee, int val)
+{
+   if (ee->prop.maximized == val) return;
+   ee->prop.maximized = val;
+   if (val) evas_object_show(ee->engine.ews.image);
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_MAXIMIZED_CHANGE);
+}
+
+static void
+_ecore_evas_ews_fullscreen_set(Ecore_Evas *ee, int val)
+{
+   if (ee->prop.fullscreen == val) return;
+   ee->prop.fullscreen = val;
+
+   if (!val)
+     {
+        evas_object_move(ee->engine.ews.image, ee->x, ee->y);
+        evas_object_resize(ee->engine.ews.image, ee->w, ee->h);
+     }
+   else
+     {
+        Evas_Coord w, h;
+        ecore_evas_geometry_get(_ews_ee, NULL, NULL, &w, &h);
+        evas_object_move(ee->engine.ews.image, 0, 0);
+        evas_object_resize(ee->engine.ews.image, w, h);
+        evas_object_focus_set(ee->engine.ews.image, EINA_TRUE);
+     }
+
+   if (ee->should_be_visible)
+     evas_object_show(ee->engine.ews.image);
+   else
+     evas_object_hide(ee->engine.ews.image);
+
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_FULLSCREEN_CHANGE);
+}
+
+static void
+_ecore_evas_ews_avoid_damage_set(Ecore_Evas *ee, int val)
+{
+   if (ee->prop.avoid_damage == val) return;
+   ee->prop.avoid_damage = val;
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE);
+}
+
+static void
+_ecore_evas_ews_withdrawn_set(Ecore_Evas *ee, int val)
+{
+   if (ee->prop.withdrawn == val) return;
+   ee->prop.withdrawn = val;
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE);
+}
+
+static void
+_ecore_evas_ews_sticky_set(Ecore_Evas *ee, int val)
+{
+   if (ee->prop.sticky == val) return;
+   ee->prop.sticky = val;
+   if ((val) && (ee->func.fn_sticky)) ee->func.fn_sticky(ee);
+   else if ((!val) && (ee->func.fn_unsticky)) ee->func.fn_unsticky(ee);
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE);
+}
+
+static void
+_ecore_evas_ews_ignore_events_set(Ecore_Evas *ee, int val)
+{
+   if (ee->ignore_events == val) return;
+   ee->ignore_events = val;
+   evas_object_pass_events_set(ee->engine.ews.image, val);
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE);
+}
+
+static void
+_ecore_evas_ews_alpha_set(Ecore_Evas *ee, int val)
+{
+   if (ee->alpha == val) return;
+   ee->alpha = val;
+   evas_object_image_alpha_set(ee->engine.ews.image, val);
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE);
+}
+
+static void
+_ecore_evas_ews_transparent_set(Ecore_Evas *ee, int val)
+{
+   if (ee->transparent == val) return;
+   ee->transparent = val;
+   evas_object_image_alpha_set(ee->engine.ews.image, val);
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE);
+}
+
+static int
+_ecore_evas_ews_render(Ecore_Evas *ee)
+{
+   Eina_List *updates, *l, *ll;
+   Ecore_Evas *ee2;
+   Eina_Rectangle *r;
+   int w, h, rend = 0;
+
+   EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2)
+     {
+        if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
+        rend |= _ecore_evas_ews_render(ee2);
+        if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
+     }
+
+   evas_object_image_size_get(ee->engine.ews.image, &w, &h);
+   if ((w != ee->w) || (h != ee->h))
+     ecore_evas_resize(ee, w, h);
+
+   updates = evas_render_updates(ee->evas);
+
+   EINA_LIST_FOREACH(updates, l, r)
+     evas_object_image_data_update_add(ee->engine.ews.image,
+                                       r->x, r->y, r->w, r->h);
+
+   if (updates)
+     {
+        evas_render_updates_free(updates);
+        _ecore_evas_idle_timeout_update(ee);
+     }
+
+   return updates ? 1 : rend;
+}
+
+static void
+_ecore_evas_ews_screen_geometry_get(const Ecore_Evas *ee __UNUSED__, int *x, int *y, int *w, int *h)
+{
+   ecore_evas_geometry_get(_ews_ee, x, y, w, h);
+}
+
+static const Ecore_Evas_Engine_Func _ecore_ews_engine_func =
+{
+     _ecore_evas_ews_free,
+     NULL,
+     NULL,
+     NULL,
+     NULL,
+     NULL,
+     NULL,
+     NULL,
+     NULL,
+     NULL,
+     NULL,
+     NULL,
+     NULL,
+     NULL,
+     NULL,
+     _ecore_evas_ews_move,
+     _ecore_evas_ews_managed_move,
+     _ecore_evas_ews_resize,
+     _ecore_evas_ews_move_resize,
+     _ecore_evas_ews_rotation_set,
+     _ecore_evas_ews_shaped_set,
+     _ecore_evas_ews_show,
+     _ecore_evas_ews_hide,
+     _ecore_evas_ews_raise,
+     _ecore_evas_ews_lower,
+     _ecore_evas_ews_activate,
+     _ecore_evas_ews_title_set,
+     _ecore_evas_ews_name_class_set,
+     _ecore_evas_ews_size_min_set,
+     _ecore_evas_ews_size_max_set,
+     _ecore_evas_ews_size_base_set,
+     _ecore_evas_ews_size_step_set,
+     _ecore_evas_ews_object_cursor_set,
+     _ecore_evas_ews_layer_set,
+     _ecore_evas_ews_focus_set,
+     _ecore_evas_ews_iconified_set,
+     _ecore_evas_ews_borderless_set,
+     _ecore_evas_ews_override_set,
+     _ecore_evas_ews_maximized_set,
+     _ecore_evas_ews_fullscreen_set,
+     _ecore_evas_ews_avoid_damage_set,
+     _ecore_evas_ews_withdrawn_set,
+     _ecore_evas_ews_sticky_set,
+     _ecore_evas_ews_ignore_events_set,
+     _ecore_evas_ews_alpha_set,
+     _ecore_evas_ews_transparent_set,
+     _ecore_evas_ews_render,
+     _ecore_evas_ews_screen_geometry_get
+};
+
+void
+_ecore_evas_ews_events_init(void)
+{
+   if (ECORE_EVAS_EWS_EVENT_MANAGER_CHANGE != 0) return;
+   ECORE_EVAS_EWS_EVENT_MANAGER_CHANGE = ecore_event_type_new();
+   ECORE_EVAS_EWS_EVENT_ADD = ecore_event_type_new();
+   ECORE_EVAS_EWS_EVENT_DEL = ecore_event_type_new();
+   ECORE_EVAS_EWS_EVENT_RESIZE = ecore_event_type_new();
+   ECORE_EVAS_EWS_EVENT_MOVE = ecore_event_type_new();
+   ECORE_EVAS_EWS_EVENT_SHOW = ecore_event_type_new();
+   ECORE_EVAS_EWS_EVENT_HIDE = ecore_event_type_new();
+   ECORE_EVAS_EWS_EVENT_FOCUS = ecore_event_type_new();
+   ECORE_EVAS_EWS_EVENT_UNFOCUS = ecore_event_type_new();
+   ECORE_EVAS_EWS_EVENT_RAISE = ecore_event_type_new();
+   ECORE_EVAS_EWS_EVENT_LOWER = ecore_event_type_new();
+   ECORE_EVAS_EWS_EVENT_ACTIVATE = ecore_event_type_new();
+   ECORE_EVAS_EWS_EVENT_ICONIFIED_CHANGE = ecore_event_type_new();
+   ECORE_EVAS_EWS_EVENT_MAXIMIZED_CHANGE = ecore_event_type_new();
+   ECORE_EVAS_EWS_EVENT_LAYER_CHANGE = ecore_event_type_new();
+   ECORE_EVAS_EWS_EVENT_FULLSCREEN_CHANGE = ecore_event_type_new();
+   ECORE_EVAS_EWS_EVENT_CONFIG_CHANGE = ecore_event_type_new();
+}
+
+static int
+_ecore_evas_ews_init(void)
+{
+   _ecore_evas_init_count++;
+   if (_ecore_evas_init_count > 1) return _ecore_evas_init_count;
+
+   _ecore_evas_ews_env_setup();
+
+   return _ecore_evas_init_count;
+}
+
+int
+_ecore_evas_ews_shutdown(void)
+{
+   _ecore_evas_init_count--;
+   if (_ecore_evas_init_count == 0)
+     {
+        if (_ews_ee)
+          {
+             ecore_evas_free(_ews_ee);
+             _ews_ee = NULL;
+          }
+        if (_ews_children)
+          {
+             eina_list_free(_ews_children);
+             _ews_children = NULL;
+          }
+
+        free(_ews_engine);
+        _ews_engine = NULL;
+        free(_ews_options);
+        _ews_options = NULL;
+        _ews_defaults_engine = EINA_TRUE;
+        _ews_defaults_geo = EINA_TRUE;
+
+     }
+   if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
+   return _ecore_evas_init_count;
+}
+
+static void
+_ecore_evas_ews_coord_translate(Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y)
+{
+   Evas_Coord xx, yy, ww, hh, fx, fy, fw, fh;
+
+   evas_object_geometry_get(ee->engine.ews.image, &xx, &yy, &ww, &hh);
+   evas_object_image_fill_get(ee->engine.ews.image, &fx, &fy, &fw, &fh);
+
+   if (fw < 1) fw = 1;
+   if (fh < 1) fh = 1;
+
+   if ((fx == 0) && (fy == 0) && (fw == ww) && (fh == hh))
+     {
+        *x = (ee->w * (*x - xx)) / fw;
+        *y = (ee->h * (*y - yy)) / fh;
+     }
+   else
+     {
+        xx = (*x - xx) - fx;
+        while (xx < 0) xx += fw;
+        while (xx > fw) xx -= fw;
+        *x = (ee->w * xx) / fw;
+
+        yy = (*y - yy) - fy;
+        while (yy < 0) yy += fh;
+        while (yy > fh) yy -= fh;
+        *y = (ee->h * yy) / fh;
+     }
+}
+
+static void
+_ecore_evas_ews_cb_mouse_in(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Ecore_Evas *ee = data;
+   Evas_Event_Mouse_In *ev = event_info;
+   evas_event_feed_mouse_in(ee->evas, ev->timestamp, NULL);
+   if (ee->func.fn_mouse_in) ee->func.fn_mouse_in(ee);
+}
+
+static void
+_ecore_evas_ews_cb_mouse_out(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Ecore_Evas *ee = data;
+   Evas_Event_Mouse_Out *ev = event_info;
+   evas_event_feed_mouse_out(ee->evas, ev->timestamp, NULL);
+   if (ee->func.fn_mouse_out) ee->func.fn_mouse_out(ee);
+}
+
+static void
+_ecore_evas_ews_cb_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Ecore_Evas *ee = data;
+   Evas_Event_Mouse_Down *ev = event_info;
+   evas_event_feed_mouse_down(ee->evas, ev->button, ev->flags, ev->timestamp, NULL);
+}
+
+static void
+_ecore_evas_ews_cb_mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Ecore_Evas *ee = data;
+   Evas_Event_Mouse_Up *ev = event_info;
+   evas_event_feed_mouse_up(ee->evas, ev->button, ev->flags, ev->timestamp, NULL);
+}
+
+static void
+_ecore_evas_ews_cb_mouse_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Ecore_Evas *ee = data;
+   Evas_Event_Mouse_Move *ev = event_info;
+   Evas_Coord x = ev->cur.canvas.x;
+   Evas_Coord y = ev->cur.canvas.y;
+   _ecore_evas_ews_coord_translate(ee, &x, &y);
+   _ecore_evas_mouse_move_process(ee, x, y, ev->timestamp);
+}
+
+static void
+_ecore_evas_ews_cb_mouse_wheel(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Ecore_Evas *ee = data;
+   Evas_Event_Mouse_Wheel *ev = event_info;
+   evas_event_feed_mouse_wheel(ee->evas, ev->direction, ev->z, ev->timestamp, NULL);
+}
+
+static void
+_ecore_evas_ews_cb_multi_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Ecore_Evas *ee = data;
+   Evas_Event_Multi_Down *ev = event_info;
+   Evas_Coord x, y, xx, yy;
+   double xf, yf;
+
+   x = ev->canvas.x;
+   y = ev->canvas.y;
+   xx = x;
+   yy = y;
+   _ecore_evas_ews_coord_translate(ee, &x, &y);
+   xf = (ev->canvas.xsub - (double)xx) + (double)x;
+   yf = (ev->canvas.ysub - (double)yy) + (double)y;
+   evas_event_feed_multi_down(ee->evas, ev->device, x, y, ev->radius, ev->radius_x, ev->radius_y, ev->pressure, ev->angle, xf, yf, ev->flags, ev->timestamp, NULL);
+}
+
+static void
+_ecore_evas_ews_cb_multi_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Ecore_Evas *ee = data;
+   Evas_Event_Multi_Up *ev = event_info;
+   Evas_Coord x, y, xx, yy;
+   double xf, yf;
+
+   x = ev->canvas.x;
+   y = ev->canvas.y;
+   xx = x;
+   yy = y;
+   _ecore_evas_ews_coord_translate(ee, &x, &y);
+   xf = (ev->canvas.xsub - (double)xx) + (double)x;
+   yf = (ev->canvas.ysub - (double)yy) + (double)y;
+   evas_event_feed_multi_up(ee->evas, ev->device, x, y, ev->radius, ev->radius_x, ev->radius_y, ev->pressure, ev->angle, xf, yf, ev->flags, ev->timestamp, NULL);
+}
+
+static void
+_ecore_evas_ews_cb_multi_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Ecore_Evas *ee = data;
+   Evas_Event_Multi_Move *ev = event_info;
+   Evas_Coord x, y, xx, yy;
+   double xf, yf;
+
+   x = ev->cur.canvas.x;
+   y = ev->cur.canvas.y;
+   xx = x;
+   yy = y;
+   _ecore_evas_ews_coord_translate(ee, &x, &y);
+   xf = (ev->cur.canvas.xsub - (double)xx) + (double)x;
+   yf = (ev->cur.canvas.ysub - (double)yy) + (double)y;
+   evas_event_feed_multi_move(ee->evas, ev->device, x, y, ev->radius, ev->radius_x, ev->radius_y, ev->pressure, ev->angle, xf, yf, ev->timestamp, NULL);
+}
+
+static void
+_ecore_evas_ews_cb_free(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Ecore_Evas *ee = data;
+   if (ee->driver) _ecore_evas_free(ee);
+}
+
+static void
+_ecore_evas_ews_cb_key_down(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Ecore_Evas *ee = data;
+   Evas_Event_Key_Down *ev = event_info;
+
+   if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Shift"))
+     evas_key_modifier_on(ee->evas, "Shift");
+   else
+     evas_key_modifier_off(ee->evas, "Shift");
+   if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Control"))
+     evas_key_modifier_on(ee->evas, "Control");
+   else
+     evas_key_modifier_off(ee->evas, "Control");
+   if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Alt"))
+     evas_key_modifier_on(ee->evas, "Alt");
+   else
+     evas_key_modifier_off(ee->evas, "Alt");
+   if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Meta"))
+     evas_key_modifier_on(ee->evas, "Meta");
+   else
+     evas_key_modifier_off(ee->evas, "Meta");
+   if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Hyper"))
+     evas_key_modifier_on(ee->evas, "Hyper");
+   else
+     evas_key_modifier_off(ee->evas, "Hyper");
+   if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Super"))
+     evas_key_modifier_on(ee->evas, "Super");
+   else
+     evas_key_modifier_off(ee->evas, "Super");
+   if (evas_key_lock_is_set(evas_key_lock_get(e), "Scroll_Lock"))
+     evas_key_lock_on(ee->evas, "Scroll_Lock");
+   else
+     evas_key_lock_off(ee->evas, "Scroll_Lock");
+   if (evas_key_lock_is_set(evas_key_lock_get(e), "Num_Lock"))
+     evas_key_lock_on(ee->evas, "Num_Lock");
+   else
+     evas_key_lock_off(ee->evas, "Num_Lock");
+   if (evas_key_lock_is_set(evas_key_lock_get(e), "Caps_Lock"))
+     evas_key_lock_on(ee->evas, "Caps_Lock");
+   else
+     evas_key_lock_off(ee->evas, "Caps_Lock");
+   evas_event_feed_key_down(ee->evas, ev->keyname, ev->key, ev->string, ev->compose, ev->timestamp, NULL);
+}
+
+static void
+_ecore_evas_ews_cb_key_up(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   Ecore_Evas *ee = data;
+   Evas_Event_Key_Up *ev = event_info;
+
+   if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Shift"))
+     evas_key_modifier_on(ee->evas, "Shift");
+   else
+     evas_key_modifier_off(ee->evas, "Shift");
+   if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Control"))
+     evas_key_modifier_on(ee->evas, "Control");
+   else
+     evas_key_modifier_off(ee->evas, "Control");
+   if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Alt"))
+     evas_key_modifier_on(ee->evas, "Alt");
+   else
+     evas_key_modifier_off(ee->evas, "Alt");
+   if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Meta"))
+     evas_key_modifier_on(ee->evas, "Meta");
+   else
+     evas_key_modifier_off(ee->evas, "Meta");
+   if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Hyper"))
+     evas_key_modifier_on(ee->evas, "Hyper");
+   else
+     evas_key_modifier_off(ee->evas, "Hyper");
+   if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Super"))
+     evas_key_modifier_on(ee->evas, "Super");
+   else
+     evas_key_modifier_off(ee->evas, "Super");
+   if (evas_key_lock_is_set(evas_key_lock_get(e), "Scroll_Lock"))
+     evas_key_lock_on(ee->evas, "Scroll_Lock");
+   else
+     evas_key_lock_off(ee->evas, "Scroll_Lock");
+   if (evas_key_lock_is_set(evas_key_lock_get(e), "Num_Lock"))
+     evas_key_lock_on(ee->evas, "Num_Lock");
+   else
+     evas_key_lock_off(ee->evas, "Num_Lock");
+   if (evas_key_lock_is_set(evas_key_lock_get(e), "Caps_Lock"))
+     evas_key_lock_on(ee->evas, "Caps_Lock");
+   else
+     evas_key_lock_off(ee->evas, "Caps_Lock");
+   evas_event_feed_key_up(ee->evas, ev->keyname, ev->key, ev->string, ev->compose, ev->timestamp, NULL);
+}
+
+static void
+_ecore_evas_ews_cb_focus_in(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Ecore_Evas *ee = data;
+   ecore_evas_focus_set(ee, EINA_TRUE);
+}
+
+static void
+_ecore_evas_ews_cb_focus_out(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Ecore_Evas *ee = data;
+   ecore_evas_focus_set(ee, EINA_FALSE);
+}
+
+static void
+_ecore_evas_ews_cb_show(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Ecore_Evas *ee = data;
+   ecore_evas_show(ee);
+}
+
+static void
+_ecore_evas_ews_cb_hide(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Ecore_Evas *ee = data;
+   if (ee->deleted) return;
+   ecore_evas_hide(ee);
+}
+#endif
+
+EAPI Ecore_Evas *
+ecore_evas_ews_new(int x, int y, int w, int h)
+{
+// basically a copy of ecore_evas_buffer_new() keep in sync...
+#ifdef BUILD_ECORE_EVAS_EWS
+   Evas_Object *o;
+   Evas_Engine_Info_Buffer *einfo;
+   Ecore_Evas *ee;
+   int rmethod;
+
+   if (_ecore_evas_ews_init() < 1) return NULL;
+
+   if (!_ews_ee) _ews_ee = _ecore_evas_ews_ee_new();
+   if (!_ews_ee)
+     {
+        ERR("Could not create EWS backing store");
+        _ecore_evas_ews_shutdown();
+        return NULL;
+     }
+
+   rmethod = evas_render_method_lookup("buffer");
+   if (!rmethod) return NULL;
+   ee = calloc(1, sizeof(Ecore_Evas));
+   if (!ee) return NULL;
+
+   o = evas_object_image_add(_ews_ee->evas);
+   evas_object_image_content_hint_set(o, EVAS_IMAGE_CONTENT_HINT_DYNAMIC);
+   evas_object_image_colorspace_set(o, EVAS_COLORSPACE_ARGB8888);
+
+   ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
+
+   ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_ews_engine_func;
+
+   ee->driver = EWS_ENGINE_NAME;
+
+   if (w < 1) w = 1;
+   if (h < 1) h = 1;
+
+   ee->x = 0;
+   ee->y = 0;
+   ee->w = w;
+   ee->h = h;
+
+   /* init evas here */
+   ee->evas = evas_new();
+   evas_data_attach_set(ee->evas, ee);
+   evas_output_method_set(ee->evas, rmethod);
+   evas_output_size_set(ee->evas, w, h);
+   evas_output_viewport_set(ee->evas, 0, 0, w, h);
+
+   evas_object_move(o, x, y);
+   evas_object_resize(o, w, h);
+   evas_object_image_fill_set(o, 0, 0, w, h);
+
+   ee->engine.ews.image = o;
+   evas_object_data_set(ee->engine.ews.image, "Ecore_Evas", ee);
+   evas_object_image_size_set(o, ee->w, ee->h);
+   evas_object_image_alpha_set(o, 1);
+   evas_object_event_callback_add(ee->engine.ews.image,
+                                  EVAS_CALLBACK_MOUSE_IN,
+                                  _ecore_evas_ews_cb_mouse_in, ee);
+   evas_object_event_callback_add(ee->engine.ews.image,
+                                  EVAS_CALLBACK_MOUSE_OUT,
+                                  _ecore_evas_ews_cb_mouse_out, ee);
+   evas_object_event_callback_add(ee->engine.ews.image,
+                                  EVAS_CALLBACK_MOUSE_DOWN,
+                                  _ecore_evas_ews_cb_mouse_down, ee);
+   evas_object_event_callback_add(ee->engine.ews.image,
+                                  EVAS_CALLBACK_MOUSE_UP,
+                                  _ecore_evas_ews_cb_mouse_up, ee);
+   evas_object_event_callback_add(ee->engine.ews.image,
+                                  EVAS_CALLBACK_MOUSE_MOVE,
+                                  _ecore_evas_ews_cb_mouse_move, ee);
+   evas_object_event_callback_add(ee->engine.ews.image,
+                                  EVAS_CALLBACK_MOUSE_WHEEL,
+                                  _ecore_evas_ews_cb_mouse_wheel, ee);
+   evas_object_event_callback_add(ee->engine.ews.image,
+                                  EVAS_CALLBACK_MULTI_DOWN,
+                                  _ecore_evas_ews_cb_multi_down, ee);
+   evas_object_event_callback_add(ee->engine.ews.image,
+                                  EVAS_CALLBACK_MULTI_UP,
+                                  _ecore_evas_ews_cb_multi_up, ee);
+   evas_object_event_callback_add(ee->engine.ews.image,
+                                  EVAS_CALLBACK_MULTI_MOVE,
+                                  _ecore_evas_ews_cb_multi_move, ee);
+   evas_object_event_callback_add(ee->engine.ews.image,
+                                  EVAS_CALLBACK_FREE,
+                                  _ecore_evas_ews_cb_free, ee);
+   evas_object_event_callback_add(ee->engine.ews.image,
+                                  EVAS_CALLBACK_KEY_DOWN,
+                                  _ecore_evas_ews_cb_key_down, ee);
+   evas_object_event_callback_add(ee->engine.ews.image,
+                                  EVAS_CALLBACK_KEY_UP,
+                                  _ecore_evas_ews_cb_key_up, ee);
+   evas_object_event_callback_add(ee->engine.ews.image,
+                                  EVAS_CALLBACK_FOCUS_IN,
+                                  _ecore_evas_ews_cb_focus_in, ee);
+   evas_object_event_callback_add(ee->engine.ews.image,
+                                  EVAS_CALLBACK_FOCUS_OUT,
+                                  _ecore_evas_ews_cb_focus_out, ee);
+   evas_object_event_callback_add(ee->engine.ews.image,
+                                  EVAS_CALLBACK_SHOW,
+                                  _ecore_evas_ews_cb_show, ee);
+   evas_object_event_callback_add(ee->engine.ews.image,
+                                  EVAS_CALLBACK_HIDE,
+                                  _ecore_evas_ews_cb_hide, ee);
+   einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas);
+   if (einfo)
+     {
+        void *pixels = evas_object_image_data_get(o, 1);
+        evas_object_image_data_set(o, pixels); // refcount
+        einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32;
+        einfo->info.dest_buffer = pixels;
+        einfo->info.dest_buffer_row_bytes = evas_object_image_stride_get(o);
+        einfo->info.use_color_key = 0;
+        einfo->info.alpha_threshold = 0;
+        einfo->info.func.new_update_region = NULL;
+        einfo->info.func.free_update_region = NULL;
+        if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
+          {
+             ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
+             ecore_evas_free(ee);
+             return NULL;
+          }
+     }
+   else
+     {
+        ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
+        ecore_evas_free(ee);
+        return NULL;
+     }
+   evas_key_modifier_add(ee->evas, "Shift");
+   evas_key_modifier_add(ee->evas, "Control");
+   evas_key_modifier_add(ee->evas, "Alt");
+   evas_key_modifier_add(ee->evas, "Meta");
+   evas_key_modifier_add(ee->evas, "Hyper");
+   evas_key_modifier_add(ee->evas, "Super");
+   evas_key_lock_add(ee->evas, "Caps_Lock");
+   evas_key_lock_add(ee->evas, "Num_Lock");
+   evas_key_lock_add(ee->evas, "Scroll_Lock");
+
+   _ews_ee->sub_ecore_evas = eina_list_append(_ews_ee->sub_ecore_evas, ee);
+   _ews_children = eina_list_append(_ews_children, ee);
+
+   _ecore_evas_ews_event(ee, ECORE_EVAS_EWS_EVENT_ADD);
+
+   return ee;
+#else
+   return NULL;
+   (void)x;
+   (void)y;
+   (void)w;
+   (void)h;
+#endif
+}
+
+EAPI Evas_Object *
+ecore_evas_ews_backing_store_get(const Ecore_Evas *ee)
+{
+#ifdef BUILD_ECORE_EVAS_EWS
+   if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+     {
+        ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+                         "ecore_evas_ews_backing_store_get");
+        return NULL;
+     }
+   return ee->engine.ews.image;
+#else
+   return NULL;
+   (void)ee;
+#endif
+}
+
+EAPI void
+ecore_evas_ews_delete_request(Ecore_Evas *ee)
+{
+#ifdef BUILD_ECORE_EVAS_EWS
+   if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
+     {
+        ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
+                         "ecore_evas_ews_delete_request");
+        return;
+     }
+   if (ee->func.fn_delete_request) ee->func.fn_delete_request(ee);
+   else ecore_evas_free(ee);
+#else
+   (void)ee;
+#endif
+}
+
+
+EAPI Eina_Bool
+ecore_evas_ews_engine_set(const char *engine, const char *options)
+{
+#ifdef BUILD_ECORE_EVAS_EWS
+   if (_ews_ee) return EINA_FALSE;
+
+   free(_ews_engine);
+   free(_ews_options);
+
+   _ews_engine = engine ? strdup(engine) : NULL;
+   _ews_options = options ? strdup(options) : NULL;
+
+   if ((engine) && (!_ews_engine)) return EINA_FALSE;
+   if ((options) && (!_ews_options)) return EINA_FALSE;
+
+   _ews_defaults_engine = EINA_FALSE;
+   return EINA_TRUE;
+#else
+   return EINA_FALSE;
+   (void)engine;
+   (void)options;
+#endif
+}
+
+EAPI Eina_Bool
+ecore_evas_ews_setup(int x, int y, int w, int h)
+{
+#ifdef BUILD_ECORE_EVAS_EWS
+   Eina_Bool ret = EINA_TRUE;
+
+   _ews_defaults_geo = EINA_FALSE;
+   _ews_x = x;
+   _ews_y = y;
+   _ews_w = w;
+   _ews_h = h;
+
+   if (!_ews_ee) return EINA_TRUE;
+
+   /* move-resize is not as implemented as move + resize */
+   ecore_evas_move(_ews_ee, x, y);
+   ecore_evas_resize(_ews_ee, w, h);
+
+   ecore_evas_geometry_get(_ews_ee, &x, &y, &w, &h);
+
+#define TST(n) if ((n != _ews_##n))                     \
+     {                                                  \
+        WRN("Asked %d, got %d for "#n, _ews_##n, n);    \
+        ret = EINA_FALSE;                               \
+     }
+   TST(x);
+   TST(y);
+   TST(w);
+   TST(h);
+#undef TST
+   return ret;
+#else
+   return EINA_FALSE;
+   (void)x;
+   (void)y;
+   (void)w;
+   (void)h;
+#endif
+}
+
+EAPI Ecore_Evas *
+ecore_evas_ews_ecore_evas_get(void)
+{
+#ifdef BUILD_ECORE_EVAS_EWS
+   if (!_ews_ee) _ews_ee = _ecore_evas_ews_ee_new();
+   return _ews_ee;
+#else
+   return NULL;
+#endif
+}
+
+EAPI Evas *
+ecore_evas_ews_evas_get(void)
+{
+#ifdef BUILD_ECORE_EVAS_EWS
+   return ecore_evas_get(ecore_evas_ews_ecore_evas_get());
+#else
+   return NULL;
+#endif
+}
+
+EAPI Evas_Object *
+ecore_evas_ews_background_get(void)
+{
+   return _ews_bg;
+}
+
+static void
+_ecore_evas_ews_background_free(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event_info __UNUSED__)
+{
+   _ews_bg = NULL;
+   ecore_evas_ews_background_set(NULL);
+}
+
+EAPI void
+ecore_evas_ews_background_set(Evas_Object *o)
+{
+   if ((o) && (o == _ews_bg)) return;
+
+   if (_ews_bg)
+     {
+        evas_object_del(_ews_bg);
+        _ews_bg = NULL;
+     }
+
+   if ((!o) && (_ews_ee))
+     {
+        o = evas_object_rectangle_add(ecore_evas_get(_ews_ee));
+        evas_object_color_set(o, 0, 0, 0, 255);
+     }
+
+   if (_ews_ee)
+     {
+        Evas_Coord w, h;
+        Evas *e = ecore_evas_get(_ews_ee);
+
+        if (e != evas_object_evas_get(o))
+          {
+             ERR("background not in ecore_evas_ews_evas_get() canvas!");
+             return;
+          }
+
+        evas_output_viewport_get(e, NULL, NULL, &w, &h);
+        evas_object_move(o, 0, 0);
+        evas_object_resize(o, w, h);
+        evas_object_layer_set(o, EVAS_LAYER_MIN);
+        evas_object_lower(o);
+        evas_object_show(o);
+
+        evas_object_event_callback_add
+          (o, EVAS_CALLBACK_FREE, _ecore_evas_ews_background_free, NULL);
+     }
+
+   _ews_bg = o;
+}
+
+
+EAPI const Eina_List *
+ecore_evas_ews_children_get(void)
+{
+#ifdef BUILD_ECORE_EVAS_EWS
+   return _ews_children;
+#else
+   return NULL;
+#endif
+}
+
+EAPI void
+ecore_evas_ews_manager_set(const void *manager)
+{
+#ifdef BUILD_ECORE_EVAS_EWS
+   if (_ews_manager ==  manager) return;
+   _ews_manager = manager;
+   ecore_event_add(ECORE_EVAS_EWS_EVENT_MANAGER_CHANGE, NULL, NULL, NULL);
+#else
+   (void)manager;
+#endif
+}
+
+EAPI const void *
+ecore_evas_ews_manager_get(void)
+{
+#ifdef BUILD_ECORE_EVAS_EWS
+   return _ews_manager;
+#else
+   return NULL;
+#endif
+}
index 8c65040..6958db1 100644 (file)
@@ -198,19 +198,17 @@ _ecore_evas_fb_render(Ecore_Evas *ee)
      {
         Eina_List *updates;
 
-#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
         Eina_List *ll;
         Ecore_Evas *ee2;
-#endif
         if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
-#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
+
         EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2)
           {
              if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
              rend |= _ecore_evas_buffer_render(ee2);
              if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
           }
-#endif
+
         updates = evas_render_updates(ee->evas);
         if (updates)
           {
index ae28ce2..e662048 100644 (file)
@@ -58,7 +58,7 @@
 # include "Ecore_DirectFB.h"
 #endif
 
-#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
+#if defined(BUILD_ECORE_EVAS_SOFTWARE_BUFFER) || defined(BUILD_ECORE_EVAS_EWS)
 # include <Evas_Engine_Buffer.h>
 #endif
 
@@ -184,6 +184,7 @@ struct _Ecore_Evas_Engine
 {
    Ecore_Evas_Engine_Func *func;
 
+/* TODO: UGLY! This should be an union or inheritance! */
 #ifdef BUILD_ECORE_EVAS_X11
    struct 
      {
@@ -259,6 +260,11 @@ struct _Ecore_Evas_Engine
       } state;
    } wince;
 #endif
+#ifdef BUILD_ECORE_EVAS_EWS
+   struct {
+      Evas_Object *image;
+   } ews;
+#endif
 
    Ecore_Timer *idle_flush_timer;
 };
@@ -345,13 +351,19 @@ struct _Ecore_Evas
    Ecore_Evas_Engine engine;
    Eina_List *sub_ecore_evas;
 
+   int refcount;
+
    unsigned char ignore_events : 1;
    unsigned char manual_render : 1;
    unsigned char registered : 1;
    unsigned char no_comp_sync  : 1;
    unsigned char semi_sync  : 1;
+   unsigned char deleted : 1;
 };
 
+void _ecore_evas_ref(Ecore_Evas *ee);
+void _ecore_evas_unref(Ecore_Evas *ee);
+
 #ifdef BUILD_ECORE_EVAS_X11
 int _ecore_evas_x_shutdown(void);
 #endif
@@ -371,6 +383,10 @@ int _ecore_evas_win32_shutdown(void);
 #ifdef BUILD_ECORE_EVAS_SOFTWARE_16_WINCE
 int _ecore_evas_wince_shutdown(void);
 #endif
+#ifdef BUILD_ECORE_EVAS_EWS
+void _ecore_evas_ews_events_init(void);
+int _ecore_evas_ews_shutdown(void);
+#endif
 
 void _ecore_evas_fps_debug_init(void);
 void _ecore_evas_fps_debug_shutdown(void);
index 7f13f98..be20a27 100644 (file)
@@ -119,8 +119,6 @@ static int
 _ecore_evas_sdl_render(Ecore_Evas *ee)
 {
    int rend = 0;
-
-#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
    Eina_List *ll;
    Ecore_Evas *ee2;
 
@@ -130,7 +128,6 @@ _ecore_evas_sdl_render(Ecore_Evas *ee)
         rend |= _ecore_evas_buffer_render(ee2);
         if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
      }
-#endif
 
    if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
 
index edf458a..f17223c 100644 (file)
@@ -48,7 +48,6 @@ _ecore_evas_win32_render(Ecore_Evas *ee)
 {
    int rend = 0;
    Eina_List *updates = NULL;
-#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
    Eina_List *ll;
    Ecore_Evas *ee2;
 
@@ -58,7 +57,7 @@ _ecore_evas_win32_render(Ecore_Evas *ee)
         rend |= _ecore_evas_buffer_render(ee2);
         if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
      }
-#endif
+
    if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
    if (ee->prop.avoid_damage)
      {
index 0a87155..3495040 100644 (file)
@@ -46,7 +46,6 @@ _ecore_evas_wince_render(Ecore_Evas *ee)
 {
    int rend = 0;
    Eina_List *updates = NULL;
-#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
    Eina_List *ll;
    Ecore_Evas *ee2;
 
@@ -56,7 +55,7 @@ _ecore_evas_wince_render(Ecore_Evas *ee)
         rend |= _ecore_evas_buffer_render(ee2);
         if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
      }
-#endif
+
    if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
    if (ee->prop.avoid_damage)
      {
index 487aa03..e9ea82c 100644 (file)
@@ -236,8 +236,6 @@ _ecore_evas_x_render(Ecore_Evas *ee)
 {
    int rend = 0;
    Eina_List *updates = NULL;
-
-#ifdef BUILD_ECORE_EVAS_SOFTWARE_BUFFER
    Eina_List *ll;
    Ecore_Evas *ee2;
 
@@ -252,7 +250,6 @@ _ecore_evas_x_render(Ecore_Evas *ee)
         rend |= _ecore_evas_buffer_render(ee2);
         if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
      }
-#endif
 
    if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
    updates = evas_render_updates(ee->evas);