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 void clutter_backend_egl_init (ClutterBackendEGL *backend_egl) { ClutterBackend *backend = CLUTTER_BACKEND (backend_egl); ClutterMainContext *context; int i; clutter_backend_set_resolution (backend, 96.0); clutter_backend_set_double_click_time (backend, 250); clutter_backend_set_double_click_distance (backend, 5); context = _clutter_context_get_default (); #define MAX_FINGERS 5 for (i = 0; i < MAX_FINGERS; i++) { ClutterFruityFingerDevice *device; device = g_new0 (ClutterFruityFingerDevice, 1); context->input_devices = g_slist_append (context->input_devices, device); device->device.id = i; device->device.click_count = 0; device->device.previous_time = 0; device->device.previous_x = -1; device->device.previous_y = -1; device->device.previous_button_number = -1; device->x = 0; device->y = 0; } #undef MAX_FINGERS }
static void clutter_backend_real_resolution_changed (ClutterBackend *backend) { ClutterBackendPrivate *priv = backend->priv; ClutterMainContext *context; ClutterSettings *settings; gdouble resolution; gint dpi; settings = clutter_settings_get_default (); g_object_get (settings, "font-dpi", &dpi, NULL); if (dpi < 0) resolution = 96.0; else resolution = dpi / 1024.0; context = _clutter_context_get_default (); if (context->font_map != NULL) cogl_pango_font_map_set_resolution (context->font_map, resolution); priv->units_per_em = get_units_per_em (backend, NULL); priv->units_serial += 1; CLUTTER_NOTE (BACKEND, "Units per em: %.2f", priv->units_per_em); }
gboolean _clutter_feature_init (GError **error) { ClutterMainContext *context; CLUTTER_NOTE (MISC, "checking features"); if (!__features) { CLUTTER_NOTE (MISC, "allocating features data"); __features = g_new0 (ClutterFeatures, 1); __features->features_set = FALSE; /* don't rely on zero-ing */ } if (__features->features_set) return TRUE; context = _clutter_context_get_default (); /* makes sure we have a GL context; if we have, this is a no-op */ if (!_clutter_backend_create_context (context->backend, error)) return FALSE; __features->flags = (clutter_features_from_cogl (cogl_get_features ()) | _clutter_backend_get_features (context->backend)); __features->features_set = TRUE; CLUTTER_NOTE (MISC, "features checked"); return TRUE; }
static void events_queue (ClutterBackend *backend) { ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend); ClutterBackendX11Class *backend_x11_class = CLUTTER_BACKEND_X11_GET_CLASS (backend_x11); ClutterEvent *event; Display *xdisplay = backend_x11->xdpy; XEvent xevent; ClutterMainContext *clutter_context; clutter_context = _clutter_context_get_default (); while (!clutter_events_pending () && XPending (xdisplay)) { XNextEvent (xdisplay, &xevent); if (backend_x11_class->handle_event (backend_x11, &xevent)) continue; event = clutter_event_new (CLUTTER_NOTHING); if (event_translate (backend, event, &xevent)) { /* push directly here to avoid copy of queue_put */ g_queue_push_head (clutter_context->events_queue, event); } else { clutter_event_free (event); } } }
void _clutter_feature_init (void) { ClutterMainContext *context; CLUTTER_NOTE (MISC, "checking features"); if (!__features) { CLUTTER_NOTE (MISC, "allocating features data"); __features = g_new0 (ClutterFeatures, 1); __features->features_set = FALSE; /* don't rely on zero-ing */ } if (__features->features_set) return; context = _clutter_context_get_default (); __features->flags = (_clutter_features_from_cogl (cogl_get_features ()) | _clutter_backend_get_features (context->backend)); __features->features_set = TRUE; CLUTTER_NOTE (MISC, "features checked"); }
/** * clutter_get_default_backend: * * Retrieves the default #ClutterBackend used by Clutter. The * #ClutterBackend holds backend-specific configuration options. * * Return value: (transfer none): the default backend. You should * not ref or unref the returned object. Applications should rarely * need to use this. * * Since: 0.4 */ ClutterBackend * clutter_get_default_backend (void) { ClutterMainContext *clutter_context; clutter_context = _clutter_context_get_default (); return clutter_context->backend; }
/** * clutter_get_current_event: * * If an event is currently being processed, return that event. * This function is intended to be used to access event state * that might not be exposed by higher-level widgets. For * example, to get the key modifier state from a Button 'clicked' * event. * * Return value: (transfer none): The current ClutterEvent, or %NULL if none * * Since: 1.2 */ const ClutterEvent * clutter_get_current_event (void) { ClutterMainContext *context = _clutter_context_get_default (); g_return_val_if_fail (context != NULL, NULL); return context->current_event; }
ClutterMasterClock * _clutter_master_clock_get_default (void) { ClutterMainContext *context = _clutter_context_get_default (); if (G_UNLIKELY (context->master_clock == NULL)) context->master_clock = g_object_new (CLUTTER_TYPE_MASTER_CLOCK_DEFAULT, NULL); return context->master_clock; }
/** * clutter_events_pending: * * Checks if events are pending in the event queue. * * Return value: TRUE if there are pending events, FALSE otherwise. * * Since: 0.4 */ gboolean clutter_events_pending (void) { ClutterMainContext *context = _clutter_context_get_default (); g_return_val_if_fail (context != NULL, FALSE); if (context->events_queue == NULL) return FALSE; return g_queue_is_empty (context->events_queue) == FALSE; }
/** * clutter_get_current_event_time: * * Retrieves the timestamp of the last event, if there is an * event or if the event has a timestamp. * * Return value: the event timestamp, or %CLUTTER_CURRENT_TIME * * Since: 1.0 */ guint32 clutter_get_current_event_time (void) { ClutterMainContext *context = _clutter_context_get_default (); g_return_val_if_fail (context != NULL, FALSE); if (context->last_event_time != 0) return context->last_event_time; return CLUTTER_CURRENT_TIME; }
/** * clutter_event_get: * * Pops an event off the event queue. Applications should not need to call * this. * * Return value: A #ClutterEvent or NULL if queue empty * * Since: 0.4 */ ClutterEvent * clutter_event_get (void) { ClutterMainContext *context = _clutter_context_get_default (); if (context->events_queue == NULL) return NULL; if (g_queue_is_empty (context->events_queue)) return NULL; return g_queue_pop_tail (context->events_queue); }
/** * clutter_event_peek: * * Returns a pointer to the first event from the event queue but * does not remove it. * * Return value: (transfer none): A #ClutterEvent or NULL if queue empty. * * Since: 0.4 */ ClutterEvent * clutter_event_peek (void) { ClutterMainContext *context = _clutter_context_get_default (); g_return_val_if_fail (context != NULL, NULL); if (context->events_queue == NULL) return NULL; if (g_queue_is_empty (context->events_queue)) return NULL; return g_queue_peek_tail (context->events_queue); }
void _clutter_backend_init_events (ClutterBackend *backend) { ClutterBackendClass *klass; ClutterMainContext *clutter_context; clutter_context = _clutter_context_get_default (); g_return_if_fail (CLUTTER_IS_BACKEND (backend)); g_return_if_fail (clutter_context != NULL); clutter_context->events_queue = g_queue_new (); klass = CLUTTER_BACKEND_GET_CLASS (backend); if (klass->init_events) klass->init_events (backend); }
ClutterMasterClock * _clutter_master_clock_get_default (void) { ClutterMainContext *context = _clutter_context_get_default (); if (G_UNLIKELY (context->master_clock == NULL)) { #ifdef CLUTTER_WINDOWING_GDK if (CLUTTER_IS_BACKEND_GDK (context->backend)) context->master_clock = g_object_new (CLUTTER_TYPE_MASTER_CLOCK_GDK, NULL); else #endif context->master_clock = g_object_new (CLUTTER_TYPE_MASTER_CLOCK_DEFAULT, NULL); } return context->master_clock; }
static void settings_update_fontmap (ClutterSettings *self, guint stamp) { if (self->backend == NULL) return; #ifdef HAVE_PANGO_FT2 CLUTTER_NOTE (BACKEND, "Update fontmaps (stamp: %d)", stamp); if (self->last_fontconfig_timestamp != stamp) { ClutterMainContext *context; gboolean update_needed = FALSE; context = _clutter_context_get_default (); /* If there is no font map yet then we don't need to do anything * because the config for fontconfig will be read when it is * created */ if (context->font_map) { PangoFontMap *fontmap = PANGO_FONT_MAP (context->font_map); if (PANGO_IS_FC_FONT_MAP (fontmap) && !FcConfigUptoDate (NULL)) { pango_fc_font_map_cache_clear (PANGO_FC_FONT_MAP (fontmap)); if (FcInitReinitialize ()) update_needed = TRUE; } } self->last_fontconfig_timestamp = stamp; if (update_needed) g_signal_emit_by_name (self->backend, "font-changed"); } #endif /* HAVE_PANGO_FT2 */ }
static void clutter_backend_dispose (GObject *gobject) { ClutterBackendPrivate *priv = CLUTTER_BACKEND (gobject)->priv; ClutterMainContext *clutter_context; clutter_context = _clutter_context_get_default (); if (clutter_context && clutter_context->events_queue) { g_queue_foreach (clutter_context->events_queue, (GFunc) clutter_event_free, NULL); g_queue_free (clutter_context->events_queue); clutter_context->events_queue = NULL; } g_free (priv->font_name); clutter_backend_set_font_options (CLUTTER_BACKEND (gobject), NULL); G_OBJECT_CLASS (clutter_backend_parent_class)->dispose (gobject); }
/** * clutter_x11_handle_event: * @xevent: pointer to XEvent structure * * This function processes a single X event; it can be used to hook * into external X event retrieval (for example that done by GDK). * * 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) { ClutterBackend *backend; ClutterBackendX11Class *backend_x11_class; ClutterEvent *event; ClutterMainContext *clutter_context; ClutterX11FilterReturn result; gint spin = 1; /* 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_enter (); clutter_context = _clutter_context_get_default (); backend = clutter_context->backend; backend_x11_class = CLUTTER_BACKEND_X11_GET_CLASS (backend); /* If the backend just observed the event and didn't want it * removed it could return FALSE, so assume that a TRUE return * means that our caller should also do no further processing. */ if (backend_x11_class->handle_event (CLUTTER_BACKEND_X11(backend), xevent)) return CLUTTER_X11_FILTER_REMOVE; event = clutter_event_new (CLUTTER_NOTHING); if (event_translate (backend, event, xevent)) { /* push directly here to avoid copy of queue_put */ result = CLUTTER_X11_FILTER_REMOVE; g_queue_push_head (clutter_context->events_queue, event); } 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_do_event (event); clutter_event_free (event); --spin; } out: clutter_threads_leave (); return result; }