tizen 2.3.1 release tizen_2.3.1 submit/tizen_2.3.1/20150915.072452 tizen_2.3.1_release
authorjk7744.park <jk7744.park@samsung.com>
Tue, 8 Sep 2015 12:32:58 +0000 (21:32 +0900)
committerjk7744.park <jk7744.park@samsung.com>
Tue, 8 Sep 2015 12:32:58 +0000 (21:32 +0900)
42 files changed:
.gitignore [moved from ChangeLog with 100% similarity]
Makefile.am [deleted file]
debian/changelog [deleted file]
debian/compat [deleted file]
debian/control [deleted file]
debian/rules [deleted file]
debian/xserver-xorg-input-gesture.install [deleted file]
debian/xsfbs/repack.sh [deleted file]
debian/xsfbs/xsfbs.mk [deleted file]
debian/xsfbs/xsfbs.sh [deleted file]
man/Makefile.am [deleted file]
mobile/AUTHORS [new file with mode: 0644]
mobile/COPYING [moved from COPYING with 100% similarity]
mobile/ChangeLog [new file with mode: 0644]
mobile/LICENSE.MIT [new file with mode: 0644]
mobile/Makefile.am [new file with mode: 0644]
mobile/NOTICE [new file with mode: 0644]
mobile/autogen.sh [moved from autogen.sh with 100% similarity]
mobile/configure.ac [moved from configure.ac with 52% similarity]
mobile/man/Makefile.am [new file with mode: 0644]
mobile/man/gesture.man [moved from man/gesture.man with 100% similarity]
mobile/src/Makefile.am [new file with mode: 0644]
mobile/src/gesture.c [new file with mode: 0644]
mobile/src/gesture.h [new file with mode: 0644]
mobile/xorg-gesture.pc.in [moved from xorg-gesture.pc.in with 100% similarity]
packaging/xorg-x11-drv-gesture.spec
src/Makefile.am [deleted file]
src/gesture.c [deleted file]
wearable/AUTHORS [new file with mode: 0644]
wearable/COPYING [new file with mode: 0755]
wearable/ChangeLog [new file with mode: 0644]
wearable/LICENSE.MIT [new file with mode: 0644]
wearable/Makefile.am [new file with mode: 0644]
wearable/NOTICE [new file with mode: 0644]
wearable/autogen.sh [new file with mode: 0755]
wearable/configure.ac [new file with mode: 0644]
wearable/man/Makefile.am [new file with mode: 0644]
wearable/man/gesture.man [new file with mode: 0644]
wearable/src/Makefile.am [new file with mode: 0644]
wearable/src/gesture.c [new file with mode: 0644]
wearable/src/gesture.h [moved from src/gesture.h with 69% similarity, mode: 0644]
wearable/xorg-gesture.pc.in [new file with mode: 0644]

similarity index 100%
rename from ChangeLog
rename to .gitignore
diff --git a/Makefile.am b/Makefile.am
deleted file mode 100644 (file)
index 50ddc5b..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-#  Copyright 2007 Peter Hutterer
-#  Copyright 2009 Przemysław Firszt
-#  Permission is hereby granted, free of charge, to any person obtaining a
-#  copy of this software and associated documentation files (the "Software"),
-#  to deal in the Software without restriction, including without limitation
-#  on the rights to use, copy, modify, merge, publish, distribute, sub
-#  license, and/or sell copies of the Software, and to permit persons to whom
-#  the Software is furnished to do so, subject to the following conditions:
-#
-#  The above copyright notice and this permission notice (including the next
-#  paragraph) shall be included in all copies or substantial portions of the
-#  Software.
-#
-#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-#  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-#  FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
-#  ADAM JACKSON BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-#  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-#  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-AUTOMAKE_OPTIONS = foreign
-
-# Ensure headers are installed below $(prefix) for distcheck
-DISTCHECK_CONFIGURE_FLAGS = --with-sdkdir='$${includedir}/xorg'
-
-SUBDIRS = src man
-
-pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = xorg-gesture.pc
-
-EXTRA_DIST = ChangeLog
-
-MAINTAINERCLEANFILES=ChangeLog
-
-.PHONY: ChangeLog
-
-ChangeLog:
-       $(CHANGELOG_CMD)
-
-dist-hook: ChangeLog
diff --git a/debian/changelog b/debian/changelog
deleted file mode 100755 (executable)
index c6c0520..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-xserver-xorg-input-gesture (0.1.0-7) unstable; urgency=low
-
-  * do not install libtool files
-  * Git: slp/pkgs/xorg/driver/xserver-xorg-input-gesture
-  * Tag: xserver-xorg-input-gesture_0.1.0-7
-
- -- SooChan Lim <sc1.lim@samsung.com>  Fri, 18 May 2012 09:27:37 +0900
-
-xserver-xorg-input-gesture (0.1.0-6) unstable; urgency=low
-
-  * Fix a bug : gesture driver doesn't work properly when id of multitouch devices is not consecutive
-  * Git: slp/pkgs/xorg/driver/xserver-xorg-input-gesture
-  * Tag: xserver-xorg-input-gesture_0.1.0-6
-
- -- Sung-Jin Park <sj76.park@samsung.com>  Mon, 02 Jan 2012 20:43:41 +0900
-
-xserver-xorg-input-gesture (0.1.0-5) unstable; urgency=low
-
-  * Implement multi-finger pinchrotation
-  * Git: slp/pkgs/xorg/driver/xserver-xorg-input-gesture
-  * Tag: xserver-xorg-input-gesture_0.1.0-5
-
- -- Sung-Jin Park <sj76.park@samsung.com>  Tue, 20 Dec 2011 13:15:05 +0900
-
-xserver-xorg-input-gesture (0.1.0-4) unstable; urgency=low
-
-  * Exception handling routine added. This commit is to fix Xorg BS problem at booting time.
-  * Git: 165.213.180.234:slp/pkgs/xorg/driver/xserver-xorg-input-gesture
-  * Tag: xserver-xorg-input-gesture_0.1.0-4
-
- -- Sung-Jin Park <sj76.park@samsung.com>  Mon, 28 Nov 2011 15:20:14 +0900
-
-xserver-xorg-input-gesture (0.1.0-3) unstable; urgency=low
-
-  * Define ErrorStatus and check up error status at important check points
-    Fix GestureEventsFlush() not to modify timestamp of each event
-    Remove unnecessary modification and remove unused code
-    Remove unused macro from gesture.h
-    Remove whitespace and fix indentation
-    Replace GestureEventsFree() with GestureEventsDrop()
-  * Git: 165.213.180.234:slp/pkgs/xorg/driver/xserver-xorg-input-gesture
-  * Tag: xserver-xorg-input-gesture_0.1.0-3
-
- -- Sung-Jin Park <sj76.park@samsung.com>  Mon, 21 Nov 2011 22:51:22 +0900
-
-xserver-xorg-input-gesture (0.1.0-2) unstable; urgency=low
-
-  * add null check
-  * Git: 165.213.180.234:slp/pkgs/xorg/driver/xserver-xorg-input-gesture
-  * Tag: xserver-xorg-input-gesture_0.1.0-2
-
- -- SooChan Lim <sc1.lim@samsung.com>  Tue, 08 Nov 2011 12:44:49 +0900
-
-xserver-xorg-input-gesture (0.1.0-1) unstable; urgency=low
-
-  * Initial version
-  * Git: 165.213.180.234:slp/pkgs/xorg/driver/xserver-xorg-input-gesture
-  * Tag: xserver-xorg-input-gesture_0.1.0-1
-
- -- Sung-Jin Park <sj76.park@samsung.com>  Wed, 19 Oct 2011 17:13:15 +0900
-
diff --git a/debian/compat b/debian/compat
deleted file mode 100644 (file)
index 7ed6ff8..0000000
+++ /dev/null
@@ -1 +0,0 @@
-5
diff --git a/debian/control b/debian/control
deleted file mode 100644 (file)
index 19f809e..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-Source: xserver-xorg-input-gesture
-Section: x11
-Priority: optional
-Maintainer: Sung-Jin Park <sj76.park@samsung.com>, Sangjin Lee <lsj119.@samsung.com>
-Uploaders: Sung-Jin Park <sj76.park@samsung.com>, SooChan Lim <sc1.lim@samsung.com>
-Build-Depends: debhelper (>= 5.0.0), pkg-config, quilt, xserver-xorg-dev (>= 1.9.3-19slp2), x11proto-core-dev, dpkg-dev (>= 1.14.17), automake, libtool, xutils-dev (>= 1:7.3~1), libpixman-1-dev, x11proto-gesture-dev (>= 0.1.0-1)
-#Build-Depends: debhelper (>= 5.0.0), pkg-config, quilt, xserver-xorg-dev (>= 1.6.99.900), x11proto-core-dev, x11proto-randr-dev, x11proto-input-dev, x11proto-kb-dev, libxkbfile-dev, dpkg-dev (>= 1.14.17), automake, libtool, xutils-dev (>= 1:7.3~1)
-Standards-Version: 3.8.3
-
-Package: xserver-xorg-input-gesture
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, ${xserver}
-Provides: ${xinpdriver:Provides}
-Description: X.Org X server -- Xserver gesture driver
- This package provides the driver for recognizing gesture(s) using button
- and motion events inside X server.
-
-Package: xserver-xorg-input-gesture-dbg
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, ${xserver}, xserver-xorg-input-gesture (=${Source-Version})
-Description: Debug package of xserver-xorg-input-gesture
diff --git a/debian/rules b/debian/rules
deleted file mode 100755 (executable)
index dd236a7..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-#!/usr/bin/make -f
-# debian/rules for the Debian xserver-xorg-input-gesture package.
-# Copyright © 2004 Scott James Remnant <scott@netsplit.com>
-# Copyright © 2005 Daniel Stone <daniel@fooishbar.org>
-# Copyright © 2005 David Nusinow <dnusinow@debian.org>
-
-# Uncomment this to turn on verbose mode.
-#export DH_VERBOSE=1
-
-include debian/xsfbs/xsfbs.mk
-
-CFLAGS = -Wall -g
-LDFLAGS +=  -Wl,--hash-style=both -Wl,--as-needed
-ifneq (,$(filter noopt,$(DEB_BUILD_OPTIONS)))
-       CFLAGS += -O0
-else
-       CFLAGS += -O2
-endif
-ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
-       NUMJOBS = $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
-       MAKEFLAGS += -j$(NUMJOBS)
-endif
-
-DEB_HOST_ARCH      ?= $(shell dpkg-architecture -qDEB_HOST_ARCH)
-DEB_HOST_GNU_TYPE  ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
-DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
-ifeq ($(DEB_BUILD_GNU_TYPE), $(DEB_HOST_GNU_TYPE))
-       confflags += --build=$(DEB_HOST_GNU_TYPE)
-else
-       confflags += --build=$(DEB_HOST_GNU_TYPE) --host=$(DEB_HOST_GNU_TYPE)
-#      confflags += --build=$(DEB_BUILD_GNU_TYPE) --host=$(DEB_HOST_GNU_TYPE)
-endif
-
-# kbd_drv.a isn't phenomenally useful; kbd_drv.so more so
-confflags += --disable-static
-
-#configure: $(STAMP_DIR)/patch
-configure:
-       autoreconf -vfi
-       #./autogen.sh
-
-obj-$(DEB_BUILD_GNU_TYPE)/config.status: configure
-       mkdir -p obj-$(DEB_BUILD_GNU_TYPE)
-       cd obj-$(DEB_BUILD_GNU_TYPE) && \
-       ../configure --prefix=/usr --mandir=\$${prefix}/share/man \
-                    --infodir=\$${prefix}/share/info $(confflags) \
-                    CFLAGS="$(CFLAGS)" \
-                    LDFLAGS="$(LDFLAGS)" 
-
-build: build-stamp
-build-stamp: obj-$(DEB_BUILD_GNU_TYPE)/config.status
-       dh_testdir
-       cd obj-$(DEB_BUILD_GNU_TYPE) && $(MAKE)
-       >$@
-
-clean: xsfclean
-       dh_testdir
-       dh_testroot
-       rm -f build-stamp
-
-       rm -f config.cache config.log config.status
-       rm -f */config.cache */config.log */config.status
-       rm -f conftest* */conftest*
-       rm -rf autom4te.cache */autom4te.cache
-       rm -rf obj-*
-       rm -f $$(find -name Makefile.in)
-       rm -f compile config.guess config.sub configure depcomp install-sh
-       rm -f ltmain.sh missing INSTALL aclocal.m4 ylwrap mkinstalldirs config.h.in
-
-       dh_clean
-
-install: build
-       dh_testdir
-       dh_testroot
-       dh_clean -k
-       dh_installdirs
-
-       cd obj-$(DEB_BUILD_GNU_TYPE) && $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install
-
-# Build architecture-dependent files here.
-binary-arch: build install serverabi
-       dh_testdir
-       dh_testroot
-
-       dh_installdocs
-       dh_installchangelogs ChangeLog
-       dh_install --sourcedir=debian/tmp --list-missing  --exclude=usr/share/man/man4
-       dh_installman
-       dh_link
-       dh_strip --dbg-package=xserver-xorg-input-gesture-dbg
-       dh_compress
-       dh_fixperms
-       dh_installdeb
-#      dh_shlibdeps -- --warnings=6
-       dh_shlibdeps --
-       dh_gencontrol
-       dh_md5sums
-       dh_builddeb
-
-# Build architecture-independent files here.
-binary-indep: build install
-# Nothing to do
-
-binary: binary-indep binary-arch
-.PHONY: build clean binary-indep binary-arch binary install
diff --git a/debian/xserver-xorg-input-gesture.install b/debian/xserver-xorg-input-gesture.install
deleted file mode 100644 (file)
index 4ac2576..0000000
+++ /dev/null
@@ -1 +0,0 @@
-usr/lib/xorg/modules/input/*.so
diff --git a/debian/xsfbs/repack.sh b/debian/xsfbs/repack.sh
deleted file mode 100644 (file)
index 5935cc9..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/sh
-
-set -e
-
-if ! [ -d debian/prune ]; then
-       exit 0
-fi
-
-if [ "x$1" != x--upstream-version ]; then
-       exit 1
-fi
-
-version="$2"
-filename="$3"
-
-if [ -z "$version" ] || ! [ -f "$filename" ]; then
-       exit 1
-fi
-
-dir="$(pwd)"
-tempdir="$(mktemp -d)"
-
-cd "$tempdir"
-tar xf "$dir/$filename"
-cat "$dir"/debian/prune/* | while read file; do rm -f */$file; done
-
-tar czf "$dir/$filename" *
-cd "$dir"
-rm -rf "$tempdir"
-echo "Done pruning upstream tarball"
-
-exit 0
diff --git a/debian/xsfbs/xsfbs.mk b/debian/xsfbs/xsfbs.mk
deleted file mode 100644 (file)
index f0f8953..0000000
+++ /dev/null
@@ -1,293 +0,0 @@
-#!/usr/bin/make -f
-
-# Debian X Strike Force Build System (XSFBS): Make portion
-
-# Copyright 1996 Stephen Early
-# Copyright 1997 Mark Eichin
-# Copyright 1998-2005, 2007 Branden Robinson
-# Copyright 2005 David Nusinow
-#
-# Licensed under the GNU General Public License, version 2.  See the file
-# /usr/share/common-licenses/GPL or <http://www.gnu.org/copyleft/gpl.txt>.
-
-# Originally by Stephen Early <sde1000@debian.org>
-# Modified by Mark W. Eichin <eichin@kitten.gen.ma.us>
-# Modified by Adam Heath <doogie@debian.org>
-# Modified by Branden Robinson <branden@debian.org>
-# Modified by Fabio Massimo Di Nitto <fabbione@fabbione.net>
-# Modified by David Nusinow <dnusinow@debian.org>
-# Acknowledgements to Manoj Srivastava.
-
-# Pass $(DH_OPTIONS) into the environment for debhelper's benefit.
-export DH_OPTIONS
-
-# force quilt to not use ~/.quiltrc and to use debian/patches
-QUILT = QUILT_PATCHES=debian/patches quilt --quiltrc /dev/null
-
-# Set up parameters for the upstream build environment.
-
-# Determine (source) package name from Debian changelog.
-SOURCE_NAME:=$(shell dpkg-parsechangelog -ldebian/changelog \
-                        | grep '^Source:' | awk '{print $$2}')
-
-# Determine package version from Debian changelog.
-SOURCE_VERSION:=$(shell dpkg-parsechangelog -ldebian/changelog \
-                        | grep '^Version:' | awk '{print $$2}')
-
-# Determine upstream version number.
-UPSTREAM_VERSION:=$(shell echo $(SOURCE_VERSION) | sed 's/-.*//')
-
-# Determine the source version without the epoch for make-orig-tar-gz
-NO_EPOCH_VER:=$(shell echo $(UPSTREAM_VERSION) | sed 's/^.://')
-
-# Figure out who's building this package.
-BUILDER:=$(shell echo $${DEBEMAIL:-$${EMAIL:-$$(echo $$LOGNAME@$$(cat /etc/mailname 2>/dev/null))}})
-
-# Find out if this is an official build; an official build has nothing but
-# digits, dots, and/or the codename of a release in the Debian part of the
-# version number.  Anything else indicates an unofficial build.
-OFFICIAL_BUILD:=$(shell VERSION=$(SOURCE_VERSION); if ! expr "$$(echo $${VERSION\#\#*-} | sed 's/\(woody\|sarge\|etch\|lenny\)//g')" : ".*[^0-9.].*" >/dev/null 2>&1; then echo yes; fi)
-
-# Set up parameters for the Debian build environment.
-
-# Determine our architecture.
-BUILD_ARCH:=$(shell dpkg-architecture -qDEB_BUILD_ARCH)
-# Work around some old-time dpkg braindamage.
-BUILD_ARCH:=$(subst i486,i386,$(BUILD_ARCH))
-# The DEB_HOST_ARCH variable may be set per the Debian cross-compilation policy.
-ifdef DEB_HOST_ARCH
- ARCH:=$(DEB_HOST_ARCH)
-else
- # dpkg-cross sets the ARCH environment variable; if set, use it.
- ifdef ARCH
-  ARCH:=$(ARCH)
- else
-  ARCH:=$(BUILD_ARCH)
- endif
-endif
-
-# $(STAMP_DIR) houses stamp files for complex targets.
-STAMP_DIR:=stampdir
-
-# $(DEBTREEDIR) is where all install rules are told (via $(DESTDIR)) to place
-# their files.
-DEBTREEDIR:=$(CURDIR)/debian/tmp
-
-# All "important" targets have four lines:
-#   1) A target name that is invoked by a package-building tool or the user.
-#      This consists of a dependency on a "$(STAMP_DIR)/"-prefixed counterpart.
-#   2) A line delcaring 1) as a phony target (".PHONY:").
-#   3) A "$(STAMP_DIR)/"-prefixed target which does the actual work, and may
-#   depend on other targets.
-#   4) A line declaring 3) as a member of the $(stampdir_targets) variable; the
-#   "$(STAMP_DIR)/" prefix is omitted.
-#
-# This indirection is needed so that the "stamp" files that signify when a rule
-# is done can be located in a separate "stampdir".  Recall that make has no way
-# to know when a goal has been met for a phony target (like "build" or
-# "install").
-#
-# At the end of each "$(STAMP_DIR)/" target, be sure to run the command ">$@"
-# so that the target will not be run again.  Removing the file will make Make
-# run the target over.
-
-# All phony targets should be declared as dependencies of .PHONY, even if they
-# do not have "($STAMP_DIR)/"-prefixed counterparts.
-
-# Define a harmless default rule to keep things from going nuts by accident.
-.PHONY: default
-default:
-
-# Set up the $(STAMP_DIR) directory.
-.PHONY: stampdir
-stampdir_targets+=stampdir
-stampdir: $(STAMP_DIR)/stampdir
-$(STAMP_DIR)/stampdir:
-       mkdir $(STAMP_DIR)
-       >$@
-
-# Set up the package build directory as quilt expects to find it.
-.PHONY: prepare
-stampdir_targets+=prepare
-prepare: $(STAMP_DIR)/prepare
-$(STAMP_DIR)/prepare: $(STAMP_DIR)/log $(STAMP_DIR)/genscripts
-       >$@
-
-.PHONY: log
-stampdir_targets+=log
-log: $(STAMP_DIR)/log
-$(STAMP_DIR)/log: $(STAMP_DIR)/stampdir
-       mkdir -p $(STAMP_DIR)/log
-
-# Apply all patches to the upstream source.
-.PHONY: patch
-stampdir_targets+=patch
-patch: $(STAMP_DIR)/patch
-$(STAMP_DIR)/patch: $(STAMP_DIR)/prepare
-       if ! [ `which quilt` ]; then \
-               echo "Couldn't find quilt. Please install it or add it to the build-depends for this package."; \
-               exit 1; \
-       fi; \
-       if $(QUILT) next >/dev/null 2>&1; then \
-         echo -n "Applying patches..."; \
-         if $(QUILT) push -a -v >$(STAMP_DIR)/log/patch 2>&1; then \
-           cat $(STAMP_DIR)/log/patch; \
-           echo "successful."; \
-         else \
-           cat $(STAMP_DIR)/log/patch; \
-           echo "failed! (check $(STAMP_DIR)/log/patch for details)"; \
-           exit 1; \
-         fi; \
-       else \
-         echo "No patches to apply"; \
-       fi; \
-       >$@
-
-# Revert all patches to the upstream source.
-.PHONY: unpatch
-unpatch: $(STAMP_DIR)/log
-       rm -f $(STAMP_DIR)/patch
-       @echo -n "Unapplying patches..."; \
-       if $(QUILT) applied >/dev/null 2>/dev/null; then \
-         if $(QUILT) pop -a -v >$(STAMP_DIR)/log/unpatch 2>&1; then \
-           cat $(STAMP_DIR)/log/unpatch; \
-           echo "successful."; \
-         else \
-           cat $(STAMP_DIR)/log/unpatch; \
-           echo "failed! (check $(STAMP_DIR)/log/unpatch for details)"; \
-           exit 1; \
-         fi; \
-       else \
-         echo "nothing to do."; \
-       fi
-
-# Clean the generated maintainer scripts.
-.PHONY: cleanscripts
-cleanscripts:
-       rm -f $(STAMP_DIR)/genscripts
-       rm -f debian/*.config \
-             debian/*.postinst \
-             debian/*.postrm \
-             debian/*.preinst \
-             debian/*.prerm
-
-# Clean the package build tree.
-.PHONY: xsfclean
-xsfclean: cleanscripts unpatch
-       dh_testdir
-       rm -rf .pc
-       rm -rf $(STAMP_DIR) $(SOURCE_DIR)
-       rm -rf imports
-       dh_clean debian/shlibs.local \
-                debian/po/pothead
-
-# Generate the debconf templates POT file header.
-debian/po/pothead: debian/po/pothead.in
-       sed -e 's/SOURCE_VERSION/$(SOURCE_VERSION)/' \
-         -e 's/DATE/$(shell date "+%F %X%z"/)' <$< >$@
-
-# Update POT and PO files.
-.PHONY: updatepo
-updatepo: debian/po/pothead
-       debian/scripts/debconf-updatepo --pot-header=pothead --verbose
-
-# Remove files from the upstream source tree that we don't need, or which have
-# licensing problems.  It must be run before creating the .orig.tar.gz.
-#
-# Note: This rule is for Debian package maintainers' convenience, and is not
-# needed for conventional build scenarios.
-.PHONY: prune-upstream-tree
-prune-upstream-tree:
-       # Ensure we're in the correct directory.
-       dh_testdir
-       grep -rvh '^#' debian/prune/ | xargs --no-run-if-empty rm -rf
-
-# Verify that there are no offsets or fuzz in the patches we apply.
-#
-# Note: This rule is for Debian package maintainers' convenience, and is not
-# needed for conventional build scenarios.
-.PHONY: patch-audit
-patch-audit: prepare unpatch
-       @echo -n "Auditing patches..."; \
-       >$(STAMP_DIR)/log/patch; \
-       FUZZY=; \
-       while [ -n "$$($(QUILT) next)" ]; do \
-         RESULT=$$($(QUILT) push -v | tee -a $(STAMP_DIR)/log/patch | grep ^Hunk | sed 's/^Hunk.*\(succeeded\|FAILED\).*/\1/');\
-         case "$$RESULT" in \
-           succeeded) \
-             echo "fuzzy patch: $$($(QUILT) top)" \
-               | tee -a $(STAMP_DIR)/log/$$($(QUILT) top); \
-             FUZZY=yes; \
-             ;; \
-           FAILED) \
-             echo "broken patch: $$($(QUILT) next)" \
-               | tee -a $(STAMP_DIR)/log/$$($(QUILT) next); \
-             exit 1; \
-             ;; \
-         esac; \
-       done; \
-       if [ -n "$$FUZZY" ]; then \
-         echo "there were fuzzy patches; please fix."; \
-         exit 1; \
-       else \
-         echo "done."; \
-       fi
-
-# Generate the maintainer scripts.
-.PHONY: genscripts
-stampdir_targets+=genscripts
-genscripts: $(STAMP_DIR)/genscripts
-$(STAMP_DIR)/genscripts: $(STAMP_DIR)/stampdir
-       for FILE in debian/*.config.in \
-                   debian/*.postinst.in \
-                   debian/*.postrm.in \
-                   debian/*.preinst.in \
-                   debian/*.prerm.in; do \
-         if [ -e "$$FILE" ]; then \
-           MAINTSCRIPT=$$(echo $$FILE | sed 's/.in$$//'); \
-           sed -n '1,/^#INCLUDE_SHELL_LIB#$$/p' <$$FILE \
-             | sed -e '/^#INCLUDE_SHELL_LIB#$$/d' >$$MAINTSCRIPT.tmp; \
-           cat debian/xsfbs/xsfbs.sh >>$$MAINTSCRIPT.tmp; \
-           sed -n '/^#INCLUDE_SHELL_LIB#$$/,$$p' <$$FILE \
-             | sed -e '/^#INCLUDE_SHELL_LIB#$$/d' >>$$MAINTSCRIPT.tmp; \
-           sed -e 's/@SOURCE_VERSION@/$(SOURCE_VERSION)/' \
-               -e 's/@OFFICIAL_BUILD@/$(OFFICIAL_BUILD)/' \
-               -e 's/@DEFAULT_DCRESOLUTIONS@/$(DEFAULT_DCRESOLUTIONS)/' \
-             <$$MAINTSCRIPT.tmp >$$MAINTSCRIPT; \
-           rm $$MAINTSCRIPT.tmp; \
-         fi; \
-       done
-       # Validate syntax of generated shell scripts.
-       #sh debian/scripts/validate-posix-sh debian/*.config \
-       #                                    debian/*.postinst \
-       #                                    debian/*.postrm \
-       #                                    debian/*.preinst \
-       #                                    debian/*.prerm
-       >$@
-
-# Generate the shlibs.local file.
-debian/shlibs.local:
-       cat debian/*.shlibs >$@
-
-SERVERMINVERS = $(shell cat /usr/share/xserver-xorg/serverminver 2>/dev/null)
-VIDEOABI = $(shell cat /usr/share/xserver-xorg/videoabiver 2>/dev/null)
-INPUTABI = $(shell cat /usr/share/xserver-xorg/inputabiver 2>/dev/null)
-SERVER_DEPENDS = xserver-xorg-core (>= $(SERVERMINVERS))
-VIDDRIVER_PROVIDES = xserver-xorg-video-$(VIDEOABI)
-INPDRIVER_PROVIDES = xserver-xorg-input-$(INPUTABI)
-ifeq ($(PACKAGE),)
-PACKAGE=$(shell awk '/^Package:/ { print $$2; exit }' < debian/control)
-endif
-
-.PHONY: serverabi
-serverabi: install
-ifeq ($(SERVERMINVERS),)
-       @echo error: xserver-xorg-dev needs to be installed
-       @exit 1
-else
-       echo "xserver:Depends=$(SERVER_DEPENDS)" >> debian/$(PACKAGE).substvars
-       echo "xviddriver:Provides=$(VIDDRIVER_PROVIDES)" >> debian/$(PACKAGE).substvars
-       echo "xinpdriver:Provides=$(INPDRIVER_PROVIDES)" >> debian/$(PACKAGE).substvars
-endif
-
-# vim:set noet ai sts=8 sw=8 tw=0:
diff --git a/debian/xsfbs/xsfbs.sh b/debian/xsfbs/xsfbs.sh
deleted file mode 100644 (file)
index 781826f..0000000
+++ /dev/null
@@ -1,853 +0,0 @@
-# $Id$
-
-# This is the X Strike Force shell library for X Window System package
-# maintainer scripts.  It serves to define shell functions commonly used by
-# such packages, and performs some error checking necessary for proper operation
-# of those functions.  By itself, it does not "do" much; the maintainer scripts
-# invoke the functions defined here to accomplish package installation and
-# removal tasks.
-
-# If you are reading this within a Debian package maintainer script (e.g.,
-# /var/lib/dpkg)info/PACKAGE.{config,preinst,postinst,prerm,postrm}), you can
-# skip past this library by scanning forward in this file to the string
-# "GOBSTOPPER".
-
-SOURCE_VERSION=@SOURCE_VERSION@
-OFFICIAL_BUILD=@OFFICIAL_BUILD@
-
-# Use special abnormal exit codes so that problems with this library are more
-# easily tracked down.
-SHELL_LIB_INTERNAL_ERROR=86
-SHELL_LIB_THROWN_ERROR=74
-SHELL_LIB_USAGE_ERROR=99
-
-# old -> new variable names
-if [ -z "$DEBUG_XORG_PACKAGE" ] && [ -n "$DEBUG_XFREE86_PACKAGE" ]; then
-  DEBUG_XORG_PACKAGE="$DEBUG_XFREE86_PACKAGE"
-fi
-if [ -z "$DEBUG_XORG_DEBCONF" ] && [ -n "$DEBUG_XFREE86_DEBCONF" ]; then
-  DEBUG_XORG_DEBCONF="$DEBUG_XFREE86_DEBCONF"
-fi
-
-# initial sanity checks
-if [ -z "$THIS_PACKAGE" ]; then
-  cat >&2 <<EOF
-Error: package maintainer script attempted to use shell library without
-definining \$THIS_PACKAGE shell variable.  Please report the package name,
-version, and the text of this error message to the Debian Bug Tracking System.
-Visit <http://www.debian.org/Bugs/Reporting> on the World Wide Web for
-instructions, read the file /usr/share/doc/debian/bug-reporting.txt from the
-"doc-debian" package, or install the "reportbug" package and use the command of
-the same name to file a report against version $SOURCE_VERSION of this package.
-EOF
-  exit $SHELL_LIB_USAGE_ERROR
-fi
-
-if [ -z "$THIS_SCRIPT" ]; then
-  cat >&2 <<EOF
-Error: package maintainer script attempted to use shell library without
-definining \$THIS_SCRIPT shell variable.  Please report the package name,
-version, and the text of this error message to the Debian Bug Tracking System.
-Visit <http://www.debian.org/Bugs/Reporting> on the World Wide Web for
-instructions, read the file /usr/share/doc/debian/bug-reporting.txt from the
-"doc-debian" package, or install the "reportbug" package and use the command of
-the same name to file a report against version $SOURCE_VERSION of the
-"$THIS_PACKAGE" package.
-EOF
-  exit $SHELL_LIB_USAGE_ERROR
-fi
-
-if [ "$1" = "reconfigure" ] || [ -n "$DEBCONF_RECONFIGURE" ]; then
-  RECONFIGURE="true"
-else
-  RECONFIGURE=
-fi
-
-if ([ "$1" = "install" ] || [ "$1" = "configure" ]) && [ -z "$2" ]; then
-  FIRSTINST="yes"
-fi
-
-if [ -z "$RECONFIGURE" ] && [ -z "$FIRSTINST" ]; then
-  UPGRADE="yes"
-fi
-
-trap "message;\
-      message \"Received signal.  Aborting $THIS_PACKAGE package $THIS_SCRIPT script.\";\
-      message;\
-      exit 1" HUP INT QUIT TERM
-
-reject_nondigits () {
-  # syntax: reject_nondigits [ operand ... ]
-  #
-  # scan operands (typically shell variables whose values cannot be trusted) for
-  # characters other than decimal digits and barf if any are found
-  while [ -n "$1" ]; do
-    # does the operand contain anything but digits?
-    if ! expr "$1" : "[[:digit:]]\+$" > /dev/null 2>&1; then
-      # can't use die(), because it wraps message() which wraps this function
-      echo "$THIS_PACKAGE $THIS_SCRIPT error: reject_nondigits() encountered" \
-           "possibly malicious garbage \"$1\"" >&2
-      exit $SHELL_LIB_THROWN_ERROR
-    fi
-    shift
-  done
-}
-
-reject_whitespace () {
-  # syntax: reject_whitespace [ operand ]
-  #
-  # scan operand (typically a shell variable whose value cannot be trusted) for
-  # whitespace characters and barf if any are found
-  if [ -n "$1" ]; then
-    # does the operand contain any whitespace?
-    if expr "$1" : "[[:space:]]" > /dev/null 2>&1; then
-      # can't use die(), because I want to avoid forward references
-      echo "$THIS_PACKAGE $THIS_SCRIPT error: reject_whitespace() encountered" \
-           "possibly malicious garbage \"$1\"" >&2
-      exit $SHELL_LIB_THROWN_ERROR
-    fi
-  fi
-}
-
-reject_unlikely_path_chars () {
-  # syntax: reject_unlikely_path_chars [ operand ... ]
-  #
-  # scan operands (typically shell variables whose values cannot be trusted) for
-  # characters unlikely to be seen in a path and which the shell might
-  # interpret and barf if any are found
-  while [ -n "$1" ]; do
-    # does the operand contain any funny characters?
-    if expr "$1" : '.*[!$&()*;<>?|].*' > /dev/null 2>&1; then
-      # can't use die(), because I want to avoid forward references
-      echo "$THIS_PACKAGE $THIS_SCRIPT error: reject_unlikely_path_chars()" \
-           "encountered possibly malicious garbage \"$1\"" >&2
-      exit $SHELL_LIB_THROWN_ERROR
-    fi
-    shift
-  done
-}
-
-# Query the terminal to establish a default number of columns to use for
-# displaying messages to the user.  This is used only as a fallback in the
-# event the COLUMNS variable is not set.  ($COLUMNS can react to SIGWINCH while
-# the script is running, and this cannot, only being calculated once.)
-DEFCOLUMNS=$(stty size 2> /dev/null | awk '{print $2}') || true
-if ! expr "$DEFCOLUMNS" : "[[:digit:]]\+$" > /dev/null 2>&1; then
-  DEFCOLUMNS=80
-fi
-
-message () {
-  # pretty-print messages of arbitrary length
-  reject_nondigits "$COLUMNS"
-  echo "$*" | fmt -t -w ${COLUMNS:-$DEFCOLUMNS} >&2
-}
-
-observe () {
-  # syntax: observe message ...
-  #
-  # issue observational message suitable for logging someday when support for
-  # it exists in dpkg
-  if [ -n "$DEBUG_XORG_PACKAGE" ]; then
-    message "$THIS_PACKAGE $THIS_SCRIPT note: $*"
-  fi
-}
-
-warn () {
-  # syntax: warn message ...
-  #
-  # issue warning message suitable for logging someday when support for
-  # it exists in dpkg; also send to standard error
-  message "$THIS_PACKAGE $THIS_SCRIPT warning: $*"
-}
-
-die () {
-  # syntax: die message ...
-  #
-  # exit script with error message
-  message "$THIS_PACKAGE $THIS_SCRIPT error: $*"
-  exit $SHELL_LIB_THROWN_ERROR
-}
-
-internal_error () {
-  # exit script with error; essentially a "THIS SHOULD NEVER HAPPEN" message
-  message "internal error: $*"
-  if [ -n "$OFFICIAL_BUILD" ]; then
-    message "Please report a bug in the $THIS_SCRIPT script of the" \
-            "$THIS_PACKAGE package, version $SOURCE_VERSION to the Debian Bug" \
-            "Tracking System.  Include all messages above that mention the" \
-            "$THIS_PACKAGE package.  Visit " \
-            "<http://www.debian.org/Bugs/Reporting> on the World Wide Web for" \
-            "instructions, read the file" \
-            "/usr/share/doc/debian/bug-reporting.txt from the doc-debian" \
-            "package, or install the reportbug package and use the command of" \
-            "the same name to file a report."
-  fi
-  exit $SHELL_LIB_INTERNAL_ERROR
-}
-
-usage_error () {
-  message "usage error: $*"
-  message "Please report a bug in the $THIS_SCRIPT script of the" \
-          "$THIS_PACKAGE package, version $SOURCE_VERSION to the Debian Bug" \
-          "Tracking System.  Include all messages above that mention the" \
-          "$THIS_PACKAGE package.  Visit " \
-          "<http://www.debian.org/Bugs/Reporting> on the World Wide Web for" \
-          "instructions, read the file" \
-          "/usr/share/doc/debian/bug-reporting.txt from the doc-debian" \
-          "package, or install the reportbug package and use the command of" \
-          "the same name to file a report."
-  exit $SHELL_LIB_USAGE_ERROR
-}
-
-
-maplink () {
-  # returns what symlink should point to; i.e., what the "sane" answer is
-  # Keep this in sync with the debian/*.links files.
-  # This is only needed for symlinks to directories.
-  #
-  # XXX: Most of these look wrong in the X11R7 world and need to be fixed.
-  # If we've stopped using this function, fixing it might enable us to re-enable
-  # it again and catch more errors.
-  case "$1" in
-    /etc/X11/xkb/compiled) echo /var/lib/xkb ;;
-    /etc/X11/xkb/xkbcomp) echo /usr/X11R6/bin/xkbcomp ;;
-    /usr/X11R6/lib/X11/app-defaults) echo /etc/X11/app-defaults ;;
-    /usr/X11R6/lib/X11/fs) echo /etc/X11/fs ;;
-    /usr/X11R6/lib/X11/lbxproxy) echo /etc/X11/lbxproxy ;;
-    /usr/X11R6/lib/X11/proxymngr) echo /etc/X11/proxymngr ;;
-    /usr/X11R6/lib/X11/rstart) echo /etc/X11/rstart ;;
-    /usr/X11R6/lib/X11/twm) echo /etc/X11/twm ;;
-    /usr/X11R6/lib/X11/xdm) echo /etc/X11/xdm ;;
-    /usr/X11R6/lib/X11/xinit) echo /etc/X11/xinit ;;
-    /usr/X11R6/lib/X11/xkb) echo /etc/X11/xkb ;;
-    /usr/X11R6/lib/X11/xserver) echo /etc/X11/xserver ;;
-    /usr/X11R6/lib/X11/xsm) echo /etc/X11/xsm ;;
-    /usr/bin/X11) echo ../X11R6/bin ;;
-    /usr/bin/rstartd) echo ../X11R6/bin/rstartd ;;
-    /usr/include/X11) echo ../X11R6/include/X11 ;;
-    /usr/lib/X11) echo ../X11R6/lib/X11 ;;
-    *) internal_error "maplink() called with unknown path \"$1\"" ;;
-  esac
-}
-
-analyze_path () {
-  # given a supplied set of pathnames, break each one up by directory and do an
-  # ls -dl on each component, cumulatively; i.e.
-  # analyze_path /usr/X11R6/bin -> ls -dl /usr /usr/X11R6 /usr/X11R6/bin
-  # Thanks to Randolph Chung for this clever hack.
-
-  local f g
-
-  while [ -n "$1" ]; do
-    reject_whitespace "$1"
-    g=
-    message "Analyzing $1:"
-    for f in $(echo "$1" | tr / \  ); do
-      if [ -e /$g$f ]; then
-        ls -dl /$g$f /$g$f.dpkg-* 2> /dev/null || true
-        g=$g$f/
-      else
-        message "/$g$f: nonexistent; directory contents of /$g:"
-        ls -l /$g
-        break
-      fi
-    done
-    shift
-  done
-}
-
-find_culprits () {
-  local f p dpkg_info_dir possible_culprits smoking_guns bad_packages package \
-    msg
-
-  reject_whitespace "$1"
-  message "Searching for overlapping packages..."
-  dpkg_info_dir=/var/lib/dpkg/info
-  if [ -d $dpkg_info_dir ]; then
-    if [ "$(echo $dpkg_info_dir/*.list)" != "$dpkg_info_dir/*.list" ]; then
-      possible_culprits=$(ls -1 $dpkg_info_dir/*.list | egrep -v \
-        "(xbase-clients|x11-common|xfs|xlibs)")
-      if [ -n "$possible_culprits" ]; then
-        smoking_guns=$(grep -l "$1" $possible_culprits || true)
-        if [ -n "$smoking_guns" ]; then
-          bad_packages=$(printf "\\n")
-          for f in $smoking_guns; do
-            # too bad you can't nest parameter expansion voodoo
-            p=${f%*.list}      # strip off the trailing ".list"
-            package=${p##*/}   # strip off the directories
-            bad_packages=$(printf "%s\n%s" "$bad_packages" "$package")
-          done
-          msg=$(cat <<EOF
-The following packages appear to have file overlaps with the X.Org packages;
-these packages are either very old, or in violation of Debian Policy.  Try
-upgrading each of these packages to the latest available version if possible:
-for example, with the command "apt-get install".  If no newer version of a
-package is available, you will have to remove it; for example, with the command
-"apt-get remove".  If even the latest available version of the package has
-this file overlap, please file a bug against that package with the Debian Bug
-Tracking System.  You may want to refer the package maintainer to section 12.8
-of the Debian Policy manual.
-EOF
-)
-          message "$msg"
-          message "The overlapping packages are: $bad_packages"
-        else
-          message "no overlaps found."
-        fi
-      fi
-    else
-      message "cannot search; no matches for $dpkg_info_dir/*.list."
-    fi
-  else
-    message "cannot search; $dpkg_info_dir does not exist."
-  fi
-}
-
-check_symlink () {
-  # syntax: check_symlink symlink
-  #
-  # See if specified symlink points where it is supposed to.  Return 0 if it
-  # does, and 1 if it does not.
-  #
-  # Primarily used by check_symlinks_and_warn() and check_symlinks_and_bomb().
-
-  local symlink
-
-  # validate arguments
-  if [ $# -ne 1 ]; then
-    usage_error "check_symlink() called with wrong number of arguments;" \
-                "expected 1, got $#"
-    exit $SHELL_LIB_USAGE_ERROR
-  fi
-
-  symlink="$1"
-
-  if [ "$(maplink "$symlink")" = "$(readlink "$symlink")" ]; then
-    return 0
-  else
-    return 1
-  fi
-}
-
-check_symlinks_and_warn () {
-  # syntax: check_symlinks_and_warn symlink ...
-  #
-  # For each argument, check for symlink sanity, and warn if it isn't sane.
-  #
-  # Call this function from a preinst script in the event $1 is "upgrade" or
-  # "install".
-
-  local errmsg symlink
-
-  # validate arguments
-  if [ $# -lt 1 ]; then
-    usage_error "check_symlinks_and_warn() called with wrong number of" \
-                "arguments; expected at least 1, got $#"
-    exit $SHELL_LIB_USAGE_ERROR
-  fi
-
-  while [ -n "$1" ]; do
-    symlink="$1"
-    if [ -L "$symlink" ]; then
-      if ! check_symlink "$symlink"; then
-        observe "$symlink symbolic link points to wrong location" \
-                "$(readlink "$symlink"); removing"
-        rm "$symlink"
-      fi
-    elif [ -e "$symlink" ]; then
-      errmsg="$symlink exists and is not a symbolic link; this package cannot"
-      errmsg="$errmsg be installed until this"
-      if [ -f "$symlink" ]; then
-        errmsg="$errmsg file"
-      elif [ -d "$symlink" ]; then
-        errmsg="$errmsg directory"
-      else
-        errmsg="$errmsg thing"
-      fi
-      errmsg="$errmsg is removed"
-      die "$errmsg"
-    fi
-    shift
-  done
-}
-
-check_symlinks_and_bomb () {
-  # syntax: check_symlinks_and_bomb symlink ...
-  #
-  # For each argument, check for symlink sanity, and bomb if it isn't sane.
-  #
-  # Call this function from a postinst script.
-
-  local problem symlink
-
-  # validate arguments
-  if [ $# -lt 1 ]; then
-    usage_error "check_symlinks_and_bomb() called with wrong number of"
-                "arguments; expected at least 1, got $#"
-    exit $SHELL_LIB_USAGE_ERROR
-  fi
-
-  while [ -n "$1" ]; do
-    problem=
-    symlink="$1"
-    if [ -L "$symlink" ]; then
-      if ! check_symlink "$symlink"; then
-        problem=yes
-        warn "$symlink symbolic link points to wrong location" \
-             "$(readlink "$symlink")"
-      fi
-    elif [ -e "$symlink" ]; then
-      problem=yes
-      warn "$symlink is not a symbolic link"
-    else
-      problem=yes
-      warn "$symlink symbolic link does not exist"
-    fi
-    if [ -n "$problem" ]; then
-      analyze_path "$symlink" "$(readlink "$symlink")"
-      find_culprits "$symlink"
-      die "bad symbolic links on system"
-    fi
-    shift
-  done
-}
-
-font_update () {
-  # run $UPDATECMDS in $FONTDIRS
-
-  local dir cmd shortcmd x_font_dir_prefix
-
-  x_font_dir_prefix="/usr/share/fonts/X11"
-
-  if [ -z "$UPDATECMDS" ]; then
-    usage_error "font_update() called but \$UPDATECMDS not set"
-  fi
-  if [ -z "$FONTDIRS" ]; then
-    usage_error "font_update() called but \$FONTDIRS not set"
-  fi
-
-  reject_unlikely_path_chars "$UPDATECMDS"
-  reject_unlikely_path_chars "$FONTDIRS"
-
-  for dir in $FONTDIRS; do
-    if [ -d "$x_font_dir_prefix/$dir" ]; then
-      for cmd in $UPDATECMDS; do
-        if which "$cmd" > /dev/null 2>&1; then
-          shortcmd=${cmd##*/}
-          observe "running $shortcmd in $dir font directory"
-         cmd_opts=
-          if [ "$shortcmd" = "update-fonts-alias" ]; then
-            cmd_opts=--x11r7-layout
-          fi
-          if [ "$shortcmd" = "update-fonts-dir" ]; then
-            cmd_opts=--x11r7-layout
-          fi
-          if [ "$shortcmd" = "update-fonts-scale" ]; then
-            cmd_opts=--x11r7-layout
-          fi
-          $cmd $cmd_opts $dir || warn "$cmd $cmd_opts $dir" \
-                              "failed; font directory data may not" \
-                              "be up to date"
-        else
-          warn "$cmd not found; not updating corresponding $dir font" \
-               "directory data"
-        fi
-      done
-    else
-      warn "$dir is not a directory; not updating font directory data"
-    fi
-  done
-}
-
-remove_conffile_prepare () {
-  # syntax: remove_conffile_prepare filename official_md5sum ...
-  #
-  # Check a conffile "filename" against a list of canonical MD5 checksums.
-  # If the file's current MD5 checksum matches one of the "official_md5sum"
-  # operands provided, then prepare the conffile for removal from the system.
-  # We defer actual deletion until the package is configured so that we can
-  # roll this operation back if package installation fails.
-  #
-  # Call this function from a preinst script in the event $1 is "upgrade" or
-  # "install" and verify $2 to ensure the package is being upgraded from a
-  # version (or installed over a version removed-but-not-purged) prior to the
-  # one in which the conffile was obsoleted.
-
-  local conffile current_checksum
-
-  # validate arguments
-  if [ $# -lt 2 ]; then
-    usage_error "remove_conffile_prepare() called with wrong number of" \
-                "arguments; expected at least 2, got $#"
-    exit $SHELL_LIB_USAGE_ERROR
-  fi
-
-  conffile="$1"
-  shift
-
-  # does the conffile even exist?
-  if [ -e "$conffile" ]; then
-    # calculate its checksum
-    current_checksum=$(md5sum < "$conffile" | sed 's/[[:space:]].*//')
-    # compare it to each supplied checksum
-    while [ -n "$1" ]; do
-      if [ "$current_checksum" = "$1" ]; then
-        # we found a match; move the confffile and stop looking
-        observe "preparing obsolete conffile $conffile for removal"
-        mv "$conffile" "$conffile.$THIS_PACKAGE-tmp"
-        break
-      fi
-      shift
-    done
-  fi
-}
-
-remove_conffile_lookup () {
-  # syntax: remove_conffile_lookup package filename
-  #
-  # Lookup the md5sum of a conffile in dpkg's database, and prepare for removal
-  # if it matches the actual file's md5sum.
-  #
-  # Call this function when you would call remove_conffile_prepare but only
-  # want to check against dpkg's status database instead of known checksums.
-
-  local package conffile old_md5sum
-
-  # validate arguments
-  if [ $# -ne 2 ]; then
-    usage_error "remove_conffile_lookup() called with wrong number of" \
-                "arguments; expected 1, got $#"
-    exit $SHELL_LIB_USAGE_ERROR
-  fi
-
-  package="$1"
-  conffile="$2"
-
-  if ! [ -e "$conffile" ]; then
-    return
-  fi
-  old_md5sum="$(dpkg-query -W -f='${Conffiles}' "$package" | \
-    awk '{ if (match($0, "^ '"$conffile"' ")) print $2}')"
-  if [ -n "$old_md5sum" ]; then
-    remove_conffile_prepare "$conffile" "$old_md5sum"
-  fi
-}
-
-remove_conffile_commit () {
-  # syntax: remove_conffile_commit filename
-  #
-  # Complete the removal of a conffile "filename" that has become obsolete.
-  #
-  # Call this function from a postinst script after having used
-  # remove_conffile_prepare() in the preinst.
-
-  local conffile
-
-  # validate arguments
-  if [ $# -ne 1 ]; then
-    usage_error "remove_conffile_commit() called with wrong number of" \
-                "arguments; expected 1, got $#"
-    exit $SHELL_LIB_USAGE_ERROR
-  fi
-
-  conffile="$1"
-
-  # if the temporary file created by remove_conffile_prepare() exists, remove it
-  if [ -e "$conffile.$THIS_PACKAGE-tmp" ]; then
-    observe "committing removal of obsolete conffile $conffile"
-    rm "$conffile.$THIS_PACKAGE-tmp"
-  fi
-}
-
-remove_conffile_rollback () {
-  # syntax: remove_conffile_rollback filename
-  #
-  # Roll back the removal of a conffile "filename".
-  #
-  # Call this function from a postrm script in the event $1 is "abort-upgrade"
-  # or "abort-install" is  after having used remove_conffile_prepare() in the
-  # preinst.
-
-  local conffile
-
-  # validate arguments
-  if [ $# -ne 1 ]; then
-    usage_error "remove_conffile_rollback() called with wrong number of" \
-                "arguments; expected 1, got $#"
-    exit $SHELL_LIB_USAGE_ERROR
-  fi
-
-  conffile="$1"
-
-  # if the temporary file created by remove_conffile_prepare() exists, move it
-  # back
-  if [ -e "$conffile.$THIS_PACKAGE-tmp" ]; then
-    observe "rolling back removal of obsolete conffile $conffile"
-    mv "$conffile.$THIS_PACKAGE-tmp" "$conffile"
-  fi
-}
-
-replace_conffile_with_symlink_prepare () {
-  # syntax: replace_conffile_with_symlink_prepare oldfilename newfilename \
-  # official_md5sum ...
-  #
-  # Check a conffile "oldfilename" against a list of canonical MD5 checksums.
-  # If the file's current MD5 checksum matches one of the "official_md5sum"
-  # operands provided, then prepare the conffile for removal from the system.
-  # We defer actual deletion until the package is configured so that we can
-  # roll this operation back if package installation fails. Otherwise copy it
-  # to newfilename and let dpkg handle it through conffiles mechanism.
-  #
-  # Call this function from a preinst script in the event $1 is "upgrade" or
-  # "install" and verify $2 to ensure the package is being upgraded from a
-  # version (or installed over a version removed-but-not-purged) prior to the
-  # one in which the conffile was obsoleted.
-
-  local conffile current_checksum
-
-  # validate arguments
-  if [ $# -lt 3 ]; then
-    usage_error "replace_conffile_with_symlink_prepare() called with wrong" \
-                " number of arguments; expected at least 3, got $#"
-    exit $SHELL_LIB_USAGE_ERROR
-  fi
-
-  oldconffile="$1"
-  shift
-  newconffile="$1"
-  shift
-
-  remove_conffile_prepare "$_oldconffile" "$@"
-  # If $oldconffile still exists, then md5sums didn't match.
-  # Copy it to new one.
-  if [ -f "$oldconffile" ]; then
-    cp "$oldconffile" "$newconffile"
-  fi
-
-}
-
-replace_conffile_with_symlink_commit () {
-  # syntax: replace_conffile_with_symlink_commit oldfilename
-  #
-  # Complete the removal of a conffile "oldfilename" that has been
-  # replaced by a symlink.
-  #
-  # Call this function from a postinst script after having used
-  # replace_conffile_with_symlink_prepare() in the preinst.
-
-  local conffile
-
-  # validate arguments
-  if [ $# -ne 1 ]; then
-    usage_error "replace_conffile_with_symlink_commit() called with wrong" \
-                "number of arguments; expected 1, got $#"
-    exit $SHELL_LIB_USAGE_ERROR
-  fi
-
-  conffile="$1"
-
-  remove_conffile_commit "$conffile"
-}
-
-replace_conffile_with_symlink_rollback () {
-  # syntax: replace_conffile_with_symlink_rollback oldfilename newfilename
-  #
-  # Roll back the replacing of a conffile "oldfilename" with symlink to
-  # "newfilename".
-  #
-  # Call this function from a postrm script in the event $1 is "abort-upgrade"
-  # or "abort-install" and verify $2 to ensure the package failed to upgrade
-  # from a version (or install over a version removed-but-not-purged) prior
-  # to the one in which the conffile was obsoleted.
-  # You should have  used replace_conffile_with_symlink_prepare() in the
-  # preinst.
-
-  local conffile
-
-  # validate arguments
-  if [ $# -ne 2 ]; then
-    usage_error "replace_conffile_with_symlink_rollback() called with wrong" \
-                "number of arguments; expected 2, got $#"
-    exit $SHELL_LIB_USAGE_ERROR
-  fi
-
-  oldconffile="$1"
-  newconffile="$2"
-
-  remove_conffile_rollback "$_oldconffile"
-  if [ -f "$newconffile" ]; then
-    rm "$newconffile"
-  fi
-}
-
-run () {
-  # syntax: run command [ argument ... ]
-  #
-  # Run specified command with optional arguments and report its exit status.
-  # Useful for commands whose exit status may be nonzero, but still acceptable,
-  # or commands whose failure is not fatal to us.
-  #
-  # NOTE: Do *not* use this function with db_get or db_metaget commands; in
-  # those cases the return value of the debconf command *must* be checked
-  # before the string returned by debconf is used for anything.
-
-  local retval
-
-  # validate arguments
-  if [ $# -lt 1 ]; then
-    usage_error "run() called with wrong number of arguments; expected at" \
-                "least 1, got $#"
-    exit $SHELL_LIB_USAGE_ERROR
-  fi
-
-  "$@" || retval=$?
-
-  if [ ${retval:-0} -ne 0 ]; then
-    observe "command \"$*\" exited with status $retval"
-  fi
-}
-
-make_symlink_sane () {
-  # syntax: make_symlink_sane symlink target
-  #
-  # Ensure that the symbolic link symlink exists, and points to target.
-  #
-  # If symlink does not exist, create it and point it at target.
-  #
-  # If symlink exists but is not a symbolic link, back it up.
-  #
-  # If symlink exists, is a symbolic link, but points to the wrong location, fix
-  # it.
-  #
-  # If symlink exists, is a symbolic link, and already points to target, do
-  # nothing.
-  #
-  # This function wouldn't be needed if ln had an -I, --idempotent option.
-
-  # Validate arguments.
-  if [ $# -ne 2 ]; then
-    usage_error "make_symlink_sane() called with wrong number of arguments;" \
-      "expected 2, got $#"
-    exit $SHELL_LIB_USAGE_ERROR
-  fi
-
-  # We could just use the positional parameters as-is, but that makes things
-  # harder to follow.
-  local symlink target
-
-  symlink="$1"
-  target="$2"
-
-  if [ -L "$symlink" ] && [ "$(readlink "$symlink")" = "$target" ]; then
-      observe "link from $symlink to $target already exists"
-  else
-    observe "creating symbolic link from $symlink to $target"
-    mkdir -p "${target%/*}" "${symlink%/*}"
-    ln -s -b -S ".dpkg-old" "$target" "$symlink"
-  fi
-}
-
-migrate_dir_to_symlink () {
-  # syntax: migrate_dir_to_symlink old_location new_location
-  #
-  # Per Debian Policy section 6.5.4, "A directory will never be replaced by a
-  # symbolic link to a directory or vice versa; instead, the existing state
-  # (symlink or not) will be left alone and dpkg will follow the symlink if
-  # there is one."
-  #
-  # We have to do it ourselves.
-  #
-  # This function moves the contents of old_location, a directory, into
-  # new_location, a directory, then makes old_location a symbolic link to
-  # new_location.
-  #
-  # old_location need not exist, but if it does, it must be a directory (or a
-  # symlink to a directory).  If it is not, it is backed up.  If new_location
-  # exists already and is not a directory, it is backed up.
-  #
-  # This function should be called from a package's preinst so that other
-  # packages unpacked after this one --- but before this package's postinst runs
-  # --- are unpacked into new_location even if their payloads contain
-  # old_location filespecs.
-
-  # Validate arguments.
-  if [ $# -ne 2 ]; then
-    usage_error "migrate_dir_to_symlink() called with wrong number of"
-                "arguments; expected 2, got $#"
-    exit $SHELL_LIB_USAGE_ERROR
-  fi
-
-  # We could just use the positional parameters as-is, but that makes things
-  # harder to follow.
-  local new old
-
-  old="$1"
-  new="$2"
-
-  # Is old location a symlink?
-  if [ -L "$old" ]; then
-    # Does it already point to new location?
-    if [ "$(readlink "$old")" = "$new" ]; then
-      # Nothing to do; migration has already been done.
-      observe "migration of $old to $new already done"
-      return 0
-    else
-      # Back it up.
-      warn "backing up symbolic link $old as $old.dpkg-old"
-      mv -b "$old" "$old.dpkg-old"
-    fi
-  fi
-
-  # Does old location exist, but is not a directory?
-  if [ -e "$old" ] && ! [ -d "$old" ]; then
-      # Back it up.
-      warn "backing up non-directory $old as $old.dpkg-old"
-      mv -b "$old" "$old.dpkg-old"
-  fi
-
-  observe "migrating $old to $new"
-
-  # Is new location a symlink?
-  if [ -L "$new" ]; then
-    # Does it point the wrong way, i.e., back to where we're migrating from?
-    if [ "$(readlink "$new")" = "$old" ]; then
-      # Get rid of it.
-      observe "removing symbolic link $new which points to $old"
-      rm "$new"
-    else
-      # Back it up.
-      warn "backing up symbolic link $new as $new.dpkg-old"
-      mv -b "$new" "$new.dpkg-old"
-    fi
-  fi
-
-  # Does new location exist, but is not a directory?
-  if [ -e "$new" ] && ! [ -d "$new" ]; then
-    warn "backing up non-directory $new as $new.dpkg-old"
-    mv -b "$new" "$new.dpkg-old"
-  fi
-
-  # Create new directory if it does not yet exist.
-  if ! [ -e "$new" ]; then
-    observe "creating $new"
-    mkdir -p "$new"
-  fi
-
-  # Copy files in old location to new location.  Back up any filenames that
-  # already exist in the new location with the extension ".dpkg-old".
-  observe "copying files from $old to $new"
-  if ! (cd "$old" && cp -a -b -S ".dpkg-old" . "$new"); then
-    die "error(s) encountered while copying files from $old to $new"
-  fi
-
-  # Remove files at old location.
-  observe "removing $old"
-  rm -r "$old"
-
-  # Create symlink from old location to new location.
-  make_symlink_sane "$old" "$new"
-}
-
-# vim:set ai et sw=2 ts=2 tw=80:
-
-# GOBSTOPPER: The X Strike Force shell library ends here.
diff --git a/man/Makefile.am b/man/Makefile.am
deleted file mode 100644 (file)
index 276f2f0..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
-# 
-# Permission to use, copy, modify, distribute, and sell this software and its
-# documentation for any purpose is hereby granted without fee, provided that
-# the above copyright notice appear in all copies and that both that
-# copyright notice and this permission notice appear in supporting
-# documentation.
-# 
-# The above copyright notice and this permission notice shall be included
-# in all copies or substantial portions of the Software.
-# 
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-# IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
-# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-# OTHER DEALINGS IN THE SOFTWARE.
-# 
-# Except as contained in this notice, the name of the copyright holders shall
-# not be used in advertising or otherwise to promote the sale, use or
-# other dealings in this Software without prior written authorization
-# from the copyright holders.
-# 
-
-drivermandir = $(DRIVER_MAN_DIR)
-
-driverman_PRE = @DRIVER_NAME@.man
-
-driverman_DATA = $(driverman_PRE:man=@DRIVER_MAN_SUFFIX@)
-
-EXTRA_DIST = @DRIVER_NAME@.man
-
-CLEANFILES = $(driverman_DATA)
-
-SED = sed
-
-# Strings to replace in man pages
-XORGRELSTRING = @PACKAGE_STRING@
-  XORGMANNAME = X Version 11
-
-MAN_SUBSTS = \
-       -e 's|__vendorversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \
-       -e 's|__xorgversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \
-       -e 's|__xservername__|Xorg|g' \
-       -e 's|__xconfigfile__|xorg.conf|g' \
-       -e 's|__projectroot__|$(prefix)|g' \
-       -e 's|__appmansuffix__|$(APP_MAN_SUFFIX)|g' \
-       -e 's|__drivermansuffix__|$(DRIVER_MAN_SUFFIX)|g' \
-       -e 's|__adminmansuffix__|$(ADMIN_MAN_SUFFIX)|g' \
-       -e 's|__miscmansuffix__|$(MISC_MAN_SUFFIX)|g' \
-       -e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g'
-
-SUFFIXES = .$(DRIVER_MAN_SUFFIX) .man
-
-.man.$(DRIVER_MAN_SUFFIX):
-       sed $(MAN_SUBSTS) < $< > $@
diff --git a/mobile/AUTHORS b/mobile/AUTHORS
new file mode 100644 (file)
index 0000000..e903784
--- /dev/null
@@ -0,0 +1,2 @@
+Sung-Jin Park <sj76.park@samsung.com>
+Sangjin Lee <lsj119@samsung.com>
similarity index 100%
rename from COPYING
rename to mobile/COPYING
diff --git a/mobile/ChangeLog b/mobile/ChangeLog
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/mobile/LICENSE.MIT b/mobile/LICENSE.MIT
new file mode 100644 (file)
index 0000000..1c81bdc
--- /dev/null
@@ -0,0 +1,20 @@
+Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved 
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without
+fee, provided that the above copyright notice appear in all copies
+and that both that copyright notice and this permission notice
+appear in supporting documentation, and that the name of Red Hat
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.  Red
+Hat makes no representations about the suitability of this software
+for any purpose.  It is provided "as is" without express or implied
+warranty.
+
+THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/mobile/Makefile.am b/mobile/Makefile.am
new file mode 100644 (file)
index 0000000..8e655ec
--- /dev/null
@@ -0,0 +1,41 @@
+#  Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved 
+#
+#  Permission to use, copy, modify, distribute, and sell this software and its
+#  documentation for any purpose is hereby granted without fee, provided that
+#  the above copyright notice appear in all copies and that both that
+#  copyright notice and this permission notice appear in supporting
+#  documentation, and that the name of Red Hat not be used in
+#  advertising or publicity pertaining to distribution of the software without
+#  specific, written prior permission.  Red Hat makes no
+#  representations about the suitability of this software for any purpose.  It
+#  is provided "as is" without express or implied warranty.
+#
+#  RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+#  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+#  EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+#  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+#  DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+#  TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+#  PERFORMANCE OF THIS SOFTWARE.
+#
+
+AUTOMAKE_OPTIONS = foreign
+
+# Ensure headers are installed below $(prefix) for distcheck
+DISTCHECK_CONFIGURE_FLAGS = --with-sdkdir='$${includedir}/xorg'
+
+SUBDIRS = src man
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = xorg-gesture.pc
+
+EXTRA_DIST = ChangeLog
+
+MAINTAINERCLEANFILES=ChangeLog
+
+.PHONY: ChangeLog
+
+ChangeLog:
+       $(CHANGELOG_CMD)
+
+dist-hook: ChangeLog
diff --git a/mobile/NOTICE b/mobile/NOTICE
new file mode 100644 (file)
index 0000000..c10a9c5
--- /dev/null
@@ -0,0 +1,3 @@
+Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved.
+Except as noted, this software is licensed under MIT License.
+Please, see the LICENSE.MIT file for MIT License terms and conditions.
similarity index 100%
rename from autogen.sh
rename to mobile/autogen.sh
similarity index 52%
rename from configure.ac
rename to mobile/configure.ac
index 8f20226..16c2d38 100644 (file)
@@ -1,25 +1,23 @@
-#  Copyright 2007 Peter Hutterer
-#  Copyright 2009 Przemysław Firszt
+#  Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
 #
-#  Permission is hereby granted, free of charge, to any person obtaining a
-#  copy of this software and associated documentation files (the "Software"),
-#  to deal in the Software without restriction, including without limitation
-#  on the rights to use, copy, modify, merge, publish, distribute, sub
-#  license, and/or sell copies of the Software, and to permit persons to whom
-#  the Software is furnished to do so, subject to the following conditions:
+#  Permission to use, copy, modify, distribute, and sell this software and its
+#  documentation for any purpose is hereby granted without fee, provided that
+#  the above copyright notice appear in all copies and that both that
+#  copyright notice and this permission notice appear in supporting
+#  documentation, and that the name of Red Hat not be used in
+#  advertising or publicity pertaining to distribution of the software without
+#  specific, written prior permission.  Red Hat makes no
+#  representations about the suitability of this software for any purpose.  It
+#  is provided "as is" without express or implied warranty.
 #
-#  The above copyright notice and this permission notice (including the next
-#  paragraph) shall be included in all copies or substantial portions of the
-#  Software.
+#  RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+#  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+#  EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+#  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+#  DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+#  TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+#  PERFORMANCE OF THIS SOFTWARE.
 #
-#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-#  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-#  FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
-#  AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-#  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-#  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-# Process this file with autoconf to produce a configure script
 
 AC_PREREQ(2.57)
 AC_INIT([xserver-xorg-input-gesture],
@@ -56,7 +54,7 @@ AC_SUBST(inputdir)
 
 # Checks for pkg-config packages. We need to be able to override sdkdir
 # to satisfy silly distcheck requirements.
-PKG_CHECK_MODULES(XORG, xorg-server xproto $REQUIRED_MODULES)
+PKG_CHECK_MODULES(XORG, xorg-server xproto xdbg $REQUIRED_MODULES)
 XORG_CFLAGS="$CWARNFLAGS $XORG_CFLAGS"
 AC_ARG_WITH([sdkdir], [],
     [sdkdir="$withval"],
diff --git a/mobile/man/Makefile.am b/mobile/man/Makefile.am
new file mode 100644 (file)
index 0000000..b91dae4
--- /dev/null
@@ -0,0 +1,53 @@
+#  Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved 
+#
+#  Permission to use, copy, modify, distribute, and sell this software and its
+#  documentation for any purpose is hereby granted without fee, provided that
+#  the above copyright notice appear in all copies and that both that
+#  copyright notice and this permission notice appear in supporting
+#  documentation, and that the name of Red Hat not be used in
+#  advertising or publicity pertaining to distribution of the software without
+#  specific, written prior permission.  Red Hat makes no
+#  representations about the suitability of this software for any purpose.  It
+#  is provided "as is" without express or implied warranty.
+#
+#  RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+#  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+#  EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+#  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+#  DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+#  TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+#  PERFORMANCE OF THIS SOFTWARE.
+#
+
+drivermandir = $(DRIVER_MAN_DIR)
+
+driverman_PRE = @DRIVER_NAME@.man
+
+driverman_DATA = $(driverman_PRE:man=@DRIVER_MAN_SUFFIX@)
+
+EXTRA_DIST = @DRIVER_NAME@.man
+
+CLEANFILES = $(driverman_DATA)
+
+SED = sed
+
+# Strings to replace in man pages
+XORGRELSTRING = @PACKAGE_STRING@
+  XORGMANNAME = X Version 11
+
+MAN_SUBSTS = \
+       -e 's|__vendorversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \
+       -e 's|__xorgversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \
+       -e 's|__xservername__|Xorg|g' \
+       -e 's|__xconfigfile__|xorg.conf|g' \
+       -e 's|__projectroot__|$(prefix)|g' \
+       -e 's|__appmansuffix__|$(APP_MAN_SUFFIX)|g' \
+       -e 's|__drivermansuffix__|$(DRIVER_MAN_SUFFIX)|g' \
+       -e 's|__adminmansuffix__|$(ADMIN_MAN_SUFFIX)|g' \
+       -e 's|__miscmansuffix__|$(MISC_MAN_SUFFIX)|g' \
+       -e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g'
+
+SUFFIXES = .$(DRIVER_MAN_SUFFIX) .man
+
+.man.$(DRIVER_MAN_SUFFIX):
+       sed $(MAN_SUBSTS) < $< > $@
similarity index 100%
rename from man/gesture.man
rename to mobile/man/gesture.man
diff --git a/mobile/src/Makefile.am b/mobile/src/Makefile.am
new file mode 100644 (file)
index 0000000..695f833
--- /dev/null
@@ -0,0 +1,37 @@
+#  Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved 
+#
+#  Permission to use, copy, modify, distribute, and sell this software and its
+#  documentation for any purpose is hereby granted without fee, provided that
+#  the above copyright notice appear in all copies and that both that
+#  copyright notice and this permission notice appear in supporting
+#  documentation, and that the name of Red Hat not be used in
+#  advertising or publicity pertaining to distribution of the software without
+#  specific, written prior permission.  Red Hat makes no
+#  representations about the suitability of this software for any purpose.  It
+#  is provided "as is" without express or implied warranty.
+#
+#  RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+#  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+#  EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+#  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+#  DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+#  TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+#  PERFORMANCE OF THIS SOFTWARE.
+#
+
+# this is obnoxious:
+# -module lets us name the module exactly how we want
+# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
+# _ladir passes a dummy rpath to libtool so the thing will actually link
+# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
+AM_CFLAGS = $(XORG_CFLAGS)
+
+@DRIVER_NAME@_drv_la_LTLIBRARIES = @DRIVER_NAME@_drv.la
+@DRIVER_NAME@_drv_la_LDFLAGS = -module -avoid-version
+@DRIVER_NAME@_drv_ladir = @inputdir@
+
+INCLUDES=-I$(top_srcdir)/include/
+
+@DRIVER_NAME@_drv_la_SOURCES = @DRIVER_NAME@.c \
+                               @DRIVER_NAME@.h 
+
diff --git a/mobile/src/gesture.c b/mobile/src/gesture.c
new file mode 100644 (file)
index 0000000..c85ffed
--- /dev/null
@@ -0,0 +1,6487 @@
+/**************************************************************************
+
+xserver-xorg-input-gesture
+
+Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+
+Contact: Sung-Jin Park <sj76.park@samsung.com>
+         Sangjin LEE <lsj119@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <linux/input.h>
+#include <linux/types.h>
+
+#include <xf86_OSproc.h>
+
+#include <unistd.h>
+
+#include <xf86.h>
+#include <xf86Xinput.h>
+#include <exevents.h>
+#include <xorgVersion.h>
+#include <xkbsrv.h>
+
+#ifdef HAVE_PROPERTIES
+#include <X11/Xatom.h>
+#include <xserver-properties.h>
+/* 1.6 has properties, but no labels */
+#ifdef AXIS_LABEL_PROP
+#define HAVE_LABELS
+#else
+#undef HAVE_LABELS
+#endif
+
+#endif
+
+#include <X11/Xatom.h>
+
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <xorg-server.h>
+#include <xorgVersion.h>
+#include <xf86Module.h>
+#include <X11/Xatom.h>
+#include "gesture.h"
+#include <xorg/mi.h>
+#include <xdbg.h>
+
+#define MGEST  XDBG_M('G','E','S','T')
+
+static const void(*PalmRecognize)(int, InternalEvent*, DeviceIntPtr);
+
+#define _GESTUREPALMRECOGNIZE_(function, type, ev, device)     \
+       if(function)    \
+       {       \
+               XDBG_WARNING(MGEST, "[_GESTUREPALMRECOGNIZE_] Enable GesturePalmRecognize. type=%d\n", type);   \
+               function(type, ev, device);     \
+       }       \
+       else    \
+       {       \
+               XDBG_WARNING(MGEST, "[_GESTUREPALMRECOGNIZE_] Disable GesturePalmRecognize \n");        \
+       }       \
+
+static void printk(const char* fmt, ...) __attribute__((format(printf, 1, 0)));
+extern char *strcasestr(const char *s, const char *find);
+extern ScreenPtr miPointerCurrentScreen(void);
+extern EventQueuePtr mieqGetEventQueuePtr();
+
+static Bool GestureIsEventInMIEQ(int finger_index, enum EventType type);
+static int GestureGetFingerIndexFromDevice(DeviceIntPtr device);
+static int GestureGetDeviceIdFromFingerIndex(int finger_index);
+static Bool GestureIsPalmEventInMIEQ(void);
+static Bool GestureIsPalmEvent(InternalEvent *event);
+static int GestureGetMTToolValuator(InternalEvent *ev, DeviceIntPtr device);
+static void GestureRegisterTouchInfo(InternalEvent *ev, DeviceIntPtr device);
+static void GestureSetToolData(InternalEvent *ev, double val_tool);
+static void GestureCleanupTouch(int screen_num, InternalEvent *ev, DeviceIntPtr device);
+static void GestureChangeEventToFirstFingerEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
+
+//Basic functions
+static int GesturePreInit(InputDriverPtr  drv, InputInfoPtr pInfo, int flags);
+static void GestureUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags);
+static pointer GesturePlug(pointer module, pointer options, int *errmaj, int  *errmin);
+static void GestureUnplug(pointer p);
+static int GestureControl(DeviceIntPtr    device,int what);
+static int GestureInit(DeviceIntPtr device);
+static void GestureFini(DeviceIntPtr device);
+static void GestureReadInput(InputInfoPtr pInfo);
+
+//other initializers
+ErrorStatus GestureRegionsInit(void);
+
+//event queue handling functions
+ErrorStatus GestureInitEQ(void);
+ErrorStatus GestureFiniEQ(void);
+ErrorStatus GestureEnqueueEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
+ErrorStatus GestureEventsFlush(void);
+void GestureEventsDrop(void);
+
+//utility functions
+ErrorStatus GestureRegionsReinit(void);
+void GestureEnable(int enable, Bool prop, DeviceIntPtr dev);
+static inline void GestureEnableDisable();
+void GestureCbEventsGrabbed(Mask *pGrabMask, GestureGrabEventPtr *pGrabEvent);
+void GestureCbEventsSelected(Window win, Mask *pEventMask);
+WindowPtr GestureGetEventsWindow(void);
+static Bool GestureHasFingersEvents(int eventType);
+
+//Enqueued event handlers and enabler/disabler
+static ErrorStatus GestureEnableEventHandler(InputInfoPtr pInfo);
+static ErrorStatus GestureDisableEventHandler(void);
+static CARD32 GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg);
+void GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
+void GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
+void GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
+void GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
+void GestureHandleKeyPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
+void GestureHandleKeyReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
+
+static void GestureRegisterDeviceInfo(DeviceIntPtr device);
+
+//Gesture recognizer helper
+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 21
+static Bool PointInBorderSize(WindowPtr pWin, int x, int y);
+#endif
+static WindowPtr GestureWindowOnXY(int x, int y);
+Bool GestureHasFingerEventMask(int eventType, int num_finger);
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+static int get_distance(int x1, int y1, int x2, int y2);
+#endif
+static double get_angle(int x1, int y1, int x2, int y2);
+
+//Gesture recognizer and handlers
+void GestureRecognize_GroupPinchRotation(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
+void GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx);
+void GestureRecognize_GroupPan(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
+void GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
+void GestureRecognize_GroupTapNHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
+void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+int GestureBezelAngleRecognize(int type, int distance, double angle);
+#endif
+void GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int direction);
+void GestureHandleGesture_Tap(int num_finger, int tap_repeat, int cx, int cy);
+void GestureHandleGesture_PinchRotation(int num_of_fingers, double zoom, double angle, int distance, int cx, int cy, int kinds);
+void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds);
+void GestureHandleGesture_TapNHold(int num_fingers, int cx, int cy, Time interval, Time holdtime, int kinds);
+void GestureHandleGesture_Pan(int num_fingers, short int dx, short int dy, int direction, int distance, Time duration, int kinds);
+static void GestureHoldDetector(int type, InternalEvent *ev, DeviceIntPtr device);
+void GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device);
+ErrorStatus GestureFlushOrDrop(void);
+
+static int GesturePalmGetHorizIndexWithX(int x, int type);
+static int GesturePalmGetVertiIndexWithY(int y, int type);
+static void GesturePalmRecognize_FlickHorizen(int type, int idx);
+static void GesturePalmRecognize_FlickVertical(int type,int idx);
+static int GesturePalmGetScreenInfo();
+static int GesturePalmGetAbsAxisInfo(DeviceIntPtr dev);
+static void GesturePalmDataUpdate(int idx, int type, InternalEvent *ev, DeviceIntPtr device);
+static void GesturePalmUpdateAreaInfo(int type, int idx);
+void GesturePalmRecognize(int type, InternalEvent *ev, DeviceIntPtr device);
+
+void GestureGenerateTouchCancelEvent(void);
+
+static void GestureDPMSCallback(CallbackListPtr *pcbl, void *unused, void *calldata);
+
+//#define __PALM_GESTURE_LOG__
+//#define __PALM_DETAIL_LOG__
+//#define __DETAIL_DEBUG__
+//#define __BEZEL_DEBUG__
+//#define __DEBUG_EVENT_HANDLER__
+
+#ifdef HAVE_PROPERTIES
+//function related property handling
+static void GestureInitProperty(DeviceIntPtr dev);
+static int GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, BOOL checkonly);
+#endif
+
+static Atom prop_gesture_recognizer_onoff = None;
+static Atom prop_gesture_palm_rejection_mode = None;
+
+#ifdef SUPPORT_ANR_WITH_INPUT_EVENT
+static Atom prop_anr_in_input_event = None;
+static Atom prop_anr_event_window = None;
+static Window prop_anr_event_window_xid = None;
+#endif
+
+GestureDevicePtr g_pGesture = NULL;
+_X_EXPORT InputDriverRec GESTURE = {
+    1,
+    "gesture",
+    NULL,
+    GesturePreInit,
+    GestureUnInit,
+    NULL,
+    0
+};
+
+static XF86ModuleVersionInfo GestureVersionRec =
+{
+    "gesture",
+    MODULEVENDORSTRING,
+    MODINFOSTRING1,
+    MODINFOSTRING2,
+    XORG_VERSION_CURRENT,
+    PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR,
+    PACKAGE_VERSION_PATCHLEVEL,
+    ABI_CLASS_XINPUT,
+    ABI_XINPUT_VERSION,
+    MOD_CLASS_XINPUT,
+    {0, 0, 0, 0}
+};
+
+_X_EXPORT XF86ModuleData gestureModuleData =
+{
+    &GestureVersionRec,
+    &GesturePlug,
+    &GestureUnplug
+};
+
+extern CallbackListPtr DPMSCallback;
+
+static void
+printk(const char* fmt, ...)
+{
+       static FILE* fp = NULL;
+       static char init = 0;
+       va_list argptr;
+
+       if(!init && !fp)
+       {
+               fp = fopen("/dev/kmsg", "wt");
+               init = 1;
+       }
+
+       if(!fp) return;
+
+       va_start(argptr, fmt);
+       vfprintf(fp, fmt, argptr);
+       fflush(fp);
+       va_end(argptr);
+}
+
+#ifdef SUPPORT_ANR_WITH_INPUT_EVENT
+static WindowPtr
+_GestureFindANRWindow(DeviceIntPtr device)
+{
+    WindowPtr root=NULL;
+    WindowPtr anr_window=NULL;
+    Window anr_xid=0;
+    PropertyPtr pProp;
+    int rc=0;
+
+    root = RootWindow(device);
+
+    if( prop_anr_event_window == None )
+        prop_anr_event_window = MakeAtom(ANR_EVENT_WINDOW, strlen(ANR_EVENT_WINDOW), TRUE);
+
+    rc = dixLookupProperty (&pProp, root, prop_anr_event_window, serverClient, DixReadAccess);
+    if (rc == Success && pProp->data){
+        anr_xid = *(int*)pProp->data;
+    }
+
+    if( anr_xid != 0 )
+    {
+        rc = dixLookupWindow(&anr_window, anr_xid, serverClient, DixSetPropAccess);
+        if( rc == BadWindow )
+        {
+            XDBG_ERROR(MGEST, "Can't find ANR window !!\n");
+            anr_window = NULL;
+        }
+        prop_anr_event_window_xid = anr_xid;
+    }
+
+    XDBG_DEBUG(MGEST, "ANR Window is %#x. Ptr is %#x\n", anr_xid, anr_window);
+    return anr_window;
+}
+#endif
+
+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 21
+static Bool
+PointInBorderSize(WindowPtr pWin, int x, int y)
+{
+    BoxRec box;
+    if (pixman_region_contains_point (&pWin->borderSize, x, y, &box))
+    {
+        return TRUE;
+    }
+    return FALSE;
+}
+#endif
+
+static WindowPtr
+GestureWindowOnXY(int x, int y)
+{
+    WindowPtr pWin;
+    BoxRec box;
+    SpritePtr pSprite;
+    DeviceIntPtr pDev = g_pGesture->master_pointer;
+
+    pSprite = pDev->spriteInfo->sprite;
+    pSprite->spriteTraceGood = 1;      /* root window still there */
+    pWin = RootWindow(pDev)->firstChild;
+    while (pWin)
+    {
+       if ((pWin->mapped) &&
+           (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
+           (x < pWin->drawable.x + (int)pWin->drawable.width +
+            wBorderWidth(pWin)) &&
+           (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
+           (y < pWin->drawable.y + (int)pWin->drawable.height +
+            wBorderWidth (pWin))
+           /* When a window is shaped, a further check
+            * is made to see if the point is inside
+            * borderSize
+            */
+           && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
+           && (!wInputShape(pWin) ||
+               RegionContainsPoint(wInputShape(pWin),
+                                   x - pWin->drawable.x,
+                                   y - pWin->drawable.y, &box))
+#ifdef ROOTLESS
+    /* In rootless mode windows may be offscreen, even when
+     * they're in X's stack. (E.g. if the native window system
+     * implements some form of virtual desktop system).
+     */
+               && !pWin->rootlessUnhittable
+#endif
+           )
+       {
+           if (pSprite->spriteTraceGood >= pSprite->spriteTraceSize)
+           {
+               pSprite->spriteTraceSize += 10;
+               pSprite->spriteTrace = realloc(pSprite->spriteTrace,
+                                   pSprite->spriteTraceSize*sizeof(WindowPtr));
+               if (!pSprite->spriteTrace) {
+                   return NULL;
+               }
+
+           }
+           pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin;
+           pWin = pWin->firstChild;
+       }
+       else
+           pWin = pWin->nextSib;
+    }
+    return pSprite->spriteTrace[pSprite->spriteTraceGood-1];
+}
+
+Bool
+GestureHasFingerEventMask(int eventType, int num_finger)
+{
+       Bool ret = FALSE;
+       Mask eventmask = (1L << eventType);
+
+       if( (g_pGesture->grabMask & eventmask) &&
+               (g_pGesture->GrabEvents[eventType].pGestureGrabWinInfo[num_finger].window != None) )
+       {
+#ifdef __DETAIL_DEBUG__
+               XDBG_DEBUG(MGEST, "TRUE !! Has grabMask\n");
+#endif//__DETAIL_DEBUG__
+               return TRUE;
+       }
+
+       if( g_pGesture->eventMask & eventmask )
+       {
+#ifdef __DETAIL_DEBUG__
+               XDBG_DEBUG(MGEST, "TRUE !! Has eventMask\n");
+#endif//__DETAIL_DEBUG__
+               return TRUE;
+       }
+
+#ifdef __DETAIL_DEBUG__
+       XDBG_DEBUG(MGEST, "FALSE !! eventType=%d, num_finger=%d\n", eventType, num_finger);
+#endif//__DETAIL_DEBUG__
+
+       return ret;
+}
+
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+static int
+get_distance(int _x1, int _y1, int _x2, int _y2)
+{
+       int xx, yy;
+       xx = ABS(_x2 - _x1);
+       yy = ABS(_y2 - _y1);
+
+       if(xx && yy)
+       {
+               return (int)sqrt(pow(xx, 2) + pow(yy, 2));
+       }
+       else if(xx)
+       {
+               return yy;
+       }
+       else if(yy)
+       {
+               return xx;
+       }
+       else
+       {
+               return 0;
+       }
+}
+#endif//_F_SUPPORT_BEZEL_FLICK_
+
+static double
+get_angle(int _x1, int _y1, int _x2, int _y2)
+{
+   double a, xx, yy;
+   xx = fabs(_x2 - _x1);
+   yy = fabs(_y2 - _y1);
+
+   if (((int) xx) && ((int) yy))
+     {
+        a = atan(yy / xx);
+        if (_x1 < _x2)
+          {
+             if (_y1 < _y2)
+               {
+                  return (RAD_360DEG - a);
+               }
+             else
+               {
+                  return (a);
+               }
+          }
+        else
+          {
+             if (_y1 < _y2)
+               {
+                  return (RAD_180DEG + a);
+               }
+             else
+               {
+                  return (RAD_180DEG - a);
+               }
+          }
+     }
+
+   if (((int) xx))
+     {  /* Horizontal line */
+        if (_x2 < _x1)
+          {
+             return (RAD_180DEG);
+          }
+        else
+          {
+             return (0.0);
+          }
+     }
+
+   /* Vertical line */
+   if (_y2 < _y1)
+     {
+        return (RAD_90DEG);
+     }
+   else
+     {
+        return (RAD_270DEG);
+     }
+}
+
+void
+GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int direction)
+{
+       Window target_win;
+       WindowPtr target_pWin;
+       xGestureNotifyFlickEvent fev;
+
+#ifdef __DETAIL_DEBUG__
+       XDBG_DEBUG(MGEST, "num_fingers=%d, distance=%d, duration=%d, direction=%d\n",
+               num_of_fingers, distance, duration, direction);
+#endif//__DETAIL_DEBUG__
+
+       if(num_of_fingers == 0)
+       {
+               if(direction == FLICK_EASTWARD || direction == FLICK_WESTWARD)
+                       g_pGesture->recognized_palm |= PalmFlickHorizFilterMask;
+               if(direction == FLICK_NORTHWARD || direction == FLICK_SOUTHWARD)
+                       g_pGesture->recognized_palm |= PalmFlickVertiFilterMask;
+       }
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+       else if(num_of_fingers == 1)
+       {
+               g_pGesture->bezel_recognized_mask |= BezelFlickFilterMask;
+       }
+#endif
+       else
+               g_pGesture->recognized_gesture |= FlickFilterMask;
+
+       memset(&fev, 0, sizeof(xGestureNotifyFlickEvent));
+       fev.type = GestureNotifyFlick;
+       fev.kind = GestureDone;
+       fev.num_finger = num_of_fingers;
+       fev.distance = distance;
+       fev.duration = duration;
+       fev.direction = direction;
+
+       if(g_pGesture->GrabEvents)
+       {
+               target_win = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].window;
+               target_pWin = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].pWin;
+       }
+       else
+       {
+               target_win = None;
+               target_pWin = None;
+       }
+
+       if( g_pGesture->grabMask && (target_win != None) )
+       {
+               fev.window = target_win;
+       }
+       else
+       {
+               fev.window = g_pGesture->gestureWin;
+       }
+
+#ifdef __DETAIL_DEBUG__
+       XDBG_DEBUG(MGEST, "fev.window=0x%x, g_pGesture->grabMask=0x%x\n", fev.window, g_pGesture->grabMask);
+#endif//__DETAIL_DEBUG__
+
+       GestureSendEvent(target_pWin, GestureNotifyFlick, GestureFlickMask, (xGestureCommonEvent *)&fev);
+}
+
+void
+GestureHandleGesture_Tap(int num_finger, int tap_repeat, int cx, int cy)
+{
+       Window target_win;
+       WindowPtr target_pWin;
+       xGestureNotifyTapEvent tev;
+
+       //skip non-tap events and single finger tap
+       if( !tap_repeat || num_finger <= 1 )
+               return;
+
+#ifdef __DETAIL_DEBUG__
+       XDBG_DEBUG(MGEST, "num_finger=%d, tap_repeat=%d, cx=%d, cy=%d\n",
+               num_finger, tap_repeat, cx, cy);
+#endif//__DETAIL_DEBUG__
+
+       g_pGesture->recognized_gesture |= TapFilterMask;
+       memset(&tev, 0, sizeof(xGestureNotifyTapEvent));
+       tev.type = GestureNotifyTap;
+       tev.kind = GestureDone;
+       tev.num_finger = num_finger;
+       tev.tap_repeat = tap_repeat;
+       tev.interval = 0;
+       tev.cx = cx;
+       tev.cy = cy;
+
+       if(g_pGesture->GrabEvents)
+       {
+               target_win = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].window;
+               target_pWin = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].pWin;
+       }
+       else
+       {
+               target_win = None;
+               target_pWin = None;
+       }
+
+       if( g_pGesture->grabMask && (target_win != None) )
+       {
+               tev.window = target_win;
+       }
+       else
+       {
+               tev.window = g_pGesture->gestureWin;
+       }
+
+#ifdef __DETAIL_DEBUG__
+       XDBG_DEBUG(MGEST, "tev.window=0x%x, g_pGesture->grabMask=0x%x\n", tev.window, g_pGesture->grabMask);
+#endif//__DETAIL_DEBUG__
+
+       GestureSendEvent(target_pWin, GestureNotifyTap, GestureTapMask, (xGestureCommonEvent *)&tev);
+}
+
+void GestureHandleGesture_PinchRotation(int num_of_fingers, double zoom, double angle, int distance, int cx, int cy, int kinds)
+{
+       Window target_win;
+       WindowPtr target_pWin;
+       xGestureNotifyPinchRotationEvent prev;
+
+#ifdef __DETAIL_DEBUG__
+       XDBG_DEBUG(MGEST, "num_fingers=%d, zoom=%.2f, angle=%.2f(deg=%.2f), distance=%d, cx=%d, cy=%d\n",
+                               num_of_fingers, zoom, angle, rad2degree(angle), distance, cx, cy);
+#endif//__DETAIL_DEBUG__
+
+       g_pGesture->recognized_gesture |= PinchRotationFilterMask;
+       memset(&prev, 0, sizeof(xGestureNotifyPinchRotationEvent));
+       prev.type = GestureNotifyPinchRotation;
+       prev.kind = kinds;
+       prev.num_finger = num_of_fingers;
+       prev.zoom = XDoubleToFixed(zoom);
+       prev.angle = XDoubleToFixed(angle);
+       prev.distance = distance;
+       prev.cx = cx;
+       prev.cy = cy;
+
+       if(g_pGesture->GrabEvents)
+       {
+               target_win = g_pGesture->GrabEvents[GestureNotifyPinchRotation].pGestureGrabWinInfo[num_of_fingers].window;
+               target_pWin = g_pGesture->GrabEvents[GestureNotifyPinchRotation].pGestureGrabWinInfo[num_of_fingers].pWin;
+       }
+       else
+       {
+               target_win = None;
+               target_pWin = None;
+       }
+
+       if( g_pGesture->grabMask && (target_win != None) )
+       {
+               prev.window = target_win;
+       }
+       else
+       {
+               prev.window = g_pGesture->gestureWin;
+       }
+
+#ifdef __DETAIL_DEBUG__
+       XDBG_DEBUG(MGEST, "prev.window=0x%x, g_pGesture->grabMask=0x%x\n", (unsigned int)prev.window, (unsigned int)g_pGesture->grabMask);
+#endif//__DETAIL_DEBUG__
+
+       GestureSendEvent(target_pWin, GestureNotifyPinchRotation, GesturePinchRotationMask, (xGestureCommonEvent *)&prev);
+}
+
+void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds)
+{
+       Window target_win;
+       WindowPtr target_pWin;
+       xGestureNotifyHoldEvent hev;
+
+#ifdef __DETAIL_DEBUG__
+       XDBG_DEBUG(MGEST, "num_fingers=%d, cx=%d, cy=%d, holdtime=%d, kinds=%d\n",
+                               num_fingers, cx, cy, holdtime, kinds);
+#endif//__DETAIL_DEBUG__
+
+       if(num_fingers == 0)
+               g_pGesture->hold_detected = TRUE;
+       else
+               g_pGesture->recognized_gesture |= HoldFilterMask;
+       memset(&hev, 0, sizeof(xGestureNotifyHoldEvent));
+       hev.type = GestureNotifyHold;
+       hev.kind = kinds;
+       hev.num_finger = num_fingers;
+       hev.holdtime = holdtime;
+       hev.cx = cx;
+       hev.cy = cy;
+
+       if(g_pGesture->GrabEvents)
+       {
+               target_win = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].window;
+               target_pWin = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].pWin;
+       }
+       else
+       {
+               target_win = None;
+               target_pWin = None;
+       }
+
+       if( g_pGesture->grabMask && (target_win != None) )
+       {
+               hev.window = target_win;
+       }
+       else
+       {
+               hev.window = g_pGesture->gestureWin;
+       }
+
+#ifdef __DETAIL_DEBUG__
+       XDBG_DEBUG(MGEST, "hev.window=0x%x, g_pGesture->grabMask=0x%x\n", hev.window, g_pGesture->grabMask);
+#endif//__DETAIL_DEBUG__
+
+       GestureSendEvent(target_pWin, GestureNotifyHold, GestureHoldMask, (xGestureCommonEvent *)&hev);
+}
+
+void GestureHandleGesture_TapNHold(int num_fingers, int cx, int cy, Time interval, Time holdtime, int kinds)
+{
+       Window target_win;
+       WindowPtr target_pWin;
+       xGestureNotifyTapNHoldEvent thev;
+
+#ifdef __DETAIL_DEBUG__
+       XDBG_DEBUG(MGEST, "num_fingers=%d, cx=%d, cy=%d, interval=%d, holdtime=%d, kinds=%d\n",
+                               num_fingers, cx, cy, interval, holdtime, kinds);
+#endif//__DETAIL_DEBUG__
+
+       g_pGesture->recognized_gesture |= TapNHoldFilterMask;
+       memset(&thev, 0, sizeof(xGestureNotifyTapNHoldEvent));
+       thev.type = GestureNotifyTapNHold;
+       thev.kind = kinds;
+       thev.num_finger = num_fingers;
+       thev.holdtime = holdtime;
+       thev.cx = cx;
+       thev.cy = cy;
+       thev.interval = interval;
+
+       if(g_pGesture->GrabEvents)
+       {
+               target_win = g_pGesture->GrabEvents[GestureNotifyTapNHold].pGestureGrabWinInfo[num_fingers].window;
+               target_pWin = g_pGesture->GrabEvents[GestureNotifyTapNHold].pGestureGrabWinInfo[num_fingers].pWin;
+       }
+       else
+       {
+               target_win = None;
+               target_pWin = None;
+       }
+
+       if( g_pGesture->grabMask && (target_win != None) )
+       {
+               thev.window = target_win;
+       }
+       else
+       {
+               thev.window = g_pGesture->gestureWin;
+       }
+
+#ifdef __DETAIL_DEBUG__
+       XDBG_DEBUG(MGEST, "thev.window=0x%x, g_pGesture->grabMask=0x%x\n", thev.window, g_pGesture->grabMask);
+#endif//__DETAIL_DEBUG__
+
+       GestureSendEvent(target_pWin, GestureNotifyTapNHold, GestureTapNHoldMask, (xGestureCommonEvent *)&thev);
+}
+
+void GestureHandleGesture_Pan(int num_fingers, short int dx, short int dy, int direction, int distance, Time duration, int kinds)
+{
+       Window target_win;
+       WindowPtr target_pWin;
+       xGestureNotifyPanEvent pev;
+
+#ifdef __DETAIL_DEBUG__
+       XDBG_DEBUG(MGEST, "num_fingers=%d, dx=%d, dy=%d, direction=%d, distance=%d, duration=%d, kinds=%d\n",
+                               num_fingers, dx, dy, direction, distance, duration, kinds);
+#endif//__DETAIL_DEBUG__
+
+       g_pGesture->recognized_gesture |= PanFilterMask;
+       memset(&pev, 0, sizeof(xGestureNotifyPanEvent));
+       pev.type = GestureNotifyPan;
+       pev.kind = kinds;
+       pev.num_finger = num_fingers;
+       pev.direction = direction;
+       pev.distance = distance;
+       pev.duration = duration;
+       pev.dx = dx;
+       pev.dy = dy;
+
+       if(g_pGesture->GrabEvents)
+       {
+               target_win = g_pGesture->GrabEvents[GestureNotifyPan].pGestureGrabWinInfo[num_fingers].window;
+               target_pWin = g_pGesture->GrabEvents[GestureNotifyPan].pGestureGrabWinInfo[num_fingers].pWin;
+       }
+       else
+       {
+               target_win = None;
+               target_pWin = None;
+       }
+
+       if( g_pGesture->grabMask && (target_win != None) )
+       {
+               pev.window = target_win;
+       }
+       else
+       {
+               pev.window = g_pGesture->gestureWin;
+       }
+
+#ifdef __DETAIL_DEBUG__
+       XDBG_DEBUG(MGEST, "pev.window=0x%x, g_pGesture->grabMask=0x%x\n", pev.window, g_pGesture->grabMask);
+#endif//__DETAIL_DEBUG__
+
+       GestureSendEvent(target_pWin, GestureNotifyPan, GesturePanMask, (xGestureCommonEvent *)&pev);
+}
+
+static void GestureHoldDetector(int type, InternalEvent *ev, DeviceIntPtr device)
+{
+       int i;
+       int idx = -1;
+       pixman_region16_t tarea1;
+       static int num_pressed = 0;
+       unsigned int hold_area_size;
+       PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
+
+       if(!g_pGesture->hold_detector_activate)
+       {
+#ifdef __HOLD_DETECTOR_DEBUG__
+               XDBG_DEBUG(MGEST, "g_pGesture->hold_detector_activate=0\n");
+#endif//__HOLD_DETECTOR_DEBUG__
+               return;
+       }
+
+       if(!g_pGesture->has_hold_grabmask)
+       {
+               Mask eventmask = (1L << GestureNotifyHold);
+
+               if( (g_pGesture->grabMask & eventmask) &&
+               (g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[0].window != None) )
+               {
+                       g_pGesture->has_hold_grabmask = 1;
+
+                       //Initialize a set of variables
+                       num_pressed = 0;
+                       memset(&g_pGesture->cts, 0, sizeof(g_pGesture->cts));
+                       pixman_region_init(&g_pGesture->chold_area);
+#ifdef __HOLD_DETECTOR_DEBUG__
+                       XDBG_DEBUG(MGEST, "[%d] Initialize...\n", __LINE__);
+#endif//__HOLD_DETECTOR_DEBUG__
+               }
+               else
+               {
+                       //reset local hold_grab_mask variable
+                       g_pGesture->has_hold_grabmask = 0;
+
+                       g_pGesture->hold_detector_activate = 0;
+#ifdef __HOLD_DETECTOR_DEBUG__
+                       XDBG_DEBUG(MGEST, "has_hold_grabmask=0 and g_pGesture->hold_detector_activate=0\n");
+#endif//__HOLD_DETECTOR_DEBUG__
+                       return;
+               }               
+       }
+
+       if( IGNORE_EVENTS == g_pGesture->ehtype ||
+               device->id < g_pGesture->first_fingerid )
+       {
+#ifdef __HOLD_DETECTOR_DEBUG__
+               XDBG_DEBUG(MGEST, "Return (IGNORE_EVENTS or device->id:%d < first_fingerid:%d)\n", device->id, g_pGesture->first_fingerid);
+#endif//__HOLD_DETECTOR_DEBUG__
+               return;
+       }
+
+       for( i = 0 ; i < g_pGesture->num_mt_devices ; i++ )
+       {
+               if( device->id == g_pGesture->mt_devices[i]->id )
+               {
+                       idx = i;
+                       break;
+               }
+       }
+       if( (idx < 0) || ((MAX_MT_DEVICES-1) < idx )) return;
+
+       switch( type )
+       {
+               case ET_ButtonPress:
+                       g_pGesture->cts[idx].status = BTN_PRESSED;
+                       g_pGesture->cts[idx].cx = ev->device_event.root_x;
+                       g_pGesture->cts[idx].cy = ev->device_event.root_y;
+
+                       num_pressed++;
+                       if(num_pressed < 3) break;
+
+                       if( num_pressed > g_pGesture->num_mt_devices )
+                               num_pressed = g_pGesture->num_mt_devices;
+
+                       pixman_region_init(&tarea1);
+                       pixman_region_init(&g_pGesture->chold_area);
+                       pixman_region_init_rect(&tarea1, g_pGesture->cts[0].cx, g_pGesture->cts[0].cy, g_pGesture->cts[0].cx+1, g_pGesture->cts[0].cy+1);
+
+                       tarea1.extents.x1 = g_pGesture->cts[0].cx;
+                       tarea1.extents.x2 = g_pGesture->cts[0].cx+1;
+                       tarea1.extents.y1 = g_pGesture->cts[0].cy;
+                       tarea1.extents.y2 = g_pGesture->cts[0].cy+1;
+
+                       pixman_region_union(&g_pGesture->chold_area, &tarea1, &tarea1);
+
+                       for( i = 1 ; i < num_pressed ; i++ )
+                       {
+                                       pixman_region_init_rect(&tarea1, g_pGesture->cts[i].cx, g_pGesture->cts[i].cy, g_pGesture->cts[i].cx + 1, g_pGesture->cts[i].cy + 1);
+
+                                       tarea1.extents.x1 = g_pGesture->cts[i].cx;
+                                       tarea1.extents.x2 = g_pGesture->cts[i].cx + 1;
+                                       tarea1.extents.y1 = g_pGesture->cts[i].cy;
+                                       tarea1.extents.y2 = g_pGesture->cts[i].cy + 1;
+
+                                       pixman_region_union(&g_pGesture->chold_area, &g_pGesture->chold_area, &tarea1);
+                       }
+                       break;
+
+               case ET_Motion:
+                       if(BTN_RELEASED == g_pGesture->cts[idx].status)
+                               return;
+
+                       g_pGesture->cts[idx].status = BTN_MOVING;
+                       g_pGesture->cts[idx].cx = ev->device_event.root_x;
+                       g_pGesture->cts[idx].cy = ev->device_event.root_y;
+
+                       if(num_pressed < 3) break;
+
+                       pixman_region_init(&tarea1);
+                       pixman_region_init(&g_pGesture->chold_area);
+                       pixman_region_init_rect(&tarea1, g_pGesture->cts[0].cx, g_pGesture->cts[0].cy, g_pGesture->cts[0].cx+1, g_pGesture->cts[0].cy+1);
+
+                       tarea1.extents.x1 = g_pGesture->cts[0].cx;
+                       tarea1.extents.x2 = g_pGesture->cts[0].cx+1;
+                       tarea1.extents.y1 = g_pGesture->cts[0].cy;
+                       tarea1.extents.y2 = g_pGesture->cts[0].cy+1;
+
+                       pixman_region_union(&g_pGesture->chold_area, &tarea1, &tarea1);
+
+                       for( i = 1 ; i < num_pressed ; i++ )
+                       {
+                                       pixman_region_init_rect(&tarea1, g_pGesture->cts[i].cx, g_pGesture->cts[i].cy, g_pGesture->cts[i].cx + 1, g_pGesture->cts[i].cy + 1);
+
+                                       tarea1.extents.x1 = g_pGesture->cts[i].cx;
+                                       tarea1.extents.x2 = g_pGesture->cts[i].cx + 1;
+                                       tarea1.extents.y1 = g_pGesture->cts[i].cy;
+                                       tarea1.extents.y2 = g_pGesture->cts[i].cy + 1;
+
+                                       pixman_region_union(&g_pGesture->chold_area, &g_pGesture->chold_area, &tarea1);
+                       }
+                       break;
+
+               case ET_ButtonRelease:
+                       g_pGesture->cts[idx].status = BTN_RELEASED;
+                       g_pGesture->cts[idx].cx = ev->device_event.root_x;
+                       g_pGesture->cts[idx].cy = ev->device_event.root_y;
+
+                       num_pressed--;
+                       if(num_pressed <3)
+                       {
+                               pixman_region_init(&g_pGesture->chold_area);
+                       }
+                       break;
+       }
+
+       if(num_pressed >= 3)
+       {
+               hold_area_size = AREA_SIZE(&g_pGesture->chold_area.extents);
+
+#ifdef __HOLD_DETECTOR_DEBUG__
+               XDBG_DEBUG(MGEST, "hold_area_size=%d, pPalmMisc->half_scrn_area_size=%d\n", hold_area_size, pPalmMisc->half_scrn_area_size);
+#endif//__HOLD_DETECTOR_DEBUG__
+
+               if(pPalmMisc->half_scrn_area_size <= hold_area_size)
+               {
+                       GestureHandleGesture_Hold(0, AREA_CENTER_X(&g_pGesture->chold_area.extents), AREA_CENTER_Y(&g_pGesture->chold_area.extents), PALM_HOLD_TIME_THRESHOLD, GestureBegin);
+                       GestureHandleGesture_Hold(0, AREA_CENTER_X(&g_pGesture->chold_area.extents), AREA_CENTER_Y(&g_pGesture->chold_area.extents), PALM_HOLD_TIME_THRESHOLD, GestureEnd);
+
+                       g_pGesture->hold_detector_activate = 0;
+                       g_pGesture->has_hold_grabmask = 0;
+               }
+       }
+}
+
+void
+GestureRecognize_GroupPinchRotation(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
+{
+       static int cx, cy;
+
+       static int num_pressed = 0;
+       static int state = GestureEnd;
+       static int event_type = GestureNotifyPinchRotation;
+       static OsTimerPtr pinchrotation_event_timer = NULL;
+
+       static pixman_region16_t base_area;
+       static pixman_region16_t cur_area;
+
+       static double base_distance = 0.0f;
+       static double base_angle = 0.0f;
+
+       static double prev_distance = 0.0f;
+       static double prev_angle = 0.0f;
+
+       static double cur_distance = 0.0f;
+       static double cur_angle = 0.0f;
+
+       double diff_distance = 0.0f;
+       double diff_angle = 0.0f;
+
+       static int has_event_mask = 0;
+
+       static Time base_time = 0;
+       Time current_time;
+
+       if(g_pGesture->recognized_palm || g_pGesture->enqueue_fulled == 1 || g_pGesture->hold_detected
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+                       || g_pGesture->bezel_recognized_mask)
+#else
+                       )
+#endif
+               goto cleanup_pinchrotation;
+
+       if( timer_expired )
+       {
+               if( state == GestureEnd )
+               {
+                       current_time = GetTimeInMillis();
+                       if( (current_time - base_time) >= g_pGesture->pinchrotation_time_threshold )
+                       {
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[Timer] You must move farther than dist threshold(=%.2f) or angle threshold(=%2f) within time threshold(=%d) !\n", g_pGesture->pinchrotation_dist_threshold, g_pGesture->pinchrotation_angle_threshold, g_pGesture->pinchrotation_time_threshold);
+#endif//__DETAIL_DEBUG__
+                               goto cleanup_pinchrotation;
+                       }
+               }
+
+               return;
+       }
+
+       switch( type )
+       {
+               case ET_ButtonPress:
+                       g_pGesture->fingers[idx].flags |= PressFlagPinchRotation;
+
+                       if( g_pGesture->num_pressed < 2 )
+                               return;
+
+                       if( g_pGesture->num_pressed < num_pressed && state != GestureEnd )
+                       {
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[P][cleanup] num_finger changed !(state: %d)  num_pressed=%d, g_pGesture->num_pressed=%d\n", state, num_pressed, g_pGesture->num_pressed);
+#endif//__DETAIL_DEBUG__
+                               goto cleanup_pinchrotation;
+                       }
+
+                       if( base_distance == 0.0f && g_pGesture->num_pressed == 2 )
+                       {
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[First Time !!!] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
+#endif//__DETAIL_DEBUG__
+
+                               base_time = GetTimeInMillis();
+                               pixman_region_init(&base_area);
+                               pixman_region_union(&base_area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[1]);
+
+                               prev_distance = base_distance = AREA_DIAG_LEN(&base_area.extents);
+
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[P] x1=%d, x2=%d, y1=%d, y2=%d\n", g_pGesture->fingers[0].px, g_pGesture->fingers[1].px,
+                               g_pGesture->fingers[0].py, g_pGesture->fingers[1].py);
+#endif//__DETAIL_DEBUG__
+
+                               prev_angle = base_angle = get_angle(g_pGesture->fingers[0].px, g_pGesture->fingers[0].py, g_pGesture->fingers[1].px, g_pGesture->fingers[1].py);
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[P] base_angle=%.2f(deg=%.2f)\n", base_angle, rad2degree(base_angle));
+#endif//__DETAIL_DEBUG__
+                               event_type = GestureNotifyPinchRotation;
+                               pinchrotation_event_timer = TimerSet(pinchrotation_event_timer, 0, g_pGesture->pinchrotation_time_threshold, GestureEventTimerHandler, (int *)&event_type);
+                       }
+                       num_pressed = g_pGesture->num_pressed;
+
+#ifdef __DETAIL_DEBUG__
+                       XDBG_DEBUG(MGEST, "[P][num_pressed=%d] AREA_SIZE(base_area.extents)=%d\n", num_pressed, AREA_SIZE(&base_area.extents));
+                       XDBG_DEBUG(MGEST, "[P][num_pressed=%d] base_distance=%.2f, base_angle=%.2f(deg=%.2f)\n", num_pressed, base_distance, base_angle, rad2degree(base_angle));
+#endif//__DETAIL_DEBUG__
+                       break;
+
+               case ET_Motion:
+                       if( !(g_pGesture->fingers[idx].flags & PressFlagPinchRotation) )
+                               break;
+
+                       if( (num_pressed != g_pGesture->num_pressed) && (state != GestureEnd) )
+                       {
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[M][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
+#endif//__DETAIL_DEBUG__
+                               goto cleanup_pinchrotation;
+                       }
+
+                       if( num_pressed < 2 )
+                               return;
+
+                       if( g_pGesture->fingers[0].mx && g_pGesture->fingers[0].my && g_pGesture->fingers[1].mx && g_pGesture->fingers[1].my )
+                       {
+                               pixman_region_init(&cur_area);
+                               pixman_region_union(&cur_area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[1]);
+
+                               cur_distance = AREA_DIAG_LEN(&cur_area.extents);
+
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[M] x1=%d, x2=%d, y1=%d, y2=%d\n", g_pGesture->fingers[0].mx, g_pGesture->fingers[1].mx,
+                               g_pGesture->fingers[0].my, g_pGesture->fingers[1].my);
+#endif//__DETAIL_DEBUG__
+
+                               cur_angle = get_angle(g_pGesture->fingers[0].mx, g_pGesture->fingers[0].my, g_pGesture->fingers[1].mx, g_pGesture->fingers[1].my);
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[M] cur_angle=%.2f(deg=%.2f)\n", cur_angle, rad2degree(cur_angle));
+#endif//__DETAIL_DEBUG__
+
+                               diff_distance = prev_distance - cur_distance;
+                               diff_angle = prev_angle - cur_angle;
+
+                               cx = AREA_CENTER_X(&cur_area.extents);
+                               cy = AREA_CENTER_Y(&cur_area.extents);
+
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[M][state=%d] cx=%d, cy=%d\n", state, cx, cy);
+#endif//__DETAIL_DEBUG__
+
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[M][num_pressed=%d] prev_distance=%.2f, cur_distance=%.2f, diff=%.2f\n", num_pressed, prev_distance, cur_distance, diff_distance);
+                               XDBG_DEBUG(MGEST, "[M][num_pressed=%d] prev_angle=%.2f(deg=%.2f), cur_angle=%.2f(deg=%.2f), diff=%.2f(deg=%.2f)\n", num_pressed, prev_angle, rad2degree(prev_angle), cur_angle, rad2degree(cur_angle), diff_angle, rad2degree(diff_angle));
+#endif//__DETAIL_DEBUG__
+
+                               switch( state )
+                               {
+                                       case GestureEnd:
+                                               if( (ABS(diff_distance) >= g_pGesture->pinchrotation_dist_threshold) || (ABS(diff_angle) >= g_pGesture->pinchrotation_angle_threshold) )
+                                               {
+#ifdef __DETAIL_DEBUG__
+                                                       if( ABS(diff_distance) >= g_pGesture->pinchrotation_dist_threshold )
+                                                               XDBG_DEBUG(MGEST, "[M] zoom changed !\n");
+
+                                                       if( ABS(diff_angle) >= g_pGesture->pinchrotation_angle_threshold )
+                                                               XDBG_DEBUG(MGEST, "[M] angle changed !\n");
+#endif//__DETAIL_DEBUG__
+
+                                                       TimerCancel(pinchrotation_event_timer);
+                                                       state = GestureBegin;
+                                                       goto gesture_begin_handle;
+                                               }
+                                               break;
+
+                                       case GestureBegin:
+gesture_begin_handle:
+#ifdef __DETAIL_DEBUG__
+                                               XDBG_DEBUG(MGEST, "PINCHROTATION Begin !cx=%d, cy=%d, state=%d\n", cx, cy, state);
+#endif//__DETAIL_DEBUG__
+                                               if( GestureHasFingerEventMask(GestureNotifyPinchRotation, num_pressed) )
+                                               {
+                                                       GestureHandleGesture_PinchRotation(num_pressed, cur_distance / base_distance, (cur_angle > base_angle) ? (cur_angle-base_angle) : (RAD_360DEG + cur_angle - base_angle), cur_distance, cx, cy, GestureBegin);
+                                                       prev_distance = cur_distance;
+                                                       prev_angle = cur_angle;
+                                                       state = GestureUpdate;
+                                                       has_event_mask = 1;
+                                               }
+                                               else
+                                               {
+                                                       has_event_mask = 0;
+                                                       goto cleanup_pinchrotation;
+                                               }
+                                               break;
+
+                                       case GestureUpdate:
+                                               //if( ABS(diff_distance) < g_pGesture->pinchrotation_dist_threshold && ABS(diff_angle) < g_pGesture->pinchrotation_angle_threshold )
+                                               //      break;
+
+#ifdef __DETAIL_DEBUG__
+                                               if( ABS(diff_distance) >= g_pGesture->pinchrotation_dist_threshold )
+                                                       XDBG_DEBUG(MGEST, "[M] zoom changed !\n");
+
+                                               if( ABS(diff_angle) >= g_pGesture->pinchrotation_angle_threshold )
+                                                       XDBG_DEBUG(MGEST, "[M] angle changed !\n");
+#endif//__DETAIL_DEBUG__
+
+#ifdef __DETAIL_DEBUG__
+                                               XDBG_DEBUG(MGEST, "PINCHROTATION Update ! cx=%d, cy=%d, state=%d\n", cx, cy, state);
+#endif//__DETAIL_DEBUG__
+                                               GestureHandleGesture_PinchRotation(num_pressed, cur_distance / base_distance, (cur_angle > base_angle) ? (cur_angle-base_angle) : (RAD_360DEG + cur_angle - base_angle), cur_distance, cx, cy, GestureUpdate);
+                                               prev_distance = cur_distance;
+                                               prev_angle = cur_angle;
+                                               break;
+
+                                       case GestureDone:
+                                       default:
+                                               break;
+                               }
+                       }
+                       break;
+
+               case ET_ButtonRelease:
+                       if( state != GestureEnd && num_pressed >= 2)
+                       {
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[R][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
+#endif//__DETAIL_DEBUG__
+                               goto cleanup_pinchrotation;
+                       }
+
+                       if( g_pGesture->num_pressed )
+                               break;
+
+                       goto cleanup_pinchrotation;
+                       break;
+       }
+
+       return;
+
+cleanup_pinchrotation:
+       g_pGesture->filter_mask |= PinchRotationFilterMask;
+       if(  has_event_mask  && (state == GestureBegin || state == GestureUpdate) )
+       {
+               state = GestureEnd;
+#ifdef __DETAIL_DEBUG__
+               XDBG_DEBUG(MGEST, "PINCHROTATION End ! cx=%d, cy=%d, state=%d\n", cx, cy, state);
+#endif//__DETAIL_DEBUG__
+               GestureHandleGesture_PinchRotation(num_pressed, cur_distance / base_distance, (cur_angle > base_angle) ? (cur_angle-base_angle) : (RAD_360DEG + cur_angle - base_angle), cur_distance, cx, cy, GestureEnd);
+       }
+       else if(g_pGesture->num_pressed > 1)
+       {
+               if(!(g_pGesture->filter_mask & PanFilterMask))
+               {
+                       pixman_region_init(&base_area);
+                       pixman_region_union(&base_area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[1]);
+
+                       prev_distance = base_distance = AREA_DIAG_LEN(&base_area.extents);
+                       prev_angle = base_angle = get_angle(g_pGesture->fingers[0].px, g_pGesture->fingers[0].py, g_pGesture->fingers[1].px, g_pGesture->fingers[1].py);
+
+                       g_pGesture->filter_mask &= ~PinchRotationFilterMask;
+
+                       return;
+               }
+               g_pGesture->recognized_gesture &= ~PinchRotationFilterMask;
+       }
+
+       if( g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL )
+       {
+#ifdef __DETAIL_DEBUG__
+               XDBG_DEBUG(MGEST, "[cleanup] GestureFlushOrDrop() !\n");
+#endif//__DETAIL_DEBUG__
+
+               if( ERROR_INVALPTR == GestureFlushOrDrop() )
+               {
+                       GestureControl(g_pGesture->this_device, DEVICE_OFF);
+               }
+       }
+
+       prev_distance = base_distance = 0.0f;
+       prev_angle = base_angle = 0.0f;
+       has_event_mask = num_pressed = 0;
+       state = GestureEnd;
+       cx = cy = 0;
+       TimerCancel(pinchrotation_event_timer);
+       return;
+}
+
+void
+GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx)
+{
+       static int num_pressed = 0;
+       static int mbits = 0;
+       static int base_area_size = 0;
+       static Time base_time = 0;
+       static int base_x, base_y;
+       Time current_time;
+       Time duration;
+       int distx, disty;
+       int distance, direction;
+       int area_size;
+       int flicked = 0;
+
+       if(g_pGesture->recognized_palm || g_pGesture->enqueue_fulled == 1 || g_pGesture->hold_detected
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+               || g_pGesture->bezel_recognized_mask)
+#else
+               )
+#endif
+               goto cleanup_flick;
+
+       switch( type )
+       {
+               case ET_ButtonPress:
+                       g_pGesture->fingers[idx].flags |= PressFlagFlick;
+                       if( g_pGesture->num_pressed < 2 )
+                               return;
+
+                       if( !base_area_size || g_pGesture->num_pressed > num_pressed )
+                       {
+                               base_area_size = AREA_SIZE(&g_pGesture->area.extents);
+                               base_x = g_pGesture->area.extents.x1;
+                               base_y = g_pGesture->area.extents.y1;
+                               base_time = GetTimeInMillis();
+                       }
+                       num_pressed = g_pGesture->num_pressed;
+
+#ifdef __DETAIL_DEBUG__
+                       XDBG_DEBUG(MGEST, "[P]][num_pressed=%d] AREA_SIZE(area.extents)=%d\n", num_pressed, base_area_size);
+#endif//__DETAIL_DEBUG__
+                       break;
+
+               case ET_Motion:
+                       if( !(g_pGesture->fingers[idx].flags & PressFlagFlick ) )
+                               break;
+
+#ifdef __DETAIL_DEBUG__
+                       if( num_pressed > g_pGesture->num_pressed )
+                       {
+                               XDBG_DEBUG(MGEST, "[M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
+                               //goto cleanup_flick;
+                       }
+#endif//__DETAIL_DEBUG__
+
+                       if( num_pressed < 2 )
+                               return;
+
+                       mbits |= (1 << idx);
+                       if( mbits == (pow(2, num_pressed)-1) )
+                       {
+                               area_size = AREA_SIZE(&g_pGesture->area.extents);
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[M][num_pressed=%d] AREA_SIZE(area.extents)=%d\n", num_pressed, area_size);
+#endif//__DETAIL_DEBUG__
+                               if( ABS(base_area_size - area_size) >= FLICK_AREA_THRESHOLD )
+                               {
+#ifdef __DETAIL_DEBUG__
+                                       XDBG_DEBUG(MGEST, "[M] diff between Area size(=%d) and base area size(=%d) is bigger than threshold(=%d)!\n", area_size, base_area_size, FLICK_AREA_THRESHOLD);
+#endif//__DETAIL_DEBUG__
+                                       goto cleanup_flick;
+                               }
+
+                               current_time = GetTimeInMillis();
+                               if( (current_time - base_time) >= FLICK_AREA_TIMEOUT )
+                               {
+#ifdef __DETAIL_DEBUG__
+                                       XDBG_DEBUG(MGEST, "[M] diff between current time(=%d) and base time(=%d) is bigger than threashold(=%d) !\n", current_time, base_time, FLICK_AREA_TIMEOUT);
+#endif//__DETAIL_DEBUG__
+                                       goto cleanup_flick;
+                               }
+                               mbits = 0;
+                       }
+                       break;
+
+               case ET_ButtonRelease:
+                       if( g_pGesture->num_pressed )
+                               break;
+
+                       duration = GetTimeInMillis() - base_time;
+                       distx = g_pGesture->area.extents.x1 - base_x;
+                       disty = g_pGesture->area.extents.y1 - base_y;
+
+#ifdef __DETAIL_DEBUG__
+                       XDBG_DEBUG(MGEST, "duration=%d, distx=%d, disty=%d\n", duration, distx, disty);
+#endif//__DETAIL_DEBUG__
+
+                       if( duration <= 0 || duration >= FLICK_AREA_TIMEOUT )
+                               goto cleanup_flick;
+
+                       if( ABS(distx) >= FLICK_MOVE_THRESHOLD )
+                       {
+                               direction = (distx > 0) ? FLICK_EASTWARD : FLICK_WESTWARD;
+                               distance = ABS(distx);
+                               flicked++;
+                       }
+                       else if( ABS(disty) >= FLICK_MOVE_THRESHOLD )
+                       {
+                               direction = (disty > 0) ? FLICK_SOUTHWARD : FLICK_NORTHWARD;
+                               distance = ABS(disty);
+                               flicked++;
+                       }
+
+                       if( !flicked )
+                               goto cleanup_flick;
+
+                       if( GestureHasFingerEventMask(GestureNotifyFlick, num_pressed) )
+                               GestureHandleGesture_Flick(num_pressed, distance, duration, direction);
+                       goto cleanup_flick_recognized;
+                       break;
+       }
+
+       return;
+
+cleanup_flick:
+
+       g_pGesture->recognized_gesture &= ~FlickFilterMask;
+
+cleanup_flick_recognized:
+
+       g_pGesture->filter_mask |= FlickFilterMask;
+       num_pressed = 0;
+       base_area_size = 0;
+       base_time = 0;
+       mbits = 0;
+       return;
+}
+
+void
+GestureRecognize_GroupPan(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
+{
+       static int num_pressed = 0;
+       static int mbits = 0;
+       static int base_area_size = 0;
+       static Time base_time = 0;
+       static pixman_box16_t base_box_ext;
+       static int base_cx;
+       static int base_cy;
+       static int prev_cx;
+       static int prev_cy;
+       static int cx = 0;
+       static int cy = 0;
+       int dx, dy;
+       static Time prev_time = 0;
+       Time current_time = 0;
+       int distance = 0;
+       int direction = 0;
+       int area_size;
+       static int time_checked = 0;
+       static int state = GestureEnd;
+
+       static OsTimerPtr pan_event_timer = NULL;
+       static int event_type = GestureNotifyPan;
+
+       if(g_pGesture->recognized_palm || g_pGesture->enqueue_fulled == 1 || g_pGesture->hold_detected
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+               || g_pGesture->bezel_recognized_mask)
+#else
+               )
+#endif
+               goto cleanup_pan;
+
+       if( timer_expired )
+       {
+               if( !time_checked )
+               {
+                       current_time = GetTimeInMillis();
+                       if( (current_time - base_time) >= PAN_TIME_THRESHOLD )
+                       {
+                               if( (!cx && !cy) || INBOX(&base_box_ext, cx, cy) )
+                               {
+#ifdef __DETAIL_DEBUG__
+                                       XDBG_DEBUG(MGEST, "[Timer] You must move farther than move threshold(=%d) within time threshold(=%d) !\n", PAN_MOVE_THRESHOLD*2, PAN_TIME_THRESHOLD);
+#endif//__DETAIL_DEBUG__
+                                       goto cleanup_pan;
+                               }
+                               time_checked = 1;
+                       }
+               }
+               return;
+       }
+
+       switch( type )
+       {
+               case ET_ButtonPress:
+                       g_pGesture->fingers[idx].flags |= PressFlagPan;
+
+                       if( g_pGesture->num_pressed < 2 )
+                               return;
+
+                       if( !base_area_size || g_pGesture->num_pressed > num_pressed )
+                       {
+                               if( state != GestureEnd )
+                               {
+#ifdef __DETAIL_DEBUG__
+                                       XDBG_DEBUG(MGEST, "[P][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
+#endif//__DETAIL_DEBUG__
+                                       goto cleanup_pan;
+                               }
+                               base_area_size = AREA_SIZE(&g_pGesture->area.extents);
+                               prev_cx = base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
+                               prev_cy = base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
+                               prev_time = base_time = GetTimeInMillis();
+                               base_box_ext.x1 = base_cx-PAN_MOVE_THRESHOLD;
+                               base_box_ext.y1 = base_cy-PAN_MOVE_THRESHOLD;
+                               base_box_ext.x2 = base_cx+PAN_MOVE_THRESHOLD;
+                               base_box_ext.y2 = base_cy+PAN_MOVE_THRESHOLD;
+                               event_type = GestureNotifyPan;
+                               pan_event_timer = TimerSet(pan_event_timer, 0, PAN_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
+                       }
+                       num_pressed = g_pGesture->num_pressed;
+
+#ifdef __DETAIL_DEBUG__
+                       XDBG_DEBUG(MGEST, "[P][num_pressed=%d] AREA_SIZE(area.extents)=%d, base_cx=%d, base_cy=%d\n", num_pressed, base_area_size, base_cx, base_cy);
+#endif//__DETAIL_DEBUG__
+                       break;
+
+               case ET_Motion:
+                       if( !(g_pGesture->fingers[idx].flags & PressFlagPan ) )
+                               break;
+
+                       if( num_pressed != g_pGesture->num_pressed )
+                       {
+                               if( state != GestureEnd )
+                               {
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[M][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
+#endif//__DETAIL_DEBUG__
+                                       goto cleanup_pan;
+                               }
+                       }
+
+                       if( num_pressed < 2 )
+                               return;
+
+                       mbits |= (1 << idx);
+                       if( mbits == (pow(2, num_pressed)-1) )
+                       {
+                               area_size = AREA_SIZE(&g_pGesture->area.extents);
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[M][num_pressed=%d] area_size=%d, base_area_size=%d, diff=%d\n", num_pressed, area_size, base_area_size, ABS(base_area_size - area_size));
+#endif//__DETAIL_DEBUG__
+
+                               if( (state != GestureUpdate) && (ABS(base_area_size - area_size) >= PAN_AREA_THRESHOLD) )
+                               {
+#ifdef __DETAIL_DEBUG__
+                                       XDBG_DEBUG(MGEST, "[M] diff between area size(=%d) and base area size(=%d) is bigger than threshold(=%d)!\n", area_size, base_area_size, PAN_AREA_THRESHOLD);
+#endif//__DETAIL_DEBUG__
+                                       goto cleanup_pan;
+                               }
+
+                               cx = AREA_CENTER_X(&g_pGesture->area.extents);
+                               cy = AREA_CENTER_Y(&g_pGesture->area.extents);
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[M] cx=%d, prev_cx=%d, diff=%d\n", cx, prev_cx, ABS(cx-prev_cx));
+                               XDBG_DEBUG(MGEST, "[M] cy=%d, prev_cy=%d, diff=%d\n", cy, prev_cy, ABS(cy-prev_cy));
+#endif//__DETAIL_DEBUG__
+
+                               if( state <= GestureBegin )
+                               {
+                                       if( !INBOX(&base_box_ext, cx, cy) )
+                                       {
+                                               TimerCancel(pan_event_timer);
+                                               pan_event_timer = NULL;
+                                               
+                                               if( GestureHasFingerEventMask(GestureNotifyPan, num_pressed) )
+                                               {
+                                                       GestureHandleGesture_Pan(num_pressed, prev_cx, prev_cy, direction, distance, current_time-prev_time, GestureBegin);
+                                                       state = GestureUpdate;
+                                               }
+                                               else
+                                                       goto cleanup_pan;
+                                       }
+                               }
+                               else
+                               {
+                                       dx = cx-prev_cx;
+                                       dy = cy-prev_cy;
+
+                                       //if( ABS(dx) >= PAN_UPDATE_MOVE_THRESHOLD || ABS(dy) >= PAN_UPDATE_MOVE_THRESHOLD )
+                                       {
+#ifdef __DETAIL_DEBUG__
+                                               XDBG_DEBUG(MGEST, "PAN Update !dx=%d, dy=%d, state=%d\n", dx, dy, state);
+#endif//__DETAIL_DEBUG__
+
+                                               GestureHandleGesture_Pan(num_pressed, dx, dy, direction, distance, current_time-prev_time, GestureUpdate);
+                                       }
+                               }
+
+                               prev_cx = cx;
+                               prev_cy = cy;
+                               mbits = 0;
+                       }
+                       break;
+
+               case ET_ButtonRelease:
+                       if( state != GestureEnd && num_pressed >= 2)
+                       {
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[R][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
+#endif//__DETAIL_DEBUG__
+                               goto cleanup_pan;
+                       }
+
+                       if( g_pGesture->num_pressed )
+                               break;
+
+                       goto cleanup_pan;
+                       break;
+       }
+
+       return;
+
+cleanup_pan:
+       g_pGesture->filter_mask |= PanFilterMask;
+       if( state == GestureBegin || state == GestureUpdate )
+       {
+               state = GestureEnd;
+               if( GestureHasFingerEventMask(GestureNotifyPan, num_pressed) )
+               {
+                       GestureHandleGesture_Pan(num_pressed, (short int)(cx-prev_cx), (short int)(cy-prev_cy), direction, distance, GetTimeInMillis()-prev_time, GestureEnd);
+               }
+       }
+       else if(g_pGesture->num_pressed > 1)
+       {
+               if(!(g_pGesture->filter_mask & PinchRotationFilterMask))
+               {
+                       base_area_size = AREA_SIZE(&g_pGesture->area.extents);
+                       prev_cx = base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
+                       prev_cy = base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
+                       prev_time = base_time = GetTimeInMillis();
+                       base_box_ext.x1 = base_cx-PAN_MOVE_THRESHOLD;
+                       base_box_ext.y1 = base_cy-PAN_MOVE_THRESHOLD;
+                       base_box_ext.x2 = base_cx+PAN_MOVE_THRESHOLD;
+                       base_box_ext.y2 = base_cy+PAN_MOVE_THRESHOLD;
+                       g_pGesture->filter_mask &= ~PanFilterMask;
+                       return;
+               }
+               g_pGesture->recognized_gesture &= ~PanFilterMask;
+       }
+
+       num_pressed = 0;
+       base_area_size = 0;
+       base_time = 0;
+       mbits = 0;
+       time_checked = 0;
+       state = GestureEnd;
+       cx = cy = 0;
+       prev_time = 0;
+       base_box_ext.x1 = base_box_ext.x2 = base_box_ext.y1 = base_box_ext.y2 = 0;
+       if( pan_event_timer )
+       {
+               TimerCancel(pan_event_timer);
+               pan_event_timer = NULL;
+       }
+       return;
+}
+
+void
+GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
+{
+       static int num_pressed = 0;
+       static int base_area_size = 0;
+
+       static Time base_time = 0;
+
+       int cx, cy;
+       int area_size;
+
+       static int state = GestureEnd;
+       static int mbits = 0;
+       static int base_cx;
+       static int base_cy;
+       static pixman_box16_t base_box_ext;
+
+       static int tap_repeat = 0;
+       static int prev_num_pressed = 0;
+
+       static OsTimerPtr tap_event_timer = NULL;
+       static int event_type = GestureNotifyTap;
+
+       if(g_pGesture->recognized_palm || g_pGesture->enqueue_fulled == 1 || g_pGesture->hold_detected
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+               || g_pGesture->bezel_recognized_mask)
+#else
+               )
+#endif
+               goto cleanup_tap;
+
+       if( timer_expired )
+       {
+#ifdef __DETAIL_DEBUG__
+               XDBG_DEBUG(MGEST, "[Timer] state=%d\n", state);
+#endif//__DETAIL_DEBUG__
+
+               switch( state )
+               {
+                       case GestureBegin://first tap initiation check
+                               if( num_pressed )
+                               {
+#ifdef __DETAIL_DEBUG__
+                                       XDBG_DEBUG(MGEST, "[Timer][state=1] Tap time expired !(num_pressed=%d, tap_repeat=%d)\n", num_pressed, tap_repeat);
+#endif//__DETAIL_DEBUG__
+                                       state = GestureEnd;
+                                       goto cleanup_tap;
+                               }
+                               break;
+
+                       case GestureUpdate:
+                               if( tap_repeat <= 1 )
+                               {
+#ifdef __DETAIL_DEBUG__
+                                       XDBG_DEBUG(MGEST, "[Timer][state=2] %d finger SINGLE TAP !(ignored)\n", prev_num_pressed);
+#endif//__DETAIL_DEBUG__
+                                       state = GestureEnd;
+                                       goto cleanup_tap;
+                               }
+
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[Timer][state=2]  tap_repeat=%d, num_pressed=%d\n", tap_repeat, num_pressed);
+#endif//__DETAIL_DEBUG__
+                               if( GestureHasFingerEventMask(GestureNotifyTap, prev_num_pressed) )
+                               {
+                                       if(prev_num_pressed == 2 && tap_repeat == 2)
+                                       {
+                                               g_pGesture->zoom_enabled = (g_pGesture->zoom_enabled + 1)%2;
+                                               if(g_pGesture->zoom_enabled == 1)
+                                               {
+                                                       g_pGesture->recognized_gesture |= TapFilterMask;
+                                               }
+                                       }
+                                       GestureHandleGesture_Tap(prev_num_pressed, tap_repeat, base_cx, base_cy);
+                               }
+                               goto cleanup_tap;
+                               break;
+               }
+
+               return;
+       }
+
+       switch( type )
+       {
+               case ET_ButtonPress:
+                       g_pGesture->fingers[idx].flags |= PressFlagTap;
+
+                       if( g_pGesture->num_pressed < 2 )
+                               return;
+
+                       if( !prev_num_pressed && (!base_area_size || g_pGesture->num_pressed > num_pressed) )
+                       {
+                               base_area_size = AREA_SIZE(&g_pGesture->area.extents);
+                               base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
+                               base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
+                               base_time = GetTimeInMillis();
+                               base_box_ext.x1 = base_cx-TAP_MOVE_THRESHOLD;
+                               base_box_ext.y1 = base_cy-TAP_MOVE_THRESHOLD;
+                               base_box_ext.x2 = base_cx+TAP_MOVE_THRESHOLD;
+                               base_box_ext.y2 = base_cy+TAP_MOVE_THRESHOLD;
+                               state = GestureBegin;
+                               TimerCancel(tap_event_timer);
+                               tap_event_timer = TimerSet(tap_event_timer, 0, g_pGesture->singletap_threshold, GestureEventTimerHandler, (int *)&event_type);
+                       }
+
+                       num_pressed = g_pGesture->num_pressed;
+
+#ifdef __DETAIL_DEBUG__
+                       XDBG_DEBUG(MGEST, "[P][num_pressed=%d] AREA_SIZE(area.extents)=%d, base_cx=%d, base_cy=%d, base_time=%d, current_time=%d\n", num_pressed, base_area_size, base_cx, base_cy, base_time, GetTimeInMillis());
+#endif//__DETAIL_DEBUG__
+                       break;
+
+               case ET_Motion:
+                       if( !(g_pGesture->fingers[idx].flags & PressFlagTap ) )
+                               break;
+
+                       if( num_pressed < 2 )
+                               return;
+
+#ifdef __DETAIL_DEBUG__
+                       XDBG_DEBUG(MGEST, "[M][num_pressed=%d] g_pGesture->num_pressed: %d\n", num_pressed, g_pGesture->num_pressed);
+#endif//__DETAIL_DEBUG__
+
+                       if( num_pressed != g_pGesture->num_pressed )
+                       {
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
+#endif//__DETAIL_DEBUG__
+                               //goto cleanup_tap;
+                               break;
+                       }
+
+                       mbits |= (1 << idx);
+                       if( mbits == (pow(2, num_pressed)-1) )
+                       {
+                               area_size = AREA_SIZE(&g_pGesture->area.extents);
+                               cx = AREA_CENTER_X(&g_pGesture->area.extents);
+                               cy = AREA_CENTER_Y(&g_pGesture->area.extents);
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[M][num_pressed=%d] area_size=%d, base_area_size=%d, diff=%d\n", num_pressed, area_size, base_area_size, ABS(base_area_size - area_size));
+                               XDBG_DEBUG(MGEST, "[M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
+                               XDBG_DEBUG(MGEST, "[M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
+#endif//__DETAIL_DEBUG__
+
+                               if( ABS(base_area_size-area_size) >= TAP_AREA_THRESHOLD )
+                               {
+#ifdef __DETAIL_DEBUG__
+                                       XDBG_DEBUG(MGEST, "[M] diff between area size(=%d) and base area size(=%d) is bigger than threshold(=%d)!\n", area_size, base_area_size, ABS(base_area_size-area_size));
+#endif//__DETAIL_DEBUG__
+                                       goto cleanup_tap;
+                               }
+
+                               if( !INBOX(&base_box_ext, cx, cy) )
+                               {
+#ifdef __DETAIL_DEBUG__
+                                       XDBG_DEBUG(MGEST, "[M] current center coordinates is not in base coordinates box !\n");
+#endif//__DETAIL_DEBUG__
+                                       goto cleanup_tap;
+                               }
+                       }
+                       break;
+
+               case ET_ButtonRelease:
+                       if( g_pGesture->num_pressed )
+                       {
+                               break;
+                       }
+
+                       if( !tap_repeat )
+                       {
+                               prev_num_pressed = num_pressed;
+                       }
+
+                       tap_repeat++;
+                       g_pGesture->tap_repeated = tap_repeat;
+
+#ifdef __DETAIL_DEBUG__
+                       XDBG_DEBUG(MGEST, "[R] tap_repeat=%d, num_pressed=%d, prev_num_pressed=%d\n", tap_repeat, num_pressed, prev_num_pressed);
+#endif//__DETAIL_DEBUG__
+
+                       if( num_pressed != prev_num_pressed || !GestureHasFingerEventMask(GestureNotifyTap, num_pressed) )
+                       {
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[R] num_pressed(=%d) != prev_num_pressed(=%d) OR %d finger tap event was not grabbed/selected !\n",
+                                       num_pressed, prev_num_pressed, num_pressed);
+#endif//__DETAIL_DEBUG__
+                               goto cleanup_tap;
+                       }
+
+                       if( tap_repeat < MAX_TAP_REPEATS )
+                       {
+                               state = GestureUpdate;
+                               TimerCancel(tap_event_timer);
+                               tap_event_timer = TimerSet(tap_event_timer, 0, g_pGesture->doubletap_threshold, GestureEventTimerHandler, (int *)&event_type);
+                               num_pressed = 0;
+                               break;
+                       }
+
+#ifdef __DETAIL_DEBUG__
+                       XDBG_DEBUG(MGEST, "[R] %d finger %s\n", num_pressed, (tap_repeat==2) ? "DBL_TAP" : "TRIPLE_TAP");
+#endif//__DETAIL_DEBUG__
+
+                       if( GestureHasFingerEventMask(GestureNotifyTap, num_pressed) )
+                               GestureHandleGesture_Tap(num_pressed, tap_repeat, base_cx, base_cy);
+
+                       goto cleanup_tap;
+       }
+
+       return;
+
+cleanup_tap:
+
+       if( GestureEnd == state )
+               g_pGesture->recognized_gesture &= ~TapFilterMask;
+       g_pGesture->filter_mask |= TapFilterMask;
+
+       if( g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL )
+       {
+#ifdef __DETAIL_DEBUG__
+               XDBG_DEBUG(MGEST, "[cleanup] GestureFlushOrDrop() !\n");
+#endif//__DETAIL_DEBUG__
+
+               if( ERROR_INVALPTR == GestureFlushOrDrop() )
+               {
+                       GestureControl(g_pGesture->this_device, DEVICE_OFF);
+               }
+       }
+
+       num_pressed = 0;
+       tap_repeat = 0;
+       g_pGesture->tap_repeated = 0;
+       prev_num_pressed = 0;
+       mbits = 0;
+       base_time = 0;
+       state = GestureEnd;
+       TimerCancel(tap_event_timer);
+       return;
+}
+
+void
+GestureRecognize_GroupTapNHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
+{
+       static int num_pressed = 0;
+       static int base_area_size = 0;
+       static Time base_time = 0;
+       static int base_cx;
+       static int base_cy;
+       int cx, cy;
+       static pixman_box16_t base_box_ext;
+       int area_size;
+       static int mbits = 0;
+
+       static int tap_repeat = 0;
+       static int prev_num_pressed = 0;
+
+       static OsTimerPtr tapnhold_event_timer = NULL;
+       static int event_type = GestureNotifyTapNHold;
+       static int state = GestureEnd;
+
+       Time interval = 0;
+       Time holdtime = 0;
+
+       if(g_pGesture->recognized_palm || g_pGesture->enqueue_fulled == 1 || g_pGesture->hold_detected
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+               || g_pGesture->bezel_recognized_mask)
+#else
+               )
+#endif
+               goto cleanup_tapnhold;
+
+       if( timer_expired )
+       {
+               if( (state == GestureEnd) && num_pressed )
+               {
+#ifdef __DETAIL_DEBUG__
+                       XDBG_DEBUG(MGEST, "[Timer][state=%d] Tap time expired !(num_pressed=%d, tap_repeat=%d)\n", GestureEnd, tap_repeat, num_pressed, tap_repeat);
+#endif//__DETAIL_DEBUG__
+                       state = 0;
+                       goto cleanup_tapnhold;
+               }
+
+               if( state == GestureDone )
+               {
+#ifdef __DETAIL_DEBUG__
+                       XDBG_DEBUG(MGEST, "[Timer][state=%d] Interval between Tap and Hold is too long !\n");
+#endif//__DETAIL_DEBUG__
+                       goto cleanup_tapnhold;
+               }
+
+#ifdef __DETAIL_DEBUG__
+               switch( state )
+               {
+                       case GestureBegin:
+                               XDBG_DEBUG(MGEST, "[Timer] TapNHold Begin !\n");
+                               break;
+
+                       case GestureUpdate:
+                               XDBG_DEBUG(MGEST, "[Timer] TapNHold Update !\n");
+                               break;
+               }
+#endif//__DETAIL_DEBUG__
+
+               if( GestureHasFingerEventMask(GestureNotifyTapNHold, prev_num_pressed) )
+               {
+                       GestureHandleGesture_TapNHold(prev_num_pressed, base_cx, base_cy, interval, holdtime, state);
+                       tapnhold_event_timer = TimerSet(tapnhold_event_timer, 0, TAPNHOLD_HOLD_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
+               }
+               else
+               {
+#ifdef __DETAIL_DEBUG__
+                       XDBG_DEBUG(MGEST, "[Timer] %d finger TapNHold event was not grabbed/selected !\n", prev_num_pressed);
+#endif//__DETAIL_DEBUG__
+                       goto cleanup_tapnhold;
+               }
+
+               if( state <= GestureBegin )
+                       state++;
+               return;
+       }
+
+       switch( type )
+       {
+               case ET_ButtonPress:
+                       g_pGesture->fingers[idx].flags |= PressFlagTapNHold;
+
+                       if( g_pGesture->num_pressed < 2 )
+                               return;
+
+                       //if( !prev_num_pressed && (!base_area_size || g_pGesture->num_pressed > num_pressed) )
+                       if( !base_area_size || g_pGesture->num_pressed > num_pressed )
+                       {
+
+                               if( state == GestureUpdate )
+                               {
+#ifdef __DETAIL_DEBUG__
+                                       XDBG_DEBUG(MGEST, "[P][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
+#endif//__DETAIL_DEBUG__
+                                       goto cleanup_tapnhold;
+                               }
+
+                               if( state == GestureDone )
+                                       state = GestureBegin;
+
+                               base_area_size = AREA_SIZE(&g_pGesture->area.extents);
+                               base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
+                               base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
+                               base_time = GetTimeInMillis();
+                               base_box_ext.x1 = base_cx-TAPNHOLD_MOVE_THRESHOLD;
+                               base_box_ext.y1 = base_cy-TAPNHOLD_MOVE_THRESHOLD;
+                               base_box_ext.x2 = base_cx+TAPNHOLD_MOVE_THRESHOLD;
+                               base_box_ext.y2 = base_cy+TAPNHOLD_MOVE_THRESHOLD;
+                               if( state == GestureEnd )
+                                       tapnhold_event_timer = TimerSet(tapnhold_event_timer, 0, TAPNHOLD_TAP_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
+                               else
+                               {
+                                       TimerCancel(tapnhold_event_timer);
+                                       tapnhold_event_timer = TimerSet(tapnhold_event_timer, 0, TAPNHOLD_HOLD_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
+                               }
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[P] Create Timer !(state=%d)\n", state);
+#endif//__DETAIL_DEBUG__
+                       }
+
+                       num_pressed = g_pGesture->num_pressed;
+
+#ifdef __DETAIL_DEBUG__
+                       XDBG_DEBUG(MGEST, "[P][num_pressed=%d] AREA_SIZE(area.extents)=%d, base_cx=%d, base_cy=%d, base_time=%d\n", num_pressed, base_area_size, base_cx, base_cy, base_time);
+#endif//__DETAIL_DEBUG__
+                       break;
+
+               case ET_Motion:
+                       if( !(g_pGesture->fingers[idx].flags & PressFlagTapNHold ) )
+                               break;
+
+                       if( num_pressed < 2 )
+                               return;
+
+                       if( num_pressed != g_pGesture->num_pressed )
+                       {
+                               if( state != GestureEnd )
+                               {
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[M][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
+#endif//__DETAIL_DEBUG__
+                                       goto cleanup_tapnhold;
+                               }
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
+#endif//__DETAIL_DEBUG__
+                               //goto cleanup_tapnhold;
+                       }
+
+                       mbits |= (1 << idx);
+                       if( mbits == (pow(2, num_pressed)-1) )
+                       {
+                               area_size = AREA_SIZE(&g_pGesture->area.extents);
+                               cx = AREA_CENTER_X(&g_pGesture->area.extents);
+                               cy = AREA_CENTER_Y(&g_pGesture->area.extents);
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[M][num_pressed=%d] area_size=%d, base_area_size=%d, diff=%d\n", num_pressed, area_size, base_area_size, ABS(base_area_size - area_size));
+                               XDBG_DEBUG(MGEST, "[M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
+                               XDBG_DEBUG(MGEST, "[M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
+#endif//__DETAIL_DEBUG__
+
+                               if( ABS(base_area_size-area_size) >= TAPNHOLD_AREA_THRESHOLD )
+                               {
+#ifdef __DETAIL_DEBUG__
+                                       XDBG_DEBUG(MGEST, "[M] diff between area size(=%d) and base area size(=%d) is bigger than threshold(=%d)!\n", area_size, base_area_size, ABS(base_area_size-area_size));
+#endif//__DETAIL_DEBUG__
+                                       goto cleanup_tapnhold;
+                               }
+
+                               if( !INBOX(&base_box_ext, cx, cy) )
+                               {
+#ifdef __DETAIL_DEBUG__
+                                       XDBG_DEBUG(MGEST, "[M] current center coordinates is not in base coordinates box !\n");
+#endif//__DETAIL_DEBUG__
+                                       goto cleanup_tapnhold;
+                               }
+                       }
+                       break;
+
+               case ET_ButtonRelease:
+                       if( state != GestureEnd && num_pressed >= 2)
+                       {
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[R][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
+#endif//__DETAIL_DEBUG__
+                               goto cleanup_tapnhold;
+                       }
+
+                       if( g_pGesture->num_pressed )
+                               break;
+
+                       if( !tap_repeat )
+                       {
+                               prev_num_pressed = num_pressed;
+                       }
+
+                       tap_repeat++;
+
+#ifdef __DETAIL_DEBUG__
+                       XDBG_DEBUG(MGEST, "[R] tap_repeat=%d, num_pressed=%d, prev_num_pressed=%d\n", tap_repeat, num_pressed, prev_num_pressed);
+#endif//__DETAIL_DEBUG__
+
+                       if( num_pressed != prev_num_pressed || !GestureHasFingerEventMask(GestureNotifyTapNHold, num_pressed) )
+                       {
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[R] num_pressed(=%d) != prev_num_pressed(=%d) OR %d finger tap event was not grabbed/selected !\n",
+                                       num_pressed, prev_num_pressed, num_pressed);
+#endif//__DETAIL_DEBUG__
+                               goto cleanup_tapnhold;
+                       }
+
+                       if( tap_repeat > 1 )
+                       {
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[R] Tap events(tap_repeat=%d) were put twice or more !(ignored)\n", tap_repeat);
+#endif//__DETAIL_DEBUG__
+                               goto cleanup_tapnhold;
+                       }
+
+                       prev_num_pressed = num_pressed;
+                       num_pressed = 0;
+                       state = GestureDone;
+
+                       TimerCancel(tapnhold_event_timer);
+                       tapnhold_event_timer = TimerSet(tapnhold_event_timer, 0, TAPNHOLD_INTV_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
+
+#ifdef __DETAIL_DEBUG__
+                       XDBG_DEBUG(MGEST, "[R][Last] state=%d, tap_repeat=%d, num_pressed=%d, prev_num_pressed=%d\n", state,  tap_repeat, num_pressed, prev_num_pressed);
+#endif//__DETAIL_DEBUG__
+                       break;
+       }
+
+       return;
+
+cleanup_tapnhold:
+
+       if( state == GestureUpdate )
+       {
+               state = GestureEnd;
+               if( GestureHasFingerEventMask(GestureNotifyTapNHold, prev_num_pressed) )
+               {
+                       GestureHandleGesture_TapNHold(prev_num_pressed, base_cx, base_cy, interval, holdtime, state);
+               }
+       }
+       else
+       {
+               g_pGesture->recognized_gesture &= ~TapNHoldFilterMask;
+       }
+
+       g_pGesture->filter_mask |= TapNHoldFilterMask;
+       if( g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL )
+       {
+#ifdef __DETAIL_DEBUG__
+               XDBG_DEBUG(MGEST, "[cleanup] GestureFlushOrDrop() !\n");
+#endif//__DETAIL_DEBUG__
+
+               if( ERROR_INVALPTR == GestureFlushOrDrop() )
+               {
+                       GestureControl(g_pGesture->this_device, DEVICE_OFF);
+               }
+       }
+
+       TimerCancel(tapnhold_event_timer);
+       num_pressed = 0;
+       tap_repeat = 0;
+       prev_num_pressed = 0;
+       mbits = 0;
+       base_time = 0;
+       state = 0;
+
+       return;
+}
+
+void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
+{
+       static int num_pressed = 0;
+       static int base_area_size = 0;
+       static Time base_time = 0;
+       static int base_cx;
+       static int base_cy;
+       int cx, cy;
+       static pixman_box16_t base_box_ext;
+       int area_size;
+       static int state = GestureEnd;
+
+       static OsTimerPtr hold_event_timer = NULL;
+       static int event_type = GestureNotifyHold;
+
+       if(g_pGesture->recognized_palm || g_pGesture->enqueue_fulled == 1 || g_pGesture->hold_detected
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+               || g_pGesture->bezel_recognized_mask)
+#else
+               )
+#endif
+               goto cleanup_hold;
+
+       if( timer_expired )
+       {
+               if( state <= GestureBegin )
+                       state++;
+
+#ifdef __DETAIL_DEBUG__
+               switch( state )
+               {
+                       case GestureBegin:
+                               XDBG_DEBUG(MGEST, "HOLD Begin !\n");
+                               break;
+
+                       case GestureUpdate:
+                               XDBG_DEBUG(MGEST, "HOLD Update !\n");
+                               break;
+               }
+#endif//__DETAIL_DEBUG__
+
+               if( GestureHasFingerEventMask(GestureNotifyHold, num_pressed) )
+               {
+                       GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state);
+                       hold_event_timer = TimerSet(hold_event_timer, 0, HOLD_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
+               }
+               return;
+       }
+
+       switch( type )
+       {
+               case ET_ButtonPress:
+                       g_pGesture->fingers[idx].flags |= PressFlagHold;
+
+                       if( g_pGesture->num_pressed < 2 )
+                               return;
+
+                       if( !base_area_size || g_pGesture->num_pressed > num_pressed )
+                       {
+                               if( state != GestureEnd )
+                               {
+#ifdef __DETAIL_DEBUG__
+                                       XDBG_DEBUG(MGEST, "[P][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
+#endif//__DETAIL_DEBUG__
+                                       goto cleanup_hold;
+                               }
+
+                               base_area_size = AREA_SIZE(&g_pGesture->area.extents);
+                               base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
+                               base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
+                               base_time = GetTimeInMillis();
+                               base_box_ext.x1 = base_cx-HOLD_MOVE_THRESHOLD;
+                               base_box_ext.y1 = base_cy-HOLD_MOVE_THRESHOLD;
+                               base_box_ext.x2 = base_cx+HOLD_MOVE_THRESHOLD;
+                               base_box_ext.y2 = base_cy+HOLD_MOVE_THRESHOLD;
+                               event_type = GestureNotifyHold;
+                               hold_event_timer = TimerSet(hold_event_timer, 0, HOLD_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
+                       }
+                       num_pressed = g_pGesture->num_pressed;
+
+#ifdef __DETAIL_DEBUG__
+                       XDBG_DEBUG(MGEST, "[P]][num_pressed=%d] AREA_SIZE(area.extents)=%d, base_cx=%d, base_cy=%d\n", num_pressed, base_area_size, base_cx, base_cy);
+#endif//__DETAIL_DEBUG__
+                       break;
+
+               case ET_Motion:
+                       if( !(g_pGesture->fingers[idx].flags & PressFlagHold ) )
+                               break;
+
+                       if( num_pressed < 2 )
+                               return;
+
+                       if( num_pressed != g_pGesture->num_pressed )
+                       {
+                               if( state != GestureEnd )
+                               {
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[M][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
+#endif//__DETAIL_DEBUG__
+                                       goto cleanup_hold;
+                               }
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
+#endif//__DETAIL_DEBUG__
+                               //goto cleanup_hold;
+                       }
+
+                       area_size = AREA_SIZE(&g_pGesture->area.extents);
+                       cx = AREA_CENTER_X(&g_pGesture->area.extents);
+                       cy = AREA_CENTER_Y(&g_pGesture->area.extents);
+#ifdef __DETAIL_DEBUG__
+                       XDBG_DEBUG(MGEST, "[M][num_pressed=%d] area_size=%d, base_area_size=%d, diff=%d\n", num_pressed, area_size, base_area_size, ABS(base_area_size - area_size));
+                       XDBG_DEBUG(MGEST, "[M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
+                       XDBG_DEBUG(MGEST, "[M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
+#endif//__DETAIL_DEBUG__
+
+                       if( ABS(base_area_size-area_size) >= HOLD_AREA_THRESHOLD )
+                       {
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[M] diff between area size(=%d) and base area size(=%d) is bigger than threshold(=%d)!\n", area_size, base_area_size, ABS(base_area_size-area_size));
+#endif//__DETAIL_DEBUG__
+                               goto cleanup_hold;
+                       }
+
+                       if( !INBOX(&base_box_ext, cx, cy) )
+                       {
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[M] current center coordinates is not in base coordinates box !\n");
+#endif//__DETAIL_DEBUG__
+                               goto cleanup_hold;
+                       }
+                       break;
+
+               case ET_ButtonRelease:
+                       if( state != GestureEnd && num_pressed >= 2)
+                       {
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[R][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
+#endif//__DETAIL_DEBUG__
+                               goto cleanup_hold;
+                       }
+
+                       //XDBG_DEBUG(MGEST, "[R] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
+                       if( g_pGesture->num_pressed )
+                               break;
+
+                       goto cleanup_hold;
+                       break;
+       }
+
+       return;
+
+cleanup_hold:
+
+       if( state == GestureBegin || state == GestureUpdate )
+       {
+               state = GestureEnd;
+               if( GestureHasFingerEventMask(GestureNotifyHold, num_pressed) )
+               {
+                       GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state);
+               }
+       }
+       else
+       {
+               g_pGesture->recognized_gesture &= ~HoldFilterMask;
+       }
+
+       g_pGesture->filter_mask |= HoldFilterMask;
+       num_pressed = 0;
+       base_area_size = 0;
+       base_time = 0;
+       base_cx = base_cy = 0;
+       state = GestureEnd;
+       base_box_ext.x1 = base_box_ext.x2 = base_box_ext.y1 = base_box_ext.y2 = 0;
+       TimerCancel(hold_event_timer);
+       return;
+}
+
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+int
+GestureBezelAngleRecognize(int type, int distance, double angle)
+{
+       if (distance < g_pGesture->bezel.flick_distance)
+       {
+#ifdef __BEZEL_DEBUG__
+               XDBG_DEBUG(MGEST, "distance(%d) < flick_distance(%d)\n", distance, g_pGesture->bezel.flick_distance);
+#endif//__BEZEL_DEBUG__
+               return 0;
+       }
+       switch(type)
+       {
+               case BEZEL_TOP_LEFT:
+                       break;
+               case BEZEL_TOP_RIGHT:
+                       break;
+               case BEZEL_BOTTOM_LEFT:
+                       if( (g_pGesture->bezel.min_rad< angle) && (angle < g_pGesture->bezel.max_rad) )
+                       {
+#ifdef __BEZEL_DEBUG__
+                               XDBG_DEBUG(MGEST, "bottom_left bezel success....\n");
+#endif//__BEZEL_DEBUG__
+                               return 1;
+                       }
+                       else
+                       {
+#ifdef __BEZEL_DEBUG__
+                               XDBG_DEBUG(MGEST, "bottom_left bezel failed....\n");
+#endif//__BEZEL_DEBUG__
+                               return 0;
+                       }
+               case BEZEL_BOTTOM_RIGHT:
+                       if( (g_pGesture->bezel.min_180_rad< angle) && (angle < g_pGesture->bezel.max_180_rad))
+                       {
+#ifdef __BEZEL_DEBUG__
+                               XDBG_DEBUG(MGEST, "bottom_right bezel success...\n");
+#endif//__BEZEL_DEBUG__
+                               return 1;
+                       }
+                       else
+                       {
+#ifdef __BEZEL_DEBUG__
+                               XDBG_DEBUG(MGEST, "bottom_right bezel failed....\n");
+#endif//__BEZEL_DEBUG__
+                               return 0;
+                       }
+               default:
+                       return 0;
+       }
+       return 0;
+}
+#endif
+
+static inline void
+GestureEnableDisable()
+{
+       if((g_pGesture->grabMask) || (g_pGesture->lastSelectedWin != None))
+       {
+               GestureEnable(1, FALSE, g_pGesture->this_device);
+       }
+       else
+       {
+               GestureEnable(0, FALSE, g_pGesture->this_device);
+       }
+}
+
+void
+GestureCbEventsGrabbed(Mask *pGrabMask, GestureGrabEventPtr *pGrabEvent)
+{
+       g_pGesture->grabMask = *pGrabMask;
+       g_pGesture->GrabEvents = (GestureGrabEventPtr)pGrabEvent;
+       GestureEnableDisable();
+}
+
+void
+GestureCbEventsSelected(Window win, Mask *pEventMask)
+{
+       g_pGesture->lastSelectedWin = win;
+       g_pGesture->lastSelectedMask = (pEventMask) ? *pEventMask : 0;
+       GestureEnableDisable();
+}
+
+WindowPtr
+GestureGetEventsWindow(void)
+{
+       Mask mask;
+       WindowPtr pWin;
+
+       pWin = GestureWindowOnXY(g_pGesture->fingers[0].px, g_pGesture->fingers[0].py);
+
+       if( pWin )
+       {
+#ifdef __DETAIL_DEBUG__
+               XDBG_DEBUG(MGEST, "pWin->drawable.id=0x%x\n", pWin->drawable.id);
+#endif//__DETAIL_DEBUG__
+               g_pGesture->gestureWin = pWin->drawable.id;
+       }
+       else
+       {
+#ifdef __DETAIL_DEBUG__
+               XDBG_DEBUG(MGEST, "GestureWindowOnXY returns NULL !\n");
+#endif//__DETAIL_DEBUG__
+               return NULL;
+       }
+       if(g_pGesture->gestureWin == g_pGesture->lastSelectedWin)
+       {
+               g_pGesture->eventMask = g_pGesture->lastSelectedMask;
+               goto nonempty_eventmask;
+       }
+
+       //check selected event(s)
+       if( !GestureHasSelectedEvents(pWin, &g_pGesture->eventMask) )
+       {
+               g_pGesture->eventMask = 0;
+       }
+       else
+       {
+               g_pGesture->lastSelectedWin = g_pGesture->gestureWin;
+               g_pGesture->lastSelectedMask = g_pGesture->eventMask;
+       }
+
+       if( !g_pGesture->eventMask && !g_pGesture->grabMask)
+       {
+#ifdef __DETAIL_DEBUG__
+               XDBG_DEBUG(MGEST, "No grabbed events or no events were selected for window(0x%x) !\n", pWin->drawable.id);
+#endif//__DETAIL_DEBUG__
+               return NULL;
+       }
+
+nonempty_eventmask:
+
+#ifdef __DETAIL_DEBUG__
+       XDBG_DEBUG(MGEST, "g_pGesture->eventMask=0x%x\n", g_pGesture->eventMask);
+#endif//__DETAIL_DEBUG__
+
+       mask = (GESTURE_FILTER_MASK_ALL & ~(g_pGesture->grabMask | g_pGesture->eventMask));
+
+#ifdef __DETAIL_DEBUG__
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+       XDBG_DEBUG(MGEST, "g_pGesture->filter_mask=0x%x, mask=0x%x, palm_filter_mask=0x%x bezel_filter_mask=0x%x\n", g_pGesture->filter_mask, mask, g_pGesture->palm_filter_mask, g_pGesture->bezel_filter_mask);
+#else
+       XDBG_DEBUG(MGEST, "g_pGesture->filter_mask=0x%x, mask=0x%x, palm_filter_mask=0x%x\n", g_pGesture->filter_mask, mask, g_pGesture->palm_filter_mask);
+#endif
+#endif//__DETAIL_DEBUG__
+       g_pGesture->palm_filter_mask = 0;
+       if(mask & FlickFilterMask)
+       {
+               g_pGesture->palm_filter_mask |= PalmFlickHorizFilterMask;
+               g_pGesture->palm_filter_mask |= PalmFlickVertiFilterMask;
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+               g_pGesture->bezel_filter_mask |= BezelFlickFilterMask;
+#endif
+       }
+       if(!(mask & FlickFilterMask))
+       {
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+               if(!(g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[1].window))
+               {
+                       g_pGesture->bezel_filter_mask |= BezelFlickFilterMask;
+               }
+               else
+#endif
+               if(!(g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[0].window))
+               {
+                       g_pGesture->palm_filter_mask |= PalmFlickHorizFilterMask;
+                       g_pGesture->palm_filter_mask |= PalmFlickVertiFilterMask;
+               }
+       }
+       if(!g_pGesture->palm.palmflag)
+       {
+               if(!GestureHasFingersEvents(HoldFilterMask))
+                       mask |= HoldFilterMask;
+               if(!GestureHasFingersEvents(FlickFilterMask))
+                       mask |= FlickFilterMask;
+               g_pGesture->filter_mask = mask;
+       }
+#ifdef __DETAIL_DEBUG__
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+       XDBG_DEBUG(MGEST, "g_pGesture->filter_mask=0x%x, palm_filter_mask: 0x%x, bezel_filter_mask=0x%x\n", g_pGesture->filter_mask, g_pGesture->palm_filter_mask, g_pGesture->bezel_filter_mask);
+#else
+       XDBG_DEBUG(MGEST, "g_pGesture->filter_mask=0x%x, palm_filter_mask: 0x%x\n", g_pGesture->filter_mask, g_pGesture->palm_filter_mask);
+#endif
+#endif//__DETAIL_DEBUG__
+
+       return pWin;
+}
+
+static Bool
+GestureHasFingersEvents(int eventType)
+{
+       int i=0;
+       Mask eventmask = (1L << eventType);
+       for(i=2; i<MAX_MT_DEVICES; i++)
+       {
+               if( (g_pGesture->grabMask & eventmask) &&
+               (g_pGesture->GrabEvents[eventType].pGestureGrabWinInfo[i].window != None) )
+               {
+#ifdef __DETAIL_DEBUG__
+                       XDBG_DEBUG(MGEST, "TRUE !! Has grabMask\n");
+#endif//__DETAIL_DEBUG__
+                       return TRUE;
+               }
+       }
+       return FALSE;
+}
+
+static CARD32
+GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
+{
+       int event_type = *(int *)arg;
+
+       switch( event_type )
+       {
+               case GestureNotifyHold:
+#ifdef __DETAIL_DEBUG__
+                       XDBG_DEBUG(MGEST, "GestureNotifyHold (event_type = %d)\n", event_type);
+#endif//__DETAIL_DEBUG__
+                       GestureRecognize_GroupHold(event_type, NULL, NULL, 0, 1);
+                       break;
+
+               case GestureNotifyPan:
+#ifdef __DETAIL_DEBUG__
+                       XDBG_DEBUG(MGEST, "GestureNotifyPan (event_type = %d)\n", event_type);
+#endif//__DETAIL_DEBUG__
+                       GestureRecognize_GroupPan(event_type, NULL, NULL, 0, 1);
+                       break;
+
+               case GestureNotifyTap:
+#ifdef __DETAIL_DEBUG__
+                       XDBG_DEBUG(MGEST, "GestureNotifyTap (event_type = %d)\n", event_type);
+#endif//__DETAIL_DEBUG__
+                       GestureRecognize_GroupTap(event_type, NULL, NULL, 0, 1);
+                       break;
+
+               case GestureNotifyTapNHold:
+#ifdef __DETAIL_DEBUG__
+                       XDBG_DEBUG(MGEST, "GestureNotifyTapNHold (event_type = %d)\n", event_type);
+#endif//__DETAIL_DEBUG__
+                       GestureRecognize_GroupTapNHold(event_type, NULL, NULL, 0, 1);
+                       break;
+
+               case GestureNotifyPinchRotation:
+#ifdef __DETAIL_DEBUG__
+                       XDBG_DEBUG(MGEST, "GestureNotifyPinchRotation (event_type = %d)\n", event_type);
+#endif//__DETAIL_DEBUG__
+                       GestureRecognize_GroupPinchRotation(event_type, NULL, NULL, 0, 1);
+                       break;
+
+               default:
+#ifdef __DETAIL_DEBUG__
+                       XDBG_DEBUG(MGEST, "unknown event_type (=%d)\n", event_type);
+#endif//__DETAIL_DEBUG__
+                       if(timer)
+                               XDBG_INFO(MGEST, "timer=%x\n", (unsigned int)timer);
+       }
+
+       return 0;
+}
+
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+static CARD32
+GestureBezelSingleFingerTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
+{
+       BezelFlickStatusPtr pBezel = &g_pGesture->bezel;
+
+       if( pBezel->is_active != BEZEL_NONE )
+       {
+               pBezel->is_active = BEZEL_END;
+#ifdef __BEZEL_DEBUG__
+               XDBG_DEBUG(MGEST, "end\n");
+#endif//__BEZEL_DEBUG__
+       }
+       return 0;
+}
+#endif
+
+static CARD32
+GestureSingleFingerTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
+{
+       g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
+       g_pGesture->recognized_gesture = 0;
+
+       if( ERROR_INVALPTR == GestureFlushOrDrop() )
+       {
+               GestureControl(g_pGesture->this_device, DEVICE_OFF);
+       }
+
+#ifdef __DETAIL_DEBUG__
+       XDBG_DEBUG(MGEST, "expired !\n");
+#endif//__DETAIL_DEBUG__
+
+       return 0;
+}
+
+static CARD32
+GesturePalmSingleFingerTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
+{
+       PalmStatusPtr pPalm = &g_pGesture->palm;
+       if(pPalm->palmflag || (pPalm->biggest_tmajor >= PALM_FLICK_FINGER_MIN_TOUCH_MAJOR))
+       {
+               pPalm->single_timer_expired = 0;
+               return 0;
+       }
+
+       pPalm->single_timer_expired = 1;
+#ifdef __PALM_DETAIL_LOG__
+       XDBG_DEBUG(MGEST, "palm expired !\n");
+#endif//__DETAIL_DEBUG__
+
+       return 0;
+}
+
+static int
+GesturePalmGetHorizIndexWithX(int x, int type)
+{
+       int i;
+       int ret_idx = -1;
+       static int pressed_idx = -1;
+       PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
+
+       for(i = 0 ; i < PALM_HORIZ_ARRAY_COUNT ; i++)
+       {
+#ifdef __PALM_DETAIL_LOG__
+               XDBG_DEBUG(MGEST, "pPalmMisc->horiz_coord[%d]=%d, x=%d\n", i, pPalmMisc->horiz_coord[i], x);
+#endif//__PALM_DETAIL_LOG__
+               if(x <= pPalmMisc->horiz_coord[i])
+               {
+#ifdef __PALM_DETAIL_LOG__
+                       XDBG_DEBUG(MGEST, "index=%d\n", i);
+#endif//__PALM_DETAIL_LOG__
+                       ret_idx = i;
+                       goto index_check;
+               }
+       }
+#ifdef __PALM_DETAIL_LOG__
+       XDBG_DEBUG(MGEST, "Error ! Failed to get horiz coordinate index !\n");
+#endif//__PALM_DETAIL_LOG__
+       return ret_idx;
+
+index_check:
+
+       if(type == ET_ButtonPress)
+       {
+               pressed_idx = ret_idx;
+       }
+       else if(type == ET_ButtonRelease)
+       {
+               if((pressed_idx <= 1) && (ret_idx >= (PALM_HORIZ_ARRAY_COUNT-2)))
+               {
+#ifdef __PALM_DETAIL_LOG__
+                       XDBG_DEBUG(MGEST, "[R] Valid !\n");
+#else
+                       ;
+#endif//__PALM_DETAIL_LOG__
+               }
+               else if((pressed_idx >= (PALM_HORIZ_ARRAY_COUNT-2)) && (ret_idx <= 1))
+               {
+#ifdef __PALM_DETAIL_LOG__
+                       XDBG_DEBUG(MGEST, "[R] Valid !\n");
+#else
+                       ;
+#endif//__PALM_DETAIL_LOG__
+               }
+               else
+               {
+#ifdef __PALM_DETAIL_LOG__
+                       XDBG_DEBUG(MGEST, "[R] Invalid !(pressed_idx=%d, released_idx=%d\n", pressed_idx, ret_idx);
+#endif//__PALM_DETAIL_LOG__
+                       ret_idx = -1;
+               }
+       }
+
+       return ret_idx;
+}
+
+static int
+GesturePalmGetVertiIndexWithY(int y, int type)
+{
+       int i;
+       int ret_idx = -1;
+       static int pressed_idx = -1;
+       PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
+
+       for(i = 0 ; i < PALM_VERTI_ARRAY_COUNT ; i++)
+       {
+#ifdef __PALM_DETAIL_LOG__
+               XDBG_DEBUG(MGEST, "pPalmMisc->verti_coord[%d]=%d, x=%d\n", i, pPalmMisc->verti_coord[i], y);
+#endif//__PALM_DETAIL_LOG__
+               if(y <= pPalmMisc->verti_coord[i])
+               {
+#ifdef __PALM_DETAIL_LOG__
+                       XDBG_DEBUG(MGEST, "index=%d\n", i);
+#endif//__PALM_DETAIL_LOG__
+                       ret_idx = i;
+                       goto index_check;
+               }
+       }
+#ifdef __PALM_DETAIL_LOG__
+       XDBG_DEBUG(MGEST, "Error ! Failed to get verti coordinate index !\n");
+#endif//__PALM_DETAIL_LOG__
+       return ret_idx;
+
+index_check:
+
+       if(type == ET_ButtonPress)
+       {
+               if((ret_idx <= 1) || (ret_idx >=(PALM_VERTI_ARRAY_COUNT-2)))
+               {
+#ifdef __PALM_DETAIL_LOG__
+                       XDBG_DEBUG(MGEST, "[P] Valid !\n");
+#endif//__PALM_DETAIL_LOG__
+                       pressed_idx = ret_idx;
+               }
+               else
+               {
+#ifdef __PALM_DETAIL_LOG__
+                       XDBG_DEBUG(MGEST, "[P] Invalid !(pressed_idx(=%d) must be between 0 and 1 or between 3 and 4\n", pressed_idx);
+#endif//__PALM_DETAIL_LOG__
+                       ret_idx = -1;
+               }
+
+       }
+       else if(type == ET_ButtonRelease)
+       {
+               if((pressed_idx <= 1) && (ret_idx >= (PALM_VERTI_ARRAY_COUNT-2)))
+               {
+#ifdef __PALM_DETAIL_LOG__
+                       XDBG_DEBUG(MGEST, "[R] Valid !\n");
+#else
+                       ;
+#endif//__PALM_DETAIL_LOG__
+               }
+               else if((pressed_idx >= (PALM_VERTI_ARRAY_COUNT-2)) && (ret_idx <= 1))
+               {
+#ifdef __PALM_DETAIL_LOG__
+                       XDBG_DEBUG(MGEST, "[R] Valid !\n");
+#else
+                       ;
+#endif//__PALM_DETAIL_LOG__
+               }
+               else
+               {
+#ifdef __PALM_DETAIL_LOG__
+                       XDBG_DEBUG(MGEST, "[R] Invalid !(pressed_idx=%d, released_idx=%d\n", pressed_idx, ret_idx);
+#endif//__PALM_DETAIL_LOG__
+                       ret_idx = -1;
+               }
+       }
+
+       return ret_idx;
+}
+
+static void
+GesturePalmRecognize_FlickHorizen(int type, int idx)
+{
+       static int curTouched = 0;
+       static int num_pressed = 0;
+       static int base_width_size = 0;
+       static Time base_time = 0;
+       static int base_x;
+       static pixman_box16_t base_box_ext;
+#ifdef __PALM_GESTURE_LOG__
+       int i;
+#endif
+
+       int line_idx;
+       static int prev_line_idx;
+       static int horiz_line[PALM_HORIZ_ARRAY_COUNT];
+
+       Time duration;
+       int distx=0, disty=0;
+       int distance, direction;
+
+       int width_size;
+       static int is_flicking = 1;
+       //static int is_surface = 0;
+       static int pass_count = 0;
+       static int base_cx=0, base_cy=0;
+       static int release_flag = 0;
+
+       PalmStatusPtr pPalm = &g_pGesture->palm;
+#ifdef __PALM_GESTURE_LOG__
+       XDBG_DEBUG(MGEST, "recognized_palm= 0x%x, palm_filter_mask= 0x%x\n", g_pGesture->recognized_palm, g_pGesture->palm_filter_mask);
+       XDBG_DEBUG(MGEST, "num_pressed: %d, cur_touched: %d palmflag: %d\n", num_pressed, pPalm->cur_touched, pPalm->palmflag);
+       XDBG_DEBUG(MGEST, "idx: %d, cx: %d, cy: %d, type: %d, touch_status: %d\n", idx, pPalm->cx, pPalm->cy, type, pPalm->pti[idx].touch_status);
+#endif
+
+       if( idx < 0 )
+               goto flick_failed;
+
+       if(g_pGesture->enqueue_fulled == 1)
+       {
+#ifdef __PALM_GESTURE_LOG__
+                       XDBG_DEBUG(MGEST, "EQ Event is full.... palm recognize drop..\n");
+#endif
+                       goto flick_failed;
+       }
+
+       if(pPalm->single_timer_expired)
+       {
+#ifdef __PALM_GESTURE_LOG__
+               XDBG_DEBUG(MGEST, "No flick single finger...expired\n");
+#endif
+               goto flick_failed;
+       }
+
+       if(g_pGesture->recognized_gesture || g_pGesture->hold_detected ||
+               (g_pGesture->recognized_palm && !(g_pGesture->recognized_palm & PalmFlickHorizFilterMask)) || (g_pGesture->palm_filter_mask & PalmFlickHorizFilterMask)
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+               || g_pGesture->bezel_recognized_mask)
+#else
+               )
+#endif
+       {
+#ifdef __PALM_GESTURE_LOG__
+               XDBG_DEBUG(MGEST, "zoom_enabled: %d\n", g_pGesture->zoom_enabled);
+               XDBG_DEBUG(MGEST, "type(%d) recognized_palm= 0x%x, palm_filter_mask= 0x%x\n", type, g_pGesture->recognized_palm, g_pGesture->palm_filter_mask);
+               XDBG_DEBUG(MGEST, "type(%d) recognized_gesture= 0x%x, filter_mask= 0x%x\n", type, g_pGesture->recognized_gesture, g_pGesture->filter_mask);
+#endif
+               goto flick_failed;
+       }
+       switch( type )
+       {
+               case ET_ButtonPress:
+                       if(!is_flicking)
+                               break;
+                       if(!base_width_size || pPalm->cur_touched > curTouched)
+                       {
+                               if(!base_time)
+                               {
+                                       base_time = GetTimeInMillis();
+                                       base_x = AREA_CENTER_X(&pPalm->area.extents);
+                                       line_idx = GesturePalmGetHorizIndexWithX(base_x, type);
+#ifdef __PALM_GESTURE_LOG__
+                                       XDBG_DEBUG(MGEST, "[P] cx: %d, cy: %d, x1: %d, x2: %d, y1: %d, y2: %d, line_idx: %d\n", pPalm->cx, pPalm->cy, pPalm->area.extents.x1, pPalm->area.extents.x2, pPalm->area.extents.y1, pPalm->area.extents.y2, line_idx);
+#endif
+                                       if(line_idx < 0)
+                                       {
+#ifdef __PALM_GESTURE_LOG__
+                                               XDBG_DEBUG(MGEST, "[P] No line_idx is invalid.. base_x: %d, line_idx: %d\n", base_x, line_idx);
+#endif
+                                               goto flick_failed;
+                                       }
+
+                                       horiz_line[line_idx]++;
+                                       pass_count++;
+                                       prev_line_idx = line_idx;
+                                       release_flag = 0;
+#ifdef __PALM_GESTURE_LOG__
+                                       XDBG_DEBUG(MGEST, "[P] Base_width=%d, base_x=%d, line_idx=%d\n", base_width_size, base_x, line_idx);
+#endif
+                               }
+
+                               base_width_size = AREA_WIDTH(&pPalm->area.extents);
+                               if(base_width_size > PALM_FLICK_HORIZ_MAX_BASE_WIDTH)
+                               {
+#ifdef __PALM_GESTURE_LOG__
+                                       XDBG_DEBUG(MGEST, "[P] No flickBase_width=%d > %d: MAX_WIDTH\n", base_width_size, PALM_FLICK_HORIZ_MAX_BASE_WIDTH);
+#endif
+                                       goto flick_failed;
+                               }
+#ifdef __PALM_GESTURE_LOG__
+                               XDBG_DEBUG(MGEST, "[P] Base_width=%d, cur_touched=%d\n", base_width_size, pPalm->cur_touched);
+#endif
+                               if(pPalm->max_touched == 1)
+                               {
+                                       base_cx = AREA_CENTER_X(&pPalm->area.extents);
+                                       base_cy = AREA_CENTER_Y(&pPalm->area.extents);
+                                       base_box_ext.x1 = base_cx-HOLD_MOVE_THRESHOLD;
+                                       base_box_ext.y1 = base_cy-HOLD_MOVE_THRESHOLD;
+                                       base_box_ext.x2 = base_cx+HOLD_MOVE_THRESHOLD;
+                                       base_box_ext.y2 = base_cy+HOLD_MOVE_THRESHOLD;
+                               }
+                       }
+                       curTouched = pPalm->cur_touched;
+                       num_pressed++;
+                       break;
+
+               case ET_Motion:
+                       if(!num_pressed || !is_flicking)
+                       {
+#ifdef __PALM_GESTURE_LOG__
+                               XDBG_DEBUG(MGEST, "[M] num_pressed: %d, is_flicking: %d\n", num_pressed, is_flicking);
+#endif
+                               break;
+                       }
+
+                       distx = AREA_CENTER_X(&pPalm->area.extents);
+                       disty = AREA_CENTER_Y(&pPalm->area.extents);
+                       line_idx = GesturePalmGetHorizIndexWithX(distx, type);
+#ifdef __PALM_GESTURE_LOG__
+                       for(i=0; i<PALM_HORIZ_ARRAY_COUNT; i++)
+                       {
+                               XDBG_DEBUG(MGEST, "M] %d: %d\n", i, horiz_line[i]);
+                       }
+                       XDBG_DEBUG(MGEST, "[M] distx: %d, line_idx: %d, prev_line_idx: %d! pass_count: %d\n", distx, line_idx, prev_line_idx, pass_count);
+#endif
+
+                       if(line_idx < 0)
+                       {
+#ifdef __PALM_GESTURE_LOG__
+                               XDBG_DEBUG(MGEST, "[M] No line_idx is invalid.. base_x: %d, line_idx: %d\n", base_x, line_idx);
+#endif
+                               goto flick_failed;
+                       }
+
+                       if(pPalm->max_touched == 1)
+                       {
+                               if(ABS(disty - base_cy) > PALM_FLICK_HORIZ_MAX_MOVE_Y)
+                               {
+#ifdef __PALM_GESTURE_LOG__
+                                       XDBG_DEBUG(MGEST, "[M] No flick ! (move too long toward y coordination %d(%d - %d) > %d\n", ABS(disty - base_cy), disty, base_cy, PALM_FLICK_HORIZ_MAX_MOVE_Y);
+#endif
+                                       goto flick_failed;
+                               }
+                       }
+
+                       if(prev_line_idx != line_idx)
+                       {
+                               horiz_line[line_idx]++;
+                               if(horiz_line[line_idx] > 2)
+                               {
+#ifdef __PALM_GESTURE_LOG__
+                                       XDBG_DEBUG(MGEST, "[M] No flick ! horiz_line[%d]: %d > 2\n", line_idx, horiz_line[line_idx]);
+#endif
+                                       goto flick_failed;
+                               }
+                               pass_count++;
+                       }
+                       if(pass_count > 6)
+                       {
+#ifdef __PALM_GESTURE_LOG__
+                               XDBG_DEBUG(MGEST, "[M] No flick !(visit same place twice !)\n");
+#endif
+                               goto flick_failed;
+                       }
+#if 0
+                       if((prev_line_idx != line_idx) && horiz_line[line_idx] && !release_flag)
+                       {
+#ifdef __PALM_GESTURE_LOG__
+                               XDBG_DEBUG(MGEST, "[M] No flick !(visit same place twice !)\n");
+#endif
+                               goto flick_failed;
+                       }
+#endif
+                       prev_line_idx = line_idx;
+
+                       width_size = AREA_WIDTH(&pPalm->area.extents);
+#ifdef __PALM_GESTURE_LOG__
+                       XDBG_DEBUG(MGEST, "[M] Base_width=%d, Current_width=%d, diff=%d\n", base_width_size, width_size, ABS(width_size - base_width_size));
+#endif
+                       duration = GetTimeInMillis() - base_time;
+#ifdef __PALM_GESTURE_LOG__
+                       XDBG_DEBUG(MGEST, "[M] duration =%d !\n", duration);
+#endif
+                       if(((!pPalm->palmflag) && (pPalm->biggest_tmajor < PALM_FLICK_TOUCH_MAJOR-20) && (pPalm->biggest_wmajor < PALM_FLICK_TOUCH_MAJOR-20)) &&
+                       (duration >= PALM_FLICK_INITIAL_TIMEOUT))
+                       {
+#ifdef __PALM_GESTURE_LOG__
+                               XDBG_DEBUG(MGEST, "[M] No flick !(initial flick timeout : duration=%d)\n", duration);
+#endif
+                               goto flick_failed;
+                       }
+                       if( (duration >= PALM_FLICK_INITIAL_TIMEOUT) && (INBOX(&base_box_ext, distx, disty)) )
+                       {
+#ifdef __PALM_GESTURE_LOG__
+                               XDBG_DEBUG(MGEST, "[M] No flick !(move too short !in duration: %d)\n", duration);
+#endif
+                               goto flick_failed;
+                       }
+                       if( (duration >= PALM_FLICK_FALSE_TIMEOUT) && (pPalm->biggest_tmajor < PALM_FLICK_TOUCH_MAJOR) && (pPalm->biggest_wmajor < PALM_FLICK_TOUCH_MAJOR))
+                       {
+#ifdef __PALM_GESTURE_LOG__
+                               XDBG_DEBUG(MGEST, "[M] No flick !(press touch major(%.f) width major (%.f) < (%.f) is little in duration(%d))\n", pPalm->biggest_tmajor, pPalm->biggest_wmajor, PALM_FLICK_TOUCH_MAJOR, duration);
+#endif
+                               goto flick_failed;
+                       }
+
+                       if(duration >= PALM_FLICK_DETECT_TIMEOUT)
+                       {
+#ifdef __PALM_GESTURE_LOG__
+                               XDBG_DEBUG(MGEST, "[M] No flick !(flick detection timeout : duration=%d)\n", duration);
+#endif
+                               goto flick_failed;
+                       }
+                       break;
+
+               case ET_ButtonRelease:
+                       release_flag = 1;
+                       if(--num_pressed < 0)
+                               num_pressed = 0;
+                       base_width_size = AREA_WIDTH(&pPalm->area.extents);
+                       if(num_pressed)
+                               break;
+
+                       if((!pPalm->palmflag) && (pPalm->biggest_tmajor < 100) && (pPalm->bigger_wmajor < 100))
+                       {
+#ifdef __PALM_GESTURE_LOG__
+                               XDBG_DEBUG(MGEST, "[R] No flick (No palm comming and all finger release))\n");
+#endif
+                               goto flick_failed;
+                       }
+
+                       if(!is_flicking)
+                               goto cleanup_flick;
+
+                       duration = GetTimeInMillis() - base_time;
+                       distx = AREA_CENTER_X(&pPalm->area.extents);
+                       line_idx = GesturePalmGetHorizIndexWithX(distx, type);
+
+                       if(line_idx < 0)
+                       {
+#ifdef __PALM_GESTURE_LOG__
+                               XDBG_DEBUG(MGEST, "[R] No flick (distx: %d, line_idx: %d))\n", distx, line_idx);
+#endif
+                               goto flick_failed;
+                       }
+#ifdef __PALM_GESTURE_LOG__
+                       XDBG_DEBUG(MGEST, "[R] duration=%d, distx=%d\n", duration, distx);
+#endif
+                       if(duration >= PALM_FLICK_DETECT_TIMEOUT)
+                       {
+#ifdef __PALM_GESTURE_LOG__
+                               XDBG_DEBUG(MGEST, "[R] No flick !(flick detection timeout : duration=%d)\n", duration);
+#endif
+                               goto flick_failed;
+                       }
+                       if(pass_count < PALM_HORIZ_ARRAY_COUNT - 1)
+                       {
+#ifdef __PALM_GESTURE_LOG__
+                               XDBG_DEBUG(MGEST, "[R] No flick !(flick distance is short!\n");
+#endif
+                               goto flick_failed;
+                       }
+                       if((pPalm->biggest_tmajor < PALM_FLICK_TOUCH_MAJOR) && (pPalm->biggest_wmajor < PALM_FLICK_TOUCH_MAJOR))
+                       {
+#ifdef __PALM_GESTURE_LOG__
+                               XDBG_DEBUG(MGEST, "[R] No flick !(touch major(%.f) width major(%.f) < %d) is small...)\n", pPalm->biggest_tmajor, pPalm->biggest_wmajor, PALM_FLICK_TOUCH_MAJOR);
+#endif
+                               goto flick_failed;
+                       }
+
+                       direction = (line_idx <= 1) ? FLICK_EASTWARD : FLICK_WESTWARD;
+                       distance = ABS(distx - base_x);
+#ifdef __PALM_GESTURE_LOG__
+                       XDBG_DEBUG(MGEST, "[R] Palm Flick !!!, direction=%d, distance=%d\n", direction, distance);
+#endif
+                       if( GestureHasFingerEventMask(GestureNotifyFlick, 0) )
+                               GestureHandleGesture_Flick(0, distance, duration, direction);
+                       goto cleanup_flick;
+                       break;
+       }
+
+       return;
+
+flick_failed:
+       is_flicking = 0;
+       g_pGesture->recognized_palm &= ~PalmFlickHorizFilterMask;
+       g_pGesture->palm_filter_mask |= PalmFlickHorizFilterMask;
+#ifdef __PALM_GESTURE_LOG__
+       XDBG_DEBUG(MGEST, "[Failed] recognized_palm= 0x%x, palm_filter_mask: 0x%x\n", g_pGesture->recognized_palm, g_pGesture->palm_filter_mask);
+#endif
+       goto cleanup_flick;
+       return;
+
+cleanup_flick:
+       num_pressed = 0;
+       is_flicking = 1;
+       base_width_size = 0;
+       //is_surface = 0;
+       base_time = 0;
+       curTouched = 0;
+       pass_count = 0;
+       prev_line_idx = 0;
+       release_flag = 0;
+       base_cx = base_cy = 0;
+       base_box_ext.x1 = base_box_ext.x2 = base_box_ext.y1 = base_box_ext.y2 = 0;
+       memset(&horiz_line, 0L, PALM_HORIZ_ARRAY_COUNT * sizeof(int));
+#ifdef __PALM_GESTURE_LOG__
+       XDBG_DEBUG(MGEST, "[cleanup_flick] base_width_size=%d, curTouched=%d\n", base_width_size, curTouched);
+#endif
+       return;
+}
+
+static void
+GesturePalmRecognize_FlickVertical(int type,int idx)
+{
+       static int curTouched = 0;
+       static int num_pressed = 0;
+       static int base_height_size = 0;
+       static Time base_time = 0;
+       static int base_y;
+       static int base_cx, base_cy;
+       static int pass_count = 0;
+       static int release_flag = 0;
+       static pixman_box16_t base_box_ext;
+
+       int line_idx;
+       static int prev_line_idx;
+       static int verti_line[PALM_VERTI_ARRAY_COUNT];
+
+       Time duration;
+       int disty;
+       int distx;
+       int distance, direction;
+
+       int height_size;
+       static int is_flicking = 1;
+       static int false_base_height_size = 0;
+
+       PalmStatusPtr pPalm = &g_pGesture->palm;
+#ifdef __PALM_GESTURE_LOG__
+       XDBG_DEBUG(MGEST, "recognized_palm= 0x%x, palm_filter_mask= 0x%x\n", g_pGesture->recognized_palm, g_pGesture->palm_filter_mask);
+       XDBG_DEBUG(MGEST, "num_pressed: %d, cur_touched: %d, palm_flag: %d, single_timer_expired: %d\n", num_pressed, pPalm->cur_touched, pPalm->palmflag, pPalm->single_timer_expired);
+#endif
+
+       if( idx < 0 )
+               goto flick_failed;
+
+       if(g_pGesture->enqueue_fulled == 1)
+       {
+#ifdef __PALM_GESTURE_LOG__
+               XDBG_DEBUG(MGEST, "EQ Event is full.... No palm recognize drop..\n");
+#endif
+               goto flick_failed;
+       }
+
+       if(g_pGesture->recognized_gesture || g_pGesture->hold_detected ||
+               (g_pGesture->recognized_palm && !(g_pGesture->recognized_palm & PalmFlickVertiFilterMask)) || (g_pGesture->palm_filter_mask & PalmFlickVertiFilterMask)
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+               || g_pGesture->bezel_recognized_mask)
+#else
+               )
+#endif
+       {
+#ifdef __PALM_GESTURE_LOG__
+               XDBG_DEBUG(MGEST, "zoom_enabled: %d\n", g_pGesture->zoom_enabled);
+               XDBG_DEBUG(MGEST, "type(%d) recognized_palm= 0x%x, palm_filter_mask= 0x%x\n", type, g_pGesture->recognized_palm, g_pGesture->palm_filter_mask);
+               XDBG_DEBUG(MGEST, "type(%d) recognized_gesture= 0x%x, filter_mask= 0x%x\n", type, g_pGesture->recognized_gesture, g_pGesture->filter_mask);
+#endif
+               goto flick_failed;
+       }
+
+       if(pPalm->single_timer_expired)
+       {
+#ifdef __PALM_GESTURE_LOG__
+               XDBG_DEBUG(MGEST, "No flick single finger...expired\n");
+#endif
+               goto flick_failed;
+       }
+
+       switch( type )
+       {
+               case ET_ButtonPress:
+                       if(!is_flicking)
+                               break;
+                       if(!base_height_size || pPalm->cur_touched > curTouched)
+                       {
+                               if(!base_time)
+                               {
+                                       base_time = GetTimeInMillis();
+                                       base_y = AREA_CENTER_Y(&pPalm->area.extents);
+                                       line_idx = GesturePalmGetVertiIndexWithY(base_y, type);
+
+#ifdef __PALM_GESTURE_LOG__
+                                       XDBG_DEBUG(MGEST, "[P] Base_height=%d, base_y=%d, line_idx=%d\n", base_height_size, base_y, line_idx);
+#endif
+                                       if(line_idx < 0)
+                                       {
+#ifdef __PALM_GESTURE_LOG__
+                                               XDBG_DEBUG(MGEST, "[P] No Base_height=%d, base_y=%d, line_idx=%d\n", base_height_size, base_y, line_idx);
+#endif
+                                               goto flick_failed;
+                                       }
+
+                                       verti_line[line_idx] = 1;
+                                       pass_count++;
+                                       prev_line_idx = line_idx;
+                                       release_flag = 0;
+#ifdef __PALM_GESTURE_LOG__
+                                       XDBG_DEBUG(MGEST, "[P] Base_height=%d, base_y=%d, line_idx=%d\n", base_height_size, base_y, line_idx);
+#endif
+                               }
+
+                               base_height_size = AREA_HEIGHT(&pPalm->area.extents);
+#ifdef __PALM_GESTURE_LOG__
+                               XDBG_DEBUG(MGEST, "[P] Base_height=%d, cur_touched=%d\n", base_height_size, pPalm->cur_touched);
+#endif
+                               if(base_height_size > PALM_FLICK_VERTI_MAX_BASE_WIDTH)
+                               {
+#ifdef __PALM_GESTURE_LOG__
+                                       XDBG_DEBUG(MGEST, "[P] No flickBase_width=%d > MAX_WIDTH\n", base_height_size, PALM_FLICK_VERTI_MAX_BASE_WIDTH);
+#endif
+                                       goto flick_failed;
+                               }
+                               false_base_height_size = 0;
+                               if(pPalm->max_touched == 1)
+                               {
+                                       base_cx = AREA_CENTER_X(&pPalm->area.extents);
+                                       base_cy = AREA_CENTER_Y(&pPalm->area.extents);
+                                       base_box_ext.x1 = base_cx-HOLD_MOVE_THRESHOLD;
+                                       base_box_ext.y1 = base_cy-HOLD_MOVE_THRESHOLD;
+                                       base_box_ext.x2 = base_cx+HOLD_MOVE_THRESHOLD;
+                                       base_box_ext.y2 = base_cy+HOLD_MOVE_THRESHOLD;
+                               }
+                       }
+
+                       curTouched = pPalm->cur_touched;
+                       num_pressed++;
+                       break;
+
+               case ET_Motion:
+                       if(!num_pressed|| !is_flicking)
+                               break;
+
+                       distx = AREA_CENTER_X(&pPalm->area.extents);
+                       disty = AREA_CENTER_Y(&pPalm->area.extents);
+                       line_idx = GesturePalmGetVertiIndexWithY(disty, type);
+#ifdef __PALM_GESTURE_LOG__
+                       XDBG_DEBUG(MGEST, "[M] line_idx: %d\n", line_idx);
+#endif
+
+                       if(line_idx < 0)
+                       {
+#ifdef __PALM_GESTURE_LOG__
+                               XDBG_DEBUG(MGEST, "[M] No line_idx: %d\n", line_idx);
+#endif
+                               goto flick_failed;
+                       }
+                       if((prev_line_idx != line_idx) && verti_line[line_idx] && !release_flag)
+                       {
+#ifdef __PALM_GESTURE_LOG__
+                               XDBG_DEBUG(MGEST, "[M] No flick !(visit same place twice !)\n");
+#endif
+                               goto flick_failed;
+                       }
+#if 0
+                       if(pPalm->max_touched == 1)
+                       {
+                               if(ABS(AREA_CENTER_X(&pPalm->area.extents) - base_cx) > PALM_FLICK_VERTI_MAX_MOVE_X)
+                               {
+#ifdef __PALM_GESTURE_LOG__
+                                       XDBG_DEBUG(MGEST, "[M] No flick ! (move too long toward x coordination %d(%d - %d) > PALM_FLICK_VERTI_MAX_MOVE_X\n", ABS(AREA_CENTER_X(&pPalm->area.extents) - base_cx), AREA_CENTER_X(&pPalm->area.extents) , base_cx, PALM_FLICK_VERTI_MAX_MOVE_X);
+#endif
+                                       goto flick_failed;
+                               }
+                       }
+#endif
+                       verti_line[line_idx] = 1;
+                       if(prev_line_idx != line_idx)
+                               pass_count++;
+                       prev_line_idx = line_idx;
+
+                       height_size = AREA_HEIGHT(&pPalm->area.extents);
+#ifdef __PALM_GESTURE_LOG__
+                       XDBG_DEBUG(MGEST, "[M] Base_height=%d, Current_height=%d, diff=%d\n", base_height_size, height_size, ABS(height_size - base_height_size));
+#endif
+
+                       duration = GetTimeInMillis() - base_time;
+#ifdef __PALM_GESTURE_LOG__
+                       XDBG_DEBUG(MGEST, "[M] duration =%d !\n", duration);
+#endif
+
+                       if(!pPalm->palmflag && (pPalm->biggest_tmajor < PALM_FLICK_TOUCH_MAJOR-20) && (pPalm->biggest_wmajor < PALM_FLICK_TOUCH_MAJOR-20)
+                                && (duration >= PALM_FLICK_INITIAL_TIMEOUT))
+                       {
+#ifdef __PALM_GESTURE_LOG__
+                               XDBG_DEBUG(MGEST, "[M] No flick !(initial flick timeout : duration=%d)\n", duration);
+#endif
+                               goto flick_failed;
+                       }
+                       if( (duration >= PALM_FLICK_INITIAL_TIMEOUT) && (INBOX(&base_box_ext, distx, disty)) )
+                       {
+#ifdef __PALM_GESTURE_LOG__
+                               XDBG_DEBUG(MGEST, "[M] No flick !(move too short !in duration: %d)\n", duration);
+#endif
+                               goto flick_failed;
+                       }
+
+                       if(duration >= PALM_FLICK_DETECT_TIMEOUT)
+                       {
+#ifdef __PALM_GESTURE_LOG__
+                               XDBG_DEBUG(MGEST, "[M] No flick !(flick detection timeout : duration=%d)\n", duration);
+#endif
+                               goto flick_failed;
+                       }
+                       break;
+
+               case ET_ButtonRelease:
+                       release_flag = 1;
+
+                       if(--num_pressed < 0)
+                               num_pressed = 0;
+                       if(num_pressed)
+                               break;
+
+                       if(!pPalm->palmflag && (pPalm->biggest_tmajor < 100) && (pPalm->bigger_wmajor < 100))
+                       {
+#ifdef __PALM_GESTURE_LOG__
+                               XDBG_DEBUG(MGEST, "[R] No flick (No palm comming and all finger release))\n");
+#endif
+                               goto flick_failed;
+                       }
+
+                       if(!is_flicking)
+                               goto cleanup_flick;
+
+                       duration = GetTimeInMillis() - base_time;
+                       disty = AREA_CENTER_Y(&pPalm->area.extents);
+                       line_idx = GesturePalmGetVertiIndexWithY(disty, type);
+#ifdef __PALM_GESTURE_LOG__
+                       XDBG_DEBUG(MGEST, "[R] line_idx: %d\n", line_idx);
+#endif
+
+                       if(line_idx < 0)
+                       {
+#ifdef __PALM_GESTURE_LOG__
+                               XDBG_DEBUG(MGEST, "[R] No line_idx: %d\n", line_idx);
+#endif
+                               goto flick_failed;
+                       }
+#ifdef __PALM_GESTURE_LOG__
+                       XDBG_DEBUG(MGEST, "[R] duration=%d, disty=%d\n", duration, disty);
+#endif
+
+                       if(duration >= PALM_FLICK_DETECT_TIMEOUT)
+                       {
+#ifdef __PALM_GESTURE_LOG__
+                               XDBG_DEBUG(MGEST, "[R] No flick !(flick detection timeout : duration=%d)\n", duration);
+#endif
+                               goto flick_failed;
+                       }
+                       if(pass_count < PALM_VERTI_ARRAY_COUNT -1)
+                       {
+#ifdef __PALM_GESTURE_LOG__
+                               XDBG_DEBUG(MGEST, "[R] No flick !(flick distance is short!)\n");
+#endif
+                               goto flick_failed;
+                       }
+                       if(pPalm->biggest_tmajor < PALM_FLICK_TOUCH_MAJOR && pPalm->biggest_wmajor < PALM_FLICK_TOUCH_MAJOR)
+                       {
+#ifdef __PALM_GESTURE_LOG__
+                               XDBG_DEBUG(MGEST, "[R] No flick !(flick touch major(%.f) width major(%.f) < %d) is small!)\n", pPalm->biggest_tmajor, pPalm->biggest_wmajor, PALM_FLICK_TOUCH_MAJOR);
+#endif
+                               goto flick_failed;
+                       }
+                       direction = (line_idx <= 1) ? FLICK_SOUTHWARD : FLICK_NORTHWARD;
+                       distance = ABS(disty - base_y);
+
+#ifdef __PALM_GESTURE_LOG__
+                       XDBG_DEBUG(MGEST, "[R] Palm Flick !!!, direction=%d, distance=%d\n", direction, distance);
+#endif
+
+                       if( GestureHasFingerEventMask(GestureNotifyFlick, 0) )
+                               GestureHandleGesture_Flick(0, distance, duration, direction);
+                       goto cleanup_flick;
+                       break;
+       }
+
+       return;
+
+flick_failed:
+       is_flicking = 0;
+       g_pGesture->recognized_palm &= ~PalmFlickVertiFilterMask;
+       g_pGesture->palm_filter_mask |= PalmFlickVertiFilterMask;
+#ifdef __PALM_GESTURE_LOG__
+       XDBG_DEBUG(MGEST, "[Fail] recognized_palm= 0x%x, palm_filter_mask= 0x%x\n", g_pGesture->recognized_palm, g_pGesture->palm_filter_mask);
+#endif
+       goto cleanup_flick;
+       return;
+
+cleanup_flick:
+       num_pressed = 0;
+       is_flicking = 1;
+       base_height_size = 0;
+       base_time = 0;
+       curTouched = 0;
+       pass_count = 0;
+       false_base_height_size = 0;
+       prev_line_idx = 0;
+       release_flag = 0;
+       base_cx = base_cy = 0;
+       base_box_ext.x1 = base_box_ext.x2 = base_box_ext.y1 = base_box_ext.y2 = 0;
+       memset(&verti_line, 0L, PALM_VERTI_ARRAY_COUNT * sizeof(int));
+#ifdef __PALM_GESTURE_LOG__
+       XDBG_DEBUG(MGEST, "[cleanup_flick] base_height_size=%d, curTouched=%d\n", base_height_size, curTouched);
+#endif
+
+       return;
+}
+
+
+static int
+GesturePalmGetScreenInfo()
+{
+       int i;
+       pixman_region16_t tarea;
+       PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
+       ScreenPtr pScreen = miPointerCurrentScreen();
+
+       if(!pScreen)
+       {
+#ifdef __PALM_DETAIL_LOG__
+               XDBG_DEBUG(MGEST, "Failed to get screen information !\n");
+#endif
+               pPalmMisc->scrn_width = pPalmMisc->scrn_height = 0;
+               return 0;
+       }
+
+       pPalmMisc->scrn_width = pScreen->width;
+       pPalmMisc->scrn_height = pScreen->height;
+       pixman_region_init(&tarea);
+       pixman_region_init_rect(&tarea, 0, 0, pPalmMisc->scrn_width, pPalmMisc->scrn_height);
+       pPalmMisc->half_scrn_area_size = AREA_SIZE(&tarea.extents);
+       pPalmMisc->half_scrn_area_size = (unsigned int)((double)pPalmMisc->half_scrn_area_size / 2.4f);
+#ifdef __HOLD_DETECTOR_DEBUG__
+       XDBG_DEBUG(MGEST, "pPalmMisc->half_scrn_area_size = %d\n", pPalmMisc->half_scrn_area_size);
+#endif//__HOLD_DETECTOR_DEBUG__
+
+       for(i = 0 ; i < PALM_HORIZ_ARRAY_COUNT ; i++)
+       {
+               pPalmMisc->horiz_coord[i] = pPalmMisc->scrn_width * ((i+1)/(double)PALM_HORIZ_ARRAY_COUNT);
+#ifdef __PALM_DETAIL_LOG__
+               XDBG_DEBUG(MGEST, "pPalmMisc->horiz_coord[%d]=%d, pPalmMisc->scrn_width=%d\n", i, pPalmMisc->horiz_coord[i], pPalmMisc->scrn_width);
+#endif
+       }
+       for(i = 0 ; i < PALM_VERTI_ARRAY_COUNT ; i++)
+       {
+               pPalmMisc->verti_coord[i] = pPalmMisc->scrn_height * ((i+1)/(double)PALM_VERTI_ARRAY_COUNT);
+#ifdef __PALM_DETAIL_LOG__
+               XDBG_DEBUG(MGEST, "pPalmMisc->verti_coord[%d]=%d, pPalmMisc->scrn_height=%d\n", i, pPalmMisc->verti_coord[i], pPalmMisc->scrn_height);
+#endif
+       }
+
+       return 1;
+}
+
+static int
+GesturePalmGetAbsAxisInfo(DeviceIntPtr dev)
+{
+       int i, found = 0;
+       int numAxes;
+       PalmStatusPtr pPalm;
+
+       Atom atom_wmajor;
+       Atom atom_tmajor;
+       Atom atom_tminor;
+       Atom atom_tangle;
+       Atom atom_tpalm;
+       Atom atom_mt_px;
+       Atom atom_mt_py;
+
+       Atom atom_px;
+       Atom atom_py;
+       Atom atom_mt_slot;
+       Atom atom_tracking_id;
+       Atom atom_distance;
+       Atom atom_mt_tool;
+
+       g_pGesture->wmajor_idx = -1;
+       g_pGesture->tmajor_idx = -1;
+       g_pGesture->tminor_idx = -1;
+       g_pGesture->tangle_idx = -1;
+       g_pGesture->tpalm_idx = -1;
+       g_pGesture->mt_px_idx = -1;
+       g_pGesture->mt_py_idx = -1;
+       g_pGesture->mt_tool_idx = -1;
+
+       memset(&g_pGesture->palm, 0, sizeof(PalmStatus));
+
+       if (!dev || !dev->valuator)
+               goto out;
+
+       numAxes = dev->valuator->numAxes;
+       atom_mt_px = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_POSITION_X);
+       atom_mt_py = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_POSITION_Y);
+       atom_wmajor = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_WIDTH_MAJOR);
+       atom_tmajor = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_TOUCH_MAJOR);
+       atom_tminor = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_TOUCH_MINOR);
+       atom_tangle = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_ANGLE);
+       atom_tpalm = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_PALM);
+
+       atom_px = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
+       atom_py = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y);
+       atom_mt_slot = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_SLOT);
+       atom_tracking_id = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_TRACKING_ID);
+       atom_distance = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_DISTANCE);
+       atom_mt_tool = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_TOOL_TYPE);
+
+       if (!numAxes || !atom_mt_px || !atom_mt_py || !atom_tmajor || !atom_tminor  || !atom_tangle || !atom_tpalm)
+       {
+               XDBG_WARNING(MGEST, "one or more axes is/are not supported!\n");
+               goto out;
+       }
+       if (!atom_mt_tool)
+       {
+               XDBG_WARNING(MGEST, "multitouch various type was not supported\n");
+       }
+
+       for( i = 0 ; i < numAxes ; i++ )
+       {
+               AxisInfoPtr axes = &dev->valuator->axes[i];
+
+               if (!axes || (axes->mode != Absolute))
+                       continue;
+
+               if ( axes->label == atom_mt_px )
+               {
+                       g_pGesture->mt_px_idx = i;
+                       found += 1;
+               }
+               else if ( axes->label == atom_mt_py )
+               {
+                       g_pGesture->mt_py_idx = i;
+                       found += 2;
+               }
+               else if ( axes->label == atom_wmajor )
+               {
+                       g_pGesture->wmajor_idx = i;
+                       found += 3;
+               }
+               else if ( axes->label == atom_tmajor )
+               {
+                       g_pGesture->tmajor_idx = i;
+                       found += 4;
+               }
+               else if ( axes->label == atom_tminor )
+               {
+                       g_pGesture->tminor_idx = i;
+                       found += 5;
+               }
+               else if ( axes->label == atom_tangle )
+               {
+                       g_pGesture->tangle_idx = i;
+                       found += 6;
+               }
+               else if ( axes->label == atom_tpalm )
+               {
+                       g_pGesture->tpalm_idx = i;
+                       found += 7;
+               }
+               else if ( atom_mt_tool && axes->label == atom_mt_tool )
+               {
+                       g_pGesture->mt_tool_idx = i;
+                       found += 8;
+               }
+       }
+
+       if (found != 36)
+       {
+               XDBG_WARNING(MGEST, "Various multitouch devices are not supported !\n");
+               if (found != 28)
+               {
+                       XDBG_WARNING(MGEST, "Axes for palm recognization are not supported !\n");
+                       goto out;
+               }
+       }
+
+       pPalm = &g_pGesture->palm;
+       pixman_region_init(&pPalm->area);
+
+       for( i = 0 ; i < MAX_MT_DEVICES ; i++ )
+       {
+               pixman_region_init_rect (&pPalm->finger_rects[i], 0, 0, FINGER_WIDTH_2T, FINGER_HEIGHT_2T);
+       }
+
+       g_pGesture->palm_misc.enabled = 1;
+       XDBG_INFO(MGEST, "Axes for palm recognization are supported !\n");
+       return 1;
+
+out:
+       g_pGesture->palm_misc.enabled = 0;
+       XDBG_INFO(MGEST, "Palm recognization is not supported !\n");
+       return 0;
+}
+
+static void
+GesturePalmDataUpdate(int idx, int type, InternalEvent *ev, DeviceIntPtr device)
+{
+       int wmajor_idx = g_pGesture->wmajor_idx;
+       int tmajor_idx = g_pGesture->tmajor_idx;
+       int tminor_idx = g_pGesture->tminor_idx;
+       int tangle_idx = g_pGesture->tangle_idx;
+       int tpalm_idx = g_pGesture->tpalm_idx;
+       int px_idx = g_pGesture->mt_px_idx;
+       int py_idx= g_pGesture->mt_py_idx;
+
+       double width_major = 0.0f;
+       double touch_major = 0.0f;
+       double touch_minor = 0.0f;
+       double touch_angle = 0.0f;
+       double touch_palm = 0.0f;
+       double max_width = -1.0f;
+
+       int i;
+       int count;
+       double meanX = 0.0f;
+       double meanY = 0.0f;
+       double tmpXp = 0.0f;
+       double tmpYp = 0.0f;
+
+       PalmStatusPtr pPalm = &g_pGesture->palm;
+       DeviceEvent *de = &ev->device_event;
+       pPalm->cx = 0;
+       pPalm->cy = 0;
+
+       if (!de)
+       {
+               XDBG_WARNING(MGEST, "de or de->valuators.data are NULL !\n");
+               return;
+       }
+
+       if ((wmajor_idx < 0) || (tmajor_idx < 0) || (tminor_idx < 0) || (tangle_idx < 0) || (tpalm_idx < 0) || (px_idx < 0) || (py_idx < 0))
+       {
+               XDBG_WARNING(MGEST, "One or more of axes are not supported !\n");
+               return;
+       }
+
+       width_major = de->valuators.data[wmajor_idx];
+       touch_major = de->valuators.data[tmajor_idx];
+       touch_minor = de->valuators.data[tminor_idx];
+       touch_angle = de->valuators.data[tangle_idx];
+       touch_palm = de->valuators.data[tpalm_idx];
+       if( !(g_pGesture->palm.palmflag) && pPalm->max_palm >= PALM_FLICK_MIN_PALM)
+       {
+               g_pGesture->palm.palmflag = 1;
+               g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
+       }
+
+#ifdef __PALM_DETAIL_LOG__
+       XDBG_DEBUG(MGEST, "[idx:%d, devid:%d, type:%d] width_major=%.f, touch_major=%.f, touch_minor=%.f, touch_palm=%.f \n", idx, de->deviceid, type, width_major, touch_major, touch_minor, touch_palm);
+       XDBG_DEBUG(MGEST, "[%d]: touch_status: %d, x: %d, y: %d  (cur_touched: %d);\n", idx, pPalm->pti[idx].touch_status, pPalm->pti[idx].x, pPalm->pti[idx].y, pPalm->cur_touched);
+#endif
+
+       switch(type)
+       {
+               case ET_ButtonPress:
+                       if (!pPalm->pti[idx].touch_status)
+                       {
+                               pPalm->cur_touched++;
+                               pPalm->pti[idx].touch_status = 1;
+                       }
+
+                       pPalm->pti[idx].x = de->root_x;
+                       pPalm->pti[idx].y = de->root_y;
+#ifdef __PALM_DETAIL_LOG__
+                       XDBG_DEBUG(MGEST, "[idx:%d(devid:%d)][PRESS] x=%d, y=%d, wmajor=%.f, tmajor=%.f, tminor=%.f, tangle=%.f, tpalm=%.f\n", idx, device->id, pPalm->pti[idx].x, pPalm->pti[idx].y, pPalm->pti[idx].wmajor, pPalm->pti[idx].tmajor, pPalm->pti[idx].tminor, pPalm->pti[idx].tangle, pPalm->pti[idx].tpalm);
+#endif
+                       break;
+
+               case ET_ButtonRelease:
+                       if (pPalm->pti[idx].touch_status)
+                       {
+                               --pPalm->cur_touched;
+                               if (pPalm->cur_touched < 0)
+                                       pPalm->cur_touched = 0;
+                       }
+
+                       pPalm->pti[idx].touch_status = 2;
+
+                       pPalm->pti[idx].x = de->root_x;
+                       pPalm->pti[idx].y = de->root_y;
+
+                       pPalm->pti[idx].tangle = 0.0f;
+                       pPalm->pti[idx].wmajor = 0.0f;
+                       pPalm->pti[idx].tmajor = 0.0f;
+                       pPalm->pti[idx].tminor = 0.0f;
+                       pPalm->pti[idx].tpalm = 0.0f;
+#ifdef __PALM_DETAIL_LOG__
+                       XDBG_DEBUG(MGEST, "[idx:%d(devid:%d)][RELEASE] x=%d, y=%d, wmajor=%.f, tmajor=%.f, tminor=%.f, tangle=%.f, tpalm=%.f\n", idx, device->id, pPalm->pti[idx].x, pPalm->pti[idx].y, pPalm->pti[idx].wmajor, pPalm->pti[idx].tmajor, pPalm->pti[idx].tminor, pPalm->pti[idx].tangle, pPalm->pti[idx].tpalm);
+#endif
+                       break;
+
+               case ET_Motion:
+                       pPalm->pti[idx].x = de->root_x;
+                       pPalm->pti[idx].y = de->root_y;
+
+                       pPalm->pti[idx].tmajor = touch_major;
+                       pPalm->pti[idx].tangle = touch_angle;
+                       pPalm->pti[idx].wmajor = width_major;
+                       pPalm->pti[idx].tminor = touch_minor;
+                       pPalm->pti[idx].tpalm = touch_palm;
+
+                       if (!pPalm->pti[idx].touch_status || (pPalm->pti[idx].tmajor == 0))
+                               return;
+#ifdef __PALM_DETAIL_LOG__
+                       XDBG_DEBUG(MGEST, "[idx:%d(devid:%d)][MOVE] x=%d, y=%d, wmajor=%.f, tmajor=%.f, tminor=%.f, tangle=%.f, tpalm=%.f\n", idx, device->id, pPalm->pti[idx].x, pPalm->pti[idx].y, pPalm->pti[idx].wmajor, pPalm->pti[idx].tmajor, pPalm->pti[idx].tminor, pPalm->pti[idx].tangle, pPalm->pti[idx].tpalm);
+#endif
+                       break;
+       }
+
+       pPalm->sum_size = 0.0f;
+       pPalm->max_wmajor = -1.0f;
+       pPalm->max_tmajor = -1.0f;
+       pPalm->max_tminor = -1.0f;
+       pPalm->max_size_idx = -1;
+       pPalm->max_palm = -1.0f;
+       max_width = -1.0f;
+
+       for( count = 0, i = 0 ; i < g_pGesture->num_mt_devices ; i++ )
+       {
+               if (!pPalm->pti[i].touch_status)
+                       continue;
+               if(pPalm->pti[i].touch_status == 2)
+                       pPalm->pti[i].touch_status =0;
+               count++;
+               meanX += pPalm->pti[i].x;
+               meanY += pPalm->pti[i].y;
+               pPalm->sum_size += pPalm->pti[i].wmajor;
+               if(max_width < pPalm->pti[i].wmajor)
+               {
+                       pPalm->max_size_idx = i;
+               }
+               if (pPalm->max_wmajor < pPalm->pti[i].wmajor)
+               {
+                       pPalm->max_wmajor = pPalm->pti[i].wmajor;
+               }
+               if(pPalm->max_tmajor < pPalm->pti[i].tmajor)
+                       pPalm->max_tmajor = pPalm->pti[i].tmajor;
+               if(pPalm->max_tminor < pPalm->pti[i].tminor)
+                       pPalm->max_tminor = pPalm->pti[i].tminor;
+               if(pPalm->max_palm < pPalm->pti[i].tpalm)
+               {
+                       pPalm->max_palm = (int)pPalm->pti[i].tpalm;
+#ifdef __PALM_DETAIL_LOG__
+                       XDBG_DEBUG(MGEST, "max_palm=%d pPalm->pti[%d].tpalm: %.f\n", pPalm->max_palm, i, pPalm->pti[i].tpalm);
+#endif
+               }
+       }
+
+       if (pPalm->max_size_idx < 0)
+       {
+#ifdef __PALM_DETAIL_LOG__
+               XDBG_DEBUG(MGEST, "Failed to get sum_size !\n");
+#endif
+               //meanX = 0;
+               //meanY = 0;
+               pPalm->dispersionX = 0.0f;
+               pPalm->deviationX = 0.0f;
+               pPalm->dispersionY= 0.0f;
+               pPalm->deviationY = 0.0f;
+               pPalm->max_eccen = 0.0f;
+               pPalm->max_angle = 0.0f;
+       }
+       else
+       {
+               meanX /= count;
+               meanY /= count;
+               pPalm->cx = meanX;
+               pPalm->cy = meanY;
+
+               for( i = 0 ; i < g_pGesture->num_mt_devices ; i++ )
+               {
+                       if (!pPalm->pti[i].touch_status)
+                               continue;
+
+                       tmpXp += (pPalm->pti[i].x - meanX)*(pPalm->pti[i].x - meanX);
+                       tmpYp += (pPalm->pti[i].y - meanY)*(pPalm->pti[i].y - meanY);
+               }
+
+               pPalm->dispersionX = tmpXp / count;
+               pPalm->deviationX = sqrt(pPalm->dispersionX);
+               pPalm->dispersionY = tmpYp / count;
+               pPalm->deviationY = sqrt(pPalm->dispersionY);
+#ifdef __PALM_DETAIL_LOG__
+               XDBG_DEBUG(MGEST, "meanX=%.f, meanY=%.f, count=%d, tmpXp=%.f, tmpYp=%.f\n", meanX, meanY, count, tmpXp, tmpYp);
+#endif
+
+               pPalm->max_eccen = pPalm->max_tmajor/ pPalm->max_tminor;
+               pPalm->max_angle = pPalm->pti[pPalm->max_size_idx].tangle;
+       }
+       if(pPalm->palmflag)
+       {
+               TimerCancel(pPalm->palm_single_finger_timer);
+               pPalm->single_timer_expired = 0;
+       }
+       if(pPalm->biggest_tmajor < pPalm->max_tmajor)
+               pPalm->biggest_tmajor = pPalm->max_tmajor;
+       if(pPalm->biggest_wmajor < pPalm->max_wmajor)
+               pPalm->biggest_wmajor = pPalm->max_wmajor;
+       if(pPalm->bigger_wmajor < pPalm->max_wmajor)
+               pPalm->bigger_wmajor = pPalm->max_wmajor;
+#ifdef __PALM_DETAIL_LOG__
+       XDBG_DEBUG(MGEST, "[maxidx:%d] cur_touched=%d, palmflag=%d, sum_size=%.f, max_wmajor=%.f, max_eccen=%.1f, max_angle=%.f\n",     pPalm->max_size_idx, pPalm->cur_touched, pPalm->palmflag, pPalm->sum_size, pPalm->max_wmajor, pPalm->max_eccen, pPalm->max_angle);
+       XDBG_DEBUG(MGEST, "sum_size=%.f, max_tmajor=%.f, dispersionX=%.f, deviationX=%.f, dispersionY=%.f, deviationY=%.f\n", pPalm->sum_size, pPalm->max_tmajor, pPalm->dispersionX, pPalm->deviationX, pPalm->dispersionY, pPalm->deviationY);
+       XDBG_DEBUG(MGEST, "max_palm=%d\n", pPalm->max_palm);
+#endif
+}
+
+static void
+GesturePalmUpdateAreaInfo(int type, int idx)
+{
+       int i;
+       PalmStatusPtr pPalm = &g_pGesture->palm;
+
+       switch(type)
+       {
+               case ET_ButtonPress:
+                       pPalm->finger_rects[idx].extents.x1 = pPalm->pti[idx].x - FINGER_WIDTH;
+                       pPalm->finger_rects[idx].extents.x2 = pPalm->pti[idx].x + FINGER_WIDTH;
+                       pPalm->finger_rects[idx].extents.y1 = pPalm->pti[idx].y - FINGER_HEIGHT;
+                       pPalm->finger_rects[idx].extents.y2 = pPalm->pti[idx].y + FINGER_HEIGHT;
+#ifdef __PALM_DETAIL_LOG__
+                       XDBG_DEBUG(MGEST, "[P] [%d]: x1: %d, x2: %d, y1: %d, y2: %d\n", idx, pPalm->finger_rects[idx].extents.x1, pPalm->finger_rects[idx].extents.x2, pPalm->finger_rects[idx].extents.y1, pPalm->finger_rects[idx].extents.y2);
+                       XDBG_DEBUG(MGEST, "[P] area [%d]: x1: %d, x2: %d, y1: %d, y2: %d\n", idx, pPalm->area.extents.x1, pPalm->area.extents.x2, pPalm->area.extents.y1, pPalm->area.extents.y2);
+#endif// __PALM_DETAIL_LOG__
+
+               if(pPalm->cur_touched == 1)
+                       {
+                               pixman_region_union(&pPalm->area, &pPalm->finger_rects[idx], &pPalm->finger_rects[idx]);
+#ifdef __PALM_DETAIL_LOG__
+                               XDBG_DEBUG(MGEST, "[P] cur:1 [%d]: x1: %d, x2: %d, y1: %d, y2: %d\n", idx, pPalm->area.extents.x1, pPalm->area.extents.x2, pPalm->area.extents.y1, pPalm->area.extents.y2);
+#endif//__PALM_DETAIL_LOG__
+                       }
+                       else
+                       {
+                               pixman_region_union(&pPalm->area, &pPalm->finger_rects[idx], &pPalm->finger_rects[idx]);
+                               for(i = 0 ; i < g_pGesture->num_mt_devices ; i++)
+                               {
+                                       if(!pPalm->pti[i].touch_status)
+                                               continue;
+
+                                       pixman_region_union(&pPalm->area, &pPalm->area, &pPalm->finger_rects[i]);
+#ifdef __PALM_DETAIL_LOG__
+                                       XDBG_DEBUG(MGEST, "[P] cur:else [%d]: x1: %d, x2: %d, y1: %d, y2: %d\n", i, pPalm->area.extents.x1, pPalm->area.extents.x2, pPalm->area.extents.y1, pPalm->area.extents.y2);
+#endif//__PALM_DETAIL_LOG__
+                               }
+                       }
+                       break;
+
+               case ET_ButtonRelease:
+                       break;
+
+               case ET_Motion:
+                       if (!pPalm->pti[idx].touch_status || (pPalm->pti[idx].tmajor == 0))
+                               return;
+                       pPalm->finger_rects[idx].extents.x1 = pPalm->pti[idx].x - FINGER_WIDTH;
+                       pPalm->finger_rects[idx].extents.x2 = pPalm->pti[idx].x + FINGER_WIDTH;
+                       pPalm->finger_rects[idx].extents.y1 = pPalm->pti[idx].y - FINGER_HEIGHT;
+                       pPalm->finger_rects[idx].extents.y2 = pPalm->pti[idx].y + FINGER_HEIGHT;
+#ifdef __PALM_DETAIL_LOG__
+                       XDBG_DEBUG(MGEST, "[M] [%d]: x1: %d, x2: %d, y1: %d, y2: %d\n", idx, pPalm->finger_rects[idx].extents.x1, pPalm->finger_rects[idx].extents.x2, pPalm->finger_rects[idx].extents.y1, pPalm->finger_rects[idx].extents.y2);
+                       XDBG_DEBUG(MGEST, "[M] area [%d]: x1: %d, x2: %d, y1: %d, y2: %d\n", idx, pPalm->area.extents.x1, pPalm->area.extents.x2, pPalm->area.extents.y1, pPalm->area.extents.y2);
+#endif//__PALM_DETAIL_LOG__
+                       if(pPalm->cur_touched == 1)
+               {
+                               pixman_region_union(&pPalm->area, &pPalm->finger_rects[idx], &pPalm->finger_rects[idx]);
+#ifdef __PALM_DETAIL_LOG__
+                               XDBG_DEBUG(MGEST, "[M] cur:1 [%d]: x1: %d, x2: %d, y1: %d, y2: %d\n", idx, pPalm->area.extents.x1, pPalm->area.extents.x2, pPalm->area.extents.y1, pPalm->area.extents.y2);
+#endif//__PALM_DETAIL_LOG__
+                       }
+                       else
+                       {
+                       pixman_region_union(&pPalm->area, &pPalm->finger_rects[idx], &pPalm->finger_rects[idx]);
+#ifdef __PALM_DETAIL_LOG__
+                       XDBG_DEBUG(MGEST, "[M] cur:else:first [%d]: x1: %d, x2: %d, y1: %d, y2: %d\n", idx, pPalm->area.extents.x1, pPalm->area.extents.x2, pPalm->area.extents.y1, pPalm->area.extents.y2);
+#endif//__PALM_DETAIL_LOG__
+
+                               for(i = 0 ; i < g_pGesture->num_mt_devices ; i++)
+                               {
+                                       if(!pPalm->pti[i].touch_status)
+                                               continue;
+                                       pixman_region_union(&pPalm->area, &pPalm->area, &pPalm->finger_rects[i]);
+#ifdef __PALM_DETAIL_LOG__
+                                       XDBG_DEBUG(MGEST, "[M] cur:else [%d]: x1: %d, x2: %d, y1: %d, y2: %d\n", i, pPalm->area.extents.x1, pPalm->area.extents.x2, pPalm->area.extents.y1, pPalm->area.extents.y2);
+#endif//__PALM_DETAIL_LOG__
+                               }
+                       }
+                       break;
+       }
+}
+
+void
+GesturePalmRecognize(int type, InternalEvent *ev, DeviceIntPtr device)
+{
+       int i;
+       int idx = -1;
+       PalmStatusPtr pPalm = &g_pGesture->palm;
+       static int calc_touched = 0;
+       static int event_sum_palm_first_finger = 0, event_sum_palm_second_finger=0;
+
+       if( device->id < g_pGesture->first_fingerid )
+               return;
+
+       idx = GestureGetFingerIndexFromDevice(device);
+       if( idx < 0 )
+               return;
+
+#ifdef __DETAIL_DEBUG__
+       XDBG_DEBUG(MGEST, "[g_pGesture->num_pressed=%d]\n", g_pGesture->num_pressed);
+#endif//__DETAIL_DEBUG__
+       if(!g_pGesture->pTempPalmWin)
+       {
+               g_pGesture->pTempPalmWin = GestureGetEventsWindow();
+               if(!g_pGesture->pTempPalmWin || g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL)
+               {
+#ifdef __PALM_DETAIL_LOG__
+                       XDBG_DEBUG(MGEST, "No events are grabbed/selected !\n");
+#endif//__PALM_DETAIL_LOG__
+                       g_pGesture->no_palm_events = TRUE;
+                       if (g_pGesture->palm_rejection_mode == 0)
+                       {
+                               g_pGesture->palm_filter_mask = GESTURE_PALM_FILTER_MASK_ALL;
+                               goto flush_or_drop;
+                       }
+                       else
+                       {
+                               g_pGesture->palm_filter_mask = 0;
+                       }
+               }
+       }
+       GesturePalmDataUpdate(idx, type, ev, device);
+       GesturePalmUpdateAreaInfo(type, idx);
+#ifdef __PALM_DETAIL_LOG__
+       XDBG_DEBUG(MGEST, "[idx: %d: %d](%d, %d)max_tmajor: %lf, palmflag: %d, max_wmajor: %lf\n", idx, type, pPalm->pti[idx].x, pPalm->pti[idx].y, pPalm->max_tmajor, pPalm->palmflag, pPalm->max_wmajor);
+       XDBG_DEBUG(MGEST, "bigger_wmajor: %lf, biggest_tmajor: %lf, biggest_wmajor: %lf\n", pPalm->bigger_wmajor, pPalm->biggest_tmajor, pPalm->biggest_wmajor);
+       XDBG_DEBUG(MGEST, "area: %d, deviationX: %lf, deviationY: %lf, dispersionX: %lf, dispersion: %lf\n", pPalm->area, pPalm->deviationX, pPalm->deviationY, pPalm->dispersionX, pPalm->dispersionY);
+#endif
+       switch(type)
+       {
+               case ET_ButtonPress:
+                       if( idx == 0 )
+                               event_sum_palm_first_finger = BTN_PRESSED;
+                       else if( idx == 1)
+                               event_sum_palm_second_finger = BTN_PRESSED;
+                       pPalm->max_touched++;
+
+                       if( g_pGesture->num_pressed == 1 )
+                       {
+                               pPalm->palm_single_finger_timer = TimerSet(pPalm->palm_single_finger_timer, 0, 50, GesturePalmSingleFingerTimerHandler, NULL);
+                       }
+                       else if(g_pGesture->num_pressed > 1)
+                       {
+                               TimerCancel(pPalm->palm_single_finger_timer);
+                       }
+                       break;
+               case ET_Motion:
+                       if(pPalm->cur_touched == 0 || pPalm->pti[idx].touch_status != 1)
+                       {
+                               return;
+                       }
+                       if((pPalm->cur_touched == 1 && idx == 0 && event_sum_palm_first_finger == BTN_PRESSED) ||
+                               (pPalm->cur_touched == 2 && idx == 1 && event_sum_palm_second_finger == BTN_PRESSED))
+                       {
+                               if(idx == 0)
+                               {
+                                       event_sum_palm_first_finger = BTN_MOVING;
+#ifdef __PALM_DETAIL_LOG__
+                                       XDBG_DEBUG(MGEST, "First move detected!\n");
+#endif//__PALM_DETAIL_LOG__
+                               }
+                               else // idx == 1
+                               {
+                                       event_sum_palm_second_finger = BTN_MOVING;
+#ifdef __PALM_DETAIL_LOG__
+                                       XDBG_DEBUG(MGEST, "Second finger First move detected!\n");
+#endif//__PALM_DETAIL_LOG__
+                               }
+                               if (pPalm->palmflag < 1 && pPalm->biggest_tmajor < g_pGesture->palm_min_touch_major && pPalm->biggest_wmajor < g_pGesture->palm_min_width_major)
+                               {
+#ifdef __PALM_DETAIL_LOG__
+                                       XDBG_DEBUG(MGEST, "No palm coming.\n");
+#endif//__PALM_DETAIL_LOG__
+                                       Bool exist;
+                                       exist = GestureIsPalmEventInMIEQ();
+#ifdef __PALM_DETAIL_LOG__
+                                       XDBG_DEBUG(MGEST, "palm event exist: %d\n", exist);
+#endif//__PALM_DETAIL_LOG__
+
+                                       if (exist)
+                                       {
+                                               pPalm->palmflag = 1;
+                                               g_pGesture->palm_detected = TRUE;
+                                       }
+                                       else
+                                       {
+                                               /*
+                                                * The following is the bezel condition for palm
+                                                * -- palm touch area can be smaller than that of non-bezel regions, so the threshold value is reduced.
+                                                */
+                                               if(!(g_pGesture->palm_filter_mask & PalmFlickHorizFilterMask) &&
+                                                       (pPalm->cx >= g_pGesture->screen_width - g_pGesture->palm_bezel || pPalm->cx < g_pGesture->palm_bezel) &&
+                                                       (pPalm->biggest_tmajor >= g_pGesture->palm_min_touch_major_bezel || pPalm->biggest_wmajor >= g_pGesture->palm_min_width_major_bezel))
+                                               {
+                                                       g_pGesture->palm_detected = TRUE;
+                                                       break;
+                                               }
+                                               if(!(g_pGesture->palm_filter_mask & PalmFlickVertiFilterMask) &&
+                                                       (pPalm->cy >= g_pGesture->screen_height - g_pGesture->palm_bezel || pPalm->cy < g_pGesture->palm_bezel) &&
+                                                       (pPalm->biggest_tmajor >= g_pGesture->palm_min_touch_major_bezel || pPalm->biggest_wmajor >= g_pGesture->palm_min_width_major_bezel))
+                                               {
+                                                       g_pGesture->palm_detected = TRUE;
+                                                       break;
+                                               }
+
+                                               if (g_pGesture->palm_rejection_mode == 1 && g_pGesture->no_palm_events == TRUE)
+                                                       g_pGesture->palm_filter_mask = GESTURE_PALM_FILTER_MASK_ALL;
+                                               g_pGesture->recognized_palm = 0;
+                                               if(!(g_pGesture->palm_filter_mask & PalmFlickHorizFilterMask))
+                                               {
+                                                       GesturePalmRecognize_FlickHorizen(type, -1);
+                                               }
+                                               if(!(g_pGesture->palm_filter_mask & PalmFlickVertiFilterMask))
+                                               {
+                                                       GesturePalmRecognize_FlickVertical(type, -1);
+                                               }
+                                               if (g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL)
+                                                       goto flush_or_drop;
+                                       }
+                               }
+                               else
+                               {
+                                       g_pGesture->palm_detected = TRUE;
+                               }
+                       }
+                       calc_touched++;
+                       if(calc_touched == pPalm->cur_touched)
+                       {
+                               calc_touched = 0;
+                       }
+                       break;
+               case ET_ButtonRelease:
+                       if( idx == 0 )
+                               event_sum_palm_first_finger = BTN_RELEASED;
+                       else if( idx == 1)
+                               event_sum_palm_second_finger = BTN_RELEASED;
+                       if(calc_touched)
+                       {
+                               calc_touched--;
+                       }
+                       break;
+       }
+       if( g_pGesture->palm_rejection_mode == 1 && g_pGesture->palm_detected == TRUE && g_pGesture->no_palm_events == TRUE)
+       {
+               g_pGesture->recognized_palm = 0;
+               g_pGesture->palm_filter_mask = GESTURE_PALM_FILTER_MASK_ALL;
+               goto flush_or_drop;
+       }
+
+       if( GestureHasFingerEventMask(GestureNotifyFlick, 0) )
+       {
+               if(!(g_pGesture->palm_filter_mask & PalmFlickHorizFilterMask))
+               {
+                       GesturePalmRecognize_FlickHorizen(type, idx);
+               }
+               if(!(g_pGesture->palm_filter_mask & PalmFlickVertiFilterMask))
+               {
+                       GesturePalmRecognize_FlickVertical(type, idx);
+               }
+       }
+
+       if(g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL)
+       {
+               pixman_region_init(&pPalm->area);
+
+               for( i = 0 ; i < MAX_MT_DEVICES ; i++ )
+               {
+                       pixman_region_init_rect (&pPalm->finger_rects[i], 0, 0, FINGER_WIDTH_2T, FINGER_HEIGHT_2T);
+               }
+               pPalm->palmflag = 0;
+       }
+
+       switch(type)
+       {
+               case ET_ButtonPress:
+                       break;
+
+               case ET_ButtonRelease:
+                       if(( g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL ) && ( pPalm->cur_touched == 0))
+                               goto flush_or_drop;
+                       break;
+
+               case ET_Motion:
+                       break;
+       }
+#ifdef __PALM_DETAIL_LOG__
+       XDBG_DEBUG(MGEST, "recognized_palm: 0x%x, palm_filter_mask: 0x%x, ehtype: %d\n", g_pGesture->recognized_palm, g_pGesture->palm_filter_mask, g_pGesture->ehtype);
+#endif//__PALM_DETAIL_LOG__
+       if( g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL )
+       {
+               if( !g_pGesture->recognized_palm )
+                       goto flush_or_drop;
+       }
+
+       if( g_pGesture->recognized_palm )
+       {
+               if( g_pGesture->ehtype == KEEP_EVENTS )
+                       GestureEventsDrop();
+               g_pGesture->ehtype = IGNORE_EVENTS;
+       }
+
+       return;
+
+flush_or_drop:
+       calc_touched = 0;
+#ifdef __PALM_DETAIL_LOG__
+               XDBG_DEBUG(MGEST, "GestureFlushOrDrop() !\n");
+#endif//__PALM_DETAIL_LOG__
+               if( ERROR_INVALPTR == GestureFlushOrDrop() )
+               {
+                       GestureControl(g_pGesture->this_device, DEVICE_OFF);
+               }
+
+}
+
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+void
+GestureBezelRecognize(int type, InternalEvent *ev, DeviceIntPtr device)
+{
+       static OsTimerPtr bezel_finger_timer = NULL;
+
+       BezelFlickStatusPtr pBezel = &g_pGesture->bezel;
+       int direction = 0;
+       int distance;
+       double angle;
+       static Time base_time = 0;
+       int idx = -1;
+       int i;
+       static int px=-1, py=-1;
+       static int mx=-1, my=-1;
+       static int rx=-1, ry=-1;
+       static int event_count=0;
+
+       if(g_pGesture->enqueue_fulled == 1)
+       {
+#ifdef __BEZEL_DEBUG__
+               XDBG_DEBUG(MGEST, "EQ Event is full.... palm recognize drop..\n");
+#endif//__BEZEL_DEBUG__
+               goto bezel_failed;
+       }
+
+       if( (PROPAGATE_EVENTS == g_pGesture->ehtype) || (device->id != g_pGesture->first_fingerid) )
+               return;
+
+       for( i = 0 ; i < g_pGesture->num_mt_devices ; i++ )
+       {
+               if( device->id == g_pGesture->mt_devices[i]->id )
+               {
+                       idx = i;
+                       break;
+               }
+       }
+#ifdef __BEZEL_DEBUG__
+       XDBG_DEBUG(MGEST, "[type: %d][g_pGesture->num_pressed=%d, x,y(%d, %d) ]\n", type, g_pGesture->num_pressed, ev->device_event.root_x, ev->device_event.root_x);
+       XDBG_DEBUG(MGEST, "[filter_mask: 0x%x, bezel_filter_mask: 0x%x, palm_filter_mask: 0x%x\n", g_pGesture->filter_mask, g_pGesture->bezel_filter_mask, g_pGesture->palm_filter_mask);
+#endif//__BEZEL_DEBUG__
+
+       if (idx < 0)
+               return;
+       if(g_pGesture->recognized_gesture || g_pGesture->recognized_palm)
+               goto bezel_failed;
+       if(g_pGesture->num_pressed > 1)
+       {
+#ifdef __BEZEL_DEBUG__
+               XDBG_DEBUG(MGEST, "Not single finger g_pGesture->num_pressed: %d\n", g_pGesture->num_pressed);
+#endif//__BEZEL_DEBUG__
+               goto bezel_failed;
+       }
+       if(pBezel->is_active == BEZEL_END)
+       {
+#ifdef __BEZEL_DEBUG__
+               XDBG_DEBUG(MGEST, "Bezel state is END pBezel->is_active: %d\n", pBezel->is_active);
+               XDBG_DEBUG(MGEST, "[filter_mask: 0x%x, bezel_filter_mask: 0x%x, palm_filter_mask: 0x%x\n", g_pGesture->filter_mask, g_pGesture->bezel_filter_mask, g_pGesture->palm_filter_mask);
+#endif//__BEZEL_DEBUG__
+               goto bezel_failed;
+       }
+
+       switch(type)
+       {
+               case ET_ButtonPress:
+                       base_time = GetTimeInMillis();
+                       px = ev->device_event.root_x;
+                       py = ev->device_event.root_y;
+#ifdef __BEZEL_DEBUG__
+                       XDBG_DEBUG(MGEST, "[P] pBezel->is_active: %d, g_pGesture->num_pressed: %d, idx: %d\n", pBezel->is_active, g_pGesture->num_pressed, idx);
+                       XDBG_DEBUG(MGEST, "[P] g_pGesture->fingers[%d].p: (%d, %d)\n", idx, px,py);
+#endif//__BEZEL_DEBUG__
+                       if( (pBezel->is_active == BEZEL_ON) && ((g_pGesture->num_pressed == 1) && (idx == 0)) )
+                       {
+                               if( ( px < pBezel->top_left.width) && ( py < pBezel->top_left.height) )
+                               {
+#ifdef __BEZEL_DEBUG__
+                                       XDBG_DEBUG(MGEST, "[P] top_left\n");
+#endif//__BEZEL_DEBUG__
+                                       pBezel->is_active = BEZEL_START;
+                                       pBezel->bezelStatus = BEZEL_TOP_LEFT;
+                               }
+                               else if( (px > (720 - pBezel->top_right.width)) && ( py < pBezel->top_right.height) )
+                               {
+#ifdef __BEZEL_DEBUG__
+                                       XDBG_DEBUG(MGEST, "[P] top_right\n");
+#endif//__BEZEL_DEBUG__
+                                       pBezel->is_active = BEZEL_START;
+                                       pBezel->bezelStatus = BEZEL_TOP_RIGHT;
+                               }
+                               else if( (px < pBezel->bottom_left.width) && ( py > (1280 - pBezel->bottom_left.height)) )
+                               {
+#ifdef __BEZEL_DEBUG__
+                                       XDBG_DEBUG(MGEST, "[P] bottom_left\n");
+#endif//__BEZEL_DEBUG__
+                                       pBezel->is_active = BEZEL_START;
+                                       pBezel->bezelStatus = BEZEL_BOTTOM_LEFT;
+                               }
+                               else if( (px > (720 - pBezel->bottom_right.width)) && ( py > (1280 - pBezel->bottom_right.height)) )
+                               {
+#ifdef __BEZEL_DEBUG__
+                                       XDBG_DEBUG(MGEST, "[P] bottom_right\n");
+#endif//__BEZEL_DEBUG__
+                                       pBezel->is_active = BEZEL_START;
+                                       pBezel->bezelStatus = BEZEL_BOTTOM_RIGHT;
+                               }
+                               else
+                               {
+#ifdef __BEZEL_DEBUG__
+                                       XDBG_DEBUG(MGEST, "[P] None\n");
+#endif//__BEZEL_DEBUG__
+                                       pBezel->bezelStatus = NO_BEZEL;
+                                       goto bezel_failed;
+                               }
+                       }
+                       if(pBezel->is_active == BEZEL_START)
+                       {
+                               bezel_finger_timer = TimerSet(bezel_finger_timer, 0, 500, GestureBezelSingleFingerTimerHandler, NULL);
+                       }
+                       else
+                       {
+                               TimerCancel(bezel_finger_timer);
+                       }
+                       break;
+               case ET_Motion:
+                       if(px <0 || py < 0)
+                               return;
+                       mx = ev->device_event.root_x;
+                       my = ev->device_event.root_y;
+                       event_count++;
+                       if( (g_pGesture->bezel.bezel_angle_moving_check) && (event_count >= 10))
+                       {
+                               angle = get_angle(px, py, mx, my);
+                               event_count = 0;
+                               if(!GestureBezelAngleRecognize(pBezel->bezelStatus, pBezel->flick_distance, angle))
+                               {
+#ifdef __BEZEL_DEBUG__
+                                       XDBG_DEBUG(MGEST, "[M] moving limit!\n");
+#endif//__BEZEL_DEBUG__
+                                       TimerCancel(bezel_finger_timer);
+                                       goto bezel_failed;
+                               }
+                       }
+                       break;
+               case ET_ButtonRelease:
+                       rx = ev->device_event.root_x;
+                       ry = ev->device_event.root_y;
+                       if( (g_pGesture->num_pressed == 0) && (g_pGesture->inc_num_pressed == 1) && (pBezel->is_active == BEZEL_START) )
+                       {
+                               angle = get_angle(px, py, rx, ry);
+                               distance = get_distance(px, py, rx, ry);
+                               Time duration = GetTimeInMillis() - base_time;
+#ifdef __BEZEL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[R] bezelStatus: %d, distance: %d, angle: %lf\n", pBezel->bezelStatus, distance, angle);
+#endif//__BEZEL_DEBUG__
+                               int res = GestureBezelAngleRecognize(pBezel->bezelStatus, distance, angle);
+                               if(res)
+                               {
+#ifdef __BEZEL_DEBUG__
+                                       XDBG_DEBUG(MGEST, "[R] Bezel Success\n");
+#endif//__BEZEL_DEBUG__
+                                       pBezel->is_active = BEZEL_DONE;
+                                       g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
+                                       g_pGesture->palm_filter_mask = GESTURE_PALM_FILTER_MASK_ALL;
+                                       TimerCancel(bezel_finger_timer);
+
+                                       if( (0.0 < angle) && (angle < RAD_90DEG))
+                                               direction = FLICK_NORTHEASTWARD;
+                                       else if(angle < RAD_180DEG)
+                                               direction = FLICK_NORTHWESTWARD;
+
+                                       if( GestureHasFingerEventMask(GestureNotifyFlick, 1) )
+                                               GestureHandleGesture_Flick(1, distance, duration, direction);
+                                       goto bezel_cleanup;
+                               }
+#ifdef __BEZEL_DEBUG__
+                               XDBG_DEBUG(MGEST, "[R] Bezel failed\n");
+#endif//__BEZEL_DEBUG__
+                               goto bezel_failed;
+                       }
+                       break;
+       }
+       return;
+bezel_failed:
+#ifdef __BEZEL_DEBUG__
+       XDBG_DEBUG(MGEST, "[F] Bezel failed\n");
+#endif//__BEZEL_DEBUG__
+       pBezel->is_active = BEZEL_END;
+       g_pGesture->bezel_filter_mask |= BezelFlickFilterMask;
+       goto bezel_cleanup;
+       return;
+bezel_cleanup:
+#ifdef __BEZEL_DEBUG__
+       XDBG_DEBUG(MGEST, "[F] Bezel cleanup\n");
+#endif//__BEZEL_DEBUG__
+       TimerCancel(bezel_finger_timer);
+       if( ERROR_INVALPTR == GestureFlushOrDrop() )
+       {
+               GestureControl(g_pGesture->this_device, DEVICE_OFF);
+       }
+       bezel_finger_timer = NULL;
+       base_time = 0;
+       px=py=mx=my=rx=ry=-1;
+       event_count = 0;
+}
+#endif
+
+static EventQueuePtr
+GestureGetMIEQ(void)
+{
+       if (*checkForInput[0] == *checkForInput[1])
+       {
+#ifdef __DETAIL_DEBUG__
+               XDBG_DEBUG(MGEST, "mieq is empty !\n");
+#endif//__DETAIL_DEBUG__
+               return NULL;
+       }
+
+       EventQueuePtr mieqEQPtr = NULL;
+       mieqEQPtr = mieqGetEventQueuePtr();
+
+       if (!mieqEQPtr)
+       {
+#ifdef __DETAIL_DEBUG__
+               XDBG_DEBUG(MGEST, "mieqEQPtr is NULL !\n");
+#endif//__DETAIL_DEBUG__
+
+               return NULL;
+       }
+
+       int num = mieqNumEnqueued(mieqEQPtr);
+#ifdef __DETAIL_DEBUG__
+       XDBG_DEBUG(MGEST, " num of event in mieq = %d\n", num);
+#endif//__DETAIL_DEBUG__
+       if (num <= 0)
+               return NULL;
+
+       return mieqEQPtr;
+}
+
+static Bool
+GestureIsEventInMIEQ(int finger_index, enum EventType type)
+{
+       EventQueuePtr mieqEQPtr = NULL;
+       mieqEQPtr = GestureGetMIEQ();
+       if (!mieqEQPtr)
+       {
+#ifdef __DETAIL_DEBUG__
+               XDBG_DEBUG(MGEST, "failed to get mieq\n");
+#endif//__DETAIL_DEBUG__
+               return FALSE;
+       }
+
+       int deviceid = GestureGetDeviceIdFromFingerIndex(finger_index);
+       if (deviceid < 0)
+       {
+               XDBG_ERROR(MGEST, "Failed to get deviceid from finger index !\n");
+               return FALSE;
+       }
+
+       EventRec *e = NULL;
+       static InternalEvent event;
+       HWEventQueueType head, tail;
+       head = mieqEQPtr->head;
+       tail = mieqEQPtr->tail;
+
+       while (head != tail)
+       {
+               e = &mieqEQPtr->events[head];
+               if (e)
+               {
+                       event = *e->events;
+
+                       if (e->pDev && (deviceid == e->pDev->id) && (event.any.type == type))
+                       {
+                               return TRUE;
+                       }
+               }
+
+               head = (head + 1) % mieqEQPtr->nevents;
+       }
+
+       return FALSE;
+}
+
+static Bool
+GestureIsPalmEventInMIEQ(void)
+{
+       EventQueuePtr mieqEQPtr = NULL;
+       mieqEQPtr = GestureGetMIEQ();
+       if (!mieqEQPtr)
+       {
+#ifdef __PALM_DETAIL_LOG__
+               XDBG_DEBUG(MGEST, "failed to get mieq\n");
+#endif//__PALM_DETAIL_LOG__
+               return FALSE;
+       }
+
+       EventRec *e = NULL;
+       static InternalEvent event;
+       HWEventQueueType head, tail;
+       head = mieqEQPtr->head;
+       tail = mieqEQPtr->tail;
+
+       while (head != tail)
+       {
+               e = &mieqEQPtr->events[head];
+               if (e)
+               {
+                       event = *e->events;
+
+                       if (GestureIsPalmEvent(&event))
+                       {
+                               return TRUE;
+                       }
+               }
+
+               head = (head + 1) % mieqEQPtr->nevents;
+       }
+
+       return FALSE;
+}
+
+static Bool
+GestureIsPalmEvent(InternalEvent *event)
+{
+       int wmajor_idx = g_pGesture->wmajor_idx;
+       int tmajor_idx = g_pGesture->tmajor_idx;
+       int tpalm_idx = g_pGesture->tpalm_idx;
+
+       double width_major = 0.0f;
+       double touch_major = 0.0f;
+       double touch_palm = 0.0f;
+
+       if (event->any.type != ET_ButtonPress && event->any.type != ET_Motion && event->any.type != ET_ButtonRelease)
+               return FALSE;
+
+       DeviceEvent *de = &event->device_event;
+
+       if (!de)
+       {
+               XDBG_WARNING(MGEST, "de or de->valuators.data are NULL !\n");
+               return FALSE;
+       }
+
+       if ((wmajor_idx < 0) || (tmajor_idx < 0) || (tpalm_idx < 0))
+       {
+               XDBG_WARNING(MGEST, "One or more of axes are not supported !\n");
+               return FALSE;
+       }
+
+       width_major = de->valuators.data[wmajor_idx];
+       touch_major = de->valuators.data[tmajor_idx];
+       touch_palm = de->valuators.data[tpalm_idx];
+#ifdef __PALM_DETAIL_LOG__
+       XDBG_DEBUG(MGEST, "width_major: %.f, touch_major: %.f, touch_palm: %.f\n", width_major, touch_major, touch_palm);
+#endif//__PALM_DETAIL_LOG__
+
+       if (touch_palm >= 1 || touch_major >= g_pGesture->palm_min_touch_major || width_major >= g_pGesture->palm_min_width_major)
+               return TRUE;
+       return FALSE;
+}
+
+static int
+GestureGetFingerIndexFromDevice(DeviceIntPtr device)
+{
+       int i;
+
+       for( i = 0 ; i < g_pGesture->num_mt_devices ; i++ )
+       {
+               if( device->id == g_pGesture->mt_devices[i]->id )
+               {
+                       return i;
+               }
+       }
+
+       return -1;
+}
+
+static int
+GestureGetDeviceIdFromFingerIndex(int finger_index)
+{
+       if (g_pGesture->num_mt_devices <= finger_index)
+               return -1;
+
+       return g_pGesture->mt_devices[finger_index]->id;
+}
+
+
+void
+GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device)
+{
+       int i;
+       static OsTimerPtr single_finger_timer = NULL;
+       int idx = -1;
+
+       if( PROPAGATE_EVENTS == g_pGesture->ehtype ||
+               device->id < g_pGesture->first_fingerid )
+               return;
+
+       idx = GestureGetFingerIndexFromDevice(device);
+
+       if( idx < 0 )
+               return;
+#ifdef __DETAIL_DEBUG__
+       XDBG_DEBUG(MGEST, "[type: %d][g_pGesture->num_pressed=%d, x,y(%d, %d) ]\n", type, g_pGesture->num_pressed, ev->device_event.root_x, ev->device_event.root_x);
+       XDBG_DEBUG(MGEST, "[inc_num_pressed: %d]\n", g_pGesture->inc_num_pressed);
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+       XDBG_DEBUG(MGEST, "[filter_mask: 0x%x, bezel_filter_mask: 0x%x, palm_filter_mask: 0x%x\n", g_pGesture->filter_mask, g_pGesture->bezel_filter_mask, g_pGesture->palm_filter_mask);
+       XDBG_DEBUG(MGEST, "[recognized_gesture: 0x%x, bezel_recognize_mask: 0x%x, recognized_palm: 0x%x\n", g_pGesture->recognized_gesture, g_pGesture->bezel_recognized_mask, g_pGesture->recognized_palm);
+#else
+       XDBG_DEBUG(MGEST, "[filter_mask: 0x%x, palm_filter_mask: 0x%x\n", g_pGesture->filter_mask, g_pGesture->palm_filter_mask);
+       XDBG_DEBUG(MGEST, "[recognized_gesture: 0x%x, recognized_palm: 0x%x\n", g_pGesture->recognized_gesture, g_pGesture->recognized_palm);
+#endif
+#endif//__DETAIL_DEBUG__
+
+
+       switch( type )
+       {
+               case ET_ButtonPress:
+                       if( idx == 0 )
+                               g_pGesture->event_sum[0] = BTN_PRESSED;
+                       g_pGesture->fingers[idx].ptime = ev->any.time;
+                       g_pGesture->fingers[idx].px = ev->device_event.root_x;
+                       g_pGesture->fingers[idx].py = ev->device_event.root_y;
+
+                       if( g_pGesture->num_pressed == 1 )
+                       {
+                               single_finger_timer = TimerSet(single_finger_timer, 0, g_pGesture->tap_repeated ? 80 : g_pGesture->singlefinger_threshold, GestureSingleFingerTimerHandler, NULL);
+                       }
+                       else
+                       {
+                               TimerCancel(single_finger_timer);
+                       }
+
+                       if( g_pGesture->num_pressed > g_pGesture->num_mt_devices )
+                               g_pGesture->num_pressed = g_pGesture->num_mt_devices;
+
+                       if( !g_pGesture->pTempWin || g_pGesture->num_pressed != g_pGesture->inc_num_pressed )
+                       {
+                               g_pGesture->pTempWin = GestureGetEventsWindow();
+
+                               if( NULL == g_pGesture->pTempWin || g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL)
+                               {
+#ifdef __DETAIL_DEBUG__
+                                       XDBG_DEBUG(MGEST, "[g_pGesture->num_pressed=%d] No events were selected !\n", g_pGesture->num_pressed);
+#endif//__DETAIL_DEBUG__
+                                       g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
+                                       goto flush_or_drop;
+                               }
+                       }
+
+                       g_pGesture->inc_num_pressed = g_pGesture->num_pressed;
+
+                       g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH;
+                       g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH;
+                       g_pGesture->finger_rects[idx].extents.y1 =  ev->device_event.root_y - FINGER_HEIGHT;
+                       g_pGesture->finger_rects[idx].extents.y2 =  ev->device_event.root_y + FINGER_HEIGHT;
+
+                       pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
+                       for( i = 1 ; i < g_pGesture->inc_num_pressed ; i++ )
+                       {
+                               pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]);
+                       }
+#ifdef __DETAIL_DEBUG__
+                       XDBG_DEBUG(MGEST, "[M][g_pGesture->inc_num_pressed=%d] AREA_SIZE(area)=%d\n", g_pGesture->inc_num_pressed, AREA_SIZE(&g_pGesture->area.extents));
+#endif//__DETAIL_DEBUG__
+
+                       break;
+
+               case ET_Motion:
+                       if( !g_pGesture->fingers[idx].ptime )
+                               return;
+
+                       g_pGesture->fingers[idx].mx = ev->device_event.root_x;
+                       g_pGesture->fingers[idx].my = ev->device_event.root_y;
+
+                       if( (g_pGesture->inc_num_pressed < 2) && (idx == 0))
+                       {
+                               g_pGesture->event_sum[0] += BTN_MOVING;
+#ifdef __DETAIL_DEBUG__
+                               XDBG_DEBUG(MGEST, "no seconds finger comming\n");
+#endif//__DETAIL_DEBUG__
+                               if(!g_pGesture->tap_repeated)
+                               {
+                                       if(g_pGesture->event_sum[0] >= 3)
+                                       {
+#ifdef __DETAIL_DEBUG__
+                                               XDBG_DEBUG(MGEST, "single finger!\n");
+#endif//__DETAIL_DEBUG__
+                                               Bool exist;
+                                               exist = GestureIsEventInMIEQ(1, ET_ButtonPress);
+#ifdef __DETAIL_DEBUG__
+                                               XDBG_DEBUG(MGEST, "two finger touch in queue, exist: %d\n", exist);
+#endif//__DETAIL_DEBUG__
+                                               if (exist)
+                                                       g_pGesture->event_sum[0] -= BTN_MOVING;
+                                               else
+                                               {
+                                                       g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
+                                                       goto flush_or_drop;
+                                               }
+                                       }
+                               }
+                               else
+                               {
+                                       if(ABS(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px) > FINGER_WIDTH
+                                       || ABS(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py) > FINGER_HEIGHT)
+                                       {
+#ifdef __DETAIL_DEBUG__
+                                               XDBG_DEBUG(MGEST, "tap repeat Moving Limit Exceeded.\n");
+#endif//__DETAIL_DEBUG__
+                                               g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
+                                               goto flush_or_drop;
+                                       }
+                                       else if(g_pGesture->event_sum[0] >= 15)
+                                       {
+#ifdef __DETAIL_DEBUG__
+                                               XDBG_DEBUG(MGEST, "tap repeat Moving Limit Exceeded.\n");
+#endif//__DETAIL_DEBUG__
+                                               Bool exist;
+                                               exist = GestureIsEventInMIEQ(1, ET_ButtonPress);
+#ifdef __DETAIL_DEBUG__
+                                               XDBG_DEBUG(MGEST, "two finger touch in queue, exist: %d\n", exist);
+#endif//__DETAIL_DEBUG__
+                                               if (exist)
+                                                       g_pGesture->event_sum[0] -= BTN_MOVING;
+                                               else
+                                               {
+                                                       g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
+                                                       goto flush_or_drop;
+                                               }
+                                       }
+                               }
+                       }
+
+                       g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH;
+                       g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH;
+                       g_pGesture->finger_rects[idx].extents.y1 =  ev->device_event.root_y - FINGER_HEIGHT;
+                       g_pGesture->finger_rects[idx].extents.y2 =  ev->device_event.root_y + FINGER_HEIGHT;
+
+                       pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
+                       for( i = 1 ; i < g_pGesture->inc_num_pressed ; i++ )
+                       {
+                               pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]);
+                       }
+#ifdef __DETAIL_DEBUG__
+                       XDBG_DEBUG(MGEST, "[M][g_pGesture->inc_num_pressed=%d] AREA_SIZE(area)=%d\n", g_pGesture->inc_num_pressed, AREA_SIZE(&g_pGesture->area.extents));
+#endif//__DETAIL_DEBUG__
+                       break;
+
+               case ET_ButtonRelease:
+                       g_pGesture->fingers[idx].rtime = ev->any.time;
+                       g_pGesture->fingers[idx].rx = ev->device_event.root_x;
+                       g_pGesture->fingers[idx].ry = ev->device_event.root_y;
+
+                       if( g_pGesture->num_pressed <= 0 )
+                       {
+#ifdef __DETAIL_DEBUG__
+       XDBG_DEBUG(MGEST, "All fingers were released !\n");
+#endif//__DETAIL_DEBUG__
+                               if( g_pGesture->inc_num_pressed == 1 )
+                                       goto flush_or_drop;
+                       }
+                       break;
+       }
+
+       if( g_pGesture->filter_mask != GESTURE_FILTER_MASK_ALL )
+       {
+               if( !(g_pGesture->filter_mask & FlickFilterMask) )
+               {
+                       GestureRecognize_GroupFlick(type, ev, device, idx);
+               }
+               if( !(g_pGesture->filter_mask & PanFilterMask) )
+               {
+                       GestureRecognize_GroupPan(type, ev, device, idx, 0);
+               }
+               if( !(g_pGesture->filter_mask & PinchRotationFilterMask) )
+               {
+                       GestureRecognize_GroupPinchRotation(type, ev, device, idx, 0);
+               }
+               if( !(g_pGesture->filter_mask & TapFilterMask) )
+               {
+                       GestureRecognize_GroupTap(type, ev, device, idx, 0);
+               }
+               if( !(g_pGesture->filter_mask & TapNHoldFilterMask) )
+               {
+                       GestureRecognize_GroupTapNHold(type, ev, device, idx, 0);
+               }
+               if( !(g_pGesture->filter_mask & HoldFilterMask) )
+               {
+                       GestureRecognize_GroupHold(type, ev, device, idx, 0);
+               }
+       }
+
+#ifdef __DETAIL_DEBUG__
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+       XDBG_DEBUG(MGEST, "[filter_mask: 0x%x, bezel_filter_mask: 0x%x, palm_filter_mask: 0x%x\n", g_pGesture->filter_mask, g_pGesture->bezel_filter_mask, g_pGesture->palm_filter_mask);
+       XDBG_DEBUG(MGEST, "[recognized_gesture: 0x%x, bezel_recognize_mask: 0x%x, recognized_palm: 0x%x\n", g_pGesture->recognized_gesture, g_pGesture->bezel_recognized_mask, g_pGesture->recognized_palm);
+#else
+       XDBG_DEBUG(MGEST, "[filter_mask: 0x%x, palm_filter_mask: 0x%x\n", g_pGesture->filter_mask, g_pGesture->palm_filter_mask);
+       XDBG_DEBUG(MGEST, "[recognized_gesture: 0x%x, recognized_palm: 0x%x\n", g_pGesture->recognized_gesture, g_pGesture->recognized_palm);
+#endif
+#endif//__DETAIL_DEBUG__
+
+       if( g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL )
+       {
+               if( !g_pGesture->recognized_gesture )
+                       goto flush_or_drop;
+               else if( !g_pGesture->num_pressed )
+                       goto flush_or_drop;
+       }
+
+       if( g_pGesture->recognized_gesture )
+       {
+               if( g_pGesture->ehtype == KEEP_EVENTS )
+                       GestureEventsDrop();
+               g_pGesture->ehtype = IGNORE_EVENTS;
+       }
+
+       return;
+
+flush_or_drop:
+       TimerCancel(single_finger_timer);
+#ifdef __DETAIL_DEBUG__
+       XDBG_DEBUG(MGEST, "GestureFlushOrDrop() !\n");
+#endif//__DETAIL_DEBUG__
+       if( ERROR_INVALPTR == GestureFlushOrDrop() )
+       {
+               GestureControl(g_pGesture->this_device, DEVICE_OFF);
+       }
+}
+
+
+ErrorStatus GestureFlushOrDrop(void)
+{
+       ErrorStatus err = ERROR_NONE;
+       PalmStatusPtr pPalm = &g_pGesture->palm;
+       int i;
+#ifdef __DETAIL_DEBUG__
+       XDBG_DEBUG(MGEST, "recognized_gesture: 0x%x, filter_mask: 0x%x\n", g_pGesture->recognized_gesture, g_pGesture->filter_mask);
+       XDBG_DEBUG(MGEST, "recognized_palm: 0x%x, palm_filter_mask: 0x%x\n", g_pGesture->recognized_palm, g_pGesture->palm_filter_mask);
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+       XDBG_DEBUG(MGEST, "bezel_recognized_mask: 0x%x, bezel_filter_mask: 0x%x\n", g_pGesture->bezel_recognized_mask, g_pGesture->bezel_filter_mask);
+#endif
+#endif//__DETAIL_DEBUG__
+
+       if(g_pGesture->recognized_gesture || g_pGesture->recognized_palm
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+                || g_pGesture->bezel_recognized_mask)
+#else
+               )
+#endif
+       {
+               g_pGesture->ehtype = IGNORE_EVENTS;
+               GestureEventsDrop();
+               if(g_pGesture->recognized_palm)
+                       err = GestureRegionsReinit();
+       //memset(pPalm->pti, 0, sizeof(pPalm->pti[MAX_MT_DEVICES]));
+               for(i=0; i<MAX_MT_DEVICES; i++)
+               {
+                       pPalm->pti[i].touch_status = 0;
+                       pPalm->pti[i].tangle = 0.0f;
+                       pPalm->pti[i].wmajor = 0.0f;
+                       pPalm->pti[i].tmajor = 0.0f;
+                       pPalm->pti[i].tminor = 0.0f;
+                       pPalm->pti[i].tpalm = 0.0f;
+               }
+               if( ERROR_NONE != err )
+                       return err;
+       }
+       else if((g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL) && (g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL)
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+               && (g_pGesture->bezel_filter_mask == BezelFlickFilterMask))
+#else
+               )
+#endif
+       {
+               g_pGesture->ehtype = PROPAGATE_EVENTS;
+               if (g_pGesture->palm_rejection_mode == 1 && g_pGesture->palm_detected == TRUE)
+               {
+                       GestureEventsDrop();
+               }
+               else
+               {
+                       err = GestureEventsFlush();
+                       if( ERROR_NONE != err )
+                               return err;
+               }
+               err = GestureRegionsReinit();
+               for(i=0; i<MAX_MT_DEVICES; i++)
+               {
+                       pPalm->pti[i].touch_status = 0;
+                       pPalm->pti[i].tangle = 0.0f;
+                       pPalm->pti[i].wmajor = 0.0f;
+                       pPalm->pti[i].tmajor = 0.0f;
+                       pPalm->pti[i].tminor = 0.0f;
+                       pPalm->pti[i].tpalm = 0.0f;
+               }
+               if( ERROR_NONE != err )
+                       return err;
+
+               g_pGesture->pTempWin = NULL;
+               g_pGesture->inc_num_pressed = 0;
+               g_pGesture->event_sum[0] = 0;
+       }
+
+       return ERROR_NONE;
+}
+
+void
+GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
+{
+       int i;
+       PalmStatusPtr pPalm = &g_pGesture->palm;
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+       BezelFlickStatusPtr pBezel = &g_pGesture->bezel;
+#endif
+#ifdef __DEBUG_EVENT_HANDLER__
+       XDBG_DEBUG(MGEST, "(%d:%d) time:%d cur:%d\n",
+                       ev->any_event.deviceid, ev->any_event.sync, (int)ev->any.time, (int)GetTimeInMillis());
+#endif//__DEBUG_EVENT_HANDLER__
+
+       if( MTOUCH_FRAME_SYNC_BEGIN == ev->any_event.sync )
+       {
+#ifdef __DEBUG_EVENT_HANDLER__
+               XDBG_DEBUG(MGEST, "SYNC_BEGIN\n");
+#endif//__DEBUG_EVENT_HANDLER
+               g_pGesture->mtsync_status = MTOUCH_FRAME_SYNC_BEGIN;
+
+               if(g_pGesture->is_active)
+               {
+                       g_pGesture->ehtype = KEEP_EVENTS;
+                       g_pGesture->filter_mask = 0;
+                       g_pGesture->recognized_gesture = 0;
+                       g_pGesture->num_pressed = 0;
+                       g_pGesture->palm_filter_mask = 0;
+                       g_pGesture->recognized_palm= 0;
+                       g_pGesture->hold_detector_activate = 1;
+                       g_pGesture->has_hold_grabmask = 0;
+                       pPalm->palmflag = 0;
+                       pPalm->single_timer_expired = 0;
+                       pPalm->biggest_tmajor = 0;
+                       pPalm->biggest_wmajor = 0;
+                       pPalm->bigger_wmajor = 0;
+                       g_pGesture->enqueue_fulled = 0;
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+                       pBezel->is_active = BEZEL_ON;
+                       g_pGesture->bezel_filter_mask = 0;
+                       g_pGesture->bezel_recognized_mask = 0;
+#endif
+                       for( i=0 ; i < g_pGesture->num_mt_devices ; i++ )
+                               g_pGesture->fingers[i].ptime = 0;
+               }
+               g_pGesture->stylusInfo.stylus_id = 0;
+               g_pGesture->stylusInfo.pen_detected = FALSE;
+               g_pGesture->no_palm_events = FALSE;
+               g_pGesture->stylusInfo.fake_events = FALSE;
+               g_pGesture->palm_detected = FALSE;
+               memset(&g_pGesture->last_touches, 0, sizeof(g_pGesture->last_touches));
+       }
+       else if( MTOUCH_FRAME_SYNC_END == ev->any_event.sync )
+       {
+#ifdef __DEBUG_EVENT_HANDLER__
+               XDBG_DEBUG(MGEST, "SYNC_END\n");
+#endif//__DEBUG_EVENT_HANDLER
+               g_pGesture->mtsync_status = MTOUCH_FRAME_SYNC_END;
+               g_pGesture->touch_cancel_status = FALSE;
+
+               if(g_pGesture->is_active)
+               {
+                       g_pGesture->ehtype = PROPAGATE_EVENTS;
+                       g_pGesture->palm_filter_mask = GESTURE_PALM_FILTER_MASK_ALL;
+                       pPalm->cur_touched = 0;
+                       pPalm->palmflag = 0;
+                       pPalm->max_palm = 0;
+                       g_pGesture->pTempPalmWin = NULL;
+                       if(pPalm->palm_single_finger_timer)
+                               TimerCancel(pPalm->palm_single_finger_timer);
+                       g_pGesture->pTempWin = NULL;
+                       g_pGesture->inc_num_pressed = g_pGesture->num_pressed = 0;
+                       g_pGesture->event_sum[0] = 0;
+                       pPalm->max_touched = 0;
+                       g_pGesture->hold_detected = FALSE;
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+                       pBezel->is_active = BEZEL_END;
+                       g_pGesture->bezel_filter_mask = BezelFlickFilterMask;
+#endif
+               }
+               for(i=0; i<MAX_MT_DEVICES; i++)
+               {
+                       g_pGesture->stylusInfo.t_status[i].status = BTN_RELEASED;
+               }
+       }
+}
+
+static int
+GestureGetMTToolValuator(InternalEvent *ev, DeviceIntPtr device)
+{
+       int mt_tool_idx = g_pGesture->mt_tool_idx;
+       double mt_tool = 0.0f;
+
+       DeviceEvent *de = &ev->device_event;
+
+       if (!de)
+       {
+               XDBG_WARNING(MGEST, "de or de->valuators.data are NULL !\n");
+               return -1;
+       }
+
+       if (0 > mt_tool_idx)
+       {
+               XDBG_WARNING(MGEST, "One or more of axes are not supported !\n");
+               return -1;
+       }
+
+       if (ev->any.type == ET_ButtonPress || ev->any.type == ET_ButtonRelease)
+       {
+               if (device->id == g_pGesture->master_pointer->id && g_pGesture->stylusInfo.stylus_id == g_pGesture->first_fingerid)
+                       de->valuators.data[mt_tool_idx] = 1;
+
+               if (g_pGesture->stylusInfo.stylus_id == device->id)
+                       de->valuators.data[mt_tool_idx] = 1;
+       }
+
+       mt_tool = de->valuators.data[mt_tool_idx];
+
+       return (int)mt_tool;
+}
+
+static void
+GestureRegisterTouchInfo(InternalEvent *ev, DeviceIntPtr device)
+{
+       int idx;
+
+       idx = GestureGetFingerIndexFromDevice(device);
+       if (idx < 0)
+       {
+               if (device->id != g_pGesture->master_pointer->id)
+                       XDBG_WARNING(MGEST, "Failed to get correct idx(%d) device->id: %d, master_pointer: %d\n", idx, device->id, g_pGesture->master_pointer->id);
+               return;
+       }
+       switch(ev->any.type)
+       {
+               case ET_ButtonPress:
+                       g_pGesture->stylusInfo.t_status[idx].status = BTN_PRESSED;
+                       break;
+               case ET_Motion:
+                       if (g_pGesture->stylusInfo.t_status[idx].status == BTN_PRESSED)
+                               g_pGesture->stylusInfo.t_status[idx].status = BTN_MOVING;
+                       break;
+               case ET_ButtonRelease:
+                       g_pGesture->stylusInfo.t_status[idx].status = BTN_RELEASED;
+                       break;
+               default:
+                       XDBG_WARNING(MGEST, "unhandled event type(%d)\n", ev->any.type);
+                       break;
+       }
+       g_pGesture->stylusInfo.t_status[idx].cx = ev->device_event.root_x;
+       g_pGesture->stylusInfo.t_status[idx].cy = ev->device_event.root_y;
+}
+
+static void
+GestureSetToolData(InternalEvent *ev, double val_tool)
+{
+       int mt_tool_idx = g_pGesture->mt_tool_idx;
+       double mt_tool = 0.0f;
+
+       DeviceEvent *de = &ev->device_event;
+
+       if (!de)
+       {
+               XDBG_WARNING(MGEST, "de or de->valuators.data are NULL !\n");
+               return;
+       }
+
+       if (0 > mt_tool_idx)
+       {
+               XDBG_WARNING(MGEST, "One or more of axes are not supported !\n");
+               return;
+       }
+       de->valuators.data[mt_tool_idx] = val_tool;
+}
+
+static void
+GestureCleanupTouch(int screen_num, InternalEvent *ev, DeviceIntPtr device)
+{
+       ErrorStatus err;
+       int i;
+       if (g_pGesture->stylusInfo.stylus_id == 0 && g_pGesture->stylusInfo.pen_detected == FALSE)
+               g_pGesture->stylusInfo.stylus_id = device->id;
+
+       if (g_pGesture->ehtype == KEEP_EVENTS)
+       {
+               GestureEventsDrop();
+               g_pGesture->ehtype = PROPAGATE_EVENTS;
+       }
+       else if (g_pGesture->stylusInfo.pen_detected == FALSE && g_pGesture->ehtype == PROPAGATE_EVENTS)
+       {
+               g_pGesture->stylusInfo.pen_detected = TRUE;
+               g_pGesture->stylusInfo.fake_events = TRUE;
+               for(i=0; i<MAX_MT_DEVICES; i++)
+               {
+                       if (g_pGesture->stylusInfo.t_status[i].status == BTN_PRESSED || g_pGesture->stylusInfo.t_status[i].status == BTN_MOVING)
+                       {
+                               InternalEvent release_ev;
+                               memcpy(&release_ev, ev, sizeof(InternalEvent));
+                               release_ev.any.time = ev->any.time;
+                               release_ev.any.type = ET_ButtonRelease;
+
+                               release_ev.device_event.detail.button = 1;
+                               release_ev.device_event.type = ET_ButtonRelease;
+                               release_ev.device_event.root_x = g_pGesture->stylusInfo.t_status[i].cx;
+                               release_ev.device_event.root_y = g_pGesture->stylusInfo.t_status[i].cy;
+                               release_ev.device_event.deviceid = g_pGesture->mt_devices[i]->id;
+                               g_pGesture->stylusInfo.t_status[i].status = BTN_RELEASED;
+                               GestureSetToolData(&release_ev, (double)0);
+
+                               GestureHandleButtonReleaseEvent(screen_num, &release_ev, g_pGesture->mt_devices[i]);
+                               if (g_pGesture->mt_devices[i]->id == g_pGesture->first_fingerid)
+                               {
+                                       InternalEvent release_mev;
+                                       memcpy(&release_mev, ev, sizeof(InternalEvent));
+                                       release_mev.any.time = ev->any.time;
+                                       release_mev.any.type = ET_ButtonRelease;
+
+                                       release_mev.device_event.detail.button = 1;
+                                       release_mev.device_event.type = ET_ButtonRelease;
+                                       release_mev.device_event.root_x = g_pGesture->stylusInfo.t_status[i].cx;
+                                       release_mev.device_event.root_y = g_pGesture->stylusInfo.t_status[i].cy;
+                                       release_mev.device_event.deviceid = g_pGesture->master_pointer->id;
+                                       GestureSetToolData(&release_mev, (double)0);
+
+                                       GestureHandleButtonReleaseEvent(screen_num, &release_mev, g_pGesture->master_pointer);
+                               }
+                       }
+               }
+               g_pGesture->stylusInfo.fake_events = FALSE;
+       }
+       g_pGesture->stylusInfo.pen_detected = TRUE;
+       g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
+       g_pGesture->recognized_gesture = 0;
+       g_pGesture->palm_filter_mask = GESTURE_PALM_FILTER_MASK_ALL;
+       g_pGesture->recognized_palm = 0;
+}
+
+static void
+GestureChangeEventToFirstFingerEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
+{
+       InternalEvent master_ev;
+       ev->device_event.deviceid = g_pGesture->first_fingerid;
+
+       switch(ev->any.type)
+       {
+               case ET_ButtonPress:
+                       if(!(device->id < g_pGesture->first_fingerid))
+                               g_pGesture->num_pressed++;
+                       break;
+               case ET_ButtonRelease:
+                       if(!(device->id < g_pGesture->first_fingerid))
+                               g_pGesture->num_pressed--;
+                       break;
+               default:
+                       break;
+       }
+       memcpy(&master_ev, ev, sizeof(InternalEvent));
+       g_pGesture->mt_devices[0]->public.processInputProc(ev, g_pGesture->mt_devices[0]);
+
+       master_ev.device_event.deviceid = g_pGesture->master_pointer->id;
+       g_pGesture->master_pointer->public.processInputProc(&master_ev, g_pGesture->master_pointer);
+}
+
+void
+GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
+{
+#ifdef __DEBUG_EVENT_HANDLER__
+       XDBG_DEBUG(MGEST, "mode: %d devid=%d time:%d cur: %d (%d, %d)\n",
+               g_pGesture->ehtype, device->id, ev->any.time, GetTimeInMillis(), ev->device_event.root_x, ev->device_event.root_y);
+#endif//__DEBUG_EVENT_HANDLER__
+       int idx=0;
+       if (g_pGesture->touch_cancel_status == TRUE)
+       {
+               XDBG_DEBUG(MGEST, "Ignore Button Press event after touch cancel generated. \n");
+               return;
+       }
+       idx = GestureGetFingerIndexFromDevice(device);
+       if (0 <= idx)
+       {
+               g_pGesture->last_touches[idx].status = BTN_PRESSED;
+               g_pGesture->last_touches[idx].cx = ev->device_event.root_x;
+               g_pGesture->last_touches[idx].cy = ev->device_event.root_y;
+       }
+
+       if (g_pGesture->stylus_able)
+       {
+               int isStylus = GestureGetMTToolValuator(ev, device);
+
+#ifdef __DEBUG_EVENT_HANDLER__
+                       XDBG_DEBUG(MGEST, "isSytlus: %d, pen_detected: %d, stylus_id: %d\n", isStylus, g_pGesture->stylusInfo.pen_detected, g_pGesture->stylusInfo.stylus_id);
+#endif//__DEBUG_EVENT_HANDLER__
+
+               if (g_pGesture->stylusInfo.pen_detected == FALSE)
+               {
+                       if (!isStylus)
+                       {
+                               GestureRegisterTouchInfo(ev, device);
+                       }
+                       else
+                       {
+                               GestureCleanupTouch(screen_num, ev, device);
+                       }
+               }
+               if (g_pGesture->stylusInfo.pen_detected == TRUE)
+               {
+                       if (!isStylus || (device->id != g_pGesture->stylusInfo.stylus_id ))
+                       {
+                               if (!(g_pGesture->stylusInfo.stylus_id == g_pGesture->first_fingerid && device->id == g_pGesture->master_pointer->id))
+                               {
+                                       return;
+                               }
+                       }
+                       else if (device->id != g_pGesture->first_fingerid)
+                       {
+                               GestureChangeEventToFirstFingerEvent(screen_num, ev, device);
+                               return;
+                       }
+               }
+       }
+
+       switch( g_pGesture->ehtype )
+       {
+               case KEEP_EVENTS:
+                       if( ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev,  device) )
+                       {
+                               GestureControl(g_pGesture->this_device, DEVICE_OFF);
+                               return;
+                       }
+                       if( g_pGesture->num_mt_devices )
+                       {
+                               if(!(device->id < g_pGesture->first_fingerid))
+                                       g_pGesture->num_pressed++;
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+                               if(!(g_pGesture->bezel_filter_mask == BezelFlickFilterMask))
+                                       GestureBezelRecognize(ET_ButtonPress, ev, device);
+#endif
+                               if(!(g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL))
+                                       GestureRecognize(ET_ButtonPress, ev, device);
+                               if(!(g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL))
+                               {
+                                       if (PalmRecognize)
+                                               _GESTUREPALMRECOGNIZE_(PalmRecognize, ET_ButtonPress, ev, device)
+                                       else
+                                               g_pGesture->ehtype = PROPAGATE_EVENTS;
+                               }
+                       }
+                       else
+                               device->public.processInputProc(ev, device);
+                       GestureHoldDetector(ET_ButtonPress, ev, device);
+                       break;
+
+               case PROPAGATE_EVENTS:
+                       if(!(device->id < g_pGesture->first_fingerid))
+                               g_pGesture->num_pressed++;
+                       if (g_pGesture->palm_rejection_mode == 1 && g_pGesture->stylusInfo.pen_detected == TRUE)
+                       {
+                               device->public.processInputProc(ev, device);
+                       }
+                       else if (!(g_pGesture->palm_rejection_mode == 1 && g_pGesture->palm_detected == TRUE))
+                       {
+                               device->public.processInputProc(ev, device);
+                       }
+                       GestureHoldDetector(ET_ButtonPress, ev, device);
+                       break;
+
+               case IGNORE_EVENTS:
+                       if(!(device->id < g_pGesture->first_fingerid))
+                               g_pGesture->num_pressed++;
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+                       if(!(g_pGesture->bezel_filter_mask == BezelFlickFilterMask))
+                               GestureBezelRecognize(ET_ButtonPress, ev, device);
+#endif
+                       if(!(g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL))
+                               GestureRecognize(ET_ButtonPress, ev, device);
+                       if(!(g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL))
+                       {
+                               if (PalmRecognize)
+                                       _GESTUREPALMRECOGNIZE_(PalmRecognize, ET_ButtonPress, ev, device);
+                       }
+                       break;
+
+               default:
+                       break;
+       }
+}
+
+void
+GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
+{
+#ifdef __DEBUG_EVENT_HANDLER__
+       XDBG_DEBUG(MGEST, "mode: %d devid=%d time:%d cur: %d (%d, %d)\n",
+               g_pGesture->ehtype, device->id, ev->any.time, GetTimeInMillis(), ev->device_event.root_x, ev->device_event.root_y);
+#endif//__DEBUG_EVENT_HANDLER__
+       int idx=0;
+       if (g_pGesture->touch_cancel_status == TRUE)
+       {
+               XDBG_DEBUG(MGEST, "Ignore Button Press event after touch cancel generated. \n");
+               return;
+       }
+       idx = GestureGetFingerIndexFromDevice(device);
+       if (0 <= idx)
+       {
+               g_pGesture->last_touches[idx].status = BTN_MOVING;
+               g_pGesture->last_touches[idx].cx = ev->device_event.root_x;
+               g_pGesture->last_touches[idx].cy = ev->device_event.root_y;
+       }
+
+       if (g_pGesture->stylus_able)
+       {
+               int isStylus = GestureGetMTToolValuator(ev, device);
+
+#ifdef __DEBUG_EVENT_HANDLER__
+                       XDBG_DEBUG(MGEST, "isSytlus: %d, pen_detected: %d, stylus_id: %d\n", isStylus, g_pGesture->stylusInfo.pen_detected, g_pGesture->stylusInfo.stylus_id);
+#endif//__DEBUG_EVENT_HANDLER__
+
+               if (g_pGesture->stylusInfo.pen_detected == FALSE)
+               {
+                       if (!isStylus)
+                       {
+                               GestureRegisterTouchInfo(ev, device);
+                       }
+                       else
+                       {
+                               GestureCleanupTouch(screen_num, ev, device);
+                       }
+               }
+               if (g_pGesture->stylusInfo.pen_detected == TRUE)
+               {
+                       if (!isStylus || (device->id != g_pGesture->stylusInfo.stylus_id ))
+                       {
+                               if (!(g_pGesture->stylusInfo.stylus_id == g_pGesture->first_fingerid && device->id == g_pGesture->master_pointer->id))
+                               {
+                                       return;
+                               }
+                       }
+                       else if (device->id != g_pGesture->first_fingerid)
+                       {
+                               GestureChangeEventToFirstFingerEvent(screen_num, ev, device);
+                               return;
+                       }
+               }
+       }
+
+       switch( g_pGesture->ehtype )
+       {
+               case KEEP_EVENTS:
+                       if( ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev,  device) )
+                       {
+                               GestureControl(g_pGesture->this_device, DEVICE_OFF);
+                               return;
+                       }
+                       if( g_pGesture->num_mt_devices )
+                       {
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+                               if(!(g_pGesture->bezel_filter_mask == BezelFlickFilterMask))
+                                       GestureBezelRecognize(ET_Motion, ev, device);
+#endif
+                               if(!(g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL))
+                                       GestureRecognize(ET_Motion, ev, device);
+                               if(!(g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL))
+                               {
+                                       if (PalmRecognize)
+                                               _GESTUREPALMRECOGNIZE_(PalmRecognize, ET_Motion, ev, device)
+                                       else
+                                               g_pGesture->ehtype = PROPAGATE_EVENTS;
+                               }
+                       }
+                       else
+                               device->public.processInputProc(ev, device);
+                       GestureHoldDetector(ET_Motion, ev, device);
+                       break;
+
+               case PROPAGATE_EVENTS:
+                       if (g_pGesture->palm_rejection_mode == 1 && g_pGesture->stylusInfo.pen_detected == TRUE)
+                       {
+                               device->public.processInputProc(ev, device);
+                       }
+                       else if (!(g_pGesture->palm_rejection_mode == 1 && g_pGesture->palm_detected == TRUE))
+                       {
+                               device->public.processInputProc(ev, device);
+                       }
+                       GestureHoldDetector(ET_Motion, ev, device);
+                       break;
+
+               case IGNORE_EVENTS:
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+                       if(!(g_pGesture->bezel_filter_mask == BezelFlickFilterMask))
+                               GestureBezelRecognize(ET_Motion, ev, device);
+#endif
+                       if(!(g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL))
+                               GestureRecognize(ET_Motion, ev, device);
+                       if(!(g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL))
+                       {
+                               if (PalmRecognize)
+                                       _GESTUREPALMRECOGNIZE_(PalmRecognize, ET_Motion, ev, device);
+                       }
+                       break;
+
+               default:
+                       break;
+       }
+
+}
+
+void
+GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
+{
+#ifdef __DEBUG_EVENT_HANDLER__
+       XDBG_DEBUG(MGEST, "mode: %d devid=%d time:%d cur: %d (%d, %d)\n",
+               g_pGesture->ehtype, device->id, ev->any.time, GetTimeInMillis(), ev->device_event.root_x, ev->device_event.root_y);
+#endif//__DEBUG_EVENT_HANDLER__
+       int idx=0;
+       if (g_pGesture->touch_cancel_status == TRUE)
+       {
+               XDBG_DEBUG(MGEST, "Ignore Button Press event after touch cancel generated. \n");
+               return;
+       }
+       idx = GestureGetFingerIndexFromDevice(device);
+       if (0 <= idx)
+       {
+               g_pGesture->last_touches[idx].status = BTN_RELEASED;
+               g_pGesture->last_touches[idx].cx = ev->device_event.root_x;
+               g_pGesture->last_touches[idx].cy = ev->device_event.root_y;
+       }
+
+       if (g_pGesture->stylus_able)
+       {
+               int isStylus = GestureGetMTToolValuator(ev, device);
+
+#ifdef __DEBUG_EVENT_HANDLER__
+       XDBG_DEBUG(MGEST, "isSytlus: %d, pen_detected: %d, stylus_id: %d\n", isStylus, g_pGesture->stylusInfo.pen_detected, g_pGesture->stylusInfo.stylus_id);
+#endif//__DEBUG_EVENT_HANDLER__
+
+               if (g_pGesture->stylusInfo.pen_detected == FALSE)
+               {
+                       if (!isStylus)
+                       {
+                               GestureRegisterTouchInfo(ev, device);
+                       }
+                       else
+                       {
+                               GestureCleanupTouch(screen_num, ev, device);
+                       }
+               }
+               if (g_pGesture->stylusInfo.pen_detected == TRUE)
+               {
+                       if (g_pGesture->stylusInfo.fake_events == TRUE)
+                       {
+                               goto deliver_event;
+                       }
+                       if (!isStylus || (device->id != g_pGesture->stylusInfo.stylus_id ))
+                       {
+                               if (!(g_pGesture->stylusInfo.stylus_id == g_pGesture->first_fingerid && device->id == g_pGesture->master_pointer->id))
+                               {
+                                       return;
+                               }
+                       }
+                       else if (device->id != g_pGesture->first_fingerid)
+                       {
+                               GestureChangeEventToFirstFingerEvent(screen_num, ev, device);
+                               return;
+                       }
+               }
+       }
+deliver_event:
+       switch( g_pGesture->ehtype )
+       {
+               case KEEP_EVENTS:
+                       if( ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev,  device) )
+                       {
+                               GestureControl(g_pGesture->this_device, DEVICE_OFF);
+                               return;
+                       }
+                       if( g_pGesture->num_mt_devices )
+                       {
+                               if(!(device->id < g_pGesture->first_fingerid))
+                                       g_pGesture->num_pressed--;
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+                               if(!(g_pGesture->bezel_filter_mask == BezelFlickFilterMask))
+                                       GestureBezelRecognize(ET_ButtonRelease, ev, device);
+#endif
+                               if(!(g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL))
+                                       GestureRecognize(ET_ButtonRelease, ev, device);
+                               if(!(g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL))
+                               {
+                                       if (PalmRecognize)
+                                               _GESTUREPALMRECOGNIZE_(PalmRecognize, ET_ButtonRelease, ev, device)
+                                       else
+                                               g_pGesture->num_mt_devices = PROPAGATE_EVENTS;
+                               }
+                       }
+                       else
+                               device->public.processInputProc(ev, device);
+                       GestureHoldDetector(ET_ButtonRelease, ev, device);
+                       break;
+
+               case PROPAGATE_EVENTS:
+#ifdef SUPPORT_ANR_WITH_INPUT_EVENT
+                     if( IsMaster(device) && ev->any.type == ET_ButtonRelease )
+                     {
+                         if( g_pGesture->anr_window == NULL )
+                         {
+                             g_pGesture->anr_window = _GestureFindANRWindow(device);
+                         }
+                         Time current_time;
+
+                         // Send event to the e17 process.
+                         current_time = GetTimeInMillis();
+                         if( g_pGesture->anr_window != NULL )
+                         {
+                             // Check anr_window validation.
+                             if( dixLookupWindow(&g_pGesture->anr_window, prop_anr_event_window_xid, serverClient, DixSetPropAccess) != BadWindow )
+                             {
+                                 if( serverClient->devPrivates != NULL )
+                                     dixChangeWindowProperty (serverClient, g_pGesture->anr_window, prop_anr_in_input_event,
+                                                                               XA_CARDINAL, 32, PropModeReplace, 1, &current_time, TRUE);
+                             }
+                             else
+                             {
+                                 prop_anr_event_window_xid = 0;
+                                 g_pGesture->anr_window = NULL;
+                             }
+                             XDBG_DEBUG(MGEST, "Release TOUCH!!   devid=%d time:%d cur: %d\n", device->id, ev->any.time, GetTimeInMillis());
+                         }
+                     }
+#endif
+                       if(!(device->id < g_pGesture->first_fingerid))
+                               g_pGesture->num_pressed--;
+                       if (g_pGesture->palm_rejection_mode == 1 && g_pGesture->stylusInfo.pen_detected == TRUE)
+                       {
+                               device->public.processInputProc(ev, device);
+                       }
+                       else if (!(g_pGesture->palm_rejection_mode == 1 && g_pGesture->palm_detected == TRUE))
+                       {
+                               device->public.processInputProc(ev, device);
+                       }
+                       GestureHoldDetector(ET_ButtonRelease, ev, device);
+                       break;
+
+               case IGNORE_EVENTS:
+                       if(!(device->id < g_pGesture->first_fingerid))
+                               g_pGesture->num_pressed--;
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+                       if(!(g_pGesture->bezel_filter_mask == BezelFlickFilterMask))
+                               GestureBezelRecognize(ET_ButtonRelease, ev, device);
+#endif
+                       if(!(g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL))
+                               GestureRecognize(ET_ButtonRelease, ev, device);
+                       if(!(g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL))
+                       {
+                               if (PalmRecognize)
+                                       _GESTUREPALMRECOGNIZE_(PalmRecognize, ET_ButtonRelease, ev, device);
+                       }
+                       break;
+
+               default:
+                       break;
+       }
+}
+
+void
+GestureHandleKeyPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
+{
+#ifdef __DEBUG_EVENT_HANDLER__
+       XDBG_DEBUG(MGEST, "devid=%d time:%d cur:%d\n", device->id, ev->any.time, GetTimeInMillis());
+#endif//__DEBUG_EVENT_HANDLER__
+       static int find_dev_false_count = 0;
+
+       if(DPMSPowerLevel == DPMSModeOff)
+       {
+               XDBG_INFO(MGEST, "LCD status : Off\n");
+
+               {
+                       int i;
+                       for(i = 0 ; i < NUM_PASSKEYS ; i++)
+                       {
+                               if(0 == g_pGesture->pass_keycodes[i])
+                                       break;
+
+                               if(g_pGesture->pass_keycodes[i] == ev->device_event.detail.key)
+                               {
+                                       XDBG_SECURE(MGEST, "Pass KeyPress (devid:%d, keycode:%d) during LCD Off!\n", device->id, ev->device_event.detail.key);
+                                       goto handle_keypress;
+                               }
+                       }
+
+                       XDBG_SECURE(MGEST, "Ignore KeyPress (devid:%d, keycode:%d) during LCD Off!\n", device->id, ev->device_event.detail.key);
+                       return;
+               }
+       }
+
+handle_keypress:
+       if (g_pGesture->touchkey_id <= 0 && find_dev_false_count < 10)
+       {
+               DeviceIntPtr dev;
+               find_dev_false_count++;
+
+               for( dev = inputInfo.keyboard ; dev; dev = dev->next )
+               {
+                       if(strcasestr(dev->name, "touchkey"))
+                       {
+                               g_pGesture->touchkey_id = dev->id;
+                               find_dev_false_count = 0;
+                               break;
+                       }
+               }
+       }
+
+       if((g_pGesture->mtsync_status != MTOUCH_FRAME_SYNC_END) && (device->id == g_pGesture->touchkey_id))
+       {
+               if(ev->device_event.detail.key == 177)
+                       XDBG_INFO(MGEST, "Ignore TouchKey KEY_MENU (devid:%d)\n", device->id);
+               else if (ev->device_event.detail.key == 166)
+                       XDBG_INFO(MGEST, "Ignore TouchKey KEY_BACK (devid:%d)\n", device->id);
+               else
+                       XDBG_SECURE(MGEST, "Ignore TouchKey KeyPress (devid:%d, keycode:%d)\n", device->id, ev->device_event.detail.key);
+               return;
+       }
+
+       device->public.processInputProc(ev, device);
+}
+
+void
+GestureHandleKeyReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
+{
+       if (g_pGesture->pass_keycodes[3] == ev->device_event.detail.key)
+       {
+               XDBG_SECURE(MGEST, "TIME = %d, keycode = %d\n", ev->any.time, ev->device_event.detail.key);
+       }
+    device->public.processInputProc(ev, device);
+}
+
+static ErrorStatus
+GestureEnableEventHandler(InputInfoPtr pInfo)
+ {
+       Bool res;
+       GestureDevicePtr pGesture = pInfo->private;
+
+       res = GestureInstallResourceStateHooks();
+
+       if( !res )
+       {
+               XDBG_ERROR(MGEST, "Failed on GestureInstallResourceStateHooks() !\n");
+               return ERROR_ABNORMAL;
+       }
+
+       res = GestureSetMaxNumberOfFingers((int)MAX_MT_DEVICES);
+
+       if( !res )
+       {
+               XDBG_ERROR(MGEST, "Failed on GestureSetMaxNumberOfFingers(%d) !\n", (int)MAX_MT_DEVICES);
+               goto failed;
+       }
+
+       res = GestureRegisterCallbacks(GestureCbEventsGrabbed, GestureCbEventsSelected);
+
+       if( !res )
+       {
+               XDBG_ERROR(MGEST, "Failed to register callbacks for GestureEventsGrabbed(), GestureEventsSelected() !\n");
+               goto failed;
+       }
+
+       return ERROR_NONE;
+
+failed:
+       GestureUninstallResourceStateHooks();
+       GestureUnsetMaxNumberOfFingers();
+
+       return ERROR_ABNORMAL;
+}
+
+static ErrorStatus
+GestureDisableEventHandler(void)
+{
+       ErrorStatus err = ERROR_NONE;
+
+       mieqSetHandler(ET_KeyPress, NULL);
+       mieqSetHandler(ET_KeyRelease, NULL);
+       mieqSetHandler(ET_ButtonPress, NULL);
+       mieqSetHandler(ET_ButtonRelease, NULL);
+       mieqSetHandler(ET_Motion, NULL);
+       mieqSetHandler(ET_MTSync, NULL);
+
+       err = GestureFiniEQ();
+
+       if( ERROR_INVALPTR == err )
+       {
+               XDBG_ERROR(MGEST, "EQ is invalid or was freed already !\n");
+       }
+
+       GestureRegisterCallbacks(NULL, NULL);
+       GestureUninstallResourceStateHooks();
+
+       return err;
+}
+
+static void
+GestureRegisterDeviceInfo(DeviceIntPtr device)
+{
+       InputInfoPtr  pInfo = device->public.devicePrivate;
+       GestureDevicePtr pGesture = pInfo->private;
+       DeviceIntPtr dev;
+       ScreenPtr pScreen = miPointerCurrentScreen();
+       int width = 0, height = 0;
+       int idx = 0;
+       int i;
+
+       XDBG_INFO(MGEST, "Get devices information\n");
+
+       for (i=0; i<MAX_MT_DEVICES; i++)
+       {
+               pGesture->mt_devices[i] = NULL;
+       }
+
+       for( dev = inputInfo.pointer ; dev; dev = dev->next )
+       {
+               if(IsMaster(dev) && IsPointerDevice(dev))
+               {
+                       pGesture->master_pointer = dev;
+                       XDBG_INFO(MGEST, "[id:%d] Master Pointer=%s\n", dev->id, pGesture->master_pointer->name);
+                       continue;
+               }
+
+               if(IsXTestDevice(dev, NULL) && IsPointerDevice(dev))
+               {
+                       pGesture->xtest_pointer = dev;
+                       XDBG_INFO(MGEST, "[id:%d] XTest Pointer=%s\n", dev->id, pGesture->xtest_pointer->name);
+                       continue;
+               }
+
+               if(IsPointerDevice(dev))
+               {
+                       if( idx >= MAX_MT_DEVICES )
+                       {
+                               XDBG_WARNING(MGEST, "Number of mt device is over MAX_MT_DEVICES(%d) !\n",
+                                       MAX_MT_DEVICES);
+                               continue;
+                       }
+                       if (strcasestr(dev->name, "Touchscreen"))
+                       {
+                               pGesture->mt_devices[idx] = dev;
+                               XDBG_INFO(MGEST, "[id:%d] MT device[%d] name=%s\n", dev->id, idx, pGesture->mt_devices[idx]->name);
+                               ErrorF("[id:%d] MT device[%d] name=%s\n", dev->id, idx, pGesture->mt_devices[idx]->name);
+                               GesturePalmGetAbsAxisInfo(dev);
+                               idx++;
+                       }
+               }
+       }
+
+       if( !pGesture->master_pointer || !pGesture->xtest_pointer )
+       {
+               XDBG_ERROR(MGEST, "Failed to get info of master pointer or XTest pointer !\n");
+               pGesture->num_mt_devices = 0;
+
+               return;
+       }
+
+       pGesture->num_mt_devices = idx;
+
+       if( !pGesture->num_mt_devices )
+       {
+               XDBG_ERROR(MGEST, "Failed to mt device information !\n");
+               pGesture->num_mt_devices = 0;
+       pGesture->first_fingerid = -1;
+               return;
+       }
+
+       pGesture->first_fingerid = pGesture->mt_devices[0]->id;
+       memset(pGesture->fingers, 0, sizeof(TouchStatus)*pGesture->num_mt_devices);
+
+       pGesture->pRootWin = RootWindow(pGesture->master_pointer);
+
+       if(g_pGesture->palm_misc.enabled)
+               GesturePalmGetScreenInfo();
+
+       g_pGesture->pTempWin = NULL;
+       g_pGesture->pTempPalmWin = NULL;
+       g_pGesture->inc_num_pressed = 0;
+
+       if( ERROR_NONE != GestureRegionsInit() || ERROR_NONE != GestureInitEQ() )
+       {
+               goto failed;
+       }
+
+       if (pScreen)
+       {
+               pGesture->screen_width = pScreen->width;
+               pGesture->screen_height = pScreen->height;
+               XDBG_ERROR(MGEST, "screen_width = %d, screen_height = %d\n", pGesture->screen_width, pGesture->screen_height);
+       }
+       else
+       {
+               XDBG_ERROR(MGEST, "Fail to get current screen size\n");
+       }
+
+       mieqSetHandler(ET_KeyPress, GestureHandleKeyPressEvent);
+       mieqSetHandler(ET_KeyRelease, GestureHandleKeyReleaseEvent);
+       mieqSetHandler(ET_ButtonPress, GestureHandleButtonPressEvent);
+       mieqSetHandler(ET_ButtonRelease, GestureHandleButtonReleaseEvent);
+       mieqSetHandler(ET_Motion, GestureHandleMotionEvent);
+       mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent);
+
+       return;
+
+failed:
+
+       GestureUninstallResourceStateHooks();
+       GestureUnsetMaxNumberOfFingers();
+}
+
+BOOL
+IsXTestDevice(DeviceIntPtr dev, DeviceIntPtr master)
+{
+       if (IsMaster(dev))
+               return FALSE;
+
+       if (master)
+               return (dev->xtest_master_id == master->id);
+
+       return (dev->xtest_master_id != 0);
+}
+
+void
+GestureGenerateTouchCancelEvent(void)
+{
+    int i;
+    Bool canceled_touch_index[MAX_MT_DEVICES] = {FALSE, };
+
+    if (g_pGesture->mtsync_status == MTOUCH_FRAME_SYNC_END)
+    {
+        XDBG_DEBUG(MGEST, "no Touch(%d)\n", g_pGesture->mtsync_status);
+        return;
+    }
+
+    for (i=0; i<MAX_MT_DEVICES; i++)
+    {
+        if (!(g_pGesture->mt_devices[i]->button->buttonsDown)) continue;
+        InternalEvent cancel_event;
+
+        cancel_event.touch_cancel_event.header = ET_Internal;
+        cancel_event.touch_cancel_event.type = ET_TouchCancel;
+        cancel_event.touch_cancel_event.length = sizeof(TouchCancelEvent);
+        cancel_event.touch_cancel_event.time = CurrentTime;
+        cancel_event.touch_cancel_event.deviceid = g_pGesture->mt_devices[i]->id;
+
+        cancel_event.touch_cancel_event.sourceid = g_pGesture->mt_devices[i]->id;
+        cancel_event.touch_cancel_event.resource = 0;
+        cancel_event.touch_cancel_event.flags = 0;
+
+        g_pGesture->mt_devices[i]->public.processInputProc(&cancel_event, g_pGesture->mt_devices[i]);
+        canceled_touch_index[i] = TRUE;
+        g_pGesture->touch_cancel_status = TRUE;
+    }
+
+    for (i=0; i<MAX_MT_DEVICES; i++)
+    {
+        if (canceled_touch_index[i] == FALSE) continue;
+        InternalEvent release_event;
+        InternalEvent release_event_master;
+
+        memset(&release_event, 0, sizeof(InternalEvent));
+
+        release_event.device_event.header = ET_Internal;
+        release_event.device_event.type = ET_ButtonRelease;
+        release_event.device_event.length = sizeof(DeviceEvent);
+        release_event.device_event.time = CurrentTime;
+        release_event.device_event.deviceid = g_pGesture->mt_devices[i]->id;
+        release_event.device_event.sourceid = g_pGesture->mt_devices[i]->button->sourceid;
+        release_event.device_event.detail.button = 1;
+        release_event.device_event.root_x = g_pGesture->last_touches[i].cx;
+        release_event.device_event.root_y = g_pGesture->last_touches[i].cy;
+        if (g_pGesture->mt_devices[i]->id == g_pGesture->first_fingerid)
+        {
+            memcpy(&release_event_master, &release_event, sizeof(InternalEvent));
+            release_event_master.device_event.deviceid = g_pGesture->master_pointer->id;
+        }
+
+        g_pGesture->mt_devices[i]->public.processInputProc(&release_event, g_pGesture->mt_devices[i]);
+        if (g_pGesture->mt_devices[i]->id == g_pGesture->first_fingerid)
+        {
+            g_pGesture->master_pointer->public.processInputProc(&release_event_master, g_pGesture->master_pointer);
+        }
+    }
+}
+
+static void
+GestureDPMSCallback(CallbackListPtr *pcbl, void *unused, void *calldata)
+{
+    int dpmsLevel = *(int *)calldata;
+
+    if ((DPMSModeOff == dpmsLevel) && (MTOUCH_FRAME_SYNC_END != g_pGesture->mtsync_status)) {
+        XDBG_DEBUG(MGEST, "TouchCancel dpmslevel: %d\n", dpmsLevel);
+        GestureGenerateTouchCancelEvent();
+    }
+}
+
+void
+GestureEnable(int enable, Bool prop, DeviceIntPtr dev)
+{
+       if((!enable) && (g_pGesture->is_active))
+       {
+               g_pGesture->is_active = 0;
+               XDBG_INFO(MGEST, "Disabled !\n");
+       }
+       else if((enable) && (!g_pGesture->is_active))
+       {
+               g_pGesture->is_active = 1;
+               XDBG_INFO(MGEST, "Enabled !\n");
+       }
+
+       if(!prop)
+                XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE);
+}
+
+ErrorStatus
+GestureRegionsInit(void)
+{
+       int i;
+       PalmStatusPtr pPalm = &g_pGesture->palm;
+
+       if( !g_pGesture )
+               return ERROR_INVALPTR;
+
+       pixman_region_init(&g_pGesture->area);
+       pixman_region_init(&pPalm->area);
+
+       for( i = 0 ; i < MAX_MT_DEVICES ; i++ )
+       {
+               pixman_region_init_rect (&g_pGesture->finger_rects[i], 0, 0, FINGER_WIDTH_2T, FINGER_HEIGHT_2T);
+               pixman_region_init_rect (&pPalm->finger_rects[i], 0, 0, FINGER_WIDTH_2T, FINGER_HEIGHT_2T);
+       }
+
+       return ERROR_NONE;
+}
+
+ErrorStatus
+GestureRegionsReinit(void)
+{
+       PalmStatusPtr pPalm = &g_pGesture->palm;
+       int i;
+       if( !g_pGesture )
+       {
+               XDBG_ERROR(MGEST, "Invalid pointer access !\n");
+               return ERROR_INVALPTR;
+       }
+
+       pixman_region_init(&g_pGesture->area);
+       pixman_region_init(&pPalm->area);
+
+       for( i = 0 ; i < MAX_MT_DEVICES ; i++ )
+       {
+               pixman_region_init_rect (&pPalm->finger_rects[i], 0, 0, FINGER_WIDTH_2T, FINGER_HEIGHT_2T);
+       }
+
+       return ERROR_NONE;
+}
+
+ErrorStatus
+GestureInitEQ(void)
+{
+       int i;
+       IEventPtr tmpEQ;
+
+       tmpEQ = (IEventRec *)calloc(GESTURE_EQ_SIZE, sizeof(IEventRec));
+
+       if( !tmpEQ )
+       {
+               XDBG_ERROR(MGEST, "Failed to allocate memory for EQ !\n");
+               return ERROR_ALLOCFAIL;
+       }
+
+       for( i = 0 ; i < GESTURE_EQ_SIZE ; i++ )
+       {
+               tmpEQ[i].event = (InternalEvent *)malloc(sizeof(InternalEvent));
+               if( !tmpEQ[i].event )
+               {
+                       XDBG_ERROR(MGEST, "Failed to allocation memory for each event buffer in EQ !\n");
+                       i--;
+                       while(i >= 0 && tmpEQ[i].event)
+                       {
+                               free(tmpEQ[i].event);
+                               tmpEQ[i].event = NULL;
+                       }
+                       free (tmpEQ);
+                       tmpEQ = NULL;
+                       return ERROR_ALLOCFAIL;
+               }
+       }
+
+       g_pGesture->EQ = tmpEQ;
+       g_pGesture->headEQ = g_pGesture->tailEQ = 0;
+
+       return ERROR_NONE;
+}
+
+ErrorStatus
+GestureFiniEQ(void)
+{
+       int i;
+
+       if( !g_pGesture || !g_pGesture->EQ )
+               return ERROR_INVALPTR;
+
+       for( i = 0 ; i < GESTURE_EQ_SIZE ; i++ )
+       {
+               if( g_pGesture->EQ[i].event )
+               {
+                       free(g_pGesture->EQ[i].event);
+                       g_pGesture->EQ[i].event = NULL;
+               }
+       }
+
+       free(g_pGesture->EQ);
+       g_pGesture->EQ = NULL;
+
+       return ERROR_NONE;
+}
+
+ErrorStatus
+GestureEnqueueEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
+{
+       int tail;
+
+       if( !g_pGesture || !g_pGesture->EQ )
+       {
+               XDBG_ERROR(MGEST, "Invalid pointer access !\n");
+               return ERROR_INVALPTR;
+       }
+
+       tail = g_pGesture->tailEQ;
+
+       if( tail >= GESTURE_EQ_SIZE )
+       {
+               XDBG_WARNING(MGEST, "Gesture EQ is full !\n");
+               printk("[X11][GestureEnqueueEvent] Gesture EQ is full...Force Gesture Flush !\n");
+               g_pGesture->enqueue_fulled = 1;
+               if(!(g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL))
+               {
+                       if( !(g_pGesture->filter_mask & FlickFilterMask) )
+                       {
+                               GestureRecognize_GroupFlick(ev->any.type, ev, device, 0);
+                       }
+                       if( !(g_pGesture->filter_mask & PanFilterMask) )
+                       {
+                               GestureRecognize_GroupPan(ev->any.type, ev, device, 0, 0);
+                       }
+                       if( !(g_pGesture->filter_mask & PinchRotationFilterMask) )
+                       {
+                               GestureRecognize_GroupPinchRotation(ev->any.type, ev, device, 0, 0);
+                       }
+                       if( !(g_pGesture->filter_mask & TapFilterMask) )
+                       {
+                               GestureRecognize_GroupTap(ev->any.type, ev, device, 0, 0);
+                       }
+                       if( !(g_pGesture->filter_mask & TapNHoldFilterMask) )
+                       {
+                               GestureRecognize_GroupTapNHold(ev->any.type, ev, device, 0, 0);
+                       }
+                       if( !(g_pGesture->filter_mask & HoldFilterMask) )
+                       {
+                               GestureRecognize_GroupHold(ev->any.type, ev, device, 0, 0);
+                       }
+               }
+               if(!(g_pGesture->palm_filter_mask == GESTURE_PALM_FILTER_MASK_ALL))
+               {
+                       if(!(g_pGesture->palm_filter_mask & PalmFlickHorizFilterMask))
+                       {
+                               GesturePalmRecognize_FlickHorizen(ev->any.type, 0);
+                       }
+                       if(!(g_pGesture->palm_filter_mask & PalmFlickHorizFilterMask))
+                       {
+                               GesturePalmRecognize_FlickVertical(ev->any.type, 0);
+                       }
+               }
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+               if(!(g_pGesture->bezel_filter_mask == BezelFlickFilterMask))
+               {
+                       GestureBezelRecognize(ev->any.type, ev, device);
+               }
+#endif
+               g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
+               g_pGesture->palm_filter_mask = GESTURE_PALM_FILTER_MASK_ALL;
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+               g_pGesture->bezel_filter_mask = BezelFlickFilterMask;
+               g_pGesture->bezel_recognized_mask = 0;
+#endif
+               g_pGesture->recognized_gesture = 0;
+               g_pGesture->recognized_palm = 0;
+               if( ERROR_INVALPTR == GestureFlushOrDrop() )
+               {
+                       GestureControl(g_pGesture->this_device, DEVICE_OFF);
+               }
+               return ERROR_EQFULL;
+       }
+
+#ifdef __DETAIL_DEBUG__
+       switch( ev->any.type )
+       {
+               case ET_ButtonPress:
+                       XDBG_DEBUG(MGEST, "ET_ButtonPress (id:%d)\n", device->id);
+                       break;
+
+               case ET_ButtonRelease:
+                       XDBG_DEBUG(MGEST, "ET_ButtonRelease (id:%d)\n", device->id);
+                       break;
+
+               case ET_Motion:
+                       XDBG_DEBUG(MGEST, "ET_Motion (id:%d)\n", device->id);
+                       break;
+       }
+#endif//__DETAIL_DEBUG__
+
+       g_pGesture->EQ[tail].device = device;
+       g_pGesture->EQ[tail].screen_num = screen_num;
+       memcpy(g_pGesture->EQ[tail].event, ev, sizeof(InternalEvent));//need to be optimized
+       g_pGesture->tailEQ++;
+
+       return ERROR_NONE;
+}
+
+ErrorStatus
+GestureEventsFlush(void)
+{
+       int i, j;
+       DeviceIntPtr device;
+
+       if( !g_pGesture->EQ )
+       {
+               XDBG_ERROR(MGEST, "Invalid pointer access !\n");
+               return ERROR_INVALPTR;
+       }
+
+#ifdef __DETAIL_DEBUG__
+       XDBG_DEBUG(MGEST, "\n");
+#endif//__DETAIL_DEBUG__
+
+       for( i = g_pGesture->headEQ ; i < g_pGesture->tailEQ ; i++)
+       {
+               device = g_pGesture->EQ[i].device;
+#ifdef __DETAIL_DEBUG__
+               if(g_pGesture->EQ[i].event->any.type != ET_Motion)
+                       XDBG_DEBUG(MGEST, "[%d] type: %d\n", device->id, g_pGesture->EQ[i].event->any.type);
+#endif//__DETAIL_DEBUG__
+
+               for(j = 0 ; j < MAX_MT_DEVICES+1 ; j++)
+               {
+                       if(g_pGesture->palm.qti[j].devid == device->id)
+                       {
+#ifdef __DETAIL_DEBUG__
+                               if(g_pGesture->EQ[i].event->any.type != ET_Motion)
+                                       XDBG_DEBUG(MGEST, "[%d] type: %d(pressed: %d) time: %d\n", device->id, g_pGesture->EQ[i].event->any.type, g_pGesture->palm.qti[j].pressed, GetTimeInMillis());
+#endif//__DETAIL_DEBUG__
+                               if( (g_pGesture->palm.qti[j].pressed == 0) && (g_pGesture->EQ[i].event->any.type == ET_ButtonRelease) )
+                               {
+                                       XDBG_WARNING(MGEST, "Enqueued event..ButtonRelease with no ButtonPress !(devid: %d)\n", device->id);
+                                       g_pGesture->EQ[i].event->any.type = ET_ButtonPress;
+                                       device->public.processInputProc(g_pGesture->EQ[i].event, device);
+                                       g_pGesture->EQ[i].event->any.type = ET_ButtonRelease;
+                                       g_pGesture->palm.qti[j].pressed = 0;
+                               }
+                               else if(g_pGesture->EQ[i].event->any.type == ET_ButtonPress)
+                               {
+                                       g_pGesture->palm.qti[j].pressed = 1;
+                               }
+                               else if( (g_pGesture->palm.qti[j].pressed == 1) && (g_pGesture->EQ[i].event->any.type == ET_ButtonRelease))
+                               {
+                                       g_pGesture->palm.qti[j].pressed = 0;
+                               }
+                               break;
+                       }
+                       else if(g_pGesture->palm.qti[j].devid == 0)
+                       {
+                               g_pGesture->palm.qti[j].devid = device->id;
+                               j--;
+                       }
+               }
+#ifdef __DETAIL_DEBUG__
+               if(g_pGesture->EQ[i].event->any.type != ET_Motion)
+                       XDBG_DEBUG(MGEST, "!!! [%d] type: %d\n", device->id, g_pGesture->EQ[i].event->any.type);
+#endif
+               device->public.processInputProc(g_pGesture->EQ[i].event, device);
+       }
+       memset(g_pGesture->palm.qti, 0, sizeof(g_pGesture->palm.qti[MAX_MT_DEVICES+1]));
+
+       for( i = 0 ; i < MAX_MT_DEVICES ; i++ )
+               g_pGesture->event_sum[i] = 0;
+
+       g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
+
+       return ERROR_NONE;
+}
+
+
+void
+GestureEventsDrop(void)
+{
+#ifdef __DETAIL_DEBUG__
+       XDBG_DEBUG(MGEST, "\n");
+#endif//__DETAIL_DEBUG__
+
+       g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
+}
+
+#ifdef HAVE_PROPERTIES
+static void
+GestureInitProperty(DeviceIntPtr dev)
+{
+       int rc;
+
+#ifdef SUPPORT_ANR_WITH_INPUT_EVENT
+       prop_anr_in_input_event = MakeAtom(CHECK_APPLICATION_NOT_RESPONSE_IN_INPUT_EVENT, strlen(CHECK_APPLICATION_NOT_RESPONSE_IN_INPUT_EVENT),  TRUE);
+       prop_anr_event_window = MakeAtom(ANR_EVENT_WINDOW, strlen(ANR_EVENT_WINDOW), TRUE);
+#endif
+
+       prop_gesture_recognizer_onoff = MakeAtom(GESTURE_RECOGNIZER_ONOFF, strlen(GESTURE_RECOGNIZER_ONOFF),  TRUE);
+       rc = XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE);
+
+       if (rc != Success)
+               return;
+
+       XISetDevicePropertyDeletable(dev, prop_gesture_recognizer_onoff, FALSE);
+
+       prop_gesture_palm_rejection_mode = MakeAtom(GESTURE_PALM_REJECTION_MODE, strlen(GESTURE_PALM_REJECTION_MODE), TRUE);
+       rc = XIChangeDeviceProperty(dev, prop_gesture_palm_rejection_mode, XA_INTEGER, 8, PropModeReplace, 1, &g_pGesture->palm_rejection_mode, FALSE);
+
+       if (rc != Success)
+               return;
+
+       XISetDevicePropertyDeletable(dev, prop_gesture_palm_rejection_mode, FALSE);
+}
+
+static int
+GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
+                 BOOL checkonly)
+{
+       if( prop_gesture_recognizer_onoff == atom )
+       {
+               int data;
+               if( val->format != 32 || val->type != XA_INTEGER || val->size != 1 )
+                       return BadMatch;
+
+               if( !checkonly )
+               {
+                       data = *((int *)val->data);
+                       GestureEnable(data, TRUE, dev);
+               }
+       }
+       else if( prop_gesture_palm_rejection_mode == atom)
+       {
+               int data;
+               if( val->format != 8 || val->type != XA_INTEGER || val->size != 1 )
+                       return BadMatch;
+
+               if( !checkonly )
+               {
+                       int ret;
+                       data = *((BOOL*)val->data);
+                       int fd, fd_result;
+                       char buf[128];
+
+                       g_pGesture->palm_rejection_mode = (int)data;
+
+                       fd = open("/sys/class/sec/tsp/cmd", O_WRONLY);
+                       if (fd < 0)
+                       {
+                               XDBG_ERROR(MGEST, "failed to open tsp node(%d)\n", fd);
+                               return Success;
+                       }
+
+                       sprintf(buf, "stylus_enable,%d", !!(g_pGesture->palm_rejection_mode));
+                       XDBG_DEBUG(MGEST, "stylus_changed: %d!\n", !!(g_pGesture->palm_rejection_mode));
+
+                       ret = write(fd, buf, strlen(buf));
+                       if (ret <= 0)
+                       {
+                               XDBG_WARNING(MGEST, "failed to stylus_changed: %d\n", !!(g_pGesture->palm_rejection_mode));
+                       }
+
+                       close(fd);
+
+                       fd_result = open("/sys/class/sec/tsp/cmd_result", O_RDONLY);
+                       if (fd_result < 0)
+                       {
+                               XDBG_ERROR(MGEST, "failed to open tsp node(%d)\n", fd_result);
+                               return Success;
+                       }
+
+                       memset(buf, 0L, sizeof(buf));
+
+                       ret = read(fd_result, buf, sizeof(buf));
+                       if (ret <= 0)
+                       {
+                               XDBG_WARNING(MGEST, "failed to read cmd_result\n");
+                       }
+                       else
+                       {
+                               ErrorF("stylus mode result: %s\n", buf);
+                       }
+                       close(fd_result);
+               }
+       }
+
+       return Success;
+}
+#endif//HAVE_PROPERTIES
+
+static int
+GestureInit(DeviceIntPtr device)
+{
+#ifdef HAVE_PROPERTIES
+       GestureInitProperty(device);
+       XIRegisterPropertyHandler(device, GestureSetProperty, NULL, NULL);
+#endif
+
+       return Success;
+}
+
+static void
+GestureFini(DeviceIntPtr device)
+{
+       XIRegisterPropertyHandler(device, NULL, NULL, NULL);
+}
+
+static pointer
+GesturePlug(pointer module, pointer options, int *errmaj, int *errmin)
+{
+       xf86AddInputDriver(&GESTURE, module, 0);
+       return module;
+}
+
+static void
+GestureUnplug(pointer p)
+{
+}
+
+static int
+GesturePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
+{
+    int rc = BadAlloc;
+    GestureDevicePtr    pGesture;
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+    BezelFlickStatusPtr pBezel;
+#endif
+
+    pGesture = calloc(1, sizeof(GestureDeviceRec));
+
+    if (!pGesture) {
+        pInfo->private = NULL;
+        //xf86DeleteInput(pInfo, 0);
+        goto error;
+    }
+
+    g_pGesture = pGesture;
+    pInfo->private = pGesture;
+    pInfo->flags = 0;
+    pInfo->read_input = GestureReadInput; /* new data avl */
+    pInfo->switch_mode = NULL; /* toggle absolute/relative mode */
+    pInfo->device_control = GestureControl; /* enable/disable dev */
+    /* process driver specific options */
+    pGesture->device = xf86SetStrOption(pInfo->options, "Device", "/dev/null");
+    pGesture->is_active = xf86SetIntOption(pInfo->options, "Activate", 0);
+       pGesture->stylus_able = xf86SetIntOption(pInfo->options, "Stylus", 0);
+       pGesture->support_palm = xf86SetIntOption(pInfo->options, "SupportPalm", 0);
+
+       if (pGesture->support_palm)
+       {
+               PalmRecognize = GesturePalmRecognize;
+               XDBG_DEBUG(MGEST, "Palm Support !!\n");
+       }
+       else
+       {
+               PalmRecognize = NULL;
+               XDBG_DEBUG(MGEST, "No Palm Support !!\n");
+       }
+
+    {
+       int i;
+       char tmp[10];
+
+       memset(&pGesture->pass_keycodes, 0, sizeof(pGesture->pass_keycodes));
+
+       for(i = 0 ; i < NUM_PASSKEYS ; i++)
+       {
+               snprintf(tmp, sizeof(tmp), "PassKey%d", i+1);
+               pGesture->pass_keycodes[i] = xf86SetIntOption(pInfo->options, tmp, 0);
+               XDBG_SECURE(MGEST, "pass_keycode[%d]=%d\n", i, pGesture->pass_keycodes[i]);
+       }
+    }
+
+    pGesture->gestureWin = None;
+
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+    pBezel = &pGesture->bezel;
+    pBezel->is_active = xf86SetIntOption(pInfo->options, "Bezel_Activate", 0);
+    pBezel->top_left.width = xf86SetIntOption(pInfo->options, "Bezel_Top_Left_Width", 0);
+    pBezel->top_left.height = xf86SetIntOption(pInfo->options, "Bezel_Top_Left_Height", 0);
+    pBezel->top_right.width = xf86SetIntOption(pInfo->options, "Bezel_Top_Right_Width", 0);
+    pBezel->top_right.height = xf86SetIntOption(pInfo->options, "Bezel_Top_Right_Height", 0);
+    pBezel->bottom_left.width = xf86SetIntOption(pInfo->options, "Bezel_Bottom_Left_Width", 0);
+    pBezel->bottom_left.height = xf86SetIntOption(pInfo->options, "Bezel_Bottom_Left_Height", 0);
+    pBezel->bottom_right.width = xf86SetIntOption(pInfo->options, "Bezel_Bottom_Right_Width", 0);
+    pBezel->bottom_right.height = xf86SetIntOption(pInfo->options, "Bezel_Bottom_Right_Height", 0);
+    pBezel->flick_distance = xf86SetIntOption(pInfo->options, "Bezel_Flick_Distance", 0);
+    pBezel->bezel_angle_ratio = xf86SetIntOption(pInfo->options, "Bezel_Flick_Angle_Ratio", 0);
+    pBezel->bezel_angle_moving_check = xf86SetIntOption(pInfo->options, "Bezel_Flick_Angle_Moving_Check", 0);
+#ifdef __BEZEL_DEBUG__
+       XDBG_DEBUG(MGEST, "[BEZEL] top_left.width: %d, top_left.height: %d\n", pBezel->top_left.width, pBezel->top_left.height);
+       XDBG_DEBUG(MGEST, "[BEZEL] top_right.width: %d, top_right.height: %d\n", pBezel->top_right.width, pBezel->top_right.height);
+       XDBG_DEBUG(MGEST, "[BEZEL] bottom_left.width: %d, bottom_left.height: %d\n", pBezel->bottom_left.width, pBezel->bottom_left.height);
+       XDBG_DEBUG(MGEST, "[BEZEL] bottom_right.width: %d, bottom_right.height: %d\n", pBezel->bottom_right.width, pBezel->bottom_right.height);
+       XDBG_DEBUG(MGEST, "[BEZEL] flick_distance: %d, bezel_angle_ratio: %d, bezel_angle_moving_check: %d\n", pBezel->flick_distance, pBezel->bezel_angle_ratio, pBezel->bezel_angle_moving_check);
+#endif//__BEZEL_DEBUG__
+#endif
+
+       pGesture->pinchrotation_time_threshold = xf86SetIntOption(pInfo->options, "PinchRotationTimeThresHold", PINCHROTATION_TIME_THRESHOLD);
+       pGesture->pinchrotation_dist_threshold = xf86SetRealOption(pInfo->options, "PinchRotationDistThresHold", PINCHROTATION_DIST_THRESHOLD);
+       pGesture->pinchrotation_angle_threshold = xf86SetRealOption(pInfo->options, "PinchRotationAngleThresHold", PINCHROTATION_ANGLE_THRESHOLD);
+       pGesture->singlefinger_threshold = xf86SetIntOption(pInfo->options, "SingleFingerThresHold", SGL_FINGER_TIME_THRESHOLD);
+       pGesture->singletap_threshold = xf86SetIntOption(pInfo->options, "SingleTapThresHold", SGL_TAP_TIME_THRESHOLD);
+       pGesture->doubletap_threshold = xf86SetIntOption(pInfo->options, "DoubleTapThresHold", DBL_TAP_TIME_THRESHOLD);
+
+       pGesture->palm_min_touch_major = xf86SetIntOption(pInfo->options, "PalmMinTouchMajor", PALM_MIN_TOUCH_MAJOR);
+       pGesture->palm_min_width_major = xf86SetIntOption(pInfo->options, "PalmMinWidthMajor", PALM_MIN_WIDTH_MAJOR);
+       pGesture->palm_min_touch_major_bezel = xf86SetIntOption(pInfo->options, "PalmMinTouchMajorBezel", PALM_MIN_TOUCH_MAJOR_BEZEL);
+       pGesture->palm_min_width_major_bezel = xf86SetIntOption(pInfo->options, "PalmMinWidthMajorBezel", PALM_MIN_WIDTH_MAJOR_BEZEL);
+       pGesture->palm_bezel = xf86SetIntOption(pInfo->options, "PalmBezel", PALM_BEZEL);
+
+       if (pGesture->is_active)
+               pGesture->ehtype = KEEP_EVENTS;
+       else
+               pGesture->ehtype = PROPAGATE_EVENTS;
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+       if(pBezel->bezel_angle_ratio > 0)
+       {
+               pBezel->min_rad = (RAD_90DEG / pBezel->bezel_angle_ratio);
+               pBezel->max_rad = ((RAD_90DEG / pBezel->bezel_angle_ratio) * (pBezel->bezel_angle_ratio-1));
+               pBezel->min_180_rad = (RAD_90DEG + pBezel->min_rad);
+               pBezel->max_180_rad = (RAD_90DEG + pBezel->max_rad);
+       }
+       else
+       {
+               pBezel->min_rad = MIN_RAD;
+               pBezel->max_rad = MAX_RAD;
+               pBezel->min_180_rad = RAD_180DEG_MIN;
+               pBezel->max_180_rad = RAD_180DEG_MAX;
+       }
+#endif
+    pGesture->lastSelectedWin = None;
+    pGesture->touchkey_id = 0;
+    pGesture->mtsync_status = MTOUCH_FRAME_SYNC_END;
+    g_pGesture->grabMask = g_pGesture->eventMask = 0;
+
+    xf86Msg(X_INFO, "%s: Using device %s.\n", pInfo->name, pGesture->device);
+
+    /* process generic options */
+    xf86CollectInputOptions(pInfo, NULL);
+    xf86ProcessCommonOptions(pInfo, pInfo->options);
+
+    pInfo->fd = -1;
+
+       g_pGesture->tap_repeated = 0;
+
+       g_pGesture->palm.palmflag = 0;
+       g_pGesture->palm.palm_single_finger_timer = NULL;
+       g_pGesture->enqueue_fulled = 0;
+       g_pGesture->zoom_enabled = 0;
+       memset(g_pGesture->palm.qti, 0, sizeof(g_pGesture->palm.qti[MAX_MT_DEVICES+1]));
+
+       g_pGesture->palm_rejection_mode = 0;
+       g_pGesture->palm_detected = FALSE;
+
+       memset(g_pGesture->stylusInfo.t_status, 0, sizeof(g_pGesture->stylusInfo.t_status[MAX_MT_DEVICES]));
+       g_pGesture->stylusInfo.stylus_id = 0;
+       g_pGesture->stylusInfo.pen_detected = FALSE;
+
+       g_pGesture->touch_cancel_status = FALSE;
+
+    return Success;
+
+error:
+    if (pInfo->fd >= 0)
+        close(pInfo->fd);
+    return rc;
+}
+
+static void
+GestureUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
+{
+       GestureDevicePtr pGesture = pInfo->private;
+
+       g_pGesture = pGesture = NULL;
+       pInfo->private = NULL;
+
+       xf86DeleteInput(pInfo, 0);
+}
+
+static int
+GestureControl(DeviceIntPtr device, int what)
+{
+    InputInfoPtr  pInfo = device->public.devicePrivate;
+    GestureDevicePtr pGesture = pInfo->private;
+
+    switch(what)
+    {
+        case DEVICE_INIT:
+            GestureInit(device);
+            break;
+
+        /* Switch device on.  Establish socket, start event delivery.  */
+        case DEVICE_ON:
+            xf86Msg(X_INFO, "%s: On.\n", pInfo->name);
+
+            if (device->public.on)
+                    break;
+
+            device->public.on = TRUE;
+            pGesture->this_device = device;
+            pGesture->num_mt_devices = 0;
+            if( ERROR_ABNORMAL == GestureEnableEventHandler(pInfo) )
+               goto device_off;
+            if (!AddCallback(&DPMSCallback, GestureDPMSCallback, NULL))
+                ErrorF("[Gesture]Failed to Add DPMS CallBack\n");
+            break;
+
+       case DEVICE_OFF:
+device_off:
+            GestureDisableEventHandler();
+            DeleteCallback(&DPMSCallback, GestureDPMSCallback, NULL);
+            GestureFini(device);
+            pGesture->this_device = NULL;
+             xf86Msg(X_INFO, "%s: Off.\n", pInfo->name);
+
+            if (!device->public.on)
+                break;
+
+            pInfo->fd = -1;
+            device->public.on = FALSE;
+            break;
+
+      case DEVICE_CLOSE:
+            /* free what we have to free */
+            break;
+      case DEVICE_READY:
+            GestureRegisterDeviceInfo(device);
+            break;
+    }
+    return Success;
+}
+
+static void
+GestureReadInput(InputInfoPtr pInfo)
+{
+}
+
diff --git a/mobile/src/gesture.h b/mobile/src/gesture.h
new file mode 100644 (file)
index 0000000..23bc008
--- /dev/null
@@ -0,0 +1,709 @@
+/**************************************************************************
+
+xserver-xorg-input-gesture
+
+Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+
+Contact: Sung-Jin Park <sj76.park@samsung.com>
+         Sangjin LEE <lsj119@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifndef _GESTURE_H_
+#define _GESTURE_H_
+
+#include <xorg/events.h>
+#include <xorg/gestureext.h>
+#include <X11/extensions/gestureconst.h>
+#include <pixman.h>
+
+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3
+#define HAVE_PROPERTIES 1
+#endif
+
+#ifndef ABS_CNT
+#define ABS_CNT (ABS_MAX+1)
+#endif
+
+/**
+ * If there's touch event in pointed window and there's no reponse, we just assume that client looks like deadlock.
+ * In this case, we will make a popup window and terminate application.
+ * To support this feature, we use SUPPORT_ANR_WITH_INPUT_EVENT flag.
+ */
+#define SUPPORT_ANR_WITH_INPUT_EVENT
+
+#define NUM_PASSKEYS   20
+
+#define SYSCALL(call) while (((call) == -1) && (errno == EINTR))
+#define RootWindow(dev) dev->spriteInfo->sprite->spriteTrace[0]
+#define CLIENT_BITS(id) ((id) & RESOURCE_CLIENT_MASK)
+#define CLIENT_ID(id) ((int)(CLIENT_BITS(id) >> CLIENTOFFSET))
+
+#define MAX_MT_DEVICES         10
+#define GESTURE_EQ_SIZE        256
+
+#define GESTURE_RECOGNIZER_ONOFF       "GESTURE_RECOGNIZER_ONOFF"
+#define GESTURE_PALM_REJECTION_MODE    "GESTURE_PALM_REJECTION_MODE"
+#define CHECK_APPLICATION_NOT_RESPONSE_IN_INPUT_EVENT "_CHECK_APPLICATION_NOT_RESPONSE_IN_INPUT_EVENT_"
+#define ANR_EVENT_WINDOW "_ANR_EVENT_WINDOW_"
+
+#define FINGER_WIDTH           10
+#define FINGER_HEIGHT          10
+#define FINGER_WIDTH_2T        20
+#define FINGER_HEIGHT_2T       20
+#define AREA_CENTER_X(extents) ((extents)->x1 + (((extents)->x2-(extents)->x1)/2))
+#define AREA_CENTER_Y(extents) ((extents)->y1 + (((extents)->y2-(extents)->y1)/2))
+#define AREA_SIZE(extents)             (ABS((extents)->x2-(extents)->x1)*ABS((extents)->y2-(extents)->y1))
+#define INBOX(r,x,y)                           ( ((r)->x2 >  x) && ((r)->x1 <= x) && ((r)->y2 >  y) && ((r)->y1 <= y) )
+#define AREA_HEIGHT(extents)    (((extents)->y2)-((extents)->y1))
+#define AREA_WIDTH(extents)    (((extents)->x2)-((extents)->x1))
+#define AREA_DIAG_LEN(extents)  sqrt((AREA_WIDTH(extents)*AREA_WIDTH(extents))+(AREA_HEIGHT(extents)*AREA_HEIGHT(extents)))
+
+//tap
+#define TAP_THRESHOLD                  100//in pixel
+#define SINGLE_TAP_TIMEOUT             100//in msec
+#define DOUBLE_TAP_TIMEOUT     250//in msec
+
+//pinch rotation
+#define ZOOM_THRESHOLD                 0.05f
+#define ANGLE_THRESHOLD                0.1f
+
+typedef int XFixed;
+typedef double XDouble;
+#define XDoubleToFixed(f)    ((XFixed) ((f) * 65536))
+#define XFixedToDouble(f)    (((XDouble) (f)) / 65536)
+
+#define MIN(x, y) (((x) < (y)) ? (x) : (y))
+#define MAX(x, y) (((x) > (y)) ? (x) : (y))
+#define ABS(x) (((x) < 0) ? -(x) : (x))
+
+enum
+{
+       FLICK_NORTHWARD = 0,
+       FLICK_NORTHEASTWARD,
+       FLICK_EASTWARD,
+       FLICK_SOUTHEASTWARD,
+       FLICK_SOUTHWARD,
+       FLICK_SOUTHWESTWARD,
+       FLICK_WESTWARD,
+       FLICK_NORTHWESTWARD
+};
+
+/* Gesture query devices infomation and register handlers
+  * if a device_control function is called using DEVICE_READY */
+#define DEVICE_READY 11
+
+#define SCREEN_WIDTH                           720
+#define SCREEN_HEIGHT                          1280
+
+#define PAN_AREA_THRESHOLD                     10000//=100pixel * 100pixel
+#define PAN_MOVE_THRESHOLD                     5//pixel
+#define PAN_UPDATE_MOVE_THRESHOLD      3//pixel
+#define PAN_TIME_THRESHOLD                     300//ms
+
+#define PINCHROTATION_TIME_THRESHOLD           500//ms
+#define PINCHROTATION_INIT_DIST_THRESHOLD      25.0f
+#define PINCHROTATION_INIT_ANGLE_THRESHOLD     0.2f
+#define PINCHROTATION_DIST_THRESHOLD           25.0f
+#define PINCHROTATION_ANGLE_THRESHOLD          0.2f
+
+#define HOLD_AREA_THRESHOLD                    2500//=50pixel * 50pixel
+#define HOLD_MOVE_THRESHOLD                    10//pixel
+#define HOLD_TIME_THRESHOLD                    500//ms
+
+#define TAP_AREA_THRESHOLD                     30000//= 300pixel * 100pixel
+#define TAP_MOVE_THRESHOLD                     300//pixel
+#define SGL_FINGER_TIME_THRESHOLD      50//ms
+#define SGL_TAP_TIME_THRESHOLD         200//ms
+#define DBL_TAP_TIME_THRESHOLD         400//ms
+#define MAX_TAP_REPEATS                                2
+
+#define TAPNHOLD_AREA_THRESHOLD                        4900//= 70pixel * 70pixel
+#define TAPNHOLD_MOVE_THRESHOLD                        50//pixel
+#define TAPNHOLD_TAP_TIME_THRESHOLD            200//ms
+#define TAPNHOLD_INTV_TIME_THRESHOLD           200//ms
+#define TAPNHOLD_HOLD_TIME_THRESHOLD   500//ms
+
+#define FLICK_AREA_THRESHOLD                   22500//=150pixel * 150pixel
+#define FLICK_AREA_TIMEOUT                             700//ms
+#define FLICK_MOVE_THRESHOLD                   100//pixel
+#define FLICK_MOVE_TIMEOUT                             1000//ms
+
+#define RAD_90DEG  M_PI_2
+#define RAD_180DEG M_PI
+#define RAD_270DEG (M_PI_2 * 3)
+#define RAD_360DEG (M_PI * 2)
+#define MIN_RAD (RAD_90DEG / 4)
+#define MAX_RAD ((RAD_90DEG / 4) * 3)
+#define RAD_180DEG_MIN (RAD_90DEG + MIN_RAD)
+#define RAD_180DEG_MAX (RAD_90DEG + MAX_RAD)
+
+#define rad2degree(r) ((r) * 180/M_PI)
+
+#define AXIS_LABEL_PROP_ABS_X           "Abs X"
+#define AXIS_LABEL_PROP_ABS_Y           "Abs Y"
+#define AXIS_LABEL_PROP_ABS_Z           "Abs Z"
+#define AXIS_LABEL_PROP_ABS_RX          "Abs Rotary X"
+#define AXIS_LABEL_PROP_ABS_RY          "Abs Rotary Y"
+#define AXIS_LABEL_PROP_ABS_RZ          "Abs Rotary Z"
+#define AXIS_LABEL_PROP_ABS_THROTTLE    "Abs Throttle"
+#define AXIS_LABEL_PROP_ABS_RUDDER      "Abs Rudder"
+#define AXIS_LABEL_PROP_ABS_WHEEL       "Abs Wheel"
+#define AXIS_LABEL_PROP_ABS_GAS         "Abs Gas"
+#define AXIS_LABEL_PROP_ABS_BRAKE       "Abs Brake"
+#define AXIS_LABEL_PROP_ABS_HAT0X       "Abs Hat 0 X"
+#define AXIS_LABEL_PROP_ABS_HAT0Y       "Abs Hat 0 Y"
+#define AXIS_LABEL_PROP_ABS_HAT1X       "Abs Hat 1 X"
+#define AXIS_LABEL_PROP_ABS_HAT1Y       "Abs Hat 1 Y"
+#define AXIS_LABEL_PROP_ABS_HAT2X       "Abs Hat 2 X"
+#define AXIS_LABEL_PROP_ABS_HAT2Y       "Abs Hat 2 Y"
+#define AXIS_LABEL_PROP_ABS_HAT3X       "Abs Hat 3 X"
+#define AXIS_LABEL_PROP_ABS_HAT3Y       "Abs Hat 3 Y"
+#define AXIS_LABEL_PROP_ABS_PRESSURE    "Abs Pressure"
+#define AXIS_LABEL_PROP_ABS_DISTANCE    "Abs Distance"
+#define AXIS_LABEL_PROP_ABS_TILT_X      "Abs Tilt X"
+#define AXIS_LABEL_PROP_ABS_TILT_Y      "Abs Tilt Y"
+#define AXIS_LABEL_PROP_ABS_TOOL_WIDTH  "Abs Tool Width"
+#define AXIS_LABEL_PROP_ABS_VOLUME      "Abs Volume"
+#define AXIS_LABEL_PROP_ABS_MT_SLOT     "Abs MT Slot"
+#define AXIS_LABEL_PROP_ABS_MT_TOUCH_MAJOR "Abs MT Touch Major"
+#define AXIS_LABEL_PROP_ABS_MT_TOUCH_MINOR "Abs MT Touch Minor"
+#define AXIS_LABEL_PROP_ABS_MT_WIDTH_MAJOR "Abs MT Width Major"
+#define AXIS_LABEL_PROP_ABS_MT_WIDTH_MINOR "Abs MT Width Minor"
+#define AXIS_LABEL_PROP_ABS_MT_ORIENTATION "Abs MT Orientation"
+#define AXIS_LABEL_PROP_ABS_MT_POSITION_X  "Abs MT Position X"
+#define AXIS_LABEL_PROP_ABS_MT_POSITION_Y  "Abs MT Position Y"
+#define AXIS_LABEL_PROP_ABS_MT_TOOL_TYPE   "Abs MT Tool Type"
+#define AXIS_LABEL_PROP_ABS_MT_BLOB_ID     "Abs MT Blob ID"
+#define AXIS_LABEL_PROP_ABS_MT_TRACKING_ID "Abs MT Tracking ID"
+#define AXIS_LABEL_PROP_ABS_MT_PRESSURE    "Abs MT Pressure"
+#define AXIS_LABEL_PROP_ABS_MT_DISTANCE    "Abs MT Distance"
+#define AXIS_LABEL_PROP_ABS_MT_ANGLE       "Abs MT Angle/MT Component"
+#define AXIS_LABEL_PROP_ABS_MT_PALM        "Abs MT Palm/MT Sumsize"
+#define AXIS_LABEL_PROP_ABS_MISC           "Abs Misc"
+
+
+typedef enum _MTSyncType
+{
+       MTOUCH_FRAME_SYNC_END,
+       MTOUCH_FRAME_SYNC_BEGIN
+} MTSyncType;
+
+typedef enum _EventHandleType
+{
+       PROPAGATE_EVENTS,
+       KEEP_EVENTS,
+       IGNORE_EVENTS
+} EventHandleType;
+
+typedef enum _ErrorStatus
+{
+       ERROR_NONE,
+       ERROR_ABNORMAL,
+       ERROR_INVALPTR,
+       ERROR_EQFULL,
+       ERROR_ALLOCFAIL
+} ErrorStatus;
+
+enum EventType
+{
+    ET_KeyPress = 2,
+    ET_KeyRelease,
+    ET_ButtonPress,
+    ET_ButtonRelease,
+    ET_Motion,
+    /*
+    ...
+    */
+    ET_TouchCancel = 31,
+    ET_MTSync = 0x7E,
+    ET_Internal = 0xFF /* First byte */
+};
+
+struct _DeviceEvent {
+    unsigned char header; /**< Always ET_Internal */
+    enum EventType type;  /**< One of EventType */
+    int length;           /**< Length in bytes */
+    Time time;            /**< Time in ms */
+    int deviceid;         /**< Device to post this event for */
+    int sourceid;         /**< The physical source device */
+    union {
+        uint32_t button;  /**< Button number (also used in pointer emulating
+                               touch events) */
+        uint32_t key;     /**< Key code */
+    } detail;
+    uint32_t touchid;     /**< Touch ID (client_id) */
+    int16_t root_x;       /**< Pos relative to root window in integral data */
+    float root_x_frac;    /**< Pos relative to root window in frac part */
+    int16_t root_y;       /**< Pos relative to root window in integral part */
+    float root_y_frac;    /**< Pos relative to root window in frac part */
+    uint8_t buttons[(MAX_BUTTONS + 7) / 8];  /**< Button mask */
+    struct {
+        uint8_t mask[(MAX_VALUATORS + 7) / 8];/**< Valuator mask */
+        uint8_t mode[(MAX_VALUATORS + 7) / 8];/**< Valuator mode (Abs or Rel)*/
+        double data[MAX_VALUATORS];           /**< Valuator data */
+    } valuators;
+    struct {
+        uint32_t base;    /**< XKB base modifiers */
+        uint32_t latched; /**< XKB latched modifiers */
+        uint32_t locked;  /**< XKB locked modifiers */
+        uint32_t effective;/**< XKB effective modifiers */
+    } mods;
+    struct {
+        uint8_t base;    /**< XKB base group */
+        uint8_t latched; /**< XKB latched group */
+        uint8_t locked;  /**< XKB locked group */
+        uint8_t effective;/**< XKB effective group */
+    } group;
+    Window root;      /**< Root window of the event */
+    int corestate;    /**< Core key/button state BEFORE the event */
+    int key_repeat;   /**< Internally-generated key repeat event */
+    uint32_t flags;   /**< Flags to be copied into the generated event */
+};
+
+typedef struct _AnyEvent AnyEvent;
+struct _AnyEvent
+{
+    unsigned char header; /**< Always ET_Internal */
+    enum EventType type;  /**< One of EventType */
+    int length;           /**< Length in bytes */
+    Time time;            /**< Time in ms */
+    int deviceid;
+    MTSyncType sync;
+    int x;
+    int y;
+};
+
+typedef struct _TouchCancelEvent TouchCancelEvent;
+struct _TouchCancelEvent {
+    unsigned char header; /**< Always ET_Internal */
+    enum EventType type;  /**< ET_TouchOwnership */
+    int length;           /**< Length in bytes */
+    Time time;            /**< Time in ms */
+    int deviceid;         /**< Device to post this event for */
+    int sourceid;         /**< The physical source device */
+    uint32_t resource;    /**< Provoking grab or event selection */
+    uint32_t flags;       /**< Flags to be copied into the generated event */
+};
+
+
+
+union _InternalEvent {
+       struct {
+           unsigned char header; /**< Always ET_Internal */
+           enum EventType type;  /**< One of ET_* */
+           int length;           /**< Length in bytes */
+           Time time;            /**< Time in ms. */
+       } any;
+       AnyEvent any_event;
+       DeviceEvent device_event;
+       TouchCancelEvent touch_cancel_event;
+};
+
+#define wUseDefault(w,field,def)       ((w)->optional ? (w)->optional->field : def)
+#define wBoundingShape(w)      wUseDefault(w, boundingShape, NULL)
+#define wInputShape(w)          wUseDefault(w, inputShape, NULL)
+#define wBorderWidth(w)                ((int) (w)->borderWidth)
+
+/* used as NULL-terminated list */
+typedef struct _DevCursorNode {
+    CursorPtr                   cursor;
+    DeviceIntPtr                dev;
+    struct _DevCursorNode*      next;
+} DevCursNodeRec, *DevCursNodePtr, *DevCursorList;
+
+typedef struct _WindowOpt {
+    VisualID           visual;            /* default: same as parent */
+    CursorPtr          cursor;            /* default: window.cursorNone */
+    Colormap           colormap;          /* default: same as parent */
+    Mask               dontPropagateMask; /* default: window.dontPropagate */
+    Mask               otherEventMasks;   /* default: 0 */
+    struct _OtherClients *otherClients;           /* default: NULL */
+    struct _GrabRec    *passiveGrabs;     /* default: NULL */
+    PropertyPtr                userProps;         /* default: NULL */
+    unsigned long      backingBitPlanes;  /* default: ~0L */
+    unsigned long      backingPixel;      /* default: 0 */
+    RegionPtr          boundingShape;     /* default: NULL */
+    RegionPtr          clipShape;         /* default: NULL */
+    RegionPtr          inputShape;        /* default: NULL */
+    struct _OtherInputMasks *inputMasks;   /* default: NULL */
+    DevCursorList       deviceCursors;     /* default: NULL */
+} WindowOptRec, *WindowOptPtr;
+
+typedef struct _Window {
+    DrawableRec                drawable;
+    PrivateRec         *devPrivates;
+    WindowPtr          parent;         /* ancestor chain */
+    WindowPtr          nextSib;        /* next lower sibling */
+    WindowPtr          prevSib;        /* next higher sibling */
+    WindowPtr          firstChild;     /* top-most child */
+    WindowPtr          lastChild;      /* bottom-most child */
+    RegionRec          clipList;       /* clipping rectangle for output */
+    RegionRec          borderClip;     /* NotClippedByChildren + border */
+    union _Validate    *valdata;
+    RegionRec          winSize;
+    RegionRec          borderSize;
+    DDXPointRec                origin;         /* position relative to parent */
+    unsigned short     borderWidth;
+    unsigned short     deliverableEvents; /* all masks from all clients */
+    Mask               eventMask;      /* mask from the creating client */
+    PixUnion           background;
+    PixUnion           border;
+    pointer            backStorage;    /* null when BS disabled */
+    WindowOptPtr       optional;
+    unsigned           backgroundState:2; /* None, Relative, Pixel, Pixmap */
+    unsigned           borderIsPixel:1;
+    unsigned           cursorIsNone:1; /* else real cursor (might inherit) */
+    unsigned           backingStore:2;
+    unsigned           saveUnder:1;
+    unsigned           DIXsaveUnder:1;
+    unsigned           bitGravity:4;
+    unsigned           winGravity:4;
+    unsigned           overrideRedirect:1;
+    unsigned           visibility:2;
+    unsigned           mapped:1;
+    unsigned           realized:1;     /* ancestors are all mapped */
+    unsigned           viewable:1;     /* realized && InputOutput */
+    unsigned           dontPropagate:3;/* index into DontPropagateMasks */
+    unsigned           forcedBS:1;     /* system-supplied backingStore */
+    unsigned           redirectDraw:2; /* COMPOSITE rendering redirect */
+    unsigned           forcedBG:1;     /* must have an opaque background */
+#ifdef ROOTLESS
+    unsigned           rootlessUnhittable:1;   /* doesn't hit-test */
+#endif
+} WindowRec;
+
+typedef struct _IEvent {
+       InternalEvent *event;
+       int screen_num;
+       DeviceIntPtr device;
+} IEventRec, *IEventPtr;
+
+enum
+{
+       BTN_RELEASED,
+       BTN_PRESSED,
+       BTN_MOVING
+};
+
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+enum
+{
+       BEZEL_NONE,
+       BEZEL_ON,
+       BEZEL_START,
+       BEZEL_DONE,
+       BEZEL_END
+};
+
+enum
+{
+       NO_BEZEL,
+       BEZEL_TOP_LEFT,
+       BEZEL_TOP_RIGHT,
+       BEZEL_BOTTOM_LEFT,
+       BEZEL_BOTTOM_RIGHT
+};
+#endif
+
+#define PressFlagFlick                 0x01//(1 << 0)
+#define PressFlagPan                           0x02//(1 << 1)
+#define PressFlagPinchRotation 0x04//(1 << 2)
+#define PressFlagTap                           0x08//(1 << 3)
+#define PressFlagTapNHold              0x10//(1 << 4)
+#define PressFlagHold                  0x20//(1 << 5)
+
+#define FlickFilterMask                        0x01//(1 << 0)
+#define PanFilterMask                  0x02//(1 << 1)
+#define PinchRotationFilterMask        0x04//(1 << 2)
+#define TapFilterMask                  0x08//(1 << 3)
+#define TapNHoldFilterMask             0x10//(1 << 4)
+#define HoldFilterMask                 0x20//(1 << 5)
+
+#define GESTURE_FILTER_MASK_ALL        0x3f//(FlickFilterMask | PanFilterMask | PinchRotationFilterMask | TapFilterMask |TapNHoldFilterMask | HoldFilterMask)
+
+#define PalmFlickHorizFilterMask               0x01//(1 << 0)
+#define PalmFlickVertiFilterMask               0x02//(1 << 1)
+
+#define GESTURE_PALM_FILTER_MASK_ALL   0x03//(PalmFlickHorizFilterMask | PalmFlickVertiFilterMask)
+
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+#define BezelFlickFilterMask           0x01//(1 << 0)
+#endif
+
+typedef struct _tagTouchStatus
+{
+       int status;//One of BTN_RELEASED, BTN_PRESSED and BTN_MOVING
+       uint32_t flags;
+
+       int px;         //press x
+       int py;         //press y
+       int mx;         //motion x
+       int my;         //motion y
+       int rx;         //release x
+       int ry;         //release y
+       Time ptime;     //press time
+       Time mtime;     //motion time
+       Time rtime;     //current/previous release time
+} TouchStatus;
+
+typedef struct _tagCurrentTouchStatus
+{
+       int status;//One of BTN_RELEASED, BTN_PRESSED and BTN_MOVING
+
+       int cx;         //current x
+       int cy;         //current y
+} CurTouchStatus;
+
+//palm global
+#define PALM_MIN_TOUCH_MAJOR                           30
+#define PALM_MIN_WIDTH_MAJOR                           40
+#define PALM_MIN_TOUCH_MAJOR_BEZEL                     16
+#define PALM_MIN_WIDTH_MAJOR_BEZEL                     24
+#define PALM_BEZEL                                                     33
+
+//palm flick
+#define PALM_FLICK_INITIAL_TIMEOUT                     300//ms
+#define PALM_FLICK_FALSE_TIMEOUT                       900//ms
+#define PALM_FLICK_DETECT_TIMEOUT                      2000//ms
+#define PALM_HORIZ_ARRAY_COUNT                         4
+#define PALM_VERTI_ARRAY_COUNT                         7
+#define PALM_FLICK_MIN_PALM                                    1
+#define PALM_FLICK_MIN_BASE_WIDTH                      30
+#define PALM_FLICK_HORIZ_MAX_BASE_WIDTH                400
+#define PALM_FLICK_VERTI_MAX_BASE_WIDTH                300
+#define PALM_FALSE_FLICK_BASE_WIDTH                    8
+#define PALM_FLICK_TOUCH_MAJOR                         80
+#define PALM_FLICK_FINGER_MIN_TOUCH_MAJOR      15
+#define PALM_FLICK_HORIZ_MAX_MOVE_Y                    400
+#define PALM_FLICK_VERTI_MAX_MOVE_X                    300
+
+//palm tap
+#define PALM_MIN_MAJOR                                 200
+#define PALM_SGL_TAP_TIMEOUT                   200//ms
+#define PALM_DBL_TAP_TIMEOUT                   300//ms
+#define PALM_TAP_MIN_DEVIATION                 100
+#define PALM_TAP_FALSE_DEVIATION               20
+#define PALM_TAP_FALSE_SIZE                            3
+
+//palm hold
+#define PALM_HOLD_TIME_THRESHOLD                       150
+
+typedef struct _tagPalmTouchInfo
+{
+       int touch_status;//One of BTN_RELEASED, BTN_PRESSED and BTN_MOVING
+
+       int x;
+       int y;
+       double wmajor;//Value of valuator ABS_MT_WIDTH_MAJOR
+       double tmajor;//Value of valuator ABS_MT_TOUCH_MAJOR
+       double tminor;//Value of valuator ABS_MT_TOUCH_MINOR
+       double tangle;//Value of valuator ABS_MT_ANGLE
+       double tpalm;//Value of valuator ABS_MT_PALM
+} PalmTouchInfo, *PalmTouchInfoPtr;
+
+typedef struct _tagQueuedTouchInfo
+{
+       int devid;
+       int pressed;
+}QueuedTouchInfo;
+
+typedef struct _tagPalmStatus
+{
+       int palmflag;
+       double sum_size;
+       double max_eccen;
+       double max_angle;
+       double max_wmajor;
+       double max_tmajor;
+       double max_tminor;
+       double biggest_tmajor;
+       double biggest_wmajor;
+       double bigger_wmajor;
+       int max_size_idx;
+       int max_touched;
+       int cur_touched;
+       double dispersionX;
+       double deviationX;
+       double dispersionY;
+       double deviationY;
+       int cx;
+       int cy;
+       int max_palm;
+       int single_timer_expired;
+
+       OsTimerPtr palm_single_finger_timer;
+       PalmTouchInfo pti[MAX_MT_DEVICES];
+       QueuedTouchInfo qti[MAX_MT_DEVICES+1];
+       pixman_region16_t area;
+       pixman_region16_t finger_rects[MAX_MT_DEVICES];
+} PalmStatus, *PalmStatusPtr;
+
+typedef struct _tagPalmDrvStatus
+{
+       int enabled;
+       int scrn_width;
+       int scrn_height;
+       unsigned int half_scrn_area_size;
+       int horiz_coord[PALM_HORIZ_ARRAY_COUNT];
+       int verti_coord[PALM_VERTI_ARRAY_COUNT];
+} PalmMiscInfo, *PalmMiscInfoPtr;
+
+typedef struct _tagStylusStatus
+{
+       CurTouchStatus t_status[MAX_MT_DEVICES];
+       int stylus_id;
+       Bool pen_detected;
+       Bool fake_events;
+} StylusInfo, *StylusInfoPtr;
+
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+typedef struct _tagBezelStatus
+{
+       int width;
+       int height;
+}BezelStatus, *BezelStatusPtr;
+typedef struct _tagBezelFlickStatus
+{
+       int is_active;
+       BezelStatus top_left;
+       BezelStatus top_right;
+       BezelStatus bottom_left;
+       BezelStatus bottom_right;
+       int flick_distance;
+       int bezel_angle_ratio;
+       double min_rad;
+       double max_rad;
+       double min_180_rad;
+       double max_180_rad;
+       int bezel_angle_moving_check;
+       int bezelStatus;
+}BezelFlickStatus, *BezelFlickStatusPtr;
+#endif
+
+typedef struct _GestureDeviceRec
+{
+       char *device;
+       int version;        /* Driver version */
+       OsTimerPtr device_setting_timer;
+
+       int is_active;
+
+       int screen_width;
+       int screen_height;
+
+       int pinchrotation_time_threshold;
+       double pinchrotation_dist_threshold;
+       double pinchrotation_angle_threshold;
+
+       int singlefinger_threshold;
+       int singletap_threshold;
+       int doubletap_threshold;
+
+       int palm_min_touch_major;
+       int palm_min_width_major;
+       int palm_min_touch_major_bezel;
+       int palm_min_width_major_bezel;
+       int palm_bezel;
+
+       int touchkey_id;
+       MTSyncType mtsync_status;
+       StylusInfo stylusInfo;
+       int palm_rejection_mode;
+       Bool palm_detected;
+       Bool no_palm_events;
+
+       int pass_keycodes[NUM_PASSKEYS];
+
+       WindowPtr pRootWin;
+       Window gestureWin;
+       int num_mt_devices;
+
+       Mask grabMask;
+       Mask eventMask;
+       GestureGrabEventPtr GrabEvents;
+       Mask lastSelectedMask;
+       Window lastSelectedWin;
+
+       EventHandleType ehtype;
+       IEventPtr       EQ;
+       int headEQ;
+       int tailEQ;
+
+       int hold_detector_activate;
+       int has_hold_grabmask;
+       pixman_region16_t chold_area;
+       CurTouchStatus cts[MAX_MT_DEVICES];
+       CurTouchStatus last_touches[MAX_MT_DEVICES];
+       Bool touch_cancel_status;
+       Bool hold_detected;
+
+       PalmStatus palm;
+       PalmMiscInfo palm_misc;
+       int wmajor_idx;
+       int tmajor_idx;
+       int tminor_idx;
+       int tangle_idx;
+       int tpalm_idx;
+       int mt_px_idx;
+       int mt_py_idx;
+       int mt_tool_idx;
+
+       pixman_region16_t area;
+       pixman_region16_t finger_rects[MAX_MT_DEVICES];
+
+       WindowPtr pTempWin;
+       WindowPtr pTempPalmWin;
+       int inc_num_pressed;
+
+       int first_fingerid;
+       int num_pressed;
+       int zoom_enabled;
+       int enqueue_fulled;
+       int tap_repeated;
+       TouchStatus fingers[MAX_MT_DEVICES];
+
+       int event_sum[MAX_MT_DEVICES];
+       uint32_t recognized_gesture;
+       uint32_t filter_mask;
+       uint32_t palm_filter_mask;
+       uint32_t recognized_palm;
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+       uint32_t bezel_filter_mask;
+       uint32_t bezel_recognized_mask;
+#endif
+
+       DeviceIntPtr this_device;
+       DeviceIntPtr mt_devices[MAX_MT_DEVICES];
+       DeviceIntPtr master_pointer;
+       DeviceIntPtr xtest_pointer;
+#ifdef _F_SUPPORT_BEZEL_FLICK_
+       BezelFlickStatus bezel;
+#endif
+    WindowPtr anr_window;
+
+    int stylus_able;
+    int support_palm;
+} GestureDeviceRec, *GestureDevicePtr ;
+
+#endif//_GESTURE_H_
similarity index 100%
rename from xorg-gesture.pc.in
rename to mobile/xorg-gesture.pc.in
index 5d11fd2..aac856c 100644 (file)
@@ -1,8 +1,9 @@
 #sbs-git:slp/pkgs/xorg/driver/xserver-xorg-input-gesture xorg-x11-drv-gesture 0.1.0 fb1092a8ea453d658b38d5c28e67a58462d7c931
 Name:  xorg-x11-drv-gesture
 Summary:    X.Org X server -- Xserver gesture driver
-Version: 0.1.0
-Release:    4
+Version: 0.1.60
+Release:    1
+VCS:        adaptation/xorg/driver/xserver-xorg-input-gesture#xorg-x11-drv-gesture-0.1.2-8-6-g7c67de9af10190753599a01144e865bf0a341604
 Group:      System/X Hardware Support
 License:    MIT
 Source0:    %{name}-%{version}.tar.gz
@@ -12,6 +13,10 @@ BuildRequires:  pkgconfig(xproto)
 BuildRequires:  pkgconfig(inputproto)
 BuildRequires:  pkgconfig(resourceproto)
 BuildRequires:  pkgconfig(xorg-macros)
+BuildRequires:  pkgconfig(dlog)
+%if "%{?tizen_profile_name}" == "mobile"
+BuildRequires:  pkgconfig(xdbg)
+%endif
 
 %description
  This package provides the driver for recognizing gesture(s) using button
@@ -26,27 +31,40 @@ Requires:   %{name} = %{version}-%{release}
 %description devel
 xorg-x11-drv-gesture development files
 
-
 %prep
 %setup -q
 
 %build
 
-autoreconf -vfi
-./configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info CFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS"
-#./configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info CFLAGS="$CFLAGS -D__DETAIL_DEBUG__ -D__DEBUG_EVENT_HANDLER__ " LDFLAGS="$LDFLAGS"
+%if "%{?tizen_profile_name}" == "wearable"
+cd wearable
+%else
+cd mobile
+%endif
+
+#%autogen -ivf
+%reconfigure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info CFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS"
 
 make %{?jobs:-j%jobs}
 
 %install
+
+%if "%{?tizen_profile_name}" == "wearable"
+cd wearable
+%else
+cd mobile
+%endif
+
 rm -rf %{buildroot}
+mkdir -p %{buildroot}/usr/share/license
+cp -af COPYING %{buildroot}/usr/share/license/%{name}
 %make_install
 
 %remove_docs
 
 %files
 %{_libdir}/xorg/modules/input/gesture_drv.so
+/usr/share/license/%{name}
 
 %files devel
 %{_libdir}/pkgconfig/xorg-gesture.pc
-
diff --git a/src/Makefile.am b/src/Makefile.am
deleted file mode 100644 (file)
index 902f7ad..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#  Copyright 2005 Adam Jackson.
-#
-#  Permission is hereby granted, free of charge, to any person obtaining a
-#  copy of this software and associated documentation files (the "Software"),
-#  to deal in the Software without restriction, including without limitation
-#  on the rights to use, copy, modify, merge, publish, distribute, sub
-#  license, and/or sell copies of the Software, and to permit persons to whom
-#  the Software is furnished to do so, subject to the following conditions:
-#
-#  The above copyright notice and this permission notice (including the next
-#  paragraph) shall be included in all copies or substantial portions of the
-#  Software.
-#
-#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-#  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-#  FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
-#  ADAM JACKSON BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-#  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-#  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-# this is obnoxious:
-# -module lets us name the module exactly how we want
-# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
-# _ladir passes a dummy rpath to libtool so the thing will actually link
-# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
-AM_CFLAGS = $(XORG_CFLAGS)
-
-@DRIVER_NAME@_drv_la_LTLIBRARIES = @DRIVER_NAME@_drv.la
-@DRIVER_NAME@_drv_la_LDFLAGS = -module -avoid-version
-@DRIVER_NAME@_drv_ladir = @inputdir@
-
-INCLUDES=-I$(top_srcdir)/include/
-
-@DRIVER_NAME@_drv_la_SOURCES = @DRIVER_NAME@.c \
-                               @DRIVER_NAME@.h 
-
diff --git a/src/gesture.c b/src/gesture.c
deleted file mode 100755 (executable)
index fa3928a..0000000
+++ /dev/null
@@ -1,2883 +0,0 @@
-/**************************************************************************
-
-xserver-xorg-input-gesture
-
-Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
-
-Contact: Sung-Jin Park <sj76.park@samsung.com>
-         Sangjin LEE <lsj119@samsung.com>
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sub license, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <linux/input.h>
-#include <linux/types.h>
-
-#include <xf86_OSproc.h>
-
-#include <unistd.h>
-
-#include <xf86.h>
-#include <xf86Xinput.h>
-#include <exevents.h>
-#include <xorgVersion.h>
-#include <xkbsrv.h>
-
-#ifdef HAVE_PROPERTIES
-#include <X11/Xatom.h>
-#include <xserver-properties.h>
-/* 1.6 has properties, but no labels */
-#ifdef AXIS_LABEL_PROP
-#define HAVE_LABELS
-#else
-#undef HAVE_LABELS
-#endif
-
-#endif
-
-#include <stdio.h>
-#include <sys/stat.h>
-#include <sys/syscall.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <xorg-server.h>
-#include <xorgVersion.h>
-#include <xf86Module.h>
-#include <X11/Xatom.h>
-#include "gesture.h"
-#include <xorg/mi.h>
-
-//Basic functions
-static InputInfoPtr GesturePreInit(InputDriverPtr  drv, InputInfoPtr pInfo, int flags);
-static void GestureUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags);
-static pointer GesturePlug(pointer module, pointer options, int *errmaj, int  *errmin);
-static void GestureUnplug(pointer p);
-static int GestureControl(DeviceIntPtr    device,int what);
-static int GestureInit(DeviceIntPtr device);
-static void GestureFini(DeviceIntPtr device);
-static void GestureReadInput(InputInfoPtr pInfo);
-
-//other initializers
-ErrorStatus GestureRegionsInit(void);
-
-//event queue handling functions
-ErrorStatus GestureInitEQ(void);
-ErrorStatus GestureFiniEQ(void);
-ErrorStatus GestureEnqueueEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
-ErrorStatus GestureEventsFlush(void);
-void GestureEventsDrop(void);
-
-//utility functions
-ErrorStatus GestureRegionsReinit(void);
-void GestureSetDisable(InputInfoPtr pInfo, int enable);
-WindowPtr GestureGetEventsWindow(void);
-
-//Enqueued event handlers and enabler/disabler
-static ErrorStatus GestureEnableEventHandler(InputInfoPtr pInfo);
-static ErrorStatus GestureDisableEventHandler(void);
-static CARD32 GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg);
-static CARD32 GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg);
-void GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
-void GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
-void GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
-void GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
-
-//Gesture recognizer helper
-static Bool PointInBorderSize(WindowPtr pWin, int x, int y);
-static WindowPtr GestureWindowOnXY(int x, int y);
-Bool GestureHasFingerEventMask(int eventType, int num_finger);
-static double get_angle(int x1, int y1, int x2, int y2);
-
-//Gesture recognizer and handlers
-void GestureRecognize_GroupPinchRotation(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
-void GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx);
-void GestureRecognize_GroupPan(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
-void GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
-void GestureRecognize_GroupTapNHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
-void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
-void GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int direction);
-void GestureHandleGesture_Tap(int num_finger, int tap_repeat, int cx, int cy);
-void GestureHandleGesture_PinchRotation(int num_of_fingers, double zoom, double angle, int distance, int cx, int cy, int kinds);
-void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds);
-void GestureHandleGesture_TapNHold(int num_fingers, int cx, int cy, Time interval, Time holdtime, int kinds);
-void GestureHandleGesture_Pan(int num_fingers, short int dx, short int dy, int direction, int distance, Time duration, int kinds);
-void GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device);
-ErrorStatus GestureFlushOrDrop(void);
-
-#ifdef HAVE_PROPERTIES
-//function related property handling
-static void GestureInitProperty(DeviceIntPtr dev);
-static int GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, BOOL checkonly);
-#endif
-
-static Atom prop_gesture_recognizer_onoff = None;
-
-GestureDevicePtr g_pGesture = NULL;
-_X_EXPORT InputDriverRec GESTURE = {
-    1,
-    "gesture",
-    NULL,
-    GesturePreInit,
-    GestureUnInit,
-    NULL,
-    0
-};
-
-static XF86ModuleVersionInfo GestureVersionRec =
-{
-    "gesture",
-    MODULEVENDORSTRING,
-    MODINFOSTRING1,
-    MODINFOSTRING2,
-    XORG_VERSION_CURRENT,
-    PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR,
-    PACKAGE_VERSION_PATCHLEVEL,
-    ABI_CLASS_XINPUT,
-    ABI_XINPUT_VERSION,
-    MOD_CLASS_XINPUT,
-    {0, 0, 0, 0}
-};
-
-_X_EXPORT XF86ModuleData gestureModuleData =
-{
-    &GestureVersionRec,
-    &GesturePlug,
-    &GestureUnplug
-};
-
-static Bool
-PointInBorderSize(WindowPtr pWin, int x, int y)
-{
-    BoxRec box;
-    if( pixman_region_contains_point (&pWin->borderSize, x, y, &box) )
-       return TRUE;
-
-    return FALSE;
-}
-
-static WindowPtr
-GestureWindowOnXY(int x, int y)
-{
-    WindowPtr pWin;
-    BoxRec box;
-    SpritePtr pSprite;
-    DeviceIntPtr pDev = g_pGesture->master_pointer;
-
-    pSprite = pDev->spriteInfo->sprite;
-    pSprite->spriteTraceGood = 1;      /* root window still there */
-    pWin = RootWindow(pDev)->firstChild;
-
-    while (pWin)
-    {
-       if ((pWin->mapped) &&
-           (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
-           (x < pWin->drawable.x + (int)pWin->drawable.width +
-            wBorderWidth(pWin)) &&
-           (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
-           (y < pWin->drawable.y + (int)pWin->drawable.height +
-            wBorderWidth (pWin))
-           /* When a window is shaped, a further check
-            * is made to see if the point is inside
-            * borderSize
-            */
-           && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
-           && (!wInputShape(pWin) ||
-               RegionContainsPoint(wInputShape(pWin),
-                                   x - pWin->drawable.x,
-                                   y - pWin->drawable.y, &box))
-#ifdef ROOTLESS
-    /* In rootless mode windows may be offscreen, even when
-     * they're in X's stack. (E.g. if the native window system
-     * implements some form of virtual desktop system).
-     */
-               && !pWin->rootlessUnhittable
-#endif
-           )
-       {
-           if (pSprite->spriteTraceGood >= pSprite->spriteTraceSize)
-           {
-               pSprite->spriteTraceSize += 10;
-               pSprite->spriteTrace = realloc(pSprite->spriteTrace,
-                                   pSprite->spriteTraceSize*sizeof(WindowPtr));
-           }
-           pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin;
-           pWin = pWin->firstChild;
-       }
-       else
-           pWin = pWin->nextSib;
-    }
-    return pSprite->spriteTrace[pSprite->spriteTraceGood-1];
-}
-
-Bool
-GestureHasFingerEventMask(int eventType, int num_finger)
-{
-       Bool ret = FALSE;
-       Mask eventmask = (1L << eventType);
-
-       if( (g_pGesture->grabMask & eventmask) &&
-               (g_pGesture->GrabEvents[eventType].pGestureGrabWinInfo[num_finger].window != None) )
-       {
-#ifdef __DETAIL_DEBUG__
-               ErrorF("[X11][GestureHasFingerEventMask] TRUE !! Has grabMask\n");
-#endif//__DETAIL_DEBUG__
-               return TRUE;
-       }
-
-       if( g_pGesture->eventMask & eventmask )
-       {
-#ifdef __DETAIL_DEBUG__
-               ErrorF("[X11][GestureHasFingerEventMask] TRUE !! Has eventMask\n");
-#endif//__DETAIL_DEBUG__
-               return TRUE;
-       }
-
-#ifdef __DETAIL_DEBUG__
-       ErrorF("[X11][GestureHasFingerEventMask] FALSE !! eventType=%d, num_finger=%d\n", eventType, num_finger);
-#endif//__DETAIL_DEBUG__
-
-       return ret;
-}
-
-static double
-get_angle(int x1, int y1, int x2, int y2)
-{
-   double a, xx, yy;
-   xx = fabs(x2 - x1);
-   yy = fabs(y2 - y1);
-
-   if (((int) xx) && ((int) yy))
-     {
-        a = atan(yy / xx);
-        if (x1 < x2)
-          {
-             if (y1 < y2)
-               {
-                  return (RAD_360DEG - a);
-               }
-             else
-               {
-                  return (a);
-               }
-          }
-        else
-          {
-             if (y1 < y2)
-               {
-                  return (RAD_180DEG + a);
-               }
-             else
-               {
-                  return (RAD_180DEG - a);
-               }
-          }
-     }
-
-   if (((int) xx))
-     {  /* Horizontal line */
-        if (x2 < x1)
-          {
-             return (RAD_180DEG);
-          }
-        else
-          {
-             return (0.0);
-          }
-     }
-
-   /* Vertical line */
-   if (y2 < y1)
-     {
-        return (RAD_90DEG);
-     }
-   else
-     {
-        return (RAD_270DEG);
-     }
-}
-
-void
-GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int direction)
-{
-       Window target_win;
-       WindowPtr target_pWin;
-       xGestureNotifyFlickEvent fev;
-
-#ifdef __DETAIL_DEBUG__
-       ErrorF("[X11][GestureHandleGesture_Flick] num_fingers=%d, distance=%d, duration=%d, direction=%d\n",
-               num_of_fingers, distance, duration, direction);
-#endif//__DETAIL_DEBUG__
-
-       g_pGesture->recognized_gesture |= FlickFilterMask;
-       memset(&fev, 0, sizeof(xGestureNotifyFlickEvent));
-       fev.type = GestureNotifyFlick;
-       fev.kind = GestureDone;
-       fev.num_finger = num_of_fingers;
-       fev.distance = distance;
-       fev.duration = duration;
-       fev.direction = direction;
-
-       target_win = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].window;
-       target_pWin = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].pWin;
-
-       if( g_pGesture->grabMask && (target_win != None) )
-       {
-               fev.window = target_win;
-       }
-       else
-       {
-               fev.window = g_pGesture->gestureWin;
-       }
-
-#ifdef __DETAIL_DEBUG__
-       ErrorF("[X11][GestureHandleGesture_Flick] fev.window=0x%x, g_pGesture->grabMask=0x%x\n", fev.window, g_pGesture->grabMask);
-#endif//__DETAIL_DEBUG__
-
-       GestureSendEvent(target_pWin, GestureNotifyFlick, GestureFlickMask, (xGestureCommonEvent *)&fev);
-}
-
-void
-GestureHandleGesture_Tap(int num_finger, int tap_repeat, int cx, int cy)
-{
-       Window target_win;
-       WindowPtr target_pWin;
-       xGestureNotifyTapEvent tev;
-
-       //skip non-tap events and single finger tap
-       if( !tap_repeat || num_finger <= 1 )
-               return;
-
-#ifdef __DETAIL_DEBUG__
-       ErrorF("[X11][GestureHandleGesture_Tap] num_finger=%d, tap_repeat=%d, cx=%d, cy=%d\n",
-               num_finger, tap_repeat, cx, cy);
-#endif//__DETAIL_DEBUG__
-
-       g_pGesture->recognized_gesture |= TapFilterMask;
-       memset(&tev, 0, sizeof(xGestureNotifyTapEvent));
-       tev.type = GestureNotifyTap;
-       tev.kind = GestureDone;
-       tev.num_finger = num_finger;
-       tev.tap_repeat = tap_repeat;
-       tev.interval = 0;
-       tev.cx = cx;
-       tev.cy = cy;
-
-       target_win = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].window;
-       target_pWin = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].pWin;
-
-       if( g_pGesture->grabMask && (target_win != None) )
-       {
-               tev.window = target_win;
-       }
-       else
-       {
-               tev.window = g_pGesture->gestureWin;
-       }
-
-#ifdef __DETAIL_DEBUG__
-       ErrorF("[X11][GestureHandleGesture_Tap] tev.window=0x%x, g_pGesture->grabMask=0x%x\n", tev.window, g_pGesture->grabMask);
-#endif//__DETAIL_DEBUG__
-
-       GestureSendEvent(target_pWin, GestureNotifyTap, GestureTapMask, (xGestureCommonEvent *)&tev);
-}
-
-void GestureHandleGesture_PinchRotation(int num_of_fingers, double zoom, double angle, int distance, int cx, int cy, int kinds)
-{
-       Window target_win;
-       WindowPtr target_pWin;
-       xGestureNotifyPinchRotationEvent prev;
-
-#ifdef __DETAIL_DEBUG__
-       ErrorF("[X11][GestureHandleGesture_PinchRotation] num_fingers=%d, zoom=%.2f, angle=%.2f(deg=%.2f), distance=%d, cx=%d, cy=%d\n",
-                               num_of_fingers, zoom, angle, rad2degree(angle), distance, cx, cy);
-#endif//__DETAIL_DEBUG__
-
-       g_pGesture->recognized_gesture |= PinchRotationFilterMask;
-       memset(&prev, 0, sizeof(xGestureNotifyPinchRotationEvent));
-       prev.type = GestureNotifyPinchRotation;
-       prev.kind = kinds;
-       prev.num_finger = num_of_fingers;
-       prev.zoom = XDoubleToFixed(zoom);
-       prev.angle = XDoubleToFixed(angle);
-       prev.distance = distance;
-       prev.cx = cx;
-       prev.cy = cy;
-
-       target_win = g_pGesture->GrabEvents[GestureNotifyPinchRotation].pGestureGrabWinInfo[num_of_fingers].window;
-       target_pWin = g_pGesture->GrabEvents[GestureNotifyPinchRotation].pGestureGrabWinInfo[num_of_fingers].pWin;
-
-       if( g_pGesture->grabMask && (target_win != None) )
-       {
-               prev.window = target_win;
-       }
-       else
-       {
-               prev.window = g_pGesture->gestureWin;
-       }
-
-#ifdef __DETAIL_DEBUG__
-       ErrorF("[X11][GestureHandleGesture_PinchRotation] prev.window=0x%x, g_pGesture->grabMask=0x%x\n", (unsigned int)prev.window, (unsigned int)g_pGesture->grabMask);
-#endif//__DETAIL_DEBUG__
-
-       GestureSendEvent(target_pWin, GestureNotifyPinchRotation, GesturePinchRotationMask, (xGestureCommonEvent *)&prev);
-}
-
-void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds)
-{
-       Window target_win;
-       WindowPtr target_pWin;
-       xGestureNotifyHoldEvent hev;
-
-#ifdef __DETAIL_DEBUG__
-       ErrorF("[X11][GestureHandleGesture_Hold] num_fingers=%d, cx=%d, cy=%d, holdtime=%d, kinds=%d\n",
-                               num_fingers, cx, cy, holdtime, kinds);
-#endif//__DETAIL_DEBUG__
-
-       g_pGesture->recognized_gesture |= HoldFilterMask;
-       memset(&hev, 0, sizeof(xGestureNotifyHoldEvent));
-       hev.type = GestureNotifyHold;
-       hev.kind = kinds;
-       hev.num_finger = num_fingers;
-       hev.holdtime = holdtime;
-       hev.cx = cx;
-       hev.cy = cy;
-
-       target_win = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].window;
-       target_pWin = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].pWin;
-
-       if( g_pGesture->grabMask && (target_win != None) )
-       {
-               hev.window = target_win;
-       }
-       else
-       {
-               hev.window = g_pGesture->gestureWin;
-       }
-
-#ifdef __DETAIL_DEBUG__
-       ErrorF("[X11][GestureHandleGesture_Hold] hev.window=0x%x, g_pGesture->grabMask=0x%x\n", hev.window, g_pGesture->grabMask);
-#endif//__DETAIL_DEBUG__
-
-       GestureSendEvent(target_pWin, GestureNotifyHold, GestureHoldMask, (xGestureCommonEvent *)&hev);
-}
-
-void GestureHandleGesture_TapNHold(int num_fingers, int cx, int cy, Time interval, Time holdtime, int kinds)
-{
-       Window target_win;
-       WindowPtr target_pWin;
-       xGestureNotifyTapNHoldEvent thev;
-
-#ifdef __DETAIL_DEBUG__
-       ErrorF("[X11][GestureHandleGesture_TapNHold] num_fingers=%d, cx=%d, cy=%d, interval=%d, holdtime=%d, kinds=%d\n",
-                               num_fingers, cx, cy, interval, holdtime, kinds);
-#endif//__DETAIL_DEBUG__
-
-       g_pGesture->recognized_gesture |= TapNHoldFilterMask;
-       memset(&thev, 0, sizeof(xGestureNotifyTapNHoldEvent));
-       thev.type = GestureNotifyTapNHold;
-       thev.kind = kinds;
-       thev.num_finger = num_fingers;
-       thev.holdtime = holdtime;
-       thev.cx = cx;
-       thev.cy = cy;
-       thev.interval = interval;
-
-       target_win = g_pGesture->GrabEvents[GestureNotifyTapNHold].pGestureGrabWinInfo[num_fingers].window;
-       target_pWin = g_pGesture->GrabEvents[GestureNotifyTapNHold].pGestureGrabWinInfo[num_fingers].pWin;
-
-       if( g_pGesture->grabMask && (target_win != None) )
-       {
-               thev.window = target_win;
-       }
-       else
-       {
-               thev.window = g_pGesture->gestureWin;
-       }
-
-#ifdef __DETAIL_DEBUG__
-       ErrorF("[X11][GestureHandleGesture_TapNHold] thev.window=0x%x, g_pGesture->grabMask=0x%x\n", thev.window, g_pGesture->grabMask);
-#endif//__DETAIL_DEBUG__
-
-       GestureSendEvent(target_pWin, GestureNotifyTapNHold, GestureTapNHoldMask, (xGestureCommonEvent *)&thev);
-}
-
-void GestureHandleGesture_Pan(int num_fingers, short int dx, short int dy, int direction, int distance, Time duration, int kinds)
-{
-       Window target_win;
-       WindowPtr target_pWin;
-       xGestureNotifyPanEvent pev;
-
-#ifdef __DETAIL_DEBUG__
-       ErrorF("[X11][GestureHandleGesture_Pan] num_fingers=%d, dx=%d, dy=%d, direction=%d, distance=%d, duration=%d, kinds=%d\n",
-                               num_fingers, dx, dy, direction, distance, duration, kinds);
-#endif//__DETAIL_DEBUG__
-
-       g_pGesture->recognized_gesture |= PanFilterMask;
-       memset(&pev, 0, sizeof(xGestureNotifyPanEvent));
-       pev.type = GestureNotifyPan;
-       pev.kind = kinds;
-       pev.num_finger = num_fingers;
-       pev.direction = direction;
-       pev.distance = distance;
-       pev.duration = duration;
-       pev.dx = dx;
-       pev.dy = dy;
-
-       target_win = g_pGesture->GrabEvents[GestureNotifyPan].pGestureGrabWinInfo[num_fingers].window;
-       target_pWin = g_pGesture->GrabEvents[GestureNotifyPan].pGestureGrabWinInfo[num_fingers].pWin;
-
-       if( g_pGesture->grabMask && (target_win != None) )
-       {
-               pev.window = target_win;
-       }
-       else
-       {
-               pev.window = g_pGesture->gestureWin;
-       }
-
-#ifdef __DETAIL_DEBUG__
-       ErrorF("[X11][GestureHandleGesture_Pan] pev.window=0x%x, g_pGesture->grabMask=0x%x\n", pev.window, g_pGesture->grabMask);
-#endif//__DETAIL_DEBUG__
-
-       GestureSendEvent(target_pWin, GestureNotifyPan, GesturePanMask, (xGestureCommonEvent *)&pev);
-}
-
-void
-GestureRecognize_GroupPinchRotation(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
-{
-       static int cx, cy;
-
-       static int num_pressed = 0;
-       static int state = GestureEnd;
-       static int event_type = GestureNotifyPinchRotation;
-       static OsTimerPtr pinchrotation_event_timer = NULL;
-
-       static pixman_region16_t base_area;
-       static pixman_region16_t cur_area;
-
-       static double base_distance = 0.0f;
-       static double base_angle = 0.0f;
-
-       static double prev_distance = 0.0f;
-       static double prev_angle = 0.0f;
-
-       static double cur_distance = 0.0f;
-       static double cur_angle = 0.0f;
-
-       double diff_distance = 0.0f;
-       double diff_angle = 0.0f;
-
-       static int has_event_mask = 0;
-
-       static Time base_time = 0;
-       Time current_time;
-
-       if( timer_expired )
-       {
-               if( state == GestureEnd )
-               {
-                       current_time = GetTimeInMillis();
-                       if( (current_time - base_time) >= PINCHROTATION_TIME_THRESHOLD )
-                       {
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupPinchRotation][Timer] You must move farther than dist threshold(=%.2f) or angle threshold(=%2f) within time threshold(=%d) !\n", PINCHROTATION_DIST_THRESHOLD, PINCHROTATION_ANGLE_THRESHOLD, PINCHROTATION_TIME_THRESHOLD);
-#endif//__DETAIL_DEBUG__
-                               goto cleanup_pinchrotation;
-                       }
-               }
-
-               return;
-       }
-
-       switch( type )
-       {
-               case ET_ButtonPress:
-                       g_pGesture->fingers[idx].flags |= PressFlagPinchRotation;
-
-                       if( g_pGesture->num_pressed < 2 )
-                               return;
-
-                       if( g_pGesture->num_pressed < num_pressed && state != GestureEnd )
-                       {
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupPinchRotation][P][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
-#endif//__DETAIL_DEBUG__
-                               goto cleanup_pinchrotation;
-                       }
-
-                       if( base_distance == 0.0f && g_pGesture->num_pressed == 2 )
-                       {
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupPinchRotation][First Time !!!] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
-#endif//__DETAIL_DEBUG__
-
-                               base_time = GetTimeInMillis();
-                               pixman_region_init(&base_area);
-                               pixman_region_union(&base_area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[1]);
-
-                               prev_distance = base_distance = AREA_DIAG_LEN(&base_area.extents);
-
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupPinchRotation][P] x1=%d, x2=%d, y1=%d, y2=%d\n", g_pGesture->fingers[0].px, g_pGesture->fingers[1].px,
-                               g_pGesture->fingers[0].py, g_pGesture->fingers[1].py);
-#endif//__DETAIL_DEBUG__
-
-                               prev_angle = base_angle = get_angle(g_pGesture->fingers[0].px, g_pGesture->fingers[0].py, g_pGesture->fingers[1].px, g_pGesture->fingers[1].py);
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupPinchRotation][P] base_angle=%.2f(deg=%.2f)\n", base_angle, rad2degree(base_angle));
-#endif//__DETAIL_DEBUG__
-                               event_type = GestureNotifyPinchRotation;
-                               pinchrotation_event_timer = TimerSet(pinchrotation_event_timer, 0, PINCHROTATION_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
-                       }
-                       num_pressed = g_pGesture->num_pressed;
-
-#ifdef __DETAIL_DEBUG__
-                       ErrorF("[GroupPinchRotation][P][num_pressed=%d] AREA_SIZE(base_area.extents)=%d\n", num_pressed, AREA_SIZE(&base_area.extents));
-                       ErrorF("[GroupPinchRotation][P][num_pressed=%d] base_distance=%.2f, base_angle=%.2f(deg=%.2f)\n", num_pressed, base_distance, base_angle, rad2degree(base_angle));
-#endif//__DETAIL_DEBUG__
-                       break;
-
-               case ET_Motion:
-                       if( !(g_pGesture->fingers[idx].flags & PressFlagPinchRotation) )
-                               break;
-
-                       if( (num_pressed != g_pGesture->num_pressed) && (state != GestureEnd) )
-                       {
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupPinchRotation][M][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
-#endif//__DETAIL_DEBUG__
-                               goto cleanup_pinchrotation;
-                       }
-
-                       if( num_pressed < 2 )
-                               return;
-
-                       if( g_pGesture->fingers[0].mx && g_pGesture->fingers[0].my && g_pGesture->fingers[1].mx && g_pGesture->fingers[1].my )
-                       {
-                               pixman_region_init(&cur_area);
-                               pixman_region_union(&cur_area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[1]);
-
-                               cur_distance = AREA_DIAG_LEN(&cur_area.extents);
-
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupPinchRotation][M] x1=%d, x2=%d, y1=%d, y2=%d\n", g_pGesture->fingers[0].mx, g_pGesture->fingers[1].mx,
-                               g_pGesture->fingers[0].my, g_pGesture->fingers[1].my);
-#endif//__DETAIL_DEBUG__
-
-                               cur_angle = get_angle(g_pGesture->fingers[0].mx, g_pGesture->fingers[0].my, g_pGesture->fingers[1].mx, g_pGesture->fingers[1].my);
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupPinchRotation][M] cur_angle=%.2f(deg=%.2f)\n", cur_angle, rad2degree(cur_angle));
-#endif//__DETAIL_DEBUG__
-
-                               diff_distance = prev_distance - cur_distance;
-                               diff_angle = prev_angle - cur_angle;
-
-                               cx = AREA_CENTER_X(&cur_area.extents);
-                               cy = AREA_CENTER_Y(&cur_area.extents);
-
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupPinchRotation][M][state=%d] cx=%d, cy=%d\n", state, cx, cy);
-#endif//__DETAIL_DEBUG__
-
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupPinchRotation][M][num_pressed=%d] prev_distance=%.2f, cur_distance=%.2f, diff=%.2f\n", num_pressed, prev_distance, cur_distance, diff_distance);
-                               ErrorF("[GroupPinchRotation][M][num_pressed=%d] prev_angle=%.2f(deg=%.2f), cur_angle=%.2f(deg=%.2f), diff=%.2f(deg=%.2f)\n", num_pressed, prev_angle, rad2degree(prev_angle), cur_angle, rad2degree(cur_angle), diff_angle, rad2degree(diff_angle));
-#endif//__DETAIL_DEBUG__
-
-                               switch( state )
-                               {
-                                       case GestureEnd:
-                                               if( (ABS(diff_distance) >= PINCHROTATION_DIST_THRESHOLD) || (ABS(diff_angle) >= PINCHROTATION_ANGLE_THRESHOLD) )
-                                               {
-#ifdef __DETAIL_DEBUG__
-                                                       if( ABS(diff_distance) >= PINCHROTATION_DIST_THRESHOLD )
-                                                               ErrorF("[GroupPinchRotation][M] zoom changed !\n");
-
-                                                       if( ABS(diff_angle) >= PINCHROTATION_ANGLE_THRESHOLD )
-                                                               ErrorF("[GroupPinchRotation][M] angle changed !\n");
-#endif//__DETAIL_DEBUG__
-
-                                                       TimerCancel(pinchrotation_event_timer);
-                                                       state = GestureBegin;
-                                                       goto gesture_begin_handle;
-                                               }
-                                               break;
-
-                                       case GestureBegin:
-gesture_begin_handle:
-#ifdef __DETAIL_DEBUG__
-                                               ErrorF("[GroupPinchRotation] PINCHROTATION Begin !cx=%d, cy=%d, state=%d\n", cx, cy, state);
-#endif//__DETAIL_DEBUG__
-                                               if( GestureHasFingerEventMask(GestureNotifyPinchRotation, num_pressed) )
-                                               {
-                                                       GestureHandleGesture_PinchRotation(num_pressed, cur_distance / base_distance, (cur_angle > base_angle) ? (cur_angle-base_angle) : (RAD_360DEG + cur_angle - base_angle), cur_distance, cx, cy, GestureBegin);
-                                                       prev_distance = cur_distance;
-                                                       prev_angle = cur_angle;
-                                                       state = GestureUpdate;
-                                                       has_event_mask = 1;
-                                               }
-                                               else
-                                               {
-                                                       has_event_mask = 0;
-                                                       goto cleanup_pinchrotation;
-                                               }
-                                               break;
-
-                                       case GestureUpdate:
-                                               //if( ABS(diff_distance) < PINCHROTATION_DIST_THRESHOLD && ABS(diff_angle) < PINCHROTATION_ANGLE_THRESHOLD )
-                                               //      break;
-
-#ifdef __DETAIL_DEBUG__
-                                               if( ABS(diff_distance) >= PINCHROTATION_DIST_THRESHOLD )
-                                                       ErrorF("[GroupPinchRotation][M] zoom changed !\n");
-
-                                               if( ABS(diff_angle) >= PINCHROTATION_ANGLE_THRESHOLD )
-                                                       ErrorF("[GroupPinchRotation][M] angle changed !\n");
-#endif//__DETAIL_DEBUG__
-
-#ifdef __DETAIL_DEBUG__
-                                               ErrorF("[GroupPinchRotation] PINCHROTATION Update ! cx=%d, cy=%d, state=%d\n", cx, cy, state);
-#endif//__DETAIL_DEBUG__
-                                               GestureHandleGesture_PinchRotation(num_pressed, cur_distance / base_distance, (cur_angle > base_angle) ? (cur_angle-base_angle) : (RAD_360DEG + cur_angle - base_angle), cur_distance, cx, cy, GestureUpdate);
-                                               prev_distance = cur_distance;
-                                               prev_angle = cur_angle;
-                                               break;
-
-                                       case GestureDone:
-                                       default:
-                                               break;
-                               }
-                       }
-                       break;
-
-               case ET_ButtonRelease:
-                       if( state != GestureEnd && num_pressed >= 2)
-                       {
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupPinchRotation][R][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
-#endif//__DETAIL_DEBUG__
-                               goto cleanup_pinchrotation;
-                       }
-
-                       if( g_pGesture->num_pressed )
-                               break;
-
-                       goto cleanup_pinchrotation;
-                       break;
-       }
-
-       return;
-
-cleanup_pinchrotation:
-
-       if(  has_event_mask  && (state == GestureBegin || state == GestureUpdate) )
-       {
-               state = GestureEnd;
-#ifdef __DETAIL_DEBUG__
-               ErrorF("[GroupPinchRotation] PINCHROTATION End ! cx=%d, cy=%d, state=%d\n", cx, cy, state);
-#endif//__DETAIL_DEBUG__
-               GestureHandleGesture_PinchRotation(num_pressed, cur_distance / base_distance, (cur_angle > base_angle) ? (cur_angle-base_angle) : (RAD_360DEG + cur_angle - base_angle), cur_distance, cx, cy, GestureEnd);
-       }
-       else
-       {
-               g_pGesture->recognized_gesture &= ~PinchRotationFilterMask;
-       }
-
-       g_pGesture->filter_mask |= PinchRotationFilterMask;
-
-       if( g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL )
-       {
-#if 1//def __DETAIL_DEBUG__
-               ErrorF("[GroupPinchRotation][cleanup] GestureFlushOrDrop() !\n");
-#endif//__DETAIL_DEBUG__
-
-               if( ERROR_INVALPTR == GestureFlushOrDrop() )
-               {
-                       GestureControl(g_pGesture->this_device, DEVICE_OFF);
-               }
-       }
-
-       prev_distance = base_distance = 0.0f;
-       prev_angle = base_angle = 0.0f;
-       has_event_mask = num_pressed = 0;
-       state = GestureEnd;
-       cx = cy = 0;
-       TimerCancel(pinchrotation_event_timer);
-       return;
-}
-
-void
-GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx)
-{
-       static int num_pressed = 0;
-       static int mbits = 0;
-       static int base_area_size = 0;
-       static Time base_time = 0;
-       static int base_x, base_y;
-       Time current_time;
-       Time duration;
-       int distx, disty;
-       int distance, direction;
-       int area_size;
-       int flicked = 0;
-
-       switch( type )
-       {
-               case ET_ButtonPress:
-                       g_pGesture->fingers[idx].flags |= PressFlagFlick;
-
-                       if( g_pGesture->num_pressed < 2 )
-                               return;
-
-                       if( !base_area_size || g_pGesture->num_pressed > num_pressed )
-                       {
-                               base_area_size = AREA_SIZE(&g_pGesture->area.extents);
-                               base_x = g_pGesture->area.extents.x1;
-                               base_y = g_pGesture->area.extents.y1;
-                               base_time = GetTimeInMillis();
-                       }
-                       num_pressed = g_pGesture->num_pressed;
-
-#ifdef __DETAIL_DEBUG__
-                       ErrorF("[GroupFlick][P]][num_pressed=%d] AREA_SIZE(area.extents)=%d\n", num_pressed, base_area_size);
-#endif//__DETAIL_DEBUG__
-                       break;
-
-               case ET_Motion:
-                       if( !(g_pGesture->fingers[idx].flags & PressFlagFlick ) )
-                               break;
-
-#ifdef __DETAIL_DEBUG__
-                       if( num_pressed > g_pGesture->num_pressed )
-                       {
-                               ErrorF("[GroupFlick][M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
-                               //goto cleanup_flick;
-                       }
-#endif//__DETAIL_DEBUG__
-
-                       if( num_pressed < 2 )
-                               return;
-
-                       mbits |= (1 << idx);
-                       if( mbits == (pow(2, num_pressed)-1) )
-                       {
-                               area_size = AREA_SIZE(&g_pGesture->area.extents);
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[M][num_pressed=%d] AREA_SIZE(area.extents)=%d\n", num_pressed, area_size);
-#endif//__DETAIL_DEBUG__
-                               if( ABS(base_area_size - area_size) >= FLICK_AREA_THRESHOLD )
-                               {
-#ifdef __DETAIL_DEBUG__
-                                       ErrorF("[GroupFlick][M] diff between Area size(=%d) and base area size(=%d) is bigger than threshold(=%d)!\n", area_size, base_area_size, FLICK_AREA_THRESHOLD);
-#endif//__DETAIL_DEBUG__
-                                       goto cleanup_flick;
-                               }
-
-                               current_time = GetTimeInMillis();
-                               if( (current_time - base_time) >= FLICK_AREA_TIMEOUT )
-                               {
-#ifdef __DETAIL_DEBUG__
-                                       ErrorF("[GroupFlick][M] diff between current time(=%d) and base time(=%d) is bigger than threashold(=%d) !\n", current_time, base_time, FLICK_AREA_TIMEOUT);
-#endif//__DETAIL_DEBUG__
-                                       goto cleanup_flick;
-                               }
-                               mbits = 0;
-                       }
-                       break;
-
-               case ET_ButtonRelease:
-                       if( g_pGesture->num_pressed )
-                               break;
-
-                       duration = GetTimeInMillis() - base_time;
-                       distx = g_pGesture->area.extents.x1 - base_x;
-                       disty = g_pGesture->area.extents.y1 - base_y;
-
-#ifdef __DETAIL_DEBUG__
-                       ErrorF("[GroupFlick] duration=%d, distx=%d, disty=%d\n", duration, distx, disty);
-#endif//__DETAIL_DEBUG__
-
-                       if( duration <= 0 || duration >= FLICK_AREA_TIMEOUT )
-                               goto cleanup_flick;
-
-                       if( ABS(distx) >= FLICK_MOVE_THRESHOLD )
-                       {
-                               direction = (distx > 0) ? FLICK_EASTWARD : FLICK_WESTWARD;
-                               distance = ABS(distx);
-                               flicked++;
-                       }
-                       else if( ABS(disty) >= FLICK_MOVE_THRESHOLD )
-                       {
-                               direction = (disty > 0) ? FLICK_SOUTHWARD : FLICK_NORTHWARD;
-                               distance = ABS(disty);
-                               flicked++;
-                       }
-
-                       if( !flicked )
-                               goto cleanup_flick;
-
-                       if( GestureHasFingerEventMask(GestureNotifyFlick, num_pressed) )
-                               GestureHandleGesture_Flick(num_pressed, distance, duration, direction);
-                       goto cleanup_flick_recognized;
-                       break;
-       }
-
-       return;
-
-cleanup_flick:
-
-       g_pGesture->recognized_gesture &= ~FlickFilterMask;
-
-cleanup_flick_recognized:
-
-       g_pGesture->filter_mask |= FlickFilterMask;
-       num_pressed = 0;
-       base_area_size = 0;
-       base_time = 0;
-       mbits = 0;
-       return;
-}
-
-void
-GestureRecognize_GroupPan(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
-{
-       static int num_pressed = 0;
-       static int mbits = 0;
-       static int base_area_size = 0;
-       static Time base_time = 0;
-       static pixman_box16_t base_box_ext;
-       static int base_cx;
-       static int base_cy;
-       static int prev_cx;
-       static int prev_cy;
-       static int cx = 0;
-       static int cy = 0;
-       int dx, dy;
-       static Time prev_time = 0;
-       Time current_time = 0;
-       int distance = 0;
-       int direction = 0;
-       int area_size;
-       static int time_checked = 0;
-       static int state = GestureEnd;
-
-       static OsTimerPtr pan_event_timer = NULL;
-       static int event_type = GestureNotifyPan;
-
-       if( timer_expired )
-       {
-               if( !time_checked )
-               {
-                       current_time = GetTimeInMillis();
-                       if( (current_time - base_time) >= PAN_TIME_THRESHOLD )
-                       {
-                               if( (!cx && !cy) || INBOX(&base_box_ext, cx, cy) )
-                               {
-#ifdef __DETAIL_DEBUG__
-                                       ErrorF("[GroupPan][Timer] You must move farther than move threshold(=%d) within time threshold(=%d) !\n", PAN_MOVE_THRESHOLD*2, PAN_TIME_THRESHOLD);
-#endif//__DETAIL_DEBUG__
-                                       goto cleanup_pan;
-                               }
-                               time_checked = 1;
-                       }
-               }
-               return;
-       }
-
-       switch( type )
-       {
-               case ET_ButtonPress:
-                       g_pGesture->fingers[idx].flags |= PressFlagPan;
-
-                       if( g_pGesture->num_pressed < 2 )
-                               return;
-
-                       if( !base_area_size || g_pGesture->num_pressed > num_pressed )
-                       {
-                               if( state != GestureEnd )
-                               {
-#ifdef __DETAIL_DEBUG__
-                                       ErrorF("[GroupPan][P][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
-#endif//__DETAIL_DEBUG__
-                                       goto cleanup_pan;
-                               }
-                               base_area_size = AREA_SIZE(&g_pGesture->area.extents);
-                               prev_cx = base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
-                               prev_cy = base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
-                               prev_time = base_time = GetTimeInMillis();
-                               base_box_ext.x1 = base_cx-PAN_MOVE_THRESHOLD;
-                               base_box_ext.y1 = base_cy-PAN_MOVE_THRESHOLD;
-                               base_box_ext.x2 = base_cx+PAN_MOVE_THRESHOLD;
-                               base_box_ext.y2 = base_cy+PAN_MOVE_THRESHOLD;
-                               event_type = GestureNotifyPan;
-                               pan_event_timer = TimerSet(pan_event_timer, 0, PAN_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
-                       }
-                       num_pressed = g_pGesture->num_pressed;
-
-#ifdef __DETAIL_DEBUG__
-                       ErrorF("[GroupPan][P][num_pressed=%d] AREA_SIZE(area.extents)=%d, base_cx=%d, base_cy=%d\n", num_pressed, base_area_size, base_cx, base_cy);
-#endif//__DETAIL_DEBUG__
-                       break;
-
-               case ET_Motion:
-                       if( !(g_pGesture->fingers[idx].flags & PressFlagPan ) )
-                               break;
-
-                       if( num_pressed != g_pGesture->num_pressed )
-                       {
-                               if( state != GestureEnd )
-                               {
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupPan][M][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
-#endif//__DETAIL_DEBUG__
-                                       goto cleanup_pan;
-                               }
-                       }
-
-                       if( num_pressed < 2 )
-                               return;
-
-                       mbits |= (1 << idx);
-                       if( mbits == (pow(2, num_pressed)-1) )
-                       {
-                               area_size = AREA_SIZE(&g_pGesture->area.extents);
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupPan][M][num_pressed=%d] area_size=%d, base_area_size=%d, diff=%d\n", num_pressed, area_size, base_area_size, ABS(base_area_size - area_size));
-#endif//__DETAIL_DEBUG__
-
-                               if( (state != GestureUpdate) && (ABS(base_area_size - area_size) >= PAN_AREA_THRESHOLD) )
-                               {
-#ifdef __DETAIL_DEBUG__
-                                       ErrorF("[GroupPan][M] diff between area size(=%d) and base area size(=%d) is bigger than threshold(=%d)!\n", area_size, base_area_size, PAN_AREA_THRESHOLD);
-#endif//__DETAIL_DEBUG__
-                                       goto cleanup_pan;
-                               }
-
-                               cx = AREA_CENTER_X(&g_pGesture->area.extents);
-                               cy = AREA_CENTER_Y(&g_pGesture->area.extents);
-
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupPan][M] cx=%d, prev_cx=%d, diff=%d\n", cx, prev_cx, ABS(cx-prev_cx));
-                               ErrorF("[GroupPan][M] cy=%d, prev_cy=%d, diff=%d\n", cy, prev_cy, ABS(cy-prev_cy));
-#endif//__DETAIL_DEBUG__
-
-                               if( !time_checked )
-                               {
-                                       current_time = GetTimeInMillis();
-                                       if( (current_time - base_time) >= PAN_TIME_THRESHOLD )
-                                       {
-                                               if( INBOX(&base_box_ext, cx, cy) )
-                                               {
-#ifdef __DETAIL_DEBUG__
-                                                       ErrorF("[GroupPan][M] You must move farther than move threshold(=%d) within time threshold(=%d) !\n", PAN_MOVE_THRESHOLD*2, PAN_TIME_THRESHOLD);
-#endif//__DETAIL_DEBUG__
-                                                       goto cleanup_pan;
-                                               }
-                                               time_checked = 1;
-                                       }
-                               }
-
-                               if( time_checked )
-                               {
-                                       if( state <= GestureBegin )
-                                       {
-                                               base_box_ext.x1 = prev_cx-PAN_MOVE_THRESHOLD;
-                                               base_box_ext.y1 = prev_cy-PAN_MOVE_THRESHOLD;
-                                               base_box_ext.x2 = prev_cx+PAN_MOVE_THRESHOLD;
-                                               base_box_ext.y2 = prev_cy+PAN_MOVE_THRESHOLD;
-
-                                               if( !INBOX(&base_box_ext, cx, cy) )
-                                               {
-                                                       current_time = GetTimeInMillis();
-#ifdef __DETAIL_DEBUG__
-                                                       ErrorF("[GroupPan] PAN Begin !dx=%d, dy=%d, state=%d\n", prev_cx, prev_cy, state);
-#endif//__DETAIL_DEBUG__
-                                                       if( GestureHasFingerEventMask(GestureNotifyPan, num_pressed) )
-                                                       {
-                                                               GestureHandleGesture_Pan(num_pressed, prev_cx, prev_cy, direction, distance, current_time-prev_time, GestureBegin);
-                                                               state = GestureUpdate;
-                                                       }
-                                                       else
-                                                               goto cleanup_pan;
-                                               }
-                                       }
-                                       else
-                                       {
-                                               dx = cx-prev_cx;
-                                               dy = cy-prev_cy;
-                                               //if( ABS(dx) >= PAN_UPDATE_MOVE_THRESHOLD || ABS(dy) >= PAN_UPDATE_MOVE_THRESHOLD )
-                                               {
-#ifdef __DETAIL_DEBUG__
-                                                       ErrorF("[GroupPan] PAN Update !dx=%d, dy=%d, state=%d\n", dx, dy, state);
-#endif//__DETAIL_DEBUG__
-
-                                                       GestureHandleGesture_Pan(num_pressed, dx, dy, direction, distance, current_time-prev_time, GestureUpdate);
-                                               }
-                                       }
-                                       prev_cx = cx;
-                                       prev_cy = cy;
-                                       prev_time = current_time;
-                               }
-                               mbits = 0;
-                       }
-                       break;
-
-               case ET_ButtonRelease:
-                       if( state != GestureEnd && num_pressed >= 2)
-                       {
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupPan][R][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
-#endif//__DETAIL_DEBUG__
-                               goto cleanup_pan;
-                       }
-
-                       if( g_pGesture->num_pressed )
-                               break;
-
-                       goto cleanup_pan;
-                       break;
-       }
-
-       return;
-
-cleanup_pan:
-
-       if( state == GestureBegin || state == GestureUpdate )
-       {
-               state = GestureEnd;
-               if( GestureHasFingerEventMask(GestureNotifyPan, num_pressed) )
-               {
-                       GestureHandleGesture_Pan(num_pressed, (short int)(cx-prev_cx), (short int)(cy-prev_cy), direction, distance, GetTimeInMillis()-prev_time, GestureEnd);
-               }
-       }
-       else
-       {
-               g_pGesture->recognized_gesture &= ~PanFilterMask;
-       }
-
-       g_pGesture->filter_mask |= PanFilterMask;
-       num_pressed = 0;
-       base_area_size = 0;
-       base_time = 0;
-       mbits = 0;
-       time_checked = 0;
-       state = GestureEnd;
-       cx = cy = 0;
-       prev_time = 0;
-       base_box_ext.x1 = base_box_ext.x2 = base_box_ext.y1 = base_box_ext.y2 = 0;
-       TimerCancel(pan_event_timer);
-       return;
-}
-
-void
-GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
-{
-       static int num_pressed = 0;
-       static int base_area_size = 0;
-
-       static Time base_time = 0;
-       Time current_time;
-
-       int cx, cy;
-       int area_size;
-
-       static int state = 0;
-       static int mbits = 0;
-       static int base_cx;
-       static int base_cy;
-       static pixman_box16_t base_box_ext;
-
-       static int tap_repeat = 0;
-       static int prev_tap_repeat = 0;
-       static int prev_num_pressed = 0;
-
-       static OsTimerPtr tap_event_timer = NULL;
-       static int event_type = GestureNotifyTap;
-
-       if( timer_expired )
-       {
-#ifdef __DETAIL_DEBUG__
-               ErrorF("[GroupTap][Timer] state=%d\n", state);
-#endif//__DETAIL_DEBUG__
-
-               switch( state )
-               {
-                       case 1://first tap initiation check
-                               if( num_pressed )
-                               {
-#ifdef __DETAIL_DEBUG__
-                                       ErrorF("[GroupTap][Timer][state=1] Tap time expired !(num_pressed=%d, tap_repeat=%d)\n", tap_repeat, num_pressed, tap_repeat);
-#endif//__DETAIL_DEBUG__
-                                       state = 0;
-                                       goto cleanup_tap;
-                               }
-                               break;
-
-                       case 2:
-                               if( tap_repeat <= 1 )
-                               {
-#ifdef __DETAIL_DEBUG__
-                                       ErrorF("[GroupTap][Timer][state=2] %d finger SINGLE TAP !(ignored)\n", prev_num_pressed);
-#endif//__DETAIL_DEBUG__
-                                       state = 0;
-                                       goto cleanup_tap;
-                               }
-
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupTap][Timer][state=2]  tap_repeat=%d, prev_tap_repeat=%d, num_pressed=%d\n", tap_repeat, prev_tap_repeat, num_pressed);
-#endif//__DETAIL_DEBUG__
-                               if( GestureHasFingerEventMask(GestureNotifyTap, prev_num_pressed) )
-                                       GestureHandleGesture_Tap(prev_num_pressed, tap_repeat, base_cx, base_cy);
-                               goto cleanup_tap;
-                               break;
-               }
-
-               return;
-       }
-
-       switch( type )
-       {
-               case ET_ButtonPress:
-                       g_pGesture->fingers[idx].flags |= PressFlagTap;
-
-                       if( g_pGesture->num_pressed < 2 )
-                               return;
-
-                       if( !prev_num_pressed && (!base_area_size || g_pGesture->num_pressed > num_pressed) )
-                       {
-                               base_area_size = AREA_SIZE(&g_pGesture->area.extents);
-                               base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
-                               base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
-                               base_time = GetTimeInMillis();
-                               base_box_ext.x1 = base_cx-TAP_MOVE_THRESHOLD;
-                               base_box_ext.y1 = base_cy-TAP_MOVE_THRESHOLD;
-                               base_box_ext.x2 = base_cx+TAP_MOVE_THRESHOLD;
-                               base_box_ext.y2 = base_cy+TAP_MOVE_THRESHOLD;
-                               state = 1;
-                               TimerCancel(tap_event_timer);
-                               tap_event_timer = TimerSet(tap_event_timer, 0, SGL_TAP_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
-                       }
-
-                       num_pressed = g_pGesture->num_pressed;
-
-                       current_time = GetTimeInMillis();
-
-#ifdef __DETAIL_DEBUG__
-                       ErrorF("[GroupTap][P][num_pressed=%d] AREA_SIZE(area.extents)=%d, base_cx=%d, base_cy=%d, base_time=%d, current_time=%d\n", num_pressed, base_area_size, base_cx, base_cy, base_time, current_time);
-#endif//__DETAIL_DEBUG__
-                       break;
-
-               case ET_Motion:
-                       if( !(g_pGesture->fingers[idx].flags & PressFlagTap ) )
-                               break;
-
-                       if( num_pressed < 2 )
-                               return;
-
-                       if( num_pressed != g_pGesture->num_pressed )
-                       {
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupTap][M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
-#endif//__DETAIL_DEBUG__
-                               //goto cleanup_tap;
-                       }
-
-                       mbits |= (1 << idx);
-                       if( mbits == (pow(2, num_pressed)-1) )
-                       {
-                               area_size = AREA_SIZE(&g_pGesture->area.extents);
-                               cx = AREA_CENTER_X(&g_pGesture->area.extents);
-                               cy = AREA_CENTER_Y(&g_pGesture->area.extents);
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupTap][M][num_pressed=%d] area_size=%d, base_area_size=%d, diff=%d\n", num_pressed, area_size, base_area_size, ABS(base_area_size - area_size));
-                               ErrorF("[GroupTap][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
-                               ErrorF("[GroupTap][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
-#endif//__DETAIL_DEBUG__
-
-                               if( ABS(base_area_size-area_size) >= TAP_AREA_THRESHOLD )
-                               {
-#ifdef __DETAIL_DEBUG__
-                                       ErrorF("[GroupTap][M] diff between area size(=%d) and base area size(=%d) is bigger than threshold(=%d)!\n", area_size, base_area_size, ABS(base_area_size-area_size));
-#endif//__DETAIL_DEBUG__
-                                       goto cleanup_tap;
-                               }
-
-                               if( !INBOX(&base_box_ext, cx, cy) )
-                               {
-#ifdef __DETAIL_DEBUG__
-                                       ErrorF("[GroupTap][M] current center coordinates is not in base coordinates box !\n");
-#endif//__DETAIL_DEBUG__
-                                       goto cleanup_tap;
-                               }
-                       }
-                       break;
-
-               case ET_ButtonRelease:
-                       if( g_pGesture->num_pressed )
-                               break;
-
-                       if( !tap_repeat )
-                       {
-                               prev_num_pressed = num_pressed;
-                       }
-
-                       prev_tap_repeat = tap_repeat;
-                       tap_repeat++;
-
-#ifdef __DETAIL_DEBUG__
-                       ErrorF("[GroupTap][R] tap_repeat=%d, prev_tap_repeat=%d, num_pressed=%d, prev_num_pressed=%d\n", tap_repeat, prev_tap_repeat, num_pressed, prev_num_pressed);
-#endif//__DETAIL_DEBUG__
-
-                       if( num_pressed != prev_num_pressed || !GestureHasFingerEventMask(GestureNotifyTap, num_pressed) )
-                       {
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupTap][R] num_pressed(=%d) != prev_num_pressed(=%d) OR %d finger tap event was not grabbed/selected !\n",
-                                       num_pressed, prev_num_pressed, num_pressed);
-#endif//__DETAIL_DEBUG__
-                               goto cleanup_tap;
-                       }
-
-                       if( tap_repeat < MAX_TAP_REPEATS )
-                       {
-                               state = 2;
-                               TimerCancel(tap_event_timer);
-                               tap_event_timer = TimerSet(tap_event_timer, 0, DBL_TAP_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
-                               num_pressed = 0;
-                               break;
-                       }
-
-#ifdef __DETAIL_DEBUG__
-                       ErrorF("[GroupTap][R] %d finger %s\n", num_pressed, (tap_repeat==2) ? "DBL_TAP" : "TRIPLE_TAP");
-#endif//__DETAIL_DEBUG__
-
-                       if( GestureHasFingerEventMask(GestureNotifyTap, num_pressed) )
-                               GestureHandleGesture_Tap(num_pressed, tap_repeat, base_cx, base_cy);
-
-                       if( tap_repeat >= MAX_TAP_REPEATS )
-                       {
-                               goto cleanup_tap;
-                       }
-
-                       prev_num_pressed = num_pressed;
-                       num_pressed = 0;
-                       break;
-       }
-
-       return;
-
-cleanup_tap:
-
-       if( 0 == state )
-               g_pGesture->recognized_gesture &= ~TapFilterMask;
-       g_pGesture->filter_mask |= TapFilterMask;
-
-       if( g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL )
-       {
-#ifdef __DETAIL_DEBUG__
-               ErrorF("[GroupTap][cleanup] GestureFlushOrDrop() !\n");
-#endif//__DETAIL_DEBUG__
-
-               if( ERROR_INVALPTR == GestureFlushOrDrop() )
-               {
-                       GestureControl(g_pGesture->this_device, DEVICE_OFF);
-               }
-       }
-
-       num_pressed = 0;
-       tap_repeat = 0;
-       prev_num_pressed = 0;
-       mbits = 0;
-       base_time = 0;
-       state = 0;
-       TimerCancel(tap_event_timer);
-       return;
-}
-
-void
-GestureRecognize_GroupTapNHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
-{
-       static int num_pressed = 0;
-       static int base_area_size = 0;
-       static Time base_time = 0;
-       static int base_cx;
-       static int base_cy;
-       int cx, cy;
-       static pixman_box16_t base_box_ext;
-       int area_size;
-       static int mbits = 0;
-
-       static int tap_repeat = 0;
-       static int prev_num_pressed = 0;
-
-       static OsTimerPtr tapnhold_event_timer = NULL;
-       static int event_type = GestureNotifyTapNHold;
-       static int state = GestureEnd;
-
-       Time interval = 0;
-       Time holdtime = 0;
-
-       if( timer_expired )
-       {
-               if( (state == GestureEnd) && num_pressed )
-               {
-#ifdef __DETAIL_DEBUG__
-                       ErrorF("[GroupTapNHold][Timer][state=%d] Tap time expired !(num_pressed=%d, tap_repeat=%d)\n", GestureEnd, tap_repeat, num_pressed, tap_repeat);
-#endif//__DETAIL_DEBUG__
-                       state = 0;
-                       goto cleanup_tapnhold;
-               }
-
-               if( state == GestureDone )
-               {
-#ifdef __DETAIL_DEBUG__
-                       ErrorF("[GroupTapNHold][Timer][state=%d] Interval between Tap and Hold is too long !\n");
-#endif//__DETAIL_DEBUG__
-                       goto cleanup_tapnhold;
-               }
-
-#ifdef __DETAIL_DEBUG__
-               switch( state )
-               {
-                       case GestureBegin:
-                               ErrorF("[GroupTapNHold][Timer] TapNHold Begin !\n");
-                               break;
-
-                       case GestureUpdate:
-                               ErrorF("[GroupTapNHold][Timer] TapNHold Update !\n");
-                               break;
-               }
-#endif//__DETAIL_DEBUG__
-
-               if( GestureHasFingerEventMask(GestureNotifyTapNHold, prev_num_pressed) )
-               {
-                       GestureHandleGesture_TapNHold(prev_num_pressed, base_cx, base_cy, interval, holdtime, state);
-                       tapnhold_event_timer = TimerSet(tapnhold_event_timer, 0, TAPNHOLD_HOLD_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
-               }
-               else
-               {
-#ifdef __DETAIL_DEBUG__
-                       ErrorF("[GroupTapNHold][Timer] %d finger TapNHold event was not grabbed/selected !\n", prev_num_pressed);
-#endif//__DETAIL_DEBUG__
-                       goto cleanup_tapnhold;
-               }
-
-               if( state <= GestureBegin )
-                       state++;
-               return;
-       }
-
-       switch( type )
-       {
-               case ET_ButtonPress:
-                       g_pGesture->fingers[idx].flags |= PressFlagTapNHold;
-
-                       if( g_pGesture->num_pressed < 2 )
-                               return;
-
-                       //if( !prev_num_pressed && (!base_area_size || g_pGesture->num_pressed > num_pressed) )
-                       if( !base_area_size || g_pGesture->num_pressed > num_pressed )
-                       {
-
-                               if( state == GestureUpdate )
-                               {
-#ifdef __DETAIL_DEBUG__
-                                       ErrorF("[GroupTapNHold][P][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
-#endif//__DETAIL_DEBUG__
-                                       goto cleanup_tapnhold;
-                               }
-
-                               if( state == GestureDone )
-                                       state = GestureBegin;
-
-                               base_area_size = AREA_SIZE(&g_pGesture->area.extents);
-                               base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
-                               base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
-                               base_time = GetTimeInMillis();
-                               base_box_ext.x1 = base_cx-TAPNHOLD_MOVE_THRESHOLD;
-                               base_box_ext.y1 = base_cy-TAPNHOLD_MOVE_THRESHOLD;
-                               base_box_ext.x2 = base_cx+TAPNHOLD_MOVE_THRESHOLD;
-                               base_box_ext.y2 = base_cy+TAPNHOLD_MOVE_THRESHOLD;
-                               if( state == GestureEnd )
-                                       tapnhold_event_timer = TimerSet(tapnhold_event_timer, 0, TAPNHOLD_TAP_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
-                               else
-                               {
-                                       TimerCancel(tapnhold_event_timer);
-                                       tapnhold_event_timer = TimerSet(tapnhold_event_timer, 0, TAPNHOLD_HOLD_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
-                               }
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupTapNHold][P] Create Timer !(state=%d)\n", state);
-#endif//__DETAIL_DEBUG__
-                       }
-
-                       num_pressed = g_pGesture->num_pressed;
-
-#ifdef __DETAIL_DEBUG__
-                       ErrorF("[GroupTapNHold][P][num_pressed=%d] AREA_SIZE(area.extents)=%d, base_cx=%d, base_cy=%d, base_time=%d\n", num_pressed, base_area_size, base_cx, base_cy, base_time);
-#endif//__DETAIL_DEBUG__
-                       break;
-
-               case ET_Motion:
-                       if( !(g_pGesture->fingers[idx].flags & PressFlagTapNHold ) )
-                               break;
-
-                       if( num_pressed < 2 )
-                               return;
-
-                       if( num_pressed != g_pGesture->num_pressed )
-                       {
-                               if( state != GestureEnd )
-                               {
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupTapNHold][M][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
-#endif//__DETAIL_DEBUG__
-                                       goto cleanup_tapnhold;
-                               }
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupTapNHold][M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
-#endif//__DETAIL_DEBUG__
-                               //goto cleanup_tapnhold;
-                       }
-
-                       mbits |= (1 << idx);
-                       if( mbits == (pow(2, num_pressed)-1) )
-                       {
-                               area_size = AREA_SIZE(&g_pGesture->area.extents);
-                               cx = AREA_CENTER_X(&g_pGesture->area.extents);
-                               cy = AREA_CENTER_Y(&g_pGesture->area.extents);
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupTapNHold][M][num_pressed=%d] area_size=%d, base_area_size=%d, diff=%d\n", num_pressed, area_size, base_area_size, ABS(base_area_size - area_size));
-                               ErrorF("[GroupTapNHold][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
-                               ErrorF("[GroupTapNHold][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
-#endif//__DETAIL_DEBUG__
-
-                               if( ABS(base_area_size-area_size) >= TAPNHOLD_AREA_THRESHOLD )
-                               {
-#ifdef __DETAIL_DEBUG__
-                                       ErrorF("[GroupTapNHold][M] diff between area size(=%d) and base area size(=%d) is bigger than threshold(=%d)!\n", area_size, base_area_size, ABS(base_area_size-area_size));
-#endif//__DETAIL_DEBUG__
-                                       goto cleanup_tapnhold;
-                               }
-
-                               if( !INBOX(&base_box_ext, cx, cy) )
-                               {
-#ifdef __DETAIL_DEBUG__
-                                       ErrorF("[GroupTapNHold][M] current center coordinates is not in base coordinates box !\n");
-#endif//__DETAIL_DEBUG__
-                                       goto cleanup_tapnhold;
-                               }
-                       }
-                       break;
-
-               case ET_ButtonRelease:
-                       if( state != GestureEnd && num_pressed >= 2)
-                       {
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupTapNHold][R][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
-#endif//__DETAIL_DEBUG__
-                               goto cleanup_tapnhold;
-                       }
-
-                       if( g_pGesture->num_pressed )
-                               break;
-
-                       if( !tap_repeat )
-                       {
-                               prev_num_pressed = num_pressed;
-                       }
-
-                       tap_repeat++;
-
-#ifdef __DETAIL_DEBUG__
-                       ErrorF("[GroupTapNHold][R] tap_repeat=%d, num_pressed=%d, prev_num_pressed=%d\n", tap_repeat, num_pressed, prev_num_pressed);
-#endif//__DETAIL_DEBUG__
-
-                       if( num_pressed != prev_num_pressed || !GestureHasFingerEventMask(GestureNotifyTapNHold, num_pressed) )
-                       {
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupTapNHold][R] num_pressed(=%d) != prev_num_pressed(=%d) OR %d finger tap event was not grabbed/selected !\n",
-                                       num_pressed, prev_num_pressed, num_pressed);
-#endif//__DETAIL_DEBUG__
-                               goto cleanup_tapnhold;
-                       }
-
-                       if( tap_repeat > 1 )
-                       {
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupTapNHold][R] Tap events(tap_repeat=%d) were put twice or more !(ignored)\n", tap_repeat);
-#endif//__DETAIL_DEBUG__
-                               goto cleanup_tapnhold;
-                       }
-
-                       prev_num_pressed = num_pressed;
-                       num_pressed = 0;
-                       state = GestureDone;
-
-                       TimerCancel(tapnhold_event_timer);
-                       tapnhold_event_timer = TimerSet(tapnhold_event_timer, 0, TAPNHOLD_INTV_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
-
-#ifdef __DETAIL_DEBUG__
-                       ErrorF("[GroupTapNHold][R][Last] state=%d, tap_repeat=%d, num_pressed=%d, prev_num_pressed=%d\n", state,  tap_repeat, num_pressed, prev_num_pressed);
-#endif//__DETAIL_DEBUG__
-                       break;
-       }
-
-       return;
-
-cleanup_tapnhold:
-
-       if( state == GestureUpdate )
-       {
-               state = GestureEnd;
-               if( GestureHasFingerEventMask(GestureNotifyTapNHold, prev_num_pressed) )
-               {
-                       GestureHandleGesture_TapNHold(prev_num_pressed, base_cx, base_cy, interval, holdtime, state);
-               }
-       }
-       else
-       {
-               g_pGesture->recognized_gesture &= ~TapNHoldFilterMask;
-       }
-
-       g_pGesture->filter_mask |= TapNHoldFilterMask;
-       if( g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL )
-       {
-#ifdef __DETAIL_DEBUG__
-               ErrorF("[GroupTapNHold][cleanup] GestureFlushOrDrop() !\n");
-#endif//__DETAIL_DEBUG__
-
-               if( ERROR_INVALPTR == GestureFlushOrDrop() )
-               {
-                       GestureControl(g_pGesture->this_device, DEVICE_OFF);
-               }
-       }
-
-       TimerCancel(tapnhold_event_timer);
-       num_pressed = 0;
-       tap_repeat = 0;
-       prev_num_pressed = 0;
-       mbits = 0;
-       base_time = 0;
-       state = 0;
-
-       return;
-}
-
-void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
-{
-       static int num_pressed = 0;
-       static int base_area_size = 0;
-       static Time base_time = 0;
-       static int base_cx;
-       static int base_cy;
-       int cx, cy;
-       static pixman_box16_t base_box_ext;
-       int area_size;
-       static int state = GestureEnd;
-
-       static OsTimerPtr hold_event_timer = NULL;
-       static int event_type = GestureNotifyHold;
-
-       if( timer_expired )
-       {
-               if( state <= GestureBegin )
-                       state++;
-
-#ifdef __DETAIL_DEBUG__
-               switch( state )
-               {
-                       case GestureBegin:
-                               ErrorF("[GroupHold] HOLD Begin !\n");
-                               break;
-
-                       case GestureUpdate:
-                               ErrorF("[GroupHold] HOLD Update !\n");
-                               break;
-               }
-#endif//__DETAIL_DEBUG__
-
-               if( GestureHasFingerEventMask(GestureNotifyHold, num_pressed) )
-               {
-                       GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state);
-                       hold_event_timer = TimerSet(hold_event_timer, 0, HOLD_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
-               }
-               return;
-       }
-
-       switch( type )
-       {
-               case ET_ButtonPress:
-                       g_pGesture->fingers[idx].flags |= PressFlagHold;
-
-                       if( g_pGesture->num_pressed < 2 )
-                               return;
-
-                       if( !base_area_size || g_pGesture->num_pressed > num_pressed )
-                       {
-                               if( state != GestureEnd )
-                               {
-#ifdef __DETAIL_DEBUG__
-                                       ErrorF("[GroupHold][P][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
-#endif//__DETAIL_DEBUG__
-                                       goto cleanup_hold;
-                               }
-
-                               base_area_size = AREA_SIZE(&g_pGesture->area.extents);
-                               base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
-                               base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
-                               base_time = GetTimeInMillis();
-                               base_box_ext.x1 = base_cx-HOLD_MOVE_THRESHOLD;
-                               base_box_ext.y1 = base_cy-HOLD_MOVE_THRESHOLD;
-                               base_box_ext.x2 = base_cx+HOLD_MOVE_THRESHOLD;
-                               base_box_ext.y2 = base_cy+HOLD_MOVE_THRESHOLD;
-                               event_type = GestureNotifyHold;
-                               hold_event_timer = TimerSet(hold_event_timer, 0, HOLD_TIME_THRESHOLD, GestureEventTimerHandler, (int *)&event_type);
-                       }
-                       num_pressed = g_pGesture->num_pressed;
-
-#ifdef __DETAIL_DEBUG__
-                       ErrorF("[GroupHold][P]][num_pressed=%d] AREA_SIZE(area.extents)=%d, base_cx=%d, base_cy=%d\n", num_pressed, base_area_size, base_cx, base_cy);
-#endif//__DETAIL_DEBUG__
-                       break;
-
-               case ET_Motion:
-                       if( !(g_pGesture->fingers[idx].flags & PressFlagHold ) )
-                               break;
-
-                       if( num_pressed < 2 )
-                               return;
-
-                       if( num_pressed != g_pGesture->num_pressed )
-                       {
-                               if( state != GestureEnd )
-                               {
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupHold][M][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
-#endif//__DETAIL_DEBUG__
-                                       goto cleanup_hold;
-                               }
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupHold][M][cleanup] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
-#endif//__DETAIL_DEBUG__
-                               //goto cleanup_hold;
-                       }
-
-                       area_size = AREA_SIZE(&g_pGesture->area.extents);
-                       cx = AREA_CENTER_X(&g_pGesture->area.extents);
-                       cy = AREA_CENTER_Y(&g_pGesture->area.extents);
-#ifdef __DETAIL_DEBUG__
-                       ErrorF("[GroupHold][M][num_pressed=%d] area_size=%d, base_area_size=%d, diff=%d\n", num_pressed, area_size, base_area_size, ABS(base_area_size - area_size));
-                       ErrorF("[GroupHold][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
-                       ErrorF("[GroupHold][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
-#endif//__DETAIL_DEBUG__
-
-                       if( ABS(base_area_size-area_size) >= HOLD_AREA_THRESHOLD )
-                       {
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupHold][M] diff between area size(=%d) and base area size(=%d) is bigger than threshold(=%d)!\n", area_size, base_area_size, ABS(base_area_size-area_size));
-#endif//__DETAIL_DEBUG__
-                               goto cleanup_hold;
-                       }
-
-                       if( !INBOX(&base_box_ext, cx, cy) )
-                       {
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupHold][M] current center coordinates is not in base coordinates box !\n");
-#endif//__DETAIL_DEBUG__
-                               goto cleanup_hold;
-                       }
-                       break;
-
-               case ET_ButtonRelease:
-                       if( state != GestureEnd && num_pressed >= 2)
-                       {
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[GroupHold][R][cleanup] num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
-#endif//__DETAIL_DEBUG__
-                               goto cleanup_hold;
-                       }
-
-                       //ErrorF("[GroupHold][R] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
-                       if( g_pGesture->num_pressed )
-                               break;
-
-                       goto cleanup_hold;
-                       break;
-       }
-
-       return;
-
-cleanup_hold:
-
-       if( state == GestureBegin || state == GestureUpdate )
-       {
-               state = GestureEnd;
-               if( GestureHasFingerEventMask(GestureNotifyHold, num_pressed) )
-               {
-                       GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state);
-               }
-       }
-       else
-       {
-               g_pGesture->recognized_gesture &= ~HoldFilterMask;
-       }
-
-       g_pGesture->filter_mask |= HoldFilterMask;
-       num_pressed = 0;
-       base_area_size = 0;
-       base_time = 0;
-       base_cx = base_cy = 0;
-       state = GestureEnd;
-       base_box_ext.x1 = base_box_ext.x2 = base_box_ext.y1 = base_box_ext.y2 = 0;
-       TimerCancel(hold_event_timer);
-       return;
-}
-
-WindowPtr
-GestureGetEventsWindow(void)
-{
-       Mask mask;
-       WindowPtr pWin;
-
-       //check grabbed event(s)
-       if( !GestureHasGrabbedEvents(&g_pGesture->grabMask, &g_pGesture->GrabEvents) )
-               g_pGesture->grabMask = 0;
-
-       pWin = GestureWindowOnXY(g_pGesture->fingers[0].px, g_pGesture->fingers[0].py);
-
-       if( pWin )
-       {
-#ifdef __DETAIL_DEBUG__
-               ErrorF("[X11][GestureGetEventsWindow] pWin->drawable.id=0x%x\n", pWin->drawable.id);
-#endif//__DETAIL_DEBUG__
-               g_pGesture->gestureWin = pWin->drawable.id;
-       }
-       else
-       {
-#ifdef __DETAIL_DEBUG__
-               ErrorF("[X11][GestureGetEventsWindow] GestureWindowOnXY returns NULL !\n");
-#endif//__DETAIL_DEBUG__
-               return NULL;
-       }
-
-       //check selected event(s)
-       if( !GestureHasSelectedEvents(pWin, &g_pGesture->eventMask) )
-               g_pGesture->eventMask = 0;
-
-       if( !g_pGesture->grabMask && !g_pGesture->eventMask )
-       {
-#ifdef __DETAIL_DEBUG__
-               ErrorF("[X11][GestureGetEventsWindow] No events were grabbed/selected for window(0x%x) !\n", pWin->drawable.id);
-#endif//__DETAIL_DEBUG__
-               return NULL;
-       }
-
-#ifdef __DETAIL_DEBUG__
-       ErrorF("[X11][GestureGetEventsWindow] g_pGesture->grabMask=0x%x, g_pGesture->eventMask=0x%x\n",
-                       g_pGesture->grabMask, g_pGesture->eventMask);
-#endif//__DETAIL_DEBUG__
-
-       mask = (GESTURE_FILTER_MASK_ALL & ~(g_pGesture->grabMask | g_pGesture->eventMask));
-
-#ifdef __DETAIL_DEBUG__
-       ErrorF("[X11][GestureGetEventsWindow] g_pGesture->filter_mask=0x%x, mask=0x%x\n", g_pGesture->filter_mask, mask);
-#endif//__DETAIL_DEBUG__
-
-       g_pGesture->filter_mask = mask;
-
-#ifdef __DETAIL_DEBUG__
-       ErrorF("[X11][GestureGetEventsWindow] g_pGesture->filter_mask=0x%x\n", g_pGesture->filter_mask);
-#endif//__DETAIL_DEBUG__
-
-       return pWin;
-}
-
-static CARD32
-GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
-{
-       int event_type = *(int *)arg;
-
-       switch( event_type )
-       {
-               case GestureNotifyHold:
-#ifdef __DETAIL_DEBUG__
-                       ErrorF("[GestureEventTimerHandler] GestureNotifyHold (event_type = %d)\n", event_type);
-#endif//__DETAIL_DEBUG__
-                       GestureRecognize_GroupHold(event_type, NULL, NULL, 0, 1);
-                       break;
-
-               case GestureNotifyPan:
-#ifdef __DETAIL_DEBUG__
-                       ErrorF("[GestureEventTimerHandler] GestureNotifyPan (event_type = %d)\n", event_type);
-#endif//__DETAIL_DEBUG__
-                       GestureRecognize_GroupPan(event_type, NULL, NULL, 0, 1);
-                       break;
-
-               case GestureNotifyTap:
-#ifdef __DETAIL_DEBUG__
-                       ErrorF("[GestureEventTimerHandler] GestureNotifyTap (event_type = %d)\n", event_type);
-#endif//__DETAIL_DEBUG__
-                       GestureRecognize_GroupTap(event_type, NULL, NULL, 0, 1);
-                       break;
-
-               case GestureNotifyTapNHold:
-#ifdef __DETAIL_DEBUG__
-                       ErrorF("[GestureEventTimerHandler] GestureNotifyTapNHold (event_type = %d)\n", event_type);
-#endif//__DETAIL_DEBUG__
-                       GestureRecognize_GroupTapNHold(event_type, NULL, NULL, 0, 1);
-                       break;
-
-               case GestureNotifyPinchRotation:
-#ifdef __DETAIL_DEBUG__
-                       ErrorF("[GestureEventTimerHandler] GestureNotifyPinchRotation (event_type = %d)\n", event_type);
-#endif//__DETAIL_DEBUG__
-                       GestureRecognize_GroupPinchRotation(event_type, NULL, NULL, 0, 1);
-                       break;
-
-               default:
-#ifdef __DETAIL_DEBUG__
-                       ErrorF("[GestureEventTimerHandler] unknown event_type (=%d)\n", event_type);
-#endif//__DETAIL_DEBUG__
-                       if(timer)
-                               ErrorF("[GestureEventTimerHandler] timer=%x\n", (unsigned int)timer);
-       }
-
-       return 0;
-}
-
-static CARD32
-GestureSingleFingerTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
-{
-       g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
-       g_pGesture->recognized_gesture = 0;
-
-       if( ERROR_INVALPTR == GestureFlushOrDrop() )
-       {
-               GestureControl(g_pGesture->this_device, DEVICE_OFF);
-       }
-
-#ifdef __DETAIL_DEBUG__
-       ErrorF("[X11][Single] expired !\n");
-#endif//__DETAIL_DEBUG__
-
-       return 0;
-}
-
-void
-GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device)
-{
-       int i;
-       static OsTimerPtr single_finger_timer = NULL;
-       int idx = -1;
-
-       if( PROPAGATE_EVENTS == g_pGesture->ehtype ||
-               device->id < g_pGesture->first_fingerid )
-               return;
-
-       for( i = 0 ; i < g_pGesture->num_mt_devices ; i++ )
-       {
-               if( device->id == g_pGesture->mt_devices[i]->id )
-               {
-                       idx = i;
-                       break;
-               }
-       }
-
-       if( idx < 0 )
-               return;
-
-       switch( type )
-       {
-               case ET_ButtonPress:
-                       if( idx == 0 )
-                               g_pGesture->event_sum[0] = BTN_PRESSED;
-                       g_pGesture->fingers[idx].ptime = ev->any.time;
-                       g_pGesture->fingers[idx].px = ev->device_event.root_x;
-                       g_pGesture->fingers[idx].py = ev->device_event.root_y;
-
-                       g_pGesture->num_pressed++;
-                       if( g_pGesture->num_pressed == 1 )
-                       {
-                               single_finger_timer = TimerSet(single_finger_timer, 0, 50, GestureSingleFingerTimerHandler, NULL);
-                       }
-                       else
-                       {
-                               TimerCancel(single_finger_timer);
-                       }
-
-                       if( g_pGesture->num_pressed > g_pGesture->num_mt_devices )
-                               g_pGesture->num_pressed = g_pGesture->num_mt_devices;
-
-                       if( !g_pGesture->pTempWin || g_pGesture->num_pressed != g_pGesture->inc_num_pressed )
-                       {
-                               g_pGesture->pTempWin = GestureGetEventsWindow();
-
-                               if( NULL == g_pGesture->pTempWin )
-                               {
-#ifdef __DETAIL_DEBUG__
-                                       ErrorF("[X11][GestureRecognize][g_pGesture->num_pressed=%d] No grabbed events and no event masks !\n", g_pGesture->num_pressed);
-#endif//__DETAIL_DEBUG__
-                                       g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
-                                       goto flush_or_drop;
-                               }
-                       }
-
-                       g_pGesture->inc_num_pressed = g_pGesture->num_pressed;
-
-                       g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH;
-                       g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH;
-                       g_pGesture->finger_rects[idx].extents.y1 =  ev->device_event.root_y - FINGER_HEIGHT;
-                       g_pGesture->finger_rects[idx].extents.y2 =  ev->device_event.root_y + FINGER_HEIGHT;
-
-                       if( g_pGesture->inc_num_pressed == 1 )
-                       {
-                               pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[P][g_pGesture->inc_num_pressed=1] AREA_SIZE(area.extents)=%d\n", AREA_SIZE(&g_pGesture->area.extents));
-#endif//__DETAIL_DEBUG__
-                       }
-                       else
-                       {
-                               pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
-                               for( i = 1 ; i < g_pGesture->inc_num_pressed ; i++ )
-                               {
-                                       pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]);
-                               }
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[P][g_pGesture->inc_num_pressed=%d] AREA_SIZE(area.extents)=%d\n", g_pGesture->inc_num_pressed, AREA_SIZE(&g_pGesture->area.extents));
-#endif//__DETAIL_DEBUG__
-                       }
-                       break;
-
-               case ET_Motion:
-                       if( !g_pGesture->fingers[idx].ptime )
-                               return;
-
-                       g_pGesture->fingers[idx].mx = ev->device_event.root_x;
-                       g_pGesture->fingers[idx].my = ev->device_event.root_y;
-
-                       if( idx == 0 && g_pGesture->event_sum[0] )
-                       {
-                               g_pGesture->event_sum[0] += BTN_MOVING;
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[X11][GestureRecognize] moving !\n");
-#endif//__DETAIL_DEBUG__
-                               if( g_pGesture->event_sum[0] >= 7 )
-                               {
-                               if( (g_pGesture->event_sum[0] >= 7) && (g_pGesture->inc_num_pressed < 2) )
-                                {
- #ifdef __DETAIL_DEBUG__
-                                       ErrorF("[X11][GestureRecognize] moving limit!\n");
- #endif//__DETAIL_DEBUG__
-                                       g_pGesture->filter_mask = GESTURE_FILTER_MASK_ALL;
-                                           goto flush_or_drop;
-                                }
-                               }
-                       }
-
-                       g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH;
-                       g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH;
-                       g_pGesture->finger_rects[idx].extents.y1 =  ev->device_event.root_y - FINGER_HEIGHT;
-                       g_pGesture->finger_rects[idx].extents.y2 =  ev->device_event.root_y + FINGER_HEIGHT;
-
-                       if( g_pGesture->inc_num_pressed == 1 )
-                       {
-                               pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[M][g_pGesture->inc_num_pressed=1] AREA_SIZE(area)=%d\n", AREA_SIZE(&g_pGesture->area.extents));
-#endif//__DETAIL_DEBUG__
-                       }
-                       else
-                       {
-                               pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
-                               for( i = 1 ; i < g_pGesture->inc_num_pressed ; i++ )
-                               {
-                                       pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]);
-                               }
-#ifdef __DETAIL_DEBUG__
-                               ErrorF("[M][g_pGesture->inc_num_pressed=%d] AREA_SIZE(area)=%d\n", g_pGesture->inc_num_pressed, AREA_SIZE(&g_pGesture->area.extents));
-#endif//__DETAIL_DEBUG__
-                       }
-                       break;
-
-               case ET_ButtonRelease:
-                       g_pGesture->fingers[idx].rtime = ev->any.time;
-                       g_pGesture->fingers[idx].rx = ev->device_event.root_x;
-                       g_pGesture->fingers[idx].ry = ev->device_event.root_y;
-
-                       g_pGesture->num_pressed--;
-                       if( g_pGesture->num_pressed <= 0 )
-                       {
-#ifdef __DETAIL_DEBUG__
-       ErrorF("[X11][GestureRecognize] All fingers were released !\n");
-#endif//__DETAIL_DEBUG__
-                               if( g_pGesture->inc_num_pressed == 1 )
-                                       goto flush_or_drop;
-                       }
-                       break;
-       }
-
-       if( g_pGesture->filter_mask != GESTURE_FILTER_MASK_ALL )
-       {
-               if( !(g_pGesture->filter_mask & FlickFilterMask) )
-               {
-                       GestureRecognize_GroupFlick(type, ev, device, idx);
-               }
-               if( !(g_pGesture->filter_mask & PanFilterMask) )
-               {
-                       GestureRecognize_GroupPan(type, ev, device, idx, 0);
-               }
-               if( !(g_pGesture->filter_mask & PinchRotationFilterMask) )
-               {
-                       GestureRecognize_GroupPinchRotation(type, ev, device, idx, 0);
-               }
-               if( !(g_pGesture->filter_mask & TapFilterMask) )
-               {
-                       GestureRecognize_GroupTap(type, ev, device, idx, 0);
-               }
-               if( !(g_pGesture->filter_mask & TapNHoldFilterMask) )
-               {
-                       GestureRecognize_GroupTapNHold(type, ev, device, idx, 0);
-               }
-               if( !(g_pGesture->filter_mask & HoldFilterMask) )
-               {
-                       GestureRecognize_GroupHold(type, ev, device, idx, 0);
-               }
-       }
-
-#ifdef __DETAIL_DEBUG__
-       ErrorF("[X11][GestureRecognize][N] g_pGesture->filter_mask = 0x%x\n", g_pGesture->filter_mask);
-       ErrorF("[X11][GestureRecognize][N] g_pGesture->GESTURE_FILTER_MASK_ALL = 0x%x\n", GESTURE_FILTER_MASK_ALL);
-       ErrorF("[X11][GestureRecognize][N] g_pGesture->recognized_gesture=0x%x\n", g_pGesture->recognized_gesture);
-#endif//__DETAIL_DEBUG__
-
-       if( g_pGesture->filter_mask == GESTURE_FILTER_MASK_ALL )
-       {
-               if( !g_pGesture->recognized_gesture )
-                       goto flush_or_drop;
-               else if( !g_pGesture->num_pressed )
-                       goto flush_or_drop;
-       }
-
-       if( g_pGesture->recognized_gesture )
-       {
-               if( g_pGesture->ehtype == KEEP_EVENTS )
-                       GestureEventsDrop();
-               g_pGesture->ehtype = IGNORE_EVENTS;
-       }
-
-       return;
-
-flush_or_drop:
-
-#ifdef __DETAIL_DEBUG__
-       ErrorF("[GestureRecognize] GestureFlushOrDrop() !\n");
-#endif//__DETAIL_DEBUG__
-       if( ERROR_INVALPTR == GestureFlushOrDrop() )
-       {
-               GestureControl(g_pGesture->this_device, DEVICE_OFF);
-       }
-}
-
-
-ErrorStatus GestureFlushOrDrop(void)
-{
-       ErrorStatus err;
-
-       if( g_pGesture->recognized_gesture )
-       {
-               GestureEventsDrop();
-       }
-       else
-       {
-               g_pGesture->ehtype = PROPAGATE_EVENTS;
-
-               err = GestureEventsFlush();
-               if( ERROR_NONE != err )
-                       return err;
-
-#ifdef __DETAIL_DEBUG__
-               ErrorF("[X11][GestureFlushOrDrop][F] g_pGesture->filter_mask = 0x%x\n", g_pGesture->filter_mask);
-               ErrorF("[X11][GestureFlushOrDrop][F] g_pGesture->GESTURE_FILTER_MASK_ALL = 0x%x\n", GESTURE_FILTER_MASK_ALL);
-               ErrorF("[X11][GestureFlushOrDrop][F] g_pGesture->recognized_gesture=0x%x\n", g_pGesture->recognized_gesture);
-#endif//__DETAIL_DEBUG__
-       }
-
-       err = GestureRegionsReinit();
-       if( ERROR_NONE != err )
-               return err;
-
-       g_pGesture->pTempWin = NULL;
-       g_pGesture->inc_num_pressed = g_pGesture->num_pressed = 0;
-       g_pGesture->event_sum[0] = 0;
-
-       return ERROR_NONE;
-}
-
-void
-GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
-{
-       int i;
-
-#ifdef __DEBUG_EVENT_HANDLER__
-       ErrorF("\n[X11][GestureHandleMTSyncEvent] (%d:%d) time:%d cur:%d\n",
-                       ev->any_event.deviceid, ev->any_event.sync, (int)ev->any.time, (int)GetTimeInMillis());
-#endif//__DEBUG_EVENT_HANDLER__
-
-       if( MTOUCH_FRAME_SYNC_BEGIN == ev->any_event.sync )
-       {
-               g_pGesture->ehtype = KEEP_EVENTS;
-               g_pGesture->filter_mask = 0;
-               g_pGesture->recognized_gesture = 0;
-               g_pGesture->num_pressed = 0;
-
-               for( i=0 ; i < g_pGesture->num_mt_devices ; i++ )
-                       g_pGesture->fingers[i].ptime = 0;
-       }
-       else if( MTOUCH_FRAME_SYNC_END == ev->any_event.sync )
-       {
-               g_pGesture->ehtype = PROPAGATE_EVENTS;
-       }
-}
-
-void
-GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
-{
-#ifdef __DEBUG_EVENT_HANDLER__
-       ErrorF("[X11][GestureHandleButtonPEvent] devid=%d time:%d cur:%d\n", device->id, ev->any.time, GetTimeInMillis());
-#endif//__DEBUG_EVENT_HANDLER__
-
-       switch( g_pGesture->ehtype )
-       {
-               case KEEP_EVENTS:
-                       if( ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev,  device) )
-                       {
-                               GestureControl(g_pGesture->this_device, DEVICE_OFF);
-                               return;
-                       }
-
-                       if( g_pGesture->num_mt_devices )
-                               GestureRecognize(ET_ButtonPress, ev, device);
-                       else
-                               device->public.processInputProc(ev, device);
-                       break;
-
-               case PROPAGATE_EVENTS:
-                       device->public.processInputProc(ev, device);
-                       break;
-
-               case IGNORE_EVENTS:
-                       GestureRecognize(ET_ButtonPress, ev, device);
-                       break;
-
-               default:
-                       break;
-       }
-}
-
-void
-GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
-{
-#ifdef __DEBUG_EVENT_HANDLER__
-       ErrorF("[X11][GestureHandleMotionEvent] devid=%d time:%d cur:%d\n", device->id, ev->any.time, GetTimeInMillis());
-#endif//__DEBUG_EVENT_HANDLER__
-
-       switch( g_pGesture->ehtype )
-       {
-               case KEEP_EVENTS:
-                       if( ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev,  device) )
-                       {
-                               GestureControl(g_pGesture->this_device, DEVICE_OFF);
-                               return;
-                       }
-
-                       if( g_pGesture->num_mt_devices )
-                               GestureRecognize(ET_Motion, ev, device);
-                       else
-                               device->public.processInputProc(ev, device);
-                       break;
-
-               case PROPAGATE_EVENTS:
-                       device->public.processInputProc(ev, device);
-                       break;
-
-               case IGNORE_EVENTS:
-                       GestureRecognize(ET_Motion, ev, device);
-                       break;
-
-               default:
-                       break;
-       }
-
-}
-
-void
-GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
-{
-#ifdef __DEBUG_EVENT_HANDLER__
-       ErrorF("[X11][GestureHandleButtonREvent] devid=%d time:%d cur:%d\n", device->id, ev->any.time, GetTimeInMillis());
-#endif//__DEBUG_EVENT_HANDLER__
-
-       switch( g_pGesture->ehtype )
-       {
-               case KEEP_EVENTS:
-                       if( ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev,  device) )
-                       {
-                               GestureControl(g_pGesture->this_device, DEVICE_OFF);
-                               return;
-                       }
-
-                       if( g_pGesture->num_mt_devices )
-                               GestureRecognize(ET_ButtonRelease, ev, device);
-                       else
-                               device->public.processInputProc(ev, device);
-                       break;
-
-               case PROPAGATE_EVENTS:
-                       device->public.processInputProc(ev, device);
-                       break;
-
-               case IGNORE_EVENTS:
-                       GestureRecognize(ET_ButtonRelease, ev, device);
-                       break;
-
-               default:
-                       break;
-       }
-}
-
-static ErrorStatus
-GestureEnableEventHandler(InputInfoPtr pInfo)
- {
-       Bool res;
-       GestureDevicePtr pGesture = pInfo->private;
-
-       res = GestureInstallResourceStateHooks();
-
-       if( !res )
-       {
-               ErrorF("[X11][GestureEnableEventHandler] Failed on GestureInstallResourceStateHooks() !\n");
-               return ERROR_ABNORMAL;
-       }
-
-       res = GestureSetMaxNumberOfFingers((int)MAX_MT_DEVICES);
-
-       if( !res )
-       {
-               ErrorF("[X11][GestureEnableEventHandler] Failed on GestureSetMaxNumberOfFingers(%d) !\n", (int)MAX_MT_DEVICES);
-               goto failed;
-       }
-
-       pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 500, GestureTimerHandler, pInfo);
-
-       if( !pGesture->device_setting_timer )
-       {
-               ErrorF("[X11][GestureEnableEventHandler] Failed to allocate memory for timer !\n");
-               goto failed;
-       }
-
-       if( ERROR_NONE != GestureRegionsInit() || ERROR_NONE != GestureInitEQ() )
-       {
-               goto failed;
-       }
-
-       mieqSetHandler(ET_ButtonPress, GestureHandleButtonPressEvent);
-       mieqSetHandler(ET_ButtonRelease, GestureHandleButtonReleaseEvent);
-       mieqSetHandler(ET_Motion, GestureHandleMotionEvent);
-       if( pGesture->is_active )
-               mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent);
-
-       return ERROR_NONE;
-
-failed:
-       GestureUninstallResourceStateHooks();
-       GestureUnsetMaxNumberOfFingers();
-
-       return ERROR_ABNORMAL;
-}
-
-static ErrorStatus
-GestureDisableEventHandler(void)
-{
-       ErrorStatus err = ERROR_NONE;
-
-       mieqSetHandler(ET_ButtonPress, NULL);
-       mieqSetHandler(ET_ButtonRelease, NULL);
-       mieqSetHandler(ET_Motion, NULL);
-       mieqSetHandler(ET_MTSync, NULL);
-
-       err = GestureFiniEQ();
-
-       if( ERROR_INVALPTR == err )
-       {
-               ErrorF("[X11][GestureDisableEventHandler] EQ is invalid or was freed already !\n");
-       }
-
-       GestureUninstallResourceStateHooks();
-       GestureUnsetMaxNumberOfFingers();
-
-       return err;
-}
-
-static CARD32
-GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
-{
-       InputInfoPtr pInfo = (InputInfoPtr)arg;
-       GestureDevicePtr pGesture = pInfo->private;
-
-       int idx = 0;
-       DeviceIntPtr dev;
-       for( dev = inputInfo.pointer ; dev; dev = dev->next )
-       {
-               if(IsMaster(dev) && IsPointerDevice(dev))
-               {
-                       pGesture->master_pointer = dev;
-                       ErrorF("[X11][GestureTimerHandler][id:%d] Master Pointer=%s\n", dev->id, pGesture->master_pointer->name);
-                       continue;
-               }
-
-               if(IsXTestDevice(dev, NULL) && IsPointerDevice(dev))
-               {
-                       pGesture->xtest_pointer = dev;
-                       ErrorF("[X11][GestureTimerHandler][id:%d] XTest Pointer=%s\n", dev->id, pGesture->xtest_pointer->name);
-                       continue;
-               }
-
-               if(IsPointerDevice(dev))
-               {
-                       if( idx >= MAX_MT_DEVICES )
-                       {
-                               ErrorF("[X11][GestureTimerHandler] Number of mt device is over MAX_MT_DEVICES(%d) !\n",
-                                       MAX_MT_DEVICES);
-                               continue;
-                       }
-                       pGesture->mt_devices[idx] = dev;
-                       ErrorF("[X11][GestureTimerHandler][id:%d] MT device[%d] name=%s\n", dev->id, idx, pGesture->mt_devices[idx]->name);
-                       idx++;
-               }
-       }
-
-       if( !pGesture->master_pointer || !pGesture->xtest_pointer )
-       {
-               ErrorF("[X11][GestureTimerHandler] Failed to get info of master pointer or XTest pointer !\n");
-               pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL);
-               pGesture->num_mt_devices = 0;
-
-               return 0;
-       }
-
-       pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL);
-       pGesture->first_fingerid = pGesture->mt_devices[0]->id;
-       pGesture->num_mt_devices = idx;
-
-       if( !pGesture->num_mt_devices )
-       {
-               ErrorF("[X11][GestureTimerHandler] Failed to mt device information !\n");
-               pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL);
-               pGesture->num_mt_devices = 0;
-
-               return 0;
-       }
-
-       memset(pGesture->fingers, 0, sizeof(TouchStatus)*pGesture->num_mt_devices);
-       pGesture->pRootWin = RootWindow(pGesture->master_pointer);
-       g_pGesture->grabMask = g_pGesture->eventMask = 0;
-       g_pGesture->pTempWin = NULL;
-       g_pGesture->inc_num_pressed = 0;
-
-       return 0;
-}
-
-BOOL
-IsXTestDevice(DeviceIntPtr dev, DeviceIntPtr master)
-{
-       if (IsMaster(dev))
-               return FALSE;
-
-       if (master)
-               return (dev->xtest_master_id == master->id);
-
-       return (dev->xtest_master_id != 0);
-}
-
-void
-GestureSetDisable(InputInfoPtr pInfo, int enable)
-{
-       if( !enable )
-       {
-               g_pGesture->ehtype = PROPAGATE_EVENTS;
-               mieqSetHandler(ET_MTSync, NULL);
-               g_pGesture->is_active = 0;
-               ErrorF("[X11][GestureSetDisable] Disabled !\n");
-       }
-       else
-       {
-               g_pGesture->ehtype = KEEP_EVENTS;
-               mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent);
-               g_pGesture->is_active = 1;
-               ErrorF("[X11][GestureSetDisable] Enabled !\n");
-       }
-}
-
-ErrorStatus
-GestureRegionsInit(void)
-{
-       int i;
-
-       if( !g_pGesture )
-               return ERROR_INVALPTR;
-
-       pixman_region_init(&g_pGesture->area);
-
-       for( i = 0 ; i < MAX_MT_DEVICES ; i++ )
-       {
-               pixman_region_init_rect (&g_pGesture->finger_rects[i], 0, 0, FINGER_WIDTH_2T, FINGER_HEIGHT_2T);
-       }
-
-       return ERROR_NONE;
-}
-
-ErrorStatus
-GestureRegionsReinit(void)
-{
-       if( !g_pGesture )
-       {
-               ErrorF("[X11][GestureRegionsReinit] Invalid pointer access !\n");
-               return ERROR_INVALPTR;
-       }
-
-       pixman_region_init(&g_pGesture->area);
-
-       return ERROR_NONE;
-}
-
-ErrorStatus
-GestureInitEQ(void)
-{
-       int i;
-       IEventPtr tmpEQ;
-
-       tmpEQ = (IEventRec *)calloc(GESTURE_EQ_SIZE, sizeof(IEventRec));
-
-       if( !tmpEQ )
-       {
-               ErrorF("[X11][GestureInitEQ] Failed to allocate memory for EQ !\n");
-               return ERROR_ALLOCFAIL;
-       }
-
-       for( i = 0 ; i < GESTURE_EQ_SIZE ; i++ )
-       {
-               tmpEQ[i].event = (InternalEvent *)malloc(sizeof(InternalEvent));
-               if( !tmpEQ[i].event )
-               {
-                       ErrorF("[X11][GestureInitEQ] Failed to allocation memory for each event buffer in EQ !\n");
-                       return ERROR_ALLOCFAIL;
-               }
-       }
-
-       g_pGesture->EQ = tmpEQ;
-       g_pGesture->headEQ = g_pGesture->tailEQ = 0;
-
-       return ERROR_NONE;
-}
-
-ErrorStatus
-GestureFiniEQ(void)
-{
-       int i;
-
-       if( !g_pGesture || !g_pGesture->EQ )
-               return ERROR_INVALPTR;
-
-       for( i = 0 ; i < GESTURE_EQ_SIZE ; i++ )
-       {
-               if( g_pGesture->EQ[i].event )
-               {
-                       free(g_pGesture->EQ[i].event);
-                       g_pGesture->EQ[i].event = NULL;
-               }
-       }
-
-       free(g_pGesture->EQ);
-       g_pGesture->EQ = NULL;
-
-       return ERROR_NONE;
-}
-
-ErrorStatus
-GestureEnqueueEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
-{
-       int tail;
-
-       if( !g_pGesture || !g_pGesture->EQ )
-       {
-               ErrorF("[X11][GestureEnqueueEvent] Invalid pointer access !\n");
-               return ERROR_INVALPTR;
-       }
-
-       tail = g_pGesture->tailEQ;
-
-       if( tail >= GESTURE_EQ_SIZE )
-       {
-               ErrorF("[X11][GestureEnqueueEvent] Gesture EQ is full !\n");
-               return ERROR_EQFULL;
-       }
-
-#ifdef __DETAIL_DEBUG__
-       switch( ev->any.type )
-       {
-               case ET_ButtonPress:
-                       ErrorF("[X11][GestureEnqueueEvent] ET_ButtonPress (id:%d)\n", device->id);
-                       break;
-
-               case ET_ButtonRelease:
-                       ErrorF("[X11][GestureEnqueueEvent] ET_ButtonRelease (id:%d)\n", device->id);
-                       break;
-
-               case ET_Motion:
-                       ErrorF("[X11][GestureEnqueueEvent] ET_Motion (id:%d)\n", device->id);
-                       break;
-       }
-#endif//__DETAIL_DEBUG__
-
-       g_pGesture->EQ[tail].device = device;
-       g_pGesture->EQ[tail].screen_num = screen_num;
-       memcpy(g_pGesture->EQ[tail].event, ev, sizeof(InternalEvent));//need to be optimized
-       g_pGesture->tailEQ++;
-
-       return ERROR_NONE;
-}
-
-ErrorStatus
-GestureEventsFlush(void)
-{
-       int i;
-       DeviceIntPtr device;
-
-       if( !g_pGesture->EQ )
-       {
-               ErrorF("[X11][GestureEventsFlush] Invalid pointer access !\n");
-               return ERROR_INVALPTR;
-       }
-
-#ifdef __DETAIL_DEBUG__
-       ErrorF("[X11][GestureEventsFlush]\n");
-#endif//__DETAIL_DEBUG__
-
-       for( i = g_pGesture->headEQ ; i < g_pGesture->tailEQ ; i++)
-       {
-               device = g_pGesture->EQ[i].device;
-               device->public.processInputProc(g_pGesture->EQ[i].event, device);
-       }
-
-       for( i = 0 ; i < MAX_MT_DEVICES ; i++ )
-               g_pGesture->event_sum[i] = 0;
-
-       g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
-
-       return ERROR_NONE;
-}
-
-void
-GestureEventsDrop(void)
-{
-       g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
-}
-
-#ifdef HAVE_PROPERTIES
-static void
-GestureInitProperty(DeviceIntPtr dev)
-{
-       int rc;
-
-       prop_gesture_recognizer_onoff = MakeAtom(GESTURE_RECOGNIZER_ONOFF, strlen(GESTURE_RECOGNIZER_ONOFF),  TRUE);
-       rc = XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE);
-
-       if (rc != Success)
-               return;
-
-       XISetDevicePropertyDeletable(dev, prop_gesture_recognizer_onoff, FALSE);
-}
-
-static int
-GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
-                 BOOL checkonly)
-{
-       InputInfoPtr pInfo  = dev->public.devicePrivate;
-
-       if( prop_gesture_recognizer_onoff == atom )
-       {
-               int data;
-               if( val->format != 32 || val->type != XA_INTEGER || val->size != 1 )
-                       return BadMatch;
-
-               if( !checkonly )
-               {
-                       data = *((int *)val->data);
-                       GestureSetDisable(pInfo, data);
-               }
-       }
-
-       return Success;
-}
-#endif//HAVE_PROPERTIES
-
-static int
-GestureInit(DeviceIntPtr device)
-{
-       InputInfoPtr pInfo;
-       pInfo = device->public.devicePrivate;
-
-#ifdef HAVE_PROPERTIES
-       GestureInitProperty(device);
-       XIRegisterPropertyHandler(device, GestureSetProperty, NULL, NULL);
-#endif
-
-       return Success;
-}
-
-static void
-GestureFini(DeviceIntPtr device)
-{
-       XIRegisterPropertyHandler(device, NULL, NULL, NULL);
-}
-
-static pointer
-GesturePlug(pointer module, pointer options, int *errmaj, int *errmin)
-{
-       xf86AddInputDriver(&GESTURE, module, 0);
-       return module;
-}
-
-static void
-GestureUnplug(pointer p)
-{
-}
-
-static InputInfoPtr
-GesturePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
-{
-    int rc = BadAlloc;
-    GestureDevicePtr    pGesture;
-
-    pGesture = calloc(1, sizeof(GestureDeviceRec));
-
-    if (!pGesture) {
-        pInfo->private = NULL;
-        //xf86DeleteInput(pInfo, 0);
-        goto error;
-    }
-
-    g_pGesture = pGesture;
-    pInfo->private = pGesture;
-    pInfo->flags = 0;
-    pInfo->read_input = GestureReadInput; /* new data avl */
-    pInfo->switch_mode = NULL; /* toggle absolute/relative mode */
-    pInfo->device_control = GestureControl; /* enable/disable dev */
-    /* process driver specific options */
-    pGesture->device = xf86SetStrOption(pInfo->options, "Device", "/dev/null");
-    pGesture->is_active = xf86SetIntOption(pInfo->options, "Activate", 0);
-    pGesture->gestureWin = None;
-
-    xf86Msg(X_INFO, "%s: Using device %s.\n", pInfo->name, pGesture->device);
-
-    /* process generic options */
-    xf86CollectInputOptions(pInfo, NULL);
-    xf86ProcessCommonOptions(pInfo, pInfo->options);
-
-    pInfo->fd = -1;
-    return Success;
-
-error:
-    if (pInfo->fd >= 0)
-        close(pInfo->fd);
-    return rc;
-}
-
-static void
-GestureUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
-{
-       GestureDevicePtr pGesture = pInfo->private;
-
-       g_pGesture = pGesture = NULL;
-       pInfo->private = NULL;
-
-       xf86DeleteInput(pInfo, 0);
-}
-
-static int
-GestureControl(DeviceIntPtr device, int what)
-{
-    InputInfoPtr  pInfo = device->public.devicePrivate;
-    GestureDevicePtr pGesture = pInfo->private;
-
-    switch(what)
-    {
-        case DEVICE_INIT:
-            GestureInit(device);
-            break;
-
-        /* Switch device on.  Establish socket, start event delivery.  */
-        case DEVICE_ON:
-            xf86Msg(X_INFO, "%s: On.\n", pInfo->name);
-
-            if (device->public.on)
-                    break;
-
-            device->public.on = TRUE;
-            pGesture->this_device = device;
-            pGesture->num_mt_devices = 0;
-            if( ERROR_ABNORMAL == GestureEnableEventHandler(pInfo) )
-               goto device_off;
-            break;
-
-       case DEVICE_OFF:
-device_off:
-            GestureDisableEventHandler();
-            GestureFini(device);
-            pGesture->this_device = NULL;
-             xf86Msg(X_INFO, "%s: Off.\n", pInfo->name);
-
-            if (!device->public.on)
-                break;
-
-            pInfo->fd = -1;
-            device->public.on = FALSE;
-            break;
-
-      case DEVICE_CLOSE:
-            /* free what we have to free */
-            break;
-    }
-    return Success;
-}
-
-static void
-GestureReadInput(InputInfoPtr pInfo)
-{
-}
-
diff --git a/wearable/AUTHORS b/wearable/AUTHORS
new file mode 100644 (file)
index 0000000..e903784
--- /dev/null
@@ -0,0 +1,2 @@
+Sung-Jin Park <sj76.park@samsung.com>
+Sangjin Lee <lsj119@samsung.com>
diff --git a/wearable/COPYING b/wearable/COPYING
new file mode 100755 (executable)
index 0000000..8f6ba4b
--- /dev/null
@@ -0,0 +1,21 @@
+Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is fur-
+nished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
+NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+
diff --git a/wearable/ChangeLog b/wearable/ChangeLog
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/wearable/LICENSE.MIT b/wearable/LICENSE.MIT
new file mode 100644 (file)
index 0000000..1c81bdc
--- /dev/null
@@ -0,0 +1,20 @@
+Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved 
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without
+fee, provided that the above copyright notice appear in all copies
+and that both that copyright notice and this permission notice
+appear in supporting documentation, and that the name of Red Hat
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.  Red
+Hat makes no representations about the suitability of this software
+for any purpose.  It is provided "as is" without express or implied
+warranty.
+
+THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/wearable/Makefile.am b/wearable/Makefile.am
new file mode 100644 (file)
index 0000000..8e655ec
--- /dev/null
@@ -0,0 +1,41 @@
+#  Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved 
+#
+#  Permission to use, copy, modify, distribute, and sell this software and its
+#  documentation for any purpose is hereby granted without fee, provided that
+#  the above copyright notice appear in all copies and that both that
+#  copyright notice and this permission notice appear in supporting
+#  documentation, and that the name of Red Hat not be used in
+#  advertising or publicity pertaining to distribution of the software without
+#  specific, written prior permission.  Red Hat makes no
+#  representations about the suitability of this software for any purpose.  It
+#  is provided "as is" without express or implied warranty.
+#
+#  RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+#  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+#  EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+#  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+#  DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+#  TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+#  PERFORMANCE OF THIS SOFTWARE.
+#
+
+AUTOMAKE_OPTIONS = foreign
+
+# Ensure headers are installed below $(prefix) for distcheck
+DISTCHECK_CONFIGURE_FLAGS = --with-sdkdir='$${includedir}/xorg'
+
+SUBDIRS = src man
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = xorg-gesture.pc
+
+EXTRA_DIST = ChangeLog
+
+MAINTAINERCLEANFILES=ChangeLog
+
+.PHONY: ChangeLog
+
+ChangeLog:
+       $(CHANGELOG_CMD)
+
+dist-hook: ChangeLog
diff --git a/wearable/NOTICE b/wearable/NOTICE
new file mode 100644 (file)
index 0000000..c10a9c5
--- /dev/null
@@ -0,0 +1,3 @@
+Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved.
+Except as noted, this software is licensed under MIT License.
+Please, see the LICENSE.MIT file for MIT License terms and conditions.
diff --git a/wearable/autogen.sh b/wearable/autogen.sh
new file mode 100755 (executable)
index 0000000..0aad669
--- /dev/null
@@ -0,0 +1,13 @@
+#! /bin/sh
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+ORIGDIR=`pwd`
+cd $srcdir
+
+autoreconf -v --install || exit 1
+cd $ORIGDIR || exit $?
+
+#$srcdir/configure --enable-maintainer-mode "$@"
+#$srcdir/configure --prefix=/usr --enable-maintainer-mode "$@"
diff --git a/wearable/configure.ac b/wearable/configure.ac
new file mode 100644 (file)
index 0000000..109646d
--- /dev/null
@@ -0,0 +1,75 @@
+#  Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved 
+#
+#  Permission to use, copy, modify, distribute, and sell this software and its
+#  documentation for any purpose is hereby granted without fee, provided that
+#  the above copyright notice appear in all copies and that both that
+#  copyright notice and this permission notice appear in supporting
+#  documentation, and that the name of Red Hat not be used in
+#  advertising or publicity pertaining to distribution of the software without
+#  specific, written prior permission.  Red Hat makes no
+#  representations about the suitability of this software for any purpose.  It
+#  is provided "as is" without express or implied warranty.
+#
+#  RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+#  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+#  EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+#  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+#  DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+#  TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+#  PERFORMANCE OF THIS SOFTWARE.
+#
+
+AC_PREREQ(2.57)
+AC_INIT([xserver-xorg-input-gesture],
+        0.1.0,
+        [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
+        xserver-xorg-input-gesture)
+
+AC_CONFIG_SRCDIR([Makefile.am])
+AC_CONFIG_AUX_DIR(.)
+AM_INIT_AUTOMAKE([dist-bzip2])
+
+AM_MAINTAINER_MODE
+
+# Require xorg-macros: XORG_DEFAULT_OPTIONS
+m4_ifndef([XORG_MACROS_VERSION], [AC_FATAL([must install xorg-macros 1.3 or later before running autoconf/autogen])])
+XORG_MACROS_VERSION(1.3)
+AM_CONFIG_HEADER([config.h])
+
+# Checks for programs.
+AC_DISABLE_STATIC
+AC_PROG_LIBTOOL
+AC_PROG_CC
+XORG_DEFAULT_OPTIONS
+
+AH_TOP([#include "xorg-server.h"])
+
+AC_ARG_WITH(xorg-module-dir,
+            AC_HELP_STRING([--with-xorg-module-dir=DIR],
+                           [Default xorg module directory [[default=$libdir/xorg/modules]]]),
+            [moduledir="$withval"],
+            [moduledir="$libdir/xorg/modules"])
+inputdir=${moduledir}/input
+AC_SUBST(inputdir)
+
+# Checks for pkg-config packages. We need to be able to override sdkdir
+# to satisfy silly distcheck requirements.
+PKG_CHECK_MODULES(XORG, xorg-server xproto dlog $REQUIRED_MODULES)
+XORG_CFLAGS="$CWARNFLAGS $XORG_CFLAGS"
+AC_ARG_WITH([sdkdir], [],
+    [sdkdir="$withval"],
+    [sdkdir=`$PKG_CONFIG --variable=sdkdir xorg-server`])
+AC_SUBST([sdkdir])
+
+# Checks for libraries.
+
+# Checks for header files.
+AC_HEADER_STDC
+
+DRIVER_NAME=gesture
+AC_SUBST([DRIVER_NAME])
+
+AC_OUTPUT([Makefile
+           src/Makefile
+           man/Makefile
+           xorg-gesture.pc])
diff --git a/wearable/man/Makefile.am b/wearable/man/Makefile.am
new file mode 100644 (file)
index 0000000..b91dae4
--- /dev/null
@@ -0,0 +1,53 @@
+#  Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved 
+#
+#  Permission to use, copy, modify, distribute, and sell this software and its
+#  documentation for any purpose is hereby granted without fee, provided that
+#  the above copyright notice appear in all copies and that both that
+#  copyright notice and this permission notice appear in supporting
+#  documentation, and that the name of Red Hat not be used in
+#  advertising or publicity pertaining to distribution of the software without
+#  specific, written prior permission.  Red Hat makes no
+#  representations about the suitability of this software for any purpose.  It
+#  is provided "as is" without express or implied warranty.
+#
+#  RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+#  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+#  EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+#  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+#  DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+#  TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+#  PERFORMANCE OF THIS SOFTWARE.
+#
+
+drivermandir = $(DRIVER_MAN_DIR)
+
+driverman_PRE = @DRIVER_NAME@.man
+
+driverman_DATA = $(driverman_PRE:man=@DRIVER_MAN_SUFFIX@)
+
+EXTRA_DIST = @DRIVER_NAME@.man
+
+CLEANFILES = $(driverman_DATA)
+
+SED = sed
+
+# Strings to replace in man pages
+XORGRELSTRING = @PACKAGE_STRING@
+  XORGMANNAME = X Version 11
+
+MAN_SUBSTS = \
+       -e 's|__vendorversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \
+       -e 's|__xorgversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \
+       -e 's|__xservername__|Xorg|g' \
+       -e 's|__xconfigfile__|xorg.conf|g' \
+       -e 's|__projectroot__|$(prefix)|g' \
+       -e 's|__appmansuffix__|$(APP_MAN_SUFFIX)|g' \
+       -e 's|__drivermansuffix__|$(DRIVER_MAN_SUFFIX)|g' \
+       -e 's|__adminmansuffix__|$(ADMIN_MAN_SUFFIX)|g' \
+       -e 's|__miscmansuffix__|$(MISC_MAN_SUFFIX)|g' \
+       -e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g'
+
+SUFFIXES = .$(DRIVER_MAN_SUFFIX) .man
+
+.man.$(DRIVER_MAN_SUFFIX):
+       sed $(MAN_SUBSTS) < $< > $@
diff --git a/wearable/man/gesture.man b/wearable/man/gesture.man
new file mode 100644 (file)
index 0000000..f3e0eeb
--- /dev/null
@@ -0,0 +1,29 @@
+.ds q \N'34'
+.TH GESUTRE __drivermansuffix__ __vendorversion__
+.SH NAME
+gesture \- Example X.Org input driver
+.SH SYNOPSIS
+.nf
+.B "Section \*qInputDevice\*q"
+.BI "  Identifier \*q" devname \*q
+.B  "  Driver \*qgesture\*q"
+.BI "  Option \*qDevice\*q   \*q" devpath \*q
+\ \ ...
+.B EndSection
+.fi
+.SH DESCRIPTION
+.B gesture 
+is an example __xservername__ input driver It reads from /dev/ugesture and
+moves the pointer along the X axis by a gesture number of pixels.
+.PP
+.SH EMPTY MANPAGE
+This is an example driver, hence the man page is not particularly useful.
+For a better structure of the man page, including which sections to use in a
+new man page see the 
+.B evdev(4)
+man page.
+
+
+.SH "SEE ALSO"
+__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__),
+README.mouse.
diff --git a/wearable/src/Makefile.am b/wearable/src/Makefile.am
new file mode 100644 (file)
index 0000000..695f833
--- /dev/null
@@ -0,0 +1,37 @@
+#  Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved 
+#
+#  Permission to use, copy, modify, distribute, and sell this software and its
+#  documentation for any purpose is hereby granted without fee, provided that
+#  the above copyright notice appear in all copies and that both that
+#  copyright notice and this permission notice appear in supporting
+#  documentation, and that the name of Red Hat not be used in
+#  advertising or publicity pertaining to distribution of the software without
+#  specific, written prior permission.  Red Hat makes no
+#  representations about the suitability of this software for any purpose.  It
+#  is provided "as is" without express or implied warranty.
+#
+#  RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+#  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+#  EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+#  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+#  DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+#  TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+#  PERFORMANCE OF THIS SOFTWARE.
+#
+
+# this is obnoxious:
+# -module lets us name the module exactly how we want
+# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
+# _ladir passes a dummy rpath to libtool so the thing will actually link
+# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
+AM_CFLAGS = $(XORG_CFLAGS)
+
+@DRIVER_NAME@_drv_la_LTLIBRARIES = @DRIVER_NAME@_drv.la
+@DRIVER_NAME@_drv_la_LDFLAGS = -module -avoid-version
+@DRIVER_NAME@_drv_ladir = @inputdir@
+
+INCLUDES=-I$(top_srcdir)/include/
+
+@DRIVER_NAME@_drv_la_SOURCES = @DRIVER_NAME@.c \
+                               @DRIVER_NAME@.h 
+
diff --git a/wearable/src/gesture.c b/wearable/src/gesture.c
new file mode 100644 (file)
index 0000000..6c6b01e
--- /dev/null
@@ -0,0 +1,3795 @@
+/**************************************************************************
+
+xserver-xorg-input-gesture
+
+Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+
+Contact: Sung-Jin Park <sj76.park@samsung.com>
+         Sangjin LEE <lsj119@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <linux/input.h>
+#include <linux/types.h>
+
+#include <xf86_OSproc.h>
+
+#include <unistd.h>
+
+#include <xf86.h>
+#include <xf86Xinput.h>
+#include <exevents.h>
+#include <xorgVersion.h>
+#include <xkbsrv.h>
+
+#ifdef HAVE_PROPERTIES
+#include <X11/Xatom.h>
+#include <xserver-properties.h>
+/* 1.6 has properties, but no labels */
+#ifdef AXIS_LABEL_PROP
+#define HAVE_LABELS
+#else
+#undef HAVE_LABELS
+#endif
+
+#endif
+
+//#define __DETAIL_DEBUG__
+//#define __DEBUG_EVENT_HANDLER__
+//#define __PalmFlick_DEBUG__
+//#define __HOLD_DETECTOR_DEBUG__
+
+#ifdef __PalmFlick_DEBUG__
+#define PalmFlickDebugPrint ErrorF
+#else
+#define PalmFlickDebugPrint(...)
+#endif
+
+#ifdef __HOLD_DETECTOR_DEBUG__
+#define HoldDetectorDebugPrint ErrorF
+#else
+#define HoldDetectorDebugPrint(...)
+#endif
+
+
+#ifdef __DETAIL_DEBUG__
+#define DetailDebugPrint ErrorF
+#else
+#define DetailDebugPrint(...)
+#endif
+
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <xorg-server.h>
+#include <xorgVersion.h>
+#include <xf86Module.h>
+#include <X11/Xatom.h>
+#include "gesture.h"
+#include <xorg/mi.h>
+
+#define LOG_TAG        "GESTURE"
+#include "dlog.h"
+
+
+
+char *strcasestr(const char *s, const char *find);
+extern ScreenPtr miPointerCurrentScreen(void);
+static void printk(const char* fmt, ...) __attribute__((format(printf, 1, 0)));
+
+//Basic functions
+static int GesturePreInit(InputDriverPtr  drv, InputInfoPtr pInfo, int flags);
+static void GestureUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags);
+static pointer GesturePlug(pointer module, pointer options, int *errmaj, int  *errmin);
+static void GestureUnplug(pointer p);
+static int GestureControl(DeviceIntPtr    device,int what);
+static int GestureInit(DeviceIntPtr device);
+static void GestureFini(DeviceIntPtr device);
+static void GestureReadInput(InputInfoPtr pInfo);
+
+//other initializers
+ErrorStatus GestureRegionsInit(void);
+
+//event queue handling functions
+ErrorStatus GestureInitEQ(void);
+ErrorStatus GestureFiniEQ(void);
+ErrorStatus GestureEnqueueEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
+ErrorStatus GestureEventsFlush(void);
+void GestureEventsDrop(void);
+
+//utility functions
+ErrorStatus GestureRegionsReinit(void);
+void GestureEnable(int enable, Bool prop, DeviceIntPtr dev);
+void GestureCbEventsGrabbed(Mask *pGrabMask, GestureGrabEventPtr *pGrabEvent);
+void GestureCbEventsSelected(Window win, Mask *pEventMask);
+WindowPtr GestureGetEventsWindow(void);
+static int GestureGetFingerIndexFromDevice(DeviceIntPtr device);
+
+//Enqueued event handlers and enabler/disabler
+static ErrorStatus GestureEnableEventHandler(InputInfoPtr pInfo);
+static ErrorStatus GestureDisableEventHandler(void);
+static CARD32 GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg);
+static CARD32 GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg);
+void GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
+void GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
+void GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
+void GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
+void GestureHandleKeyPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
+void GestureHandleKeyReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device);
+
+void GestureEmulateHWKey(DeviceIntPtr dev, int keycode);
+
+//Gesture recognizer helper
+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 21
+static Bool PointInBorderSize(WindowPtr pWin, int x, int y);
+#endif
+static WindowPtr GestureWindowOnXY(int x, int y);
+Bool GestureHasFingerEventMask(int eventType, int num_finger);
+
+//Gesture recognizer and handlers
+void GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device);
+void GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
+void GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int start_point, int direction);
+void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired);
+void GestureRecognize_PalmFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx);
+void GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int direction);
+void GestureHandleGesture_Tap(int num_finger, int tap_repeat, int cx, int cy);
+void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds);
+ErrorStatus GestureFlushOrDrop(void);
+
+static int GestureGetPalmValuator(InternalEvent *ev, DeviceIntPtr device);
+static int GesturePalmGetAbsAxisInfo(DeviceIntPtr dev);
+static void GestureHoldDetector(int type, InternalEvent *ev, DeviceIntPtr device);
+static int GesturePalmGetScreenInfo();
+static int GesturePalmGetHorizIndexWithX(int current_x, int idx, int type);
+
+void GestureGenerateTouchCancelEvent(void);
+
+static void GestureDPMSCallback(CallbackListPtr *pcbl, void *unused, void *calldata);
+
+#ifdef HAVE_PROPERTIES
+//function related property handling
+static void GestureInitProperty(DeviceIntPtr dev);
+static int GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, BOOL checkonly);
+#endif
+
+static Atom prop_gesture_recognizer_onoff = None;
+
+#ifdef SUPPORT_ANR_WITH_INPUT_EVENT
+static Atom prop_anr_in_input_event = None;
+static Atom prop_anr_event_window = None;
+static Window prop_anr_event_window_xid = None;
+#endif
+
+
+GestureDevicePtr g_pGesture = NULL;
+_X_EXPORT InputDriverRec GESTURE = {
+    1,
+    "gesture",
+    NULL,
+    GesturePreInit,
+    GestureUnInit,
+    NULL,
+    0
+};
+
+static XF86ModuleVersionInfo GestureVersionRec =
+{
+    "gesture",
+    MODULEVENDORSTRING,
+    MODINFOSTRING1,
+    MODINFOSTRING2,
+    XORG_VERSION_CURRENT,
+    PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR,
+    PACKAGE_VERSION_PATCHLEVEL,
+    ABI_CLASS_XINPUT,
+    ABI_XINPUT_VERSION,
+    MOD_CLASS_XINPUT,
+    {0, 0, 0, 0}
+};
+
+_X_EXPORT XF86ModuleData gestureModuleData =
+{
+    &GestureVersionRec,
+    &GesturePlug,
+    &GestureUnplug
+};
+
+extern CallbackListPtr DPMSCallback;
+
+static void
+printk(const char* fmt, ...)
+{
+    static FILE* fp = NULL;
+    static char init = 0;
+    va_list argptr;
+
+    if (!init && !fp)
+    {
+        fp = fopen("/dev/kmsg", "wt");
+        init = 1;
+    }
+
+    if (!fp) return;
+
+    va_start(argptr, fmt);
+    vfprintf(fp, fmt, argptr);
+    fflush(fp);
+    va_end(argptr);
+}
+
+#ifdef SUPPORT_ANR_WITH_INPUT_EVENT
+static WindowPtr
+_GestureFindANRWindow(DeviceIntPtr device)
+{
+    WindowPtr root=NULL;
+    WindowPtr anr_window=NULL;
+    Window anr_xid=0;
+    PropertyPtr pProp;
+    int rc=0;
+
+    root = RootWindow(device);
+
+    if( prop_anr_event_window == None )
+        prop_anr_event_window = MakeAtom(ANR_EVENT_WINDOW, strlen(ANR_EVENT_WINDOW), TRUE);
+
+    rc = dixLookupProperty (&pProp, root, prop_anr_event_window, serverClient, DixReadAccess);
+    if (rc == Success && pProp->data){
+        anr_xid = *(int*)pProp->data;
+    }
+
+    if( anr_xid != 0 )
+    {
+        rc = dixLookupWindow(&anr_window, anr_xid, serverClient, DixSetPropAccess);
+        if( rc == BadWindow )
+        {
+            ErrorF("Can't find ANR window !!\n");
+            anr_window = NULL;
+        }
+        prop_anr_event_window_xid = anr_xid;
+    }
+
+    ErrorF("ANR Window is %#x. Ptr is %#x\n", anr_xid, anr_window);
+    return anr_window;
+}
+#endif
+
+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 21
+static Bool
+PointInBorderSize(WindowPtr pWin, int x, int y)
+{
+    BoxRec box;
+    if (pixman_region_contains_point (&pWin->borderSize, x, y, &box))
+    {
+        return TRUE;
+    }
+    return FALSE;
+}
+#endif
+
+static WindowPtr
+GestureWindowOnXY(int x, int y)
+{
+    WindowPtr pWin;
+    BoxRec box;
+    SpritePtr pSprite;
+    DeviceIntPtr pDev = g_pGesture->master_pointer;
+
+    pSprite = pDev->spriteInfo->sprite;
+    pSprite->spriteTraceGood = 1;      /* root window still there */
+    pWin = RootWindow(pDev)->firstChild;
+
+    while (pWin)
+    {
+        if ((pWin->mapped) &&
+                (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
+                (x < pWin->drawable.x + (int)pWin->drawable.width +
+                 wBorderWidth(pWin)) &&
+                (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
+                (y < pWin->drawable.y + (int)pWin->drawable.height +
+                 wBorderWidth (pWin))
+                /* When a window is shaped, a further check
+                 * is made to see if the point is inside
+                 * borderSize
+                 */
+                && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
+                && (!wInputShape(pWin) ||
+                    RegionContainsPoint(wInputShape(pWin),
+                        x - pWin->drawable.x,
+                        y - pWin->drawable.y, &box))
+#ifdef ROOTLESS
+                /* In rootless mode windows may be offscreen, even when
+                 * they're in X's stack. (E.g. if the native window system
+                 * implements some form of virtual desktop system).
+                 */
+                    && !pWin->rootlessUnhittable
+#endif
+                    )
+                    {
+                        if (pSprite->spriteTraceGood >= pSprite->spriteTraceSize)
+                        {
+                            pSprite->spriteTraceSize += 10;
+                            pSprite->spriteTrace = realloc(pSprite->spriteTrace,
+                                    pSprite->spriteTraceSize*sizeof(WindowPtr));
+                            if (!pSprite->spriteTrace) {
+                                return NULL;
+                            }
+                        }
+                        pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin;
+                        pWin = pWin->firstChild;
+                    }
+        else
+            pWin = pWin->nextSib;
+    }
+    return pSprite->spriteTrace[pSprite->spriteTraceGood-1];
+}
+
+    Bool
+GestureHasFingerEventMask(int eventType, int num_finger)
+{
+    Bool ret = FALSE;
+    Mask eventmask = (1L << eventType);
+
+    if ((g_pGesture->grabMask & eventmask) &&
+            (g_pGesture->GrabEvents[eventType].pGestureGrabWinInfo[num_finger].window != None))
+    {
+        DetailDebugPrint("[GestureHasFingerEventMask] TRUE !! Has grabMask\n");
+        return TRUE;
+    }
+
+    if (g_pGesture->eventMask & eventmask)
+    {
+        DetailDebugPrint("[GestureHasFingerEventMask] TRUE !! Has eventMask\n");
+        return TRUE;
+    }
+
+    DetailDebugPrint("[GestureHasFingerEventMask] FALSE !! eventType=%d, num_finger=%d\n", eventType, num_finger);
+
+    return ret;
+}
+
+static CARD32
+GestureEventTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
+{
+    int event_type = *(int *)arg;
+
+    switch (event_type)
+    {
+        case GestureNotifyHold:
+            DetailDebugPrint("[GestureEventTimerHandler] GestureNotifyHold (event_type = %d)\n", event_type);
+            GestureRecognize_GroupHold(event_type, NULL, NULL, 0, 1);
+            break;
+        case GestureNotifyTap:
+            DetailDebugPrint("[GestureEventTimerHandler] GestureNotifyTap (event_type = %d)\n", event_type);
+            GestureRecognize_GroupTap(event_type, NULL, NULL, 0, 1);
+            break;
+        default:
+            DetailDebugPrint("[GestureEventTimerHandler] unknown event_type (=%d)\n", event_type);
+            if (timer)
+            {
+                DetailDebugPrint("[GestureEventTimerHandler] timer=%x\n", (unsigned int)timer);
+            }
+    }
+
+    return 0;
+}
+
+void
+GestureHandleGesture_Tap(int num_finger, int tap_repeat, int cx, int cy)
+{
+    Window target_win;
+    WindowPtr target_pWin;
+    xGestureNotifyTapEvent tev;
+
+    //skip non-tap events and single finger tap
+    if (!tap_repeat || num_finger <= 1)
+    {
+        return;
+    }
+
+    DetailDebugPrint("[GestureHandleGesture_Tap] num_finger=%d, tap_repeat=%d, cx=%d, cy=%d\n", num_finger, tap_repeat, cx, cy);
+
+    g_pGesture->recognized_gesture |= WTapFilterMask;
+    memset(&tev, 0, sizeof(xGestureNotifyTapEvent));
+    tev.type = GestureNotifyTap;
+    tev.kind = GestureDone;
+    tev.num_finger = num_finger;
+    tev.tap_repeat = tap_repeat;
+    tev.interval = 0;
+    tev.cx = cx;
+    tev.cy = cy;
+
+    target_win = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].window;
+    target_pWin = g_pGesture->GrabEvents[GestureNotifyTap].pGestureGrabWinInfo[num_finger].pWin;
+
+    if (g_pGesture->grabMask && (target_win != None))
+    {
+        tev.window = target_win;
+    }
+    else
+    {
+        tev.window = g_pGesture->gestureWin;
+    }
+
+    DetailDebugPrint("[GestureHandleGesture_Tap] tev.window=0x%x, g_pGesture->grabMask=0x%x\n", (unsigned int)tev.window, (unsigned int)g_pGesture->grabMask);
+
+    GestureSendEvent(target_pWin, GestureNotifyTap, GestureTapMask, (xGestureCommonEvent *)&tev);
+    LOGI("GroupTap Event done. 2 fingers %d tap!", tap_repeat);
+}
+
+void
+GestureHandleGesture_Flick(int num_of_fingers, int distance, Time duration, int direction)
+{
+    if (num_of_fingers == 0)
+    {
+        Window target_win;
+        WindowPtr target_pWin;
+        xGestureNotifyFlickEvent fev;
+
+        DetailDebugPrint("[GestureHandleGesture_Flick] num_fingers=%d, distance=%d, duration=%d, direction=%d\n", num_of_fingers, distance, duration, direction);
+
+        g_pGesture->recognized_gesture |= WPalmFlickFilterMask;
+
+        memset(&fev, 0, sizeof(xGestureNotifyFlickEvent));
+        fev.type = GestureNotifyFlick;
+        fev.kind = GestureDone;
+        fev.num_finger = num_of_fingers;
+        fev.distance = distance;
+        fev.duration = duration;
+        fev.direction = direction;
+
+        if (g_pGesture->GrabEvents)
+        {
+            target_win = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].window;
+            target_pWin = g_pGesture->GrabEvents[GestureNotifyFlick].pGestureGrabWinInfo[num_of_fingers].pWin;
+        }
+        else
+        {
+            target_win = None;
+            target_pWin = None;
+        }
+
+        if (g_pGesture->grabMask && (target_win != None))
+        {
+            fev.window = target_win;
+        }
+        else
+        {
+            fev.window = g_pGesture->gestureWin;
+        }
+
+        DetailDebugPrint("[GestureHandleGesture_Flick] fev.window=0x%x, g_pGesture->grabMask=0x%x\n", fev.window, g_pGesture->grabMask);
+
+        GestureSendEvent(target_pWin, GestureNotifyFlick, GestureFlickMask, (xGestureCommonEvent *)&fev);
+    }
+    else
+    {
+        DetailDebugPrint("[GestureHandleGesture_Flick] num_fingers=%d, distance=%d, duration=%d, direction=%d\n", num_of_fingers, distance, duration, direction);
+
+        switch (direction)
+        {
+            case FLICK_NORTHWARD:
+                DetailDebugPrint("[GestureHandleGesture_Flick] Flick Down \n");
+                GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_down);
+                break;
+
+            case FLICK_SOUTHWARD:
+                DetailDebugPrint("[GestureHandleGesture_Flick] Flick Up \n");
+                GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_up);
+                break;
+            case FLICK_WESTWARD:
+                if (g_pGesture->power_pressed == 2)
+                {
+                    DetailDebugPrint("[GestureHandleGesture_Flick] Flick Right & power_pressed\n");
+                    GestureEmulateHWKey(g_pGesture->hwkey_dev, 122);
+                }
+                break;
+            default:
+                break;
+        }
+        g_pGesture->recognized_gesture |= WFlickFilterMask;
+    }
+}
+
+void GestureHandleGesture_Hold(int num_fingers, int cx, int cy, Time holdtime, int kinds)
+{
+    Window target_win;
+    WindowPtr target_pWin;
+    xGestureNotifyHoldEvent hev;
+
+    DetailDebugPrint("[GestureHandleGesture_Hold] num_fingers=%d, cx=%d, cy=%d, holdtime=%d, kinds=%d\n", num_fingers, cx, cy, holdtime, kinds);
+
+    if (num_fingers == 0)
+    {
+        g_pGesture->hold_detected = TRUE;
+        LOGI("[PalmHold] PalmHold success !\n");
+    }
+    else
+    {
+        g_pGesture->recognized_gesture |= WHoldFilterMask;
+    }
+
+    memset(&hev, 0, sizeof(xGestureNotifyHoldEvent));
+    hev.type = GestureNotifyHold;
+    hev.kind = kinds;
+    hev.num_finger = num_fingers;
+    hev.holdtime = holdtime;
+    hev.cx = cx;
+    hev.cy = cy;
+
+    if (g_pGesture->GrabEvents)
+    {
+        target_win = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].window;
+        target_pWin = g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[num_fingers].pWin;
+    }
+    else
+    {
+        target_win = None;
+        target_pWin = None;
+    }
+
+    if (g_pGesture->grabMask && (target_win != None))
+    {
+        hev.window = target_win;
+    }
+    else
+    {
+        hev.window = g_pGesture->gestureWin;
+    }
+
+    DetailDebugPrint("[GestureHandleGesture_Hold] hev.window=0x%x, g_pGesture->grabMask=0x%x\n", hev.window, g_pGesture->grabMask);
+
+    GestureSendEvent(target_pWin, GestureNotifyHold, GestureHoldMask, (xGestureCommonEvent *)&hev);
+    LOGI("[GroupHold] GestureHold success !\n");
+}
+
+
+void
+GestureRecognize_GroupTap(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
+{
+    static int num_pressed = 0;
+    static int base_area_size = 0;
+
+    int cx, cy;
+    int area_size;
+
+    static int state = 0;
+    static int mbits = 0;
+    static int base_cx;
+    static int base_cy;
+    static pixman_box16_t base_box_ext;
+
+    static int tap_repeat = 0;
+    static int prev_num_pressed = 0;
+
+    static OsTimerPtr tap_event_timer = NULL;
+    static int event_type = GestureNotifyTap;
+
+    if (timer_expired)
+    {
+        DetailDebugPrint("[GroupTap][Timer] state=%d, num_pressed=%d, tap_repeat=%d\n", state, num_pressed, tap_repeat);
+
+        switch (state)
+        {
+            case 1://first tap initiation check
+                if (num_pressed)
+                {
+                    DetailDebugPrint("[GroupTap][Timer][state=1] Tap time expired !(num_pressed=%d, tap_repeat=%d)\n", num_pressed, tap_repeat);
+                    DetailDebugPrint("[GroupTap][F] 1\n");
+
+                    state = 0;
+                    goto cleanup_tap;
+                }
+                break;
+
+            case 2:
+                if (tap_repeat <= 1)
+                {
+                    state = 0;
+                    DetailDebugPrint("[GroupTap][Timer][state=2] 2 finger %d tap\n", tap_repeat);
+                    LOGI("[GroupTap][F] Second tap doesn't come up in 400ms after first tap.\n");
+                    goto cleanup_tap;
+                }
+
+                if (GestureHasFingerEventMask(GestureNotifyTap, prev_num_pressed))
+                {
+                    DetailDebugPrint("[GroupTap] Success 1!! 2 finger %d tap\n", tap_repeat);
+                    GestureHandleGesture_Tap(prev_num_pressed, tap_repeat, base_cx, base_cy);
+                    goto cleanup_tap;
+                }
+                break;
+        }
+        return;
+    }
+
+    switch (type)
+    {
+        case ET_ButtonPress:
+            g_pGesture->fingers[idx].flags |= PressFlagTap;
+
+            if (g_pGesture->num_pressed < 2)
+            {
+                DetailDebugPrint("[GroupTap][P] num_pressed=%d, base_px=%d, base_py=%d. return \n", g_pGesture->num_pressed, g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
+                return;
+            }
+
+            if ((!base_area_size || g_pGesture->num_pressed > num_pressed))
+            {
+                base_area_size = AREA_SIZE(&g_pGesture->area.extents);
+                base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
+                base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
+                base_box_ext.x1 = base_cx-TAP_MOVE_THRESHOLD;
+                base_box_ext.y1 = base_cy-TAP_MOVE_THRESHOLD;
+                base_box_ext.x2 = base_cx+TAP_MOVE_THRESHOLD;
+                base_box_ext.y2 = base_cy+TAP_MOVE_THRESHOLD;
+                state = 1;
+                TimerCancel(tap_event_timer);
+                tap_event_timer = TimerSet(tap_event_timer, 0, g_pGesture->singletap_threshold, GestureEventTimerHandler, (int *)&event_type);
+            }
+            num_pressed = g_pGesture->num_pressed;
+
+            DetailDebugPrint("[GroupTap][P] num_pressed=%d, area_size=%d, base_mx=%d, base_my=%d\n", num_pressed, base_area_size, g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
+            break;
+
+        case ET_Motion:
+            if (!(g_pGesture->fingers[idx].flags & PressFlagTap))
+            {
+                break;
+            }
+
+            if (num_pressed < 2)
+            {
+                DetailDebugPrint("[GroupTap][M] num_pressed=%d, return \n", num_pressed);
+                return;
+            }
+
+            if (num_pressed != g_pGesture->num_pressed)
+            {
+                DetailDebugPrint("[GroupTap][M] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
+            }
+
+            mbits |= (1 << idx);
+            if (mbits == (pow(2, num_pressed)-1))
+            {
+                area_size = AREA_SIZE(&g_pGesture->area.extents);
+                cx = AREA_CENTER_X(&g_pGesture->area.extents);
+                cy = AREA_CENTER_Y(&g_pGesture->area.extents);
+
+                DetailDebugPrint("[GroupTap][M][num_pressed=%d] area_size=%d, base_area_size=%d, diff=%d\n", num_pressed, area_size, base_area_size, ABS(base_area_size - area_size));
+                DetailDebugPrint("[GroupTap][M] cx=%d, base_cx=%d, diff=%d\n", cx, g_pGesture->fingers[idx].mx, ABS(cx-base_cx));
+                DetailDebugPrint("[GroupTap][M] cy=%d, base_cy=%d, diff=%d\n", cy, g_pGesture->fingers[idx].my, ABS(cy-base_cy));
+
+                if (ABS(base_area_size-area_size) >= TAP_AREA_THRESHOLD)
+                {
+                    DetailDebugPrint("[GroupTap][M] diff between area size(=%d) and base area size(=%d) is bigger than threshold(=%d)!\n", area_size, base_area_size, ABS(base_area_size-area_size));
+                    DetailDebugPrint("[GroupTap][F] 3\n");
+                    LOGI("[GroupTap][F] diff between area size(=%d) and base area size(=%d) is bigger than threshold(=%d)!\n", area_size, base_area_size, ABS(base_area_size-area_size));
+
+                    goto cleanup_tap;
+                }
+
+                if (!INBOX(&base_box_ext, cx, cy))
+                {
+                    DetailDebugPrint("[GroupTap][M] current center coordinates is not in base coordinates box !\n");
+                    DetailDebugPrint("[GroupTap][F] 4\n");
+                    LOGI("[GroupTap][F] current center coordinates is not in base coordinates box !\n");
+
+                    goto cleanup_tap;
+                }
+            }
+            break;
+
+        case ET_ButtonRelease:
+            if (g_pGesture->num_pressed)
+            {
+                DetailDebugPrint("[GroupTap][R] Second finger doesn't come up. g_pGesture->num_pressed=%d\n", g_pGesture->num_pressed);
+                break;
+            }
+
+            if (!tap_repeat)
+            {
+                prev_num_pressed = num_pressed;
+            }
+
+            tap_repeat++;
+            g_pGesture->num_tap_repeated = tap_repeat;
+
+            DetailDebugPrint("[GroupTap][R] tap_repeat=%d, num_pressed=%d, prev_num_pressed=%d\n", tap_repeat, num_pressed, prev_num_pressed);
+            DetailDebugPrint("[GroupTap][R] base_rx=%d, base_ry=%d,\n", g_pGesture->fingers[idx].rx, g_pGesture->fingers[idx].ry);
+
+            if ((num_pressed != prev_num_pressed) || (!GestureHasFingerEventMask(GestureNotifyTap, num_pressed)))
+            {
+                DetailDebugPrint("[GroupTap][R] num_pressed(=%d) != prev_num_pressed(=%d) OR %d finger tap event was not grabbed/selected !\n",
+                        num_pressed, prev_num_pressed, num_pressed);
+                DetailDebugPrint("[GroupTap][F] 5\n");
+                LOGI("[GroupTap][F] num_pressed(=%d) != prev_num_pressed(=%d) OR %d finger tap event was not grabbed/selected !\n",
+                        num_pressed, prev_num_pressed, num_pressed);
+                goto cleanup_tap;
+            }
+
+            if (tap_repeat == 1)
+            {
+                DetailDebugPrint("[GroupTap][R] %d finger %d tap\n", num_pressed, tap_repeat);
+                TimerCancel(tap_event_timer);
+                tap_event_timer = TimerSet(tap_event_timer, 0, g_pGesture->doubletap_threshold, GestureEventTimerHandler, (int *)&event_type);
+                state = 2;
+                prev_num_pressed = num_pressed;
+                num_pressed = 0;
+                break;
+            }
+
+            else if (tap_repeat == 2)
+            {
+                DetailDebugPrint("[GroupTap][R] %d finger %d tap\n", num_pressed, tap_repeat);
+                TimerCancel(tap_event_timer);
+                tap_event_timer = TimerSet(tap_event_timer, 0, g_pGesture->tripletap_threshold, GestureEventTimerHandler, (int *)&event_type);
+                state = 2;
+                base_area_size = num_pressed = 0;
+                break;
+            }
+
+            DetailDebugPrint("[GroupTap][R] %d finger %d tap\n", num_pressed, tap_repeat);
+
+            if (tap_repeat == MAX_TAP_REPEATS)
+            {
+                if (GestureHasFingerEventMask(GestureNotifyTap, num_pressed))
+                {
+                    DetailDebugPrint("[GroupTap] Sucess 2!\n");
+                    GestureHandleGesture_Tap(num_pressed, tap_repeat, base_cx, base_cy);
+                }
+                goto cleanup_tap;
+            }
+
+            if (tap_repeat >= MAX_TAP_REPEATS)
+            {
+                LOGI("[GroupTap][F] More than 3 taps. Ignore. \n");
+                goto cleanup_tap;
+            }
+
+            prev_num_pressed = num_pressed;
+            num_pressed = 0;
+            break;
+    }
+
+    return;
+
+cleanup_tap:
+
+    DetailDebugPrint("[GroupTap][cleanup_tap]\n");
+
+    if (0 == state)
+    {
+        g_pGesture->recognized_gesture &= ~WTapFilterMask;
+    }
+
+    g_pGesture->filter_mask |= WTapFilterMask;
+
+    if (g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL)
+    {
+        DetailDebugPrint("[GroupTap][cleanup] GestureFlushOrDrop() !\n");
+
+        if (ERROR_INVALPTR == GestureFlushOrDrop())
+        {
+            GestureControl(g_pGesture->this_device, DEVICE_OFF);
+        }
+    }
+
+    num_pressed = 0;
+    g_pGesture->num_tap_repeated = tap_repeat = 0;
+    prev_num_pressed = 0;
+    mbits = 0;
+    state = 0;
+    TimerCancel(tap_event_timer);
+    return;
+}
+
+void
+GestureRecognize_GroupFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int start_point, int direction)
+{
+    static int num_pressed = 0;
+    static Time base_time = 0;
+    Time duration;
+    int distance;
+    static int diff_base_coord = 0;
+    static int diff_base_minor_coord = 0;
+    static int diff_current_coord = 0;
+    static int false_diff_count = 0;
+    static int false_minor_diff_count = 0;
+    static float angle = 0.0f;
+    static int angle_base_x = 0, angle_base_y = 0;
+    static int motion_count = 0;
+
+    if (g_pGesture->num_pressed > 1)
+    {
+        DetailDebugPrint("[GroupFlick][F] 1\n");
+        goto cleanup_flick;
+    }
+
+    if ((start_point <= FLICK_POINT_NONE) || (FLICK_POINT_MAX <= start_point))
+    {
+        DetailDebugPrint("[GroupFlick][F] 2\n");
+        goto cleanup_flick;
+    }
+
+    switch (type)
+    {
+        case ET_ButtonPress:
+            g_pGesture->fingers[idx].flags = PressFlagFlick;
+            base_time = GetTimeInMillis();
+            num_pressed = g_pGesture->num_pressed;
+            switch (start_point)
+            {
+                case FLICK_POINT_UP:
+                    if (g_pGesture->fingers[idx].py > g_pGesture->flick_press_area)
+                    {
+                        DetailDebugPrint("[GroupFlick][FlickDown][P] press coord is out of bound. (%d, %d)\n",
+                                g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
+                        DetailDebugPrint("[GroupFlick][F] 3\n");
+                        //LOGI("[BackKey][F] press coord is out of bound (40 pixel from upper vezel). press y=%d\n", g_pGesture->fingers[idx].py);
+                        goto cleanup_flick;
+                    }
+
+                    angle_base_y = diff_base_coord = diff_current_coord = g_pGesture->fingers[idx].py;
+                    angle_base_x = g_pGesture->fingers[idx].px;
+                    DetailDebugPrint("[GroupFlick][FlickDown][P] px=%d, py=%d\n", g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
+                    break;
+
+                case FLICK_POINT_DOWN:
+                    if (g_pGesture->fingers[idx].py < g_pGesture->screen_height - g_pGesture->flick_press_area)
+                    {
+                        DetailDebugPrint("[GroupFlick][FlickUp][P] press coord is out of bound. (%d, %d)\n",
+                                g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
+                        DetailDebugPrint("[GroupFlick][F] 4\n");
+                        goto cleanup_flick;
+                    }
+                    angle_base_y = diff_base_coord = diff_current_coord = g_pGesture->fingers[idx].py;
+                    angle_base_x = g_pGesture->fingers[idx].px;
+                    break;
+
+                case FLICK_POINT_LEFT:
+                    if (g_pGesture->fingers[idx].px > g_pGesture->flick_press_area)
+                    {
+                        DetailDebugPrint("[GroupFlick][FlickLeft][P] press coord is out of bound. (%d, %d)\n",
+                                g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
+                        DetailDebugPrint("[GroupFlick][F] 5\n");
+                        goto cleanup_flick;
+                    }
+                    angle_base_y = diff_base_coord = diff_current_coord = g_pGesture->fingers[idx].py;
+                    angle_base_x = g_pGesture->fingers[idx].px;
+                    break;
+
+                default:
+                    DetailDebugPrint("[GroupFlick][F] 6\n");
+                    goto cleanup_flick;
+                    break;
+            }
+
+            break;
+
+        case ET_Motion:
+
+            motion_count++;
+
+            if (motion_count > 15)
+            {
+                DetailDebugPrint("[GroupFlick][F] 6-1 motion_count=%d\n", motion_count);
+                LOGI("[BackKey][F] More than 15 motion.\n");
+                goto cleanup_flick;
+            }
+
+            if (!(g_pGesture->fingers[idx].flags & PressFlagFlick))
+            {
+                break;
+            }
+
+            switch (start_point)
+            {
+                case FLICK_POINT_UP:
+                    diff_base_coord = diff_current_coord;
+                    diff_current_coord = g_pGesture->fingers[idx].my;
+
+                    if ((diff_current_coord - diff_base_coord) < 0)
+                    {
+                        DetailDebugPrint("[GroupFlick][FlickDown][M] false_diff\n");
+                        false_diff_count++;
+                    }
+
+                    if (false_diff_count > FLICK_FALSE_Y_DIFF_COUNT)
+                    {
+                        DetailDebugPrint("[GroupFlick][FlickDown][M] false_diff_count: %d > %d\n",
+                                false_diff_count, FLICK_FALSE_Y_DIFF_COUNT);
+                        DetailDebugPrint("[GroupFlick][F] 7\n");
+                        LOGI("[BackKey][F] Direction is wrong for 7 times.\n");
+                        goto cleanup_flick;
+                    }
+
+                    if ((g_pGesture->fingers[idx].my < g_pGesture->flick_press_area) &&
+                            (abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px) >(int)( g_pGesture->screen_width/2)))
+                    {
+                        DetailDebugPrint("[GroupFlick][FlickDown][M] move x: %d - %d, y coord: %d\n",
+                                g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].my);
+                        DetailDebugPrint("[GroupFlick][F] 8\n");
+                        LOGI("[BackKey][F] From press point, moving x axis is more than half screen size.\n");
+                        goto cleanup_flick;
+                    }
+
+                    if ((g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py) > g_pGesture->flick_minimum_height)
+                    {
+                        DetailDebugPrint("[GroupFlick][FlickDown][M] %d - %d < %d(min_size), angle_base_coord (%d, %d)\n",
+                                g_pGesture->fingers[idx].my, g_pGesture->fingers[idx].py, g_pGesture->flick_minimum_height, angle_base_x, angle_base_y);
+
+                        if (abs(g_pGesture->fingers[idx].mx - angle_base_x) == 0)
+                        {
+                            DetailDebugPrint("[GroupFlick][FlickDown][M] abs(%d - %d) = 0\n",
+                                    g_pGesture->fingers[idx].mx, angle_base_x);
+                            angle = 1.0f;
+                        }
+                        else
+                        {
+                            DetailDebugPrint("[GroupFlick][FlickDown][M] angle_base_x: %d, angle_base_y: %d\n",
+                                    angle_base_x, angle_base_y);
+                            int y_diff = abs(g_pGesture->fingers[idx].my - angle_base_y);
+                            int x_diff = abs(g_pGesture->fingers[idx].mx - angle_base_x);
+                            angle = (float)y_diff / (float)x_diff;
+                        }
+
+                        if (angle < 0.23f)
+                        {
+                            DetailDebugPrint("[GroupFlick][FlickDown][M][F] %d / %d = %f (angle)\n",
+                                    abs(g_pGesture->fingers[idx].my - angle_base_y), abs(g_pGesture->fingers[idx].mx - angle_base_x), angle);
+                            DetailDebugPrint("[GroupFlick][F] 9\n");
+                            LOGI("[BackKey][F] angle is improper. %d < 0.23\n", angle);
+                            goto cleanup_flick;
+                        }
+
+                        distance = g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py;
+                        duration = GetTimeInMillis() - base_time;
+
+                        GestureHandleGesture_Flick(num_pressed, distance, duration, direction);
+                        DetailDebugPrint("[GroupFlick][FlickDown][M] FlickDown Done!!\n");
+                        goto cleanup_flick_recognized;
+                    }
+                    else
+                    {
+                        if ((g_pGesture->fingers[idx].mx - diff_base_minor_coord) < 0)
+                        {
+                            false_minor_diff_count++;
+                        }
+
+                        if (false_minor_diff_count> FLICK_FALSE_X_DIFF_COUNT)
+                        {
+                            DetailDebugPrint("[GroupFlick][FlickDown][M] false_minor_diff_count: %d > %d\n",
+                                    false_minor_diff_count, FLICK_FALSE_X_DIFF_COUNT);
+                            DetailDebugPrint("[GroupFlick][F] 10\n");
+                            goto cleanup_flick;
+                        }
+                    }
+
+                    if (g_pGesture->fingers[idx].my < g_pGesture->flick_press_area)
+                    {
+                        angle_base_x = g_pGesture->fingers[idx].px;
+                        angle_base_y = g_pGesture->fingers[idx].py;
+                    }
+                    DetailDebugPrint("[GroupFlick][FlickDown][M] mx=%d, my=%d, diff_x=%d, diff_y=%d\n",
+                            g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].my, abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px), abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py));
+
+                    break;
+
+                case FLICK_POINT_DOWN:
+                    diff_base_coord = diff_current_coord;
+                    diff_current_coord = g_pGesture->fingers[idx].my;
+
+                    if ((diff_base_coord - diff_current_coord) < 0)
+                    {
+                        false_diff_count++;
+                    }
+
+                    if (false_diff_count > FLICK_FALSE_Y_DIFF_COUNT)
+                    {
+                        DetailDebugPrint("[GroupFlick][FlickUp][M] false_diff_count: %d > %d\n",
+                                false_diff_count, FLICK_FALSE_Y_DIFF_COUNT);
+                        DetailDebugPrint("[GroupFlick][F] 11\n");
+                        goto cleanup_flick;
+                    }
+
+                    if ((g_pGesture->fingers[idx].py - g_pGesture->fingers[idx].my) > g_pGesture->flick_minimum_height)
+                    {
+                        DetailDebugPrint("[GroupFlick][FlickUp][R] %d - %d < %d(min_size)\n",
+                                g_pGesture->fingers[idx].my, g_pGesture->fingers[idx].py, g_pGesture->flick_minimum_height);
+                        if (abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px) == 0)
+                        {
+                            DetailDebugPrint("[GroupFlick][FlickUp][R] abs(%d - %d) = 0\n",
+                                    g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].px);
+                            angle = 1.0f;
+                        }
+                        else
+                        {
+                            int y_diff = abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py);
+                            int x_diff = abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px);
+                            angle = (float)y_diff / (float)x_diff;
+                        }
+
+                        if (angle <0.5f)
+                        {
+                            DetailDebugPrint("[GroupFlick][FlickUp][R] %d / %d = %f (angle)\n",
+                                    abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py), abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px), angle);
+                            DetailDebugPrint("[GroupFlick][F] 12\n");
+                            goto cleanup_flick;
+                        }
+
+                        distance = g_pGesture->fingers[idx].py - g_pGesture->fingers[idx].my;
+                        duration = GetTimeInMillis() - base_time;
+
+                        GestureHandleGesture_Flick(num_pressed, distance, duration, direction);
+                        goto cleanup_flick_recognized;
+                    }
+                    break;
+
+                case FLICK_POINT_LEFT:
+                    diff_base_coord = diff_current_coord;
+                    diff_current_coord = g_pGesture->fingers[idx].mx;
+
+                    if ((diff_current_coord - diff_base_coord) < 0)
+                    {
+                        false_diff_count++;
+                    }
+
+                    if (false_diff_count > FLICK_FALSE_Y_DIFF_COUNT)
+                    {
+                        DetailDebugPrint("[GroupFlick][FlickLeft][M] false_diff_count: %d > %d\n",
+                                false_diff_count, FLICK_FALSE_Y_DIFF_COUNT);
+                        DetailDebugPrint("[GroupFlick][F] 13\n");
+                        goto cleanup_flick;
+                    }
+
+                    if ((g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px) > g_pGesture->flick_minimum_height)
+                    {
+                        DetailDebugPrint("[GroupFlick][FlickLeft][M] %d - %d < %d(min_size)\n",
+                                g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].px, g_pGesture->flick_minimum_height);
+
+                        if (abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py) == 0)
+                        {
+                            DetailDebugPrint("[GroupFlick][FlickLeft][M] abs(%d - %d) = 0\n",
+                                    g_pGesture->fingers[idx].my, g_pGesture->fingers[idx].py);
+                            angle = 1.0f;
+                        }
+                        else
+                        {
+                            int y_diff = abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py);
+                            int x_diff = abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px);
+                            angle = (float)x_diff / (float)y_diff;
+                        }
+
+                        if ( angle < 0.5f)
+                        {
+                            DetailDebugPrint("[GroupFlick][FlickLeft][M] %d / %d = %f (angle)\n",
+                                    abs(g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px), abs(g_pGesture->fingers[idx].my - g_pGesture->fingers[idx].py), angle);
+                            DetailDebugPrint("[GroupFlick][F] 14\n");
+                            goto cleanup_flick;
+                        }
+
+                        distance = g_pGesture->fingers[idx].mx - g_pGesture->fingers[idx].px;
+                        duration = GetTimeInMillis() - base_time;
+
+                        GestureHandleGesture_Flick(num_pressed, distance, duration, direction);
+                        goto cleanup_flick_recognized;
+                    }
+
+                    break;
+                default:
+                    DetailDebugPrint("[GroupFlick][F] 15\n");
+                    goto cleanup_flick;
+                    break;
+            }
+            break;
+
+        case ET_ButtonRelease:
+            DetailDebugPrint("[GroupFlick][R][F] 16\n");
+            goto cleanup_flick;
+            break;
+    }
+
+    return;
+
+cleanup_flick:
+    DetailDebugPrint("[GroupFlick] cleanup_flick \n");
+    g_pGesture->recognized_gesture &= ~WFlickFilterMask;
+    motion_count = 0;
+
+cleanup_flick_recognized:
+    DetailDebugPrint("[GroupFlick] Flick recognized !\n");
+    g_pGesture->filter_mask |= WFlickFilterMask;
+    num_pressed = 0;
+    base_time = 0;
+    false_diff_count = 0;
+    diff_base_coord = 0;
+    diff_current_coord = 0;
+    angle = 0.0f;
+    angle_base_x = angle_base_y = 0;
+    motion_count = 0;
+    return;
+}
+
+void GestureRecognize_GroupHold(int type, InternalEvent *ev, DeviceIntPtr device, int idx, int timer_expired)
+{
+    static int num_pressed = 0;
+    static int base_area_size = 0;
+    static Time base_time = 0;
+    static int base_cx;
+    static int base_cy;
+    int cx, cy;
+    static pixman_box16_t base_box_ext;
+    int area_size;
+    static int state = GestureEnd;
+
+    static OsTimerPtr hold_event_timer = NULL;
+    static int event_type = GestureNotifyHold;
+
+    if (timer_expired)
+    {
+        if (state <= GestureBegin)
+        {
+            state++;
+        }
+
+        switch (state)
+        {
+            case GestureBegin:
+                DetailDebugPrint("[GroupHold] HOLD Begin !\n");
+                break;
+
+            case GestureUpdate:
+                DetailDebugPrint("[GroupHold] HOLD Update !\n");
+                break;
+        }
+
+        if (GestureHasFingerEventMask(GestureNotifyHold, num_pressed))
+        {
+            DetailDebugPrint("[GroupHold] Success 1! \n");
+            GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state);
+
+            // one more time
+            hold_event_timer = TimerSet(hold_event_timer, 0, g_pGesture->hold_time_threshold, GestureEventTimerHandler, (int *)&event_type);
+        }
+        return;
+    }
+
+    switch (type)
+    {
+        case ET_ButtonPress:
+            g_pGesture->fingers[idx].flags |= PressFlagHold;
+
+            if (g_pGesture->num_pressed < 2)
+            {
+                DetailDebugPrint("[GroupHold][P] No num_finger changed ! num_pressed=%d\n", num_pressed);
+                DetailDebugPrint("[GroupHold][F] 0\n");
+                return;
+            }
+
+            if (!base_area_size || g_pGesture->num_pressed > num_pressed)
+            {
+                if (state != GestureEnd)
+                {
+                    DetailDebugPrint("[GroupHold][P][cleanup] No num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
+                    DetailDebugPrint("[GroupHold][F] 1\n");
+
+                    goto cleanup_hold;
+                }
+
+                base_area_size = AREA_SIZE(&g_pGesture->area.extents);
+                base_cx = AREA_CENTER_X(&g_pGesture->area.extents);
+                base_cy = AREA_CENTER_Y(&g_pGesture->area.extents);
+                base_time = GetTimeInMillis();
+
+                base_box_ext.x1 = base_cx-g_pGesture->hold_move_threshold;
+                base_box_ext.y1 = base_cy-g_pGesture->hold_move_threshold;
+                base_box_ext.x2 = base_cx+g_pGesture->hold_move_threshold;
+                base_box_ext.y2 = base_cy+g_pGesture->hold_move_threshold;
+
+                event_type = GestureNotifyHold;
+
+                hold_event_timer = TimerSet(hold_event_timer, 0, g_pGesture->hold_time_threshold, GestureEventTimerHandler, (int *)&event_type);
+            }
+            num_pressed = g_pGesture->num_pressed;
+
+            DetailDebugPrint("[GroupHold][P] num_pressed=%d area_size=%d, base_cx=%d, base_cy=%d\n", num_pressed, base_area_size, base_cx, base_cy);
+
+            break;
+
+        case ET_Motion:
+            if (!(g_pGesture->fingers[idx].flags & PressFlagHold))
+            {
+                DetailDebugPrint("[GroupHold][M] No PressFlagHold\n");
+                break;
+            }
+
+            if (num_pressed < 2)
+            {
+                DetailDebugPrint("[GroupHold][M] No num_finger changed ! num_pressed=%d\n", num_pressed);
+                DetailDebugPrint("[GroupHold][F] 2\n");
+                return;
+            }
+
+            if (num_pressed != g_pGesture->num_pressed)
+            {
+                if (state != GestureEnd)
+                {
+                    DetailDebugPrint("[GroupHold][M][cleanup] No num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
+                    DetailDebugPrint("[GroupHold][F] 3\n");
+                    goto cleanup_hold;
+                }
+
+                DetailDebugPrint("[GroupHold][M] num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
+            }
+
+            area_size = AREA_SIZE(&g_pGesture->area.extents);
+            cx = AREA_CENTER_X(&g_pGesture->area.extents);
+            cy = AREA_CENTER_Y(&g_pGesture->area.extents);
+
+            DetailDebugPrint("[GroupHold][M] num_pressed=%d area_size=%d, base_area_size=%d, diff=%d\n", num_pressed, area_size, base_area_size, ABS(base_area_size - area_size));
+            DetailDebugPrint("[GroupHold][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
+            DetailDebugPrint("[GroupHold][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
+
+            if (area_size > 0 && base_area_size > 0)
+            {
+                if (((area_size > base_area_size) ? (double)area_size / (double)base_area_size : (double)base_area_size / (double) area_size) >= g_pGesture->hold_area_threshold)
+                {
+                    DetailDebugPrint("[GroupHold][M] No diff between area size(=%d) and base area size(=%d) is bigger than threshold(=%lf)!\n", area_size, base_area_size, ((area_size > base_area_size) ? (double)area_size / (double)base_area_size : (double)base_area_size / (double) area_size));
+                    DetailDebugPrint("[GroupHold][F] 4\n");
+                    goto cleanup_hold;
+                }
+            }
+
+            if (!INBOX(&base_box_ext, cx, cy))
+            {
+                DetailDebugPrint("[GroupHold][M] No current center coordinates is not in base coordinates box !\n");
+                DetailDebugPrint("[GroupHold][M] cx=%d, base_cx=%d, diff=%d\n", cx, base_cx, ABS(cx-base_cx));
+                DetailDebugPrint("[GroupHold][M] cy=%d, base_cy=%d, diff=%d\n", cy, base_cy, ABS(cy-base_cy));
+                DetailDebugPrint("[GroupHold][F] 5\n");
+                goto cleanup_hold;
+            }
+            break;
+
+        case ET_ButtonRelease:
+            if (state != GestureEnd && num_pressed >= 2)
+            {
+                DetailDebugPrint("[GroupHold][R] No num_finger changed ! num_pressed=%d, g_pGesture->num_pressed=%d\n", num_pressed, g_pGesture->num_pressed);
+                DetailDebugPrint("[GroupHold][F] 6\n");
+                goto cleanup_hold;
+            }
+
+            if (g_pGesture->num_pressed)
+            {
+                DetailDebugPrint("[GroupHold][R] num_pressed=%d\n", num_pressed);
+                DetailDebugPrint("[GroupHold][F] 7\n");
+                break;
+            }
+
+            goto cleanup_hold;
+            break;
+    }
+
+    return;
+
+cleanup_hold:
+
+    DetailDebugPrint("[GroupHold][cleanup_hold] enter!\n");
+
+    if (state == GestureBegin || state == GestureUpdate)
+    {
+        state = GestureEnd;
+        if (GestureHasFingerEventMask(GestureNotifyHold, num_pressed))
+        {
+            DetailDebugPrint("[GroupHold] Success 2!\n");
+            GestureHandleGesture_Hold(num_pressed, base_cx, base_cy, GetTimeInMillis()-base_time, state);
+        }
+    }
+    else
+    {
+        g_pGesture->recognized_gesture &= ~WHoldFilterMask;
+    }
+
+    g_pGesture->filter_mask |= WHoldFilterMask;
+    num_pressed = 0;
+    base_area_size = 0;
+    base_time = 0;
+    base_cx = base_cy = 0;
+    state = GestureEnd;
+    base_box_ext.x1 = base_box_ext.x2 = base_box_ext.y1 = base_box_ext.y2 = 0;
+    TimerCancel(hold_event_timer);
+    return;
+}
+
+int
+GestureGetMaxTmajor(InternalEvent *ev, int max_tmajor)
+{
+    int mt_tmajor_idx = g_pGesture->tmajor_idx;
+    int mt_tmajor = 0;
+
+    DeviceEvent *de = &ev->device_event;
+
+    if (!de)
+    {
+        DetailDebugPrint("[GestureGetMaxTmajor] de is NULL !\n");
+        return -1;
+    }
+
+    if (mt_tmajor_idx < 0)
+    {
+        DetailDebugPrint("[GestureGetMaxTmajor] One or more of axes are not supported !\n");
+        return -1;
+    }
+
+    mt_tmajor = de->valuators.data[mt_tmajor_idx];
+
+    DetailDebugPrint("[GestureGetMaxTmajor]mt_tmajor_idx=%d, mt_tmajor=%d, max_tmajor=%d\n", mt_tmajor_idx, mt_tmajor, max_tmajor);
+
+    return ((mt_tmajor > max_tmajor) ? mt_tmajor : max_tmajor);
+
+}
+
+void
+GestureRecognize_PalmFlick(int type, InternalEvent *ev, DeviceIntPtr device, int idx)
+{
+    // static int num_pressed = 0;
+    static int base_time = 0, current_time = 0;
+    static int base_x[MAX_MT_DEVICES] = {0}, base_y[MAX_MT_DEVICES] = {0};
+    static int update_x[MAX_MT_DEVICES] = {0}, update_y[MAX_MT_DEVICES] = {0};
+
+
+    static int current_x[MAX_MT_DEVICES] = {0}, current_y[MAX_MT_DEVICES] = {0};
+    static Bool press_status[MAX_MT_DEVICES] = {FALSE, FALSE};
+    static Bool release_status[MAX_MT_DEVICES] = {FALSE, FALSE};
+
+    static int line_idx[MAX_MT_DEVICES] = {0}, prev_line_idx[MAX_MT_DEVICES] = {0}, press_idx[MAX_MT_DEVICES] = {0};
+    static Bool is_line_invalid[MAX_MT_DEVICES] = {TRUE, TRUE};
+
+    static int max_tmajor[MAX_MT_DEVICES] = {0};
+    static int total_max_tmajor = 0;
+    static Bool is_tmajor_invalid[MAX_MT_DEVICES] = {TRUE, TRUE};
+
+    static int mt_sync_count[MAX_MT_DEVICES] = {0};
+
+    static Bool is_palm = FALSE;
+    PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
+
+    static Bool is_retry = FALSE;
+
+    int distance, direction, duration;
+
+    if (g_pGesture->recognized_gesture && !(g_pGesture->recognized_gesture & WPalmFlickFilterMask))
+    {
+        PalmFlickDebugPrint("[PalmFlick] recognize other gesture already( g_pGesture->recognized_gesture: %d)\n", g_pGesture->recognized_gesture);
+        PalmFlickDebugPrint("[PalmFlick][F] 1\n");
+        goto flick_failed;
+    }
+
+    // only first finger recognize
+    if (!(idx == 0 || idx == 1))
+    {
+        PalmFlickDebugPrint("[PalmFlick] idx=%d, least two fingers come on\n", idx);
+        return;
+    }
+
+    switch (type)
+    {
+        case ET_ButtonPress:
+
+            if (!is_palm)
+            {
+                if (idx == 0)
+                {
+                    base_time = GetTimeInMillis();
+                }
+
+                // press (x,y), touch major
+                update_x[idx] = base_x[idx] = g_pGesture->fingers[idx].px;
+                update_y[idx] = base_y[idx] = g_pGesture->fingers[idx].py;
+                max_tmajor[idx] = g_pGesture->max_mt_tmajor[idx];
+                press_status[idx] = TRUE;
+                is_tmajor_invalid[idx] = FALSE;
+                is_line_invalid[idx] = FALSE;
+
+                total_max_tmajor = (total_max_tmajor > max_tmajor[idx]) ? total_max_tmajor : max_tmajor[idx];
+
+                // press region
+                press_idx[idx] = prev_line_idx[idx] = line_idx[idx] = GesturePalmGetHorizIndexWithX(base_x[idx], idx, type);
+
+                PalmFlickDebugPrint("[PalmFlick][P] idx: %d, num_pressed: %d\n", idx, g_pGesture->num_pressed);
+                PalmFlickDebugPrint("[PalmFlick][P] base_time: %d, base_x: %d, base_y: %d, line_idx: %d, touch_major=%d\n",
+                        base_time, base_x[idx], base_y[idx], line_idx[idx], max_tmajor[idx]);
+
+                // invalid region
+                if (line_idx[idx] < 0 || line_idx[idx] >= PALM_HORIZ_ARRAY_COUNT)
+                {
+                    PalmFlickDebugPrint("[PalmFlick][P][F] No line_idx is invalid.. base_x: %d, line_idx: %d\n", base_x[idx], line_idx[idx]);
+                    PalmFlickDebugPrint("[PalmFlick][F] 2\n");
+                    goto flick_failed;
+                }
+
+                // check press point when there are two fingers
+                if (idx == 1)
+                {
+                    if (press_idx[0] != press_idx[1])
+                    {
+                        PalmFlickDebugPrint("[PalmFlick] Press line_idx is the different between two fingers. 1st finger_line_idx=%d, 2nd finger_line_idx=%d\n",
+                                press_idx[0], press_idx[1]);
+                        PalmFlickDebugPrint("[PalmFlick][F] 2-1\n");
+                        goto flick_failed;
+                    }
+                }
+            }
+            else
+            {
+                update_x[idx] = g_pGesture->fingers[idx].px;
+                update_y[idx] = g_pGesture->fingers[idx].py;
+
+                PalmFlickDebugPrint("[PalmFlick][P] Already palm flick success. base_x=%d, base_y=%d, update_x=%d, update_y=%d\n",
+                        base_x[idx], base_y[idx], update_x[idx], update_y[idx]);
+            }
+
+            break;
+
+        case ET_Motion:
+
+            if (total_max_tmajor > g_pGesture->palm_flick_max_tmajor_threshold)
+            {
+                mt_sync_count[idx]++;
+                is_palm = TRUE;
+                DetailDebugPrint("[PalmFlick][M] Sufficient touch enough ! max_tmajor=%d\n", total_max_tmajor);
+                break;
+            }
+
+            // motion information (touch major, x, y)
+            current_x[idx] = g_pGesture->fingers[idx].mx;
+            current_y[idx] = g_pGesture->fingers[idx].my;
+            max_tmajor[idx] = g_pGesture->max_mt_tmajor[idx];
+            mt_sync_count[idx]++;
+
+            //int temp_total_max_tmajor = (idx == 0 ? max_tmajor[0] : max_tmajor[0] + max_tmajor[1]);
+            int temp_total_max_tmajor = max_tmajor[idx];
+            total_max_tmajor = (total_max_tmajor > temp_total_max_tmajor ? total_max_tmajor : temp_total_max_tmajor);
+
+            PalmFlickDebugPrint("[PalmFlick][M] idx=%d, total_max_tmajor=%d, max_tmajor[0]=%d, max_tmajor[1]=%d, current current=(%d, %d)\n",
+                    idx, total_max_tmajor, max_tmajor[0], max_tmajor[1], current_x[idx], current_y[idx]);
+
+            // exception vezel end line motion
+            if (current_x[idx] < 5 || current_x[idx] > 355)
+            {
+                if (total_max_tmajor >= g_pGesture->palm_flick_max_tmajor_threshold)
+                {
+                    PalmFlickDebugPrint("[PalmFlick][M][Vezel] Sufficient touch major was came(%d)\n", total_max_tmajor);
+                    is_palm = TRUE;
+                }
+                else
+                {
+                    mt_sync_count[idx]--;
+                    PalmFlickDebugPrint("[PalmFlick][M] Except vezel end line condition. x=%d, sync_count=%d \n",
+                            current_x[idx], mt_sync_count[idx]);
+                }
+                break;
+            }
+
+            // get current position
+            line_idx[idx] = GesturePalmGetHorizIndexWithX(current_x[idx], idx, type);
+
+            PalmFlickDebugPrint("[PalmFlick][M] line_idx: %d, prev_line_idx: %d, sync_count: %d\n",
+                    line_idx[idx], prev_line_idx[idx], mt_sync_count[idx]);
+
+            //error check
+            if (line_idx[idx] < 0 || line_idx[idx] >= PALM_HORIZ_ARRAY_COUNT)
+            {
+                PalmFlickDebugPrint("[PalmFlick][M][F] No line_idx is invalid.. base_x: %d, line_idx: %d\n", base_x[idx], line_idx[idx]);
+                PalmFlickDebugPrint("[PalmFlick][F] 3\n");
+                goto flick_failed;
+            }
+
+            // screen capture motion validation
+            if (line_idx[idx] != prev_line_idx[idx])
+            {
+                if (base_x[idx] <= pPalmMisc->horiz_coord[0])
+                {
+                    if (line_idx[idx] < prev_line_idx[idx])
+                    {
+                        PalmFlickDebugPrint("[PalmFlick][M][F] Invalid line_idx.. line_idx: %d, prev_line_idx: %d, pPalmMisc->horiz_coord[0]: %d\n",
+                                line_idx[idx], prev_line_idx[idx], pPalmMisc->horiz_coord[0]);
+
+                        is_line_invalid[idx] = TRUE;
+
+                        if (is_line_invalid[0] && is_line_invalid[1])
+                        {
+                            PalmFlickDebugPrint("[PalmFlick][F] 4\n");
+                            goto flick_failed;
+                        }
+                    }
+                }
+                else if (base_x[idx] >= pPalmMisc->horiz_coord[PALM_HORIZ_ARRAY_COUNT-1])
+                {
+                    if (line_idx[idx] > prev_line_idx[idx])
+                    {
+                        PalmFlickDebugPrint("[PalmFlick][M][F] Invalid line_idx.. line_idx: %d, prev_line_idx: %d, pPalmMisc->horiz_coord[%d]: %d\n",
+                                line_idx[idx], prev_line_idx[idx], PALM_HORIZ_ARRAY_COUNT-1, pPalmMisc->horiz_coord[PALM_HORIZ_ARRAY_COUNT-1]);
+
+                        is_line_invalid[idx] = TRUE;
+
+                        if (is_line_invalid[0] && is_line_invalid[1])
+                        {
+                            PalmFlickDebugPrint("[PalmFlick][F] 5\n");
+                            goto flick_failed;
+                        }
+                    }
+                }
+                prev_line_idx[idx] = line_idx[idx];
+            }
+
+            if (is_palm == FALSE)
+            {
+                switch (mt_sync_count[idx])
+                {
+                    case 1:
+                        if (total_max_tmajor <= g_pGesture->palm_flick_min_tmajor_threshold)
+                        {
+                            PalmFlickDebugPrint("[PalmFlick][M][F] mtsync_count: %d, max_tmajor: %d(%d) line_idx: %d\n",
+                                    mt_sync_count[idx], total_max_tmajor, g_pGesture->palm_flick_min_tmajor_threshold, line_idx[idx]);
+                            PalmFlickDebugPrint("[PalmFlick][F] 6\n");
+                            is_tmajor_invalid[idx] = TRUE;
+                            //goto flick_failed;
+                        }
+                        break;
+                    case 2:
+                        if (total_max_tmajor <= (g_pGesture->palm_flick_max_tmajor_threshold - 10))
+                        {
+                            PalmFlickDebugPrint("[PalmFlick][M][F] mtsync_count: %d, max_tmajor: %d(%d) line_idx: %d\n",
+                                    mt_sync_count[idx], total_max_tmajor, g_pGesture->palm_flick_max_tmajor_threshold-10, line_idx[idx]);
+                            PalmFlickDebugPrint("[PalmFlick][F] 7\n");
+                            is_tmajor_invalid[idx] = TRUE;
+                            //goto flick_failed;
+                        }
+                        break;
+                    case 3:
+                        if (total_max_tmajor < g_pGesture->palm_flick_max_tmajor_threshold)
+                        {
+                            PalmFlickDebugPrint("[PalmFlick][M][F] mtsync_count: %d, max_tmajor: %d(%d) line_idx: %d\n",
+                                    mt_sync_count[idx], total_max_tmajor, g_pGesture->palm_flick_max_tmajor_threshold, line_idx[idx]);
+                            PalmFlickDebugPrint("[PalmFlick][F] 8\n");
+                            is_tmajor_invalid[idx] = TRUE;
+                            //goto flick_failed;
+                        }
+                        break;
+                    default:
+                        PalmFlickDebugPrint("[PalmFlick][M] See more next motion...\n");
+                        break;
+                }
+            }
+
+            if (is_tmajor_invalid[0] && is_tmajor_invalid[1])
+            {
+                PalmFlickDebugPrint("[PalmFlick][M][F] max_tmajor=%d\n", total_max_tmajor);
+                goto flick_failed;
+            }
+
+            current_time = GetTimeInMillis();
+
+            if (current_time - base_time > g_pGesture->palm_flick_time_threshold)
+            {
+                PalmFlickDebugPrint("[PalmFlick][M][F] Release event were not came too long time (%d - %d > %d)\n", current_time, base_time, g_pGesture->palm_flick_time_threshold);
+                PalmFlickDebugPrint("[PalmFlick][F] 10\n");
+                goto flick_failed;
+            }
+
+            break;
+
+        case ET_ButtonRelease:
+            current_x[idx] = g_pGesture->fingers[idx].mx;
+            current_y[idx] = g_pGesture->fingers[idx].my;
+            release_status[idx] = TRUE;
+
+            if ((update_x[idx] == current_x[idx]) && (update_y[idx] == current_y[idx]))
+            {
+                PalmFlickDebugPrint("[PalmFlick][R][F] Press point and release point are the same. base_x=%d, base_y=%d, current_x=%d, current_y=%d\n",
+                        update_x[idx], update_y[idx], current_x[idx], current_y[idx]);
+                PalmFlickDebugPrint("[PalmFlick][F] 10-1\n");
+                break;
+                //goto flick_failed;
+            }
+
+            if (!is_palm)
+            {
+                is_tmajor_invalid[idx] = TRUE;
+
+                if (is_tmajor_invalid[0] && is_tmajor_invalid[1])
+                {
+                    PalmFlickDebugPrint("[PalmFlick][R][F] Insufficient touch major was came(%d)\n", total_max_tmajor);
+                    PalmFlickDebugPrint("[PalmFlick][F] 11\n");
+                    goto flick_failed;
+                }
+            }
+
+            line_idx[idx] = GesturePalmGetHorizIndexWithX(current_x[idx], idx, type);
+
+            if (is_palm && line_idx[idx] == 1)
+            {
+                PalmFlickDebugPrint("[PalmFlick][R] Enough major, but release. base_x=%d, base_y=%d, current_x=%d, current_y=%d\n",
+                        base_x[idx], base_y[idx], current_x[idx], current_y[idx]);
+                is_retry = TRUE;
+                mt_sync_count[idx] = 0;
+                break;
+            }
+
+            if (line_idx[idx] < 0 || line_idx[idx] > PALM_HORIZ_ARRAY_COUNT - 1)
+            {
+                is_line_invalid[idx] = TRUE;
+
+                if (is_line_invalid[0] && is_line_invalid[1])
+                {
+                    PalmFlickDebugPrint("[PalmFlick][R][F] No line_idx is invalid.. base_x: %d, current_x: %d\n", base_x[idx], current_x[idx]);
+                    PalmFlickDebugPrint("[PalmFlick][F] 12\n");
+                    goto flick_failed;
+                }
+            }
+
+            current_time = GetTimeInMillis();
+
+            if (current_time - base_time > g_pGesture->palm_flick_time_threshold)
+            {
+                PalmFlickDebugPrint("[PalmFlick][R][F] Release event were came to have long delay (%d - %d > %d)\n",
+                        current_time, base_time, g_pGesture->palm_flick_time_threshold);
+                PalmFlickDebugPrint("[PalmFlick][F] 13\n");
+                goto flick_failed;
+            }
+
+            direction = (line_idx[idx] <= 1) ? FLICK_EASTWARD : FLICK_WESTWARD;
+            distance = ABS(current_x[idx] - base_x[idx]);
+            duration = current_time - base_time;
+
+            if (!is_retry)
+            {
+                if (GestureHasFingerEventMask(GestureNotifyFlick, 0))
+                {
+                    PalmFlickDebugPrint("[PalmFlick][R] Palm Flick1 !!!, direction=%d, distance=%d\n", direction, distance);
+                    is_palm = FALSE;
+                    GestureHandleGesture_Flick(0, distance, duration, direction);
+                }
+            }
+            else
+            {
+                if (mt_sync_count[idx] < 25)
+                {
+                    PalmFlickDebugPrint("[PalmFlick][R][F] No enough motion=%d\n", mt_sync_count[idx]);
+                    PalmFlickDebugPrint("[PalmFlick][F] 14\n");
+                    goto flick_failed;
+                }
+                else
+                {
+                    if (GestureHasFingerEventMask(GestureNotifyFlick, 0))
+                    {
+                        PalmFlickDebugPrint("[PalmFlick][R] Palm Flick2 !!!, direction=%d, distance=%d\n", direction, distance);
+                        is_palm = FALSE;
+                        GestureHandleGesture_Flick(0, distance, duration, direction);
+                    }
+                }
+            }
+
+            g_pGesture->recognized_gesture |= WPalmFlickFilterMask;
+
+            goto cleanup_flick;
+            break;
+    }
+
+    return;
+
+flick_failed:
+
+    DetailDebugPrint("[PalmFlick][R] flick failed\n");
+
+    g_pGesture->recognized_gesture &= ~WPalmFlickFilterMask;
+    g_pGesture->filter_mask |= WPalmFlickFilterMask;
+    goto cleanup_flick;
+
+cleanup_flick:
+
+    DetailDebugPrint("[PalmFlick][R] cleanup_flick\n");
+
+    for (int i = 0; i < MAX_MT_DEVICES; i++)
+    {
+        base_x[i] = 0;
+        base_y[i] = 0;
+        update_x[i] = 0;
+        update_y[i] = 0;
+        current_x[i] = 0;
+        current_y[i] = 0;
+        line_idx[i] = 0;
+        press_idx[i] = 0;
+        prev_line_idx[i] = 0;
+        max_tmajor[i] = 0;
+        mt_sync_count[i] = 0;
+        press_status[i] = FALSE;
+        release_status[i] = FALSE;
+        is_tmajor_invalid[i] = TRUE;
+        is_line_invalid[i] = TRUE;
+    }
+
+    total_max_tmajor = 0;
+    is_palm = FALSE;
+    is_retry = FALSE;
+
+    return;
+}
+
+static int
+GesturePalmGetHorizIndexWithX(int current_x, int idx, int type)
+{
+    int i;
+    int ret_idx = -1;
+    static int pressed_idx[MAX_MT_DEVICES] = {-1, -1};
+    PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
+
+    for (i = 0; i < PALM_HORIZ_ARRAY_COUNT; i++)
+    {
+        if (current_x <= pPalmMisc->horiz_coord[i])
+        {
+            DetailDebugPrint("[GesturePalmGetHorizIndexWithX] index=%d, pPalmMisc->horiz_coord[%d]=%d\n", i, i, pPalmMisc->horiz_coord[i]);
+
+            ret_idx = i;
+            goto index_check;
+        }
+    }
+
+    DetailDebugPrint("[GesturePalmGetHorizIndexWithX]Error ! Failed to get horiz coordinate index !\n");
+    return ret_idx;
+
+index_check:
+
+    if (type == ET_ButtonPress)
+    {
+        pressed_idx[idx] = ret_idx;
+
+        // first press is center
+        if (pressed_idx[idx] == PALM_HORIZ_ARRAY_COUNT -2)
+        {
+            DetailDebugPrint("[GesturePalmGetHorizIndexWithX][P] Invalid press area x=%d, idx=%d, pressed_idx=%d\n", current_x, idx, pressed_idx[idx]);
+            ret_idx = -1;
+        }
+
+        DetailDebugPrint("[GesturePalmGetHorizIndexWithX][P] pressed_idx=%d\n", pressed_idx[idx]);
+    }
+
+    else if (type == ET_Motion)
+    {
+        DetailDebugPrint("[GesturePalmGetHorizIndexWithX][M] moving x=%d, idx=%d, pressed_idx=%d\n", current_x, idx, pressed_idx[idx]);
+    }
+
+    else if (type == ET_ButtonRelease)
+    {
+        if ((pressed_idx[idx] == 0) && (ret_idx == (PALM_HORIZ_ARRAY_COUNT - 1)))
+        {
+            DetailDebugPrint("[GesturePalmGetHorizIndexWithX][R] From the left to the right ! pressed_idx=%d, ret_idx=%d\n", pressed_idx[idx], ret_idx);
+        }
+        else if ((pressed_idx[idx] == (PALM_HORIZ_ARRAY_COUNT - 1)) && (ret_idx == 0))
+        {
+            DetailDebugPrint("[GesturePalmGetHorizIndexWithX][R] From the right to the left ! pressed_idx=%d, ret_idx=%d\n", pressed_idx[idx], ret_idx);
+        }
+        else if ((pressed_idx[idx] == ret_idx) && ret_idx != 1)
+        {
+            DetailDebugPrint("[GesturePalmGetHorizIndexWithX][R] Relased the same region ! pressed_idx=%d, ret_idx=%d\n", pressed_idx[idx], ret_idx);
+            return 1;
+        }
+        else
+        {
+            DetailDebugPrint("[GesturePalmGetHorizIndexWithX][R] Invalid ! pressed_idx=%d, released_idx=%d\n", pressed_idx[idx], ret_idx);
+            ret_idx = -1;
+        }
+
+        pressed_idx[idx] = -1;
+    }
+
+    return ret_idx;
+}
+
+static int
+GesturePalmGetAbsAxisInfo(DeviceIntPtr dev)
+{
+    int i, found = 0;
+    int numAxes;
+
+    Atom atom_tpalm;
+    Atom atom_mt_slot;
+    Atom atom_tracking_id;
+    Atom atom_tmajor;
+    Atom atom_tminor;
+
+    g_pGesture->tpalm_idx = -1;
+    g_pGesture->tmajor_idx = -1;
+    g_pGesture->tminor_idx = -1;
+
+    if (!dev || !dev->valuator)
+        goto out;
+
+    numAxes = dev->valuator->numAxes;
+
+    atom_tpalm = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_PALM);
+    atom_mt_slot = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_SLOT);
+    atom_tracking_id = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_TRACKING_ID);
+    atom_tmajor = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_TOUCH_MAJOR);
+    atom_tminor = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_TOUCH_MINOR);
+
+    if (!numAxes || !atom_tpalm || !atom_tmajor || !atom_tminor)
+    {
+        ErrorF("one or more axes is/are not supported!\n");
+        goto out;
+    }
+
+    for (i = 0; i < numAxes; i++)
+    {
+        AxisInfoPtr axes = &dev->valuator->axes[i];
+
+        if (!axes || (axes->mode != Absolute))
+            continue;
+
+        if (axes->label == atom_tpalm)
+        {
+            g_pGesture->tpalm_idx = i;
+            found += 1;
+        }
+        else if (axes->label == atom_tmajor)
+        {
+            g_pGesture->tmajor_idx = i;
+            found += 2;
+        }
+        else if (axes->label == atom_tminor)
+        {
+            g_pGesture->tminor_idx = i;
+            found += 4;
+        }
+    }
+
+    if (found != 7)
+    {
+        ErrorF("Axes for palm recognization are not supported !\n");
+        goto out;
+    }
+
+    g_pGesture->palm_misc.enabled = 1;
+    ErrorF("Axes for palm recognization are supported !\n");
+    return 1;
+
+out:
+    g_pGesture->palm_misc.enabled = 0;
+    ErrorF("Palm recognization is not supported !\n");
+    return 0;
+}
+
+static int
+GestureGetPalmValuator(InternalEvent *ev, DeviceIntPtr device)
+{
+    int mt_palm_idx = g_pGesture->tpalm_idx;
+    int mt_palm = 0;
+
+    DeviceEvent *de = &ev->device_event;
+
+    if (!de)
+    {
+        ErrorF("[GestureGetPalmValuator] de is NULL !\n");
+        return -1;
+    }
+
+    if (mt_palm_idx < 0)
+    {
+        ErrorF("[GestureGetPalmValuator] One or more of axes are not supported !\n");
+        return -1;
+    }
+
+    mt_palm = de->valuators.data[mt_palm_idx];
+
+    HoldDetectorDebugPrint("[GestureGetPalmValuator] mt_palm:%d\n", mt_palm);
+
+    return mt_palm;
+}
+
+static void GestureHoldDetector(int type, InternalEvent *ev, DeviceIntPtr device)
+{
+    int i;
+    int idx = -1;
+    pixman_region16_t tarea1;
+    static int num_pressed = 0;
+    unsigned int hold_area_size;
+    PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
+    int palm_flag = 0;
+
+    if (!g_pGesture->has_hold_grabmask)
+    {
+        HoldDetectorDebugPrint("[GestureHoldDetector] g_pGesture->has_hold_grabmask=%d\n", g_pGesture->has_hold_grabmask);
+
+        Mask eventmask = (1L << GestureNotifyHold);
+
+        if ((g_pGesture->grabMask & eventmask) &&
+                (g_pGesture->GrabEvents[GestureNotifyHold].pGestureGrabWinInfo[0].window != None))
+        {
+            g_pGesture->has_hold_grabmask = 1;
+
+            //Initialize a set of variables
+            num_pressed = 0;
+            memset(&g_pGesture->cts, 0, sizeof(g_pGesture->cts));
+            pixman_region_init(&g_pGesture->chold_area);
+
+            HoldDetectorDebugPrint("[GestureHoldDetector] Initialize...\n");
+        }
+        else
+        {
+            //reset local hold_grab_mask variable
+            g_pGesture->has_hold_grabmask = 0;
+
+            g_pGesture->hold_detector_activate = 0;
+            HoldDetectorDebugPrint("[GestureHoldDetector] has_hold_grabmask=0 and g_pGesture->hold_detector_activate=0\n");
+            return;
+        }
+    }
+
+    if (IGNORE_EVENTS == g_pGesture->ehtype ||
+            device->id < g_pGesture->first_fingerid)
+    {
+        HoldDetectorDebugPrint("[GestureHoldDetector] Return (IGNORE_EVENTS or device->id:%d < first_fingerid:%d)\n", device->id, g_pGesture->first_fingerid);
+        return;
+    }
+
+    palm_flag = GestureGetPalmValuator(ev, device);
+
+    if (palm_flag)
+    {
+        GestureHandleGesture_Hold(0, 0, 0, PALM_HOLD_TIME_THRESHOLD, GestureBegin);
+        GestureHandleGesture_Hold(0, 0, 0, PALM_HOLD_TIME_THRESHOLD, GestureEnd);
+
+        g_pGesture->hold_detector_activate = 0;
+        g_pGesture->has_hold_grabmask = 0;
+        HoldDetectorDebugPrint("[GestureHoldDetector] palm_flag:%d enable\n", palm_flag);
+        return;
+    }
+    else
+    {
+        HoldDetectorDebugPrint("[GestureHoldDetector] palm_flag:%d disable\n", palm_flag);
+        return;
+    }
+
+    HoldDetectorDebugPrint("[GestureHoldDetector] g_pGesture->num_mt_devices:%d\n", g_pGesture->num_mt_devices);
+
+    for (i = 0; i < g_pGesture->num_mt_devices; i++)
+    {
+        if ( device->id == g_pGesture->mt_devices[i]->id)
+        {
+            idx = i;
+            HoldDetectorDebugPrint("[GestureHoldDetector] idx:%d\n", idx);
+            break;
+        }
+    }
+    if ((idx < 0) || ((MAX_MT_DEVICES-1) < idx)) return;
+
+    switch (type)
+    {
+        case ET_ButtonPress:
+            g_pGesture->cts[idx].status = BTN_PRESSED;
+            g_pGesture->cts[idx].cx = ev->device_event.root_x;
+            g_pGesture->cts[idx].cy = ev->device_event.root_y;
+            num_pressed++;
+            HoldDetectorDebugPrint("[GestureHoldDetector][P] cx:%d, cy:%d, num_pressed:%d\n", g_pGesture->cts[idx].cx, g_pGesture->cts[idx].cy, num_pressed);
+
+            if (num_pressed < 2)
+            {
+                HoldDetectorDebugPrint("[GestureHoldDetector][P] num_pressed:%d\n", num_pressed);
+                break;
+            }
+
+            if (num_pressed > g_pGesture->num_mt_devices)
+                num_pressed = g_pGesture->num_mt_devices;
+
+            pixman_region_init(&tarea1);
+            pixman_region_init(&g_pGesture->chold_area);
+            pixman_region_init_rect(&tarea1, g_pGesture->cts[0].cx, g_pGesture->cts[0].cy, g_pGesture->cts[0].cx+1, g_pGesture->cts[0].cy+1);
+
+            tarea1.extents.x1 = g_pGesture->cts[0].cx;
+            tarea1.extents.x2 = g_pGesture->cts[0].cx+1;
+            tarea1.extents.y1 = g_pGesture->cts[0].cy;
+            tarea1.extents.y2 = g_pGesture->cts[0].cy+1;
+
+            pixman_region_union(&g_pGesture->chold_area, &tarea1, &tarea1);
+
+            for (i = 1; i < num_pressed; i++)
+            {
+                pixman_region_init_rect(&tarea1, g_pGesture->cts[i].cx, g_pGesture->cts[i].cy, g_pGesture->cts[i].cx + 1, g_pGesture->cts[i].cy + 1);
+
+                tarea1.extents.x1 = g_pGesture->cts[i].cx;
+                tarea1.extents.x2 = g_pGesture->cts[i].cx + 1;
+                tarea1.extents.y1 = g_pGesture->cts[i].cy;
+                tarea1.extents.y2 = g_pGesture->cts[i].cy + 1;
+
+                pixman_region_union(&g_pGesture->chold_area, &g_pGesture->chold_area, &tarea1);
+            }
+            break;
+
+        case ET_Motion:
+            if (BTN_RELEASED == g_pGesture->cts[idx].status)
+                return;
+
+            g_pGesture->cts[idx].status = BTN_MOVING;
+            g_pGesture->cts[idx].cx = ev->device_event.root_x;
+            g_pGesture->cts[idx].cy = ev->device_event.root_y;
+
+            HoldDetectorDebugPrint("[GestureHoldDetector][M] cx:%d, cy:%d, num_pressed:%d\n", g_pGesture->cts[idx].cx, g_pGesture->cts[idx].cy, num_pressed);
+
+            if (num_pressed < 2)
+            {
+                HoldDetectorDebugPrint("[GestureHoldDetector][M] num_pressed:%d\n", num_pressed);
+                break;
+            }
+
+            pixman_region_init(&tarea1);
+            pixman_region_init(&g_pGesture->chold_area);
+            pixman_region_init_rect(&tarea1, g_pGesture->cts[0].cx, g_pGesture->cts[0].cy, g_pGesture->cts[0].cx+1, g_pGesture->cts[0].cy+1);
+
+            tarea1.extents.x1 = g_pGesture->cts[0].cx;
+            tarea1.extents.x2 = g_pGesture->cts[0].cx+1;
+            tarea1.extents.y1 = g_pGesture->cts[0].cy;
+            tarea1.extents.y2 = g_pGesture->cts[0].cy+1;
+
+            pixman_region_union(&g_pGesture->chold_area, &tarea1, &tarea1);
+
+            for (i = 1; i < num_pressed; i++)
+            {
+                pixman_region_init_rect(&tarea1, g_pGesture->cts[i].cx, g_pGesture->cts[i].cy, g_pGesture->cts[i].cx + 1, g_pGesture->cts[i].cy + 1);
+
+                tarea1.extents.x1 = g_pGesture->cts[i].cx;
+                tarea1.extents.x2 = g_pGesture->cts[i].cx + 1;
+                tarea1.extents.y1 = g_pGesture->cts[i].cy;
+                tarea1.extents.y2 = g_pGesture->cts[i].cy + 1;
+
+                pixman_region_union(&g_pGesture->chold_area, &g_pGesture->chold_area, &tarea1);
+            }
+            break;
+
+        case ET_ButtonRelease:
+            g_pGesture->cts[idx].status = BTN_RELEASED;
+            g_pGesture->cts[idx].cx = ev->device_event.root_x;
+            g_pGesture->cts[idx].cy = ev->device_event.root_y;
+
+            HoldDetectorDebugPrint("[GestureHoldDetector][R] cx:%d, cy:%d\n", g_pGesture->cts[idx].cx, g_pGesture->cts[idx].cy);
+
+            num_pressed--;
+            if (num_pressed <3)
+            {
+                pixman_region_init(&g_pGesture->chold_area);
+            }
+            break;
+    }
+
+    if (num_pressed >= 2)
+    {
+        hold_area_size = AREA_SIZE(&g_pGesture->chold_area.extents);
+
+        HoldDetectorDebugPrint("[GestureHoldDetector] hold_area_size=%d, pPalmMisc->half_scrn_area_size=%d\n", hold_area_size, pPalmMisc->half_scrn_area_size);
+
+        if (pPalmMisc->half_scrn_area_size <= hold_area_size)
+        {
+            GestureHandleGesture_Hold(0, AREA_CENTER_X(&g_pGesture->chold_area.extents), AREA_CENTER_Y(&g_pGesture->chold_area.extents), PALM_HOLD_TIME_THRESHOLD, GestureBegin);
+            GestureHandleGesture_Hold(0, AREA_CENTER_X(&g_pGesture->chold_area.extents), AREA_CENTER_Y(&g_pGesture->chold_area.extents), PALM_HOLD_TIME_THRESHOLD, GestureEnd);
+
+            g_pGesture->hold_detector_activate = 0;
+            g_pGesture->has_hold_grabmask = 0;
+        }
+    }
+    else
+    {
+        hold_area_size = AREA_SIZE(&g_pGesture->chold_area.extents);
+        HoldDetectorDebugPrint("[GestureHoldDetector] num_pressed is under 2, hold_area_size=%d\n", hold_area_size);
+    }
+}
+
+
+static int
+GesturePalmGetScreenInfo()
+{
+    int i;
+    pixman_region16_t tarea;
+    PalmMiscInfoPtr pPalmMisc = &g_pGesture->palm_misc;
+    ScreenPtr pScreen = miPointerCurrentScreen();
+
+    if (!pScreen)
+    {
+        DetailDebugPrint("[X11][GesturePalmGetScreenInfo]Failed to get screen information !\n");
+
+        pPalmMisc->scrn_width = pPalmMisc->scrn_height = 0;
+        return 0;
+    }
+
+    pPalmMisc->scrn_width = pScreen->width;
+    pPalmMisc->scrn_height = pScreen->height;
+    pixman_region_init(&tarea);
+    pixman_region_init_rect(&tarea, 0, 0, pPalmMisc->scrn_width, pPalmMisc->scrn_height);
+
+    DetailDebugPrint("[X11][GesturePalmGetScreenInfo] x2:%d, x2:%d, y2:%d, y1:%d \n", tarea.extents.x2, tarea.extents.x1, tarea.extents.y2, tarea.extents.y1);
+    pPalmMisc->half_scrn_area_size = AREA_SIZE(&tarea.extents);
+    pPalmMisc->half_scrn_area_size = (unsigned int)((double)pPalmMisc->half_scrn_area_size / 4);
+
+    DetailDebugPrint("[X11][GesturePalmGetScreenInfo] pPalmMisc->half_scrn_area_size = %d\n", pPalmMisc->half_scrn_area_size);
+
+    for (i = 0; i < PALM_HORIZ_ARRAY_COUNT; i++)
+    {
+        pPalmMisc->horiz_coord[i] = pPalmMisc->scrn_width * ((i+1)/(double)PALM_HORIZ_ARRAY_COUNT);
+        DetailDebugPrint("[X11][GesturePalmGetScreenInfo] pPalmMisc->horiz_coord[%d]=%d, pPalmMisc->scrn_width=%d\n", i, pPalmMisc->horiz_coord[i], pPalmMisc->scrn_width);
+    }
+    for (i = 0; i < PALM_VERTI_ARRAY_COUNT; i++)
+    {
+        pPalmMisc->verti_coord[i] = pPalmMisc->scrn_height * ((i+1)/(double)PALM_VERTI_ARRAY_COUNT);
+        DetailDebugPrint("[X11][GesturePalmGetScreenInfo] pPalmMisc->verti_coord[%d]=%d, pPalmMisc->scrn_height=%d\n", i, pPalmMisc->verti_coord[i], pPalmMisc->scrn_height);
+    }
+
+    return 1;
+}
+
+
+static inline void
+GestureEnableDisable()
+{
+    GestureEnable(1, FALSE, g_pGesture->this_device);
+#if 0
+    if ((g_pGesture->grabMask) || (g_pGesture->lastSelectedWin != None))
+    {
+        GestureEnable(1, FALSE, g_pGesture->this_device);
+    }
+    else
+    {
+        GestureEnable(0, FALSE, g_pGesture->this_device);
+    }
+#endif
+}
+
+void
+GestureCbEventsGrabbed(Mask *pGrabMask, GestureGrabEventPtr *pGrabEvent)
+{
+    g_pGesture->grabMask = *pGrabMask;
+    g_pGesture->GrabEvents = (GestureGrabEventPtr)pGrabEvent;
+    GestureEnableDisable();
+}
+
+void
+GestureCbEventsSelected(Window win, Mask *pEventMask)
+{
+    g_pGesture->lastSelectedWin = win;
+    g_pGesture->lastSelectedMask = (pEventMask) ? *pEventMask : 0;
+    GestureEnableDisable();
+}
+
+WindowPtr
+GestureGetEventsWindow(void)
+{
+    Mask mask;
+    WindowPtr pWin;
+
+    pWin = GestureWindowOnXY(g_pGesture->fingers[0].px, g_pGesture->fingers[0].py);
+
+    if (pWin)
+    {
+        DetailDebugPrint("[GestureGetEventsWindow] pWin->drawable.id=0x%x\n", pWin->drawable.id);
+        g_pGesture->gestureWin = pWin->drawable.id;
+    }
+    else
+    {
+        DetailDebugPrint("[GestureGetEventsWindow] GestureWindowOnXY returns NULL !\n");
+        return NULL;
+    }
+
+    if (g_pGesture->gestureWin == g_pGesture->lastSelectedWin)
+    {
+        g_pGesture->eventMask = g_pGesture->lastSelectedMask;
+        goto nonempty_eventmask;
+    }
+
+    //check selected event(s)
+    if (!GestureHasSelectedEvents(pWin, &g_pGesture->eventMask))
+    {
+        g_pGesture->eventMask = 0;
+    }
+    else
+    {
+        g_pGesture->lastSelectedWin = g_pGesture->gestureWin;
+        g_pGesture->lastSelectedMask = g_pGesture->eventMask;
+    }
+
+    if (!g_pGesture->eventMask && !g_pGesture->grabMask)
+    {
+        DetailDebugPrint("[X11][GestureGetEventsWindow] No grabbed events or no events were selected for window(0x%x) !\n", pWin->drawable.id);
+        return NULL;
+    }
+
+nonempty_eventmask:
+
+    DetailDebugPrint("[X11][GestureGetEventsWindow] g_pGesture->eventMask=0x%x\n", g_pGesture->eventMask);
+
+    mask = (GESTURE_FILTER_MASK_ALL & ~(g_pGesture->grabMask | g_pGesture->eventMask));
+
+    DetailDebugPrint("[X11][GestureGetEventsWindow] g_pGesture->filter_mask=0x%x, mask=0x%x\n", g_pGesture->filter_mask, mask);
+
+    g_pGesture->filter_mask = mask;
+
+    DetailDebugPrint("[X11][GestureGetEventsWindow] g_pGesture->filter_mask=0x%x\n", g_pGesture->filter_mask);
+
+    return pWin;
+}
+
+static CARD32
+GestureSingleFingerTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
+{
+    g_pGesture->filter_mask |= WTapFilterMask;
+    g_pGesture->filter_mask |= WHoldFilterMask;
+    //LOGI("[GroupTap][GroupHold] 50ms after 1st finger.\n");
+
+    DetailDebugPrint("[GestureSingleFingerTimerHandler] TapFilterMask, HoldFilterMask \n");
+
+    if ((g_pGesture->event_sum[0] == BTN_PRESSED) && ((g_pGesture->flick_pressed_point <= FLICK_POINT_NONE) && (FLICK_POINT_MAX <= g_pGesture->flick_pressed_point)))
+    {
+        DetailDebugPrint("[GestureSingleFingerTimerHandler] press_point: %d\n", g_pGesture->flick_pressed_point);
+        DetailDebugPrint("[GestureSingleFingerTimerHandler] FlickFilterMask\n");
+        g_pGesture->filter_mask |= WFlickFilterMask;
+    }
+
+    if (g_pGesture->flick_pressed_point == FLICK_POINT_DOWN && abs(g_pGesture->fingers[0].py - g_pGesture->fingers[0].my) < 3)
+    {
+        DetailDebugPrint("[GestureSingleFingerTimerHandler] py: %d, my: %d\n", g_pGesture->fingers[0].py, g_pGesture->fingers[0].my);
+        DetailDebugPrint("[GestureSingleFingerTimerHandler] FlickFilterMask\n");
+        g_pGesture->filter_mask |= WFlickFilterMask;
+    }
+
+    DetailDebugPrint("[GestureSingleFingerTimerHandler] expired !\n");
+
+    if (g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL)
+    {
+        if ( ERROR_INVALPTR == GestureFlushOrDrop())
+        {
+            DetailDebugPrint("[GestureSingleFingerTimerHandler] AllFilterMask, Flush!\n");
+            GestureControl(g_pGesture->this_device, DEVICE_OFF);
+        }
+    }
+
+    return 0;
+}
+
+static int
+GestureGetFingerIndexFromDevice(DeviceIntPtr device)
+{
+    int i;
+
+    for( i = 0 ; i < g_pGesture->num_mt_devices ; i++ )
+    {
+        if( device->id == g_pGesture->mt_devices[i]->id )
+        {
+            return i;
+        }
+    }
+
+    return -1;
+}
+
+void
+GestureRecognize(int type, InternalEvent *ev, DeviceIntPtr device)
+{
+    int i;
+    static OsTimerPtr single_finger_timer = NULL;
+    int idx = -1;
+
+    if (PROPAGATE_EVENTS == g_pGesture->ehtype || device->id < g_pGesture->first_fingerid)
+    {
+        return;
+    }
+
+    idx = GestureGetFingerIndexFromDevice(device);
+
+    if (idx < 0)
+        return;
+
+    switch (type)
+    {
+        case ET_ButtonPress:
+            if (idx == 0)
+            {
+                g_pGesture->event_sum[0] = BTN_PRESSED;
+            }
+
+            g_pGesture->max_mt_tmajor[idx] = GestureGetMaxTmajor(ev, g_pGesture->max_mt_tmajor[idx]);
+
+            g_pGesture->fingers[idx].ptime = ev->any.time;
+            g_pGesture->fingers[idx].px = ev->device_event.root_x;
+            g_pGesture->fingers[idx].py = ev->device_event.root_y;
+
+            g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH;
+            g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH;
+            g_pGesture->finger_rects[idx].extents.y1 =  ev->device_event.root_y - FINGER_HEIGHT;
+            g_pGesture->finger_rects[idx].extents.y2 =  ev->device_event.root_y + FINGER_HEIGHT;
+
+            g_pGesture->num_pressed++;
+            g_pGesture->inc_num_pressed = g_pGesture->num_pressed;
+
+            if (g_pGesture->inc_num_pressed == 1)
+            {
+                pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
+            }
+            else
+            {
+                pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
+
+                for (i = 1; i < g_pGesture->inc_num_pressed; i++)
+                {
+                    pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]);
+                }
+            }
+
+            DetailDebugPrint("[GestureRecognize][P] num_pressed=%d, area_size=%d, px=%d, py=%d\n",
+                    g_pGesture->num_pressed, AREA_SIZE(&g_pGesture->area.extents), g_pGesture->fingers[idx].px, g_pGesture->fingers[idx].py);
+
+            if (g_pGesture->num_pressed == 1)
+            {
+                single_finger_timer = TimerSet(single_finger_timer, 0, 50, GestureSingleFingerTimerHandler, NULL);
+
+                if (g_pGesture->fingers[idx].py <= g_pGesture->flick_press_area)
+                {
+                    if ((!g_pGesture->activate_flick_down)
+                            || (g_pGesture->fingers[idx].px <= (g_pGesture->flick_press_area_left_right))
+                            || (g_pGesture->fingers[idx].px >= (g_pGesture->screen_width - g_pGesture->flick_press_area_left_right)))
+                    {
+                        DetailDebugPrint("[GestureRecognize][P] px=%d, flick_press_area_left_right=%d\n",
+                            g_pGesture->fingers[idx].px, g_pGesture->flick_press_area_left_right);
+                        g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
+                        LOGI("[BackKey][F] Press touch within 40 pixel area from left or right vezel\n");
+                    }
+                    else
+                    {
+                        DetailDebugPrint("[GestureRecognize][P] FLICK_POINT_UP\n");
+                        g_pGesture->flick_pressed_point = FLICK_POINT_UP;
+                    }
+                }
+                else
+                {
+                    LOGI("[BackKey][F] Press touch outside 40 pixel area from upper vezel. \n");
+                }
+
+                if (g_pGesture->fingers[idx].py >= (g_pGesture->screen_height - g_pGesture->flick_press_area))
+                {
+                    if (!g_pGesture->activate_flick_up)
+                    {
+                        g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
+                    }
+                    else
+                    {
+                        DetailDebugPrint("[GestureRecognize][P] FLICK_POINT_DOWN\n");
+                        g_pGesture->flick_pressed_point = FLICK_POINT_DOWN;
+                    }
+                }
+                else if ( g_pGesture->fingers[idx].px <= g_pGesture->flick_press_area_left)
+                {
+                    if (!g_pGesture->activate_flick_right)
+                    {
+                        g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
+                    }
+                    else
+                    {
+                        DetailDebugPrint("[GestureRecognize][P] FLICK_POINT_LEFT\n");
+                        g_pGesture->flick_pressed_point = FLICK_POINT_LEFT;
+                    }
+                }
+
+                DetailDebugPrint("[GestureRecognize][P] flick_press_point: %d\n", g_pGesture->flick_pressed_point);
+
+                if ((g_pGesture->flick_pressed_point <= FLICK_POINT_NONE) || (FLICK_POINT_MAX <= g_pGesture->flick_pressed_point))
+                {
+                    DetailDebugPrint("[GestureRecognize][P] FLICK_POINT_NONE\n");
+                    g_pGesture->filter_mask |= WFlickFilterMask;
+                    g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
+                }
+                else
+                {
+                    g_pGesture->flick_direction = (g_pGesture->flick_pressed_point - 1) * 2;
+                    if ((g_pGesture->flick_direction == FLICK_WESTWARD) && (g_pGesture->power_pressed != 2))
+                    {
+                        DetailDebugPrint("[GestureRecognize][P] Flick WesWard is disable when power is not pressed\n");
+                        g_pGesture->filter_mask |= WFlickFilterMask;
+                        g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
+                    }
+                    if ((g_pGesture->flick_direction < FLICK_NORTHWARD) || (FLICK_NORTHWESTWARD < g_pGesture->flick_direction))
+                    {
+                        DetailDebugPrint("[GestureRecognize][P] Invalid flick direction\n");
+                        g_pGesture->filter_mask |= WFlickFilterMask;
+                        g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
+                    }
+
+                    DetailDebugPrint("[GestureRecognize][P] flick_direction: %d\n", g_pGesture->flick_direction);
+                }
+            }
+            else
+            {
+                DetailDebugPrint("[GestureRecognize][P] Two more fingers come on!\n");
+                TimerCancel(single_finger_timer);
+                single_finger_timer = NULL;
+            }
+            break;
+
+        case ET_Motion:
+
+            if (!g_pGesture->fingers[idx].ptime)
+            {
+                DetailDebugPrint("[GestureRecognize][M] Start motion. idx=%d\n", idx);
+                g_pGesture->max_mt_tmajor[idx] = GestureGetMaxTmajor(ev, g_pGesture->max_mt_tmajor[idx]);
+                return;
+            }
+
+            g_pGesture->fingers[idx].mx = ev->device_event.root_x;
+            g_pGesture->fingers[idx].my = ev->device_event.root_y;
+            g_pGesture->max_mt_tmajor[idx] = GestureGetMaxTmajor(ev, g_pGesture->max_mt_tmajor[idx]);
+
+            if (idx == 0)
+            {
+                g_pGesture->event_sum[0] += BTN_MOVING;
+            }
+
+            g_pGesture->finger_rects[idx].extents.x1 = ev->device_event.root_x - FINGER_WIDTH;
+            g_pGesture->finger_rects[idx].extents.x2 = ev->device_event.root_x + FINGER_WIDTH;
+            g_pGesture->finger_rects[idx].extents.y1 =  ev->device_event.root_y - FINGER_HEIGHT;
+            g_pGesture->finger_rects[idx].extents.y2 =  ev->device_event.root_y + FINGER_HEIGHT;
+
+            if (g_pGesture->inc_num_pressed == 1)
+            {
+                pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
+            }
+            else
+            {
+                pixman_region_union(&g_pGesture->area, &g_pGesture->finger_rects[0], &g_pGesture->finger_rects[0]);
+
+                for (i = 1; i < g_pGesture->inc_num_pressed; i++)
+                {
+                    pixman_region_union(&g_pGesture->area, &g_pGesture->area, &g_pGesture->finger_rects[i]);
+                }
+            }
+
+            DetailDebugPrint("[GestureRecognize][M] num_pressed=%d, area_size=%d, mx=%d, my=%d\n",
+                    g_pGesture->num_pressed, AREA_SIZE(&g_pGesture->area.extents), g_pGesture->fingers[idx].mx, g_pGesture->fingers[idx].my);
+
+            break;
+
+        case ET_ButtonRelease:
+            g_pGesture->fingers[idx].rtime = ev->any.time;
+            g_pGesture->fingers[idx].rx = ev->device_event.root_x;
+            g_pGesture->fingers[idx].ry = ev->device_event.root_y;
+            g_pGesture->max_mt_tmajor[idx] = GestureGetMaxTmajor(ev, g_pGesture->max_mt_tmajor[idx]);
+
+            g_pGesture->num_pressed--;
+
+            if (g_pGesture->num_pressed == 0)
+            {
+                DetailDebugPrint("[GestureRecognize] All fingers were released !\n");
+            }
+            else if (g_pGesture->num_pressed < 0)
+            {
+                DetailDebugPrint("[GestureRecognize] All fingers were released. But, num_pressed is under 0 !\n");
+            }
+
+            DetailDebugPrint("[GestureRecognize][R] num_pressed=%d, rx=%d, ry=%d\n",
+                    g_pGesture->num_pressed, g_pGesture->fingers[idx].rx, g_pGesture->fingers[idx].ry);
+
+            break;
+    }
+
+    if (!(g_pGesture->filter_mask & WFlickFilterMask))
+    {
+        DetailDebugPrint("[GestureRecognize] GestureRecognize_groupFlick !\n");
+        GestureRecognize_GroupFlick(type, ev, device, idx, g_pGesture->flick_pressed_point, g_pGesture->flick_direction);
+    }
+    if (!(g_pGesture->filter_mask & WTapFilterMask))
+    {
+        DetailDebugPrint("[GestureRecognize] GestureRecognize_groupTap !\n");
+        GestureRecognize_GroupTap(type, ev, device, idx, 0);
+    }
+    if (!(g_pGesture->filter_mask & WHoldFilterMask))
+    {
+        DetailDebugPrint("[GestureRecognize] GestureRecognize_groupHold !\n");
+        GestureRecognize_GroupHold(type, ev, device, idx, 0);
+    }
+/*
+    if (!(g_pGesture->filter_mask & WPalmFlickFilterMask))
+    {
+        DetailDebugPrint("[GestureRecognize] GestureRecognize_palmFlick !\n");
+        GestureRecognize_PalmFlick(type, ev, device, idx);
+    }
+*/
+    DetailDebugPrint("[GestureRecognize][N] g_pGesture->filter_mask = 0x%x, g_pGesture->GESTURE_WATCH_FILTER_MASK_ALL = 0x%x, g_pGesture->recognized_gesture=0x%x\n",
+            g_pGesture->filter_mask, GESTURE_WATCH_FILTER_MASK_ALL, g_pGesture->recognized_gesture);
+
+    if (g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL)
+    {
+        if (!g_pGesture->recognized_gesture)
+        {
+            DetailDebugPrint("[GestureRecognize][F] 1 !\n");
+            goto flush_or_drop;
+        }
+        else if (!g_pGesture->num_pressed)
+        {
+            DetailDebugPrint("[GestureRecognize][F] 2 !\n");
+            goto flush_or_drop;
+        }
+    }
+
+    if (g_pGesture->recognized_gesture)
+    {
+        if (g_pGesture->ehtype == KEEP_EVENTS)
+        {
+            DetailDebugPrint("[GestureRecognize] Keep Event !\n");
+            GestureEventsDrop();
+        }
+        g_pGesture->ehtype = IGNORE_EVENTS;
+    }
+    return;
+
+flush_or_drop:
+
+    DetailDebugPrint("[GestureRecognize] GestureFlushOrDrop() !\n");
+
+    if (ERROR_INVALPTR == GestureFlushOrDrop())
+    {
+        GestureControl(g_pGesture->this_device, DEVICE_OFF);
+    }
+}
+
+ErrorStatus GestureFlushOrDrop(void)
+{
+    ErrorStatus err;
+
+    if (g_pGesture->recognized_gesture)
+    {
+        g_pGesture->ehtype = IGNORE_EVENTS;
+        GestureEventsDrop();
+        DetailDebugPrint("[GestureFlushOrDrop][Drop] IGNORE_EVENTS\n");
+    }
+    else
+    {
+        g_pGesture->ehtype = PROPAGATE_EVENTS;
+
+        err = GestureEventsFlush();
+
+        if (ERROR_NONE != err)
+        {
+            return err;
+        }
+
+        DetailDebugPrint("[GestureFlushOrDrop][Flush] PROPAGATE_EVENTS\n");
+        DetailDebugPrint("[GestureFlushOrDrop][Flush] g_pGesture->filter_mask = 0x%x\n", g_pGesture->filter_mask);
+        DetailDebugPrint("[GestureFlushOrDrop][Flush] g_pGesture->GESTURE_WATCH_FILTER_MASK_ALL = 0x%x\n", GESTURE_WATCH_FILTER_MASK_ALL);
+        DetailDebugPrint("[GestureFlushOrDrop][Flush] g_pGesture->recognized_gesture=0x%x\n", g_pGesture->recognized_gesture);
+    }
+
+    err = GestureRegionsReinit();
+
+    if (ERROR_NONE != err)
+    {
+        return err;
+    }
+
+    g_pGesture->pTempWin = NULL;
+    g_pGesture->inc_num_pressed = g_pGesture->num_pressed = 0;
+    g_pGesture->event_sum[0] = 0;
+
+    return ERROR_NONE;
+}
+
+void
+GestureHandleMTSyncEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
+{
+    int i;
+    int idx;
+
+#ifdef __DEBUG_EVENT_HANDLER__
+    DetailDebugPrint("[GestureHandleMTSyncEvent] (%d:%d) time:%d cur:%d\n",
+            ev->any_event.deviceid, ev->any_event.sync, (int)ev->any.time, (int)GetTimeInMillis());
+#endif
+
+    if (!g_pGesture->is_active)
+    {
+        g_pGesture->ehtype = PROPAGATE_EVENTS;
+        DetailDebugPrint("[GestureHandleMTSyncEvent] PROPAGATE_EVENT\n");
+        return;
+    }
+
+    switch(ev->any_event.sync)
+    {
+    case ROTARY_FRAME_SYNC_BEGIN:
+        if (g_pGesture->mt_devices[0] && (g_pGesture->mtsync_flag & MTSYNC_FLAG_TOUCH))
+        {
+            int zero = 0;
+            xf86PostButtonEvent(g_pGesture->mt_devices[0], 0, Button1, 0, 0, 2, &zero, &zero);
+        }
+        g_pGesture->mtsync_flag |= MTSYNC_FLAG_ROTARY;
+        DetailDebugPrint("[GestureHandleMTSyncEvent] Rotary input starts. Now touch events are dropped!\n");
+        break;
+    case ROTARY_FRAME_SYNC_END:
+        g_pGesture->mtsync_flag &= ~MTSYNC_FLAG_ROTARY;
+        DetailDebugPrint("[GestureHandleMTSyncEvent] Rotary input is finished. Now touch events are not dropped!\n");
+        break;
+    case MTOUCH_FRAME_SYNC_BEGIN:
+        g_pGesture->mtsync_flag |= MTSYNC_FLAG_TOUCH;
+        DetailDebugPrint("[GestureHandleMTSyncEvent] SYNC_BEGIN\n");
+        g_pGesture->ehtype = KEEP_EVENTS;
+        g_pGesture->filter_mask = 0;
+        g_pGesture->recognized_gesture = 0;
+        g_pGesture->hold_detector_activate = 1;
+        g_pGesture->num_pressed = 0;
+        g_pGesture->has_hold_grabmask = 0;
+        g_pGesture->mtsync_total_count = 0;
+        memset(&g_pGesture->last_touches, 0, sizeof(g_pGesture->last_touches));
+        for (i=0; i < g_pGesture->num_mt_devices; i++)
+        {
+            g_pGesture->fingers[i].ptime = 0;
+            g_pGesture->max_mt_tmajor[i] = 0;
+        }
+        break;
+    case MTOUCH_FRAME_SYNC_END:
+        g_pGesture->mtsync_flag &= ~MTSYNC_FLAG_TOUCH;
+        DetailDebugPrint("[GestureHandleMTSyncEvent] SYNC_END\n");
+        g_pGesture->ehtype = PROPAGATE_EVENTS;
+        g_pGesture->flick_pressed_point = FLICK_POINT_NONE;
+        g_pGesture->pTempWin = NULL;
+        g_pGesture->num_pressed = 0;
+        g_pGesture->hold_detected = FALSE;
+        break;
+    case MTOUCH_FRAME_SYNC_UPDATE:
+        g_pGesture->mtsync_flag |= MTSYNC_FLAG_TOUCH;
+        g_pGesture->mtsync_total_count++;
+
+        DetailDebugPrint("[GestureHandleMTSyncEvent] SYNC_Update. mt_total_sync=%d\n", g_pGesture->mtsync_total_count);
+
+        if ((g_pGesture->inc_num_pressed < 2) && (g_pGesture->filter_mask != GESTURE_WATCH_FILTER_MASK_ALL))
+        {
+            if (g_pGesture->num_tap_repeated == 1 || g_pGesture->num_tap_repeated == 2)
+            {
+                if (g_pGesture->mtsync_total_count >= 6)
+                {
+                    DetailDebugPrint("[GestureHandleMTSyncEvent] Moving Limit first tap repeated. tap_repeated: %d, mtsync_total_count: %d\n",
+                            g_pGesture->num_tap_repeated, g_pGesture->mtsync_total_count);
+                    g_pGesture->filter_mask |= WTapFilterMask;
+                    g_pGesture->filter_mask |= WHoldFilterMask;
+                                       LOGI("[GroupTap][GroupHold] Motions are more than 6 between 1st finger and 2nd finger.\n");
+                }
+            }
+
+            if (g_pGesture->filter_mask == GESTURE_WATCH_FILTER_MASK_ALL)
+            {
+                DetailDebugPrint("[GestureHandleMTSyncEvent] Gesture filter mask all. GestureFlushOrDrop() !\n");
+
+                if (ERROR_INVALPTR == GestureFlushOrDrop())
+                {
+                    GestureControl(g_pGesture->this_device, DEVICE_OFF);
+                }
+            }
+        }
+        break;
+    default:
+        ErrorF("[GestureHandleMTSyncEvent] Unknown MTSync Event received.\n");
+        break;
+    }
+}
+
+void GestureEmulateHWKey(DeviceIntPtr dev, int keycode)
+{
+    if (dev)
+    {
+        DetailDebugPrint("[GestureEmulateHWKey] keycode=%d\n", keycode);
+        xf86PostKeyboardEvent(dev, keycode, 1);
+        xf86PostKeyboardEvent(dev, keycode, 0);
+    }
+}
+
+void
+GestureHandleButtonPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
+{
+#ifdef __DEBUG_EVENT_HANDLER__
+    DetailDebugPrint("[GestureHandleButtonPressEvent] devid=%d time:%d cur:%d (%d, %d)\n", device->id, ev->any.time, GetTimeInMillis(), ev->device_event.root_x, ev->device_event.root_y);
+#endif//__DEBUG_EVENT_HANDLER__
+    int idx=0;
+    if (g_pGesture->touch_cancel_status == TRUE)
+    {
+        DetailDebugPrint("[GestureHandleButtonPressEvent] Ignore Button Press event after touch cancel generated. \n");
+        return;
+    }
+
+    idx = GestureGetFingerIndexFromDevice(device);
+    if (0 <= idx)
+    {
+        g_pGesture->last_touches[idx].status = BTN_PRESSED;
+        g_pGesture->last_touches[idx].cx = ev->device_event.root_x;
+        g_pGesture->last_touches[idx].cy = ev->device_event.root_y;
+    }
+
+    if (g_pGesture->ehtype != KEEP_EVENTS)
+    {
+        if(g_pGesture->mtsync_flag & MTSYNC_FLAG_ROTARY)
+        {
+            DetailDebugPrint("[GestureHandleButtonPressEvent] Rotary input is coming. Dropping touch events.\n");
+            return;
+        }
+        else if (g_pGesture->mtsync_flag & ~MTSYNC_FLAG_TOUCH)
+        {
+            DetailDebugPrint("[GestureHandleButtonPressEvent] Other input is coming. Dropping touch events.\n");
+            return;
+        }
+    }
+
+    switch (g_pGesture->ehtype)
+    {
+        case KEEP_EVENTS:
+            DetailDebugPrint("[GestureHandleButtonPressEvent] KEEP_EVENT\n");
+
+            if (ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev, device))
+            {
+                GestureControl(g_pGesture->this_device, DEVICE_OFF);
+                return;
+            }
+
+            if (g_pGesture->num_mt_devices)
+            {
+                GestureRecognize(ET_ButtonPress, ev, device);
+            }
+            else
+            {
+                device->public.processInputProc(ev, device);
+            }
+
+            GestureHoldDetector(ET_ButtonPress, ev, device);
+            break;
+
+        case PROPAGATE_EVENTS:
+            DetailDebugPrint("[GestureHandleButtonPressEvent] PROPAGATE_EVENT\n");
+
+            device->public.processInputProc(ev, device);
+            GestureHoldDetector(ET_ButtonPress, ev, device);
+            break;
+
+        case IGNORE_EVENTS:
+            DetailDebugPrint("[GestureHandleButtonPressEvent] IGNORE_EVENTS\n");
+
+            GestureRecognize(ET_ButtonPress, ev, device);
+            break;
+
+        default:
+            break;
+    }
+}
+
+void
+GestureHandleMotionEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
+{
+#ifdef __DEBUG_EVENT_MOTION_HANDLER__
+    DetailDebugPrint("[GestureHandleMotionEvent] devid=%d time:%d cur:%d (%d, %d)\n", device->id, ev->any.time, GetTimeInMillis(), ev->device_event.root_x, ev->device_event.root_y);
+#endif
+    int idx=0;
+    if (g_pGesture->touch_cancel_status == TRUE)
+    {
+        DetailDebugPrint("[GestureHandleButtonPressEvent] Ignore Button Press event after touch cancel generated. \n");
+        return;
+    }
+
+    idx = GestureGetFingerIndexFromDevice(device);
+    if (0 <= idx)
+    {
+        g_pGesture->last_touches[idx].status = BTN_MOVING;
+        g_pGesture->last_touches[idx].cx = ev->device_event.root_x;
+        g_pGesture->last_touches[idx].cy = ev->device_event.root_y;
+    }
+
+    if (g_pGesture->ehtype != KEEP_EVENTS)
+    {
+        if(g_pGesture->mtsync_flag & MTSYNC_FLAG_ROTARY)
+        {
+            DetailDebugPrint("[GestureHandleMotionEvent] Rotary input is coming. Dropping touch events.\n");
+            return;
+        }
+        else if (g_pGesture->mtsync_flag & ~MTSYNC_FLAG_TOUCH)
+        {
+            DetailDebugPrint("[GestureHandleMotionEvent] Other input is coming. Dropping touch events.\n");
+            return;
+        }
+    }
+
+    switch (g_pGesture->ehtype)
+    {
+        case KEEP_EVENTS:
+            if (ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev, device))
+            {
+                GestureControl(g_pGesture->this_device, DEVICE_OFF);
+                return;
+            }
+
+            if (g_pGesture->num_mt_devices)
+            {
+                GestureRecognize(ET_Motion, ev, device);
+            }
+            else
+            {
+                device->public.processInputProc(ev, device);
+            }
+
+            GestureHoldDetector(ET_Motion, ev, device);
+            break;
+
+        case PROPAGATE_EVENTS:
+            device->public.processInputProc(ev, device);
+            GestureHoldDetector(ET_Motion, ev, device);
+            break;
+
+        case IGNORE_EVENTS:
+            GestureRecognize(ET_Motion, ev, device);
+            break;
+
+        default:
+            break;
+    }
+
+}
+
+void
+GestureHandleButtonReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
+{
+#ifdef __DEBUG_EVENT_HANDLER__
+    DetailDebugPrint("[GestureHandleButtonReleaseEvent] devid=%d time:%d cur:%d (%d, %d)\n", device->id, ev->any.time, GetTimeInMillis(), ev->device_event.root_x, ev->device_event.root_y);
+#endif
+    int idx=0;
+    if (g_pGesture->touch_cancel_status == TRUE)
+    {
+        DetailDebugPrint("[GestureHandleButtonPressEvent] Ignore Button Press event after touch cancel generated. \n");
+        return;
+    }
+
+    idx = GestureGetFingerIndexFromDevice(device);
+    if (0 <= idx)
+    {
+        g_pGesture->last_touches[idx].status = BTN_RELEASED;
+        g_pGesture->last_touches[idx].cx = ev->device_event.root_x;
+        g_pGesture->last_touches[idx].cy = ev->device_event.root_y;
+    }
+
+    if (g_pGesture->ehtype != KEEP_EVENTS)
+    {
+        if(!(g_pGesture->mtsync_flag & MTSYNC_FLAG_TOUCH))
+        {
+            if(g_pGesture->mtsync_flag & MTSYNC_FLAG_ROTARY)
+            {
+                DetailDebugPrint("[GestureHandleButtonReleaseEvent] Rotary input is coming. Dropping touch events.\n");
+                return;
+            }
+            else if (g_pGesture->mtsync_flag & ~MTSYNC_FLAG_TOUCH)
+            {
+                DetailDebugPrint("[GestureHandleButtonReleaseEvent] Other input is coming. Dropping touch events.\n");
+                return;
+            }
+        }
+    }
+
+    switch (g_pGesture->ehtype)
+    {
+        case KEEP_EVENTS:
+            DetailDebugPrint("[GestureHandleButtonReleaseEvent] KEEP_EVENT\n");
+
+            if (ERROR_INVALPTR == GestureEnqueueEvent(screen_num, ev,  device))
+            {
+                GestureControl(g_pGesture->this_device, DEVICE_OFF);
+                return;
+            }
+
+            if (g_pGesture->num_mt_devices)
+            {
+                GestureRecognize(ET_ButtonRelease, ev, device);
+            }
+            else
+            {
+                device->public.processInputProc(ev, device);
+            }
+
+            GestureHoldDetector(ET_ButtonRelease, ev, device);
+            break;
+
+        case PROPAGATE_EVENTS:
+            DetailDebugPrint("[GestureHandleButtonReleaseEvent] PROPAGATE_EVENTS\n");
+#ifdef SUPPORT_ANR_WITH_INPUT_EVENT
+                     if( IsMaster(device) && ev->any.type == ET_ButtonRelease )
+                     {
+                         if( g_pGesture->anr_window == NULL )
+                         {
+                             g_pGesture->anr_window = _GestureFindANRWindow(device);
+                         }
+                         Time current_time;
+
+                         // Send event to the e17 process.
+                         current_time = GetTimeInMillis();
+                         if( g_pGesture->anr_window != NULL )
+                         {
+                             // Check anr_window validation.
+                             if( dixLookupWindow(&g_pGesture->anr_window, prop_anr_event_window_xid, serverClient, DixSetPropAccess) != BadWindow )
+                             {
+                                 if( serverClient->devPrivates != NULL )
+                                     dixChangeWindowProperty (serverClient, g_pGesture->anr_window, prop_anr_in_input_event,
+                                                                               XA_CARDINAL, 32, PropModeReplace, 1, &current_time, TRUE);
+                             }
+                             else
+                             {
+                                 prop_anr_event_window_xid = 0;
+                                 g_pGesture->anr_window = NULL;
+                             }
+                             DetailDebugPrint("[GestureHandleButtonReleaseEvent] Release TOUCH!! devid=%d time:%d cur: %d\n", device->id, ev->any.time, GetTimeInMillis());
+                         }
+                     }
+#endif
+            device->public.processInputProc(ev, device);
+            GestureHoldDetector(ET_ButtonRelease, ev, device);
+#if 0
+            GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_down);
+            GestureEmulateHWKey(g_pGesture->hwkey_dev, g_pGesture->hwkeycode_flick_up);
+#endif
+            break;
+
+        case IGNORE_EVENTS:
+            DetailDebugPrint("[GestureHandleButtonReleaseEvent] IGNORE_EVENTS\n");
+            GestureRecognize(ET_ButtonRelease, ev, device);
+            break;
+
+        default:
+            break;
+    }
+}
+
+void
+GestureHandleKeyPressEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
+{
+    if ((ev->device_event.detail.key == 124) && (g_pGesture->power_pressed != 0))
+    {
+        g_pGesture->power_pressed = 2;
+        g_pGesture->power_device = device;
+
+        DetailDebugPrint("[GestureHandleKeyPressEvent] power key pressed devid: %d, hwkey_id: %d\n", device->id, g_pGesture->hwkey_id);
+        DetailDebugPrint("[GestureHandleKeyPressEvent] power_pressed: %d\n", g_pGesture->power_pressed);
+    }
+    device->public.processInputProc(ev, device);
+}
+
+void
+GestureHandleKeyReleaseEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
+{
+    if ((ev->device_event.detail.key == 124) && (g_pGesture->power_pressed != 0))
+    {
+        g_pGesture->power_pressed = 1;
+        g_pGesture->power_device = device;
+
+        DetailDebugPrint("[GestureHandleKeyReleaseEvent] power key released devid: %d, hwkey_id: %d\n", device->id, g_pGesture->hwkey_id);
+        DetailDebugPrint("[GestureHandleKeyReleaseEvent] power_pressed: %d\n", g_pGesture->power_pressed);
+    }
+    device->public.processInputProc(ev, device);
+}
+
+static void
+GestureHandleClientState (CallbackListPtr *list, pointer closure, pointer calldata)
+{
+    NewClientInfoRec *clientinfo = (NewClientInfoRec*)calldata;
+    ClientPtr client = clientinfo->client;
+
+    if (client->clientState != ClientStateGone)
+    {
+        return;
+    }
+
+    if (!g_pGesture->factory_cmdname)
+    {
+        return;
+    }
+
+    if (strncmp(client->clientIds->cmdname, g_pGesture->factory_cmdname, strlen(g_pGesture->factory_cmdname)))
+    {
+        return;
+    }
+
+    if (g_pGesture->is_active == 0)
+    {
+        int prop_val = 1;
+        int rc = XIChangeDeviceProperty(g_pGesture->this_device, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &prop_val, FALSE);
+
+        ErrorF("[GestureHandleClientState] %s is exited unintentionally\n", g_pGesture->factory_cmdname);
+
+        if (rc != Success)
+        {
+            ErrorF("[GestureHandleClientState] Failed to Gesture Enable\n");
+            return;
+        }
+    }
+}
+
+static ErrorStatus
+GestureEnableEventHandler(InputInfoPtr pInfo)
+{
+    Bool res;
+    GestureDevicePtr pGesture = pInfo->private;
+
+    res = GestureInstallResourceStateHooks();
+
+    if (!res)
+    {
+        ErrorF("[GestureEnableEventHandler] Failed on GestureInstallResourceStateHooks() !\n");
+        return ERROR_ABNORMAL;
+    }
+
+    res = GestureSetMaxNumberOfFingers((int)MAX_MT_DEVICES);
+
+    if (!res)
+    {
+        ErrorF("[GestureEnableEventHandler] Failed on GestureSetMaxNumberOfFingers(%d) !\n", (int)MAX_MT_DEVICES);
+        goto failed;
+    }
+
+    res = GestureRegisterCallbacks(GestureCbEventsGrabbed, GestureCbEventsSelected);
+
+    if (!res)
+    {
+        ErrorF("[GestureEnableEventHandler] Failed to register callbacks for GestureEventsGrabbed(), GestureEventsSelected() !\n");
+        goto failed;
+    }
+
+    pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 5000, GestureTimerHandler, pInfo);
+
+    if (!pGesture->device_setting_timer)
+    {
+        ErrorF("[GestureEnableEventHandler] Failed to set time for detecting devices !\n");
+        goto failed;
+    }
+
+    return ERROR_NONE;
+
+failed:
+    GestureUninstallResourceStateHooks();
+    GestureUnsetMaxNumberOfFingers();
+
+    return ERROR_ABNORMAL;
+}
+
+static ErrorStatus
+GestureDisableEventHandler(void)
+{
+    ErrorStatus err = ERROR_NONE;
+
+    mieqSetHandler(ET_ButtonPress, NULL);
+    mieqSetHandler(ET_ButtonRelease, NULL);
+    mieqSetHandler(ET_Motion, NULL);
+    mieqSetHandler(ET_KeyPress, NULL);
+    mieqSetHandler(ET_KeyRelease, NULL);
+    mieqSetHandler(ET_MTSync, NULL);
+
+    err = GestureFiniEQ();
+
+    if (ERROR_INVALPTR == err)
+    {
+        ErrorF("[GestureDisableEventHandler] EQ is invalid or was freed already !\n");
+    }
+
+    GestureRegisterCallbacks(NULL, NULL);
+    GestureUninstallResourceStateHooks();
+
+    return err;
+}
+
+static CARD32
+GestureTimerHandler(OsTimerPtr timer, CARD32 time, pointer arg)
+{
+    InputInfoPtr pInfo = (InputInfoPtr)arg;
+    GestureDevicePtr pGesture;
+    int idx;
+    DeviceIntPtr dev;
+
+    if (!pInfo)
+    {
+        ErrorF("[GestureTimerHandler][%s] pInfo is NULL !\n");
+        goto failed;
+    }
+
+    pGesture = pInfo->private;
+
+    idx = 0;
+    for (dev = inputInfo.pointer; dev; dev = dev->next)
+    {
+        if (IsMaster(dev) && IsPointerDevice(dev))
+        {
+            pGesture->master_pointer = dev;
+            ErrorF("[GestureTimerHandler][id:%d] Master Pointer=%s\n", dev->id, pGesture->master_pointer->name);
+            continue;
+        }
+
+        if (IsXTestDevice(dev, NULL) && IsPointerDevice(dev))
+        {
+            pGesture->xtest_pointer = dev;
+            ErrorF("[GestureTimerHandler][id:%d] XTest Pointer=%s\n", dev->id, pGesture->xtest_pointer->name);
+            continue;
+        }
+
+        if (IsPointerDevice(dev))
+        {
+            if (idx >= MAX_MT_DEVICES)
+            {
+                ErrorF("[GestureTimerHandler] Number of mt device is over MAX_MT_DEVICES(%d) !\n", MAX_MT_DEVICES);
+                continue;
+            }
+            pGesture->mt_devices[idx] = dev;
+            ErrorF("[GestureTimerHandler][id:%d] MT device[%d] name=%s\n", dev->id, idx, pGesture->mt_devices[idx]->name);
+            GesturePalmGetAbsAxisInfo(dev);
+            idx++;
+        }
+    }
+
+    for (dev = inputInfo.keyboard ; dev; dev = dev->next)
+    {
+        if (g_pGesture->hwkey_name && !strncmp(dev->name, g_pGesture->hwkey_name, strlen(dev->name)))
+        {
+            g_pGesture->hwkey_id = dev->id;
+            g_pGesture->hwkey_dev = dev;
+
+            ErrorF("[GestureTimerHandler] hwkey_name has been found. hwkey_id=%d (hwkey_dev->name:%s)\n", g_pGesture->hwkey_id, g_pGesture->hwkey_dev->name);
+            break;
+        }
+        else if (!strncmp(dev->name, "tizen_rotary", strlen(dev->name)))
+        {
+            g_pGesture->rotary_id = dev->id;
+            g_pGesture->rotary_dev = dev;
+
+            ErrorF("[GestureTimerHandler] rotary_name has been found. rotary_id=%d (rotary_dev->name:%s)\n", g_pGesture->rotary_id, g_pGesture->rotary_dev->name);
+            break;
+        }
+        else if (!strcasestr(dev->name, "keyboard") && strcasestr(dev->name, "key") && !IsXTestDevice(dev, NULL) && !IsMaster(dev))
+        {
+            g_pGesture->hwkey_id = dev->id;
+            g_pGesture->hwkey_dev = dev;
+
+            ErrorF("[GestureTimerHandler] hwkey has been found. hwkey_id=%d (hwkey_dev->name:%s)\n", g_pGesture->hwkey_id, g_pGesture->hwkey_dev->name);
+            break;
+        }
+    }
+
+    if (!g_pGesture->hwkey_id)
+    {
+        g_pGesture->hwkey_id = inputInfo.keyboard->id;
+        g_pGesture->hwkey_dev = inputInfo.keyboard;
+
+        ErrorF("[GestureTimerHandler] No hwkey has been found. Back key will go through VCK. hwkey_id=%d (hwkey_dev->name:%s)\n",
+                g_pGesture->hwkey_id, g_pGesture->hwkey_dev->name);
+    }
+
+    if (!pGesture->master_pointer || !pGesture->xtest_pointer)
+    {
+        ErrorF("[GestureTimerHandler] Failed to get info of master pointer or XTest pointer !\n");
+        pGesture->device_setting_timer = TimerSet(pGesture->device_setting_timer, 0, 0, NULL, NULL);
+        pGesture->num_mt_devices = 0;
+
+        return 0;
+    }
+
+    TimerCancel(pGesture->device_setting_timer);
+    pGesture->device_setting_timer = NULL;
+    pGesture->num_mt_devices = idx;
+
+    if (!pGesture->num_mt_devices)
+    {
+        ErrorF("[GestureTimerHandler] Failed to mt device information !\n");
+        TimerCancel(pGesture->device_setting_timer);
+        pGesture->device_setting_timer = NULL;
+        pGesture->num_mt_devices = 0;
+        pGesture->first_fingerid = -1;
+        return 0;
+    }
+
+    pGesture->first_fingerid = pGesture->mt_devices[0]->id;
+    memset(pGesture->fingers, 0, sizeof(TouchStatus)*pGesture->num_mt_devices);
+    pGesture->pRootWin = RootWindow(pGesture->master_pointer);
+
+    if (g_pGesture->palm_misc.enabled)
+    {
+        GesturePalmGetScreenInfo();
+    }
+
+    g_pGesture->pTempWin = NULL;
+    g_pGesture->inc_num_pressed = 0;
+
+    if (ERROR_NONE != GestureRegionsInit() || ERROR_NONE != GestureInitEQ())
+    {
+        goto failed;
+    }
+
+    mieqSetHandler(ET_ButtonPress, GestureHandleButtonPressEvent);
+    mieqSetHandler(ET_ButtonRelease, GestureHandleButtonReleaseEvent);
+    mieqSetHandler(ET_Motion, GestureHandleMotionEvent);
+    mieqSetHandler(ET_KeyPress, GestureHandleKeyPressEvent);
+    mieqSetHandler(ET_KeyRelease, GestureHandleKeyReleaseEvent);
+
+    //if ( pGesture->is_active)
+    mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent);
+
+    return 0;
+
+failed:
+    GestureUninstallResourceStateHooks();
+    GestureUnsetMaxNumberOfFingers();
+
+    return 0;
+}
+
+BOOL
+IsXTestDevice(DeviceIntPtr dev, DeviceIntPtr master)
+{
+    if (IsMaster(dev))
+    {
+        return FALSE;
+    }
+
+    if (master)
+    {
+        return (dev->xtest_master_id == master->id);
+    }
+
+    return (dev->xtest_master_id != 0);
+}
+
+void
+GestureGenerateTouchCancelEvent(void)
+{
+    int i;
+    Bool canceled_touch_index[MAX_MT_DEVICES] = {FALSE, };
+
+    if (g_pGesture->mtsync_flag & MTSYNC_FLAG_TOUCH)
+    {
+        ErrorF("no Touch(%d)\n", g_pGesture->mtsync_flag);
+        return;
+    }
+
+    for (i=0; i<MAX_MT_DEVICES; i++)
+    {
+        if (!(g_pGesture->mt_devices[i]->button->buttonsDown)) continue;
+        InternalEvent cancel_event;
+
+        cancel_event.touch_cancel_event.header = ET_Internal;
+        cancel_event.touch_cancel_event.type = ET_TouchCancel;
+        cancel_event.touch_cancel_event.length = sizeof(TouchCancelEvent);
+        cancel_event.touch_cancel_event.time = CurrentTime;
+        cancel_event.touch_cancel_event.deviceid = g_pGesture->mt_devices[i]?g_pGesture->mt_devices[i]->id:0;
+
+        cancel_event.touch_cancel_event.sourceid = g_pGesture->mt_devices[i]?g_pGesture->mt_devices[i]->id:0;
+        cancel_event.touch_cancel_event.resource = 0;
+        cancel_event.touch_cancel_event.flags = 0;
+
+        g_pGesture->mt_devices[i]->public.processInputProc(&cancel_event, g_pGesture->mt_devices[i]);
+        canceled_touch_index[i] = TRUE;
+        g_pGesture->touch_cancel_status = TRUE;
+    }
+
+    for (i=0; i<MAX_MT_DEVICES; i++)
+    {
+        if (canceled_touch_index[i] == FALSE) continue;
+        InternalEvent release_event;
+        InternalEvent release_event_master;
+
+        memset(&release_event, 0, sizeof(InternalEvent));
+
+        release_event.device_event.header = ET_Internal;
+        release_event.device_event.type = ET_ButtonRelease;
+        release_event.device_event.length = sizeof(DeviceEvent);
+        release_event.device_event.time = CurrentTime;
+        release_event.device_event.deviceid = g_pGesture->mt_devices[i]->id;
+        release_event.device_event.sourceid = g_pGesture->mt_devices[i]->button->sourceid;
+        release_event.device_event.detail.button = 1;
+        release_event.device_event.root_x = g_pGesture->last_touches[i].cx;
+        release_event.device_event.root_y = g_pGesture->last_touches[i].cy;
+        if (g_pGesture->mt_devices[i]->id == g_pGesture->first_fingerid)
+        {
+            memcpy(&release_event_master, &release_event, sizeof(InternalEvent));
+            release_event_master.device_event.deviceid = g_pGesture->master_pointer->id;
+        }
+
+        g_pGesture->mt_devices[i]->public.processInputProc(&release_event, g_pGesture->mt_devices[i]);
+        if (g_pGesture->mt_devices[i]->id == g_pGesture->first_fingerid)
+        {
+            g_pGesture->master_pointer->public.processInputProc(&release_event_master, g_pGesture->master_pointer);
+        }
+        g_pGesture->touch_cancel_status = TRUE;
+    }
+}
+
+static void
+GestureDPMSCallback(CallbackListPtr *pcbl, void *unused, void *calldata)
+{
+    int dpmsLevel = *(int *)calldata;
+
+    if ((DPMSModeOff == dpmsLevel) && (MTSYNC_FLAG_TOUCH & g_pGesture->mtsync_flag)) {
+        ErrorF("TouchCancel dpmslevel: %d, g_pGesture->mtsync_flag: %d\n", dpmsLevel, g_pGesture->mtsync_flag);
+        GestureGenerateTouchCancelEvent();
+    }
+}
+
+void
+GestureEnable(int enable, Bool prop, DeviceIntPtr dev)
+{
+    if ((!enable) && (g_pGesture->is_active))
+    {
+        g_pGesture->ehtype = PROPAGATE_EVENTS;
+        mieqSetHandler(ET_MTSync, NULL);
+        g_pGesture->is_active = 0;
+        ErrorF("[GestureEnable] Disabled !\n");
+        int res = AddCallback (&ClientStateCallback, GestureHandleClientState, NULL);
+
+        if (!res)
+        {
+            ErrorF("[GestureEnable] Failed to add callback for client state\n");
+            return;
+        }
+    }
+
+    else if ((enable) && (!g_pGesture->is_active))
+    {
+        g_pGesture->ehtype = KEEP_EVENTS;
+        mieqSetHandler(ET_MTSync, GestureHandleMTSyncEvent);
+        g_pGesture->is_active = 1;
+        ErrorF("[GestureEnable] Enabled !\n");
+
+        DeleteCallback (&ClientStateCallback, GestureHandleClientState, NULL);
+    }
+
+    if (!prop)
+    {
+        XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE);
+    }
+}
+
+ErrorStatus
+GestureRegionsInit(void)
+{
+    int i;
+
+    if (!g_pGesture)
+    {
+        return ERROR_INVALPTR;
+    }
+
+    pixman_region_init(&g_pGesture->area);
+
+    for (i = 0; i < MAX_MT_DEVICES; i++)
+    {
+        pixman_region_init_rect(&g_pGesture->finger_rects[i], 0, 0, FINGER_WIDTH_2T, FINGER_HEIGHT_2T);
+    }
+
+    return ERROR_NONE;
+}
+
+ErrorStatus
+GestureRegionsReinit(void)
+{
+    if (!g_pGesture)
+    {
+        ErrorF("[GestureRegionsReinit] Invalid pointer access !\n");
+        return ERROR_INVALPTR;
+    }
+
+    pixman_region_init(&g_pGesture->area);
+
+    return ERROR_NONE;
+}
+
+ErrorStatus
+GestureInitEQ(void)
+{
+    int i;
+    IEventPtr tmpEQ;
+
+    tmpEQ = (IEventRec *)calloc(GESTURE_EQ_SIZE, sizeof(IEventRec));
+
+    if (!tmpEQ)
+    {
+        ErrorF("[GestureInitEQ] Failed to allocate memory for EQ !\n");
+        return ERROR_ALLOCFAIL;
+    }
+
+    for (i = 0; i < GESTURE_EQ_SIZE; i++)
+    {
+        tmpEQ[i].event = (InternalEvent *)malloc(sizeof(InternalEvent));
+        if (!tmpEQ[i].event)
+        {
+            ErrorF("[GestureInitEQ] Failed to allocation memory for each event buffer in EQ !\n");
+            i--;
+            while(i >= 0 && tmpEQ[i].event)
+            {
+                free(tmpEQ[i].event);
+                tmpEQ[i].event = NULL;
+            }
+            free (tmpEQ);
+            tmpEQ = NULL;
+            return ERROR_ALLOCFAIL;
+        }
+    }
+
+    g_pGesture->EQ = tmpEQ;
+    g_pGesture->headEQ = g_pGesture->tailEQ = 0;
+
+    return ERROR_NONE;
+}
+
+ErrorStatus
+GestureFiniEQ(void)
+{
+    int i;
+
+    if (!g_pGesture || !g_pGesture->EQ)
+    {
+        return ERROR_INVALPTR;
+    }
+
+    for (i = 0; i < GESTURE_EQ_SIZE; i++)
+    {
+        if (g_pGesture->EQ[i].event)
+        {
+            free(g_pGesture->EQ[i].event);
+            g_pGesture->EQ[i].event = NULL;
+        }
+    }
+
+    free(g_pGesture->EQ);
+    g_pGesture->EQ = NULL;
+
+    return ERROR_NONE;
+}
+
+ErrorStatus
+GestureEnqueueEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
+{
+    int tail;
+
+    if (!g_pGesture || !g_pGesture->EQ)
+    {
+        ErrorF("[GestureEnqueueEvent] Invalid pointer access !\n");
+        return ERROR_INVALPTR;
+    }
+
+    tail = g_pGesture->tailEQ;
+
+    if (tail >= GESTURE_EQ_SIZE)
+    {
+        ErrorF("[GestureEnqueueEvent] Gesture EQ is full !\n");
+        printk("[GestureEnqueueEvent] Gesture EQ is full...Force Gesture Flush !\n");
+        GestureEventsFlush();
+        return ERROR_EQFULL;
+    }
+
+    if((g_pGesture->mtsync_flag & MTSYNC_FLAG_ROTARY) || (g_pGesture->mtsync_flag & ~MTSYNC_FLAG_TOUCH))
+    {
+        DetailDebugPrint("[GestureEnqueueEvent] Rotary or other input are coming. Do not push events to queue.\n");
+        return ERROR_NONE;
+    }
+
+    switch (ev->any.type)
+    {
+        case ET_ButtonPress:
+            DetailDebugPrint("[GestureEnqueueEvent] ET_ButtonPress (id:%d)\n", device->id);
+            break;
+
+        case ET_ButtonRelease:
+            DetailDebugPrint("[GestureEnqueueEvent] ET_ButtonRelease (id:%d)\n", device->id);
+            break;
+
+        case ET_Motion:
+            DetailDebugPrint("[GestureEnqueueEvent] ET_Motion (id:%d)\n", device->id);
+            break;
+    }
+
+    g_pGesture->EQ[tail].device = device;
+    g_pGesture->EQ[tail].screen_num = screen_num;
+    memcpy(g_pGesture->EQ[tail].event, ev, sizeof(InternalEvent));//need to be optimized
+    g_pGesture->tailEQ++;
+
+    return ERROR_NONE;
+}
+
+ErrorStatus
+GestureEventsFlush(void)
+{
+    int i;
+    DeviceIntPtr device;
+
+    if (!g_pGesture->EQ)
+    {
+        ErrorF("[GestureEventsFlush] Invalid pointer access !\n");
+        return ERROR_INVALPTR;
+    }
+
+    DetailDebugPrint("[GestureEventsFlush]\n");
+
+    for (i = g_pGesture->headEQ; i < g_pGesture->tailEQ; i++)
+    {
+        device = g_pGesture->EQ[i].device;
+        device->public.processInputProc(g_pGesture->EQ[i].event, device);
+    }
+
+    for (i = 0; i < MAX_MT_DEVICES; i++)
+    {
+        g_pGesture->event_sum[i] = 0;
+    }
+
+    g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
+
+    return ERROR_NONE;
+}
+
+void
+GestureEventsDrop(void)
+{
+    DetailDebugPrint("[GestureEventsDrop]\n");
+    g_pGesture->headEQ = g_pGesture->tailEQ = 0;//Free EQ
+}
+
+#ifdef HAVE_PROPERTIES
+static void
+GestureInitProperty(DeviceIntPtr dev)
+{
+    int rc;
+
+#ifdef SUPPORT_ANR_WITH_INPUT_EVENT
+    prop_anr_in_input_event = MakeAtom(CHECK_APPLICATION_NOT_RESPONSE_IN_INPUT_EVENT, strlen(CHECK_APPLICATION_NOT_RESPONSE_IN_INPUT_EVENT),  TRUE);
+    prop_anr_event_window = MakeAtom(ANR_EVENT_WINDOW, strlen(ANR_EVENT_WINDOW), TRUE);
+#endif
+
+    prop_gesture_recognizer_onoff = MakeAtom(GESTURE_RECOGNIZER_ONOFF, strlen(GESTURE_RECOGNIZER_ONOFF),  TRUE);
+    rc = XIChangeDeviceProperty(dev, prop_gesture_recognizer_onoff, XA_INTEGER, 32, PropModeReplace, 1, &g_pGesture->is_active, FALSE);
+
+    if (rc != Success)
+    {
+        return;
+    }
+
+    XISetDevicePropertyDeletable(dev, prop_gesture_recognizer_onoff, FALSE);
+}
+
+static int
+GestureSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
+        BOOL checkonly)
+{
+    if (prop_gesture_recognizer_onoff == atom)
+    {
+        int data;
+        if (val->format != 32 || val->type != XA_INTEGER || val->size != 1)
+            return BadMatch;
+
+        if (!checkonly)
+        {
+            data = *((int *)val->data);
+            GestureEnable(data, TRUE, dev);
+        }
+    }
+    return Success;
+}
+#endif//HAVE_PROPERTIES
+
+static int
+GestureInit(DeviceIntPtr device)
+{
+#ifdef HAVE_PROPERTIES
+    GestureInitProperty(device);
+    XIRegisterPropertyHandler(device, GestureSetProperty, NULL, NULL);
+#endif
+    //GestureEnable(1, FALSE, g_pGesture->this_device);
+    return Success;
+}
+
+static void
+GestureFini(DeviceIntPtr device)
+{
+    XIRegisterPropertyHandler(device, NULL, NULL, NULL);
+}
+
+static pointer
+GesturePlug(pointer module, pointer options, int *errmaj, int *errmin)
+{
+    xf86AddInputDriver(&GESTURE, module, 0);
+    return module;
+}
+
+static void
+GestureUnplug(pointer p)
+{
+}
+
+static int
+GesturePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
+{
+    int rc = BadAlloc;
+    GestureDevicePtr pGesture;
+
+    pGesture = calloc(1, sizeof(GestureDeviceRec));
+
+    if (!pGesture)
+    {
+        pInfo->private = NULL;
+        //xf86DeleteInput(pInfo, 0);
+        goto error;
+    }
+
+    g_pGesture = pGesture;
+
+    pInfo->private = pGesture;
+    pInfo->flags = 0;
+    pInfo->read_input = GestureReadInput; /* new data avl */
+    pInfo->switch_mode = NULL; /* toggle absolute/relative mode */
+    pInfo->device_control = GestureControl; /* enable/disable dev */
+
+    /* process driver specific options */
+    pGesture->device = xf86SetStrOption(pInfo->options, "Device", "/dev/null");
+    pGesture->is_active = xf86SetIntOption(pInfo->options, "Activate", 0);
+    pGesture->gestureWin = None;
+    pGesture->lastSelectedWin = None;
+    pGesture->power_pressed = 1;
+    pGesture->hwkey_id = 0;
+    pGesture->hwkey_dev = NULL;
+    pGesture->num_tap_repeated = 0;
+    pGesture->mtsync_total_count = 0;
+    pGesture->hwkey_name = xf86SetStrOption(pInfo->options, "BackHWKeyName", NULL);
+    pGesture->screen_width = xf86SetIntOption(pInfo->options,"ScreenWidth", 0);
+    pGesture->screen_height = xf86SetIntOption(pInfo->options,"ScreenHeight", 0);
+    pGesture->hwkeycode_flick_down = xf86SetIntOption(pInfo->options, "FlickDownKeycode", 0);
+    pGesture->hwkeycode_flick_up = xf86SetIntOption(pInfo->options, "FlickUpKeycode", 0);
+    pGesture->flick_press_area = xf86SetIntOption(pInfo->options, "FlickPressArea", 0);
+    pGesture->flick_press_area_left = xf86SetIntOption(pInfo->options, "FlickPressArea_LEFT", 0);
+    pGesture->flick_press_area_left_right = xf86SetIntOption(pInfo->options, "FlickPressArea_LEFT_RIGHT", 0);
+    pGesture->flick_minimum_height = xf86SetIntOption(pInfo->options, "FlickMinimumHeight", 0);
+    pGesture->shutdown_keycode = xf86SetIntOption(pInfo->options, "ShutdownKeycode", 0);
+    pGesture->singletap_threshold= xf86SetIntOption(pInfo->options, "SingleTapThresHold", 0);
+    pGesture->doubletap_threshold= xf86SetIntOption(pInfo->options, "DoubleTapThresHold", 0);
+    pGesture->tripletap_threshold= xf86SetIntOption(pInfo->options, "TripleTapThresHold", 0);
+    pGesture->hold_area_threshold = xf86SetRealOption(pInfo->options, "HoldAreaThresHold", 0);
+    pGesture->hold_move_threshold = xf86SetIntOption(pInfo->options, "HoldMoveThresHold", 0);
+    pGesture->hold_time_threshold = xf86SetIntOption(pInfo->options, "HoldTimeThresHold", 0);
+    pGesture->palm_flick_time_threshold = xf86SetIntOption(pInfo->options, "PalmFlickTimeThresHold", 0);
+    pGesture->palm_flick_max_tmajor_threshold = xf86SetIntOption(pInfo->options, "PalmFlickMaxTouchMajorThresHold", 0);
+    pGesture->palm_flick_min_tmajor_threshold = xf86SetIntOption(pInfo->options, "PalmFlickMinTouchMajorThresHold", 0);
+    pGesture->activate_flick_down = xf86SetIntOption(pInfo->options, "ActivateFlickDown", 0);
+    pGesture->activate_flick_up = xf86SetIntOption(pInfo->options, "ActivateFlickUp", 0);
+    pGesture->activate_flick_right = xf86SetIntOption(pInfo->options, "ActivateFlickRight", 0);
+    pGesture->factory_cmdname = xf86SetStrOption(pInfo->options, "FactoryCmdName", NULL);
+
+    ErrorF("[X11][%s] ###############################################################\n", __FUNCTION__);
+    ErrorF("[X11][%s] screen_width=%d, screen_height=%d\n", __FUNCTION__,
+            pGesture->screen_width, pGesture->screen_height);
+    ErrorF("[X11][%s] FlickDownKeycode=%d, FlickUpKeycode=%d\n", __FUNCTION__,
+            pGesture->hwkeycode_flick_down, pGesture->hwkeycode_flick_up);
+    ErrorF("[X11][%s] flick_press_area=%d, flick_press_area_left: %d, flick_press_area_left_right: %d, flick_minimum_height=%d\n", __FUNCTION__,
+            pGesture->flick_press_area, pGesture->flick_press_area_left, pGesture->flick_press_area_left_right, pGesture->flick_minimum_height);
+    ErrorF("[X11][%s] ShutdownKeycode=%d\n", __FUNCTION__, pGesture->shutdown_keycode);
+    ErrorF("[X11][%s] singletap_threshold=%d, doubletap_threshold=%d\n", __FUNCTION__, pGesture->singletap_threshold, pGesture->doubletap_threshold);
+    ErrorF("[X11][%s] hold_area_threshold: %f, hold_move_threshold: %d, hold_time_threshold: %d\n", __FUNCTION__,
+            pGesture->hold_area_threshold, pGesture->hold_move_threshold, pGesture->hold_time_threshold);
+    ErrorF("[X11][%s] palm_flick_time_threshold: %d, palm_flick_max_tmajor_threshold: %d, palm_flick_min_tmajor_threshold: %d\n", __FUNCTION__,
+            pGesture->palm_flick_time_threshold, pGesture->palm_flick_max_tmajor_threshold, pGesture->palm_flick_min_tmajor_threshold);
+    ErrorF("[X11][%s] activate_flick_down=%d, activate_flick_up=%d, activate_flick_right=%d\n", __FUNCTION__,
+            pGesture->activate_flick_down, pGesture->activate_flick_up, pGesture->activate_flick_right);
+    ErrorF("[X11][%s] factory cmd name: %s\n", __FUNCTION__, pGesture->factory_cmdname);
+    ErrorF("[X11][%s] ###############################################################\n", __FUNCTION__);
+
+    if (pGesture->hwkey_name)
+    {
+        ErrorF("[X11][%s] hwkey_name=%s\n", __FUNCTION__, pGesture->hwkey_name);
+    }
+
+    pGesture->mtsync_flag = 0x00;
+    g_pGesture->grabMask = g_pGesture->eventMask = 0;
+
+    xf86Msg(X_INFO, "%s: Using device %s.\n", pInfo->name, pGesture->device);
+
+    /* process generic options */
+    xf86CollectInputOptions(pInfo, NULL);
+    xf86ProcessCommonOptions(pInfo, pInfo->options);
+
+    pInfo->fd = -1;
+
+    g_pGesture->touch_cancel_status = FALSE;
+
+    return Success;
+
+error:
+    if (pInfo->fd >= 0)
+        close(pInfo->fd);
+    return rc;
+}
+
+static void
+GestureUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
+{
+    GestureDevicePtr pGesture = pInfo->private;
+
+    g_pGesture = pGesture = NULL;
+    pInfo->private = NULL;
+
+    xf86DeleteInput(pInfo, 0);
+}
+
+static int
+GestureControl(DeviceIntPtr device, int what)
+{
+    InputInfoPtr  pInfo = device->public.devicePrivate;
+    GestureDevicePtr pGesture = pInfo->private;
+
+    switch (what)
+    {
+        case DEVICE_INIT:
+            GestureInit(device);
+            break;
+
+            /* Switch device on.  Establish socket, start event delivery.  */
+        case DEVICE_ON:
+            xf86Msg(X_INFO, "%s: On.\n", pInfo->name);
+
+            if (device->public.on)
+                break;
+
+            device->public.on = TRUE;
+            pGesture->this_device = device;
+            pGesture->num_mt_devices = 0;
+            if (ERROR_ABNORMAL == GestureEnableEventHandler(pInfo))
+                goto device_off;
+            if (!AddCallback(&DPMSCallback, GestureDPMSCallback, NULL))
+                ErrorF("[Gesture]Failed to Add DPMS CallBack\n");
+            break;
+
+        case DEVICE_OFF:
+device_off:
+            GestureDisableEventHandler();
+            DeleteCallback(&DPMSCallback, GestureDPMSCallback, NULL);
+            GestureFini(device);
+            pGesture->this_device = NULL;
+            xf86Msg(X_INFO, "%s: Off.\n", pInfo->name);
+
+            if (!device->public.on)
+                break;
+
+            pInfo->fd = -1;
+            device->public.on = FALSE;
+            break;
+
+        case DEVICE_CLOSE:
+            /* free what we have to free */
+            break;
+    }
+    return Success;
+}
+
+static void
+GestureReadInput(InputInfoPtr pInfo)
+{
+}
+
+
+
old mode 100755 (executable)
new mode 100644 (file)
similarity index 69%
rename from src/gesture.h
rename to wearable/src/gesture.h
index 8f7bed0..e5c59ae
@@ -41,12 +41,25 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define HAVE_PROPERTIES 1
 #endif
 
+/**
+ * If there's touch event in pointed window and there's no reponse, we just assume that client looks like deadlock.
+ * In this case, we will make a popup window and terminate application.
+ * To support this feature, we use SUPPORT_ANR_WITH_INPUT_EVENT flag.
+ */
+#define SUPPORT_ANR_WITH_INPUT_EVENT
+
+#define GESTURE_RECOGNIZER_ONOFF       "GESTURE_RECOGNIZER_ONOFF"
+#define GESTURE_PALM_REJECTION_MODE    "GESTURE_PALM_REJECTION_MODE"
+#define CHECK_APPLICATION_NOT_RESPONSE_IN_INPUT_EVENT "_CHECK_APPLICATION_NOT_RESPONSE_IN_INPUT_EVENT_"
+#define ANR_EVENT_WINDOW "_ANR_EVENT_WINDOW_"
+
+
 #define SYSCALL(call) while (((call) == -1) && (errno == EINTR))
 #define RootWindow(dev) dev->spriteInfo->sprite->spriteTrace[0]
 #define CLIENT_BITS(id) ((id) & RESOURCE_CLIENT_MASK)
 #define CLIENT_ID(id) ((int)(CLIENT_BITS(id) >> CLIENTOFFSET))
 
-#define MAX_MT_DEVICES         3
+#define MAX_MT_DEVICES         2
 #define GESTURE_EQ_SIZE        256
 
 #define GESTURE_RECOGNIZER_ONOFF       "GESTURE_RECOGNIZER_ONOFF"
@@ -68,9 +81,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define SINGLE_TAP_TIMEOUT             100//in msec
 #define DOUBLE_TAP_TIMEOUT     250//in msec
 
-//pinch rotation
-#define ZOOM_THRESHOLD                 0.05f
-#define ANGLE_THRESHOLD                0.1f
+//palm
+#define PALM_HORIZ_ARRAY_COUNT 3
+#define PALM_VERTI_ARRAY_COUNT 4
 
 typedef int XFixed;
 typedef double XDouble;
@@ -93,54 +106,51 @@ enum
        FLICK_NORTHWESTWARD
 };
 
-#define PAN_AREA_THRESHOLD                     10000//=100pixel * 100pixel
-#define PAN_MOVE_THRESHOLD                     5//pixel
-#define PAN_UPDATE_MOVE_THRESHOLD      3//pixel
-#define PAN_TIME_THRESHOLD                     300//ms
-
-#define PINCHROTATION_TIME_THRESHOLD           500//ms
-#define PINCHROTATION_INIT_DIST_THRESHOLD      25.0f
-#define PINCHROTATION_INIT_ANGLE_THRESHOLD     0.2f
-#define PINCHROTATION_DIST_THRESHOLD           25.0f
-#define PINCHROTATION_ANGLE_THRESHOLD          0.2f
-
-#define HOLD_AREA_THRESHOLD                    2500//=50pixel * 50pixel
-#define HOLD_MOVE_THRESHOLD                    10//pixel
-#define HOLD_TIME_THRESHOLD                    500//ms
+enum
+{
+       FLICK_POINT_NONE = 0,
+       FLICK_POINT_UP,
+       FLICK_POINT_RIGHT,
+       FLICK_POINT_DOWN,
+       FLICK_POINT_LEFT,
+       FLICK_POINT_MAX
+};
 
 #define TAP_AREA_THRESHOLD                     10000//= 100pixel * 100pixel
-#define TAP_MOVE_THRESHOLD                     70//pixel
-#define SGL_TAP_TIME_THRESHOLD         200//ms
+#define TAP_MOVE_THRESHOLD                     35//pixel
+#define SGL_TAP_TIME_THRESHOLD         300//ms
 #define DBL_TAP_TIME_THRESHOLD         200//ms
-#define MAX_TAP_REPEATS                                3
-
-#define TAPNHOLD_AREA_THRESHOLD                        4900//= 70pixel * 70pixel
-#define TAPNHOLD_MOVE_THRESHOLD                        50//pixel
-#define TAPNHOLD_TAP_TIME_THRESHOLD            200//ms
-#define TAPNHOLD_INTV_TIME_THRESHOLD           200//ms
-#define TAPNHOLD_HOLD_TIME_THRESHOLD   500//ms
+#define MAX_TAP_REPEATS             3
 
 #define FLICK_AREA_THRESHOLD                   22500//=150pixel * 150pixel
 #define FLICK_AREA_TIMEOUT                             700//ms
 #define FLICK_MOVE_THRESHOLD                   100//pixel
 #define FLICK_MOVE_TIMEOUT                             1000//ms
+#define FLICK_FALSE_Y_DIFF_COUNT               7
+#define FLICK_FALSE_X_DIFF_COUNT               5
+
+#define PALM_FLICK_DETECT_TIMEOUT                      1000//ms
+#define PALM_FLICK_MAX_TOUCH_MAJOR             130
 
-#define RAD_90DEG  M_PI_2
-#define RAD_180DEG M_PI
-#define RAD_270DEG (M_PI_2 * 3)
-#define RAD_360DEG (M_PI * 2)
-#define rad2degree(r) ((r) * 180/M_PI)
+#define AXIS_LABEL_PROP_ABS_MT_TRACKING_ID "Abs MT Tracking ID"
+#define AXIS_LABEL_PROP_ABS_MT_SLOT     "Abs MT Slot"
+#define AXIS_LABEL_PROP_ABS_MT_TOUCH_MAJOR "Abs MT Touch Major"
+#define AXIS_LABEL_PROP_ABS_MT_TOUCH_MINOR "Abs MT Touch Minor"
+#define AXIS_LABEL_PROP_ABS_MT_PALM        "Abs MT Palm/MT Sumsize"
 
 typedef enum _MTSyncType
 {
        MTOUCH_FRAME_SYNC_END,
-       MTOUCH_FRAME_SYNC_BEGIN
+       MTOUCH_FRAME_SYNC_BEGIN,
+       MTOUCH_FRAME_SYNC_UPDATE,
+       ROTARY_FRAME_SYNC_END,
+       ROTARY_FRAME_SYNC_BEGIN
 } MTSyncType;
 
 typedef enum _EventHandleType
 {
-       KEEP_EVENTS,
        PROPAGATE_EVENTS,
+       KEEP_EVENTS,
        IGNORE_EVENTS
 } EventHandleType;
 
@@ -163,12 +173,12 @@ enum EventType
     /*
     ...
     */
+    ET_TouchCancel = 31,
     ET_MTSync = 0x7E,
     ET_Internal = 0xFF /* First byte */
 };
 
-struct _DeviceEvent
-{
+struct _DeviceEvent {
     unsigned char header; /**< Always ET_Internal */
     enum EventType type;  /**< One of EventType */
     int length;           /**< Length in bytes */
@@ -176,19 +186,20 @@ struct _DeviceEvent
     int deviceid;         /**< Device to post this event for */
     int sourceid;         /**< The physical source device */
     union {
-        uint32_t button;  /**< Button number */
+        uint32_t button;  /**< Button number (also used in pointer emulating
+                               touch events) */
         uint32_t key;     /**< Key code */
     } detail;
+    uint32_t touchid;     /**< Touch ID (client_id) */
     int16_t root_x;       /**< Pos relative to root window in integral data */
     float root_x_frac;    /**< Pos relative to root window in frac part */
     int16_t root_y;       /**< Pos relative to root window in integral part */
     float root_y_frac;    /**< Pos relative to root window in frac part */
-    uint8_t    buttons[(MAX_BUTTONS + 7)/8]; /**< Button mask */
+    uint8_t buttons[(MAX_BUTTONS + 7) / 8];  /**< Button mask */
     struct {
-        uint8_t  mask[(MAX_VALUATORS + 7)/8]; /**< Valuator mask */
-        uint8_t  mode[(MAX_VALUATORS + 7)/8]; /**< Valuator mode (Abs or Rel)*/
-        int32_t  data[MAX_VALUATORS];         /**< Valuator data */
-        int32_t  data_frac[MAX_VALUATORS];    /**< Fractional part for data */
+        uint8_t mask[(MAX_VALUATORS + 7) / 8];/**< Valuator mask */
+        uint8_t mode[(MAX_VALUATORS + 7) / 8];/**< Valuator mode (Abs or Rel)*/
+        double data[MAX_VALUATORS];           /**< Valuator data */
     } valuators;
     struct {
         uint32_t base;    /**< XKB base modifiers */
@@ -202,9 +213,10 @@ struct _DeviceEvent
         uint8_t locked;  /**< XKB locked group */
         uint8_t effective;/**< XKB effective group */
     } group;
-    Window      root; /**< Root window of the event */
+    Window root;      /**< Root window of the event */
     int corestate;    /**< Core key/button state BEFORE the event */
     int key_repeat;   /**< Internally-generated key repeat event */
+    uint32_t flags;   /**< Flags to be copied into the generated event */
 };
 
 typedef struct _AnyEvent AnyEvent;
@@ -220,6 +232,20 @@ struct _AnyEvent
     int y;
 };
 
+typedef struct _TouchCancelEvent TouchCancelEvent;
+struct _TouchCancelEvent {
+    unsigned char header; /**< Always ET_Internal */
+    enum EventType type;  /**< ET_TouchOwnership */
+    int length;           /**< Length in bytes */
+    Time time;            /**< Time in ms */
+    int deviceid;         /**< Device to post this event for */
+    int sourceid;         /**< The physical source device */
+    uint32_t resource;    /**< Provoking grab or event selection */
+    uint32_t flags;       /**< Flags to be copied into the generated event */
+};
+
+
+
 union _InternalEvent {
        struct {
            unsigned char header; /**< Always ET_Internal */
@@ -229,6 +255,7 @@ union _InternalEvent {
        } any;
        AnyEvent any_event;
        DeviceEvent device_event;
+       TouchCancelEvent touch_cancel_event;
 };
 
 #define wUseDefault(w,field,def)       ((w)->optional ? (w)->optional->field : def)
@@ -333,6 +360,18 @@ enum
 
 #define GESTURE_FILTER_MASK_ALL        0x3f//(FlickFilterMask | PanFilterMask | PinchRotationFilterMask | TapFilterMask |TapNHoldFilterMask | HoldFilterMask)
 
+#define WFlickFilterMask                               0x01//(1 << 0)
+#define WTapFilterMask                         0x02//(1 << 1)
+#define WHoldFilterMask                                0x04//(1 << 2)
+#define WPalmFlickFilterMask                   0x08//(1 << 3)
+
+#define GESTURE_WATCH_FILTER_MASK_ALL  0x07//(WFlickFilterMask | WTapFilterMask | WHoldFilterMask )
+
+#define MTSYNC_FLAG_TOUCH 0x01//(1 << 0)
+#define MTSYNC_FLAG_ROTARY 0x02//(1 << 1)
+
+#define PALM_HOLD_TIME_THRESHOLD 150
+
 typedef struct _tagTouchStatus
 {
        int status;//One of BTN_RELEASED, BTN_PRESSED and BTN_MOVING
@@ -349,6 +388,24 @@ typedef struct _tagTouchStatus
        Time rtime;     //current/previous release time
 } TouchStatus;
 
+typedef struct _tagCurrentTouchStatus
+{
+       int status;//One of BTN_RELEASED, BTN_PRESSED and BTN_MOVING
+       int cx;         //current x
+       int cy;         //current y
+} CurTouchStatus;
+
+typedef struct _tagPalmDrvStatus
+{
+       int enabled;
+       int scrn_width;
+       int scrn_height;
+       unsigned int half_scrn_area_size;
+       int horiz_coord[PALM_HORIZ_ARRAY_COUNT];
+       int verti_coord[PALM_VERTI_ARRAY_COUNT];
+} PalmMiscInfo, *PalmMiscInfoPtr;
+
+
 typedef struct _GestureDeviceRec
 {
        char *device;
@@ -356,6 +413,49 @@ typedef struct _GestureDeviceRec
        OsTimerPtr device_setting_timer;
 
        int is_active;
+       int power_pressed;
+       int flick_pressed_point;
+       int flick_direction;
+
+       int hwkeycode_flick_down;
+       int hwkeycode_flick_up;
+       int shutdown_keycode;
+       int flick_press_area;
+       int flick_press_area_left;
+       int flick_press_area_left_right;
+       int flick_minimum_height;
+       int activate_flick_down;//up to down
+       int activate_flick_up;//down to up
+       int activate_flick_right;//left to right
+       int screen_width;
+       int screen_height;
+
+       int singletap_threshold;
+       int doubletap_threshold;
+       int tripletap_threshold;
+
+       int num_tap_repeated;
+
+       double hold_area_threshold;
+       int hold_move_threshold;
+       int hold_time_threshold;
+
+       int palm_flick_time_threshold;
+       int palm_flick_max_tmajor_threshold;
+       int palm_flick_min_tmajor_threshold;
+       char *factory_cmdname;
+
+       int max_mt_tmajor[MAX_MT_DEVICES];
+
+       int hwkey_id;
+       char *hwkey_name;
+       DeviceIntPtr hwkey_dev;
+       int rotary_id;
+       DeviceIntPtr rotary_dev;
+       unsigned char mtsync_flag;
+       int mtsync_total_count;
+
+       DeviceIntPtr power_device;
 
        WindowPtr pRootWin;
        Window gestureWin;
@@ -364,12 +464,29 @@ typedef struct _GestureDeviceRec
        Mask grabMask;
        Mask eventMask;
        GestureGrabEventPtr GrabEvents;
+       Mask lastSelectedMask;
+       Window lastSelectedWin;
 
        EventHandleType ehtype;
        IEventPtr       EQ;
        int headEQ;
        int tailEQ;
 
+       int hold_detector_activate;
+       int has_hold_grabmask;
+       pixman_region16_t chold_area;
+       CurTouchStatus cts[MAX_MT_DEVICES];
+       CurTouchStatus last_touches[MAX_MT_DEVICES];
+       Bool touch_cancel_status;
+       Bool hold_detected;
+
+       PalmMiscInfo palm_misc;
+       int tmajor_idx;
+       int tminor_idx;
+       int tpalm_idx;
+       int mt_px_idx;
+       int mt_py_idx;
+
        pixman_region16_t area;
        pixman_region16_t finger_rects[MAX_MT_DEVICES];
 
@@ -388,6 +505,8 @@ typedef struct _GestureDeviceRec
        DeviceIntPtr mt_devices[MAX_MT_DEVICES];
        DeviceIntPtr master_pointer;
        DeviceIntPtr xtest_pointer;
+
+       WindowPtr anr_window;
 } GestureDeviceRec, *GestureDevicePtr ;
 
 #endif//_GESTURE_H_
diff --git a/wearable/xorg-gesture.pc.in b/wearable/xorg-gesture.pc.in
new file mode 100644 (file)
index 0000000..320b0be
--- /dev/null
@@ -0,0 +1,6 @@
+sdkdir=@sdkdir@
+
+Name: xorg-evdev
+Description: X.Org gesture input driver.
+Version: @PACKAGE_VERSION@
+Cflags: -I${sdkdir}