From b51eb3a2087f44c85e1eea985934b02d921c385e Mon Sep 17 00:00:00 2001 From: JengHyun Kang Date: Fri, 11 Mar 2016 15:00:02 +0900 Subject: [PATCH 2/6] Import initial codes Change-Id: I3314517fa6ff6d2f9a65e6dfcef0c161b0e9c788 --- .gitignore | 0 COPYING | 25 +++ Makefile.am | 8 + autogen.sh | 16 ++ configure.ac | 143 ++++++++++++ packaging/e-mod-tizen-gesture.spec | 53 +++++ src/Makefile.am | 14 ++ src/e_mod_gesture_events.c | 418 +++++++++++++++++++++++++++++++++++ src/e_mod_main.c | 430 +++++++++++++++++++++++++++++++++++++ src/e_mod_main.h | 124 +++++++++++ 10 files changed, 1231 insertions(+) create mode 100644 .gitignore create mode 100644 COPYING create mode 100644 Makefile.am create mode 100755 autogen.sh create mode 100644 configure.ac create mode 100644 packaging/e-mod-tizen-gesture.spec create mode 100644 src/Makefile.am create mode 100644 src/e_mod_gesture_events.c create mode 100644 src/e_mod_main.c create mode 100644 src/e_mod_main.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/COPYING b/COPYING new file mode 100644 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 index 0000000..a30d363 --- /dev/null +++ b/Makefile.am @@ -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 index 0000000..1ac867a --- /dev/null +++ b/autogen.sh @@ -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 index 0000000..c1e5180 --- /dev/null +++ b/configure.ac @@ -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 index 0000000..c443906 --- /dev/null +++ b/packaging/e-mod-tizen-gesture.spec @@ -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 index 0000000..59ac035 --- /dev/null +++ b/src/Makefile.am @@ -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 index 0000000..fe73bf3 --- /dev/null +++ b/src/e_mod_gesture_events.c @@ -0,0 +1,418 @@ +#define E_COMP_WL +#include "e_mod_main.h" +#include + +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 index 0000000..949c45e --- /dev/null +++ b/src/e_mod_main.c @@ -0,0 +1,430 @@ +#define E_COMP_WL +#include "e_mod_main.h" +#include + +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 index 0000000..fddbf43 --- /dev/null +++ b/src/e_mod_main.h @@ -0,0 +1,124 @@ +#ifndef E_MOD_MAIN_H +#define E_MOD_MAIN_H + +#include +#include +#include + +#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 -- 2.7.4 From 2ed1bc2ad83f02ea0e5759c630f670ba0745f498 Mon Sep 17 00:00:00 2001 From: Duna Oh Date: Wed, 6 Apr 2016 18:51:23 +0900 Subject: [PATCH 3/6] events: handle Ecore_Device Signed-off-by: Duna Oh Change-Id: Ia11d6c8eeec1cf1efaa8c3b49f8d45ae38aedd57 --- src/e_mod_gesture_events.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/e_mod_gesture_events.c b/src/e_mod_gesture_events.c index fe73bf3..72231e5 100644 --- a/src/e_mod_gesture_events.c +++ b/src/e_mod_gesture_events.c @@ -25,10 +25,16 @@ _e_gesture_swipe_cancel(void) } static Eina_Bool -_e_gesture_is_touch_device(const char *identifier) +_e_gesture_is_touch_device(Ecore_Device *dev) { Eina_List *l; char *data; + const char *identifier; + + EINA_SAFETY_ON_NULL_RETURN_VAL(dev, EINA_FALSE); + + identifier = ecore_device_identifier_get(dev); + if (!identifier) return EINA_FALSE; EINA_LIST_FOREACH(gesture->touch_devices, l, data) { @@ -82,7 +88,7 @@ _e_gesture_process_device_add(void *event) { Ecore_Event_Device_Info *ev = event; - if (ev->caps & EVDEV_SEAT_TOUCH) + if (ev->clas == ECORE_DEVICE_CLASS_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); @@ -97,7 +103,7 @@ _e_gesture_process_device_del(void *event) Eina_List *l, *l_next; char *data; - if (ev->caps & EVDEV_SEAT_TOUCH) + if (ev->clas == ECORE_DEVICE_CLASS_TOUCH) { EINA_LIST_FOREACH_SAFE(gesture->touch_devices, l, l_next, data) { @@ -278,7 +284,7 @@ _e_gesture_process_mouse_button_down(void *event) { return EINA_TRUE; } - if (_e_gesture_is_touch_device(ev->dev_name) == EINA_FALSE) + if (_e_gesture_is_touch_device(ev->dev) == EINA_FALSE) { return EINA_TRUE; } @@ -321,7 +327,7 @@ _e_gesture_process_mouse_button_up(void *event) { return EINA_TRUE; } - if (_e_gesture_is_touch_device(ev->dev_name) == EINA_FALSE) + if (_e_gesture_is_touch_device(ev->dev) == EINA_FALSE) { return EINA_TRUE; } @@ -349,7 +355,7 @@ _e_gesture_process_mouse_move(void *event) { return EINA_TRUE; } - if (_e_gesture_is_touch_device(ev->dev_name) == EINA_FALSE) + if (_e_gesture_is_touch_device(ev->dev) == EINA_FALSE) { return EINA_TRUE; } -- 2.7.4 From a0dd6ef2377db0093323a975e944b413a8175355 Mon Sep 17 00:00:00 2001 From: JengHyun Kang Date: Thu, 7 Apr 2016 14:29:02 +0900 Subject: [PATCH 4/6] Enable default single finger gesture - Convert single finger gesture to Back Key - This will be changed to configuration Change-Id: I779d50c9fac6293704f88f81d79b6dd47c2b3d34 --- src/Makefile.am | 3 +- src/e_mod_gesture_device.c | 164 +++++++++++++++++++++++++++++++++++++++++++++ src/e_mod_gesture_events.c | 94 ++++++++++++++------------ src/e_mod_main.c | 11 +++ src/e_mod_main.h | 26 ++++++- 5 files changed, 251 insertions(+), 47 deletions(-) create mode 100644 src/e_mod_gesture_device.c diff --git a/src/Makefile.am b/src/Makefile.am index 59ac035..563afca 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -7,7 +7,8 @@ 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 + e_mod_gesture_events.c \ + e_mod_gesture_device.c module_la_CFLAGS = @ENLIGHTENMENT_CFLAGS@ @WAYLAND_CFLAGS@ -DHAVE_WAYLAND_ONLY module_la_LDFLAGS = -module -avoid-version @WAYLAND_LIBS@ @ENLIGHTENMENT_LIBS@ diff --git a/src/e_mod_gesture_device.c b/src/e_mod_gesture_device.c new file mode 100644 index 0000000..38aa14b --- /dev/null +++ b/src/e_mod_gesture_device.c @@ -0,0 +1,164 @@ +#define E_COMP_WL +#include "e_mod_main.h" +#include +#include + +static void +_e_gesture_device_keydev_create(void) +{ + int uinp_fd = -1; + struct uinput_user_dev uinp; + int ret = 0; + + uinp_fd = open("/dev/uinput", O_WRONLY | O_NDELAY); + if ( uinp_fd < 0) + { + GTWRN("Failed to open /dev/uinput: (%d)\n", uinp_fd); + return; + } + + memset(&uinp, 0, sizeof(struct uinput_user_dev)); + strncpy(uinp.name, E_GESTURE_KEYBOARD_NAME, UINPUT_MAX_NAME_SIZE); + uinp.id.version = 4; + uinp.id.bustype = BUS_USB; + + ioctl(uinp_fd, UI_SET_EVBIT, EV_KEY); + ioctl(uinp_fd, UI_SET_EVBIT, EV_SYN); + ioctl(uinp_fd, UI_SET_EVBIT, EV_MSC); + + ioctl(uinp_fd, UI_SET_KEYBIT, KEY_BACK); + + ret = write(uinp_fd, &uinp, sizeof(struct uinput_user_dev)); + if (ret < 0) + { + GTWRN("Failed to write UINPUT device\n"); + close(uinp_fd); + return; + } + if (ioctl(uinp_fd, UI_DEV_CREATE)) + { + GTWRN("Unable to create UINPUT device\n"); + close(uinp_fd); + return; + } + + gesture->device.uinp_fd = uinp_fd; +} + +void +e_gesture_device_keydev_set(char *option) +{ + if (!option) + { + _e_gesture_device_keydev_create(); + gesture->device.kbd_name = strdup(E_GESTURE_KEYBOARD_NAME); + } + else if (strncmp(option, "Any", sizeof("Any"))) + { + gesture->device.kbd_name = strdup(option); + } +} + +Ecore_Device * +_e_gesture_device_ecore_device_get(char *path, unsigned int clas) +{ + const Eina_List *dev_list = NULL; + const Eina_List *l; + Ecore_Device *dev = NULL; + const char *identifier; + + if (!path) return NULL; + + dev_list = ecore_device_list(); + if (!dev_list) return NULL; + EINA_LIST_FOREACH(dev_list, l, dev) + { + if (!dev) continue; + GTINF("dev: %s\n", ecore_device_name_get(dev)); + identifier = ecore_device_identifier_get(dev); + if (!identifier) continue; + if ((ecore_device_class_get(dev) == clas) && !(strcmp(identifier, path))) + return dev; + } + + return NULL; +} + +Eina_Bool +e_gesture_device_add(Ecore_Event_Device_Info *ev) +{ + if (ev->clas == ECORE_DEVICE_CLASS_TOUCH) + { + gesture->device.touch_devices = eina_list_append(gesture->device.touch_devices, ev->identifier); + GTINF("%s(%s) device is touch device: add list\n", ev->name, ev->identifier); + } + if ((!gesture->device.kbd_identifier) && + (ev->clas == ECORE_DEVICE_CLASS_KEYBOARD)) + { + if (gesture->device.kbd_name) + { + if (!strncmp(ev->name, gesture->device.kbd_name, strlen(gesture->device.kbd_name))) + { + GTINF("%s(%s) device is key generated device in gesture\n", ev->name, ev->identifier); + gesture->device.kbd_identifier = strdup(ev->identifier); + gesture->device.kbd_device = _e_gesture_device_ecore_device_get(gesture->device.kbd_identifier, ECORE_DEVICE_CLASS_KEYBOARD); + } + } + else + { + GTINF("%s(%s) device is key generated device in gesture\n", ev->name, ev->identifier); + gesture->device.kbd_name = strdup(ev->name); + gesture->device.kbd_identifier = strdup(ev->identifier); + gesture->device.kbd_device = _e_gesture_device_ecore_device_get(gesture->device.kbd_identifier, ECORE_DEVICE_CLASS_KEYBOARD); + } + } + return EINA_TRUE; +} + +Eina_Bool +e_gesture_device_del(Ecore_Event_Device_Info *ev) +{ + Eina_List *l, *l_next; + char *data; + + if (ev->clas == ECORE_DEVICE_CLASS_TOUCH) + { + EINA_LIST_FOREACH_SAFE(gesture->device.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->device.touch_devices = eina_list_remove(gesture->device.touch_devices, data); + E_FREE(data); + } + } + } + if ((gesture->device.kbd_identifier) && + (ev->clas == ECORE_DEVICE_CLASS_KEYBOARD)) + { + if (!strncmp(ev->name, gesture->device.kbd_name, strlen(gesture->device.kbd_name))) + { + GTWRN("Gesture keyboard device(%s) is disconnected. Gesture cannot create key events\n", gesture->device.kbd_name); + E_FREE(gesture->device.kbd_identifier); + E_FREE(gesture->device.kbd_name); + } + } + return EINA_TRUE; +} + +Eina_Bool +e_gesture_is_touch_device(const Ecore_Device *dev) +{ + if (ecore_device_class_get(dev) == ECORE_DEVICE_CLASS_TOUCH) + return EINA_TRUE; + + return EINA_FALSE; +} + +void +e_gesture_device_shutdown(void) +{ + E_FREE(gesture->device.kbd_identifier); + E_FREE(gesture->device.kbd_name); + gesture->device.touch_devices = eina_list_free(gesture->device.touch_devices); +} diff --git a/src/e_mod_gesture_events.c b/src/e_mod_gesture_events.c index 72231e5..5492964 100644 --- a/src/e_mod_gesture_events.c +++ b/src/e_mod_gesture_events.c @@ -24,26 +24,44 @@ _e_gesture_swipe_cancel(void) gesture->gesture_filter |= TIZEN_GESTURE_TYPE_SWIPE; } -static Eina_Bool -_e_gesture_is_touch_device(Ecore_Device *dev) +static void +_e_gesture_keyevent_free(void *data EINA_UNUSED, void *ev) { - Eina_List *l; - char *data; - const char *identifier; + Ecore_Event_Key *e = ev; - EINA_SAFETY_ON_NULL_RETURN_VAL(dev, EINA_FALSE); + eina_stringshare_del(e->keyname); + eina_stringshare_del(e->key); + eina_stringshare_del(e->compose); - identifier = ecore_device_identifier_get(dev); - if (!identifier) return EINA_FALSE; + E_FREE(e); +} - EINA_LIST_FOREACH(gesture->touch_devices, l, data) - { - if (!strncmp(data, identifier, strlen(identifier))) - { - return EINA_TRUE; - } - } - return EINA_FALSE; +/* Optional: This function is currently used to generate back key. + * But how about change this function to generate every key? + * _e_gesture_send_key(char *keyname, Eina_Bool pressed) + */ +static void +_e_gesture_send_back_key(Eina_Bool pressed) +{ + Ecore_Event_Key *ev; + + EINA_SAFETY_ON_NULL_RETURN(e_comp_wl->xkb.keymap); + + ev = E_NEW(Ecore_Event_Key, 1); + EINA_SAFETY_ON_NULL_RETURN(ev); + + ev->key = (char *)eina_stringshare_add("XF86Back"); + ev->keyname = (char *)eina_stringshare_add(ev->key); + ev->compose = (char *)eina_stringshare_add(ev->key); + ev->timestamp = (int)(ecore_time_get()*1000); + ev->same_screen = 1; + ev->keycode = E_GESTURE_SWIPE_BACK_KEY; + ev->dev = gesture->device.kbd_device; + + if (pressed) + ecore_event_add(ECORE_EVENT_KEY_DOWN, ev, _e_gesture_keyevent_free, NULL); + else + ecore_event_add(ECORE_EVENT_KEY_UP, ev, _e_gesture_keyevent_free, NULL); } static void @@ -51,6 +69,7 @@ _e_gesture_send_swipe(int fingers, int x, int y, int direction, struct wl_client { enum tizen_gesture_direction dir = 0; Ecore_Event_Mouse_Button *ev_cancel; + switch (direction) { case E_GESTURE_DIRECTION_DOWN: @@ -76,46 +95,33 @@ _e_gesture_send_swipe(int fingers, int x, int y, int direction, struct wl_client ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_CANCEL, ev_cancel, NULL, NULL); GTINF("Send swipe gesture (direction: %d) to client: %p\n", dir, client); + + if (E_GESTURE_SWIPE_BACK_DEFAULT_ENABLE && + direction == E_GESTURE_DIRECTION_DOWN) + { + _e_gesture_send_back_key(EINA_TRUE); + _e_gesture_send_back_key(EINA_FALSE); + goto finish; + } tizen_gesture_send_swipe(res, fingers, TIZEN_GESTURE_MODE_DONE, x, y, dir); _e_gesture_swipe_cancel(); +finish: + _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->clas == ECORE_DEVICE_CLASS_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; + return e_gesture_device_add(event); } 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->clas == ECORE_DEVICE_CLASS_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; + return e_gesture_device_del(event); } static Eina_Bool @@ -284,7 +290,7 @@ _e_gesture_process_mouse_button_down(void *event) { return EINA_TRUE; } - if (_e_gesture_is_touch_device(ev->dev) == EINA_FALSE) + if (e_gesture_is_touch_device(ev->dev) == EINA_FALSE) { return EINA_TRUE; } @@ -327,7 +333,7 @@ _e_gesture_process_mouse_button_up(void *event) { return EINA_TRUE; } - if (_e_gesture_is_touch_device(ev->dev) == EINA_FALSE) + if (e_gesture_is_touch_device(ev->dev) == EINA_FALSE) { return EINA_TRUE; } @@ -355,7 +361,7 @@ _e_gesture_process_mouse_move(void *event) { return EINA_TRUE; } - if (_e_gesture_is_touch_device(ev->dev) == EINA_FALSE) + if (e_gesture_is_touch_device(ev->dev) == EINA_FALSE) { return EINA_TRUE; } diff --git a/src/e_mod_main.c b/src/e_mod_main.c index 949c45e..529a02f 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -352,6 +352,16 @@ _e_gesture_init(E_Module *m) gesture->gesture_filter = E_GESTURE_TYPE_MAX; + if (E_GESTURE_SWIPE_BACK_DEFAULT_ENABLE) + { + gesture->grabbed_gesture |= TIZEN_GESTURE_TYPE_SWIPE; + gesture->gesture_events.swipes.fingers[1].enabled = EINA_TRUE; + gesture->gesture_events.swipes.fingers[1].direction[E_GESTURE_DIRECTION_DOWN].client = (void *)0x1; + gesture->gesture_events.swipes.fingers[1].direction[E_GESTURE_DIRECTION_DOWN].res = (void *)0x1; + } + + e_gesture_device_keydev_set(E_GESTURE_KEYBOARD_DEVICE); + return m; err: @@ -370,6 +380,7 @@ e_modapi_init(E_Module *m) E_API int e_modapi_shutdown(E_Module *m) { + e_gesture_device_shutdown(); return 1; } diff --git a/src/e_mod_main.h b/src/e_mod_main.h index fddbf43..6fca7ef 100644 --- a/src/e_mod_main.h +++ b/src/e_mod_main.h @@ -1,8 +1,8 @@ #ifndef E_MOD_MAIN_H #define E_MOD_MAIN_H -#include #include +#include #include #define GTERR(msg, ARG...) ERR("[tizen_gesture][%s:%d] "msg, __FUNCTION__, __LINE__, ##ARG) @@ -13,14 +13,20 @@ #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 +#define E_GESTURE_KEYBOARD_NAME "Gesture Keyboard" /* FIX ME: Set values in contiguration file, do not use definition */ +#define E_GESTURE_KEYBOARD_DEVICE "Any" + #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 +/* FIX ME: Key code will be get from keymap */ #define E_GESTURE_SWIPE_COMBINE_KEY 124 +#define E_GESTURE_SWIPE_BACK_KEY 166 +#define E_GESTURE_SWIPE_BACK_DEFAULT_ENABLE EINA_TRUE #define ABS(x) ((x)>0)?(x):-(x) @@ -82,6 +88,7 @@ struct _E_Gesture_Event_Swipe E_Gesture_Direction direction; unsigned int combined_keycode; + unsigned int back_keycode; unsigned int enabled_finger; Ecore_Timer *start_timer; @@ -104,7 +111,14 @@ struct _E_Gesture Eina_List *handlers; Eina_List *grab_client_list; - Eina_List *touch_devices; + struct + { + Eina_List *touch_devices; + int uinp_fd; + char *kbd_identifier; + char *kbd_name; + Ecore_Device *kbd_device; + }device; unsigned int grabbed_gesture; E_Gesture_Event gesture_events; @@ -121,4 +135,12 @@ 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); + +/* Device control */ +void e_gesture_device_shutdown(void); +Eina_Bool e_gesture_device_add(Ecore_Event_Device_Info *ev); +Eina_Bool e_gesture_device_del(Ecore_Event_Device_Info *ev); +Eina_Bool e_gesture_is_touch_device(const Ecore_Device *dev); +void e_gesture_device_keydev_set(char *option); + #endif -- 2.7.4 From 25905450a1935f007eb3a255482489466921529a Mon Sep 17 00:00:00 2001 From: JengHyun Kang Date: Wed, 20 Apr 2016 14:17:39 +0900 Subject: [PATCH 5/6] Enable/disable gesture and swipe back key by config file and aux hint Change-Id: Idadfafe8ec3f44bb6b648d7dd357154368a5e6ff --- src/Makefile.am | 3 +- src/e_mod_gesture_conf.c | 61 ++++++++++++++++++++++++++++++++++++++ src/e_mod_gesture_events.c | 46 +++++++++++++++------------- src/e_mod_main.c | 74 ++++++++++++++++++++++++++++++++++++++++++---- src/e_mod_main.h | 31 +++++++++++++++++++ 5 files changed, 188 insertions(+), 27 deletions(-) create mode 100644 src/e_mod_gesture_conf.c diff --git a/src/Makefile.am b/src/Makefile.am index 563afca..75ef645 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,7 +8,8 @@ pkg_LTLIBRARIES = module.la module_la_SOURCES = e_mod_main.c \ e_mod_main.h \ e_mod_gesture_events.c \ - e_mod_gesture_device.c + e_mod_gesture_device.c \ + e_mod_gesture_conf.c module_la_CFLAGS = @ENLIGHTENMENT_CFLAGS@ @WAYLAND_CFLAGS@ -DHAVE_WAYLAND_ONLY module_la_LDFLAGS = -module -avoid-version @WAYLAND_LIBS@ @ENLIGHTENMENT_LIBS@ diff --git a/src/e_mod_gesture_conf.c b/src/e_mod_gesture_conf.c new file mode 100644 index 0000000..beb0422 --- /dev/null +++ b/src/e_mod_gesture_conf.c @@ -0,0 +1,61 @@ +#define E_COMP_WL +#include "e_mod_main.h" + +void +_e_gesture_conf_value_check(E_Gesture_Config_Data* gconfig) +{ + E_Gesture_Conf_Edd *conf; + if (!gconfig->conf) gconfig->conf = E_NEW(E_Gesture_Conf_Edd, 1); + EINA_SAFETY_ON_NULL_RETURN(gconfig->conf); + + conf = gconfig->conf; + if (!conf->key_device_name) conf->key_device_name = strdup(E_GESTURE_KEYBOARD_DEVICE); + if (conf->swipe.time_done <= 0.0) conf->swipe.time_done = E_GESTURE_SWIPE_DONE_TIME; + if (conf->swipe.time_begin <= 0.0) conf->swipe.time_begin = E_GESTURE_SWIPE_START_TIME; + if (conf->swipe.area_offset <= 0) conf->swipe.area_offset = E_GESTURE_SWIPE_START_AREA; + if (conf->swipe.min_length <= 0) conf->swipe.min_length = E_GESTURE_SWIPE_DIFF_FAIL; + if (conf->swipe.max_length <= 0) conf->swipe.max_length = E_GESTURE_SWIPE_DIFF_SUCCESS; + if (conf->swipe.compose_key <= 0) conf->swipe.compose_key = E_GESTURE_SWIPE_COMBINE_KEY; + if (conf->swipe.back_key <= 0) conf->swipe.back_key = E_GESTURE_SWIPE_BACK_KEY; +} + +void +e_gesture_conf_init(E_Gesture_Config_Data *gconfig) +{ + gconfig->conf_edd = E_CONFIG_DD_NEW("Gesture_Config", E_Gesture_Conf_Edd); +#undef T +#undef D +#define T E_Gesture_Conf_Edd +#define D gconfig->conf_edd + E_CONFIG_VAL(D, T, key_device_name, STR); + E_CONFIG_VAL(D, T, swipe.time_done, DOUBLE); + E_CONFIG_VAL(D, T, swipe.time_begin, DOUBLE); + E_CONFIG_VAL(D, T, swipe.area_offset, INT); + E_CONFIG_VAL(D, T, swipe.min_length, INT); + E_CONFIG_VAL(D, T, swipe.max_length, INT); + E_CONFIG_VAL(D, T, swipe.compose_key, INT); + E_CONFIG_VAL(D, T, swipe.back_key, INT); + E_CONFIG_VAL(D, T, swipe.default_enable_back, CHAR); + +#undef T +#undef D + gconfig->conf = e_config_domain_load("module.gesture", gconfig->conf_edd); + + if (!gconfig->conf) + { + GTWRN("Failed to find module.keyrouter config file.\n"); + } + _e_gesture_conf_value_check(gconfig); +} + +void +e_gesture_conf_deinit(E_Gesture_Config_Data *gconfig) +{ + if (gconfig->conf) + { + E_FREE(gconfig->conf->key_device_name); + E_FREE(gconfig->conf); + } + E_CONFIG_DD_FREE(gconfig->conf_edd); + E_FREE(gconfig); +} diff --git a/src/e_mod_gesture_events.c b/src/e_mod_gesture_events.c index 5492964..b0548b8 100644 --- a/src/e_mod_gesture_events.c +++ b/src/e_mod_gesture_events.c @@ -44,6 +44,7 @@ static void _e_gesture_send_back_key(Eina_Bool pressed) { Ecore_Event_Key *ev; + E_Gesture_Conf_Edd *conf = gesture->config->conf; EINA_SAFETY_ON_NULL_RETURN(e_comp_wl->xkb.keymap); @@ -55,7 +56,7 @@ _e_gesture_send_back_key(Eina_Bool pressed) ev->compose = (char *)eina_stringshare_add(ev->key); ev->timestamp = (int)(ecore_time_get()*1000); ev->same_screen = 1; - ev->keycode = E_GESTURE_SWIPE_BACK_KEY; + ev->keycode = conf->swipe.back_key; ev->dev = gesture->device.kbd_device; if (pressed) @@ -69,6 +70,7 @@ _e_gesture_send_swipe(int fingers, int x, int y, int direction, struct wl_client { enum tizen_gesture_direction dir = 0; Ecore_Event_Mouse_Button *ev_cancel; + E_Gesture_Conf_Edd *conf = gesture->config->conf; switch (direction) { @@ -96,7 +98,7 @@ _e_gesture_send_swipe(int fingers, int x, int y, int direction, struct wl_client GTINF("Send swipe gesture (direction: %d) to client: %p\n", dir, client); - if (E_GESTURE_SWIPE_BACK_DEFAULT_ENABLE && + if (conf->swipe.default_enable_back && direction == E_GESTURE_DIRECTION_DOWN) { _e_gesture_send_back_key(EINA_TRUE); @@ -163,6 +165,7 @@ static void _e_gesture_process_swipe_down(Ecore_Event_Mouse_Button *ev) { E_Gesture_Event_Swipe *swipes = &gesture->gesture_events.swipes; + E_Gesture_Conf_Edd *conf = gesture->config->conf; int i; unsigned int idx = ev->multi.device+1; @@ -176,17 +179,17 @@ _e_gesture_process_swipe_down(Ecore_Event_Mouse_Button *ev) } } - if (ev->y < E_GESTURE_SWIPE_START_AREA) + if (ev->y < conf->swipe.area_offset) swipes->direction = E_GESTURE_DIRECTION_DOWN; - else if (ev->y > e_comp->h - E_GESTURE_SWIPE_START_AREA) + else if (ev->y > e_comp->h - conf->swipe.area_offset) swipes->direction = E_GESTURE_DIRECTION_UP; - else if (ev->x < E_GESTURE_SWIPE_START_AREA) + else if (ev->x < conf->swipe.area_offset) swipes->direction = E_GESTURE_DIRECTION_RIGHT; - else if (ev->x > e_comp->w - E_GESTURE_SWIPE_START_AREA) + else if (ev->x > e_comp->w - conf->swipe.area_offset) 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)) + !((swipes->combined_keycode == conf->swipe.compose_key) && swipes->direction == E_GESTURE_DIRECTION_RIGHT)) { _e_gesture_swipe_cancel(); } @@ -194,8 +197,8 @@ _e_gesture_process_swipe_down(Ecore_Event_Mouse_Button *ev) { 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); + swipes->start_timer = ecore_timer_add(conf->swipe.time_begin, _e_gesture_timer_swipe_start, NULL); + swipes->done_timer = ecore_timer_add(conf->swipe.time_done, _e_gesture_timer_swipe_done, NULL); } } else @@ -212,6 +215,7 @@ static void _e_gesture_process_swipe_move(Ecore_Event_Mouse_Move *ev) { E_Gesture_Event_Swipe *swipes = &gesture->gesture_events.swipes; + E_Gesture_Conf_Edd *conf = gesture->config->conf; Coords diff; unsigned int idx = ev->multi.device+1; @@ -224,45 +228,45 @@ _e_gesture_process_swipe_move(Ecore_Event_Mouse_Move *ev) switch(swipes->direction) { case E_GESTURE_DIRECTION_DOWN: - if (diff.x > E_GESTURE_SWIPE_DIFF_FAIL) + if (diff.x > conf->swipe.min_length) { _e_gesture_swipe_cancel(); break; } - if (diff.y > E_GESTURE_SWIPE_DIFF_SUCCESS) + if (diff.y > conf->swipe.max_length) { _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) + if (diff.y > conf->swipe.min_length) { _e_gesture_swipe_cancel(); break; } - if (diff.x > E_GESTURE_SWIPE_DIFF_SUCCESS) + if (diff.x > conf->swipe.max_length) { _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) + if (diff.x > conf->swipe.min_length) { _e_gesture_swipe_cancel(); break; } - if (diff.y > E_GESTURE_SWIPE_DIFF_SUCCESS) + if (diff.y > conf->swipe.max_length) { _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) + if (diff.y > conf->swipe.min_length) { _e_gesture_swipe_cancel(); break; } - if (diff.x > E_GESTURE_SWIPE_DIFF_SUCCESS) + if (diff.x > conf->swipe.max_length) { _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); } @@ -383,10 +387,11 @@ static Eina_Bool _e_gesture_process_key_down(void *event) { Ecore_Event_Key *ev = event; + E_Gesture_Conf_Edd *conf = gesture->config->conf; - if (ev->keycode == E_GESTURE_SWIPE_COMBINE_KEY) + if (ev->keycode == conf->swipe.compose_key) { - gesture->gesture_events.swipes.combined_keycode = E_GESTURE_SWIPE_COMBINE_KEY; + gesture->gesture_events.swipes.combined_keycode = conf->swipe.compose_key; } return EINA_TRUE; @@ -396,8 +401,9 @@ static Eina_Bool _e_gesture_process_key_up(void *event) { Ecore_Event_Key *ev = event; + E_Gesture_Conf_Edd *conf = gesture->config->conf; - if (ev->keycode == E_GESTURE_SWIPE_COMBINE_KEY) + if (ev->keycode == conf->swipe.compose_key) { gesture->gesture_events.swipes.combined_keycode = 0; } diff --git a/src/e_mod_main.c b/src/e_mod_main.c index 529a02f..d5c4f88 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -5,7 +5,7 @@ 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 E_Gesture_Config_Data *_e_gesture_init(E_Module *m); static void _e_gesture_init_handlers(void); @@ -318,15 +318,51 @@ _e_gesture_event_filter(void *data, void *loop_data EINA_UNUSED, int type, void return e_gesture_process_events(event, type); } +static Eina_Bool +_e_gesture_cb_client_focus_in(void *data, int type, void *event) +{ + E_Client *ec; + E_Comp_Wl_Aux_Hint *hint; + Eina_List *l; + Eina_Bool gesture_disable = EINA_FALSE; + E_Event_Client *ev = (E_Event_Client *)event; + + EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON); + ec = ev->ec; + EINA_SAFETY_ON_NULL_RETURN_VAL(ec, ECORE_CALLBACK_PASS_ON); + EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, ECORE_CALLBACK_PASS_ON); + + if (ec->gesture_disable && gesture->enable) + { + GTINF("Disable gesture\n"); + ecore_event_filter_del(gesture->ef_handler); + gesture->ef_handler = NULL; + gesture->enable = EINA_FALSE; + } + else if (!ec->gesture_disable && !gesture->enable) + { + GTINF("enable gesture\n"); + gesture->ef_handler = ecore_event_filter_add(NULL, _e_gesture_event_filter, NULL, NULL); + gesture->enable = EINA_TRUE; + } + + return ECORE_CALLBACK_PASS_ON; +} + static void _e_gesture_init_handlers(void) { gesture->ef_handler = ecore_event_filter_add(NULL, _e_gesture_event_filter, NULL, NULL); + + gesture->handlers = eina_list_append(gesture->handlers, + ecore_event_handler_add(E_EVENT_CLIENT_FOCUS_IN, + _e_gesture_cb_client_focus_in, NULL)); } -static void * +static E_Gesture_Config_Data * _e_gesture_init(E_Module *m) { + E_Gesture_Config_Data *gconfig = NULL; gesture = E_NEW(E_Gesture, 1); if (!gesture) @@ -341,8 +377,25 @@ _e_gesture_init(E_Module *m) goto err; } - /* Add filtering mechanism */ + /* Add filtering mechanism + * FIXME: Add handlers after first gesture is grabbed + */ _e_gesture_init_handlers(); + + /* Init config */ + gconfig = E_NEW(E_Gesture_Config_Data, 1); + EINA_SAFETY_ON_NULL_GOTO(gconfig, err); + gconfig->module = m; + + e_gesture_conf_init(gconfig); + EINA_SAFETY_ON_NULL_GOTO(gconfig->conf, err); + gesture->config = gconfig; + + GTDBG("config value\n"); + GTDBG("keyboard: %s, time_done: %lf, time_begin: %lf\n", gconfig->conf->key_device_name, gconfig->conf->swipe.time_done, gconfig->conf->swipe.time_begin); + GTDBG("area_offset: %d, min_length: %d, max_length: %d\n", gconfig->conf->swipe.area_offset, gconfig->conf->swipe.min_length, gconfig->conf->swipe.max_length); + GTDBG("compose key: %d, back: %d, default: %d\n", gconfig->conf->swipe.compose_key, gconfig->conf->swipe.back_key, gconfig->conf->swipe.default_enable_back); + gesture->global = wl_global_create(e_comp_wl->wl.disp, &tizen_gesture_interface, 1, gesture, _e_gesture_cb_bind); if (!gesture->global) { @@ -352,7 +405,7 @@ _e_gesture_init(E_Module *m) gesture->gesture_filter = E_GESTURE_TYPE_MAX; - if (E_GESTURE_SWIPE_BACK_DEFAULT_ENABLE) + if (gconfig->conf->swipe.default_enable_back) { gesture->grabbed_gesture |= TIZEN_GESTURE_TYPE_SWIPE; gesture->gesture_events.swipes.fingers[1].enabled = EINA_TRUE; @@ -360,11 +413,14 @@ _e_gesture_init(E_Module *m) gesture->gesture_events.swipes.fingers[1].direction[E_GESTURE_DIRECTION_DOWN].res = (void *)0x1; } - e_gesture_device_keydev_set(E_GESTURE_KEYBOARD_DEVICE); + e_gesture_device_keydev_set(gesture->config->conf->key_device_name); + + gesture->enable = EINA_TRUE; - return m; + return gconfig; err: + if (gconfig) e_gesture_conf_deinit(gconfig); if (gesture && gesture->ef_handler) ecore_event_filter_del(gesture->ef_handler); if (gesture) E_FREE(gesture); @@ -380,6 +436,8 @@ e_modapi_init(E_Module *m) E_API int e_modapi_shutdown(E_Module *m) { + E_Gesture_Config_Data *gconfig = m->data; + e_gesture_conf_deinit(gconfig); e_gesture_device_shutdown(); return 1; } @@ -388,6 +446,10 @@ E_API int e_modapi_save(E_Module *m) { /* Save something to be kept */ + E_Gesture_Config_Data *gconfig = m->data; + e_config_domain_save("module.gesture", + gconfig->conf_edd, + gconfig->conf); return 1; } diff --git a/src/e_mod_main.h b/src/e_mod_main.h index 6fca7ef..2f552f4 100644 --- a/src/e_mod_main.h +++ b/src/e_mod_main.h @@ -37,6 +37,8 @@ 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 _E_Gesture_Conf_Edd E_Gesture_Conf_Edd; +typedef struct _E_Gesture_Config_Data E_Gesture_Config_Data; typedef struct _Coords Coords; @@ -59,6 +61,29 @@ struct _Coords int x, y; }; +struct _E_Gesture_Conf_Edd +{ + char *key_device_name; + struct + { + double time_done; + double time_begin; + int area_offset; + int min_length; + int max_length; + int compose_key; + int back_key; + Eina_Bool default_enable_back; + } swipe; +}; + +struct _E_Gesture_Config_Data +{ + E_Module *module; + E_Config_DD *conf_edd; + E_Gesture_Conf_Edd *conf; +}; + struct _E_Gesture_Event_Swipe_Finger_Direction { struct wl_client *client; @@ -106,6 +131,8 @@ struct _E_Gesture_Event struct _E_Gesture { struct wl_global *global; + E_Gesture_Config_Data *config; + Eina_Bool enable; Ecore_Event_Filter *ef_handler; Eina_List *handlers; @@ -136,6 +163,10 @@ 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); +/* Config */ +void e_gesture_conf_init(E_Gesture_Config_Data *gconfig); +void e_gesture_conf_deinit(E_Gesture_Config_Data *gconfig); + /* Device control */ void e_gesture_device_shutdown(void); Eina_Bool e_gesture_device_add(Ecore_Event_Device_Info *ev); -- 2.7.4 From 8167ee4493c7b0229e0895626c5a365a2d515d33 Mon Sep 17 00:00:00 2001 From: JengHyun Kang Date: Fri, 24 Jun 2016 15:01:41 +0900 Subject: [PATCH 6/6] Fix build warnings Change-Id: Ia4339faa2bcd83a3c4f134d4108926c0e343acce --- src/e_mod_main.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/e_mod_main.c b/src/e_mod_main.c index d5c4f88..41999b1 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -322,9 +322,6 @@ static Eina_Bool _e_gesture_cb_client_focus_in(void *data, int type, void *event) { E_Client *ec; - E_Comp_Wl_Aux_Hint *hint; - Eina_List *l; - Eina_Bool gesture_disable = EINA_FALSE; E_Event_Client *ev = (E_Event_Client *)event; EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON); -- 2.7.4