2007-03-22 Emmanuele Bassi <ebassi@openedhand.com>
* clutter/clutter-private.h: Remove inclusion of backend-specific headers; update the main context object; add the declarations for the event queue functions. * clutter/clutter-backend.[ch]: Add the abstract ClutterBackend object, which holds backend-specific settings, the main stage, and the event queue. Every backend must implement a subclass of ClutterBackend and ClutterStage. * clutter/clutter-feature.c: Protect the GLX specific calls behing #ifdef HAVE_CLUTTER_GLX. * clutter/clutter-actor.c: * clutter/clutter-group.c: * clutter/clutter-clone-texture.c: Include GL/gl.h * clutter/clutter-event.[ch]: Update public API and implement the event queue private API; hold a reference on the event objects; move out the keysym-to-unicode table; add the new event types. * clutter/clutter-color.h: Include clutter-fixed.h * clutter/clutter-main.c: Update API; get the main stage from the backend object; process the event received from the queue; lock/unlock the main mutex if we have one; move the initialisation process sooner in the init sequence, in order to have the backend object when we check for options; call the backed vfuncs in the pre/post parse hooks. * clutter/clutter-stage.c: Make ClutterStage and abstract class, implemented by the backends. * clutter/clutter/glx/clutter-glx.h: * clutter/clutter/glx/clutter-backend-glx.[ch]: * clutter/clutter/glx/clutter-event-glx.c: * clutter/clutter/glx/clutter-stage-glx.[ch]: * clutter/clutter/glx/Makefile.am: Add the GLX backend. * clutter/clutter/egl/clutter-backend-egl.[ch]: * clutter/clutter/egl/clutter-event-egl.c: * clutter/clutter/egl/clutter-stage-egl.[ch]: * clutter/clutter/egl/Makefile.am: Add the stub for a EGL backend. * examples/*.c: Update for the new API.
This commit is contained in:
@ -36,6 +36,8 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "clutter-event.h"
|
||||
#include "clutter-backend.h"
|
||||
#include "clutter-main.h"
|
||||
#include "clutter-feature.h"
|
||||
#include "clutter-actor.h"
|
||||
@ -44,10 +46,6 @@
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-version.h" /* For flavour define */
|
||||
|
||||
#ifdef CLUTTER_FLAVOUR_GLX
|
||||
#include <clutter/clutter-backend-glx.h>
|
||||
#endif
|
||||
|
||||
static ClutterMainContext *ClutterCntx = NULL;
|
||||
|
||||
static gboolean clutter_is_initialized = FALSE;
|
||||
@ -72,14 +70,32 @@ static const GDebugKey clutter_debug_keys[] = {
|
||||
#endif /* CLUTTER_ENABLE_DEBUG */
|
||||
|
||||
|
||||
/**
|
||||
* clutter_get_show_fps:
|
||||
*
|
||||
* FIXME
|
||||
*
|
||||
* Return value: FIXME
|
||||
*
|
||||
* Since: 0.4
|
||||
*/
|
||||
gboolean
|
||||
clutter_want_fps (void)
|
||||
clutter_get_show_fps (void)
|
||||
{
|
||||
return clutter_show_fps;
|
||||
}
|
||||
|
||||
const gchar *
|
||||
clutter_vblank_method (void)
|
||||
/**
|
||||
* clutter_get_vblank_method:
|
||||
*
|
||||
* FIXME
|
||||
*
|
||||
* Return value: FIXME
|
||||
*
|
||||
* Since: 0.4
|
||||
*/
|
||||
G_CONST_RETURN gchar *
|
||||
clutter_get_vblank_method (void)
|
||||
{
|
||||
return clutter_vblank_name;
|
||||
}
|
||||
@ -92,10 +108,57 @@ clutter_vblank_method (void)
|
||||
void
|
||||
clutter_redraw (void)
|
||||
{
|
||||
ClutterMainContext *ctx = CLUTTER_CONTEXT();
|
||||
ClutterStage *stage = ctx->stage;
|
||||
ClutterMainContext *ctx;
|
||||
|
||||
ctx = clutter_context_get_default ();
|
||||
if (ctx->backend)
|
||||
clutter_actor_paint (clutter_backend_get_stage (ctx->backend));
|
||||
}
|
||||
|
||||
clutter_actor_paint (CLUTTER_ACTOR(stage));
|
||||
static void
|
||||
clutter_main_do_event (ClutterEvent *event,
|
||||
gpointer dummy)
|
||||
{
|
||||
ClutterMainContext *context;
|
||||
ClutterBackend *backend;
|
||||
ClutterActor *stage;
|
||||
|
||||
context = clutter_context_get_default ();
|
||||
backend = context->backend;
|
||||
stage = clutter_backend_get_stage (backend);
|
||||
if (!stage)
|
||||
return;
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case CLUTTER_NOTHING:
|
||||
break;
|
||||
case CLUTTER_BUTTON_PRESS:
|
||||
case CLUTTER_2BUTTON_PRESS:
|
||||
case CLUTTER_3BUTTON_PRESS:
|
||||
g_signal_emit_by_name (stage, "button-press-event", event);
|
||||
break;
|
||||
case CLUTTER_BUTTON_RELEASE:
|
||||
g_signal_emit_by_name (stage, "button-release-event", event);
|
||||
break;
|
||||
case CLUTTER_SCROLL:
|
||||
g_signal_emit_by_name (stage, "scroll-event", event);
|
||||
break;
|
||||
case CLUTTER_KEY_PRESS:
|
||||
g_signal_emit_by_name (stage, "key-press-event", event);
|
||||
break;
|
||||
case CLUTTER_KEY_RELEASE:
|
||||
g_signal_emit_by_name (stage, "key-release-event", event);
|
||||
break;
|
||||
case CLUTTER_MOTION:
|
||||
g_signal_emit_by_name (stage, "motion-event", event);
|
||||
break;
|
||||
case CLUTTER_DESTROY_NOTIFY:
|
||||
g_signal_emit_by_name (stage, "delete-event");
|
||||
break;
|
||||
case CLUTTER_STAGE_STATE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -164,7 +227,10 @@ clutter_main (void)
|
||||
|
||||
if (context->main_loop_level == 0)
|
||||
{
|
||||
clutter_actor_destroy (CLUTTER_ACTOR (context->stage));
|
||||
/* this will take care of destroying the stage */
|
||||
g_object_unref (context->backend);
|
||||
context->backend = NULL;
|
||||
|
||||
g_free (context);
|
||||
}
|
||||
}
|
||||
@ -179,7 +245,8 @@ clutter_threads_enter(void)
|
||||
{
|
||||
ClutterMainContext *context = CLUTTER_CONTEXT ();
|
||||
|
||||
g_mutex_lock (context->gl_lock);
|
||||
if (context->gl_lock)
|
||||
g_mutex_lock (context->gl_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -192,21 +259,26 @@ clutter_threads_leave (void)
|
||||
{
|
||||
ClutterMainContext *context = CLUTTER_CONTEXT ();
|
||||
|
||||
g_mutex_unlock (context->gl_lock);
|
||||
if (context->gl_lock)
|
||||
g_mutex_unlock (context->gl_lock);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* clutter_want_debug:
|
||||
* clutter_get_debug_enabled:
|
||||
*
|
||||
* Check if clutter has debugging turned on.
|
||||
*
|
||||
* Return value: TRUE if debugging is turned on, FALSE otherwise.
|
||||
*/
|
||||
gboolean
|
||||
clutter_want_debug (void)
|
||||
clutter_get_debug_enabled (void)
|
||||
{
|
||||
#ifdef CLUTTER_ENABLE_DEBUG
|
||||
return clutter_debug_flags != 0;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
ClutterMainContext*
|
||||
@ -217,6 +289,8 @@ clutter_context_get_default (void)
|
||||
ClutterMainContext *ctx;
|
||||
|
||||
ctx = g_new0 (ClutterMainContext, 1);
|
||||
ctx->backend = g_object_new (_clutter_backend_impl_get_type (), NULL);
|
||||
|
||||
ctx->is_initialized = FALSE;
|
||||
|
||||
ClutterCntx = ctx;
|
||||
@ -225,33 +299,6 @@ clutter_context_get_default (void)
|
||||
return ClutterCntx;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_gl_version_at_least_12 (void)
|
||||
{
|
||||
#define NON_VENDOR_VERSION_MAX_LEN 32
|
||||
gchar non_vendor_version[NON_VENDOR_VERSION_MAX_LEN];
|
||||
const gchar *version;
|
||||
gint i = 0;
|
||||
|
||||
version = (const gchar*) glGetString (GL_VERSION);
|
||||
|
||||
while ( ((version[i] <= '9' && version[i] >= '0') || version[i] == '.')
|
||||
&& i < NON_VENDOR_VERSION_MAX_LEN)
|
||||
{
|
||||
non_vendor_version[i] = version[i];
|
||||
i++;
|
||||
}
|
||||
|
||||
non_vendor_version[i] = '\0';
|
||||
|
||||
if (strstr (non_vendor_version, "1.0") == NULL
|
||||
&& strstr (non_vendor_version, "1.0") == NULL)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CLUTTER_ENABLE_DEBUG
|
||||
static gboolean
|
||||
clutter_arg_debug_cb (const char *key,
|
||||
@ -304,12 +351,24 @@ pre_parse_hook (GOptionContext *context,
|
||||
gpointer data,
|
||||
GError **error)
|
||||
{
|
||||
ClutterMainContext *clutter_context;
|
||||
ClutterBackend *backend;
|
||||
const char *env_string;
|
||||
|
||||
if (clutter_is_initialized)
|
||||
return TRUE;
|
||||
|
||||
g_type_init ();
|
||||
clutter_context = clutter_context_get_default ();
|
||||
clutter_context->main_loops = NULL;
|
||||
clutter_context->main_loop_level = 0;
|
||||
|
||||
clutter_context->font_map = PANGO_FT2_FONT_MAP (pango_ft2_font_map_new ());
|
||||
pango_ft2_font_map_set_resolution (clutter_context->font_map, 96.0, 96.0);
|
||||
|
||||
backend = clutter_context->backend;
|
||||
g_assert (CLUTTER_IS_BACKEND (backend));
|
||||
|
||||
_clutter_set_events_handler (clutter_main_do_event, NULL, NULL);
|
||||
|
||||
#ifdef CLUTTER_ENABLE_DEBUG
|
||||
env_string = g_getenv ("CLUTTER_DEBUG");
|
||||
@ -334,6 +393,9 @@ pre_parse_hook (GOptionContext *context,
|
||||
if (env_string)
|
||||
clutter_show_fps = TRUE;
|
||||
|
||||
if (CLUTTER_BACKEND_GET_CLASS (backend)->pre_parse)
|
||||
return CLUTTER_BACKEND_GET_CLASS (backend)->pre_parse (backend, error);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -347,10 +409,16 @@ post_parse_hook (GOptionContext *context,
|
||||
GError **error)
|
||||
{
|
||||
ClutterMainContext *clutter_context;
|
||||
ClutterBackend *backend;
|
||||
gboolean retval = FALSE;
|
||||
|
||||
if (clutter_is_initialized)
|
||||
return TRUE;
|
||||
|
||||
clutter_context = clutter_context_get_default ();
|
||||
backend = clutter_context->backend;
|
||||
g_assert (CLUTTER_IS_BACKEND (backend));
|
||||
|
||||
if (clutter_fatal_warnings)
|
||||
{
|
||||
GLogLevelFlags fatal_mask;
|
||||
@ -360,18 +428,14 @@ post_parse_hook (GOptionContext *context,
|
||||
g_log_set_always_fatal (fatal_mask);
|
||||
}
|
||||
|
||||
clutter_context = clutter_context_get_default ();
|
||||
clutter_context->main_loops = NULL;
|
||||
clutter_context->main_loop_level = 0;
|
||||
if (CLUTTER_BACKEND_GET_CLASS (backend)->post_parse)
|
||||
retval = CLUTTER_BACKEND_GET_CLASS (backend)->post_parse (backend, error);
|
||||
else
|
||||
retval = TRUE;
|
||||
|
||||
clutter_context->font_map = PANGO_FT2_FONT_MAP (pango_ft2_font_map_new ());
|
||||
pango_ft2_font_map_set_resolution (clutter_context->font_map, 96.0, 96.0);
|
||||
|
||||
clutter_context->gl_lock = g_mutex_new ();
|
||||
|
||||
clutter_is_initialized = TRUE;
|
||||
clutter_is_initialized = retval;
|
||||
|
||||
return TRUE;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -390,15 +454,22 @@ post_parse_hook (GOptionContext *context,
|
||||
GOptionGroup *
|
||||
clutter_get_option_group (void)
|
||||
{
|
||||
ClutterMainContext *context;
|
||||
GOptionGroup *group;
|
||||
|
||||
context = clutter_context_get_default ();
|
||||
|
||||
group = g_option_group_new ("clutter",
|
||||
"Clutter Options",
|
||||
"Show Clutter Options",
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
g_option_group_set_parse_hooks (group, pre_parse_hook, post_parse_hook);
|
||||
g_option_group_add_entries (group, clutter_args);
|
||||
|
||||
/* add backend-specific options */
|
||||
clutter_backend_add_options (context->backend, group);
|
||||
|
||||
return group;
|
||||
}
|
||||
@ -409,34 +480,6 @@ clutter_init_error_quark (void)
|
||||
return g_quark_from_static_string ("clutter-init-error-quark");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_stage_init (ClutterMainContext *context,
|
||||
GError **error)
|
||||
{
|
||||
context->stage = CLUTTER_STAGE (clutter_stage_get_default ());
|
||||
if (!CLUTTER_IS_STAGE (context->stage))
|
||||
{
|
||||
g_set_error (error, clutter_init_error_quark (),
|
||||
CLUTTER_INIT_ERROR_INTERNAL,
|
||||
"Unable to create the main stage");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_object_ref_sink (context->stage);
|
||||
|
||||
/* Realize to get context */
|
||||
clutter_actor_realize (CLUTTER_ACTOR (context->stage));
|
||||
if (!CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (context->stage)))
|
||||
{
|
||||
g_set_error (error, clutter_init_error_quark (),
|
||||
CLUTTER_INIT_ERROR_INTERNAL,
|
||||
"Unable to realize the main stage");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_init_with_args:
|
||||
* @argc: a pointer to the number of command line arguments
|
||||
@ -482,14 +525,11 @@ clutter_init_with_args (int *argc,
|
||||
if (clutter_is_initialized)
|
||||
return CLUTTER_INIT_SUCCESS;
|
||||
|
||||
if (!g_thread_supported ())
|
||||
g_thread_init (NULL);
|
||||
g_type_init ();
|
||||
|
||||
group = clutter_get_option_group ();
|
||||
context = g_option_context_new (parameter_string);
|
||||
|
||||
clutter_backend_init (context);
|
||||
|
||||
g_option_context_add_group (context, group);
|
||||
|
||||
if (entries)
|
||||
@ -507,12 +547,14 @@ clutter_init_with_args (int *argc,
|
||||
clutter_context = clutter_context_get_default ();
|
||||
|
||||
stage_error = NULL;
|
||||
if (!clutter_stage_init (clutter_context, &stage_error))
|
||||
if (!clutter_backend_init_stage (clutter_context->backend, &stage_error))
|
||||
{
|
||||
g_propagate_error (error, stage_error);
|
||||
return CLUTTER_INIT_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
clutter_backend_init_events (clutter_context->backend);
|
||||
|
||||
return CLUTTER_INIT_SUCCESS;
|
||||
}
|
||||
|
||||
@ -533,10 +575,8 @@ clutter_parse_args (int *argc,
|
||||
g_option_context_set_help_enabled (option_context, FALSE);
|
||||
|
||||
/* Initiate any command line options from the backend */
|
||||
clutter_backend_init (option_context);
|
||||
|
||||
clutter_group = clutter_get_option_group ();
|
||||
|
||||
g_option_context_set_main_group (option_context, clutter_group);
|
||||
|
||||
if (!g_option_context_parse (option_context, argc, argv, &error))
|
||||
@ -573,8 +613,7 @@ clutter_init (int *argc,
|
||||
if (clutter_is_initialized)
|
||||
return CLUTTER_INIT_SUCCESS;
|
||||
|
||||
if (!g_thread_supported ())
|
||||
g_thread_init (NULL);
|
||||
g_type_init ();
|
||||
|
||||
if (clutter_parse_args (argc, argv) == FALSE)
|
||||
return CLUTTER_INIT_ERROR_INTERNAL;
|
||||
@ -582,22 +621,14 @@ clutter_init (int *argc,
|
||||
context = clutter_context_get_default ();
|
||||
|
||||
stage_error = NULL;
|
||||
if (!clutter_stage_init (context, &stage_error))
|
||||
if (!clutter_backend_init_stage (context->backend, &stage_error))
|
||||
{
|
||||
g_critical (stage_error->message);
|
||||
g_error_free (stage_error);
|
||||
return CLUTTER_INIT_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* FIXME: move to backend */
|
||||
/* At least GL 1.2 is needed for CLAMP_TO_EDGE */
|
||||
if (!is_gl_version_at_least_12 ())
|
||||
{
|
||||
g_critical ("Clutter needs at least version 1.2 of OpenGL");
|
||||
return CLUTTER_INIT_ERROR_OPENGL;
|
||||
}
|
||||
#endif
|
||||
_clutter_events_init (context->backend);
|
||||
|
||||
return 1;
|
||||
return CLUTTER_INIT_SUCCESS;
|
||||
}
|
||||
|
Reference in New Issue
Block a user