[FEATURE] add gesture layer callback probes 77/39477/1
authorVitaliy Cherepanov <v.cherepanov@samsung.com>
Fri, 30 Jan 2015 11:58:03 +0000 (14:58 +0300)
committerVitaliy Cherepanov <v.cherepanov@samsung.com>
Fri, 15 May 2015 11:37:01 +0000 (14:37 +0300)
Change-Id: I0290573d504d59ee2a1a1ec50f781317e594b422
Signed-off-by: Vitaliy Cherepanov <v.cherepanov@samsung.com>
Makefile
helper/dacollection.c
include/binproto.h
include/dacollection.h
include/daprobe.h
include/khash.h
probe_event/api_names.txt
probe_event/da_event.h
probe_event/gesture.c [new file with mode: 0755]
probe_event/gesture.h
probe_event/gesture_tizen.h [new file with mode: 0644]

index c526d41..048a9d5 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -10,6 +10,7 @@ DEBUG_FLAGS=                                  \
 INCLUDE_CPPFLAGS =                             \
                -I./include                     \
                -I./probe_thread                \
+               -I./probe_event                         \
                -I/usr/include/appfw            \
                -I/usr/include/dbus-1.0         \
                -I/usr/include/e_dbus-1         \
@@ -94,6 +95,7 @@ PROBE_SRCS =                                  \
        ./probe_memory/libdamemalloc.c          \
        ./probe_memory/libdamemmanage.c         \
        ./probe_socket/libdasocket.c            \
+       ./probe_event/gesture.c                 \
        ./probe_event/da_event.c                \
        ./probe_event/keytouch.c                \
        ./probe_event/orientation.c             \
index 8be156a..a55adc9 100755 (executable)
 #include "dahelper.h"
 #include "daerror.h"
 #include "dacollection.h"
+#include "gesture.h"
+
+// khash table function definition
+
+KHASH_MAP_INIT_VOIDP(symbol, char*)
+
+KHASH_MAP_INIT_VOIDP(detector, void*)
+
+KHASH_MAP_INIT_VOIDP(uiobject, _uiobjectinfo*)
+
+KHASH_MAP_INIT_VOIDP(object, unsigned short)
+
+KHASH_MAP_INIT_VOIDP(allocmap, uint64_t)
+
+KHASH_INIT(gesture, void *, void *, 1, kh_gesture_calc_hash, kh_gesture_cmp)
 
 // hash table variable
 __hashInfo _hashinfo =
@@ -49,7 +64,9 @@ __hashInfo _hashinfo =
        NULL,                                           // khash_t(object)*     objHash
        PTHREAD_MUTEX_INITIALIZER,      // pthread_mutex_t objHashMutex
        NULL,                                           // khash_t(detector)*   dttHash
-       PTHREAD_MUTEX_INITIALIZER       // pthread_mutex_t dttHashMutex
+       PTHREAD_MUTEX_INITIALIZER,      // pthread_mutex_t dttHashMutex
+       NULL,                                           // khash_t(gesture)*    gestHash
+       PTHREAD_MUTEX_INITIALIZER       // pthread_mutex_t gestHashMutex
 };
 
 // glist typedef and variable
@@ -93,6 +110,9 @@ int initialize_hash_table()
        DETECTORHASH = kh_init(detector);
        DETECTORHASH_UNLOCK;
 
+       GESTUREHASH_LOCK;
+       GESTUREHASH = kh_init(gesture);
+       GESTUREHASH_UNLOCK;
        return 0;
 }
 
@@ -162,6 +182,24 @@ int finalize_hash_table()
                DETECTORHASH_UNLOCK;
        }
 
+       if (GESTUREHASH) {
+               khiter_t k;
+               void *val;
+
+               GESTUREHASH_LOCK;
+               for(k = kh_begin(GESTUREHASH); k != kh_end(GESTUREHASH); k++) {
+                       if (kh_exist(GESTUREHASH, k)) {
+                               val = kh_value(GESTUREHASH, k);
+                               if (likely(val != NULL))
+                                       free(val);
+                       }
+               }
+               kh_destroy(gesture, GESTUREHASH);
+               GESTUREHASH = NULL;
+               GESTUREHASH_UNLOCK;
+       }
+
+
        return 0;
 }
 
@@ -186,7 +224,7 @@ int find_symbol_hash(void* ptr, char** psymbol)
                return ERR_WRONGPARAMETER;
 
        SYMBOLHASH_LOCK;
