2007-07-06 Matthew Allum <mallum@openedhand.com>

* clutter/Makefile.am:
        * clutter/eglnative/Makefile.am:
        * clutter/eglnative/clutter-backend-egl.c:
        * clutter/eglnative/clutter-backend-egl.h:
        * clutter/eglnative/clutter-egl.h:
        * clutter/eglnative/clutter-event-egl.c:
        * clutter/eglnative/clutter-stage-egl.c:
        * clutter/eglnative/clutter-stage-egl.h:
        * clutter/eglx/Makefile.am:
        * clutter/eglx/clutter-backend-egl.c:
        * clutter/eglx/clutter-egl.h:
        * clutter/eglx/clutter-event-egl.c:
        * clutter/eglx/clutter-stage-egl.c:
        * configure.ac:
        Add a new 'native' EGL backend for non X based EGL's
        (i.e on framebuffer).
        Rename old backend to 'eglx' and namespace public funcs with this.

        * clutter/pango/pangoclutter-private.h:
        Add extra checks for expected defines.
This commit is contained in:
Matthew Allum 2007-07-06 13:56:01 +00:00
parent bbdcf5542b
commit 051a76c155
16 changed files with 913 additions and 70 deletions

View File

@ -1,3 +1,26 @@
2007-07-06 Matthew Allum <mallum@openedhand.com>
* clutter/Makefile.am:
* clutter/eglnative/Makefile.am:
* clutter/eglnative/clutter-backend-egl.c:
* clutter/eglnative/clutter-backend-egl.h:
* clutter/eglnative/clutter-egl.h:
* clutter/eglnative/clutter-event-egl.c:
* clutter/eglnative/clutter-stage-egl.c:
* clutter/eglnative/clutter-stage-egl.h:
* clutter/eglx/Makefile.am:
* clutter/eglx/clutter-backend-egl.c:
* clutter/eglx/clutter-egl.h:
* clutter/eglx/clutter-event-egl.c:
* clutter/eglx/clutter-stage-egl.c:
* configure.ac:
Add a new 'native' EGL backend for non X based EGL's
(i.e on framebuffer).
Rename old backend to 'eglx' and namespace public funcs with this.
* clutter/pango/pangoclutter-private.h:
Add extra checks for expected defines.
2007-07-06 Matthew Allum <mallum@openedhand.com> 2007-07-06 Matthew Allum <mallum@openedhand.com>
* NEWS: * NEWS:

View File

@ -2,7 +2,7 @@ NULL =
SUBDIRS = cogl pango $(clutterbackend) SUBDIRS = cogl pango $(clutterbackend)
DIST_SUBDIRS = pango glx egl cogl sdl DIST_SUBDIRS = pango glx eglx eglnative cogl sdl
target = $(clutterbackend) target = $(clutterbackend)

View File

@ -0,0 +1,19 @@
libclutterincludedir = $(includedir)/clutter-@CLUTTER_MAJORMINOR@/clutter
INCLUDES = \
-DG_LOG_DOMAIN=\"ClutterEGL\" \
-I$(top_srcdir) \
$(CLUTTER_CFLAGS) \
$(CLUTTER_DEBUG_CFLAGS) \
$(GCC_FLAGS)
LDADD = $(CLUTTER_LIBS)
noinst_LTLIBRARIES = libclutter-eglnative.la
libclutter_eglnative_la_SOURCES = \
clutter-backend-egl.h \
clutter-backend-egl.c \
clutter-event-egl.c \
clutter-stage-egl.h \
clutter-stage-egl.c

View File

