Пример #1
0
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);
}
Пример #2
0
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
}
Пример #3
0
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);
}
Пример #4
0
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;
}
Пример #5
0
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);
        }
    }
}
Пример #6
0
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");
}
Пример #7
0
/**
 * 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;
}
Пример #8
0
/**
 * 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;
}
Пример #9
0
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;

}
Пример #10
0
/**
 * 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;
}
Пример #11
0
/**
 * 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;
}
Пример #12
0
/**
 * 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);
}
Пример #13
0
/**
 * 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);
}
Пример #14
0
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);
}
Пример #15
0
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;

}
Пример #16
0
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 */
}
Пример #17
0
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);
}
Пример #18
0
/**
 * 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;
}