* clutter/clutter-main.c: (emit_event): renamed from deliver_event,

(emit_pointer_event): utility function to emit pointer event signals
(which takes pointer grab into account).
(emit_keyboard_event): utility function to emit keyboard event signals
(which takes keyboard grab into account).
(clutter_do_event): use the above utility functions, also reindented
the source.
This commit is contained in:
Øyvind Kolås 2007-11-16 13:41:07 +00:00
parent 8339cf3fce
commit 3c0897a102
2 changed files with 162 additions and 135 deletions

View File

@ -1,4 +1,14 @@
2007-11-16 Øyvind Kolås <pippin@gimp.org> 2007-11-16 Øyvind Kolås <pippin@o-hand.com>
* clutter/clutter-main.c: (emit_event): renamed from deliver_event,
(emit_pointer_event): utility function to emit pointer event signals
(which takes pointer grab into account).
(emit_keyboard_event): utility function to emit keyboard event signals
(which takes keyboard grab into account).
(clutter_do_event): use the above utility functions, also reindented
the source.
2007-11-16 Øyvind Kolås <pippin@o-hand.com>
* tests/test-grab.c: (main): fix use of clutter_actor_set_reactive * tests/test-grab.c: (main): fix use of clutter_actor_set_reactive

View File

@ -1151,16 +1151,18 @@ event_click_count_generate (ClutterEvent *event)
} }
} }
static inline void static inline void
deliver_event (ClutterEvent *event) emit_event (ClutterEvent *event,
gboolean is_key_event)
{ {
#define MAX_EVENT_DEPTH 512 #define MAX_EVENT_DEPTH 512
static ClutterActor **event_tree = NULL; static ClutterActor **event_tree = NULL;
static gboolean lock = FALSE; static gboolean lock = FALSE;
ClutterActor *actor; ClutterActor *actor;
gint i = 0, n_tree_events = 0; gint i = 0, n_tree_events = 0;
g_return_if_fail (event->any.source != NULL); g_return_if_fail (event->any.source != NULL);
g_return_if_fail (lock == FALSE); g_return_if_fail (lock == FALSE);
@ -1173,14 +1175,21 @@ deliver_event (ClutterEvent *event)
actor = event->any.source; actor = event->any.source;
/* Build 'tree' of events */ /* Build 'tree' of emitters for the event */
while (actor && n_tree_events < MAX_EVENT_DEPTH) while (actor && n_tree_events < MAX_EVENT_DEPTH)
{ {
if (clutter_actor_get_reactive (actor) || ClutterActor *parent;
clutter_actor_get_parent (actor) == NULL)
event_tree[n_tree_events++] = g_object_ref (actor);
actor = clutter_actor_get_parent (actor); parent = clutter_actor_get_parent (actor);
if (clutter_actor_get_reactive (actor) ||
parent == NULL || /* stage gets all events */
is_key_event) /* keyboard events are always emitted */
{
event_tree[n_tree_events++] = g_object_ref (actor);
}
actor = parent;
} }
/* Capture */ /* Capture */
@ -1204,11 +1213,37 @@ done:
} }
static inline void static inline void
generate_enter_leave_events (ClutterMainContext *context, emit_pointer_event (ClutterEvent *event)
ClutterActor *motion_current_actor,
ClutterEvent *event)
{ {
static ClutterActor *motion_last_actor = NULL; /* Using the global variable directly, since it has to be initialized
* at this point
*/
ClutterMainContext *context = ClutterCntx;
if (G_UNLIKELY (context->pointer_grab_actor != NULL))
clutter_actor_event (context->pointer_grab_actor, event, FALSE);
else
emit_event (event, FALSE);
}
static inline void
emit_keyboard_event (ClutterEvent *event)
{
ClutterMainContext *context = ClutterCntx;
if (G_UNLIKELY (context->keyboard_grab_actor != NULL))
clutter_actor_event (context->keyboard_grab_actor, event, FALSE);
else
emit_event (event, TRUE);
}
static inline void
generate_enter_leave_events (ClutterEvent *event)
{
ClutterMainContext *context = ClutterCntx;
static ClutterActor *motion_last_actor = NULL;
ClutterActor *motion_current_actor = event->motion.source;
if (motion_last_actor != motion_current_actor) if (motion_last_actor != motion_current_actor)
{ {
@ -1262,7 +1297,6 @@ clutter_do_event (ClutterEvent *event)
ClutterBackend *backend; ClutterBackend *backend;
ClutterActor *stage; ClutterActor *stage;
context = clutter_context_get_default (); context = clutter_context_get_default ();
backend = context->backend; backend = context->backend;
stage = _clutter_backend_get_stage (backend); stage = _clutter_backend_get_stage (backend);
@ -1274,141 +1308,124 @@ clutter_do_event (ClutterEvent *event)
switch (event->type) switch (event->type)
{ {
case CLUTTER_NOTHING: case CLUTTER_NOTHING:
event->any.source = stage; event->any.source = stage;
break; break;
case CLUTTER_ENTER:
case CLUTTER_LEAVE:
if (context->pointer_grab_actor != NULL) case CLUTTER_ENTER:
case CLUTTER_LEAVE:
emit_pointer_event (event);
break;
case CLUTTER_DESTROY_NOTIFY:
case CLUTTER_DELETE:
event->any.source = stage;
if (clutter_stage_event (CLUTTER_STAGE (stage), event))
clutter_main_quit ();
break;
case CLUTTER_KEY_PRESS:
case CLUTTER_KEY_RELEASE:
{ {
clutter_actor_event (context->pointer_grab_actor, event, FALSE); ClutterActor *actor = NULL;
return;
actor = clutter_stage_get_key_focus (CLUTTER_STAGE (stage));
event->any.source = actor;
g_return_if_fail (actor != NULL);
emit_keyboard_event (event);
} }
deliver_event (event); break;
break;
case CLUTTER_DESTROY_NOTIFY:
case CLUTTER_DELETE:
event->any.source = stage;
if (clutter_stage_event (CLUTTER_STAGE (stage), event))
clutter_main_quit ();
break;
case CLUTTER_KEY_PRESS:
case CLUTTER_KEY_RELEASE:
{
ClutterActor *actor = NULL;
actor = clutter_stage_get_key_focus (CLUTTER_STAGE (stage)); case CLUTTER_MOTION:
event->any.source = actor; if (context->motion_events_per_actor == FALSE)
g_return_if_fail (actor != NULL);
if (context->keyboard_grab_actor != NULL)
{ {
clutter_actor_event (context->keyboard_grab_actor, event, FALSE); /* Only stage gets motion events */
return; event->any.source = stage;
}
deliver_event (event);
}
break;
case CLUTTER_MOTION:
if (context->motion_events_per_actor == FALSE)
{
/* Only stage gets motion events */
event->any.source = stage;
if (context->pointer_grab_actor != NULL) if (context->pointer_grab_actor != NULL)
{
clutter_actor_event (context->pointer_grab_actor, event, FALSE);
return;
}
/* Trigger handlers on stage in both capture .. */
if (!clutter_actor_event (stage, event, TRUE))
{
/* and bubbling phase */
clutter_actor_event (stage, event, FALSE);
}
break;
}
case CLUTTER_BUTTON_PRESS:
case CLUTTER_BUTTON_RELEASE:
case CLUTTER_SCROLL:
{
ClutterActor *actor;
gint x,y;
clutter_event_get_coords (event, &x, &y);
/* Handle release off stage */
if ((x >= CLUTTER_STAGE_WIDTH () ||
y >= CLUTTER_STAGE_HEIGHT() ||
x < 0 || y < 0))
{
if (event->type == CLUTTER_BUTTON_RELEASE)
{ {
CLUTTER_NOTE (EVENT, "Release off stage received at %i, %i", x, y); clutter_actor_event (context->pointer_grab_actor, event, FALSE);
break;
}
event->button.source = stage; /* Trigger handlers on stage in both capture .. */
if (!clutter_actor_event (stage, event, TRUE))
if (context->pointer_grab_actor != NULL) {
{ /* and bubbling phase */
clutter_actor_event (context->pointer_grab_actor, clutter_actor_event (stage, event, FALSE);
event, FALSE);
return;
}
deliver_event (event);
} }
break; break;
} }
/* Map the event to a reactive actor */ /* fallthrough */
actor = _clutter_do_pick (CLUTTER_STAGE (stage),
x, y,
CLUTTER_PICK_REACTIVE);
event->any.source = actor; case CLUTTER_BUTTON_PRESS:
case CLUTTER_BUTTON_RELEASE:
case CLUTTER_SCROLL:
{
ClutterActor *actor;
gint x,y;
if (!actor) clutter_event_get_coords (event, &x, &y);
break;
/* FIXME: for an optimisation should check if there are /* Handle release off stage */
* actually any reactive actors and avoid the pick all togeather if ((x >= CLUTTER_STAGE_WIDTH () ||
* (signalling just the stage). Should be big help for gles. y >= CLUTTER_STAGE_HEIGHT() ||
*/ x < 0 || y < 0))
CLUTTER_NOTE (EVENT, "Reactive event received at %i, %i - actor: %p",
x, y, actor);
if (event->type == CLUTTER_MOTION)
{
/* Generate enter leave events (if any) */
generate_enter_leave_events (context, actor, event);
}
else /* (button event) */
{
/* Generate click count */
event_click_count_generate (event);
}
if (context->pointer_grab_actor != NULL)
{ {
clutter_actor_event (context->pointer_grab_actor, event, FALSE); if (event->type == CLUTTER_BUTTON_RELEASE)
return; {
CLUTTER_NOTE (EVENT, "Release off stage received at %i, %i",
x, y);
event->button.source = stage;
emit_pointer_event (event);
}
break;
} }
deliver_event (event);
} /* Map the event to a reactive actor */
break; actor = _clutter_do_pick (CLUTTER_STAGE (stage),
case CLUTTER_STAGE_STATE: x, y,
/* fullscreen / focus - forward to stage */ CLUTTER_PICK_REACTIVE);
event->any.source = stage;
clutter_stage_event (CLUTTER_STAGE (stage), event); event->any.source = actor;
break;
case CLUTTER_CLIENT_MESSAGE: if (!actor)
break; break;
/* FIXME: for an optimisation should check if there are
* actually any reactive actors and avoid the pick all togeather
* (signalling just the stage). Should be big help for gles.
*/
CLUTTER_NOTE (EVENT, "Reactive event received at %i, %i - actor: %p",
x, y, actor);
if (event->type == CLUTTER_MOTION)
{
/* Generate enter leave events (if any) */
generate_enter_leave_events (event);
}
else /* (button event) */
{
/* Generate click count */
event_click_count_generate (event);
}
emit_pointer_event (event);
break;
}
case CLUTTER_STAGE_STATE:
/* fullscreen / focus - forward to stage */
event->any.source = stage;
clutter_stage_event (CLUTTER_STAGE (stage), event);
break;
case CLUTTER_CLIENT_MESSAGE:
break;
} }
} }