@ -0,0 +1,212 @@
#include "config.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;
G_DEFINE_TYPE (ClutterBackendEGL, clutter_backend_egl, CLUTTER_TYPE_BACKEND);
static gboolean
clutter_backend_egl_pre_parse (ClutterBackend *backend,
GError **error)
{
return TRUE;
}
static gboolean
clutter_backend_egl_post_parse (ClutterBackend *backend,
GError **error)
{
backend_egl->edpy = eglGetDisplay(backend_egl->xdpy);
status = eglInitialize(backend_egl->edpy,
&backend_egl->egl_version_major,
&backend_egl->egl_version_minor);
if (status != EGL_TRUE)
{
g_set_error (error, CLUTTER_INIT_ERROR,
CLUTTER_INIT_ERROR_BACKEND,
"Unable to Initialize EGL");
return FALSE;
}
}
CLUTTER_NOTE (BACKEND, "EGL Reports version %i.%i",
backend_egl->egl_version_major,
backend_egl->egl_version_minor);
return TRUE;
}
static gboolean
clutter_backend_egl_init_stage (ClutterBackend *backend,
GError **error)
{
ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (backend);
if (!backend_egl->stage)
{
ClutterStageEGL *stage_egl;
ClutterActor *stage;
stage = g_object_new (CLUTTER_TYPE_STAGE_EGL, NULL);
g_object_set_data (G_OBJECT (stage), "clutter-backend", backend);
backend_egl->stage = g_object_ref_sink (stage);
}
clutter_actor_realize (backend_egl->stage);
if (!CLUTTER_ACTOR_IS_REALIZED (backend_egl->stage))
{
g_set_error (error, CLUTTER_INIT_ERROR,
CLUTTER_INIT_ERROR_INTERNAL,
"Unable to realize the main stage");
return FALSE;
}
return TRUE;
}
static void
clutter_backend_egl_init_events (ClutterBackend *backend)
{
_clutter_events_init (backend);
}
static const GOptionEntry entries[] =
{
{ NULL }
};
static void
clutter_backend_egl_redraw (ClutterBackend *backend)
{
ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (backend);
ClutterStageEGL *stage_egl;
stage_egl = CLUTTER_STAGE_EGL(backend_egl->stage);
clutter_actor_paint (CLUTTER_ACTOR(stage_egl));
/* Why this paint is done in backend as likely GL windowing system
* specific calls, like swapping buffers.
*/
if (stage_egl->xwin)
{
/* clutter_feature_wait_for_vblank (); */
eglSwapBuffers (backend_egl->edpy, stage_egl->egl_surface);
}
else
{
eglWaitGL ();
CLUTTER_GLERR ();
}
}
static ClutterActor *
clutter_backend_egl_get_stage (ClutterBackend *backend)
{
ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (backend);
return backend_egl->stage;
}
static void
clutter_backend_egl_finalize (GObject *gobject)
{
ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (gobject);
if (backend_singleton)
backend_singleton = NULL;
G_OBJECT_CLASS (clutter_backend_egl_parent_class)->finalize (gobject);
}
static void
clutter_backend_egl_dispose (GObject *gobject)
{
ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (gobject);
_clutter_events_uninit (CLUTTER_BACKEND (backend_egl));
if (backend_egl->stage)
{
g_object_unref (backend_egl->stage);
backend_egl->stage = NULL;
}
G_OBJECT_CLASS (clutter_backend_egl_parent_class)->dispose (gobject);
}
static GObject *
clutter_backend_egl_constructor (GType gtype,
guint n_params,
GObjectConstructParam *params)
{
GObjectClass *parent_class;
GObject *retval;
if (!backend_singleton)
{
parent_class = G_OBJECT_CLASS (clutter_backend_egl_parent_class);
retval = parent_class->constructor (gtype, n_params, params);
backend_singleton = CLUTTER_BACKEND_EGL (retval);
return retval;
}
g_warning ("Attempting to create a new backend object. This should "
"never happen, so we return the singleton instance.");
return g_object_ref (backend_singleton);
}
static void
clutter_backend_egl_class_init (ClutterBackendEGLClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
ClutterBackendClass *backend_class = CLUTTER_BACKEND_CLASS (klass);
gobject_class->constructor = clutter_backend_egl_constructor;
gobject_class->dispose = clutter_backend_egl_dispose;
gobject_class->finalize = clutter_backend_egl_finalize;
backend_class->pre_parse = clutter_backend_egl_pre_parse;
backend_class->post_parse = clutter_backend_egl_post_parse;
backend_class->init_stage = clutter_backend_egl_init_stage;
backend_class->init_events = clutter_backend_egl_init_events;
backend_class->get_stage = clutter_backend_egl_get_stage;
backend_class->add_options = clutter_backend_egl_add_options;
backend_class->redraw = clutter_backend_egl_redraw;
}
static void
clutter_backend_egl_init (ClutterBackendEGL *backend_egl)
{
ClutterBackend *backend = CLUTTER_BACKEND (backend_egl);
clutter_backend_set_double_click_time (backend, 250);
clutter_backend_set_double_click_distance (backend, 5);
}
GType
_clutter_backend_impl_get_type (void)
{
return clutter_backend_egl_get_type ();
}
EGLDisplay
clutter_egl_display (void)
{
return (EGLDisplay)clutter_egl_get_default_display ();
}

View File

@ -0,0 +1,72 @@
/* Clutter.
* An OpenGL based 'interactive canvas' library.
* Authored By Matthew Allum <mallum@openedhand.com>
* Copyright (C) 2006-2007 OpenedHand
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __CLUTTER_BACKEND_EGL_H__
#define __CLUTTER_BACKEND_EGL_H__
#include <glib-object.h>
#include <clutter/clutter-backend.h>
#include <GLES/gl.h>
#include <GLES/egl.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_BACKEND_EGL (clutter_backend_egl_get_type ())
#define CLUTTER_BACKEND_EGL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BACKEND_EGL, ClutterBackendEGL))
#define CLUTTER_IS_BACKEND_EGL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BACKEND_EGL))
#define CLUTTER_BACKEND_EGL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BACKEND_EGL, ClutterBackendEGLClass))
#define CLUTTER_IS_BACKEND_EGL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BACKEND_EGL))
#define CLUTTER_BACKEND_EGL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BACKEND_EGL, ClutterBackendEGLClass))
typedef struct _ClutterBackendEGL ClutterBackendEGL;
typedef struct _ClutterBackendEGLClass ClutterBackendEGLClass;
struct _ClutterBackendEGL
{
ClutterBackend parent_instance;
/* EGL Specific */
EGLDisplay edpy;
gint egl_version_major, egl_version_minor;
/* main stage singleton */
ClutterActor *stage;
/* event source */
GSource *event_source;
/*< private >*/
};
struct _ClutterBackendEGLClass
{
ClutterBackendClass parent_class;
};
GType clutter_backend_egl_get_type (void) G_GNUC_CONST;
void _clutter_events_init (ClutterBackend *backend);
void _clutter_events_uninit (ClutterBackend *backend);
G_END_DECLS
#endif /* __CLUTTER_BACKEND_EGL_H__ */