-       k = kh_get(symbol, SYMBOLHASH, (uint32_t)ptr);
+       k = kh_get(symbol, SYMBOLHASH, ptr);
        if (k == kh_end(SYMBOLHASH))            // there is no entry for key
        {
                ret = 0;
@@ -219,7 +257,7 @@ int add_symbol_hash(void* ptr, const char* str, int strlen)
                return ERR_WRONGPARAMETER;
 
        SYMBOLHASH_LOCK;
-       k = kh_put(symbol, SYMBOLHASH, (uint32_t)ptr, &rethash);
+       k = kh_put(symbol, SYMBOLHASH, ptr, &rethash);
        if (likely(rethash != 0))       // succeed to add in hash table
        {
                char* tlast = (char*)real_malloc(strlen);
@@ -264,7 +302,7 @@ int add_memory_hash(void* ptr, size_t size, unsigned short type, unsigned short
                return ERR_WRONGPARAMETER;
 
        MEMORYHASH_LOCK;
-       k = kh_put(allocmap, MEMORYHASH, (uint32_t)ptr, &rethash);
+       k = kh_put(allocmap, MEMORYHASH, ptr, &rethash);
        if (likely(rethash != 0))       // succeed to add in hash table
        {
                kh_value(MEMORYHASH, k) = MAKE_MEMINFO(caller, type, size);
@@ -304,7 +342,7 @@ int del_memory_hash(void* ptr, unsigned short type, unsigned short* caller)
                return ERR_WRONGPARAMETER;
 
        MEMORYHASH_LOCK;
-       k = kh_get(allocmap, MEMORYHASH, (uint32_t)ptr);
+       k = kh_get(allocmap, MEMORYHASH, ptr);
        if (likely(k != kh_end(MEMORYHASH)))
        {                               // there is entry in hash table
                meminfo = kh_value(MEMORYHASH, k);
@@ -354,7 +392,7 @@ int find_uiobject_hash(void* ptr, char** type, char** classname)
                return ERR_WRONGPARAMETER;
 
        UIOBJECTHASH_LOCK;
-       k = kh_get(uiobject, UIOBJECTHASH, (uint32_t)ptr);
+       k = kh_get(uiobject, UIOBJECTHASH, ptr);
        if (unlikely(k == kh_end(UIOBJECTHASH)))                // there is no entry for key
        {
                ret = 0;
@@ -391,7 +429,7 @@ int add_uiobject_hash_class(void* ptr, const char* classname)
        str_len = strlen(classname) + 1;
 
        UIOBJECTHASH_LOCK;
-       k = kh_put(uiobject, UIOBJECTHASH, (uint32_t)ptr, &rethash);
+       k = kh_put(uiobject, UIOBJECTHASH, ptr, &rethash);
        if (likely(rethash == 0))       // entry is already in hash table
        {
                if (likely(kh_value(UIOBJECTHASH, k) != NULL))
@@ -445,7 +483,7 @@ int add_uiobject_hash_type(void* ptr, const char* type)
        str_len = strlen(type) + 1;
 
        UIOBJECTHASH_LOCK;
-       k = kh_put(uiobject, UIOBJECTHASH, (uint32_t)ptr, &rethash);
+       k = kh_put(uiobject, UIOBJECTHASH, ptr, &rethash);
        if (likely(rethash != 0))       // succeed to add in hash table
        {
                char* tlast;
@@ -498,7 +536,7 @@ int del_uiobject_hash(void* ptr)
                return ERR_WRONGPARAMETER;
 
        UIOBJECTHASH_LOCK;
-       k = kh_get(uiobject, UIOBJECTHASH, (uint32_t)ptr);
+       k = kh_get(uiobject, UIOBJECTHASH, ptr);
        if (likely(k != kh_end(UIOBJECTHASH)))          // there is entry in hash table
        {
                val = kh_value(UIOBJECTHASH, k);
@@ -537,7 +575,7 @@ int find_object_hash(void* ptr, unsigned short *caller)
                return ERR_WRONGPARAMETER;
 
        OBJECTHASH_LOCK;
-       k = kh_get(object, OBJECTHASH, (uint32_t)ptr);
+       k = kh_get(object, OBJECTHASH, ptr);
        if (unlikely(k == kh_end(OBJECTHASH)))          // there is no entry for key
        {
                ret = 0;
@@ -567,7 +605,7 @@ int add_object_hash(void* ptr, unsigned short caller)
                return ERR_WRONGPARAMETER;
 
        OBJECTHASH_LOCK;
-       k = kh_put(object, OBJECTHASH, (uint32_t)ptr, &rethash);
+       k = kh_put(object, OBJECTHASH, ptr, &rethash);
        if (likely(rethash != 0))       // entry is already in hash table
        {
                kh_value(OBJECTHASH, k) = caller;
@@ -601,7 +639,7 @@ int del_object_hash(void* ptr, unsigned short *caller)
                return ERR_WRONGPARAMETER;
 
        OBJECTHASH_LOCK;
-       k = kh_get(object, OBJECTHASH, (uint32_t)ptr);
+       k = kh_get(object, OBJECTHASH, ptr);
        if (likely(k != kh_end(OBJECTHASH)))            // there is entry in hash table
        {
                *caller = kh_value(OBJECTHASH, k);
@@ -637,7 +675,7 @@ int add_detector_hash(void* ptr, void* listener)
                return ERR_WRONGPARAMETER;
 
        DETECTORHASH_LOCK;
-       k = kh_put(detector, DETECTORHASH, (uint32_t)ptr, &rethash);
+       k = kh_put(detector, DETECTORHASH, ptr, &rethash);
        if (likely(rethash != 0))       // succeed to add in hash table
        {
                kh_value(DETECTORHASH, k) = listener;
@@ -667,7 +705,7 @@ int del_detector_hash(void* ptr)
                return ERR_WRONGPARAMETER;
 
        DETECTORHASH_LOCK;
-       k = kh_get(detector, DETECTORHASH, (uint32_t)ptr);
+       k = kh_get(detector, DETECTORHASH, ptr);
        if (likely(k != kh_end(DETECTORHASH)))          // there is entry in hash table
        {
                kh_del(detector, DETECTORHASH, k);
@@ -810,3 +848,110 @@ void* find_glist(char* key)
                return NULL;
 }
 
+
+/***********************************************************
+ * gesture hash related functions
+ ***********************************************************
+ * return 0 if succeed
+ * return 1 if key is already exist in hash table
+ * return negative value if other error occurred
+ */
+//uint32_t kh_gesture_calc_hash(struct __elm_gesture_layer_cb_set_data *elm)
+uint32_t kh_gesture_calc_hash(void *data)
+{
+       struct __elm_gesture_layer_cb_set_data *elm = data;
+
+       /* FIXME cast to uint64 */
+       uint32_t res = ((uint32_t)elm->obj << 16) +
+                      ((uint32_t)elm->idx << 8) +
+                      ((uint32_t)elm->cb_type << 0);
+       return res;
+}
+
+int kh_gesture_cmp(void *data1, void *data2)
+{
+       int res = 1;
+       struct __elm_gesture_layer_cb_set_data *elm1 = data1;
+       struct __elm_gesture_layer_cb_set_data *elm2 = data2;
+
+       if (elm1 == NULL || elm2 == NULL) {
+               PRINTERR("wrong incoming data");
+               goto exit;
+       }
+
+       res = (elm1->obj == elm2->obj &&
+              elm1->idx == elm2->idx &&
+              elm1->cb_type == elm2->cb_type);
+
+exit:
+       return res;
+}
+
+int gesture_update(struct __elm_gesture_layer_cb_set_data *elm1,
+                  struct __elm_gesture_layer_cb_set_data *elm2)
+{
+       int res = 0;
+       if (elm1 == NULL || elm2 == NULL) {
+               PRINTERR("wrong incoming data");
+               res = 1;
+               goto exit;
+       } else {
+               elm1->cb = elm2->cb;
+               elm1->data = elm2->data;
+       }
+
+exit:
+       return res;
+}
+
+void *add_gesture_hash(void *ptr)
+{
+       khiter_t k;
+       int rethash;
+       void *ret = NULL;
+       struct __elm_gesture_layer_cb_set_data *data;
+
+       if (GESTUREHASH == NULL) {
+               PRINTERR("gesture hash not initialized");
+               goto exit;
+       }
+
+       if (ptr == NULL) {
+               PRINTERR("wrong incoming data");
+               goto exit;
+       }
+
+       GESTUREHASH_LOCK;
+
+       data = (struct __elm_gesture_layer_cb_set_data *)ptr;
+       k = kh_put(gesture, GESTUREHASH, data, &rethash);
+       if (rethash != 0) {
+               // succeed to add in hash table
+               if (data != NULL) {
+                       data = (struct __elm_gesture_layer_cb_set_data *)real_malloc(sizeof(*data));
+                       memcpy(data, ptr, sizeof(*data));
+
+                       kh_key(GESTUREHASH, k) = data;
+                       kh_value(GESTUREHASH, k) = data;
+                       ret = data;
+               } else {
+                       PRINTERR("Cannot alloc memory.");
+                       goto exit_unlock;
+               }
+       } else {
+               // key is already exist in hash
+               // update memory info
+               data = kh_value(GESTUREHASH, k);
+               if (gesture_update(data, (struct __elm_gesture_layer_cb_set_data *)ptr) != 0) {
+                       PRINTERR("Cannot update hash data");
+                       goto exit_unlock;
+               }
+               ret = data;
+       }
+
+exit_unlock:
+       GESTUREHASH_UNLOCK;
+
+exit:
+       return ret;
+}
index 0b5ec1f..91813e9 100644 (file)
@@ -387,14 +387,26 @@ static char __attribute__((used)) *pack_ret(char *to, char ret_type, ...)
                }                                                       \
        } while(0)
 
-#define PACK_UIEVENT(event_type, detail_type, x, y, info1, info2)      \
-       do {    /* PACK_UIEVENT */                                      \
+#define PACK_UIEVENT_HEAD(event_type, detail_type)                     \
                BUF_PTR = pack_int32(BUF_PTR, event_type);              \
                BUF_PTR = pack_int32(BUF_PTR, detail_type);             \
+
+#define PACK_UIEVENT_XY(x, y)                                          \
                BUF_PTR = pack_int32(BUF_PTR, x);                       \
                BUF_PTR = pack_int32(BUF_PTR, y);                       \
+
+#define PACK_UIEVENT_INFO1(info1)                                      \
                BUF_PTR = pack_string(BUF_PTR, info1);                  \
+
+#define PACK_UIEVENT_INFO2(info2)                                      \
                BUF_PTR = pack_int32(BUF_PTR, info2);                   \
+
+#define PACK_UIEVENT(event_type, detail_type, x, y, info1, info2)      \
+       do {    /* PACK_UIEVENT */                                      \
+               PACK_UIEVENT_HEAD(event_type, detail_type);             \
+               PACK_UIEVENT_XY(x, y)                                   \
+               PACK_UIEVENT_INFO1(info1)                               \
+               PACK_UIEVENT_INFO2(info2)                               \
        } while (0)
 
 #define PACK_RESOURCE(size, fd_value, fd_api_type, file_size,  \
index e67da49..8aa63dc 100755 (executable)
@@ -35,6 +35,7 @@
 
 #include "khash.h"
 #include "real_functions.h"
+#include "gesture.h"
 
 #ifdef __cplusplus
 extern "C"{
@@ -60,6 +61,10 @@ extern "C"{
 #define DETECTORHASH_LOCK      pthread_mutex_lock(&(_hashinfo.dttHashMutex))
 #define DETECTORHASH_UNLOCK    pthread_mutex_unlock(&(_hashinfo.dttHashMutex))
 
+#define GESTUREHASH            _hashinfo.gestHash
+#define GESTUREHASH_LOCK       pthread_mutex_lock(&(_hashinfo.gestHashMutex))
+#define GESTUREHASH_UNLOCK     pthread_mutex_unlock(&(_hashinfo.gestHashMutex))
+
 #define MEMTYPE_ALLOC  0x01
 #define MEMTYPE_FREE   0x01
 #define MEMTYPE_NEW            0x03
@@ -88,16 +93,12 @@ typedef struct
        char* name;
 } _uiobjectinfo;
 
-// khash table function definition
-KHASH_MAP_INIT_INT(symbol, char*)
-
-KHASH_MAP_INIT_INT(allocmap, uint64_t)
-
-KHASH_MAP_INIT_INT(uiobject, _uiobjectinfo*)
-
-KHASH_MAP_INIT_INT(object, unsigned short)
-
-KHASH_MAP_INIT_INT(detector, void*)
+KHASH_INIT_TYPE_VOIDP(symbol, char*)
+KHASH_INIT_TYPE_VOIDP(detector, void*)
+KHASH_INIT_TYPE_VOIDP(uiobject, _uiobjectinfo*)
+KHASH_INIT_TYPE_VOIDP(object, unsigned short)
+KHASH_INIT_TYPE_VOIDP(allocmap, uint64_t)
+KHASH_INIT_TYPE_VOIDP(gesture, void *)
 
 typedef struct
 {
@@ -111,6 +112,8 @@ typedef struct
        pthread_mutex_t         objHashMutex;
        khash_t(detector)*      dttHash;
        pthread_mutex_t         dttHashMutex;
+       khash_t(gesture)*       gestHash;
+       pthread_mutex_t         gestHashMutex;
 } __hashInfo;
 
 extern __hashInfo _hashinfo;
@@ -139,6 +142,10 @@ int find_object_hash(void* ptr, unsigned short *caller);
 int add_object_hash(void* ptr, unsigned short caller);
 int del_object_hash(void* ptr, unsigned short *caller);
 
+int find_gesture_hash(void *data);
+void *add_gesture_hash(void *data);
+int del_gesture_hash(void *data);
+
 int add_detector_hash(void* ptr, void* listener);
 int del_detector_hash(void* ptr);
 
index 7ba1015..d5b882d 100644 (file)
@@ -207,14 +207,14 @@ typedef struct {
                                        lib_handle[SONAME] = dlopen(lib_string[SONAME], RTLD_LAZY);                     \
                                        if (lib_handle[SONAME] == NULL) {                               \
                                                fprintf(stderr, "dlopen failed : %s\n", lib_string[SONAME]);    \
-                                               PRINTMSG("dlopen failed : %s\n", lib_string[SONAME]);   \
+                                               PRINTERR("dlopen failed : %s\n", lib_string[SONAME]);   \
                                                exit(0);                                                                        \
                                        } \
                                }                                                                                                       \
                                FUNCTIONPOINTER = dlsym(lib_handle[SONAME], FUNCNAME);          \
                                if (FUNCTIONPOINTER == NULL || dlerror() != NULL) {             \
                                        fprintf(stderr, "dlsym failed : <" FUNCNAME ">\n");                     \
-                                       PRINTMSG("dlsym failed : <" FUNCNAME ">\n");                    \
+                                       PRINTERR("dlsym failed : <" FUNCNAME ">\n");                    \
                                        exit(0);                                                                                \
                                }                                                                                                       \
                        }                                                                                                               \
index a92ec5e..8be76f2 100755 (executable)
@@ -1,7 +1,5 @@
 /* The MIT License
-
-   Copyright (c) 2008, by Attractive Chaos <attractivechaos@aol.co.uk>
-
+   Copyright (c) 2008, 2009, 2011 by Attractive Chaos <attractor@live.co.uk>
    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
@@ -9,10 +7,8 @@
    distribute, sublicense, 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 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
@@ -25,7 +21,6 @@
 
 /*
   An example:
-
 #include "khash.h"
 KHASH_MAP_INIT_INT(32, char)
 int main() {
@@ -33,44 +28,57 @@ int main() {
     khiter_t k;
     khash_t(32) *h = kh_init(32);
     k = kh_put(32, h, 5, &ret);
-    if (!ret) kh_del(32, h, k);
     kh_value(h, k) = 10;
     k = kh_get(32, h, 10);
     is_missing = (k == kh_end(h));
     k = kh_get(32, h, 5);
     kh_del(32, h, k);
     for (k = kh_begin(h); k != kh_end(h); ++k)
-        if (kh_exist(h, k)) kh_value(h, k) = 1;
+       if (kh_exist(h, k)) kh_value(h, k) = 1;
     kh_destroy(32, h);
     return 0;
 }
 */
 
 /*
+  2013-05-02 (0.2.8):
+    * Use quadratic probing. When the capacity is power of 2, stepping function
+      i*(i+1)/2 guarantees to traverse each bucket. It is better than double
+      hashing on cache performance and is more robust than linear probing.
+      In theory, double hashing should be more robust than quadratic probing.
+      However, my implementation is probably not for large hash tables, because
+      the second hash function is closely tied to the first hash function,
+      which reduce the effectiveness of double hashing.
+    Reference: http://research.cs.vt.edu/AVresearch/hashing/quadratic.php
+  2011-12-29 (0.2.7):
+    * Minor code clean up; no actual effect.
+  2011-09-16 (0.2.6):
+    * The capacity is a power of 2. This seems to dramatically improve the
+      speed for simple keys. Thank Zilong Tan for the suggestion. Reference:
+       - http://code.google.com/p/ulib/
+       - http://nothings.org/computer/judy/
+    * Allow to optionally use linear probing which usually has better
+      performance for random input. Double hashing is still the default as it
+      is more robust to certain non-random input.
+    * Added Wang's integer hash function (not used by default). This hash
+      function is more robust to certain non-random input.
+  2011-02-14 (0.2.5):
+    * Allow to declare global functions.
+  2009-09-26 (0.2.4):
+    * Improve portability
   2008-09-19 (0.2.3):
-
     * Corrected the example
     * Improved interfaces
-
   2008-09-11 (0.2.2):
-
     * Improved speed a little in kh_put()
-
   2008-09-10 (0.2.1):
-
     * Added kh_clear()
     * Fixed a compiling error
-
   2008-09-02 (0.2.0):
-
     * Changed to token concatenation which increases flexibility.
-
   2008-08-31 (0.1.2):
-
     * Fixed a bug in kh_get(), which has not been tested previously.
-
   2008-08-31 (0.1.1):
-
     * Added destructor
 */
 
@@ -78,28 +86,42 @@ int main() {
 #ifndef __AC_KHASH_H
 #define __AC_KHASH_H
 
-#define AC_VERSION_KHASH_H "0.2.2"
+/*!
+  @header
+  Generic hash table library.
+ */
+
+#define AC_VERSION_KHASH_H "0.2.8"
 
-#include <stdio.h>
-#include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
-
-typedef uint32_t khint_t;
+#include <limits.h>
+
+/* compiler specific configuration */
+
+#if UINT_MAX == 0xffffffffu
+typedef unsigned int khint32_t;
+#elif ULONG_MAX == 0xffffffffu
+typedef unsigned long khint32_t;
+#endif
+
+#if ULONG_MAX == ULLONG_MAX
+typedef unsigned long khint64_t;
+#else
+typedef unsigned long long khint64_t;
+#endif
+
+#ifndef kh_inline
+#ifdef _MSC_VER
+#define kh_inline __inline
+#else
+#define kh_inline inline
+#endif
+#endif /* kh_inline */
+
+typedef khint32_t khint_t;
 typedef khint_t khiter_t;
 
-#define __ac_HASH_PRIME_SIZE 32
-static const uint32_t __ac_prime_list[__ac_HASH_PRIME_SIZE] =
-{
-  0ul,          3ul,          11ul,         23ul,         53ul,
-  97ul,         193ul,        389ul,        769ul,        1543ul,
-  3079ul,       6151ul,       12289ul,      24593ul,      49157ul,
-  98317ul,      196613ul,     393241ul,     786433ul,     1572869ul,
-  3145739ul,    6291469ul,    12582917ul,   25165843ul,   50331653ul,
-  100663319ul,  201326611ul,  402653189ul,  805306457ul,  1610612741ul,
-  3221225473ul, 4294967291ul
-};
-
 #define __ac_isempty(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&2)
 #define __ac_isdel(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&1)
 #define __ac_iseither(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&3)
@@ -108,220 +130,468 @@ static const uint32_t __ac_prime_list[__ac_HASH_PRIME_SIZE] =
 #define __ac_set_isboth_false(flag, i) (flag[i>>4]&=~(3ul<<((i&0xfU)<<1)))
 #define __ac_set_isdel_true(flag, i) (flag[i>>4]|=1ul<<((i&0xfU)<<1))
 
+#define __ac_fsize(m) ((m) < 16? 1 : (m)>>4)
+
+#ifndef kroundup32
+#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x))
+#endif
+
+#ifndef kcalloc
+#define kcalloc(N,Z) calloc(N,Z)
+#endif
+#ifndef kmalloc
+#define kmalloc(Z) malloc(Z)
+#endif
+#ifndef krealloc
+#define krealloc(P,Z) realloc(P,Z)
+#endif
+#ifndef kfree
+#define kfree(P) free(P)
+#endif
+
 static const double __ac_HASH_UPPER = 0.77;
 
-#define KHASH_INIT(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
-    typedef struct {                                                    \
-        khint_t n_buckets, size, n_occupied, upper_bound;               \
-        uint32_t *flags;                                                \
-        khkey_t *keys;                                                  \
-        khval_t *vals;                                                  \
-    } kh_##name##_t;                                                    \
-    static inline kh_##name##_t *kh_init_##name() {                     \
-        return (kh_##name##_t*)calloc(1, sizeof(kh_##name##_t));        \
-    }                                                                   \
-    static inline void kh_destroy_##name(kh_##name##_t *h)              \
-    {                                                                   \
-        if (h) {                                                        \
-            free(h->keys); free(h->flags);                              \
-            free(h->vals);                                              \
-            free(h);                                                    \
-        }                                                               \
-    }                                                                   \
-    static inline void kh_clear_##name(kh_##name##_t *h)                \
-    {                                                                   \
-        if (h && h->flags) { \
-            memset(h->flags, 0xaa, ((h->n_buckets>>4) + 1) * sizeof(uint32_t)); \
-            h->size = h->n_occupied = 0;                                \
-        }                                                               \
-    }                                                                   \
-    static inline khint_t kh_get_##name(kh_##name##_t *h, khkey_t key)  \
-    {                                                                   \
-        if (h->n_buckets) {                                             \
-            khint_t inc, k, i, last;                                    \
-            k = __hash_func(key); i = k % h->n_buckets;                 \
-            inc = 1 + k % (h->n_buckets - 1); last = i;                 \
-            while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \
-                if (i + inc >= h->n_buckets) i = i + inc - h->n_buckets; \
-                else i += inc;                                          \
-                if (i == last) return h->n_buckets;                     \
-            }                                                           \
-            return __ac_iseither(h->flags, i)? h->n_buckets : i;            \
-        } else return 0;                                                \
-    }                                                                   \
-    static inline void kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \
-    {                                                                   \
-        uint32_t *new_flags = 0;                                        \
-        khint_t j = 1;                                                  \
-        {                                                               \
-            khint_t t = __ac_HASH_PRIME_SIZE - 1;                       \
-            if (new_n_buckets < __ac_prime_list[__ac_HASH_PRIME_SIZE - 1]) { \
-                while (__ac_prime_list[t] > new_n_buckets) {            \
-                    --t;                                                \
-                }                                                       \
-                new_n_buckets = __ac_prime_list[t + 1];                 \
-            }                                                           \
-            if (h->size >= (khint_t)(new_n_buckets * __ac_HASH_UPPER + 0.5)) j = 0; \
-            else {                                                      \
-                new_flags = (uint32_t*)real_malloc(((new_n_buckets>>4) + 1) * sizeof(uint32_t)); \
-                memset(new_flags, 0xaa, ((new_n_buckets>>4) + 1) * sizeof(uint32_t)); \
-                if (h->n_buckets < new_n_buckets) {                     \
-                    h->keys = (khkey_t*)realloc(h->keys, new_n_buckets * sizeof(khkey_t)); \
-                    if (kh_is_map)                                      \
-                        h->vals = (khval_t*)realloc(h->vals, new_n_buckets * sizeof(khval_t)); \
-                }                                                       \
-            }                                                           \
-        }                                                               \
-        if (j) {                                                        \
-            for (j = 0; j != h->n_buckets; ++j) {                       \
-                if (__ac_iseither(h->flags, j) == 0) {                  \
-                    khkey_t key = h->keys[j];                           \
-                    khval_t val;                                        \
-                    if (kh_is_map) val = h->vals[j];                    \
-                    __ac_set_isdel_true(h->flags, j);                   \
-                    while (1) {                                         \
-                        khint_t inc, k, i;                              \
-                        k = __hash_func(key);                           \
-                        i = k % new_n_buckets;                          \
-                        inc = 1 + k % (new_n_buckets - 1);              \
-                        while (!__ac_isempty(new_flags, i)) {           \
-                            if (i + inc >= new_n_buckets) i = i + inc - new_n_buckets; \
-                            else i += inc;                              \
-                        }                                               \
-                        __ac_set_isempty_false(new_flags, i);           \
-                        if (i < h->n_buckets && __ac_iseither(h->flags, i) == 0) { \
-                            { khkey_t tmp = h->keys[i]; h->keys[i] = key; key = tmp; } \
-                            if (kh_is_map) { khval_t tmp = h->vals[i]; h->vals[i] = val; val = tmp; } \
-                            __ac_set_isdel_true(h->flags, i);           \
-                        } else {                                        \
-                            h->keys[i] = key;                           \
-                            if (kh_is_map) h->vals[i] = val;            \
-                            break;                                      \
-                        }                                               \
-                    }                                                   \
-                }                                                       \
-            }                                                           \
-            if (h->n_buckets > new_n_buckets) {                         \
-                h->keys = (khkey_t*)realloc(h->keys, new_n_buckets * sizeof(khkey_t)); \
-                if (kh_is_map)                                          \
-                    h->vals = (khval_t*)realloc(h->vals, new_n_buckets * sizeof(khval_t)); \
-            }                                                           \
-            free(h->flags);                                             \
-            h->flags = new_flags;                                       \
-            h->n_buckets = new_n_buckets;                               \
-            h->n_occupied = h->size;                                    \
-            h->upper_bound = (khint_t)(h->n_buckets * __ac_HASH_UPPER + 0.5); \
-        }                                                               \
-    }                                                                   \
-    static inline khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret) \
-    {                                                                   \
-        khint_t x;                                                      \
-        if (h->n_occupied >= h->upper_bound) {                          \
-            if (h->n_buckets > (h->size<<1)) kh_resize_##name(h, h->n_buckets - 1); \
-            else kh_resize_##name(h, h->n_buckets + 1);                 \
-        }                                                               \
-        {                                                               \
-            khint_t inc, k, i, site, last;                              \
-            x = site = h->n_buckets; k = __hash_func(key); i = k % h->n_buckets; \
-            if (__ac_isempty(h->flags, i)) x = i;                       \
-            else {                                                      \
-                inc = 1 + k % (h->n_buckets - 1); last = i;             \
-                while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \
-                    if (__ac_isdel(h->flags, i)) site = i;              \
-                    if (i + inc >= h->n_buckets) i = i + inc - h->n_buckets; \
-                    else i += inc;                                      \
-                    if (i == last) { x = site; break; }                 \
-                }                                                       \
-                if (x == h->n_buckets) {                                \
-                    if (__ac_isempty(h->flags, i) && site != h->n_buckets) x = site; \
-                    else x = i;                                         \
-                }                                                       \
-            }                                                           \
-        }                                                               \
-        if (__ac_isempty(h->flags, x)) {                                \
-            h->keys[x] = key;                                           \
-            __ac_set_isboth_false(h->flags, x);                         \
-            ++h->size; ++h->n_occupied;                                 \
-            *ret = 1;                                                   \
-        } else if (__ac_isdel(h->flags, x)) {                           \
-            h->keys[x] = key;                                           \
-            __ac_set_isboth_false(h->flags, x);                         \
-            ++h->size;                                                  \
-            *ret = 2;                                                   \
-        } else *ret = 0;                                                \
-        return x;                                                       \
-    }                                                                   \
-    static inline void kh_del_##name(kh_##name##_t *h, khint_t x)       \
-    {                                                                   \
-        if (x != h->n_buckets && !__ac_iseither(h->flags, x)) {         \
-            __ac_set_isdel_true(h->flags, x);                           \
-            --h->size;                                                  \
-        }                                                               \
+#define __KHASH_TYPE(name, khkey_t, khval_t) \
+    typedef struct kh_##name##_s { \
+       khint_t n_buckets, size, n_occupied, upper_bound; \
+       khint32_t *flags; \
+       khkey_t *keys; \
+       khval_t *vals; \
+    } kh_##name##_t;
+
+#define __KHASH_PROTOTYPES(name, khkey_t, khval_t)                                             \
+    extern kh_##name##_t *kh_init_##name(void);                                                        \
+    extern void kh_destroy_##name(kh_##name##_t *h);                                   \
+    extern void kh_clear_##name(kh_##name##_t *h);                                             \
+    extern khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key);         \
+    extern int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets); \
+    extern khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret); \
+    extern void kh_del_##name(kh_##name##_t *h, khint_t x);
+
+#define __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
+    SCOPE kh_##name##_t *kh_init_##name(void) {                                                        \
+       return (kh_##name##_t*)kcalloc(1, sizeof(kh_##name##_t));               \
+    }                                                                                                                                  \
+    SCOPE void kh_destroy_##name(kh_##name##_t *h)                                             \
+    {                                                                                                                                  \
+       if (h) {                                                                                                                \
+           kfree((void *)h->keys); kfree(h->flags);                                    \
+           kfree((void *)h->vals);                                                                             \
+           kfree(h);                                                                                                   \
+       }                                                                                                                               \
+    }                                                                                                                                  \
+    SCOPE void kh_clear_##name(kh_##name##_t *h)                                               \
+    {                                                                                                                                  \
+       if (h && h->flags) {                                                                                    \
+           memset(h->flags, 0xaa, __ac_fsize(h->n_buckets) * sizeof(khint32_t)); \
+           h->size = h->n_occupied = 0;                                                                \
+       }                                                                                                                               \
+    }                                                                                                                                  \
+    SCOPE khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key)   \
+    {                                                                                                                                  \
+       if (h->n_buckets) {                                                                                             \
+           khint_t k, i, last, mask, step = 0; \
+           mask = h->n_buckets - 1;                                                                    \
+           k = __hash_func(key); i = k & mask;                                                 \
+           last = i; \
+           while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \
+               i = (i + (++step)) & mask; \
+               if (i == last) return h->n_buckets;                                             \
+           }                                                                                                                   \
+           return __ac_iseither(h->flags, i)? h->n_buckets : i;                \
+       } else return 0;                                                                                                \
+    }                                                                                                                                  \
+    SCOPE int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \
+    { /* This function uses 0.25*n_buckets bytes of working space instead of [sizeof(key_t+val_t)+.25]*n_buckets. */ \
+       khint32_t *new_flags = 0;                                                                               \
+       khint_t j = 1;                                                                                                  \
+       {                                                                                                                               \
+           kroundup32(new_n_buckets);                                                                  \
+           if (new_n_buckets < 4) new_n_buckets = 4;                                   \
+           if (h->size >= (khint_t)(new_n_buckets * __ac_HASH_UPPER + 0.5)) j = 0;     /* requested size is too small */ \
+           else { /* hash table size to be changed (shrink or expand); rehash */ \
+               new_flags = (khint32_t*)kmalloc(__ac_fsize(new_n_buckets) * sizeof(khint32_t)); \
+               if (!new_flags) return -1;                                                              \
+               memset(new_flags, 0xaa, __ac_fsize(new_n_buckets) * sizeof(khint32_t)); \
+               if (h->n_buckets < new_n_buckets) {     /* expand */            \
+                   khkey_t *new_keys = (khkey_t*)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \
+                   if (!new_keys) { kfree(new_flags); return -1; }             \
+                   h->keys = new_keys;                                                                 \
+                   if (kh_is_map) {                                                                    \
+                       khval_t *new_vals = (khval_t*)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \
+                       if (!new_vals) { kfree(new_flags); return -1; } \
+                       h->vals = new_vals;                                                             \
+                   }                                                                                                   \
+               } /* otherwise shrink */                                                                \
+           }                                                                                                                   \
+       }                                                                                                                               \
+       if (j) { /* rehashing is needed */                                                              \
+           for (j = 0; j != h->n_buckets; ++j) {                                               \
+               if (__ac_iseither(h->flags, j) == 0) {                                  \
+                   khkey_t key = h->keys[j];                                                   \
+                   khval_t val;                                                                                \
+                   khint_t new_mask;                                                                   \
+                   new_mask = new_n_buckets - 1;                                               \
+                   if (kh_is_map) val = h->vals[j];                                    \
+                   __ac_set_isdel_true(h->flags, j);                                   \
+                   while (1) { /* kick-out process; sort of like in Cuckoo hashing */ \
+                       khint_t k, i, step = 0; \
+                       k = __hash_func(key);                                                   \
+                       i = k & new_mask;                                                               \
+                       while (!__ac_isempty(new_flags, i)) i = (i + (++step)) & new_mask; \
+                       __ac_set_isempty_false(new_flags, i);                   \
+                       if (i < h->n_buckets && __ac_iseither(h->flags, i) == 0) { /* kick out the existing element */ \
+                           { khkey_t tmp = h->keys[i]; h->keys[i] = key; key = tmp; } \
+                           if (kh_is_map) { khval_t tmp = h->vals[i]; h->vals[i] = val; val = tmp; } \
+                           __ac_set_isdel_true(h->flags, i); /* mark it as deleted in the old hash table */ \
+                       } else { /* write the element and jump out of the loop */ \
+                           h->keys[i] = key;                                                   \
+                           if (kh_is_map) h->vals[i] = val;                    \
+                           break;                                                                              \
+                       }                                                                                               \
+                   }                                                                                                   \
+               }                                                                                                               \
+           }                                                                                                                   \
+           if (h->n_buckets > new_n_buckets) { /* shrink the hash table */ \
+               h->keys = (khkey_t*)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \
+               if (kh_is_map) h->vals = (khval_t*)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \
+           }                                                                                                                   \
+           kfree(h->flags); /* free the working space */                               \
+           h->flags = new_flags;                                                                               \
+           h->n_buckets = new_n_buckets;                                                               \
+           h->n_occupied = h->size;                                                                    \
+           h->upper_bound = (khint_t)(h->n_buckets * __ac_HASH_UPPER + 0.5); \
+       }                                                                                                                               \
+       return 0;                                                                                                               \
+    }                                                                                                                                  \
+    SCOPE khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret) \
+    {                                                                                                                                  \
+       khint_t x;                                                                                                              \
+       if (h->n_occupied >= h->upper_bound) { /* update the hash table */ \
+           if (h->n_buckets > (h->size<<1)) {                                                  \
+               if (kh_resize_##name(h, h->n_buckets - 1) < 0) { /* clear "deleted" elements */ \
+                   *ret = -1; return h->n_buckets;                                             \
+               }                                                                                                               \
+           } else if (kh_resize_##name(h, h->n_buckets + 1) < 0) { /* expand the hash table */ \
+               *ret = -1; return h->n_buckets;                                                 \
+           }                                                                                                                   \
+       } /* TODO: to implement automatically shrinking; resize() already support shrinking */ \
+       {                                                                                                                               \
+           khint_t k, i, site, last, mask = h->n_buckets - 1, step = 0; \
+           x = site = h->n_buckets; k = __hash_func(key); i = k & mask; \
+           if (__ac_isempty(h->flags, i)) x = i; /* for speed up */    \
+           else {                                                                                                              \
+               last = i; \
+               while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \
+                   if (__ac_isdel(h->flags, i)) site = i;                              \
+                   i = (i + (++step)) & mask; \
+                   if (i == last) { x = site; break; }                                 \
+               }                                                                                                               \
+               if (x == h->n_buckets) {                                                                \
+                   if (__ac_isempty(h->flags, i) && site != h->n_buckets) x = site; \
+                   else x = i;                                                                                 \
+               }                                                                                                               \
+           }                                                                                                                   \
+       }                                                                                                                               \
+       if (__ac_isempty(h->flags, x)) { /* not present at all */               \
+           h->keys[x] = key;                                                                                   \
+           __ac_set_isboth_false(h->flags, x);                                                 \
+           ++h->size; ++h->n_occupied;                                                                 \
+           *ret = 1;                                                                                                   \
+       } else if (__ac_isdel(h->flags, x)) { /* deleted */                             \
+           h->keys[x] = key;                                                                                   \
+           __ac_set_isboth_false(h->flags, x);                                                 \
+           ++h->size;                                                                                                  \
+           *ret = 2;                                                                                                   \
+       } else *ret = 0; /* Don't touch h->keys[x] if present and not deleted */ \
+       return x;                                                                                                               \
+    }                                                                                                                                  \
+    SCOPE void kh_del_##name(kh_##name##_t *h, khint_t x)                              \
+    {                                                                                                                                  \
+       if (x != h->n_buckets && !__ac_iseither(h->flags, x)) {                 \
+           __ac_set_isdel_true(h->flags, x);                                                   \
+           --h->size;                                                                                                  \
+       }                                                                                                                               \
     }
 
+#define KHASH_DECLARE(name, khkey_t, khval_t)                                                  \
+    __KHASH_TYPE(name, khkey_t, khval_t)                                                               \
+    __KHASH_PROTOTYPES(name, khkey_t, khval_t)
+
+#define KHASH_INIT2(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
+    __KHASH_TYPE(name, khkey_t, khval_t)                                                               \
+    __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal)
+
+#define KHASH_INIT3(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
+    __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal)
+
+#define KHASH_INIT(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
+    KHASH_INIT3(name, static kh_inline, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal)
+
 /* --- BEGIN OF HASH FUNCTIONS --- */
 
-#define kh_int_hash_func(key) (uint32_t)(key)
-#define kh_int_hash_equal(a, b) (a == b)
-#define kh_int64_hash_func(key) (uint32_t)((key)>>33^(key)^(key)<<11)
-#define kh_int64_hash_equal(a, b) (a == b)
-static inline khint_t __ac_X31_hash_string(const char *s)
+/*! @function
+  @abstract     Integer hash function
+  @param  key   The integer [khint32_t]
+  @return       The hash value [khint_t]
+ */
+#define kh_int_hash_func(key) (khint32_t)(key)
+/*! @function
+  @abstract     Integer comparison function
+ */
+#define kh_int_hash_equal(a, b) ((a) == (b))
+/*! @function
+  @abstract     64-bit integer hash function
+  @param  key   The integer [khint64_t]
+  @return       The hash value [khint_t]
+ */
+#define kh_int64_hash_func(key) (khint32_t)((key)>>33^(key)^(key)<<11)
+/*! @function
+  @abstract     64-bit integer comparison function
+ */
+#define kh_int64_hash_equal(a, b) ((a) == (b))
+/*! @function
+  @abstract     const char* hash function
+  @param  s     Pointer to a null terminated string
+  @return       The hash value
+ */
+static kh_inline khint_t __ac_X31_hash_string(const char *s)
 {
-    khint_t h = *s;
-    if (h)
-       {
-               for (++s ; *s; ++s)
-               {
-                       h = (h << 5) - h + *s;
-               }
-       }
+    khint_t h = (khint_t)*s;
+    if (h) for (++s ; *s; ++s) h = (h << 5) - h + (khint_t)*s;
     return h;
 }
+/*! @function
+  @abstract     Another interface to const char* hash function
+  @param  key   Pointer to a null terminated string [const char*]
+  @return       The hash value [khint_t]
+ */
 #define kh_str_hash_func(key) __ac_X31_hash_string(key)
+/*! @function
+  @abstract     Const char* comparison function
+ */
 #define kh_str_hash_equal(a, b) (strcmp(a, b) == 0)
 
+static kh_inline khint_t __ac_Wang_hash(khint_t key)
+{
+    key += ~(key << 15);
+    key ^=  (key >> 10);
+    key +=  (key << 3);
+    key ^=  (key >> 6);
+    key += ~(key << 11);
+    key ^=  (key >> 16);
+    return key;
+}
+#define kh_int_hash_func2(k) __ac_Wang_hash((khint_t)key)
+
 /* --- END OF HASH FUNCTIONS --- */
 
-/* Other necessary macros... */
+/* Other convenient macros... */
 
+/*!
+  @abstract Type of the hash table.
+  @param  name  Name of the hash table [symbol]
+ */
 #define khash_t(name) kh_##name##_t
 
+/*! @function
+  @abstract     Initiate a hash table.
+  @param  name  Name of the hash table [symbol]
+  @return       Pointer to the hash table [khash_t(name)*]
+ */
 #define kh_init(name) kh_init_##name()
+
+/*! @function
+  @abstract     Destroy a hash table.
+  @param  name  Name of the hash table [symbol]
+  @param  h     Pointer to the hash table [khash_t(name)*]
+ */
 #define kh_destroy(name, h) kh_destroy_##name(h)
+
+/*! @function
+  @abstract     Reset a hash table without deallocating memory.
+  @param  name  Name of the hash table [symbol]
+  @param  h     Pointer to the hash table [khash_t(name)*]
+ */
 #define kh_clear(name, h) kh_clear_##name(h)
+
+/*! @function
+  @abstract     Resize a hash table.
+  @param  name  Name of the hash table [symbol]
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @param  s     New size [khint_t]
+ */
 #define kh_resize(name, h, s) kh_resize_##name(h, s)
+
+/*! @function
+  @abstract     Insert a key to the hash table.
+  @param  name  Name of the hash table [symbol]
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @param  k     Key [type of keys]
+  @param  r     Extra return code: -1 if the operation failed;
+                0 if the key is present in the hash table;
+                1 if the bucket is empty (never used); 2 if the element in
+               the bucket has been deleted [int*]
+  @return       Iterator to the inserted element [khint_t]
+ */
 #define kh_put(name, h, k, r) kh_put_##name(h, k, r)
+
+/*! @function
+  @abstract     Retrieve a key from the hash table.
+  @param  name  Name of the hash table [symbol]
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @param  k     Key [type of keys]
+  @return       Iterator to the found element, or kh_end(h) if the element is absent [khint_t]
+ */
 #define kh_get(name, h, k) kh_get_##name(h, k)
+
+/*! @function
+  @abstract     Remove a key from the hash table.
+  @param  name  Name of the hash table [symbol]
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @param  k     Iterator to the element to be deleted [khint_t]
+ */
 #define kh_del(name, h, k) kh_del_##name(h, k)
 
+/*! @function
+  @abstract     Test whether a bucket contains data.
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @param  x     Iterator to the bucket [khint_t]
+  @return       1 if containing data; 0 otherwise [int]
+ */
 #define kh_exist(h, x) (!__ac_iseither((h)->flags, (x)))
+
+/*! @function
+  @abstract     Get key given an iterator
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @param  x     Iterator to the bucket [khint_t]
+  @return       Key [type of keys]
+ */
 #define kh_key(h, x) ((h)->keys[x])
+
+/*! @function
+  @abstract     Get value given an iterator
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @param  x     Iterator to the bucket [khint_t]
+  @return       Value [type of values]
+  @discussion   For hash sets, calling this results in segfault.
+ */
 #define kh_val(h, x) ((h)->vals[x])
+
+/*! @function
+  @abstract     Alias of kh_val()
+ */
 #define kh_value(h, x) ((h)->vals[x])
+
+/*! @function
+  @abstract     Get the start iterator
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @return       The start iterator [khint_t]
+ */
 #define kh_begin(h) (khint_t)(0)
+
+/*! @function
+  @abstract     Get the end iterator
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @return       The end iterator [khint_t]
+ */
 #define kh_end(h) ((h)->n_buckets)
-#define kh_size(h) ((h)->size)
-#define kh_n_buckets(h) ((h)->n_buckets)
 
-/* More conenient interfaces */
+/*! @function
+  @abstract     Get the number of elements in the hash table
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @return       Number of elements in the hash table [khint_t]
+ */
+#define kh_size(h) ((h)->size)
 
-#define KHASH_SET_INIT_INT(name)                                        \
-    KHASH_INIT(name, uint32_t, char, 0, kh_int_hash_func, kh_int_hash_equal)
+/*! @function
+  @abstract     Get the number of buckets in the hash table
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @return       Number of buckets in the hash table [khint_t]
+ */
+#define kh_n_buckets(h) ((h)->n_buckets)
 
-#define KHASH_MAP_INIT_INT(name, khval_t)                               \
-    KHASH_INIT(name, uint32_t, khval_t, 1, kh_int_hash_func, kh_int_hash_equal)
+/*! @function
+  @abstract     Iterate over the entries in the hash table
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @param  kvar  Variable to which key will be assigned
+  @param  vvar  Variable to which value will be assigned
+  @param  code  Block of code to execute
+ */
+#define kh_foreach(h, kvar, vvar, code) { khint_t __i;         \
+    for (__i = kh_begin(h); __i != kh_end(h); ++__i) {         \
+       if (!kh_exist(h,__i)) continue;                                         \
+       (kvar) = kh_key(h,__i);                                                         \
+       (vvar) = kh_val(h,__i);                                                         \
+       code;                                                                                           \
+    } }
+
+/*! @function
+  @abstract     Iterate over the values in the hash table
+  @param  h     Pointer to the hash table [khash_t(name)*]
+  @param  vvar  Variable to which value will be assigned
+  @param  code  Block of code to execute
+ */
+#define kh_foreach_value(h, vvar, code) { khint_t __i;         \
+    for (__i = kh_begin(h); __i != kh_end(h); ++__i) {         \
+       if (!kh_exist(h,__i)) continue;                                         \
+       (vvar) = kh_val(h,__i);                                                         \
+       code;                                                                                           \
+    } }
 
