eglnative: Update implementation
authorEmmanuele Bassi <ebassi@linux.intel.com>
Sat, 27 Feb 2010 09:42:42 +0000 (09:42 +0000)
committerEmmanuele Bassi <ebassi@linux.intel.com>
Tue, 2 Mar 2010 11:50:31 +0000 (11:50 +0000)
Update the EGL native framebuffer backend to be 1.2-ready:

  » create the EGL context and the surface inside the create_context()
    implementation so that a context is always available

  » simplify the StageWindow implementation

  » clean up old code

http://bugzilla.openedhand.com/show_bug.cgi?id=1997

clutter/eglnative/clutter-backend-egl.c
clutter/eglnative/clutter-backend-egl.h
clutter/eglnative/clutter-event-egl.c
clutter/eglnative/clutter-stage-egl.c
clutter/eglnative/clutter-stage-egl.h

index 1e8b2d2..59fee18 100644 (file)
@@ -10,7 +10,6 @@
 
 static ClutterBackendEGL *backend_singleton = NULL;
 
-
 G_DEFINE_TYPE (ClutterBackendEGL, clutter_backend_egl, CLUTTER_TYPE_BACKEND);
 
 static void
@@ -61,7 +60,148 @@ static void
 clutter_backend_egl_ensure_context (ClutterBackend *backend,
                                     ClutterStage   *stage)
 {
-  /* not doing anything since we only have one context */
+  /* not doing anything since we only have one context and
+   * it is permanently made current
+   */
+}
+
+static gboolean
+clutter_backend_egl_create_context (ClutterBackend  *backend,
+                                    GError         **error)
+{
+  ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (backend);
+  EGLConfig configs[2];
+  EGLint config_count;
+  EGLBoolean status;
+  EGLint cfg_attribs[] = {
+    EGL_BUFFER_SIZE,     EGL_DONT_CARE,
+    EGL_RED_SIZE,        5,
+    EGL_GREEN_SIZE,      6,
+    EGL_BLUE_SIZE,       5,
+    EGL_DEPTH_SIZE,      16,
+    EGL_ALPHA_SIZE,      EGL_DONT_CARE,
+    EGL_STENCIL_SIZE,    2,
+#ifdef HAVE_COGL_GLES2
+    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+#else /* HAVE_COGL_GLES2 */
+    EGL_SURFACE_TYPE,    EGL_WINDOW_BIT,
+#endif /* HAVE_COGL_GLES2 */
+    EGL_NONE
+  };
+
+  status = eglGetConfigs (backend_egl->edpy,
+                          configs,
+                          2,
+                          &config_count);
+
+  if (status != EGL_TRUE)
+    {
+      g_set_error (error, CLUTTER_INIT_ERROR,
+                   CLUTTER_INIT_ERROR_BACKEND,
+                   "No EGL configurations found");
+      return FALSE;
+    }
+
+  status = eglChooseConfig (backend_egl->edpy,
+                            cfg_attribs,
+                            configs,
+                            G_N_ELEMENTS (configs),
+                            &config_count);
+
+  if (status != EGL_TRUE)
+    {
+      g_set_error (error, CLUTTER_INIT_ERROR,
+                   CLUTTER_INIT_ERROR_BACKEND,
+                   "Unable to select a valid EGL configuration");
+      return FALSE;
+    }
+
+  CLUTTER_NOTE (BACKEND, "Got %i configs", config_count);
+
+  if (G_UNLIKELY (backend_egl->egl_surface != EGL_NO_SURFACE))
+    {
+      eglDestroySurface (backend_egl->edpy, backend_egl->egl_surface);
+      backend_egl->egl_surface = EGL_NO_SURFACE;
+    }
+
+   if (G_UNLIKELY (backend_egl->egl_context != NULL))
+     {
+       eglDestroyContext (backend_egl->edpy, backend_egl->egl_context);
+       backend_egl->egl_context = NULL;
+     }
+
+  backend_egl->egl_surface =
+    eglCreateWindowSurface (backend_egl->edpy,
+                            configs[0],
+                            NULL,
+                            NULL);
+
+  if (backend_egl->egl_surface == EGL_NO_SURFACE)
+    {
+      g_set_error (error, CLUTTER_INIT_ERROR,
+                   CLUTTER_INIT_ERROR_BACKEND,
+                   "Unable to create EGL window surface");
+
+      return FALSE;
+    }
+
+#ifdef HAVE_COGL_GLES2
+  {
+    static const EGLint attribs[3] = {
+      EGL_CONTEXT_CLIENT_VERSION, 2,
+      EGL_NONE
+    };
+
+    backend_egl->egl_context = eglCreateContext (backend_egl->edpy,
+                                                 configs[0],
+                                                 EGL_NO_CONTEXT,
+                                                 attribs);
+  }
+#else
+  /* Seems some GLES implementations 1.x do not like attribs... */
+  backend_egl->egl_context = eglCreateContext (backend_egl->edpy,
+                                               configs[0],
+                                               EGL_NO_CONTEXT,
+                                               NULL);
+#endif
+
+  if (backend_egl->egl_context == EGL_NO_CONTEXT)
+    {
+      g_set_error (error, CLUTTER_INIT_ERROR,
+                   CLUTTER_INIT_ERROR_BACKEND,
+                   "Unable to create a suitable EGL context");
+      return FALSE;
+    }
+
+  CLUTTER_NOTE (GL, "Created EGL Context");
+
+  CLUTTER_NOTE (BACKEND, "Setting context");
+
+  /* eglnative can have only one stage, so we store the EGL surface
+   * in the backend itself, instead of the StageWindow implementation,
+   * and we make it current immediately to make sure the Cogl and
+   * Clutter can query the EGL context for features.
+   */
+  status = eglMakeCurrent (backend_egl->edpy,
+                           backend_egl->egl_surface,
+                           backend_egl->egl_surface,
+                           backend_egl->egl_context);
+
+  eglQuerySurface (backend_egl->edpy,
+                   backend_egl->egl_surface,
+                   EGL_WIDTH,
+                   &backend_egl->surface_width);
+
+  eglQuerySurface (backend_egl->edpy,
+                   backend_egl->egl_surface,
+                   EGL_HEIGHT,
+                   &backend_egl->surface_height);
+
+  CLUTTER_NOTE (BACKEND, "EGL surface is %ix%i",
+                backend_egl->surface_width,
+                backend_egl->surface_height);
+
+  return TRUE;
 }
 
 static void