View File

@ -0,0 +1,43 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Authored By Matthew Allum <mallum@openedhand.com>
*
* Copyright (C) 2006 OpenedHand
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __CLUTTER_EGL_H__
#define __CLUTTER_EGL_H__
#include <glib.h>
#include <GLES/gl.h>
#include <GLES/egl.h>
#include <clutter/clutter-stage.h>
G_BEGIN_DECLS
EGLDisplay
clutter_egl_display (void);
G_END_DECLS
#endif /* __CLUTTER_EGL_H__ */

View File

@ -0,0 +1,121 @@
/* Clutter.
* An OpenGL based 'interactive canvas' library.
* Authored By Matthew Allum <mallum@openedhand.com>
* Copyright (C) 2006-2007 OpenedHand
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include "clutter-stage-egl.h"
#include "clutter-backend-egl.h"
#include "clutter-egl.h"
#include "../clutter-backend.h"
#include "../clutter-event.h"
#include "../clutter-private.h"
#include "../clutter-debug.h"
#include "../clutter-main.h"
#include <string.h>
#include <glib.h>
typedef struct _ClutterEventSource ClutterEventSource;
struct _ClutterEventSource
{
GSource source;
ClutterBackend *backend;
GPollFD event_poll_fd;
};
static gboolean clutter_event_prepare (GSource *source,
gint *timeout);
static gboolean clutter_event_check (GSource *source);
static gboolean clutter_event_dispatch (GSource *source,
GSourceFunc callback,
gpointer user_data);
static GList *event_sources = NULL;
static GSourceFuncs event_funcs = {
clutter_event_prepare,
clutter_event_check,
clutter_event_dispatch,
NULL
};
static GSource *
clutter_event_source_new (ClutterBackend *backend)
{
GSource *source = g_source_new (&event_funcs, sizeof (ClutterEventSource));
ClutterEventSource *event_source = (ClutterEventSource *) source;
event_source->backend = backend;
return source;
}
void
_clutter_events_init (ClutterBackend *backend)
{
GSource *source;
ClutterEventSource *event_source;
ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (backend);
#if 0
int connection_number;
connection_number = ConnectionNumber (backend_egl->xdpy);
CLUTTER_NOTE (EVENT, "Connection number: %d", connection_number);
source = backend_egl->event_source = clutter_event_source_new (backend);
event_source = (ClutterEventSource *) source;
g_source_set_priority (source, CLUTTER_PRIORITY_EVENTS);
event_source->event_poll_fd.fd = connection_number;
event_source->event_poll_fd.events = G_IO_IN;
event_sources = g_list_prepend (event_sources, event_source);
g_source_add_poll (source, &event_source->event_poll_fd);
g_source_set_can_recurse (source, TRUE);
g_source_attach (source, NULL);
#endif
}
void
_clutter_events_uninit (ClutterBackend *backend)
{
ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (backend);
if (backend_egl->event_source)
{
#if 0
CLUTTER_NOTE (EVENT, "Destroying the event source");
event_sources = g_list_remove (event_sources,
backend_egl->event_source);
g_source_destroy (backend_egl->event_source);
g_source_unref (backend_egl->event_source);
#endif
backend_egl->event_source = NULL;
}
}

View File

@ -0,0 +1,263 @@
#include "config.h"
#include "clutter-stage-egl.h"
#include "clutter-egl.h"
#include "../clutter-main.h"
#include "../clutter-feature.h"
#include "../clutter-color.h"
#include "../clutter-util.h"
#include "../clutter-event.h"
#include "../clutter-enum-types.h"
#include "../clutter-private.h"
#include "../clutter-debug.h"
#include "../clutter-units.h"
G_DEFINE_TYPE (ClutterStageEGL, clutter_stage_egl, CLUTTER_TYPE_STAGE);
/* NOTE: EGL implementation needs to provide this function */
extern NativeWindowType createNativeWindow(void);
static void
clutter_stage_egl_show (ClutterActor *actor)
{
ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (actor);
/* we are always shown... */
return;
}
static void
clutter_stage_egl_hide (ClutterActor *actor)
{
ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (actor);
/* we are always shown... */
return;
}
static void
clutter_stage_egl_unrealize (ClutterActor *actor)
{
ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (actor);
gboolean was_offscreen;
CLUTTER_MARK();
g_object_get (actor, "offscreen", &was_offscreen, NULL);
if (stage_egl->egl_surface)
eglDestroySurface (clutter_egl_display(), stage_egl->egl_surface);
stage_egl->egl_surface = NULL;
if (stage_egl->egl_context)
eglDestroyContext (clutter_egl_display(), stage_egl->egl_context);
stage_egl->egl_context = NULL;
eglMakeCurrent (clutter_egl_display(),
EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
stage_egl->egl_context = EGL_NO_CONTEXT;
}
static void
clutter_stage_egl_realize (ClutterActor *actor)
{
ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (actor);
EGLConfig configs[2];
EGLint config_count;
EGLBoolean status;
ClutterPerspective perspective;
gboolean is_offscreen;
CLUTTER_NOTE (BACKEND, "Realizing main stage");
g_object_get (actor, "offscreen", &is_offscreen, NULL);
if (G_LIKELY (!is_offscreen))
{
NativeWindowType window;
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, EGL_DONT_CARE,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_NONE };
status = eglGetConfigs (clutter_egl_display(),
configs,
2,
&config_count);
if (status != EGL_TRUE)
g_warning ("eglGetConfigs");
status = eglChooseConfig (clutter_egl_display(),
cfg_attribs,
configs,
sizeof configs / sizeof configs[0],
&config_count);
if (status != EGL_TRUE)
g_warning ("eglChooseConfig");
if (stage_egl->egl_context)
eglDestroyContext (clutter_egl_display(), stage_egl->egl_context);
if (stage_egl->egl_surface)
eglDestroySurface (clutter_egl_display(), stage_egl->egl_surface);
/* EGL Implementation needs to provide createNativeWindow() */
window = createNativeWindow();
stage_egl->egl_surface
= eglCreateWindowSurface (clutter_egl_display(),
configs[0],
window,
NULL);
eglQuerySurface (clutter_egl_display(),
stage_egl->egl_surface,
EGL_WIDTH,
&stage_egl->surface_width);
eglQuerySurface (clutter_egl_display(),
stage_egl->egl_surface,
EGL_HEIGHT,
&stage_egl->surface_height);
if (stage_egl->egl_surface == EGL_NO_SURFACE)
g_warning ("eglCreateWindowSurface");
CLUTTER_NOTE (BACKEND, "surface is %ix%i",
stage_egl->surface_width, stage_egl->surface_height);
stage_egl->egl_context = eglCreateContext (clutter_egl_display(),
configs[0],
EGL_NO_CONTEXT,
NULL);
if (stage_egl->egl_context == EGL_NO_CONTEXT)
g_warning ("eglCreateContext");
status = eglMakeCurrent (clutter_egl_display(),
stage_egl->egl_surface,
stage_egl->egl_surface,
stage_egl->egl_context);
if (status != EGL_TRUE)
g_warning ("eglMakeCurrent");
}
else
{
/* FIXME */
}
clutter_stage_get_perspectivex (CLUTTER_STAGE (actor), &perspective);
cogl_setup_viewport (clutter_actor_get_width (actor),
clutter_actor_get_height (actor),
perspective.fovy,
perspective.aspect,
perspective.z_near,
perspective.z_far);
}
static void
clutter_stage_egl_query_coords (ClutterActor *self,
ClutterActorBox *box)
{
ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (self);
box->x1 = box->y1 = 0;
box->x2 = box->x1 + CLUTTER_UNITS_FROM_INT (stage_egl->surface_width);
box->y2 = box->y1 + CLUTTER_UNITS_FROM_INT (stage_egl->surface_height);
}
static void
clutter_stage_egl_request_coords (ClutterActor *self,
ClutterActorBox *box)
{
ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (self);
/* framebuffer no resize */
box->x1 = 0;
box->y1 = 0;
box->x2 = CLUTTER_UNITS_FROM_INT (stage_egl->surface_width);
box->y2 = CLUTTER_UNITS_FROM_INT (stage_egl->surface_height);
}
static void
clutter_stage_egl_set_fullscreen (ClutterStage *stage,
gboolean fullscreen)
{
g_warning ("Stage of type `%s' do not support ClutterStage::set_fullscreen",
G_OBJECT_TYPE_NAME (stage));
}
static void
clutter_stage_egl_set_offscreen (ClutterStage *stage,
gboolean offscreen)
{
g_warning ("Stage of type `%s' do not support ClutterStage::set_offscreen",
G_OBJECT_TYPE_NAME (stage));
}
static GdkPixbuf*
clutter_stage_egl_draw_to_pixbuf (ClutterStage *stage,
gint x,
gint y,
gint width,
gint height)
{
g_warning ("Stage of type `%s' do not support ClutterStage::draw_to_pixbuf",
G_OBJECT_TYPE_NAME (stage));
return NULL;
}
static void
clutter_stage_egl_dispose (GObject *gobject)
{
ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (gobject);
clutter_actor_unrealize (CLUTTER_ACTOR (stage_egl));
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);
ClutterStageClass *stage_class = CLUTTER_STAGE_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->request_coords = clutter_stage_egl_request_coords;
actor_class->query_coords = clutter_stage_egl_query_coords;
stage_class->set_fullscreen = clutter_stage_egl_set_fullscreen;
stage_class->set_offscreen = clutter_stage_egl_set_offscreen;
stage_class->draw_to_pixbuf = clutter_stage_egl_draw_to_pixbuf;
}
static void
clutter_stage_egl_init (ClutterStageEGL *stage)
{
;
}