-#define KHASH_SET_INIT_INT64(name)                                      \
-    KHASH_INIT(name, uint64_t, char, 0, kh_int64_hash_func, kh_int64_hash_equal)
+/* More conenient interfaces */
 
-#define KHASH_MAP_INIT_INT64(name, khval_t)                             \
-    KHASH_INIT(name, uint64_t, khval_t, 1, kh_int64_hash_func, kh_int64_hash_equal)
+/*! @function
+  @abstract     Instantiate a hash set containing integer keys
+  @param  name  Name of the hash table [symbol]
+ */
+#define KHASH_SET_INIT_INT(name)                                                                               \
+    KHASH_INIT(name, khint32_t, char, 0, kh_int_hash_func, kh_int_hash_equal)
+
+/*! @function
+  @abstract     Instantiate a hash map containing integer keys
+  @param  name  Name of the hash table [symbol]
+  @param  khval_t  Type of values [type]
+ */
+#define KHASH_MAP_INIT_INT(name, khval_t)                                                              \
+    KHASH_INIT(name, khint32_t, khval_t, 1, kh_int_hash_func, kh_int_hash_equal)
+
+/*! @function
+  @abstract     Instantiate a hash map containing 64-bit integer keys
+  @param  name  Name of the hash table [symbol]
+ */
+#define KHASH_SET_INIT_INT64(name)                                                                             \
+    KHASH_INIT(name, khint64_t, char, 0, kh_int64_hash_func, kh_int64_hash_equal)
+
+/*! @function
+  @abstract     Instantiate a hash map containing 64-bit integer keys
+  @param  name  Name of the hash table [symbol]
+  @param  khval_t  Type of values [type]
+ */
+#define KHASH_MAP_INIT_INT64(name, khval_t)                                                            \
+    KHASH_INIT(name, khint64_t, khval_t, 1, kh_int64_hash_func, kh_int64_hash_equal)
 
 typedef const char *kh_cstr_t;