@@ -73,32 +213,34 @@ clutter_backend_egl_redraw (ClutterBackend *backend,
   ClutterStageWindow *impl;
 
   impl = _clutter_stage_get_window (stage);
-  if (!impl)
+  if (impl == NULL)
     return;
 
   g_assert (CLUTTER_IS_STAGE_EGL (impl));
   stage_egl = CLUTTER_STAGE_EGL (impl);
 
   eglWaitNative (EGL_CORE_NATIVE_ENGINE);
-  clutter_actor_paint (CLUTTER_ACTOR (stage));
+  clutter_actor_paint (CLUTTER_ACTOR (stage_egl->wrapper));
   cogl_flush ();
 
   eglWaitGL();
-  eglSwapBuffers (backend_egl->edpy,  stage_egl->egl_surface);
+  eglSwapBuffers (backend_egl->edpy,  backend_egl->egl_surface);
 }
 
-static ClutterActor *
+static ClutterStageWindow *
 clutter_backend_egl_create_stage (ClutterBackend  *backend,
                                   ClutterStage    *wrapper,
                                   GError         **error)
 {
   ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (backend);
-  ClutterStageEGL   *stage_egl;
-  ClutterActor      *stage;
+  ClutterStageEGL *stage_egl;
+  ClutterStageWindow *stage;
 
-  if (backend_egl->stage)
+  if (G_UNLIKELY (backend_egl->stage != NULL))
     {
-      g_warning ("The EGL native backend does not support multiple stages");
+      g_set_error (error, CLUTTER_INIT_ERROR,
+                   CLUTTER_INIT_ERROR_BACKEND,
+                   "The EGL native backend does not support multiple stages");
       return backend_egl->stage;
     }
 
@@ -116,7 +258,7 @@ clutter_backend_egl_create_stage (ClutterBackend  *backend,
 static void
 clutter_backend_egl_init_events (ClutterBackend *backend)
 {
-  _clutter_events_init (backend);
+  _clutter_events_egl_init (CLUTTER_BACKEND_EGL (backend));
 }
 
 static const GOptionEntry entries[] =
@@ -137,10 +279,23 @@ static void
 clutter_backend_egl_dispose (GObject *gobject)
 {
   ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (gobject);
+  ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (backend_egl->stage);
 
-  _clutter_events_uninit (CLUTTER_BACKEND (backend_egl));
+  _clutter_events_egl_uninit (backend_egl);
 
-  if (backend_egl->egl_context)
+  if (backend_egl->stage != NULL)
+    {
+      clutter_actor_destroy (CLUTTER_ACTOR (stage_egl->wrapper));
+      backend_egl->stage = NULL;
+    }
+
+  if (backend_egl->egl_surface != EGL_NO_SURFACE)
+    {
+      eglDestroySurface (backend_egl->edpy, backend_egl->egl_surface);
+      backend_egl->egl_surface = EGL_NO_SURFACE;
+    }
+
+  if (backend_egl->egl_context != NULL)
     {
       eglDestroyContext (backend_egl->edpy, backend_egl->egl_context);
       backend_egl->egl_context = NULL;
@@ -152,7 +307,7 @@ clutter_backend_egl_dispose (GObject *gobject)
       backend_egl->edpy = 0;
     }
 
-  if (backend_egl->event_timer)
+  if (backend_egl->event_timer != NULL)
     {
       g_timer_destroy (backend_egl->event_timer);
       backend_egl->event_timer = NULL;
@@ -190,6 +345,8 @@ clutter_backend_egl_get_features (ClutterBackend *backend)
 {
   ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (backend);
 
+  g_assert (backend_egl->egl_context != NULL);
+
   CLUTTER_NOTE (BACKEND, "Checking features\n"
                 "GL_VENDOR: %s\n"
                 "GL_RENDERER: %s\n"
@@ -221,6 +378,7 @@ clutter_backend_egl_class_init (ClutterBackendEGLClass *klass)
   backend_class->post_parse       = clutter_backend_egl_post_parse;
   backend_class->init_events      = clutter_backend_egl_init_events;
   backend_class->create_stage     = clutter_backend_egl_create_stage;
+  backend_class->create_context   = clutter_backend_egl_create_context;
   backend_class->ensure_context   = clutter_backend_egl_ensure_context;
   backend_class->redraw           = clutter_backend_egl_redraw;
   backend_class->get_features     = clutter_backend_egl_get_features;
index b802495..9731d79 100644 (file)
@@ -1,7 +1,10 @@
 /* Clutter.
  * An OpenGL based 'interactive canvas' library.
+ *
  * Authored By Matthew Allum  <mallum@openedhand.com>
- * Copyright (C) 2006-2007 OpenedHand
+ *
+ * Copyright (C) 2006, 2007, 2008 OpenedHand
+ * Copyright (C) 2009, 2010 Intel Corp
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -38,7 +41,6 @@ G_BEGIN_DECLS
 typedef struct _ClutterBackendEGL       ClutterBackendEGL;
 typedef struct _ClutterBackendEGLClass  ClutterBackendEGLClass;
 
-
 struct _ClutterBackendEGL
 {
   ClutterBackend parent_instance;
@@ -48,11 +50,15 @@ struct _ClutterBackendEGL
   EGLSurface egl_surface;
   EGLContext egl_context;
 
-  gint       egl_version_major;
-  gint       egl_version_minor;
+  /* from the backend */
+  gint surface_width;
+  gint surface_height;
+
+  gint egl_version_major;
+  gint egl_version_minor;
 
   /* main stage singleton */
-  ClutterActor *stage;
+  ClutterStageWindow *stage;
 
   /* event source */
   GSource *event_source;
@@ -70,8 +76,8 @@ struct _ClutterBackendEGLClass
 
 GType clutter_backend_egl_get_type (void) G_GNUC_CONST;
 
-void _clutter_events_init (ClutterBackend *backend);
-void _clutter_events_uninit (ClutterBackend *backend);
+void _clutter_events_egl_init (ClutterBackendEGL *backend);
+void _clutter_events_egl_uninit (ClutterBackendEGL *backend);
 
 G_END_DECLS
 
index dc9f390..56732c4 100644 (file)
@@ -47,8 +47,9 @@ struct _ClutterEventSource
 {
   GSource source;
 
-  ClutterBackend *backend;
-  GPollFD         event_poll_fd;
+  ClutterBackendEGL *backend;
+  GPollFD event_poll_fd;
+
 #ifdef HAVE_TSLIB
   struct tsdev   *ts_device;
 #endif
@@ -71,7 +72,7 @@ static GSourceFuncs event_funcs = {
 };
 
 static GSource *
-clutter_event_source_new (ClutterBackend *backend)
+clutter_event_source_new (ClutterBackendEGL *backend)
 {
   GSource *source = g_source_new (&event_funcs, sizeof (ClutterEventSource));
   ClutterEventSource *event_source = (ClutterEventSource *) source;
@@ -92,36 +93,45 @@ get_backend_time (void)
 }
 
 void
-_clutter_events_init (ClutterBackend *backend)
+_clutter_events_egl_init (ClutterBackendEGL *backend_egl)
 {
-  ClutterBackendEGL  *backend_egl = CLUTTER_BACKEND_EGL (backend);
-  GSource            *source;
   ClutterEventSource *event_source;
+  const char *device_name;
+  GSource *source;
 
   CLUTTER_NOTE (EVENT, "Starting timer");
   g_assert (backend_egl->event_timer != NULL);
   g_timer_start (backend_egl->event_timer);
 
 #ifdef HAVE_TSLIB
-  /* FIXME LEAK on error paths */
-  source = backend_egl->event_source = clutter_event_source_new (backend);
+  source = backend_egl->event_source = clutter_event_source_new (backend_egl);
   event_source = (ClutterEventSource *) source;
 
-  event_source->ts_device = ts_open (g_getenv ("TSLIB_TSDEVICE"), 0);
+  device_name = g_getenv ("TSLIB_TSDEVICE");
+  if (device_name == NULL || device_name[0] == '\0')
+    {
+      g_warning ("No device for TSLib has been defined; please set the "
+                 "TSLIB_TSDEVICE environment variable to define a touch "
+                 "screen device to be used with Clutter.");
+      g_source_unref (source);
+      return;
+    }
 
+  event_source->ts_device = ts_open (device_name, 0);
   if (event_source->ts_device)
     {
-      CLUTTER_NOTE (EVENT, "Opened '%s'", g_getenv ("TSLIB_TSDEVICE"));
+      CLUTTER_NOTE (EVENT, "Opened '%s'", device_name);
 
       if (ts_config (event_source->ts_device))
        {
-         g_warning ("ts_config() failed");
+         g_warning ("Closing device '%s': ts_config() failed", device_name);
          ts_close (event_source->ts_device);
+          g_source_unref (source);
          return;
        }
 
       g_source_set_priority (source, CLUTTER_PRIORITY_EVENTS);
-      event_source->event_poll_fd.fd = ts_fd(event_source->ts_device);
+      event_source->event_poll_fd.fd = ts_fd (event_source->ts_device);
       event_source->event_poll_fd.events = G_IO_IN;
 
       event_sources = g_list_prepend (event_sources, event_source);
@@ -131,24 +141,25 @@ _clutter_events_init (ClutterBackend *backend)
       g_source_attach (source, NULL);
     }
   else
-    g_warning ("ts_open() failed opening %s'",
-              g_getenv("TSLIB_TSDEVICE") ?
-                g_getenv("TSLIB_TSDEVICE") : "None, TSLIB_TSDEVICE not set");
-#endif
+    {
+      g_warning ("Unable to open '%s'", device_name);
+      g_source_unref (source);
+    }
+#endif /* HAVE_TSLIB */
 }
 
 void
-_clutter_events_uninit (ClutterBackend *backend)
+_clutter_events_egl_uninit (ClutterBackend *backend)
 {
   ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (backend);
 
-  if (backend_egl->event_timer)
+  if (backend_egl->event_timer != NULL)
     {
       CLUTTER_NOTE (EVENT, "Stopping the timer");
       g_timer_stop (backend_egl->event_timer);
     }
 
-  if (backend_egl->event_source)
+  if (backend_egl->event_source != NULL)
     {
       CLUTTER_NOTE (EVENT, "Destroying the event source");
 
@@ -157,9 +168,9 @@ _clutter_events_uninit (ClutterBackend *backend)
 
 #ifdef HAVE_TSLIB
       ts_close (event_source->ts_device);
-      event_sources = g_list_remove (event_sources,
-                                     backend_egl->event_source);
-#endif
+      event_sources = g_list_remove (event_sources, backend_egl->event_source);
+#endif /* HAVE_TSLIB */
+
       g_source_destroy (backend_egl->event_source);
       g_source_unref (backend_egl->event_source);
       backend_egl->event_source = NULL;
@@ -225,7 +236,8 @@ clutter_event_dispatch (GSource     *source,
         (ts_read(event_source->ts_device, &tsevent, 1) == 1))
     {
       /* Avoid sending too many events which are just pressure changes.
-       * We dont current handle pressure in events (FIXME) and thus
+       *
+       * FIXME - We don't current handle pressure in events and thus
        * event_button_generate gets confused generating lots of double
        * and triple clicks.
       */
@@ -266,7 +278,7 @@ clutter_event_dispatch (GSource     *source,
 
       g_queue_push_head (clutter_context->events_queue, event);
     }
-#endif
+#endif /* HAVE_TSLIB */
 
   /* Pop an event off the queue if any */
   event = clutter_event_get ();
index 8d728f2..0a0dec0 100644 (file)
@@ -22,263 +22,108 @@ static void clutter_stage_window_iface_init (ClutterStageWindowIface *iface);
 
 G_DEFINE_TYPE_WITH_CODE (ClutterStageEGL,
                          clutter_stage_egl,
-                         CLUTTER_TYPE_ACTOR,
+                         G_TYPE_OBJECT,
                          G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW,
                                                 clutter_stage_window_iface_init));
 
 static void
-clutter_stage_egl_show (ClutterActor *actor)
+clutter_stage_egl_class_init (ClutterStageEGLClass *klass)
 {
-  CLUTTER_ACTOR_SET_FLAGS (actor, CLUTTER_ACTOR_MAPPED);
-  CLUTTER_ACTOR_SET_FLAGS (CLUTTER_STAGE_EGL (actor)->wrapper,
-                           CLUTTER_ACTOR_MAPPED);
 }
 
 static void
-clutter_stage_egl_hide (ClutterActor *actor)
+clutter_stage_egl_set_fullscreen (ClutterStageWindow *stage_window,
+                                  gboolean            fullscreen)
 {
-  CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_MAPPED);
-  CLUTTER_ACTOR_UNSET_FLAGS (CLUTTER_STAGE_EGL (actor)->wrapper,
-                             CLUTTER_ACTOR_MAPPED);
+  g_warning ("Stage of type '%s' do not support ClutterStage::set_fullscreen",
+             G_OBJECT_TYPE_NAME (stage_window));
 }
 
 static void
-clutter_stage_egl_unrealize (ClutterActor *actor)
+clutter_stage_egl_set_title (ClutterStageWindow *stage_window,
+                             const gchar        *title)
 {
-  ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (actor);
-
-  CLUTTER_MARK();
-
-  if (CLUTTER_ACTOR_CLASS (clutter_stage_egl_parent_class)->unrealize != NULL)
-    CLUTTER_ACTOR_CLASS (clutter_stage_egl_parent_class)->unrealize (actor);
-
-  if (stage_egl->egl_surface)
-    {
-      eglDestroySurface (clutter_egl_display (), stage_egl->egl_surface);
-      stage_egl->egl_surface = EGL_NO_SURFACE;
-    }
+  g_warning ("Stage of type '%s' do not support ClutterStage::set_title",
+             G_OBJECT_TYPE_NAME (stage_window));
 }
 
 static void
-clutter_stage_egl_realize (ClutterActor *actor)
+clutter_stage_egl_set_cursor_visible (ClutterStageWindow *stage_window,
+                                      gboolean            cursor_visible)
 {
-  ClutterStageEGL     *stage_egl = CLUTTER_STAGE_EGL (actor);
-  ClutterBackendEGL   *backend_egl;
-  EGLConfig            configs[2];
-  EGLint               config_count;
-  EGLBoolean           status;
-  EGLint cfg_attribs[] = { EGL_BUFFER_SIZE,     EGL_DONT_CARE,
-                           EGL_RED_SIZE,        5,
-                           EGL_GREEN_SIZE,      6,
-                           EGL_BLUE_SIZE,       5,
-                           EGL_DEPTH_SIZE,      16,
-                           EGL_ALPHA_SIZE,      EGL_DONT_CARE,
-                           EGL_STENCIL_SIZE,    2,
-#ifdef HAVE_COGL_GLES2
-                           EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-#else /* HAVE_COGL_GLES2 */
-                           EGL_SURFACE_TYPE,    EGL_WINDOW_BIT,
-#endif /* HAVE_COGL_GLES2 */
-                           EGL_NONE };
-
-  CLUTTER_NOTE (BACKEND, "Realizing main stage");
-
-  backend_egl = CLUTTER_BACKEND_EGL (clutter_get_default_backend ());
-
-  status = eglGetConfigs (backend_egl->edpy,
-                          configs,
-                          2,
-                          &config_count);
-
-  if (status != EGL_TRUE)
-    {
-      g_critical ("eglGetConfigs failed");
-      CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
-      return;
-    }
-
-  status = eglChooseConfig (backend_egl->edpy,
-                            cfg_attribs,
-                            configs,
-                            G_N_ELEMENTS (configs),
-                            &config_count);
-
-  if (status != EGL_TRUE)
-    {
-      g_critical ("eglChooseConfig failed");
-      CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
-      return;
-    }
-
-  CLUTTER_NOTE (BACKEND, "Got %i configs", config_count);
-
-  if (stage_egl->egl_surface != EGL_NO_SURFACE)
-    {
-      eglDestroySurface (backend_egl->edpy, stage_egl->egl_surface);
-      stage_egl->egl_surface = EGL_NO_SURFACE;
-    }
-
-   if (backend_egl->egl_context)
-     {
-        eglDestroyContext (backend_egl->edpy, backend_egl->egl_context);
-        backend_egl->egl_context = NULL;
-     }
-
-  stage_egl->egl_surface =
-    eglCreateWindowSurface (backend_egl->edpy,
-                            configs[0],
-                            NULL,
-                            NULL);
-
-  if (stage_egl->egl_surface == EGL_NO_SURFACE)
-    {
-      g_critical ("Unable to create an EGL surface");
-
-      CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
-      return;
-    }
-
-  eglQuerySurface (backend_egl->edpy,
-                   stage_egl->egl_surface,
-                   EGL_WIDTH,
-                   &stage_egl->surface_width);
-
-  eglQuerySurface (backend_egl->edpy,
-                   stage_egl->egl_surface,
-                   EGL_HEIGHT,
-                   &stage_egl->surface_height);
-
-  CLUTTER_NOTE (BACKEND, "EGL surface is %ix%i",
-                stage_egl->surface_width,
-                stage_egl->surface_height);
-
-
-  if (G_UNLIKELY (backend_egl->egl_context == NULL))
-    {
-#ifdef HAVE_COGL_GLES2
-      static const EGLint attribs[3]
-        = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
-
-      backend_egl->egl_context = eglCreateContext (backend_egl->edpy,
-                                                   configs[0],
-                                                   EGL_NO_CONTEXT,
-                                                   attribs);
-#else
-      /* Seems some GLES implementations 1.x do not like attribs... */
-      backend_egl->egl_context = eglCreateContext (backend_egl->edpy,
-                                                   configs[0],
-                                                   EGL_NO_CONTEXT,
-                                                   NULL);
-#endif
-
-      if (backend_egl->egl_context == EGL_NO_CONTEXT)
-        {
-          g_critical ("Unable to create a suitable EGL context");
-
-          CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
-          return;
-        }
-
-      CLUTTER_NOTE (GL, "Created EGL Context");
-    }
-
-  CLUTTER_NOTE (BACKEND, "Setting context");
-
-  /* eglnative can have only one stage */
-  status = eglMakeCurrent (backend_egl->edpy,
-                           stage_egl->egl_surface,
-                           stage_egl->egl_surface,
-                           backend_egl->egl_context);
-
-  if (status != EGL_TRUE)
-    {
-      g_critical ("eglMakeCurrent failed");
-
-      CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
-      return;
-    }
+  g_warning ("Stage of type '%s' do not support ClutterStage::set_cursor_visible",
+             G_OBJECT_TYPE_NAME (stage_window));
+}
 
-  /* since we only have one size and it cannot change, we
-   * just need to update the GL viewport now that we have
-   * been realized
-   */
-  CLUTTER_SET_PRIVATE_FLAGS (actor, CLUTTER_ACTOR_SYNC_MATRICES);
+static ClutterActor *
+clutter_stage_egl_get_wrapper (ClutterStageWindow *stage_window)
+{
+  return CLUTTER_ACTOR (CLUTTER_STAGE_EGL (stage_window)->wrapper);
 }
 
 static void
-clutter_stage_egl_get_preferred_width (ClutterActor *self,
-                                       gfloat        for_height,
-                                       gfloat       *min_width_p,
-                                       gfloat       *natural_width_p)
+clutter_stage_egl_show (ClutterStageWindow *stage_window,
+                        gboolean            do_raise)
 {
-  ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (self);
-
-  if (min_width_p)
-    *min_width_p = CLUTTER_UNITS_FROM_DEVICE (stage_egl->surface_width);
+  ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (stage_window);
 
-  if (natural_width_p)
-    *natural_width_p = CLUTTER_UNITS_FROM_DEVICE (stage_egl->surface_width);
+  clutter_actor_map (CLUTTER_ACTOR (stage_egl->wrapper));
 }
 
 static void
-clutter_stage_egl_get_preferred_height (ClutterActor *self,
-                                        gfloat        for_width,
-                                        gfloat       *min_height_p,
-                                        gfloat       *natural_height_p)
+clutter_stage_egl_hide (ClutterStageWindow *stage_window)
 {
-  ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (self);
-
-  if (min_height_p)
-    *min_height_p = CLUTTER_UNITS_FROM_DEVICE (stage_egl->surface_height);
+  ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (stage_window);
 
-  if (natural_height_p)
-    *natural_height_p = CLUTTER_UNITS_FROM_DEVICE (stage_egl->surface_height);
+  clutter_actor_unmap (CLUTTER_ACTOR (stage_egl->wrapper));
 }
 
 static void
-clutter_stage_egl_dispose (GObject *gobject)
+clutter_stage_egl_unrealize (ClutterStageWindow *stage_window)
 {
-  ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (gobject);
+}
 
-  G_OBJECT_CLASS (clutter_stage_egl_parent_class)->dispose (gobject);
+static gboolean
+clutter_stage_egl_realize (ClutterStageWindow *stage_window)
+{
+  /* the EGL surface is created by the backend */
+  return TRUE;
 }
 
 static void
-clutter_stage_egl_class_init (ClutterStageEGLClass *klass)
+clutter_stage_egl_get_geometry (ClutterStageWindow *stage_window,
+                                ClutterGeometry    *geometry)
 {
-  GObjectClass      *gobject_class = G_OBJECT_CLASS (klass);
-  ClutterActorClass *actor_class   = CLUTTER_ACTOR_CLASS (klass);
+  ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (stage_window);
+  ClutterBackendEGL *backend_egl = stage_egl->backend;
 
-  gobject_class->dispose = clutter_stage_egl_dispose;
+  if (geometry)
+    {
+      geometry->x = geometry->y = 0;
 
-  actor_class->show                 = clutter_stage_egl_show;
-  actor_class->hide                 = clutter_stage_egl_hide;
-  actor_class->realize              = clutter_stage_egl_realize;
-  actor_class->unrealize            = clutter_stage_egl_unrealize;
-  actor_class->get_preferred_width  = clutter_stage_egl_get_preferred_width;
-  actor_class->get_preferred_height = clutter_stage_egl_get_preferred_height;
+      geometry->width = backend_egl->surface_width;
+      geometry->height = backend_egl->surface_height;
+    }
 }
 
 static void
-clutter_stage_egl_set_fullscreen (ClutterStageWindow *stage_window,
-                                  gboolean            fullscreen)
+clutter_stage_egl_resize (ClutterStageWindow *stage_window,
+                          gint                width,
+                          gint                height)
 {
-  g_warning ("Stage of type '%s' do not support ClutterStage::set_fullscreen",
-             G_OBJECT_TYPE_NAME (stage_window));
-}
-
-static ClutterActor *
-clutter_stage_egl_get_wrapper (ClutterStageWindow *stage_window)
-{
-  return CLUTTER_ACTOR (CLUTTER_STAGE_EGL (stage_window)->wrapper);
 }
 
 static void
 clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
 {
   iface->set_fullscreen = clutter_stage_egl_set_fullscreen;
-  iface->set_title = NULL;
+  iface->set_title = clutter_stage_egl_set_title;
+  iface->set_cursor_visible = clutter_stage_egl_set_cursor_visible;
   iface->get_wrapper = clutter_stage_egl_get_wrapper;
+  iface->realize = clutter_stage_egl_realize;
+  iface->unrealize = clutter_stage_egl_unrealize;
+  iface->get_geometry = clutter_stage_egl_get_geometry;
+  iface->resize = clutter_stage_egl_resize;
 }
 
 static void
index 9141d67..49a6c79 100644 (file)
@@ -21,14 +21,10 @@ struct _ClutterStageEGL
 {
   ClutterActor parent_instance;
 
-  /* from the backend */
-  gint         surface_width;
-  gint         surface_height;
-
-  EGLSurface   egl_surface;
-
   /* the stage wrapper */
   ClutterStage      *wrapper;
+
+  /* back pointer to the backend */
   ClutterBackendEGL *backend;
 };