View File

@ -0,0 +1,38 @@
#ifndef __CLUTTER_STAGE_EGL_H__
#define __CLUTTER_STAGE_EGL_H__
#include <glib-object.h>
#include <clutter/clutter-stage.h>
#include <GLES/gl.h>
#include <GLES/egl.h>
#define CLUTTER_TYPE_STAGE_EGL (clutter_stage_egl_get_type ())
#define CLUTTER_STAGE_EGL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_STAGE_EGL, ClutterStageEGL))
#define CLUTTER_IS_STAGE_EGL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_STAGE_EGL))
#define CLUTTER_STAGE_EGL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_STAGE_EGL, ClutterStageEGLClass))
#define CLUTTER_IS_STAGE_EGL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_STAGE_EGL))
#define CLUTTER_STAGE_EGL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_STAGE_EGL, ClutterStageEGLClass))
typedef struct _ClutterStageEGL ClutterStageEGL;
typedef struct _ClutterStageEGLClass ClutterStageEGLClass;
struct _ClutterStageEGL
{
ClutterStage parent_instance;
/* from the backend */
gint surface_width;
gint surface_height;
EGLSurface egl_surface;
EGLContext egl_context;
};
struct _ClutterStageEGLClass
{
ClutterStageClass parent_class;
};
GType clutter_stage_egl_get_type (void) G_GNUC_CONST;
#endif /* __CLUTTER_STAGE_EGL_H__ */

