void _clutter_event_push (const ClutterEvent *event, gboolean do_copy) { ClutterMainContext *context = _clutter_context_get_default (); ClutterInputDevice *device; g_assert (context != NULL); if (context->events_queue == NULL) context->events_queue = g_queue_new (); /* disabled devices don't propagate events */ device = clutter_event_get_device (event); if (device != NULL) { if (!clutter_input_device_get_enabled (device)) return; } if (do_copy) { ClutterEvent *copy; copy = clutter_event_copy (event); event = copy; } g_queue_push_head (context->events_queue, (gpointer) event); }
static GesturePoint * gesture_register_point (ClutterGestureAction *action, ClutterEvent *event) { ClutterGestureActionPrivate *priv = action->priv; GesturePoint *point = NULL; if (priv->points->len >= MAX_GESTURE_POINTS) return NULL; g_array_set_size (priv->points, priv->points->len + 1); point = &g_array_index (priv->points, GesturePoint, priv->points->len - 1); point->last_event = clutter_event_copy (event); point->device = clutter_event_get_device (event); clutter_event_get_coords (event, &point->press_x, &point->press_y); point->last_motion_x = point->press_x; point->last_motion_y = point->press_y; point->last_motion_time = clutter_event_get_time (event); point->last_delta_x = point->last_delta_y = 0; point->last_delta_time = 0; if (clutter_event_type (event) != CLUTTER_BUTTON_PRESS) point->sequence = clutter_event_get_event_sequence (event); else point->sequence = NULL; return point; }
/** * clutter_event_put: * @event: a #ClutterEvent * * Puts a copy of the event on the back of the event queue. The event will have * the #CLUTTER_EVENT_FLAG_SYNTHETIC flag set. If the source is set event * signals will be emitted for this source and capture/bubbling for it's * ancestors. If the source is not set it will be generated by picking or use * the actor that currently has keyboard focus. * * Since: 0.6 */ void clutter_event_put (ClutterEvent *event) { ClutterMainContext *context = clutter_context_get_default (); ClutterEvent *event_copy; /* FIXME: check queue is valid */ g_return_if_fail (context != NULL); event_copy = clutter_event_copy (event); event_copy->any.flags |= CLUTTER_EVENT_FLAG_SYNTHETIC; g_queue_push_head (context->events_queue, event_copy); }
static void gesture_update_release_point (GesturePoint *point, ClutterEvent *event) { gint64 _time; clutter_event_get_coords (event, &point->release_x, &point->release_y); clutter_event_free (point->last_event); point->last_event = clutter_event_copy (event); /* Treat the release event as the continuation of the last motion, * in case the user keeps the pointer still for a while before * releasing it. */ _time = clutter_event_get_time (event); point->last_delta_time += _time - point->last_motion_time; }
static void gesture_update_motion_point (GesturePoint *point, ClutterEvent *event) { gfloat motion_x, motion_y; gint64 _time; clutter_event_get_coords (event, &motion_x, &motion_y); clutter_event_free (point->last_event); point->last_event = clutter_event_copy (event); point->last_delta_x = motion_x - point->last_motion_x; point->last_delta_y = motion_y - point->last_motion_y; point->last_motion_x = motion_x; point->last_motion_y = motion_y; _time = clutter_event_get_time (event); point->last_delta_time = _time - point->last_motion_time; point->last_motion_time = _time; }
static void start_slow_keys (ClutterEvent *event, ClutterInputDeviceEvdev *device, ClutterEmitInputDeviceEvent emit_event_func) { SlowKeysEventPending *slow_keys_event; ClutterKeyEvent *key_event = (ClutterKeyEvent *) event; if (key_event->flags & CLUTTER_EVENT_FLAG_REPEATED) return; slow_keys_event = g_new0 (SlowKeysEventPending, 1); slow_keys_event->device = device; slow_keys_event->event = clutter_event_copy (event); slow_keys_event->emit_event_func = emit_event_func; slow_keys_event->timer = clutter_threads_add_timeout (get_slow_keys_delay (CLUTTER_INPUT_DEVICE (device)), trigger_slow_keys, slow_keys_event); device->slow_keys_list = g_list_append (device->slow_keys_list, slow_keys_event); if (device->a11y_flags & CLUTTER_A11Y_SLOW_KEYS_BEEP_PRESS) clutter_input_device_evdev_bell_notify (); }
/* Dragged actor moved */ static void _xfdashboard_drag_action_drag_motion(ClutterDragAction *inAction, ClutterActor *inActor, gfloat inDeltaX, gfloat inDeltaY) { XfdashboardDragAction *self; XfdashboardDragActionPrivate *priv; ClutterDragActionClass *dragActionClass; gfloat stageX, stageY; XfdashboardDropAction *dropTarget; gfloat dropX, dropY; const ClutterEvent *event; g_return_if_fail(XFDASHBOARD_IS_DRAG_ACTION(inAction)); self=XFDASHBOARD_DRAG_ACTION(inAction); priv=self->priv; dragActionClass=CLUTTER_DRAG_ACTION_CLASS(xfdashboard_drag_action_parent_class); /* Call parent's class method */ if(dragActionClass->drag_motion) dragActionClass->drag_motion(inAction, inActor, inDeltaX, inDeltaY); /* Remember motion delta coordinates */ priv->lastDeltaX=inDeltaX; priv->lastDeltaY=inDeltaY; /* Get event coordinates relative to stage */ clutter_drag_action_get_motion_coords(inAction, &stageX, &stageY); /* Find drop target at stage coordinate */ dropTarget=_xfdashboard_drag_action_find_drop_traget_at_coord(self, stageX, stageY); /* If found drop target is not the same as the last one emit "drag-leave" * signal at last drop target and "drag-enter" in new drop target */ if(priv->lastDropTarget!=dropTarget) { /* Emit "drag-leave" signal on last drop target */ if(priv->lastDropTarget) { g_signal_emit_by_name(priv->lastDropTarget, "drag-leave", self, NULL); priv->lastDropTarget=NULL; } /* Check if new drop target is active and emit "drag-enter" signal */ if(dropTarget) { ClutterActorMeta *actorMeta=CLUTTER_ACTOR_META(dropTarget); ClutterActor *dropActor=clutter_actor_meta_get_actor(actorMeta); if(clutter_actor_meta_get_enabled(actorMeta) && clutter_actor_is_visible(dropActor) && clutter_actor_get_reactive(dropActor)) { g_signal_emit_by_name(dropTarget, "drag-enter", self, NULL); priv->lastDropTarget=dropTarget; } } } /* Transform event coordinates relative to last drop target which * should be the drop target under pointer device if it is active * and emit "drag-motion" signal */ if(priv->lastDropTarget) { dropX=dropY=0.0f; _xfdashboard_drag_action_transform_stage_point(priv->lastDropTarget, stageX, stageY, &dropX, &dropY); g_signal_emit_by_name(priv->lastDropTarget, "drag-motion", self, dropX, dropY, NULL); } /* We are derived from ClutterDragAction and this one disables stage motion * so no "enter-event", "motion-event" and "leave-event" will be emitted while * dragging. We need to do it on our own. */ event=clutter_get_current_event(); if(event && clutter_event_type(event)==CLUTTER_MOTION) { GSList *list, *next; ClutterStage *stage; ClutterActor *motionActor; gboolean newMotionActor; ClutterActor *actor; gfloat x, y, w, h; gboolean result; ClutterEvent *actorEvent; /* Get stage where event happened */ stage=clutter_event_get_stage(event); if(stage) { /* Get actor under pointer */ newMotionActor=TRUE; motionActor=clutter_stage_get_actor_at_pos(stage, CLUTTER_PICK_REACTIVE, stageX, stageY); /* Iterate through list of crossed actors so far and check if pointer * is still inside. If pointer is outside of an actor emit "leave-event". * For each actor the pointer is still inside emit this "motion-event". * Also check if actor under pointer is already is list to prevent * "enter-event" to be emitted more than once. */ list=priv->lastMotionActors; while(list) { /* Get next entry now as this entry might get deleted */ next=g_slist_next(list); /* Get actor from entry */ actor=CLUTTER_ACTOR(list->data); /* Actor must be one same stage where event happened */ if(clutter_actor_get_stage(actor)!=CLUTTER_ACTOR(stage)) continue; /* Get position and size of actor in stage coordinates */ clutter_actor_get_transformed_position(actor, &x, &y); clutter_actor_get_transformed_size(actor, &w, &h); /* Check if pointer is still inside actor */ if(stageX>=x && stageX<(x+w) && stageY>=y && stageY<(y+h)) { /* Check if actor is the "new" motion actor. If so set flag. */ if(actor==motionActor) newMotionActor=FALSE; /* Emit "motion-event" */ actorEvent=clutter_event_copy(event); actorEvent->motion.source=actor; g_signal_emit_by_name(actor, "motion-event", actorEvent, &result); clutter_event_free(actorEvent); } /* Pointer is not inside actor anymore so remove actor from list * of last known "motion actors" and send "leave-event" */ else { /* Disconnect signal */ g_signal_handlers_disconnect_by_func(actor, G_CALLBACK(_xfdashboard_drag_action_on_motion_actor_destroyed), self); /* Remove from list */ priv->lastMotionActors=g_slist_remove_link(priv->lastMotionActors, list); g_slist_free_1(list); /* Create and emit "leave-event" */ actorEvent=clutter_event_new(CLUTTER_LEAVE); actorEvent->crossing.time=event->motion.time; actorEvent->crossing.flags=event->motion.flags; actorEvent->crossing.stage=event->motion.stage; actorEvent->crossing.source=actor; actorEvent->crossing.x=event->motion.x; actorEvent->crossing.y=event->motion.y; actorEvent->crossing.device=event->motion.device; actorEvent->crossing.related=event->motion.source; g_signal_emit_by_name(actor, "leave-event", actorEvent, &result); clutter_event_free(actorEvent); } /* Proceed with next actor */ list=next; } /* We have an actor under pointer and was not seen while iterating * through list of all last known "motion actors" then add this actor * to list and emit "enter-event" and also all parent actors because * if pointer is inside their child then it is also inside them. */ if(motionActor && newMotionActor) { while(motionActor) { /* Avoid duplicates */ if(!g_slist_find(priv->lastMotionActors, motionActor)) { /* Add to list */ priv->lastMotionActors=g_slist_append(priv->lastMotionActors, motionActor); /* Create and emit "enter-event" */ actorEvent=clutter_event_new(CLUTTER_ENTER); actorEvent->crossing.time=event->motion.time; actorEvent->crossing.flags=event->motion.flags; actorEvent->crossing.stage=event->motion.stage; actorEvent->crossing.source=event->motion.source; actorEvent->crossing.x=event->motion.x; actorEvent->crossing.y=event->motion.y; actorEvent->crossing.device=event->motion.device; actorEvent->crossing.related=motionActor; g_signal_emit_by_name(motionActor, "enter-event", actorEvent, &result); clutter_event_free(actorEvent); /* To prevent emiting these motion events on actors being * destroyed while drag is in progress we connect to 'destroy' * signal of each "motion actor" added to list. The signal * handler will be removed either on actor's destruction by * signal handler's callback, when pointer leaves actor or on * end of drag. */ g_signal_connect(motionActor, "destroy", G_CALLBACK(_xfdashboard_drag_action_on_motion_actor_destroyed), self); } /* Get parent */ motionActor=clutter_actor_get_parent(motionActor); } } } } }