static gboolean clutter_event_dispatch (GSource *source, GSourceFunc callback, gpointer user_data) { ClutterBackendX11 *backend = ((ClutterEventSource *) source)->backend; ClutterEvent *event; _clutter_threads_acquire_lock (); /* Grab the event(s), translate and figure out double click. * The push onto queue (stack) if valid. */ events_queue (backend); /* Pop an event off the queue if any */ event = clutter_event_get (); if (event != NULL) { /* forward the event into clutter for emission etc. */ _clutter_stage_queue_event (event->any.stage, event, FALSE); } _clutter_threads_release_lock (); return TRUE; }
/* * _clutter_input_device_set_stage: * @device: a #ClutterInputDevice * @stage: a #ClutterStage or %NULL * * Stores the stage under the device */ void _clutter_input_device_set_stage (ClutterInputDevice *device, ClutterStage *stage) { ClutterStage *old_stage; g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); old_stage = device->stage; device->stage = stage; /* if we left the stage then we also need to unset the * cursor actor (and update its :has-pointer property) */ if (device->stage == NULL && device->cursor_actor != NULL && device->cursor_actor != CLUTTER_ACTOR (old_stage)) { ClutterEvent cev; cev.crossing.type = CLUTTER_LEAVE; cev.crossing.time = device->current_time; cev.crossing.flags = 0; cev.crossing.stage = old_stage; cev.crossing.source = device->cursor_actor; cev.crossing.x = device->current_x; cev.crossing.y = device->current_y; cev.crossing.device = device; cev.crossing.related = device->stage != NULL ? CLUTTER_ACTOR (device->stage) : CLUTTER_ACTOR (old_stage); _clutter_stage_queue_event (old_stage, &cev); _clutter_actor_set_has_pointer (device->cursor_actor, FALSE); g_object_weak_unref (G_OBJECT (device->cursor_actor), cursor_weak_unref, device); } device->cursor_actor = NULL; }
/** * clutter_x11_handle_event: * @xevent: pointer to XEvent structure * * This function processes a single X event; it can be used to hook * into external X11 event processing (for example, a GDK filter * function). * * If clutter_x11_disable_event_retrieval() has been called, you must * let this function process events to update Clutter's internal state. * * Return value: #ClutterX11FilterReturn. %CLUTTER_X11_FILTER_REMOVE * indicates that Clutter has internally handled the event and the * caller should do no further processing. %CLUTTER_X11_FILTER_CONTINUE * indicates that Clutter is either not interested in the event, * or has used the event to update internal state without taking * any exclusive action. %CLUTTER_X11_FILTER_TRANSLATE will not * occur. * * Since: 0.8 */ ClutterX11FilterReturn clutter_x11_handle_event (XEvent *xevent) { ClutterX11FilterReturn result; ClutterBackend *backend; ClutterEvent *event; gint spin = 1; #ifdef HAVE_XGE ClutterBackendX11 *backend_x11; Display *xdisplay; gboolean allocated_event; #endif /* The return values here are someone approximate; we return * CLUTTER_X11_FILTER_REMOVE if a clutter event is * generated for the event. This mostly, but not entirely, * corresponds to whether other event processing should be * excluded. As long as the stage window is not shared with another * toolkit it should be safe, and never return * %CLUTTER_X11_FILTER_REMOVE when more processing is needed. */ result = CLUTTER_X11_FILTER_CONTINUE; _clutter_threads_acquire_lock (); backend = clutter_get_default_backend (); event = clutter_event_new (CLUTTER_NOTHING); #ifdef HAVE_XGE backend_x11 = CLUTTER_BACKEND_X11 (backend); xdisplay = backend_x11->xdpy; allocated_event = XGetEventData (xdisplay, &xevent->xcookie); #endif if (_clutter_backend_translate_event (backend, xevent, event)) { _clutter_event_push (event, FALSE); result = CLUTTER_X11_FILTER_REMOVE; } else { clutter_event_free (event); goto out; } /* * Motion events can generate synthetic enter and leave events, so if we * are processing a motion event, we need to spin the event loop at least * two extra times to pump the enter/leave events through (otherwise they * just get pushed down the queue and never processed). */ if (event->type == CLUTTER_MOTION) spin += 2; while (spin > 0 && (event = clutter_event_get ())) { /* forward the event into clutter for emission etc. */ _clutter_stage_queue_event (event->any.stage, event, FALSE); --spin; } out: #ifdef HAVE_XGE if (allocated_event) XFreeEventData (xdisplay, &xevent->xcookie); #endif _clutter_threads_release_lock (); return result; }