Merge branch 'eglnative-update'

* eglnative-update:
  eglnative: Add CLUTTER_FB_DEVICE
  eglnative: Update implementation
This commit is contained in:
Emmanuele Bassi 2010-03-02 12:25:45 +00:00
commit 3a84af0106
5 changed files with 349 additions and 280 deletions

View File

@ -2,14 +2,20 @@
#include "config.h"
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "clutter-backend-egl.h"
#include "clutter-stage-egl.h"
#include "../clutter-private.h"
#include "../clutter-main.h"
#include "../clutter-debug.h"
static ClutterBackendEGL *backend_singleton = NULL;
static const gchar *clutter_fb_device = NULL;
G_DEFINE_TYPE (ClutterBackendEGL, clutter_backend_egl, CLUTTER_TYPE_BACKEND);
@ -24,6 +30,12 @@ static gboolean
clutter_backend_egl_pre_parse (ClutterBackend *backend,
GError **error)
{
const gchar *env_string;
env_string = g_getenv ("CLUTTER_FB_DEVICE");
if (env_string != NULL && env_string[0] != '\0')
clutter_fb_device = g_strdup (env_string);
return TRUE;
}
@ -61,7 +73,176 @@ 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;
}
if (clutter_fb_device != NULL)
{
int fd = open (clutter_fb_device, O_RDWR);
if (fd < 0)
{
int errno_save = errno;
g_set_error (error, CLUTTER_INIT_ERROR,
CLUTTER_INIT_ERROR_BACKEND,
"Unable to open the framebuffer device '%s': %s",
clutter_fb_device,
g_strerror (errno_save));
return FALSE;
}
else
backend_egl->fb_device_id = fd;
backend_egl->egl_surface =
eglCreateWindowSurface (backend_egl->edpy,
configs[0],
(NativeWindowType) backend_egl->fb_device_id,
NULL);
}
else
{
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 +254,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 +299,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 +320,29 @@ 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->fb_device_id != -1)
{
close (backend_egl->fb_device_id);
backend_egl->fb_device_id = -1;
}
if (backend_egl->egl_context != NULL)
{
eglDestroyContext (backend_egl->edpy, backend_egl->egl_context);
backend_egl->egl_context = NULL;
@ -152,7 +354,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 +392,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 +425,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;
@ -236,6 +441,8 @@ clutter_backend_egl_init (ClutterBackendEGL *backend_egl)
clutter_backend_set_double_click_distance (backend, 5);
backend_egl->event_timer = g_timer_new ();
backend_egl->fb_device_id = -1;
}
GType

View 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;
@ -60,6 +66,9 @@ struct _ClutterBackendEGL
/* event timer */
GTimer *event_timer;
/* FB device */
gint fb_device_id;
/*< private >*/
};
@ -70,8 +79,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

View 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 ();

View File

@ -22,241 +22,13 @@ 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_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_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_MAPPED);
CLUTTER_ACTOR_UNSET_FLAGS (CLUTTER_STAGE_EGL (actor)->wrapper,
CLUTTER_ACTOR_MAPPED);
}
static void
clutter_stage_egl_unrealize (ClutterActor *actor)
{
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;
}
}
static void
clutter_stage_egl_realize (ClutterActor *actor)
{
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;
}
/* 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 void
clutter_stage_egl_get_preferred_width (ClutterActor *self,
gfloat for_height,
gfloat *min_width_p,
gfloat *natural_width_p)
{
ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (self);
if (min_width_p)
*min_width_p = CLUTTER_UNITS_FROM_DEVICE (stage_egl->surface_width);
if (natural_width_p)
*natural_width_p = CLUTTER_UNITS_FROM_DEVICE (stage_egl->surface_width);
}
static void
clutter_stage_egl_get_preferred_height (ClutterActor *self,
gfloat for_width,
gfloat *min_height_p,
gfloat *natural_height_p)
{
ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (self);
if (min_height_p)
*min_height_p = CLUTTER_UNITS_FROM_DEVICE (stage_egl->surface_height);
if (natural_height_p)
*natural_height_p = CLUTTER_UNITS_FROM_DEVICE (stage_egl->surface_height);
}
static void
clutter_stage_egl_dispose (GObject *gobject)
{
ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (gobject);
G_OBJECT_CLASS (clutter_stage_egl_parent_class)->dispose (gobject);
}
static void
clutter_stage_egl_class_init (ClutterStageEGLClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
gobject_class->dispose = clutter_stage_egl_dispose;
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;
}
static void
@ -267,18 +39,91 @@ clutter_stage_egl_set_fullscreen (ClutterStageWindow *stage_window,
G_OBJECT_TYPE_NAME (stage_window));
}
static void
clutter_stage_egl_set_title (ClutterStageWindow *stage_window,
const gchar *title)
{
g_warning ("Stage of type '%s' do not support ClutterStage::set_title",
G_OBJECT_TYPE_NAME (stage_window));
}
static void
clutter_stage_egl_set_cursor_visible (ClutterStageWindow *stage_window,
gboolean cursor_visible)
{
g_warning ("Stage of type '%s' do not support ClutterStage::set_cursor_visible",
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_egl_show (ClutterStageWindow *stage_window,
gboolean do_raise)
{
ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (stage_window);
clutter_actor_map (CLUTTER_ACTOR (stage_egl->wrapper));
}
static void
clutter_stage_egl_hide (ClutterStageWindow *stage_window)
{
ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (stage_window);
clutter_actor_unmap (CLUTTER_ACTOR (stage_egl->wrapper));
}
static void
clutter_stage_egl_unrealize (ClutterStageWindow *stage_window)
{
}
static gboolean
clutter_stage_egl_realize (ClutterStageWindow *stage_window)
{
/* the EGL surface is created by the backend */
return TRUE;
}
static void
clutter_stage_egl_get_geometry (ClutterStageWindow *stage_window,
ClutterGeometry *geometry)
{
ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (stage_window);
ClutterBackendEGL *backend_egl = stage_egl->backend;
if (geometry)
{
geometry->x = geometry->y = 0;
geometry->width = backend_egl->surface_width;
geometry->height = backend_egl->surface_height;
}
}
static void
clutter_stage_egl_resize (ClutterStageWindow *stage_window,
gint width,
gint height)
{
}
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

View 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;
};