EVAS_OBJECT_POINTER_MODE_NOGRAB
} Evas_Object_Pointer_Mode; /**< How mouse pointer should be handled by Evas. */
-typedef void (*Evas_Smart_Cb) (void *data, Evas_Object *obj, void *event_info);
-typedef void (*Evas_Event_Cb) (void *data, Evas *e, void *event_info);
-typedef void (*Evas_Object_Event_Cb) (void *data, Evas *e, Evas_Object *obj, void *event_info);
+typedef void (*Evas_Smart_Cb) (void *data, Evas_Object *obj, void *event_info);
+typedef void (*Evas_Event_Cb) (void *data, Evas *e, void *event_info);
+typedef Eina_Bool (*Evas_Object_Event_Post_Cb) (void *data, Evas *e);
+typedef void (*Evas_Object_Event_Cb) (void *data, Evas *e, Evas_Object *obj, void *event_info);
#ifdef __cplusplus
extern "C" {
* @ingroup Evas_Canvas
*/
- EAPI void evas_event_callback_add (Evas *e, Evas_Callback_Type type, Evas_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 3);
- EAPI void *evas_event_callback_del (Evas *e, Evas_Callback_Type type, Evas_Event_Cb func) EINA_ARG_NONNULL(1, 3);
- EAPI void *evas_event_callback_del_full (Evas *e, Evas_Callback_Type type, Evas_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 3);
-
+ EAPI void evas_event_callback_add (Evas *e, Evas_Callback_Type type, Evas_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 3);
+ EAPI void *evas_event_callback_del (Evas *e, Evas_Callback_Type type, Evas_Event_Cb func) EINA_ARG_NONNULL(1, 3);
+ EAPI void *evas_event_callback_del_full (Evas *e, Evas_Callback_Type type, Evas_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 3);
+ EAPI void evas_post_event_callback_push (Evas *e, Evas_Object_Event_Post_Cb func, const void *data);
+ EAPI void evas_post_event_callback_remove (Evas *e, Evas_Object_Event_Post_Cb func);
+ EAPI void evas_post_event_callback_remove_full (Evas *e, Evas_Object_Event_Post_Cb func, const void *data);
+
/**
* @defgroup Evas_Image_Group Image Functions
*
int _evas_event_counter = 0;
void
+_evas_post_event_callback_call(Evas *e)
+{
+ Evas_Post_Callback *pc;
+ int skip = 0;
+
+ if (e->delete_me) return;
+ _evas_walk(e);
+ EINA_LIST_FREE(e->post_events, pc)
+ {
+ if ((!skip) && (!e->delete_me) && (!pc->delete_me))
+ {
+ if (!pc->func(e, pc->data)) skip = 1;
+ }
+ free(pc);
+ }
+ _evas_unwalk(e);
+}
+
+void
+_evas_post_event_callback_free(Evas *e)
+{
+ Evas_Post_Callback *pc;
+
+ EINA_LIST_FREE(e->post_events, pc)
+ {
+ free(pc);
+ }
+ _evas_unwalk(e);
+}
+
+void
evas_event_callback_list_post_free(Eina_Inlist **list)
{
Eina_Inlist *l;
}
/**
+ * Push a callback on the post-event callback stack
+ *
+ * @param e Canvas to push the callback on
+ * @param func The function that to be called when the stack is unwound
+ * @param data The data pointer to be passed to the callback
+ *
+ * Evas has a stack of callbacks that get called after all the callbacks for
+ * an event have triggered (all the objects it triggers on and al the callbacks
+ * in each object triggered). When all these have been called, the stack is
+ * unwond from most recently to least recently pushed item and removed from the
+ * stack calling the callback set for it.
+ *
+ * This is intended for doing reverse logic-like processing, example - when a
+ * child object that happens to get the event later is meant to be able to
+ * "steal" functions from a parent and thus on unwind of this stack hav its
+ * function called first, thus being able to set flags, or return 0 from the
+ * post-callback that stops all other post-callbacks in the current stack from
+ * being called (thus basically allowing a child to take control, if the event
+ * callback prepares information ready for taking action, but the post callback
+ * actually does the action).
+ *
+ */
+EAPI void
+evas_post_event_callback_push(Evas *e, Evas_Object_Event_Post_Cb func, const void *data)
+{
+ Evas_Post_Callback *pc;
+
+ MAGIC_CHECK(e, Evas, MAGIC_EVAS);
+ return;
+ MAGIC_CHECK_END();
+
+ pc = evas_mem_calloc(sizeof(Evas_Post_Callback));
+ if (!pc) return;
+ if (e->delete_me) return;
+
+ pc->func = func;
+ pc->data = data;
+ e->post_events = eina_list_prepend(e->post_events, pc);
+}
+
+/**
+ * Remove a callback from the post-event callback stack
+ *
+ * @param e Canvas to push the callback on
+ * @param func The function that to be called when the stack is unwound
+ *
+ * This removes a callback from the stack added with
+ * evas_post_event_callback_push(). The first instance of the function in
+ * the callback stack is removed from being executed when the stack is
+ * unwound. Further instances may still be run on unwind.
+ */
+EAPI void
+evas_post_event_callback_remove(Evas *e, Evas_Object_Event_Post_Cb func)
+{
+ Evas_Post_Callback *pc;
+ Eina_List *l;
+
+ MAGIC_CHECK(e, Evas, MAGIC_EVAS);
+ return;
+ MAGIC_CHECK_END();
+
+ EINA_LIST_FOREACH(e->post_events, l, pc)
+ {
+ if (pc->func == func)
+ {
+ pc->delete_me = 1;
+ return;
+ }
+ }
+}
+
+/**
+ * Remove a callback from the post-event callback stack
+ *
+ * @param e Canvas to push the callback on
+ * @param func The function that to be called when the stack is unwound
+ * @param data The data pointer to be passed to the callback
+ *
+ * This removes a callback from the stack added with
+ * evas_post_event_callback_push(). The first instance of the function and data
+ * in the callback stack is removed from being executed when the stack is
+ * unwound. Further instances may still be run on unwind.
+ */
+EAPI void
+evas_post_event_callback_remove_full(Evas *e, Evas_Object_Event_Post_Cb func, const void *data)
+{
+ Evas_Post_Callback *pc;
+ Eina_List *l;
+
+ MAGIC_CHECK(e, Evas, MAGIC_EVAS);
+ return;
+ MAGIC_CHECK_END();
+
+ EINA_LIST_FOREACH(e->post_events, l, pc)
+ {
+ if ((pc->func == func) && (pc->data == data))
+ {
+ pc->delete_me = 1;
+ return;
+ }
+ }
+}
+/**
* @}
*/
}
if (copy) eina_list_free(copy);
e->last_mouse_down_counter++;
+ _evas_post_event_callback_call(e);
_evas_unwalk(e);
}
}
if (copy) copy = eina_list_free(copy);
e->last_mouse_up_counter++;
+ _evas_post_event_callback_call(e);
}
if (!e->pointer.button)
}
if (e->delete_me) break;
}
+ _evas_post_event_callback_call(e);
}
if (copy) copy = eina_list_free(copy);
if (e->pointer.inside)
}
if (e->delete_me) break;
}
+ _evas_post_event_callback_call(e);
}
else
{
if (e->delete_me) break;
}
if (copy) copy = eina_list_free(copy);
+ _evas_post_event_callback_call(e);
_evas_unwalk(e);
}
outs = eina_list_append(outs, obj);
if (e->delete_me) break;
}
+ _evas_post_event_callback_call(e);
}
{
Evas_Event_Mouse_Out ev;
evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_OUT, &ev);
}
}
+ _evas_post_event_callback_call(e);
}
}
else
}
if (e->delete_me) break;
}
+ _evas_post_event_callback_call(e);
_evas_object_event_new();
eina_list_free(e->pointer.object.in);
/* and set up the new one */
e->pointer.object.in = ins;
+ _evas_post_event_callback_call(e);
}
_evas_unwalk(e);
}
e->pointer.object.in = eina_list_free(e->pointer.object.in);
/* and set up the new one */
e->pointer.object.in = ins;
+ _evas_post_event_callback_call(e);
evas_event_feed_mouse_move(e, e->pointer.x, e->pointer.y, timestamp, data);
_evas_unwalk(e);
}
if (copy) copy = eina_list_free(copy);
/* free our old list of ins */
e->pointer.object.in = eina_list_free(e->pointer.object.in);
+ _evas_post_event_callback_call(e);
}
_evas_unwalk(e);
}
if (e->delete_me) break;
}
if (copy) eina_list_free(copy);
+ _evas_post_event_callback_call(e);
_evas_unwalk(e);
}
if (e->delete_me) break;
}
if (copy) copy = eina_list_free(copy);
-
+ _evas_post_event_callback_call(e);
_evas_unwalk(e);
}
}
if (e->delete_me) break;
}
+ _evas_post_event_callback_call(e);
}
else
{
eina_list_free(e->pointer.object.in);
/* and set up the new one */
e->pointer.object.in = ins;
+ _evas_post_event_callback_call(e);
}
_evas_unwalk(e);
}
if ((e->focused) && (!exclusive))
{
if (e->events_frozen <= 0)
- evas_object_event_callback_call(e->focused, EVAS_CALLBACK_KEY_DOWN, &ev);
+ evas_object_event_callback_call(e->focused, EVAS_CALLBACK_KEY_DOWN, &ev);
}
+ _evas_post_event_callback_call(e);
}
_evas_unwalk(e);
}
if ((e->focused) && (!exclusive))
{
if (e->events_frozen <= 0)
- evas_object_event_callback_call(e->focused, EVAS_CALLBACK_KEY_UP, &ev);
+ evas_object_event_callback_call(e->focused, EVAS_CALLBACK_KEY_UP, &ev);
}
+ _evas_post_event_callback_call(e);
}
_evas_unwalk(e);
}
if (e->delete_me) break;
}
if (copy) copy = eina_list_free(copy);
+ _evas_post_event_callback_call(e);
_evas_unwalk(e);
-
_evas_object_event_new();
}
if (focus)
{
- if (obj->focused) return;
+ if (obj->focused) goto end;
if (obj->layer->evas->focused)
evas_object_focus_set(obj->layer->evas->focused, 0);
obj->focused = 1;
}
else
{
- if (!obj->focused) return;
+ if (!obj->focused) goto end;
obj->focused = 0;
obj->layer->evas->focused = NULL;
evas_object_event_callback_call(obj, EVAS_CALLBACK_FOCUS_OUT, NULL);
}
+ end:
+ _evas_post_event_callback_call(obj->layer->evas);
}
/**
e->callbacks = NULL;
}
+ _evas_post_event_callback_free(e);
+
del = 1;
e->walking_list++;
e->cleanup = 1;
_evas_object_event_new();
evas_object_event_callback_call(obj, EVAS_CALLBACK_SHOW, NULL);
+ _evas_post_event_callback_call(obj->layer->evas);
}
void
_evas_object_event_new();
evas_object_event_callback_call(obj, EVAS_CALLBACK_HIDE, NULL);
+ _evas_post_event_callback_call(obj->layer->evas);
}
void
_evas_object_event_new();
evas_object_event_callback_call(obj, EVAS_CALLBACK_MOVE, NULL);
+ _evas_post_event_callback_call(obj->layer->evas);
}
void
_evas_object_event_new();
evas_object_event_callback_call(obj, EVAS_CALLBACK_RESIZE, NULL);
+ _evas_post_event_callback_call(obj->layer->evas);
}
void
_evas_object_event_new();
evas_object_event_callback_call(obj, EVAS_CALLBACK_RESTACK, NULL);
+ _evas_post_event_callback_call(obj->layer->evas);
}
void
_evas_object_event_new();
evas_object_event_callback_call(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, NULL);
+ _evas_post_event_callback_call(obj->layer->evas);
}
void
_evas_object_event_new();
evas_object_event_callback_call(obj, EVAS_CALLBACK_IMAGE_PRELOADED, NULL);
+ _evas_post_event_callback_call(obj->layer->evas);
}
_evas_object_event_new();
evas_object_event_callback_call(obj, EVAS_CALLBACK_DEL, NULL);
+ _evas_post_event_callback_call(obj->layer->evas);
if (obj->name) evas_object_name_set(obj, NULL);
if (!obj->layer)
{
obj->layer->evas->focused = NULL;
_evas_object_event_new();
evas_object_event_callback_call(obj, EVAS_CALLBACK_FOCUS_OUT, NULL);
+ _evas_post_event_callback_call(obj->layer->evas);
}
obj->layer->evas->pointer.mouse_grabbed -= obj->mouse_grabbed;
obj->mouse_grabbed = 0;
evas_object_map_set(obj, NULL);
_evas_object_event_new();
evas_object_event_callback_call(obj, EVAS_CALLBACK_FREE, NULL);
+ _evas_post_event_callback_call(obj->layer->evas);
evas_object_smart_cleanup(obj);
obj->delete_me = 1;
evas_object_change(obj);
ev.timestamp = obj->layer->evas->last_timestamp;
ev.event_flags = EVAS_EVENT_FLAG_NONE;
evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_OUT, &ev);
+ _evas_post_event_callback_call(obj->layer->evas);
}
}
}
typedef struct _Evas_Format Evas_Format;
typedef struct _Evas_Map_Point Evas_Map_Point;
typedef struct _Evas_Smart_Cb_Description_Array Evas_Smart_Cb_Description_Array;
+typedef struct _Evas_Post_Callback Evas_Post_Callback;
#define MAGIC_EVAS 0x70777770
#define MAGIC_OBJ 0x71777770
Evas_Modifier_Mask mask; /* we have a max of 64 locks */
};
+struct _Evas_Post_Callback
+{
+ Evas_Object *obj;
+ Evas_Object_Event_Post_Cb func;
+ const void *data;
+ unsigned char delete_me : 1;
+};
+
struct _Evas_Callbacks
{
Eina_Inlist *callbacks;
Eina_Array calculate_objects;
Eina_Array clip_changes;
+ Eina_List *post_events; // free me on evas_free
+
Evas_Callbacks *callbacks;
int delete_grabs;
const Eina_Inlist *evas_object_smart_members_get_direct(const Evas_Object *obj);
void evas_call_smarts_calculate(Evas *e);
void *evas_mem_calloc(int size);
+void _evas_post_event_callback_call(Evas *e);
+void _evas_post_event_callback_free(Evas *e);
void evas_event_callback_list_post_free(Eina_Inlist **list);
void evas_object_event_callback_all_del(Evas_Object *obj);
void evas_object_event_callback_cleanup(Evas_Object *obj);