Import initial codes 04/61904/3 accepted/tizen/common/20160323.184058 accepted/tizen/mobile/20160323.135310 accepted/tizen/wearable/20160323.135328 submit/tizen/20160322.073128 submit/tizen/20160323.075331
authorJengHyun Kang <jhyuni.kang@samsung.com>
Fri, 11 Mar 2016 06:00:02 +0000 (15:00 +0900)
committerJengHyun Kang <jhyuni.kang@samsung.com>
Mon, 21 Mar 2016 10:50:27 +0000 (19:50 +0900)
Change-Id: I3314517fa6ff6d2f9a65e6dfcef0c161b0e9c788

.gitignore [new file with mode: 0644]
COPYING [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
autogen.sh [new file with mode: 0755]
configure.ac [new file with mode: 0644]
packaging/e-mod-tizen-gesture.spec [new file with mode: 0644]
src/Makefile.am [new file with mode: 0644]
src/e_mod_gesture_events.c [new file with mode: 0644]
src/e_mod_main.c [new file with mode: 0644]
src/e_mod_main.h [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..f3bbff3
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,25 @@
+Copyright notice for Enlightenment:
+
+Copyright (C) 2000-2012 Carsten Haitzler and various contributors (see AUTHORS)
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+   1. Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+   2. Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..a30d363
--- /dev/null
@@ -0,0 +1,8 @@
+#maintainer-clean removes everything
+MAINTAINERCLEANFILES = aclocal.m4 compile config.sub config.guess config.h.in \
+                      configure depcomp install-sh ltmain.sh Makefile.in missing
+
+SUBDIRS = src
+
+MAINTAINERCLEANFILES = \
+                      Makefile.in
diff --git a/autogen.sh b/autogen.sh
new file mode 100755 (executable)
index 0000000..1ac867a
--- /dev/null
@@ -0,0 +1,16 @@
+#!/bin/sh
+# Run this to generate all the initial makefiles, etc.
+
+#rm -rf autom4te.cache
+#rm -f aclocal.m4 ltmain.sh
+
+#echo "Running autoreconf..." ; autoreconf -v --install || exit 1
+#echo "Running configure..." ; ./configure --enable-maintainer-mode
+
+set  -x
+aclocal
+autoconf
+libtoolize --copy --force
+autoheader
+automake --foreign --add-missing --copy
+
diff --git a/configure.ac b/configure.ac
new file mode 100644 (file)
index 0000000..c1e5180
--- /dev/null
@@ -0,0 +1,143 @@
+# Process this file with autoconf to produce a configure script.
+dnl Process this file with autoconf to produce a configure script.
+
+# Note )
+#
+# AC_DEFINE(VARIABLE, VALUE, DESCRIPTION)
+#   output the following to config.h
+#   /* DESCRIPTION */
+#   #define VARIABLE VALUE
+#
+# AC_SUBST(VARIABLE, [VALUE])
+#   define $(VARIABLE) as VALUE in Makefile
+
+dnl ========================================================================
+# initialization
+dnl ========================================================================
+AC_INIT([e-mod-tizen-gesture], [0.1], [jhyuni.kang@samsung.com])
+
+# check for tools needed by automake generated Makefiles
+# -Wall  : Turn all warnings on.
+# -Werror: report warings as errors.
+# foreign: relax some GNU standard requirements
+#AM_INIT_AUTOMAKE([-Wall -Werror foreign])
+AM_INIT_AUTOMAKE([-Wall foreign])
+
+dnl ========================================================================
+# checks for programs
+dnl ========================================================================
+AC_PROG_CC
+AC_DISABLE_STATIC
+AC_PROG_LIBTOOL
+
+dnl ========================================================================
+# checks for libraries
+dnl ========================================================================
+
+dnl ========================================================================
+# checks for header files
+dnl ========================================================================
+#AC_HEADER_STDC
+AC_CHECK_HEADERS([math.h fcntl.h stdlib.h string.h unistd.h])
+
+dnl ========================================================================
+# checks for input files
+dnl ========================================================================
+
+dnl ========================================================================
+# checks for typedefs, structures, and compiler characteristics
+AC_C_CONST
+
+dnl ========================================================================
+# checks for library functions
+dnl ========================================================================
+#AC_FUNC_MALLOC
+AC_FUNC_MMAP
+AC_CHECK_FUNCS([memset munmap strcasecmp strdup])
+
+dnl ========================================================================
+# checks for pkg-config
+dnl ========================================================================
+PKG_PROG_PKG_CONFIG
+
+dnl ========================================================================
+# checks for pkg-config
+dnl ========================================================================
+PKG_CHECK_MODULES(ENLIGHTENMENT, [enlightenment,
+                                  dlog])
+ENLIGHTENMENT_CFLAGS="${ENLIGHTENMENT_CFLAGS} -D_GNU_SOURCE "
+AC_SUBST(ENLIGHTENMENT_CFLAGS)
+AC_SUBST(ENLIGHTENMENT_LIBS)
+
+# Find edje_cc
+#PKG_CHECK_MODULES(EDJE, [edje >= 0.5.0])
+#AC_ARG_WITH(edje-cc,
+#      AC_HELP_STRING([--with-edje-cc=PATH], [specify a specific path to edje_cc]),
+#      [
+#              v=$withval;
+#              EDJE_CC=$v
+#      ],
+#      [
+#              EDJE_CC=$(pkg-config --variable=prefix edje)/bin/edje_cc
+#      ]
+#)
+#AC_SUBST(EDJE_CC)
+#AC_MSG_CHECKING([Which edje_cc to use])
+#AC_MSG_RESULT(${EDJE_CC})
+
+dnl ========================================================================
+# checks for wayland only argument
+dnl ========================================================================
+have_wayland_only=no
+AC_ARG_ENABLE([wayland-only],
+  AS_HELP_STRING([--enable-wayland-only],[enable wayland-only version of enlightenment @<:@default=disabled@:>@]),
+  [have_wayland_only=$enableval],
+  [have_wayland_only=no])
+AC_MSG_CHECKING([whether wayland-only version is enabled])
+AM_CONDITIONAL(WAYLAND_ONLY, test x$have_wayland_only = xyes)
+if test "x${have_wayland_only}" != "xno"; then
+  AC_DEFINE_UNQUOTED([HAVE_WAYLAND_ONLY],[1],[enable wayland-only version of enlightenment])
+fi
+
+# to include e_comp_wl.h
+if test "x${have_wayland_only}" != "xno"; then
+  AC_DEFINE_UNQUOTED([HAVE_WAYLAND],[1],[enable wayland support])
+fi
+
+dnl ========================================================================
+# checks for wayland only argument
+dnl ========================================================================
+if test "x${have_wayland_only}" = "xyes"; then
+  PKG_CHECK_MODULES(WAYLAND, [wayland-server, tizen-extension-server])
+fi
+
+release=$(pkg-config --variable=release enlightenment)
+MODULE_ARCH="$host_os-$host_cpu-$release"
+AC_SUBST(MODULE_ARCH)
+AC_DEFINE_UNQUOTED(MODULE_ARCH, "$MODULE_ARCH", "Module architecture")
+
+datadir=$(pkg-config --variable=modules enlightenment)/${PACKAGE}
+AC_ARG_ENABLE(homedir-install,
+       AS_HELP_STRING([--enable-homedir-install], [Install module in homedir]),
+       [ datadir="${HOME}/.e/e/modules/${PACKAGE}" ]
+)
+
+dnl ========================================================================
+# output files
+dnl ========================================================================
+
+# create HEADER for all HEADER.in.
+# HEADERS contain definitions made with AC_DEFINE.
+# the following command will create config.h from config.h.in
+AC_CONFIG_HEADERS([config.h])
+
+# create FILE for all FILE.in.
+# FILES contains definitions made with AC_SUBST.
+AC_CONFIG_FILES([
+                Makefile
+                src/Makefile
+                ])
+
+AC_OUTPUT
+
+
diff --git a/packaging/e-mod-tizen-gesture.spec b/packaging/e-mod-tizen-gesture.spec
new file mode 100644 (file)
index 0000000..c443906
--- /dev/null
@@ -0,0 +1,53 @@
+%bcond_with x
+%bcond_with wayland
+
+Name: e-mod-tizen-gesture
+Version: 0.1.0
+Release: 1
+Summary: The Enlightenment Gesture Module for Tizen
+URL: http://www.enlightenment.org
+Group: Graphics & UI Framework/Other
+Source0: %{name}-%{version}.tar.gz
+License: BSD-2-Clause
+BuildRequires:  pkgconfig(enlightenment)
+BuildRequires:  gettext
+BuildRequires:  pkgconfig(wayland-server)
+BuildRequires:  pkgconfig(tizen-extension-server)
+BuildRequires:  pkgconfig(dlog)
+
+%global TZ_SYS_RO_SHARE  %{?TZ_SYS_RO_SHARE:%TZ_SYS_RO_SHARE}%{!?TZ_SYS_RO_SHARE:/usr/share}
+
+%description
+This package is a the Enlightenment Gesture Module for Tizen.
+
+%prep
+%setup -q
+
+%build
+
+export GC_SECTIONS_FLAGS="-fdata-sections -ffunction-sections -Wl,--gc-sections"
+export CFLAGS+=" -Wall -g -fPIC -rdynamic ${GC_SECTIONS_FLAGS} -DE_LOGGING=1 "
+export LDFLAGS+=" -Wl,--hash-style=both -Wl,--as-needed -Wl,--rpath=/usr/lib"
+
+%autogen
+%configure --prefix=/usr \
+           --enable-wayland-only \
+make
+
+%install
+rm -rf %{buildroot}
+
+# for license notification
+mkdir -p %{buildroot}/%{TZ_SYS_RO_SHARE}/license
+cp -a %{_builddir}/%{buildsubdir}/COPYING %{buildroot}/%{TZ_SYS_RO_SHARE}/license/%{name}
+
+# install
+make install DESTDIR=%{buildroot}
+
+# clear useless textual files
+find  %{buildroot}%{_libdir}/enlightenment/modules/%{name} -name *.la | xargs rm
+
+%files
+%defattr(-,root,root,-)
+%{_libdir}/enlightenment/modules/e-mod-tizen-gesture
+/%{TZ_SYS_RO_SHARE}/license/%{name}
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644 (file)
index 0000000..59ac035
--- /dev/null
@@ -0,0 +1,14 @@
+MAINTAINERCLEANFILES = Makefile.in
+MODULE = e-mod-tizen-gesture
+
+LDFLAGS +=
+
+pkgdir                 = $(libdir)/enlightenment/modules/$(MODULE)/$(MODULE_ARCH)
+pkg_LTLIBRARIES        = module.la
+module_la_SOURCES      = e_mod_main.c \
+                         e_mod_main.h \
+                                                e_mod_gesture_events.c
+module_la_CFLAGS       = @ENLIGHTENMENT_CFLAGS@ @WAYLAND_CFLAGS@ -DHAVE_WAYLAND_ONLY
+module_la_LDFLAGS      = -module -avoid-version @WAYLAND_LIBS@ @ENLIGHTENMENT_LIBS@
+
+module_la_DEPENDENCIES = $(top_builddir)/config.h
diff --git a/src/e_mod_gesture_events.c b/src/e_mod_gesture_events.c
new file mode 100644 (file)
index 0000000..fe73bf3
--- /dev/null
@@ -0,0 +1,418 @@
+#define E_COMP_WL
+#include "e_mod_main.h"
+#include <string.h>
+
+static void
+_e_gesture_swipe_cancel(void)
+{
+   E_Gesture_Event_Swipe *swipes = &gesture->gesture_events.swipes;
+
+   if (swipes->start_timer)
+     {
+        ecore_timer_del(swipes->start_timer);
+        swipes->start_timer = NULL;
+     }
+   if (swipes->done_timer)
+     {
+        ecore_timer_del(swipes->done_timer);
+        swipes->done_timer = NULL;
+     }
+
+   swipes->enabled_finger = 0x0;
+   swipes->direction = E_GESTURE_DIRECTION_NONE;
+
+   gesture->gesture_filter |= TIZEN_GESTURE_TYPE_SWIPE;
+}
+
+static Eina_Bool
+_e_gesture_is_touch_device(const char *identifier)
+{
+   Eina_List *l;
+   char *data;
+
+   EINA_LIST_FOREACH(gesture->touch_devices, l, data)
+     {
+        if (!strncmp(data, identifier, strlen(identifier)))
+          {
+             return EINA_TRUE;
+          }
+     }
+   return EINA_FALSE;
+}
+
+static void
+_e_gesture_send_swipe(int fingers, int x, int y, int direction, struct wl_client *client, struct wl_resource *res)
+{
+   enum tizen_gesture_direction dir = 0;
+   Ecore_Event_Mouse_Button *ev_cancel;
+   switch (direction)
+     {
+        case E_GESTURE_DIRECTION_DOWN:
+           dir = TIZEN_GESTURE_DIRECTION_DOWN;
+           break;
+        case E_GESTURE_DIRECTION_LEFT:
+           dir = TIZEN_GESTURE_DIRECTION_LEFT;
+           break;
+        case E_GESTURE_DIRECTION_UP:
+           dir = TIZEN_GESTURE_DIRECTION_UP;
+           break;
+        case E_GESTURE_DIRECTION_RIGHT:
+           dir = TIZEN_GESTURE_DIRECTION_RIGHT;
+           break;
+     }
+
+   ev_cancel = E_NEW(Ecore_Event_Mouse_Button, 1);
+   EINA_SAFETY_ON_NULL_RETURN(ev_cancel);
+
+   ev_cancel->timestamp = (int)(ecore_time_get()*1000);
+   ev_cancel->same_screen = 1;
+
+   ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_CANCEL, ev_cancel, NULL, NULL);
+
+   GTINF("Send swipe gesture (direction: %d) to client: %p\n", dir, client);
+   
+   tizen_gesture_send_swipe(res, fingers, TIZEN_GESTURE_MODE_DONE, x, y, dir);
+   _e_gesture_swipe_cancel();
+
+   gesture->gesture_events.recognized_gesture |= TIZEN_GESTURE_TYPE_SWIPE;
+}
+
+static Eina_Bool
+_e_gesture_process_device_add(void *event)
+{
+   Ecore_Event_Device_Info *ev = event;
+
+   if (ev->caps & EVDEV_SEAT_TOUCH)
+     {
+        gesture->touch_devices = eina_list_append(gesture->touch_devices, ev->identifier);
+        GTINF("%s(%s) device is touch device: add list\n", ev->name, ev->identifier);
+     }
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_e_gesture_process_device_del(void *event)
+{
+   Ecore_Event_Device_Info *ev = event;
+   Eina_List *l, *l_next;
+   char *data;
+
+   if (ev->caps & EVDEV_SEAT_TOUCH)
+     {
+        EINA_LIST_FOREACH_SAFE(gesture->touch_devices, l, l_next, data)
+          {
+             if (!strncmp(data, ev->identifier, strlen(ev->identifier)))
+               {
+                  GTINF("%s(%s) device is touch device: remove list\n", ev->name, ev->identifier);
+                  gesture->touch_devices = eina_list_remove(gesture->touch_devices, data);
+                  E_FREE(data);
+               }
+          }
+     }
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_e_gesture_timer_swipe_start(void *data)
+{
+   E_Gesture_Event_Swipe *swipes = &gesture->gesture_events.swipes;
+   int idx = gesture->gesture_events.num_pressed;
+   int i;
+
+   GTDBG("Swipe start timer is expired. Currently alived swipe fingers: 0x%x\n", swipes->enabled_finger);
+
+   for (i = E_GESTURE_FINGER_MAX; i > idx; i--)
+     {
+        swipes->enabled_finger &= ~(1 << i);
+     }
+   if ((swipes->direction == E_GESTURE_DIRECTION_DOWN && !swipes->fingers[idx].direction[E_GESTURE_DIRECTION_DOWN].client) ||
+       (swipes->direction == E_GESTURE_DIRECTION_LEFT && !swipes->fingers[idx].direction[E_GESTURE_DIRECTION_LEFT].client) ||
+       (swipes->direction == E_GESTURE_DIRECTION_UP && !swipes->fingers[idx].direction[E_GESTURE_DIRECTION_UP].client) ||
+       (swipes->direction == E_GESTURE_DIRECTION_RIGHT && !swipes->fingers[idx].direction[E_GESTURE_DIRECTION_RIGHT].client))
+     {
+        _e_gesture_swipe_cancel();
+     }
+   return ECORE_CALLBACK_CANCEL;
+}
+
+static Eina_Bool
+_e_gesture_timer_swipe_done(void *data)
+{
+   E_Gesture_Event_Swipe *swipes = &gesture->gesture_events.swipes;
+
+   GTDBG("Swipe done timer is expired. Currently alived swipe fingers: 0x%x\n", swipes->enabled_finger);
+
+   _e_gesture_swipe_cancel();
+
+   return ECORE_CALLBACK_CANCEL;
+}
+
+static void
+_e_gesture_process_swipe_down(Ecore_Event_Mouse_Button *ev)
+{
+   E_Gesture_Event_Swipe *swipes = &gesture->gesture_events.swipes;
+   int i;
+   unsigned int idx = ev->multi.device+1;
+
+   if (gesture->gesture_events.num_pressed == 1)
+     {
+        for (i = 0; i < E_GESTURE_FINGER_MAX+1; i++)
+          {
+             if (swipes->fingers[i].enabled)
+               {
+                  swipes->enabled_finger |= (1 << i);
+               }
+          }
+
+        if (ev->y < E_GESTURE_SWIPE_START_AREA)
+          swipes->direction = E_GESTURE_DIRECTION_DOWN;
+        else if (ev->y > e_comp->h - E_GESTURE_SWIPE_START_AREA)
+          swipes->direction = E_GESTURE_DIRECTION_UP;
+        else if (ev->x < E_GESTURE_SWIPE_START_AREA)
+          swipes->direction = E_GESTURE_DIRECTION_RIGHT;
+        else if (ev->x > e_comp->w - E_GESTURE_SWIPE_START_AREA)
+          swipes->direction = E_GESTURE_DIRECTION_LEFT;
+
+        if (swipes->direction != E_GESTURE_DIRECTION_DOWN &&
+       !((swipes->combined_keycode == E_GESTURE_SWIPE_COMBINE_KEY) && swipes->direction == E_GESTURE_DIRECTION_RIGHT))
+          {
+             _e_gesture_swipe_cancel();
+          }
+        else
+          {
+             swipes->fingers[idx].start.x = ev->x;
+             swipes->fingers[idx].start.y = ev->y;
+             swipes->start_timer = ecore_timer_add(E_GESTURE_SWIPE_START_TIME, _e_gesture_timer_swipe_start, NULL);
+             swipes->done_timer = ecore_timer_add(E_GESTURE_SWIPE_DONE_TIME, _e_gesture_timer_swipe_done, NULL);
+          }
+     }
+   else
+     {
+        swipes->enabled_finger &= ~(1 << (gesture->gesture_events.num_pressed - 1));
+        if (swipes->start_timer == NULL)
+          {
+             _e_gesture_swipe_cancel();
+          }
+     }
+}
+
+static void
+_e_gesture_process_swipe_move(Ecore_Event_Mouse_Move *ev)
+{
+   E_Gesture_Event_Swipe *swipes = &gesture->gesture_events.swipes;
+   Coords diff;
+   unsigned int idx = ev->multi.device+1;
+
+   if (!(swipes->enabled_finger & (1 << idx)))
+     return;
+
+   diff.x = ABS(swipes->fingers[idx].start.x - ev->x);
+   diff.y = ABS(swipes->fingers[idx].start.y - ev->y);
+
+   switch(swipes->direction)
+     {
+        case E_GESTURE_DIRECTION_DOWN:
+           if (diff.x > E_GESTURE_SWIPE_DIFF_FAIL)
+             {
+                _e_gesture_swipe_cancel();
+                break;
+             }
+           if (diff.y > E_GESTURE_SWIPE_DIFF_SUCCESS)
+             {
+                _e_gesture_send_swipe(idx, swipes->fingers[idx].start.x, swipes->fingers[idx].start.y, swipes->direction, swipes->fingers[idx].direction[E_GESTURE_DIRECTION_DOWN].client, swipes->fingers[idx].direction[E_GESTURE_DIRECTION_DOWN].res);
+             }
+           break;
+        case E_GESTURE_DIRECTION_LEFT:
+           if (diff.y > E_GESTURE_SWIPE_DIFF_FAIL)
+             {
+                _e_gesture_swipe_cancel();
+                break;
+             }
+           if (diff.x > E_GESTURE_SWIPE_DIFF_SUCCESS)
+             {
+                _e_gesture_send_swipe(idx, swipes->fingers[idx].start.x, swipes->fingers[idx].start.y, swipes->direction, swipes->fingers[idx].direction[E_GESTURE_DIRECTION_LEFT].client, swipes->fingers[idx].direction[E_GESTURE_DIRECTION_LEFT].res);
+             }
+           break;
+        case E_GESTURE_DIRECTION_UP:
+           if (diff.x > E_GESTURE_SWIPE_DIFF_FAIL)
+             {
+                _e_gesture_swipe_cancel();
+                break;
+             }
+           if (diff.y > E_GESTURE_SWIPE_DIFF_SUCCESS)
+             {
+                _e_gesture_send_swipe(idx, swipes->fingers[idx].start.x, swipes->fingers[idx].start.y, swipes->direction, swipes->fingers[idx].direction[E_GESTURE_DIRECTION_UP].client, swipes->fingers[idx].direction[E_GESTURE_DIRECTION_UP].res);
+             }
+           break;
+        case E_GESTURE_DIRECTION_RIGHT:
+           if (diff.y > E_GESTURE_SWIPE_DIFF_FAIL)
+             {
+                _e_gesture_swipe_cancel();
+                break;
+             }
+           if (diff.x > E_GESTURE_SWIPE_DIFF_SUCCESS)
+             {
+                _e_gesture_send_swipe(idx, swipes->fingers[idx].start.x, swipes->fingers[idx].start.y, swipes->direction, swipes->fingers[idx].direction[E_GESTURE_DIRECTION_RIGHT].client, swipes->fingers[idx].direction[E_GESTURE_DIRECTION_RIGHT].res);
+             }
+           break;
+        default:
+           GTWRN("Invalid direction(%d)\n", swipes->direction);
+           break;
+     }
+}
+
+static void
+_e_gesture_process_swipe_up(Ecore_Event_Mouse_Button *ev)
+{
+   _e_gesture_swipe_cancel();
+}
+
+static Eina_Bool
+_e_gesture_process_mouse_button_down(void *event)
+{
+   Ecore_Event_Mouse_Button *ev = event;
+
+   gesture->gesture_events.num_pressed++;
+
+   if (!gesture->grabbed_gesture)
+     {
+        return EINA_TRUE;
+     }
+   if (_e_gesture_is_touch_device(ev->dev_name) == EINA_FALSE)
+     {
+        return EINA_TRUE;
+     }
+   if (ev->multi.device > E_GESTURE_FINGER_MAX)
+     {
+        return EINA_TRUE;
+     }
+
+   if (gesture->gesture_events.num_pressed == 1)
+     {
+        gesture->gesture_events.recognized_gesture = 0x0;
+     }
+
+   if (gesture->gesture_events.recognized_gesture)
+     {
+        return EINA_FALSE;
+     }
+
+   if (gesture->gesture_events.num_pressed == 1)
+     {
+        gesture->gesture_filter = E_GESTURE_TYPE_ALL & ~gesture->grabbed_gesture;
+     }
+
+   if (!(gesture->gesture_filter & TIZEN_GESTURE_TYPE_SWIPE))
+     {
+        _e_gesture_process_swipe_down(ev);
+     }
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_e_gesture_process_mouse_button_up(void *event)
+{
+   Ecore_Event_Mouse_Button *ev = event;
+
+   gesture->gesture_events.num_pressed--;
+
+   if (!gesture->grabbed_gesture)
+     {
+        return EINA_TRUE;
+     }
+   if (_e_gesture_is_touch_device(ev->dev_name) == EINA_FALSE)
+     {
+        return EINA_TRUE;
+     }
+
+   if (gesture->gesture_events.recognized_gesture)
+     {
+        return EINA_FALSE;
+     }
+
+   if (!(gesture->gesture_filter & TIZEN_GESTURE_TYPE_SWIPE))
+     {
+        _e_gesture_process_swipe_up(ev);
+     }
+
+   return EINA_TRUE;
+}
+
+
+static Eina_Bool
+_e_gesture_process_mouse_move(void *event)
+{
+   Ecore_Event_Mouse_Move *ev = event;
+
+   if (!gesture->grabbed_gesture)
+     {
+        return EINA_TRUE;
+     }
+   if (_e_gesture_is_touch_device(ev->dev_name) == EINA_FALSE)
+     {
+        return EINA_TRUE;
+     }
+
+   if (gesture->gesture_events.recognized_gesture)
+     {
+        return EINA_FALSE;
+     }
+
+   if (!(gesture->gesture_filter & TIZEN_GESTURE_TYPE_SWIPE))
+     {
+        _e_gesture_process_swipe_move(ev);
+     }
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_e_gesture_process_key_down(void *event)
+{
+   Ecore_Event_Key *ev = event;
+
+   if (ev->keycode == E_GESTURE_SWIPE_COMBINE_KEY)
+     {
+        gesture->gesture_events.swipes.combined_keycode = E_GESTURE_SWIPE_COMBINE_KEY;
+     }
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_e_gesture_process_key_up(void *event)
+{
+   Ecore_Event_Key *ev = event;
+
+   if (ev->keycode == E_GESTURE_SWIPE_COMBINE_KEY)
+     {
+        gesture->gesture_events.swipes.combined_keycode = 0;
+     }
+
+   return EINA_TRUE;
+}
+
+/* Function for checking the existing grab for a key and sending key event(s) */
+Eina_Bool
+e_gesture_process_events(void *event, int type)
+{
+   Eina_Bool res = EINA_TRUE;
+
+   if (type == ECORE_EVENT_MOUSE_BUTTON_DOWN)
+     res = _e_gesture_process_mouse_button_down(event);
+   else if (type == ECORE_EVENT_MOUSE_BUTTON_UP)
+     res = _e_gesture_process_mouse_button_up(event);
+   else if (type == ECORE_EVENT_MOUSE_MOVE)
+     res = _e_gesture_process_mouse_move(event);
+   else if (type == ECORE_EVENT_KEY_DOWN)
+     res = _e_gesture_process_key_down(event);
+   else if (type == ECORE_EVENT_KEY_UP)
+     res = _e_gesture_process_key_up(event);
+   else if (type == ECORE_EVENT_DEVICE_ADD)
+     res = _e_gesture_process_device_add(event);
+   else if (type == ECORE_EVENT_DEVICE_DEL)
+     res = _e_gesture_process_device_del(event);
+
+   return res;
+}
diff --git a/src/e_mod_main.c b/src/e_mod_main.c
new file mode 100644 (file)
index 0000000..949c45e
--- /dev/null
@@ -0,0 +1,430 @@
+#define E_COMP_WL
+#include "e_mod_main.h"
+#include <string.h>
+
+E_GesturePtr gesture = NULL;
+E_API E_Module_Api e_modapi = { E_MODULE_API_VERSION, "Gesture Module of Window Manager" };
+
+static void *_e_gesture_init(E_Module *m);
+static void _e_gesture_init_handlers(void);
+
+
+static void _e_gesture_wl_client_cb_destroy(struct wl_listener *l, void *data);
+
+static void
+_e_gesture_swipe_set_client_to_list(struct wl_client *client, E_Gesture_Event_Swipe_Finger *fingers, unsigned int direction)
+{
+   if (direction & TIZEN_GESTURE_DIRECTION_DOWN)
+     fingers->direction[E_GESTURE_DIRECTION_DOWN].client = client;
+   if (direction & TIZEN_GESTURE_DIRECTION_LEFT)
+     fingers->direction[E_GESTURE_DIRECTION_LEFT].client = client;
+   if (direction & TIZEN_GESTURE_DIRECTION_UP)
+     fingers->direction[E_GESTURE_DIRECTION_UP].client = client;
+   if (direction & TIZEN_GESTURE_DIRECTION_RIGHT)
+     fingers->direction[E_GESTURE_DIRECTION_RIGHT].client = client;
+}
+
+/* Function for registering wl_client destroy listener */
+int
+e_gesture_add_client_destroy_listener(struct wl_client *client, int mode EINA_UNUSED, int num_of_fingers, unsigned int direction)
+{
+   struct wl_listener *destroy_listener = NULL;
+   Eina_List *l;
+   E_Gesture_Grabbed_Client *grabbed_client, *data;
+
+   EINA_LIST_FOREACH(gesture->grab_client_list, l, data)
+     {
+        if (data->client == client)
+          {
+             _e_gesture_swipe_set_client_to_list(client, &data->swipe_fingers[num_of_fingers], direction);
+
+             return TIZEN_GESTURE_ERROR_NONE;
+          }
+     }
+
+   destroy_listener = E_NEW(struct wl_listener, 1);
+   if (!destroy_listener)
+     {
+        GTERR("Failed to allocate memory for wl_client destroy listener !\n");
+        return TIZEN_GESTURE_ERROR_NO_SYSTEM_RESOURCES;
+     }
+
+   grabbed_client = E_NEW(E_Gesture_Grabbed_Client, 1);
+   if (!grabbed_client)
+     {
+        GTERR("Failed to allocate memory to save client information !\n");
+        return TIZEN_GESTURE_ERROR_NO_SYSTEM_RESOURCES;
+     }
+
+   destroy_listener->notify = _e_gesture_wl_client_cb_destroy;
+   wl_client_add_destroy_listener(client, destroy_listener);
+   grabbed_client->client = client;
+   grabbed_client->destroy_listener = destroy_listener;
+   _e_gesture_swipe_set_client_to_list(client, &grabbed_client->swipe_fingers[num_of_fingers], direction);
+
+   gesture->grab_client_list = eina_list_append(gesture->grab_client_list, grabbed_client);
+
+   return TIZEN_KEYROUTER_ERROR_NONE;
+}
+
+static void
+_e_gesture_remove_client_destroy_listener(struct wl_client *client, unsigned int num_of_fingers, unsigned int direction)
+{
+   Eina_List *l, *l_next;
+   E_Gesture_Grabbed_Client *data;
+   int i;
+
+   EINA_LIST_FOREACH_SAFE(gesture->grab_client_list, l, l_next, data)
+     {
+        if (data->client == client)
+          {
+             _e_gesture_swipe_set_client_to_list(NULL, &data->swipe_fingers[num_of_fingers], direction);
+
+             for (i = 0; i < E_GESTURE_FINGER_MAX+1; i++)
+               {
+                  if (data->swipe_fingers[i].direction[E_GESTURE_DIRECTION_DOWN].client ||
+                      data->swipe_fingers[i].direction[E_GESTURE_DIRECTION_LEFT].client ||
+                      data->swipe_fingers[i].direction[E_GESTURE_DIRECTION_UP].client ||
+                      data->swipe_fingers[i].direction[E_GESTURE_DIRECTION_RIGHT].client)
+                    {
+                       return;
+                    }
+               }
+             wl_list_remove(&data->destroy_listener->link);
+             E_FREE(data->destroy_listener);
+             gesture->grab_client_list = eina_list_remove(gesture->grab_client_list, data);
+             E_FREE(data);
+          }
+     }
+}
+
+static void
+_e_gesture_cb_grab_swipe(struct wl_client *client,
+                   struct wl_resource *resource,
+                   uint32_t num_of_fingers, uint32_t direction)
+{
+   E_Gesture_Event *gev;
+   unsigned int grabbed_direction = 0x0;
+
+   GTINF("client %p is request grab gesture, fingers: %d, direction: 0x%x\n", client, num_of_fingers, direction);
+   if (num_of_fingers > E_GESTURE_FINGER_MAX)
+     {
+        GTWRN("Do not support %d fingers (max: %d)\n", num_of_fingers, E_GESTURE_FINGER_MAX);
+        tizen_gesture_send_grab_swipe_notify(resource, num_of_fingers, direction, TIZEN_GESTURE_ERROR_INVALID_DATA);
+        goto out;
+     }
+
+   gev = &gesture->gesture_events;
+
+   if (direction & TIZEN_GESTURE_DIRECTION_DOWN)
+     {
+        if (gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_DOWN].client)
+           {
+              grabbed_direction |= TIZEN_GESTURE_DIRECTION_DOWN;
+           }
+        else
+           {
+              gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_DOWN].client = client;
+              gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_DOWN].res = resource;
+           }
+     }
+   if (direction & TIZEN_GESTURE_DIRECTION_LEFT)
+     {
+        if (gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_LEFT].client)
+           {
+              grabbed_direction |= TIZEN_GESTURE_DIRECTION_LEFT;
+           }
+        else
+           {
+              gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_LEFT].client = client;
+              gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_LEFT].res = resource;
+           }
+     }
+   if (direction & TIZEN_GESTURE_DIRECTION_UP)
+     {
+        if (gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_UP].client)
+           {
+              grabbed_direction |= TIZEN_GESTURE_DIRECTION_UP;
+           }
+        else
+           {
+              gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_UP].client = client;
+              gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_UP].res = resource;
+           }
+     }
+   if (direction & TIZEN_GESTURE_DIRECTION_RIGHT)
+     {
+        if (gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_RIGHT].client)
+           {
+              grabbed_direction |= TIZEN_GESTURE_DIRECTION_RIGHT;
+           }
+        else
+           {
+              gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_RIGHT].client = client;
+              gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_RIGHT].res = resource;
+           }
+     }
+
+   if (grabbed_direction)
+     tizen_gesture_send_grab_swipe_notify(resource, num_of_fingers, grabbed_direction, TIZEN_GESTURE_ERROR_GRABBED_ALREADY);
+
+   e_gesture_add_client_destroy_listener(client, TIZEN_GESTURE_TYPE_SWIPE, num_of_fingers, direction & ~grabbed_direction);
+   gesture->grabbed_gesture |= TIZEN_GESTURE_TYPE_SWIPE;
+   gev->swipes.fingers[num_of_fingers].enabled = EINA_TRUE;
+
+   if (!grabbed_direction)
+     tizen_gesture_send_grab_swipe_notify(resource, num_of_fingers, direction, TIZEN_GESTURE_ERROR_NONE);
+
+out:
+   return;
+}
+
+static void
+_e_gesture_cb_ungrab_swipe(struct wl_client *client,
+                           struct wl_resource *resouce,
+                           uint32_t num_of_fingers, uint32_t direction)
+{
+   int i, j;
+   E_Gesture_Event *gev;
+   unsigned int ungrabbed_direction = 0x0;
+   int ret = TIZEN_GESTURE_ERROR_NONE;
+
+   GTINF("client %p is request ungrab swipe gesture, fingers: %d, direction: 0x%x, client: %p\n", client, num_of_fingers, direction, gesture->gesture_events.swipes.fingers[0].direction[3].client);
+
+   if (num_of_fingers > E_GESTURE_FINGER_MAX)
+     {
+        GTWRN("Do not support %d fingers (max: %d)\n", num_of_fingers, E_GESTURE_FINGER_MAX);
+        ret = TIZEN_GESTURE_ERROR_INVALID_DATA;
+        goto finish;
+     }
+
+   gev = &gesture->gesture_events;
+
+   if (direction & TIZEN_GESTURE_DIRECTION_DOWN)
+     {
+        if ((gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_DOWN].client) &&
+            (gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_DOWN].client == client))
+           {
+              gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_DOWN].client = NULL;
+              gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_DOWN].res = NULL;
+           }
+        else
+           {
+              ungrabbed_direction |= TIZEN_GESTURE_DIRECTION_DOWN;
+           }
+     }
+   if (direction & TIZEN_GESTURE_DIRECTION_LEFT)
+     {
+        if ((gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_LEFT].client) &&
+            (gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_LEFT].client == client))
+           {
+              gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_LEFT].client = NULL;
+              gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_LEFT].res = NULL;
+           }
+        else
+           {
+              ungrabbed_direction |= TIZEN_GESTURE_DIRECTION_LEFT;
+           }
+     }
+   if (direction & TIZEN_GESTURE_DIRECTION_UP)
+     {
+        if ((gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_UP].client) &&
+            (gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_UP].client == client))
+           {
+              gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_UP].client = NULL;
+              gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_UP].res = NULL;
+           }
+        else
+           {
+              ungrabbed_direction |= TIZEN_GESTURE_DIRECTION_UP;
+           }
+     }
+   if (direction & TIZEN_GESTURE_DIRECTION_RIGHT)
+     {
+        if ((gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_RIGHT].client) &&
+            (gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_RIGHT].client == client))
+           {
+              gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_RIGHT].client = NULL;
+              gev->swipes.fingers[num_of_fingers].direction[E_GESTURE_DIRECTION_RIGHT].res = NULL;
+           }
+        else
+           {
+              ungrabbed_direction |= TIZEN_GESTURE_DIRECTION_RIGHT;
+           }
+     }
+
+   if (direction & ~ungrabbed_direction)
+     {
+        _e_gesture_remove_client_destroy_listener(client, num_of_fingers, direction & ~ungrabbed_direction);
+        for (i = 0; i < E_GESTURE_FINGER_MAX+1; i++)
+          {
+             for (j = 0; j < E_GESTURE_DIRECTION_MAX+1; j++)
+               {
+                  if (gev->swipes.fingers[i].direction[j].client)
+                    {
+                       goto finish;
+                    }
+               }
+             gev->swipes.fingers[i].enabled = EINA_FALSE;
+          }
+        gesture->grabbed_gesture &= ~TIZEN_GESTURE_TYPE_SWIPE;
+     }
+
+finish:
+   tizen_gesture_send_grab_swipe_notify(resouce, num_of_fingers, direction, ret);
+   return;
+}
+
+static const struct tizen_gesture_interface _e_gesture_implementation = {
+   _e_gesture_cb_grab_swipe,
+   _e_gesture_cb_ungrab_swipe
+};
+
+/* tizen_gesture global object destroy function */
+static void
+_e_gesture_cb_destory(struct wl_resource *resource)
+{
+   /* TODO : destroy resources if exist */
+}
+
+/* tizen_keyrouter global object bind function */
+static void
+_e_gesture_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
+{
+   E_GesturePtr gesture_instance = data;
+   struct wl_resource *resource;
+
+   resource = wl_resource_create(client, &tizen_gesture_interface, MIN(version, 1), id);
+
+   GTDBG("wl_resource_create(...,tizen_gesture_interface,...)\n");
+
+   if (!resource)
+     {
+        GTERR("Failed to create resource ! (version :%d, id:%d)\n", version, id);
+        wl_client_post_no_memory(client);
+        return;
+     }
+
+   wl_resource_set_implementation(resource, &_e_gesture_implementation, gesture_instance, _e_gesture_cb_destory);
+}
+
+
+
+static Eina_Bool
+_e_gesture_event_filter(void *data, void *loop_data EINA_UNUSED, int type, void *event)
+{
+   (void) data;
+
+   return e_gesture_process_events(event, type);
+}
+
+static void
+_e_gesture_init_handlers(void)
+{
+   gesture->ef_handler = ecore_event_filter_add(NULL, _e_gesture_event_filter, NULL, NULL);
+}
+
+static void *
+_e_gesture_init(E_Module *m)
+{
+   gesture = E_NEW(E_Gesture, 1);
+
+   if (!gesture)
+     {
+        GTERR("Failed to allocate memory for gesture !\n");
+        return NULL;
+     }
+
+   if (!e_comp)
+     {
+        GTERR("Failed to initialize gesture module ! (e_comp == NULL)\n");
+        goto err;
+     }
+
+   /* Add filtering mechanism */
+   _e_gesture_init_handlers();
+   gesture->global = wl_global_create(e_comp_wl->wl.disp, &tizen_gesture_interface, 1, gesture, _e_gesture_cb_bind);
+   if (!gesture->global)
+     {
+        GTERR("Failed to create global !\n");
+        goto err;
+     }
+
+   gesture->gesture_filter = E_GESTURE_TYPE_MAX;
+
+   return m;
+
+err:
+   if (gesture && gesture->ef_handler) ecore_event_filter_del(gesture->ef_handler);
+   if (gesture) E_FREE(gesture);
+
+   return NULL;
+}
+
+E_API void *
+e_modapi_init(E_Module *m)
+{
+   return _e_gesture_init(m);
+}
+
+E_API int
+e_modapi_shutdown(E_Module *m)
+{
+   return 1;
+}
+
+E_API int
+e_modapi_save(E_Module *m)
+{
+   /* Save something to be kept */
+   return 1;
+}
+
+static void
+_e_gesture_wl_client_cb_destroy(struct wl_listener *l, void *data)
+{
+   struct wl_client *client = data;
+   int i, j;
+   Eina_List *l_list, *l_next;
+   E_Gesture_Grabbed_Client *client_data;
+
+   if (gesture->grabbed_gesture & TIZEN_GESTURE_TYPE_SWIPE)
+     {
+        for (i = 0; i < E_GESTURE_FINGER_MAX+1; i++)
+          {
+             for (j = 0; j < E_GESTURE_DIRECTION_MAX+1; j++)
+               {
+                  if (gesture->gesture_events.swipes.fingers[i].direction[j].client == client)
+                    {
+                       gesture->gesture_events.swipes.fingers[i].direction[j].client = NULL;
+                       gesture->gesture_events.swipes.fingers[i].direction[j].res = NULL;
+                    }
+               }
+          }
+
+        for (i = 0; i < E_GESTURE_FINGER_MAX+1; i++)
+          {
+             for (j = 0; j < E_GESTURE_DIRECTION_MAX+1; j++)
+               {
+                  if (gesture->gesture_events.swipes.fingers[i].direction[j].client)
+                    {
+                       goto out;
+                    }
+               }
+             gesture->gesture_events.swipes.fingers[i].enabled = EINA_FALSE;
+          }
+        gesture->grabbed_gesture &= ~TIZEN_GESTURE_TYPE_SWIPE;
+     }
+
+out:
+   E_FREE(l);
+   l = NULL;
+   EINA_LIST_FOREACH_SAFE(gesture->grab_client_list, l_list, l_next, client_data)
+     {
+        if (client_data->client == client)
+          {
+             gesture->grab_client_list = eina_list_remove(gesture->grab_client_list, client_data);
+             E_FREE(client_data);
+          }
+     }
+}
diff --git a/src/e_mod_main.h b/src/e_mod_main.h
new file mode 100644 (file)
index 0000000..fddbf43
--- /dev/null
@@ -0,0 +1,124 @@
+#ifndef E_MOD_MAIN_H
+#define E_MOD_MAIN_H
+
+#include <tizen-extension-server-protocol.h>
+#include <e.h>
+#include <Ecore_Drm.h>
+
+#define GTERR(msg, ARG...) ERR("[tizen_gesture][%s:%d] "msg, __FUNCTION__, __LINE__, ##ARG)
+#define GTWRN(msg, ARG...) WRN("[tizen_gesture][%s:%d] "msg, __FUNCTION__, __LINE__, ##ARG)
+#define GTINF(msg, ARG...) INF("[tizen_gesture][%s:%d] "msg, __FUNCTION__, __LINE__, ##ARG)
+#define GTDBG(msg, ARG...) DBG("[tizen_gesture][%s:%d] "msg, __FUNCTION__, __LINE__, ##ARG)
+
+#define E_GESTURE_FINGER_MAX 3
+#define E_GESTURE_TYPE_MAX TIZEN_GESTURE_TYPE_SWIPE+1
+#define E_GESTURE_TYPE_ALL TIZEN_GESTURE_TYPE_SWIPE
+
+/* FIX ME: Set values in contiguration file, do not use definition */
+#define E_GESTURE_SWIPE_DONE_TIME 0.5
+#define E_GESTURE_SWIPE_START_TIME 0.01
+#define E_GESTURE_SWIPE_START_AREA 50
+#define E_GESTURE_SWIPE_DIFF_FAIL 100
+#define E_GESTURE_SWIPE_DIFF_SUCCESS 300
+#define E_GESTURE_SWIPE_COMBINE_KEY 124
+
+#define ABS(x) ((x)>0)?(x):-(x)
+
+typedef struct _E_Gesture E_Gesture;
+typedef struct _E_Gesture* E_GesturePtr;
+typedef struct _E_Gesture_Event E_Gesture_Event;
+typedef struct _E_Gesture_Event_Swipe E_Gesture_Event_Swipe;
+typedef struct _E_Gesture_Event_Swipe_Finger E_Gesture_Event_Swipe_Finger;
+typedef struct _E_Gesture_Event_Swipe_Finger_Direction E_Gesture_Event_Swipe_Finger_Direction;
+typedef struct _E_Gesture_Grabbed_Client E_Gesture_Grabbed_Client;
+
+typedef struct _Coords Coords;
+
+typedef enum _E_Gesture_Direction E_Gesture_Direction;
+
+extern E_GesturePtr gesture;
+
+#define E_GESTURE_DIRECTION_MAX 4
+enum _E_Gesture_Direction
+{
+   E_GESTURE_DIRECTION_NONE,
+   E_GESTURE_DIRECTION_DOWN, //Start point is North
+   E_GESTURE_DIRECTION_LEFT, // Start point is East
+   E_GESTURE_DIRECTION_UP, // Start point is South
+   E_GESTURE_DIRECTION_RIGHT // Start point is West
+};
+
+struct _Coords
+{
+   int x, y;
+};
+
+struct _E_Gesture_Event_Swipe_Finger_Direction
+{
+   struct wl_client *client;
+   struct wl_resource *res;
+};
+
+struct _E_Gesture_Event_Swipe_Finger
+{
+   Coords start;
+   Eina_Bool enabled;
+   E_Gesture_Event_Swipe_Finger_Direction direction[E_GESTURE_DIRECTION_MAX+1];
+};
+
+struct _E_Gesture_Grabbed_Client
+{
+   struct wl_client *client;
+   struct wl_listener *destroy_listener;
+
+   E_Gesture_Event_Swipe_Finger swipe_fingers[E_GESTURE_FINGER_MAX+1];
+};
+
+
+struct _E_Gesture_Event_Swipe
+{
+   E_Gesture_Event_Swipe_Finger fingers[E_GESTURE_FINGER_MAX+1];
+
+   E_Gesture_Direction direction;
+
+   unsigned int combined_keycode;
+
+   unsigned int enabled_finger;
+   Ecore_Timer *start_timer;
+   Ecore_Timer *done_timer;
+};
+
+struct _E_Gesture_Event
+{
+   E_Gesture_Event_Swipe swipes;
+
+   int num_pressed;
+   Eina_Bool recognized_gesture;
+};
+
+struct _E_Gesture
+{
+   struct wl_global *global;
+
+   Ecore_Event_Filter *ef_handler;
+   Eina_List *handlers;
+   Eina_List *grab_client_list;
+
+   Eina_List *touch_devices;
+
+   unsigned int grabbed_gesture;
+   E_Gesture_Event gesture_events;
+
+   unsigned int gesture_filter;
+   unsigned int gesture_recognized;
+};
+
+/* E Module */
+E_API extern E_Module_Api e_modapi;
+E_API void *e_modapi_init(E_Module *m);
+E_API int   e_modapi_shutdown(E_Module *m);
+E_API int   e_modapi_save(E_Module *m);
+
+Eina_Bool e_gesture_process_events(void *event, int type);
+int e_gesture_type_convert(uint32_t type);
+#endif