move around - flatter.
[profile/ivi/evas.git] / src / lib / canvas / evas_callbacks.c
1 #include "evas_common.h"
2 #include "evas_private.h"
3
4 static void evas_object_event_callback_list_post_free(Evas_Object_List **list);
5 static void evas_object_event_callback_clear(Evas_Object *obj);
6
7 static void
8 evas_object_event_callback_list_post_free(Evas_Object_List **list)
9 {
10    Evas_Object_List *l;
11
12    /* MEM OK */
13    for (l = *list; l;)
14      {
15         Evas_Func_Node *fn;
16
17         fn = (Evas_Func_Node *)l;
18         l = l->next;
19         if (fn->delete_me)
20           {
21              *list = evas_object_list_remove(*list, fn);
22              free(fn);
23           }
24      }
25 }
26
27 static void
28 evas_object_event_callback_clear(Evas_Object *obj)
29 {
30    if (!obj->callbacks) return;
31    if (!obj->callbacks->deletions_waiting) return;
32    obj->callbacks->deletions_waiting = 0;
33    evas_object_event_callback_list_post_free(&obj->callbacks->callbacks);
34    if (!obj->callbacks->callbacks)
35      {
36         free(obj->callbacks);
37         obj->callbacks = NULL;
38      }
39 }
40
41 void
42 evas_object_event_callback_all_del(Evas_Object *obj)
43 {
44    Evas_Object_List *l;
45
46    if (!obj->callbacks) return;
47    for (l = obj->callbacks->callbacks; l; l = l->next)
48      {
49         Evas_Func_Node *fn;
50
51         fn = (Evas_Func_Node *)l;
52         fn->delete_me = 1;
53      }
54 }
55
56 void
57 evas_object_event_callback_cleanup(Evas_Object *obj)
58 {
59    /* MEM OK */
60    if (!obj->callbacks) return;
61    evas_object_event_callback_list_post_free(&obj->callbacks->callbacks);
62    free(obj->callbacks);
63    obj->callbacks = NULL;
64 }
65
66 void
67 evas_object_event_callback_call(Evas_Object *obj, Evas_Callback_Type type, void *event_info)
68 {
69    /* MEM OK */
70    Evas_Object_List **l_mod = NULL, *l;
71    Evas_Button_Flags flags = EVAS_BUTTON_NONE;
72    Evas *e;
73
74    if (obj->delete_me) return;
75    e = evas_object_evas_get(obj);
76      
77    _evas_walk(e);
78    if (obj->callbacks)
79      {
80         l_mod = &obj->callbacks->callbacks;
81         switch (type)
82           {
83              case EVAS_CALLBACK_MOUSE_DOWN:
84                {
85                   Evas_Event_Mouse_Down *ev = event_info;
86                   
87                   flags = ev->flags;
88                   if (ev->flags & (EVAS_BUTTON_DOUBLE_CLICK | EVAS_BUTTON_TRIPLE_CLICK))
89                     {
90                        if (obj->last_mouse_down_counter < (e->last_mouse_down_counter - 1))
91                          ev->flags &= ~(EVAS_BUTTON_DOUBLE_CLICK | EVAS_BUTTON_TRIPLE_CLICK);
92                     }
93                   obj->last_mouse_down_counter = e->last_mouse_down_counter;
94                   break;
95                }
96              case EVAS_CALLBACK_MOUSE_UP:
97                {
98                   Evas_Event_Mouse_Up *ev = event_info;
99                   
100                   flags = ev->flags;
101                   if (ev->flags & (EVAS_BUTTON_DOUBLE_CLICK | EVAS_BUTTON_TRIPLE_CLICK))
102                     {
103                        if (obj->last_mouse_up_counter < (e->last_mouse_up_counter - 1))
104                          ev->flags &= ~(EVAS_BUTTON_DOUBLE_CLICK | EVAS_BUTTON_TRIPLE_CLICK);
105                     }
106                   obj->last_mouse_up_counter = e->last_mouse_up_counter;
107                   break;
108                }
109              default:
110                break;
111           }
112         obj->callbacks->walking_list++;
113         for (l = *l_mod; l; l = l->next)
114           {
115              Evas_Func_Node *fn;
116
117              fn = (Evas_Func_Node *)l;
118              if ((fn->type == type) && (!fn->delete_me))
119                {
120                   if (fn->func)
121                     fn->func(fn->data, obj->layer->evas, obj, event_info);
122                }
123              if (obj->delete_me) break;
124           }
125         obj->callbacks->walking_list--;
126         if (!obj->callbacks->walking_list)
127           {
128              evas_object_event_callback_clear(obj);
129              l_mod = NULL;
130           }
131         
132         if (type == EVAS_CALLBACK_MOUSE_DOWN)
133           {
134              Evas_Event_Mouse_Down *ev = event_info;
135              ev->flags = flags;
136           }
137         else if (type == EVAS_CALLBACK_MOUSE_UP)
138           {
139              Evas_Event_Mouse_Up *ev = event_info;
140              ev->flags = flags;
141           }
142      }
143    
144    if (!((obj->no_propagate) && (l_mod) && (*l_mod)))
145      {
146         if ((obj->smart.parent) && (type != EVAS_CALLBACK_FREE) &&
147             (type <= EVAS_CALLBACK_KEY_UP))
148           evas_object_event_callback_call(obj->smart.parent, type, event_info);
149      }
150    _evas_unwalk(e);
151 }
152
153 /**
154  * @defgroup Evas_Object_Callback_Group Object Callback Functions
155  *
156  * Functions that add and remove callbacks to evas objects.
157  */
158
159 /**
160  * @todo Move this next code example and most of the documentation for
161  * this next function into the group documentation.
162  */
163
164 /**
165  * Add a callback function to an object
166  * @param obj Object to attach a callback to
167  * @param type The type of event that will trigger the callback
168  * @param func The function to be called when the event is triggered
169  * @param data The data pointer to be passed to @p func
170  *
171  * This function adds a function callback to an object when the event of type
172  * @p type occurs on object @p obj. The function is @p func.
173  *
174  * In the event of a memory allocation error during addition of the callback to
175  * the object, evas_alloc_error() should be used to determine the nature of
176  * the error, if any, and the program should sensibly try and recover.
177  *
178  * The function will be passed the pointer @p data when it is called. A
179  * callback function must look like this:
180  *
181  * @code
182  * void callback (void *data, Evas *e, Evas_Object *obj, void *event_info);
183  * @endcode
184  *
185  * The first parameter @p data in this function will be the same value passed
186  * to evas_object_event_callback_add() as the @p data parameter. The second
187  * parameter is a convenience for the programmer to know what evas canvas the
188  * event occured on. The third parameter @p obj is the Object handle on which
189  * the event occured. The foruth parameter @p event_info is a pointer to a
190  * data structure that may or may not be passed to the callback, depending on
191  * the event type that triggered the callback.
192  *
193  * The event type @p type to trigger the function may be one of
194  * EVAS_CALLBACK_MOUSE_IN, EVAS_CALLBACK_MOUSE_OUT, EVAS_CALLBACK_MOUSE_DOWN,
195  * EVAS_CALLBACK_MOUSE_UP, EVAS_CALLBACK_MOUSE_MOVE, EVAS_CALLBACK_MOUSE_WHEEL,
196  * EVAS_CALLBACK_FREE, EVAS_CALLBACK_KEY_DOWN, EVAS_CALLBACK_KEY_UP,
197  * EVAS_CALLBACK_FOCUS_IN, EVAS_CALLBACK_FOCUS_OUT, EVAS_CALLBACK_SHOW,
198  * EVAS_CALLBACK_HIDE, EVAS_CALLBACK_MOVE, EVAS_CALLBACK_RESIZE or EVAS_CALLBACK_RESTACK.
199  * This determines the kind of event that will trigger the callback to be called.
200  * The @p event_info pointer passed to the callback will be one of the
201  * following, depending on the event triggering it:
202  *
203  * EVAS_CALLBACK_MOUSE_IN: event_info = pointer to Evas_Event_Mouse_In
204  *
205  * This event is triggered when the mouse pointer enters the region of
206  * the object @p obj. This may occur by the mouse pointer being moved by
207  * evas_event_feed_mouse_move() or evas_event_feed_mouse_move_data() calls,
208  * or by the object being shown, raised, moved, resized, or other objects
209  * being moved out of the way, hidden, lowered or moved out of the way.
210  *
211  * EVAS_CALLBACK_MOUSE_OUT: event_info = pointer to Evas_Event_Mouse_Out
212  *
213  * This event is triggered exactly like EVAS_CALLBACK_MOUSE_IN is, but occurs
214  * when the mouse pointer exits an object. Note that no out events will be
215  * reported if the mouse pointer is implicitly grabbed to an object (the
216  * mouse buttons are down at all and any were pressed on that object). An
217  * out event will be reported as soon as the mouse is no longer grabbed (no
218  * mouse buttons are depressed). Out events will be reported once all buttons
219  * are released, if the mouse has left the object.
220  *
221  * EVAS_CALLBACK_MOUSE_DOWN: event_info = pointer to Evas_Event_Mouse_Down
222  *
223  * This event is triggered by a mouse button being depressed while over an
224  * object. If pointermode is EVAS_OBJECT_POINTER_MODE_AUTOGRAB (default)
225  * this causes this object to passively grab the mouse until all mouse
226  * buttons have been released.
227  * That means if this mouse button is the first to be pressed, all future
228  * mouse events will be reported to only this object until no buttons are
229  * down. That includes mouse move events, in and out events, and further
230  * button presses. When all buttons are released, event propagation occurs
231  * as normal.
232  *
233  * EVAS_CALLBACK_MOUSE_UP: event_info = pointer to Evas_Event_Mouse_Up
234  *
235  * This event is triggered by a mouse button being released while over an
236  * object or when passively grabbed to an object. If this is the last mouse
237  * button to be raised on an object then the passive grab is released and
238  * event processing will continue as normal.
239  *
240  * EVAS_CALLBACK_MOUSE_MOVE: event_info = pointer to Evas_Event_Mouse_Move
241  *
242  * This event is triggered by the mouse pointer moving while over an object or
243  * passively grabbed to an object.
244  *
245  * EVAS_CALLBACK_MOUSE_WHEEL: event_info = pointer to Evas_Event_Mouse_Wheel
246  *
247  * This event is triggered by the mouse wheel being rolled while over an object
248  * or passively grabbed to an object.
249  *
250  * EVAS_CALLBACK_FREE: event_info = NULL
251  *
252  * This event is triggered just before Evas is about to free all memory used
253  * by an object and remove all references to it. This is useful for programs
254  * to use if they attached data to an object and want to free it when the
255  * object is deleted. The object is still valid when this callback is called,
256  * but after this callback returns, there is no guarantee on the object's
257  * validity.
258  *
259  * EVAS_CALLBACK_KEY_DOWN: event_info = pointer to Evas_Event_Key_Down
260  *
261  * This callback is called when a key is pressed and the focus is on the
262  * object, or a key has been grabbed to a particular object which wants to
263  * intercept the key press regardless of what object has the focus.
264  *
265  * EVAS_CALLBACK_KEY_UP: event_info = pointer to Evas_Event_Key_Up
266  *
267  * This callback is called when a key is released and the focus is on the
268  * object, or a key has been grabbed to a particular object which wants to
269  * intercept the key release regardless of what object has the focus.
270  *
271  * EVAS_CALLBACK_FOCUS_IN: event_info = NULL
272  *
273  * This event is called when an object gains the focus. When the callback is
274  * called the object has already gained the focus.
275  *
276  * EVAS_CALLBACK_FOCUS_OUT: event_info = NULL
277  *
278  * This event is triggered by an object losing the focus. When the callback is
279  * called the object has already lost the focus.
280  *
281  * EVAS_CALLBACK_SHOW: event_info = NULL
282  *
283  * This event is triggered by the object being shown by evas_object_show().
284  *
285  * EVAS_CALLBACK_HIDE: event_info = NULL
286  *
287  * This event is triggered by an object being hidden by evas_object_hide().
288  *
289  * EVAS_CALLBACK_MOVE: event_info = NULL
290  *
291  * This event is triggered by an object being moved. evas_object_move() can
292  * trigger this, as can any object-specific manipulations that would mean the
293  * object's origin could move.
294  *
295  * EVAS_CALLBACK_RESIZE: event_info = NULL
296  *
297  * This event is triggered by an object being resized. Resizes can be
298  * triggered by evas_object_resize() or by any object-specific calls that may
299  * cause the object to resize.
300  *
301  * Example:
302  * @code
303  * extern Evas_Object *object;
304  * extern void *my_data;
305  * void down_callback(void *data, Evas *e, Evas_Object *obj, void *event_info);
306  * void up_callback(void *data, Evas *e, Evas_Object *obj, void *event_info);
307  *
308  * evas_object_event_callback_add(object, EVAS_CALLBACK_MOUSE_UP, up_callback, my_data);
309  * if (evas_alloc_error() != EVAS_ALLOC_ERROR_NONE)
310  *   {
311  *     fprintf(stderr, "ERROR: Callback registering failed! Abort!\n");
312  *     exit(-1);
313  *   }
314  * evas_object_event_callback_add(object, EVAS_CALLBACK_MOUSE_DOWN, down_callback, my_data);
315  * if (evas_alloc_error() != EVAS_ALLOC_ERROR_NONE)
316  *   {
317  *     fprintf(stderr, "ERROR: Callback registering failed! Abort!\n");
318  *     exit(-1);
319  *   }
320  * @endcode
321  * @ingroup Evas_Object_Callback_Group
322  */
323 EAPI void
324 evas_object_event_callback_add(Evas_Object *obj, Evas_Callback_Type type, void (*func) (void *data, Evas *e, Evas_Object *obj, void *event_info), const void *data)
325 {
326    /* MEM OK */
327    Evas_Func_Node *fn;
328
329    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
330    return;
331    MAGIC_CHECK_END();
332
333    if (!func) return;
334
335    fn = evas_mem_calloc(sizeof(Evas_Func_Node));
336    if (!fn) return;
337    fn->func = func;
338    fn->data = (void *)data;
339    fn->type = type;
340
341    if (!obj->callbacks)
342      obj->callbacks = evas_mem_calloc(sizeof(Evas_Callbacks));
343    if (!obj->callbacks)
344      {
345         free(fn);
346         return;
347      }
348    obj->callbacks->callbacks = 
349      evas_object_list_append(obj->callbacks->callbacks, fn);
350 }
351
352 /**
353  * Delete a callback function from an object
354  * @param obj Object to remove a callback from
355  * @param type The type of event that was triggering the callback
356  * @param func The function that was to be called when the event was triggered
357  * @return The data pointer that was to be passed to the callback
358  *
359  * This function removes the most recently added callback from the object
360  * @p obj which was triggered by the event type @p type and was calling the
361  * function @p func when triggered. If the removal is successful it will also
362  * return the data pointer that was passed to evas_object_event_callback_add()
363  * when the callback was added to the object. If not successful NULL will be
364  * returned.
365  *
366  * Example:
367  * @code
368  * extern Evas_Object *object;
369  * void *my_data;
370  * void up_callback(void *data, Evas *e, Evas_Object *obj, void *event_info);
371  *
372  * my_data = evas_object_event_callback_del(object, EVAS_CALLBACK_MOUSE_UP, up_callback);
373  * @endcode
374  * @ingroup Evas_Object_Callback_Group
375  */
376 EAPI void *
377 evas_object_event_callback_del(Evas_Object *obj, Evas_Callback_Type type, void (*func) (void *data, Evas *e, Evas_Object *obj, void *event_info))
378 {
379    /* MEM OK */
380    Evas_Object_List *l;
381
382    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
383    return NULL;
384    MAGIC_CHECK_END();
385
386    if (!func) return NULL;
387
388    if (!obj->callbacks) return NULL;
389
390    for (l = obj->callbacks->callbacks; l; l = l->next)
391      {
392         Evas_Func_Node *fn;
393
394         fn = (Evas_Func_Node *)l;
395         if ((fn->func == func) && (fn->type == type) && (!fn->delete_me))
396           {
397              void *data;
398
399              data = fn->data;
400              fn->delete_me = 1;
401              obj->callbacks->deletions_waiting = 1;
402              if (!obj->callbacks->walking_list)
403                evas_object_event_callback_clear(obj);
404              return data;
405           }
406      }
407    return NULL;
408 }
409
410 /**
411  * Delete a callback function from an object
412  * @param obj Object to remove a callback from
413  * @param type The type of event that was triggering the callback
414  * @param func The function that was to be called when the event was triggered
415  * @param data The data pointer that was to be passed to the callback
416  * @return The data pointer that was to be passed to the callback
417  *
418  * This function removes the most recently added callback from the object
419  * @p obj which was triggered by the event type @p type and was calling the
420  * function @p func with data @p data when triggered. If the removal is
421  * successful it will also return the data pointer that was passed to
422  * evas_object_event_callback_add() (that will be the same as the parameter)
423  * when the callback was added to the object. If not successful NULL will be
424  * returned.
425  *
426  * Example:
427  * @code
428  * extern Evas_Object *object;
429  * void *my_data;
430  * void up_callback(void *data, Evas *e, Evas_Object *obj, void *event_info);
431  *
432  * my_data = evas_object_event_callback_del_full(object, EVAS_CALLBACK_MOUSE_UP, up_callback, data);
433  * @endcode
434  * @ingroup Evas_Object_Callback_Group
435  */
436 EAPI void *
437 evas_object_event_callback_del_full(Evas_Object *obj, Evas_Callback_Type type, void (*func) (void *data, Evas *e, Evas_Object *obj, void *event_info), const void *data)
438 {
439    /* MEM OK */
440    Evas_Object_List *l;
441
442    MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
443    return NULL;
444    MAGIC_CHECK_END();
445
446    if (!func) return NULL;
447
448    if (!obj->callbacks) return NULL;
449
450    for (l = obj->callbacks->callbacks; l; l = l->next)
451      {
452         Evas_Func_Node *fn;
453
454         fn = (Evas_Func_Node *)l;
455         if ((fn->func == func) && (fn->type == type) && (fn->data == data) && (!fn->delete_me))
456           {
457              void *data;
458
459              data = fn->data;
460              fn->delete_me = 1;
461              obj->callbacks->deletions_waiting = 1;
462              if (!obj->callbacks->walking_list)
463                evas_object_event_callback_clear(obj);
464              return data;
465           }
466      }
467    return NULL;
468 }