-#define KHASH_SET_INIT_STR(name)                                        \
+/*! @function
+  @abstract     Instantiate a hash map containing const char* keys
+  @param  name  Name of the hash table [symbol]
+ */
+#define KHASH_SET_INIT_STR(name)                                                                               \
     KHASH_INIT(name, kh_cstr_t, char, 0, kh_str_hash_func, kh_str_hash_equal)
 
-#define KHASH_MAP_INIT_STR(name, khval_t)                               \
+/*! @function
+  @abstract     Instantiate a hash map containing const char* keys
+  @param  name  Name of the hash table [symbol]
+  @param  khval_t  Type of values [type]
+ */
+#define KHASH_MAP_INIT_STR(name, khval_t)                                                              \
     KHASH_INIT(name, kh_cstr_t, khval_t, 1, kh_str_hash_func, kh_str_hash_equal)
 
+#define KHASH_MAP_INIT_VOIDP(name, khval_t)                                                            \
+    KHASH_INIT(name, void *, khval_t, 1, kh_int_hash_func, kh_int_hash_equal)
+
+#define KHASH_INIT_TYPE_VOIDP(name, khval_t)                                                           \
+    __KHASH_TYPE(name, void *, khval_t)                                                                \
+
+
 #endif /* __AC_KHASH_H */
