aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/evas/canvas/evas_object_intercept.c
blob: 75254765c0cdad9eff3d512d95b681885ce7bb62 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include "evas_common_private.h"
#include "evas_private.h"

/* local calls */

static void evas_object_intercept_init(Evas_Object *eo_obj);
static void evas_object_intercept_deinit(Evas_Object *eo_obj);

static void
evas_object_intercept_init(Evas_Object *eo_obj)
{
   Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
   if (!obj->interceptors)
     obj->interceptors = evas_mem_calloc(sizeof(Evas_Intercept_Func));
}

static void
evas_object_intercept_deinit(Evas_Object *eo_obj)
{
   Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
   if (!obj->interceptors) return;
   if ((obj->interceptors->show.func) ||
       (obj->interceptors->hide.func) ||
       (obj->interceptors->move.func) ||
       (obj->interceptors->resize.func) ||
       (obj->interceptors->raise.func) ||
       (obj->interceptors->lower.func) ||
       (obj->interceptors->stack_above.func) ||
       (obj->interceptors->stack_below.func) ||
       (obj->interceptors->layer_set.func) ||
       (obj->interceptors->color_set.func) ||
       (obj->interceptors->clip_set.func) ||
       (obj->interceptors->clip_unset.func))
     return;
   free(obj->interceptors);
   obj->interceptors = NULL;
}

/* private calls */

void
evas_object_intercept_cleanup(Evas_Object *eo_obj)
{
   Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
   if (obj->interceptors) free(obj->interceptors);
}

#define COMMON_ARGS Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
#define UNPACK_ARG1(a) , a
#define UNPACK_ARG2(a, b) , a, b
#define UNPACK_ARG4(a, b, c, d) , a, b, c, d

#define EVAS_OBJECT_INTERCEPT_CALL(Type, Args, ...) \
  int evas_object_intercept_call_##Type Args \
  { \
     if (!obj->interceptors) return 0; \
     if (obj->interceptors->Type.intercepted) return 0; \
     if (!obj->interceptors->Type.func) return 0; \
     obj->interceptors->Type.intercepted = EINA_TRUE; \
     obj->interceptors->Type.func(obj->interceptors->Type.data, eo_obj __VA_ARGS__); \
     if (obj->interceptors) obj->interceptors->Type.intercepted = EINA_FALSE; \
     return 1; \
  }

EVAS_OBJECT_INTERCEPT_CALL(show,        (COMMON_ARGS))
EVAS_OBJECT_INTERCEPT_CALL(hide,        (COMMON_ARGS))
EVAS_OBJECT_INTERCEPT_CALL(raise,       (COMMON_ARGS))
EVAS_OBJECT_INTERCEPT_CALL(lower,       (COMMON_ARGS))
EVAS_OBJECT_INTERCEPT_CALL(clip_unset,  (COMMON_ARGS))
EVAS_OBJECT_INTERCEPT_CALL(move,        (COMMON_ARGS, Evas_Coord a, Evas_Coord b), UNPACK_ARG2(a, b))
EVAS_OBJECT_INTERCEPT_CALL(resize,      (COMMON_ARGS, Evas_Coord a, Evas_Coord b), UNPACK_ARG2(a, b))
EVAS_OBJECT_INTERCEPT_CALL(stack_above, (COMMON_ARGS, Evas_Object *rel_to), UNPACK_ARG1(rel_to))
EVAS_OBJECT_INTERCEPT_CALL(stack_below, (COMMON_ARGS, Evas_Object *rel_to), UNPACK_ARG1(rel_to))
EVAS_OBJECT_INTERCEPT_CALL(layer_set,   (COMMON_ARGS, int l), UNPACK_ARG1(l))
EVAS_OBJECT_INTERCEPT_CALL(focus_set,   (COMMON_ARGS, Eina_Bool focus), UNPACK_ARG1(focus))
EVAS_OBJECT_INTERCEPT_CALL(color_set,   (COMMON_ARGS, int r, int g, int b, int a), UNPACK_ARG4(r, g, b, a))
EVAS_OBJECT_INTERCEPT_CALL(clip_set,    (COMMON_ARGS, Evas_Object *clip), UNPACK_ARG1(clip))

/* public calls */

#define EVAS_OBJECT_INTERCEPT_CALLBACK_DEFINE(Up_Type, Lower_Type)      \
  EAPI void                                                             \
  evas_object_intercept_##Lower_Type##_callback_add(Evas_Object *eo_obj,\
                                                    Evas_Object_Intercept_##Up_Type##_Cb func, const void *data) \
  {                                                                     \
     MAGIC_CHECK(eo_obj, Evas_Object, MAGIC_OBJ);                       \
     return;                                                            \
     MAGIC_CHECK_END();                                                 \
     Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS); \
     if (!func) return;                                                 \
     evas_object_intercept_init(eo_obj);                                \
     if (!obj->interceptors) return;                                    \
     obj->interceptors->Lower_Type.func = func;                         \
     obj->interceptors->Lower_Type.data = (void *)data;                 \
  }                                                                     \
                                                                        \
  EAPI void *                                                           \
  evas_object_intercept_##Lower_Type##_callback_del(Evas_Object *eo_obj,\
                                                    Evas_Object_Intercept_##Up_Type##_Cb func) \
  {                                                                     \
     void *data;                                                        \
                                                                        \
     MAGIC_CHECK(eo_obj, Evas_Object, MAGIC_OBJ);                       \
     return NULL;                                                       \
     MAGIC_CHECK_END();                                                 \
     Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS); \
     if (!func) return NULL;                                            \
     if (!obj->interceptors) return NULL;                               \
     obj->interceptors->Lower_Type.func = NULL;                         \
     data = obj->interceptors->Lower_Type.data;                         \
     obj->interceptors->Lower_Type.data = NULL;                         \
     evas_object_intercept_deinit(eo_obj);                              \
     return data;                                                       \
  }

EVAS_OBJECT_INTERCEPT_CALLBACK_DEFINE(Show, show);
EVAS_OBJECT_INTERCEPT_CALLBACK_DEFINE(Hide, hide);
EVAS_OBJECT_INTERCEPT_CALLBACK_DEFINE(Move, move);
EVAS_OBJECT_INTERCEPT_CALLBACK_DEFINE(Resize, resize);
EVAS_OBJECT_INTERCEPT_CALLBACK_DEFINE(Raise, raise);
EVAS_OBJECT_INTERCEPT_CALLBACK_DEFINE(Lower, lower);
EVAS_OBJECT_INTERCEPT_CALLBACK_DEFINE(Stack_Above, stack_above);
EVAS_OBJECT_INTERCEPT_CALLBACK_DEFINE(Stack_Below, stack_below);
EVAS_OBJECT_INTERCEPT_CALLBACK_DEFINE(Layer_Set, layer_set);
EVAS_OBJECT_INTERCEPT_CALLBACK_DEFINE(Focus_Set, focus_set);
EVAS_OBJECT_INTERCEPT_CALLBACK_DEFINE(Color_Set, color_set);
EVAS_OBJECT_INTERCEPT_CALLBACK_DEFINE(Clip_Set, clip_set);
EVAS_OBJECT_INTERCEPT_CALLBACK_DEFINE(Clip_Unset, clip_unset);