View File

@ -9,9 +9,9 @@ INCLUDES = \
LDADD = $(CLUTTER_LIBS) LDADD = $(CLUTTER_LIBS)
noinst_LTLIBRARIES = libclutter-egl.la noinst_LTLIBRARIES = libclutter-eglx.la
libclutter_egl_la_SOURCES = \ libclutter_eglx_la_SOURCES = \
clutter-backend-egl.h \ clutter-backend-egl.h \
clutter-backend-egl.c \ clutter-backend-egl.c \
clutter-event-egl.c \ clutter-event-egl.c \

View File

@ -305,21 +305,21 @@ error_handler(Display *xdpy,
} }
/** /**
* clutter_egl_trap_x_errors: * clutter_eglx_trap_x_errors:
* *
* FIXME * FIXME
* *
* Since: 0.4 * Since: 0.4
*/ */
void void
clutter_egl_trap_x_errors (void) clutter_eglx_trap_x_errors (void)
{ {
TrappedErrorCode = 0; TrappedErrorCode = 0;
old_error_handler = XSetErrorHandler (error_handler); old_error_handler = XSetErrorHandler (error_handler);
} }
/** /**
* clutter_egl_untrap_x_errors: * clutter_eglx_untrap_x_errors:
* *
* FIXME * FIXME
* *
@ -328,7 +328,7 @@ clutter_egl_trap_x_errors (void)
* Since: 0.4 * Since: 0.4
*/ */
gint gint
clutter_egl_untrap_x_errors (void) clutter_eglx_untrap_x_errors (void)
{ {
XSetErrorHandler (old_error_handler); XSetErrorHandler (old_error_handler);
@ -336,7 +336,7 @@ clutter_egl_untrap_x_errors (void)
} }
/** /**
* clutter_egl_get_default_display: * clutter_eglx_get_default_xdisplay:
* *
* Returns the default X Display * Returns the default X Display
* *
@ -345,7 +345,7 @@ clutter_egl_untrap_x_errors (void)
* Since: 0.4 * Since: 0.4
*/ */
Display * Display *
clutter_egl_get_default_display (void) clutter_eglx_get_default_xdisplay (void)
{ {
if (!backend_singleton) if (!backend_singleton)
{ {
@ -357,7 +357,7 @@ clutter_egl_get_default_display (void)
} }
/** /**
* clutter_egl_get_default_screen: * clutter_eglx_get_default_screen:
* *
* FIXME * FIXME
* *
@ -366,7 +366,7 @@ clutter_egl_get_default_display (void)
* Since: 0.4 * Since: 0.4
*/ */
gint gint
clutter_egl_get_default_screen (void) clutter_eglx_get_default_screen (void)
{ {
if (!backend_singleton) if (!backend_singleton)
{ {
@ -378,7 +378,7 @@ clutter_egl_get_default_screen (void)
} }
/** /**
* clutter_egl_get_default_root_window: * clutter_eglx_get_default_root_window:
* *
* FIXME * FIXME
* *
@ -387,7 +387,7 @@ clutter_egl_get_default_screen (void)
* Since: 0.4 * Since: 0.4
*/ */
Window Window
clutter_egl_get_default_root_window (void) clutter_eglx_get_default_root_window (void)
{ {
if (!backend_singleton) if (!backend_singleton)
{ {
@ -408,7 +408,7 @@ clutter_egl_get_default_root_window (void)
* Since: 0.4 * Since: 0.4
*/ */
EGLDisplay EGLDisplay
clutter_egl_display (void) clutter_eglx_display (void)
{ {
return backend_singleton->edpy; return backend_singleton->edpy;
} }

View File

@ -39,21 +39,21 @@
G_BEGIN_DECLS G_BEGIN_DECLS
void clutter_egl_trap_x_errors (void); void clutter_eglx_trap_x_errors (void);
gint clutter_egl_untrap_x_errors (void); gint clutter_eglx_untrap_x_errors (void);
Display *clutter_egl_get_default_display (void); Display *clutter_eglx_get_default_xdisplay (void);
gint clutter_egl_get_default_screen (void); gint clutter_eglx_get_default_screen (void);
Window clutter_egl_get_default_root_window (void); Window clutter_eglx_get_default_root_window (void);
Window clutter_egl_get_stage_window (ClutterStage *stage); Window clutter_eglx_get_stage_window (ClutterStage *stage);
XVisualInfo *clutter_egl_get_stage_visual (ClutterStage *stage); XVisualInfo *clutter_eglx_get_stage_visual (ClutterStage *stage);
void clutter_egl_set_stage_foreign (ClutterStage *stage, void clutter_eglx_set_stage_foreign (ClutterStage *stage,
Window window); Window window);
EGLDisplay EGLDisplay
clutter_egl_display (void); clutter_eglx_display (void);
G_END_DECLS G_END_DECLS

View File

@ -178,7 +178,7 @@ clutter_event_translate (ClutterBackend *backend,
backend_egl = CLUTTER_BACKEND_EGL (backend); backend_egl = CLUTTER_BACKEND_EGL (backend);
stage = CLUTTER_STAGE (_clutter_backend_get_stage (backend)); stage = CLUTTER_STAGE (_clutter_backend_get_stage (backend));
stage_xwindow = clutter_egl_get_stage_window (stage); stage_xwindow = clutter_eglx_get_stage_window (stage);
xwindow = xevent->xany.window; xwindow = xevent->xany.window;
if (xwindow == None) if (xwindow == None)

View File

@ -68,14 +68,14 @@ clutter_stage_egl_unrealize (ClutterActor *actor)
} }
if (stage_egl->egl_surface) if (stage_egl->egl_surface)
eglDestroySurface (clutter_egl_display(), stage_egl->egl_surface); eglDestroySurface (clutter_eglx_display(), stage_egl->egl_surface);
stage_egl->egl_surface = NULL; stage_egl->egl_surface = NULL;
if (stage_egl->egl_context) if (stage_egl->egl_context)
eglDestroyContext (clutter_egl_display(), stage_egl->egl_context); eglDestroyContext (clutter_eglx_display(), stage_egl->egl_context);
stage_egl->egl_context = NULL; stage_egl->egl_context = NULL;
eglMakeCurrent (clutter_egl_display(), eglMakeCurrent (clutter_eglx_display(),
EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
stage_egl->egl_context = None; stage_egl->egl_context = None;
@ -105,7 +105,7 @@ clutter_stage_egl_realize (ClutterActor *actor)
EGL_BLUE_SIZE, 5, EGL_BLUE_SIZE, 5,
EGL_NONE }; EGL_NONE };
status = eglGetConfigs (clutter_egl_display(), status = eglGetConfigs (clutter_eglx_display(),
configs, configs,
2, 2,
&config_count); &config_count);
@ -113,7 +113,7 @@ clutter_stage_egl_realize (ClutterActor *actor)
if (status != EGL_TRUE) if (status != EGL_TRUE)
g_warning ("eglGetConfigs"); g_warning ("eglGetConfigs");
status = eglChooseConfig (clutter_egl_display(), status = eglChooseConfig (clutter_eglx_display(),
cfg_attribs, cfg_attribs,
configs, configs,
sizeof configs / sizeof configs[0], sizeof configs / sizeof configs[0],
@ -124,16 +124,16 @@ clutter_stage_egl_realize (ClutterActor *actor)
if (stage_egl->xwin == None) if (stage_egl->xwin == None)
stage_egl->xwin stage_egl->xwin
= XCreateSimpleWindow(clutter_egl_get_default_display(), = XCreateSimpleWindow(clutter_eglx_get_default_xdisplay(),
clutter_egl_get_default_root_window(), clutter_eglx_get_default_root_window(),
0, 0, 0, 0,
stage_egl->xwin_width, stage_egl->xwin_width,
stage_egl->xwin_height, stage_egl->xwin_height,
0, 0, 0, 0,
WhitePixel(clutter_egl_get_default_display(), WhitePixel(clutter_eglx_get_default_xdisplay(),
clutter_egl_get_default_screen())); clutter_eglx_get_default_screen()));
XSelectInput(clutter_egl_get_default_display(), XSelectInput(clutter_eglx_get_default_xdisplay(),
stage_egl->xwin, stage_egl->xwin,
StructureNotifyMask StructureNotifyMask
|ExposureMask |ExposureMask
@ -146,13 +146,13 @@ clutter_stage_egl_realize (ClutterActor *actor)
|PropertyChangeMask); |PropertyChangeMask);
if (stage_egl->egl_context) if (stage_egl->egl_context)
eglDestroyContext (clutter_egl_display(), stage_egl->egl_context); eglDestroyContext (clutter_eglx_display(), stage_egl->egl_context);
if (stage_egl->egl_surface) if (stage_egl->egl_surface)
eglDestroySurface (clutter_egl_display(), stage_egl->egl_surface); eglDestroySurface (clutter_eglx_display(), stage_egl->egl_surface);
stage_egl->egl_surface stage_egl->egl_surface
= eglCreateWindowSurface (clutter_egl_display(), = eglCreateWindowSurface (clutter_eglx_display(),
configs[0], configs[0],
(NativeWindowType)stage_egl->xwin, (NativeWindowType)stage_egl->xwin,
NULL); NULL);
@ -160,7 +160,7 @@ clutter_stage_egl_realize (ClutterActor *actor)
if (stage_egl->egl_surface == EGL_NO_SURFACE) if (stage_egl->egl_surface == EGL_NO_SURFACE)
g_warning ("eglCreateWindowSurface"); g_warning ("eglCreateWindowSurface");
stage_egl->egl_context = eglCreateContext (clutter_egl_display(), stage_egl->egl_context = eglCreateContext (clutter_eglx_display(),
configs[0], configs[0],
EGL_NO_CONTEXT, EGL_NO_CONTEXT,
NULL); NULL);
@ -168,7 +168,7 @@ clutter_stage_egl_realize (ClutterActor *actor)
if (stage_egl->egl_context == EGL_NO_CONTEXT) if (stage_egl->egl_context == EGL_NO_CONTEXT)
g_warning ("eglCreateContext"); g_warning ("eglCreateContext");
status = eglMakeCurrent (clutter_egl_display(), status = eglMakeCurrent (clutter_eglx_display(),
stage_egl->egl_surface, stage_egl->egl_surface,
EGL_NO_SURFACE, EGL_NO_SURFACE,
stage_egl->egl_context); stage_egl->egl_context);
@ -382,7 +382,7 @@ clutter_stage_egl_init (ClutterStageEGL *stage)
} }
/** /**
* clutter_egl_get_stage_window: * clutter_eglx_get_stage_window:
* @stage: a #ClutterStage * @stage: a #ClutterStage
* *
* FIXME * FIXME
@ -392,7 +392,7 @@ clutter_stage_egl_init (ClutterStageEGL *stage)
* Since: 0.4 * Since: 0.4
*/ */
Window Window
clutter_egl_get_stage_window (ClutterStage *stage) clutter_eglx_get_stage_window (ClutterStage *stage)
{ {
g_return_val_if_fail (CLUTTER_IS_STAGE_EGL (stage), None); g_return_val_if_fail (CLUTTER_IS_STAGE_EGL (stage), None);
@ -400,7 +400,7 @@ clutter_egl_get_stage_window (ClutterStage *stage)
} }
/** /**
* clutter_egl_get_stage_visual: * clutter_eglx_get_stage_visual:
* @stage: a #ClutterStage * @stage: a #ClutterStage
* *
* FIXME * FIXME
@ -410,7 +410,7 @@ clutter_egl_get_stage_window (ClutterStage *stage)
* Since: 0.4 * Since: 0.4
*/ */
XVisualInfo * XVisualInfo *
clutter_egl_get_stage_visual (ClutterStage *stage) clutter_eglx_get_stage_visual (ClutterStage *stage)
{ {
g_return_val_if_fail (CLUTTER_IS_STAGE_EGL (stage), NULL); g_return_val_if_fail (CLUTTER_IS_STAGE_EGL (stage), NULL);
@ -418,7 +418,7 @@ clutter_egl_get_stage_visual (ClutterStage *stage)
} }
/** /**
* clutter_egl_set_stage_foreign: * clutter_eglx_set_stage_foreign:
* @stage: a #ClutterStage * @stage: a #ClutterStage
* @window: FIXME * @window: FIXME
* *
@ -427,7 +427,7 @@ clutter_egl_get_stage_visual (ClutterStage *stage)
* Since: 0.4 * Since: 0.4
*/ */
void void
clutter_egl_set_stage_foreign (ClutterStage *stage, clutter_eglx_set_stage_foreign (ClutterStage *stage,
Window window) Window window)
{ {
g_return_if_fail (CLUTTER_IS_STAGE_EGL (stage)); g_return_if_fail (CLUTTER_IS_STAGE_EGL (stage));

View File

@ -26,7 +26,20 @@
#include <glib-object.h> #include <glib-object.h>
#include <pango/pangofc-decoder.h> #include <pango/pangofc-decoder.h>
/* Defines duped */ /* Defines duped - fun,fun.. */
#ifndef PANGO_GLYPH_EMPTY
#define PANGO_GLYPH_EMPTY ((PangoGlyph)0x0FFFFFFF)
#endif
#ifndef PANGO_GLYPH_UNKNOWN_FLAG
#define PANGO_GLYPH_UNKNOWN_FLAG ((PangoGlyph)0x10000000)
#endif
#ifndef PANGO_UNKNOWN_GLYPH_WIDTH
#define PANGO_UNKNOWN_GLYPH_WIDTH 10
#endif
#ifndef PANGO_UNKNOWN_GLYPH_HEIGHT
#define PANGO_UNKNOWN_GLYPH_HEIGHT 14
#endif
#define PANGO_SCALE_26_6 (PANGO_SCALE / (1<<6)) #define PANGO_SCALE_26_6 (PANGO_SCALE / (1<<6))

View File

@ -74,25 +74,6 @@ AC_CHECK_FUNCS([memset munmap strcasecmp strdup])
dnl ======================================================================== dnl ========================================================================
PKG_CHECK_MODULES(X11, x11, [have_x11=yes], [have_x11=no])
if test x$have_x11 = xno
then
AC_PATH_X
if test x"$x_includes" != x"NONE" && test -n "$x_includes" ; then
X11_CFLAGS=-I`echo $x_includes | sed -e "s/:/ -I/g"`
fi
if test x"$x_libraries" != x"NONE" && test -n "$x_libraries" ; then
X11_LIBS=-L`echo $x_libraries | sed -e "s/:/ -L/g"`
fi
fi
PKG_CHECK_MODULES(XFIXES, xfixes >= 4, [have_xfixes=yes], [have_xfixes=no])
if test x$have_xfixes = xyes
then
AC_DEFINE(HAVE_XFIXES, 1, Have the XFIXES X extension)
X11_LIBS="$X11_LIBS -lXfixes"
fi
CLUTTER_NO_FPU="0" CLUTTER_NO_FPU="0"
AC_ARG_WITH(fpu, AC_ARG_WITH(fpu,
AS_HELP_STRING([--without-fpu], AS_HELP_STRING([--without-fpu],
@ -108,12 +89,36 @@ AC_SUBST(CLUTTER_NO_FPU)
clutterbackend=glx clutterbackend=glx
AC_ARG_WITH([flavour], AC_ARG_WITH([flavour],
AC_HELP_STRING([--with-flavour=@<:@glx/eglx/sdl@:>@], AC_HELP_STRING([--with-flavour=@<:@glx/eglx/eglnative/sdl@:>@],
[Select the Clutter backend]), [Select the Clutter backend]),
clutterbackend=$with_flavour) clutterbackend=$with_flavour)
BACKEND_PC_FILES="" BACKEND_PC_FILES=""
# Check for X though could be redundant if backend does not need it.
PKG_CHECK_MODULES(X11, x11, [have_x11=yes], [have_x11=no])
if test x$have_x11 = xno; then
AC_PATH_X
if test x"$no_x" = "yes" ; then
if test "x$clutterbackend" = "xglx" or "x$clutterbackend" = "xeglx"
then
AC_MSG_ERROR([[No X11 Libraries found and required by backend.]])
fi
fi
if test x"$x_includes" != x"NONE" && test -n "$x_includes" ; then
X11_CFLAGS=-I`echo $x_includes | sed -e "s/:/ -I/g"`
fi
if test x"$x_libraries" != x"NONE" && test -n "$x_libraries" ; then
X11_LIBS=-L`echo $x_libraries | sed -e "s/:/ -L/g"`
fi
fi
PKG_CHECK_MODULES(XFIXES, xfixes >= 4, [have_xfixes=yes], [have_xfixes=no])
if test x$have_xfixes = xyes; then
AC_DEFINE(HAVE_XFIXES, 1, Have the XFIXES X extension)
X11_LIBS="$X11_LIBS -lXfixes"
fi
case $clutterbackend in case $clutterbackend in
sdl) sdl)
@ -200,16 +205,49 @@ case $clutterbackend in
CLUTTER_COGL="gles" CLUTTER_COGL="gles"
AC_DEFINE([HAVE_COGL_GLES], 1, [Have GL/ES for rendering]) AC_DEFINE([HAVE_COGL_GLES], 1, [Have GL/ES for rendering])
# try for libvincent first
PKG_CHECK_MODULES(EGL, libvincent, HAVE_OGLES=yes, HAVE_OGLES=no) PKG_CHECK_MODULES(EGL, libvincent, HAVE_OGLES=yes, HAVE_OGLES=no)
if test "x$HAVE_OGLES" = "xno"; then if test "x$HAVE_OGLES" = "xno"; then
AC_MSG_ERROR([libvincent (ogles) not found and egl backend requested.]); AC_CHECK_HEADERS([GLES/egl.h GLES/gl.h],,
[AC_MSG_ERROR([Unable to locate required GLES headers])])
AC_CHECK_LIB(GLES_CM, eglInitialize, HAVE_LIBGLES=yes, HAVE_LIBGLES=no)
if test "x$HAVE_LIBGLES" = "xno"; then
AC_MSG_ERROR([GLES library not found and egl backend requested.]);
fi
EGL_LIBS="-lGLES_CM"
fi fi
EGL_LIBS="$EGL_LIBS $X11_LIBS" EGL_LIBS="$EGL_LIBS $X11_LIBS"
EGL_CFLAGS="$EGL_CFLAGS $X11_CFLAGS" EGL_CFLAGS="$EGL_CFLAGS $X11_CFLAGS"
;; ;;
*) AC_MSG_ERROR([Invalid backend for Clutter: use glx,sdl or eglx]) eglnative)
CLUTTER_FLAVOUR="eglnative"
AC_DEFINE([HAVE_CLUTTER_EGL], 1, [Have the EGL backend])
# We currently assume having egl means also having gles..
CLUTTER_COGL="gles"
AC_DEFINE([HAVE_COGL_GLES], 1, [Have GL/ES for rendering])
AC_CHECK_HEADERS([GLES/egl.h GLES/gl.h],,
[AC_MSG_ERROR([Unable to locate required GLES headers])])
AC_CHECK_LIB(GLES_CM, eglInitialize, HAVE_LIBGLES=yes, HAVE_LIBGLES=no)
if test "x$HAVE_LIBGLES" = "xno"; then
AC_MSG_ERROR([libGLES_CM not found and egl backend requested.]);
fi
EGL_LIBS="-lGLES_CM"
EGL_CFLAGS=""
;;
*) AC_MSG_ERROR([Invalid backend for Clutter: use glx,sdl, eglx or eglnative])
;; ;;
esac esac
@ -297,7 +335,8 @@ AC_CONFIG_FILES([
clutter/Makefile clutter/Makefile
clutter/clutter-version.h clutter/clutter-version.h
clutter/glx/Makefile clutter/glx/Makefile
clutter/egl/Makefile clutter/eglx/Makefile
clutter/eglnative/Makefile
clutter/sdl/Makefile clutter/sdl/Makefile
clutter/cogl/Makefile clutter/cogl/Makefile
clutter/cogl/gl/Makefile clutter/cogl/gl/Makefile