index 4b77d69..8985936 100644 (file)
@@ -24,6 +24,11 @@ void GestureEventListener::OnRotationGestureStarted (TouchRotationGestureDetecto
 void GestureEventListener::OnTapGestureCanceled (TouchTapGestureDetector &gestureDetector)
 void GestureEventListener::OnTapGestureDetected (TouchTapGestureDetector &gestureDetector)
 
+#filename "gesture.c"
+#lib "???"
+#feature ---
+__common_elm_gesture_layer_cb
+
 #filename "orientation.c"
 #lib "???"
 #feature ---
index af7e679..622d708 100755 (executable)
 
 enum __event_type
 {
+       _EVENT_UNKNOWN = -1,
+
        _EVENT_KEY = 1,
        _EVENT_TOUCH = 2,
-       _EVENT_GESTURE = 3,
-       _EVENT_ORIENTATION = 4,
-       _EVENT_LISTENER = 5
+       _EVENT_ORIENTATION = 3,
+       _EVENT_LISTENER = 4,
+
+       _EVENT_GESTURE_N_TAPS = 5,
+       _EVENT_GESTURE_N_DOUBLE_TAPS = 6,
+       _EVENT_GESTURE_N_TRIPLE_TAPS = 7,
+       _EVENT_GESTURE_N_LONG_TAPS = 8,
+       _EVENT_GESTURE_N_FLICKS = 9,
+       _EVENT_GESTURE_N_LINES = 10,
+       _EVENT_GESTURE_ZOOM = 11,
+       _EVENT_GESTURE_ROTATE = 12,
+       _EVENT_GESTURE_MOMENTUM = 13,
+
 } EVENT_TYPE;
 
 enum __key_status
diff --git a/probe_event/gesture.c b/probe_event/gesture.c
new file mode 100755 (executable)
index 0000000..ae1c6a7
--- /dev/null
@@ -0,0 +1,240 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Vitaliy Cherepanov <v.cherepanov@samsung.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#include "daprobe.h"
+#include "dahelper.h"
+#include "probeinfo.h"
+#include "tizen_probe.h"
+#include "dacollection.h"
+#include "da_event.h"
+#include "binproto.h"
+
+#include "common_probe_init.h"
+
+#include "gesture.h"
+#include "da_event.h"
+
+#define LOGW PRINTWRN
+
+#define MAX_INFO1_LEN 64
+
+/* START - pack for gestures */
+
+/*
+   ELM_GESTURE_N_TAPS,
+   ELM_GESTURE_N_LONG_TAPS,
+   ELM_GESTURE_N_DOUBLE_TAPS,
+   ELM_GESTURE_N_TRIPLE_TAPS,
+*/
+static inline char *__n_finger_tap_pack(char *to, void *event_info)
+{
+       Elm_Gesture_Taps_Info *ev = (Elm_Gesture_Taps_Info *) event_info;
+       char *p = to;
+
+       PACK_UIEVENT_XY(ev->x, ev->y);
+       PACK_UIEVENT_INFO1(NULL);
+       PACK_UIEVENT_INFO2(ev->n);
+
+       return p;
+       to++;
+}
+
+/*
+   ELM_GESTURE_MOMENTUM,
+*/
+static inline char *__momentum_pack(char *to, void *event_info)
+{
+       Elm_Gesture_Momentum_Info *ev = (Elm_Gesture_Momentum_Info *) event_info;
+       char *p = to;
+
+       PACK_UIEVENT_XY(ev->x1, ev->y1);
+       PACK_UIEVENT_INFO1(NULL);
+       PACK_UIEVENT_INFO2(ev->n);
+
+       return p;
+}
+
+/*
+   ELM_GESTURE_N_LINES,
+   ELM_GESTURE_N_FLICKS,
+*/
+static inline char *__line_flick_pack(char *to, void *event_info)
+{
+       Elm_Gesture_Line_Info *ev = (Elm_Gesture_Line_Info *) event_info;
+       char *p = to;
+
+       PACK_UIEVENT_XY(ev->momentum.x1, ev->momentum.y1);
+       p += snprintf(p, MAX_INFO1_LEN, "%d, %d, %d, %d",
+                     ev->momentum.x2, ev->momentum.y2,
+                     ev->momentum.mx, ev->momentum.my) + 1;
+       PACK_UIEVENT_INFO2((int)ev->angle);
+
+       return p;
+}
+
+/*
+    ELM_GESTURE_ZOOM
+*/
+static inline char *__zoom_pack(char *to, void *event_info)
+{
+       Elm_Gesture_Zoom_Info *ev = (Elm_Gesture_Zoom_Info *) event_info;
+       char *p = to;
+
+       PACK_UIEVENT_XY(ev->x, ev->y);
+       p += snprintf(p, MAX_INFO1_LEN, "%f, %f", ev->zoom, ev->momentum) + 1;
+       PACK_UIEVENT_INFO2(ev->radius);
+
+       return p;
+}
+
+/*
+    ELM_GESTURE_ROTATE
+*/
+static inline char *__rotate_pack(char *to, void *event_info)
+{
+       Elm_Gesture_Rotate_Info *ev = (Elm_Gesture_Rotate_Info *) event_info;
+       char *p = to;
+
+       PACK_UIEVENT_XY(ev->x, ev->y);
+       p += snprintf(p, MAX_INFO1_LEN, "%f, %f, %f", ev->base_angle, ev->angle,
+                     ev->momentum) + 1;
+       PACK_UIEVENT_INFO2(ev->radius);
+
+       return p;
+}
+/* END   - pack for gestures */
+
+char *__pack_callback_data(char *to,
+                          struct __elm_gesture_layer_cb_set_data *data,
+                          void *event_info)
+{
+       char *res = NULL;
+
+       if (to == NULL) {
+               PRINTERR("destination pointer is NULL");
+               return NULL;
+       }
+
+       switch (data->idx) {
+       case ELM_GESTURE_N_TAPS: /**< N fingers single taps */
+       case ELM_GESTURE_N_LONG_TAPS: /**< N fingers single long-taps */
+       case ELM_GESTURE_N_DOUBLE_TAPS: /**< N fingers double-single taps */
+       case ELM_GESTURE_N_TRIPLE_TAPS: /**< N fingers triple-single taps */
+               res = __n_finger_tap_pack(to, event_info);
+               break;
+
+       case ELM_GESTURE_MOMENTUM: /**< Reports momentum in the direction of movement */
+               res = __momentum_pack(to, event_info);
+               break;
+
+       case ELM_GESTURE_N_LINES: /**< N fingers line gesture */
+       case ELM_GESTURE_N_FLICKS: /**< N fingers flick gesture */
+               res = __line_flick_pack(to, event_info);
+               break;
+
+       case ELM_GESTURE_ZOOM: /**< Zoom */
+               res = __zoom_pack(to, event_info);
+               break;
+
+       case ELM_GESTURE_ROTATE: /**< Rotate */
+               res = __rotate_pack(to, event_info);
+               break;
+       default:
+               PRINTERR("wrong event: obj=%p idx=%d cb_type=%d cb=%p data=%p",
+                        data->obj, data->idx, data->cb_type, data->cb, data->data);
+       }
+
+       return res;
+}
+
+static inline enum __event_type __get_event_type_code(Elm_Gesture_Type idx)
+{
+       /* I am so sorry */
+       switch (idx) {
+       case ELM_GESTURE_N_TAPS: return _EVENT_GESTURE_N_TAPS;
+       case ELM_GESTURE_N_LONG_TAPS: return _EVENT_GESTURE_N_LONG_TAPS;
+       case ELM_GESTURE_N_DOUBLE_TAPS: return _EVENT_GESTURE_N_DOUBLE_TAPS;
+       case ELM_GESTURE_N_TRIPLE_TAPS: return _EVENT_GESTURE_N_TRIPLE_TAPS;
+       case ELM_GESTURE_MOMENTUM: return _EVENT_GESTURE_MOMENTUM;
+       case ELM_GESTURE_N_LINES: return _EVENT_GESTURE_N_LINES;
+       case ELM_GESTURE_N_FLICKS: return _EVENT_GESTURE_N_FLICKS;
+       case ELM_GESTURE_ZOOM: return _EVENT_GESTURE_ZOOM;
+       case ELM_GESTURE_ROTATE: return _EVENT_GESTURE_ROTATE;
+       default:
+               PRINTERR("wrong event type");
+       }
+
+       return _EVENT_UNKNOWN;
+}
+
+/* Callbacks */
+Evas_Event_Flags __common_elm_gesture_layer_cb(void *data , void *event_info)
+{
+       probeInfo_t     probeInfo;
+       struct __elm_gesture_layer_cb_set_data *d = data;
+       Evas_Event_Flags res;
+
+       res = d->cb(d->data, event_info);
+
+       setProbePoint(&probeInfo);
+       PREPARE_LOCAL_BUF();
+       PACK_COMMON_BEGIN(MSG_PROBE_UIEVENT, API_ID___common_elm_gesture_layer_cb, "p", CALLER_ADDRESS);
+       PACK_COMMON_END('d', res, 0, 0);
+       PACK_UIEVENT_HEAD(__get_event_type_code(d->idx), d->cb_type);
+
+       BUF_PTR = __pack_callback_data(BUF_PTR, data, event_info);
+
+       FLUSH_LOCAL_BUF();
+
+       return res;
+}
+
+void elm_gesture_layer_cb_set(Evas_Object *obj, Elm_Gesture_Type idx,
+                             Elm_Gesture_State cb_type, Elm_Gesture_Event_Cb cb,
+                             void *data)
+{
+       struct __elm_gesture_layer_cb_set_data d, *elm;
+       static void (*elm_gesture_layer_cb_setp)(Evas_Object *obj, Elm_Gesture_Type idx,
+                     Elm_Gesture_State cb_type, Elm_Gesture_Event_Cb cb,
+                     void *data);
+
+       d.obj = obj;
+       d.idx = idx;
+       d.cb_type = cb_type;
+       d.cb = cb;
+       d.data = data;
+
+       elm = add_gesture_hash(&d);
+
+       GET_REAL_FUNC_RTLD_NEXT(elm_gesture_layer_cb_set);
+
+       elm_gesture_layer_cb_setp(obj, idx, cb_type, __common_elm_gesture_layer_cb, elm);
+       return;
+}
+
index 612b766..e1d6208 100644 (file)
 #ifndef __GESTURE_H__
 #define __GESTURE_H__
 
-#include <FUi.h>
-
-using namespace Tizen::Ui;
-
-class GestureEventListener :
-               public ITouchCustomGestureEventListener,
-               public ITouchFlickGestureEventListener,
-               public ITouchLongPressGestureEventListener,
-               public ITouchPanningGestureEventListener,
-               public ITouchPinchGestureEventListener,
-               public ITouchRotationGestureEventListener,
-               public ITouchTapGestureEventListener
-{
-public:
-       GestureEventListener();
-       virtual ~GestureEventListener();
-
-       virtual void    OnCustomGestureStarted (TouchGestureDetector &gestureDetector);
-       virtual void    OnCustomGestureChanged (TouchGestureDetector &gestureDetector);
-       virtual void    OnCustomGestureFinished (TouchGestureDetector &gestureDetector);
-       virtual void    OnCustomGestureCanceled (TouchGestureDetector &gestureDetector);
-
-       virtual void    OnFlickGestureDetected (TouchFlickGestureDetector &gestureDetector);
-       virtual void    OnFlickGestureCanceled (TouchFlickGestureDetector &gestureDetector);
-
-       virtual void    OnLongPressGestureDetected (TouchLongPressGestureDetector &gestureDetector);
-       virtual void    OnLongPressGestureCanceled (TouchLongPressGestureDetector &gestureDetector);
-
-       virtual void    OnPanningGestureStarted (TouchPanningGestureDetector &gestureDetector);
-       virtual void    OnPanningGestureChanged (TouchPanningGestureDetector &gestureDetector);
-       virtual void    OnPanningGestureFinished (TouchPanningGestureDetector &gestureDetector);
-       virtual void    OnPanningGestureCanceled (TouchPanningGestureDetector &gestureDetector);
-
-       virtual void    OnPinchGestureStarted (TouchPinchGestureDetector &gestureDetector);
-       virtual void    OnPinchGestureChanged (TouchPinchGestureDetector &gestureDetector);
-       virtual void    OnPinchGestureFinished (TouchPinchGestureDetector &gestureDetector);
-       virtual void    OnPinchGestureCanceled (TouchPinchGestureDetector &gestureDetector);
-
-       virtual void    OnRotationGestureStarted (TouchRotationGestureDetector &gestureDetector);
-       virtual void    OnRotationGestureChanged (TouchRotationGestureDetector &gestureDetector);
-       virtual void    OnRotationGestureFinished (TouchRotationGestureDetector &gestureDetector);
-       virtual void    OnRotationGestureCanceled (TouchRotationGestureDetector &gestureDetector);
+#include <Evas.h>
+#include <elm_gesture_layer.h>
+
+struct __elm_gesture_layer_cb_set_data{
+       Evas_Object *obj;
+       Elm_Gesture_Type idx;
+       Elm_Gesture_State cb_type;
+       Elm_Gesture_Event_Cb cb;
+       void *data;
+};
 
-       virtual void    OnTapGestureDetected (TouchTapGestureDetector &gestureDetector);
-       virtual void    OnTapGestureCanceled (TouchTapGestureDetector &gestureDetector);
+//int kh_gesture_cmp(struct __elm_gesture_layer_cb_set_data *elm1,
+//                struct __elm_gesture_layer_cb_set_data *elm2);
+//uint32_t kh_gesture_calc_hash(struct __elm_gesture_layer_cb_set_data *elm);
 
-       static GestureEventListener& GetInstance(void);
+int kh_gesture_cmp(void *elm1, void *elm2);
+uint32_t kh_gesture_calc_hash(void *elm);
 
-private:
-       static GestureEventListener rInstance;
-};
 
 #endif
diff --git a/probe_event/gesture_tizen.h b/probe_event/gesture_tizen.h
new file mode 100644 (file)
index 0000000..9e08594
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ *  DA probe
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ * Juyoung Kim <j0.kim@samsung.com>
+ * Anastasia Lyupa <a.lyupa@samsung.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#ifndef __GESTURE_TIZEN_H__
+#define __GESTURE_TIZEN_H__
+
+#include <FUi.h>
+
+using namespace Tizen::Ui;
+
+class GestureEventListener :
+               public ITouchCustomGestureEventListener,
+               public ITouchFlickGestureEventListener,
+               public ITouchLongPressGestureEventListener,
+               public ITouchPanningGestureEventListener,
+               public ITouchPinchGestureEventListener,
+               public ITouchRotationGestureEventListener,
+               public ITouchTapGestureEventListener
+{
+public:
+       GestureEventListener();
+       virtual ~GestureEventListener();
+
+       virtual void    OnCustomGestureStarted (TouchGestureDetector &gestureDetector);
+       virtual void    OnCustomGestureChanged (TouchGestureDetector &gestureDetector);
+       virtual void    OnCustomGestureFinished (TouchGestureDetector &gestureDetector);
+       virtual void    OnCustomGestureCanceled (TouchGestureDetector &gestureDetector);
+
+       virtual void    OnFlickGestureDetected (TouchFlickGestureDetector &gestureDetector);
+       virtual void    OnFlickGestureCanceled (TouchFlickGestureDetector &gestureDetector);
+
+       virtual void    OnLongPressGestureDetected (TouchLongPressGestureDetector &gestureDetector);
+       virtual void    OnLongPressGestureCanceled (TouchLongPressGestureDetector &gestureDetector);
+
+       virtual void    OnPanningGestureStarted (TouchPanningGestureDetector &gestureDetector);
+       virtual void    OnPanningGestureChanged (TouchPanningGestureDetector &gestureDetector);
+       virtual void    OnPanningGestureFinished (TouchPanningGestureDetector &gestureDetector);
+       virtual void    OnPanningGestureCanceled (TouchPanningGestureDetector &gestureDetector);
+
+       virtual void    OnPinchGestureStarted (TouchPinchGestureDetector &gestureDetector);
+       virtual void    OnPinchGestureChanged (TouchPinchGestureDetector &gestureDetector);
+       virtual void    OnPinchGestureFinished (TouchPinchGestureDetector &gestureDetector);
+       virtual void    OnPinchGestureCanceled (TouchPinchGestureDetector &gestureDetector);
+
+       virtual void    OnRotationGestureStarted (TouchRotationGestureDetector &gestureDetector);
+       virtual void    OnRotationGestureChanged (TouchRotationGestureDetector &gestureDetector);
+       virtual void    OnRotationGestureFinished (TouchRotationGestureDetector &gestureDetector);
+       virtual void    OnRotationGestureCanceled (TouchRotationGestureDetector &gestureDetector);
+
+       virtual void    OnTapGestureDetected (TouchTapGestureDetector &gestureDetector);
+       virtual void    OnTapGestureCanceled (TouchTapGestureDetector &gestureDetector);
+
+       static GestureEventListener& GetInstance(void);
+
+private:
+       static GestureEventListener rInstance;
+};
+
+#endif