Пример #1
0
ClutterActor *
_clutter_backend_create_stage (ClutterBackend  *backend,
                               ClutterStage    *wrapper,
                               GError         **error)
{
  ClutterBackendClass *klass;
  ClutterStageManager *stage_manager;
  ClutterActor        *stage = NULL;

  g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), FALSE);
  g_return_val_if_fail (CLUTTER_IS_STAGE (wrapper), FALSE);

  stage_manager = clutter_stage_manager_get_default ();

  klass = CLUTTER_BACKEND_GET_CLASS (backend);
  if (klass->create_stage)
    stage = klass->create_stage (backend, wrapper, error);

  if (!stage)
    return NULL;

  g_assert (CLUTTER_IS_STAGE_WINDOW (stage));
  _clutter_stage_set_window (wrapper, CLUTTER_STAGE_WINDOW (stage));
  _clutter_stage_manager_add_stage (stage_manager, wrapper);

  return stage;
}
Пример #2
0
static ClutterStageWindow *
clutter_backend_real_create_stage (ClutterBackend  *backend,
                                   ClutterStage    *wrapper,
                                   GError         **error)
{
  ClutterBackendClass *klass;

  if (!clutter_feature_available (CLUTTER_FEATURE_STAGE_MULTIPLE))
    {
      ClutterStageManager *manager = clutter_stage_manager_get_default ();

      if (clutter_stage_manager_get_default_stage (manager) != NULL)
        {
          g_set_error (error, CLUTTER_INIT_ERROR,
                       CLUTTER_INIT_ERROR_BACKEND,
                       _("The backend of type '%s' does not support "
                         "creating multiple stages"),
                       G_OBJECT_TYPE_NAME (backend));
          return NULL;
        }
    }

  klass = CLUTTER_BACKEND_GET_CLASS (backend);
  g_assert (klass->stage_window_type != G_TYPE_INVALID);

  return g_object_new (klass->stage_window_type,
                       "backend", backend,
                       "wrapper", wrapper,
                       NULL);
}
Пример #3
0
void
_clutter_backend_ensure_context_internal (ClutterBackend  *backend,
                                          ClutterStage    *stage)
{
  ClutterBackendClass *klass = CLUTTER_BACKEND_GET_CLASS (backend);
  if (G_LIKELY (klass->ensure_context))
    klass->ensure_context (backend, stage);
}
Пример #4
0
gboolean
_clutter_backend_translate_event (ClutterBackend *backend,
                                  gpointer        native,
                                  ClutterEvent   *event)
{
  return CLUTTER_BACKEND_GET_CLASS (backend)->translate_event (backend,
                                                               native,
                                                               event);
}
Пример #5
0
void
_clutter_backend_ensure_context (ClutterBackend *backend,
                                 ClutterStage   *stage)
{
  static ClutterStage *current_context_stage = NULL;
  ClutterBackendClass *klass;

  g_return_if_fail (CLUTTER_IS_BACKEND (backend));
  g_return_if_fail (CLUTTER_IS_STAGE (stage));

  if (current_context_stage != stage || !CLUTTER_ACTOR_IS_REALIZED (stage))
    {
      ClutterStage *new_stage = NULL;

      if (!CLUTTER_ACTOR_IS_REALIZED (stage))
        {
          new_stage = NULL;

          CLUTTER_NOTE (MULTISTAGE,
                        "Stage [%p] is not realized, unsetting the stage",
                        stage);
        }
      else
        {
          new_stage = stage;

          CLUTTER_NOTE (MULTISTAGE,
                        "Setting the new stage [%p]",
                        new_stage);
        }

      klass = CLUTTER_BACKEND_GET_CLASS (backend);
      if (G_LIKELY (klass->ensure_context))
        klass->ensure_context (backend, new_stage);
      
      /* FIXME: With a NULL stage and thus no active context it may make more
       * sense to clean the context but then re call with the default stage 
       * so at least there is some kind of context in place (as to avoid
       * potential issue of GL calls with no context)
       */
      current_context_stage = new_stage;

      /* if the new stage has a different size than the previous one
       * we need to update the viewport; we do it by simply setting the
       * SYNC_MATRICES flag and letting the next redraw cycle take care
       * of calling glViewport()
       */
      if (current_context_stage)
        {
          CLUTTER_SET_PRIVATE_FLAGS (current_context_stage,
                                     CLUTTER_ACTOR_SYNC_MATRICES);
        }
    }
  else
    CLUTTER_NOTE (MULTISTAGE, "Stage is the same");
}
Пример #6
0
void
_clutter_backend_free_event_data (ClutterBackend *backend,
                                  ClutterEvent   *event)
{
  ClutterBackendClass *klass;

  klass = CLUTTER_BACKEND_GET_CLASS (backend);
  if (klass->free_event_data != NULL)
    klass->free_event_data (backend, event);
}
Пример #7
0
gboolean
_clutter_backend_create_context (ClutterBackend  *backend,
                                 GError         **error)
{
  ClutterBackendClass *klass;

  klass = CLUTTER_BACKEND_GET_CLASS (backend);

  return klass->create_context (backend, error);
}
Пример #8
0
void
_clutter_backend_redraw (ClutterBackend *backend,
                         ClutterStage   *stage)
{
  ClutterBackendClass *klass;

  klass = CLUTTER_BACKEND_GET_CLASS (backend);
  if (G_LIKELY (klass->redraw))
    klass->redraw (backend, stage);
}
Пример #9
0
void
_clutter_backend_init_events (ClutterBackend *backend)
{
  ClutterBackendClass *klass;

  g_assert (CLUTTER_IS_BACKEND (backend));

  klass = CLUTTER_BACKEND_GET_CLASS (backend);
  klass->init_events (backend);
}
Пример #10
0
void
_clutter_backend_copy_event_data (ClutterBackend     *backend,
                                  const ClutterEvent *src,
                                  ClutterEvent       *dest)
{
  ClutterBackendClass *klass;

  klass = CLUTTER_BACKEND_GET_CLASS (backend);
  if (klass->copy_event_data != NULL)
    klass->copy_event_data (backend, src, dest);
}
Пример #11
0
PangoDirection
_clutter_backend_get_keymap_direction (ClutterBackend *backend)
{
  ClutterBackendClass *klass;

  klass = CLUTTER_BACKEND_GET_CLASS (backend);
  if (klass->get_keymap_direction != NULL)
    return klass->get_keymap_direction (backend);

  return PANGO_DIRECTION_NEUTRAL;
}
Пример #12
0
void
_clutter_backend_add_options (ClutterBackend *backend,
                              GOptionGroup   *group)
{
  ClutterBackendClass *klass;

  g_return_if_fail (CLUTTER_IS_BACKEND (backend));

  klass = CLUTTER_BACKEND_GET_CLASS (backend);
  if (klass->add_options)
    klass->add_options (backend, group);
}
Пример #13
0
ClutterFeatureFlags
_clutter_backend_get_features (ClutterBackend *backend)
{
  ClutterBackendClass *klass;

  g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), 0);

  klass = CLUTTER_BACKEND_GET_CLASS (backend);
  if (klass->get_features)
    return klass->get_features (backend);
  
  return 0;
}
Пример #14
0
gboolean
_clutter_backend_post_parse (ClutterBackend  *backend,
                             GError         **error)
{
  ClutterBackendClass *klass;

  g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), FALSE);

  klass = CLUTTER_BACKEND_GET_CLASS (backend);
  if (klass->post_parse)
    return klass->post_parse (backend, error);

  return TRUE;
}
Пример #15
0
gboolean
_clutter_backend_pre_parse (ClutterBackend  *backend,
                            GError         **error)
{
  ClutterBackendClass *klass;

  g_assert (CLUTTER_IS_BACKEND (backend));

  klass = CLUTTER_BACKEND_GET_CLASS (backend);
  if (klass->pre_parse)
    return klass->pre_parse (backend, error);

  return TRUE;
}
Пример #16
0
gboolean
_clutter_backend_create_context (ClutterBackend  *backend,
                                 gboolean         is_offscreen,
                                 GError         **error)
{
  ClutterBackendClass *klass;

  g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), FALSE);

  klass = CLUTTER_BACKEND_GET_CLASS (backend);
  if (klass->create_context)
    return klass->create_context (backend, is_offscreen, error);

  return TRUE;
}
Пример #17
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);
}
Пример #18
0
void
_clutter_backend_free_event_data (ClutterBackend *backend,
                                  ClutterEvent   *event)
{
  ClutterEventExtenderInterface *iface;
  ClutterBackendClass *klass;

  klass = CLUTTER_BACKEND_GET_CLASS (backend);

  if (CLUTTER_IS_EVENT_EXTENDER (backend->device_manager))
    {
      iface = CLUTTER_EVENT_EXTENDER_GET_IFACE (backend->device_manager);
      iface->free_event_data (CLUTTER_EVENT_EXTENDER (backend->device_manager),
                              event);
    }
  else if (klass->free_event_data != NULL)
    klass->free_event_data (backend, event);
}
Пример #19
0
ClutterFeatureFlags
_clutter_backend_get_features (ClutterBackend *backend)
{
  ClutterBackendClass *klass;
  GError *error;

  g_assert (CLUTTER_IS_BACKEND (backend));

  klass = CLUTTER_BACKEND_GET_CLASS (backend);

  /* we need to have a context here; so we create the
   * GL context first and the ask for features. if the
   * context already exists this should be a no-op
   */
  error = NULL;
  if (klass->create_context != NULL)
    {
      gboolean res;

      res = klass->create_context (backend, &error);
      if (!res)
        {
          if (error)
            {
              g_critical ("Unable to create a context: %s", error->message);
              g_error_free (error);
            }
          else
            g_critical ("Unable to create a context: unknown error");

          return 0;
        }
    }

  if (klass->get_features)
    return klass->get_features (backend);
  
  return 0;
}
Пример #20
0
ClutterStageWindow *
_clutter_backend_create_stage (ClutterBackend  *backend,
                               ClutterStage    *wrapper,
                               GError         **error)
{
  ClutterBackendClass *klass;
  ClutterStageWindow *stage_window;

  g_assert (CLUTTER_IS_BACKEND (backend));
  g_assert (CLUTTER_IS_STAGE (wrapper));

  klass = CLUTTER_BACKEND_GET_CLASS (backend);
  if (klass->create_stage != NULL)
    stage_window = klass->create_stage (backend, wrapper, error);
  else
    stage_window = NULL;

  if (stage_window == NULL)
    return NULL;

  g_assert (CLUTTER_IS_STAGE_WINDOW (stage_window));

  return stage_window;
}
Пример #21
0
static gboolean
clutter_backend_real_create_context (ClutterBackend  *backend,
                                     GError         **error)
{
  ClutterBackendClass *klass;
  CoglSwapChain *swap_chain;
  GError *internal_error;

  if (backend->cogl_context != NULL)
    return TRUE;

  klass = CLUTTER_BACKEND_GET_CLASS (backend);

  swap_chain = NULL;
  internal_error = NULL;

  CLUTTER_NOTE (BACKEND, "Creating Cogl renderer");
  if (klass->get_renderer != NULL)
    backend->cogl_renderer = klass->get_renderer (backend, &internal_error);
  else
    backend->cogl_renderer = cogl_renderer_new ();

  if (backend->cogl_renderer == NULL)
    goto error;

#ifdef HAVE_CLUTTER_WAYLAND_COMPOSITOR
  /* If the application is trying to act as a Wayland compositor then
     it needs to have an EGL-based renderer backend */
  if (_wayland_compositor_display)
    cogl_renderer_add_constraint (backend->cogl_renderer,
                                  COGL_RENDERER_CONSTRAINT_USES_EGL);
#endif

  CLUTTER_NOTE (BACKEND, "Connecting the renderer");
  if (!cogl_renderer_connect (backend->cogl_renderer, &internal_error))
    goto error;

  CLUTTER_NOTE (BACKEND, "Creating Cogl swap chain");
  swap_chain = cogl_swap_chain_new ();

  CLUTTER_NOTE (BACKEND, "Creating Cogl display");
  if (klass->get_display != NULL)
    {
      backend->cogl_display = klass->get_display (backend,
                                                  backend->cogl_renderer,
                                                  swap_chain,
                                                  &internal_error);
    }
  else
    {
      CoglOnscreenTemplate *tmpl;
      gboolean res;

      tmpl = cogl_onscreen_template_new (swap_chain);

      /* XXX: I have some doubts that this is a good design.
       *
       * Conceptually should we be able to check an onscreen_template
       * without more details about the CoglDisplay configuration?
       */
      res = cogl_renderer_check_onscreen_template (backend->cogl_renderer,
                                                   tmpl,
                                                   &internal_error);

      if (!res)
        goto error;

      backend->cogl_display = cogl_display_new (backend->cogl_renderer, tmpl);

      /* the display owns the template */
      cogl_object_unref (tmpl);
    }

  if (backend->cogl_display == NULL)
    goto error;

#ifdef HAVE_CLUTTER_WAYLAND_COMPOSITOR
  cogl_wayland_display_set_compositor_display (backend->cogl_display,
                                               _wayland_compositor_display);
#endif

  CLUTTER_NOTE (BACKEND, "Setting up the display");
  if (!cogl_display_setup (backend->cogl_display, &internal_error))
    goto error;

  CLUTTER_NOTE (BACKEND, "Creating the Cogl context");
  backend->cogl_context = cogl_context_new (backend->cogl_display, &internal_error);
  if (backend->cogl_context == NULL)
    goto error;

  backend->cogl_source = cogl_glib_source_new (backend->cogl_context,
                                               G_PRIORITY_DEFAULT);
  g_source_attach (backend->cogl_source, NULL);

  /* the display owns the renderer and the swap chain */
  cogl_object_unref (backend->cogl_renderer);
  cogl_object_unref (swap_chain);

  return TRUE;

error:
  if (backend->cogl_display != NULL)
    {
      cogl_object_unref (backend->cogl_display);
      backend->cogl_display = NULL;
    }

  if (backend->cogl_renderer != NULL)
    {
      cogl_object_unref (backend->cogl_renderer);
      backend->cogl_renderer = NULL;
    }

  if (swap_chain != NULL)
    cogl_object_unref (swap_chain);

  if (internal_error != NULL)
    g_propagate_error (error, internal_error);
  else
    g_set_error_literal (error, CLUTTER_INIT_ERROR,
                         CLUTTER_INIT_ERROR_BACKEND,
                         _("Unable to initialize the Clutter backend"));

  return FALSE;
}