#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 =
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
DETECTORHASH = kh_init(detector);
DETECTORHASH_UNLOCK;
+ GESTUREHASH_LOCK;
+ GESTUREHASH = kh_init(gesture);
+ GESTUREHASH_UNLOCK;
return 0;
}
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;
}
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;
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);
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);
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);
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;
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))
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;
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);
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;
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;
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);
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;
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);
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;
+}
/* 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
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
/*
An example:
-
#include "khash.h"
KHASH_MAP_INIT_INT(32, char)
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
*/
#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)
#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 */
--- /dev/null
+/*
+ * 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;
+}
+