2006-11-21 Emmanuele Bassi <ebassi@openedhand.com>

* configure.ac: Enable debug messages also when
	--enable-debug is set to "minimum".

	* clutter/Makefile.am:
	* clutter/clutter-debug.h: Move all debugging macros inside
	this private header; make all debug macros depend on the
	CLUTTER_ENABLE_DEBUG compile time define, controlled by
	the --enable-debug configure switch; add G_LOG_DOMAIN define.

	* clutter/clutter-main.c: Clean up the debug stuff; add
	command line argument parsing using GOption; the debug
	messages now are triggered like this:

	  CLUTTER_DEBUG=section:section:... clutter-app
	
	or like this:

	  clutter-app --clutter-debug=section:section:...
	
	where "section" is one of the sections listed in clutter-main.c,
	or "all", for all sections; each section is bound to a flag,
	which can be used to define a domain when adding a debug note
	using the CLUTTER_NOTE() macro; the old CLUTTER_DBG() macro is
	just a wrapper around that, under the CLUTTER_DEBUG_MISC domain;
	CLUTTER_NOTE() is used like this:

	  CLUTTER_NOTE (DOMAIN, log-function);
	
	where log function is g_printerr(), g_message(), g_warning(),
	g_critical() or directly g_log() - for instance:

	  CLUTTER_NOTE (PANGO, g_warning ("Cache miss: %d", glyph));

	will print the warning only if the "pango" flag has been
	set to the CLUTTER_DEBUG envvar or passed to the --clutter-debug
	command line argument.

	similar to CLUTTER_SHOW_FPS, there's also the --clutter-show-fps
	command line switch; also, the --display and --screen command
	line switches have been added: the first overrides the DISPLAY
	envvar and the second controls the X screen used by Clutter to
	get the root window on the display.

	* clutter/clutter-main.h:
	* clutter/clutter-main.c: Add extended support for GOption
	in Clutter; use clutter_init_with_args() to let Clutter
	parse your own command line arguments; use instead
	clutter_get_option_group() to get the GOptionGroup used by
	Clutter if you want to do the parsing yourself with
	g_option_context_parse(). The init sequence has been verified,
	updated and moved into common functions where possible.

	* clutter/pango/pangoclutter-render.c:
	* clutter/*.c: Include "clutter-debug.h" where needed; use
	CLUTTER_NOTE() instead of CLUTTER_DBG().

	* examples/super-oh.c: Use the new clutter_init_with_args()
	function, and add a --num-hands command line switch to
	the SuperOH example code controlling the number of hands at
	runtime.
This commit is contained in:
Emmanuele Bassi 2006-11-21 21:27:53 +00:00
parent ff84406143
commit e4b9a507e3
21 changed files with 721 additions and 220 deletions

View File

@ -1,3 +1,66 @@
2006-11-21 Emmanuele Bassi <ebassi@openedhand.com>
* configure.ac: Enable debug messages also when
--enable-debug is set to "minimum".
* clutter/Makefile.am:
* clutter/clutter-debug.h: Move all debugging macros inside
this private header; make all debug macros depend on the
CLUTTER_ENABLE_DEBUG compile time define, controlled by
the --enable-debug configure switch; add G_LOG_DOMAIN define.
* clutter/clutter-main.c: Clean up the debug stuff; add
command line argument parsing using GOption; the debug
messages now are triggered like this:
CLUTTER_DEBUG=section:section:... clutter-app
or like this:
clutter-app --clutter-debug=section:section:...
where "section" is one of the sections listed in clutter-main.c,
or "all", for all sections; each section is bound to a flag,
which can be used to define a domain when adding a debug note
using the CLUTTER_NOTE() macro; the old CLUTTER_DBG() macro is
just a wrapper around that, under the CLUTTER_DEBUG_MISC domain;
CLUTTER_NOTE() is used like this:
CLUTTER_NOTE (DOMAIN, log-function);
where log function is g_printerr(), g_message(), g_warning(),
g_critical() or directly g_log() - for instance:
CLUTTER_NOTE (PANGO, g_warning ("Cache miss: %d", glyph));
will print the warning only if the "pango" flag has been
set to the CLUTTER_DEBUG envvar or passed to the --clutter-debug
command line argument.
similar to CLUTTER_SHOW_FPS, there's also the --clutter-show-fps
command line switch; also, the --display and --screen command
line switches have been added: the first overrides the DISPLAY
envvar and the second controls the X screen used by Clutter to
get the root window on the display.
* clutter/clutter-main.h:
* clutter/clutter-main.c: Add extended support for GOption
in Clutter; use clutter_init_with_args() to let Clutter
parse your own command line arguments; use instead
clutter_get_option_group() to get the GOptionGroup used by
Clutter if you want to do the parsing yourself with
g_option_context_parse(). The init sequence has been verified,
updated and moved into common functions where possible.
* clutter/pango/pangoclutter-render.c:
* clutter/*.c: Include "clutter-debug.h" where needed; use
CLUTTER_NOTE() instead of CLUTTER_DBG().
* examples/super-oh.c: Use the new clutter_init_with_args()
function, and add a --num-hands command line switch to
the SuperOH example code controlling the number of hands at
runtime.
2006-11-21 Emmanuele Bassi <ebassi@openedhand.com>
* configure.ac: Rename G_ENABLE_DEBUG to CLUTTER_ENABLE_DEBUG.

View File

@ -112,7 +112,7 @@ source_c = clutter-main.c \
clutter-media.c \
clutter-enum-types.c
source_h_priv = clutter-private.h
source_h_priv = clutter-debug.h clutter-private.h
libclutter_@CLUTTER_MAJORMINOR@_la_SOURCES = $(MARSHALFILES) \
$(source_c) \
@ -126,6 +126,7 @@ INCLUDES = \
-DLIBDIR=\""$(libdir)"\" \
-DDATADIR=\""$(datadir)"\" \
-DG_DISABLE_DEPRECATED \
-DG_LOG_DOMAIN=\"Clutter\" \
$(GCC_FLAGS) \
$(CLUTTER_CFLAGS) \
$(CLUTTER_DEBUG_CFLAGS)

View File

@ -241,12 +241,12 @@ clutter_actor_paint (ClutterActor *self)
if (!CLUTTER_ACTOR_IS_REALIZED (self))
{
CLUTTER_DBG("@@@ Attempting realize via paint() @@@");
CLUTTER_NOTE (PAINT, g_message ("Attempting realize via paint()"));
clutter_actor_realize(self);
if (!CLUTTER_ACTOR_IS_REALIZED (self))
{
CLUTTER_DBG("*** Attempt failed, aborting paint ***");
CLUTTER_NOTE (PAINT, g_warning ("Attempt failed, aborting paint"));
return;
}
}
@ -553,9 +553,9 @@ clutter_actor_dispose (GObject *object)
{
ClutterActor *self = CLUTTER_ACTOR (object);
CLUTTER_DBG ("Disposing of object (id=%d) of type `%s'",
self->priv->id,
g_type_name (G_OBJECT_TYPE (self)));
CLUTTER_NOTE (MISC, g_message ("Disposing of object (id=%d) of type `%s'",
self->priv->id,
g_type_name (G_OBJECT_TYPE (self))));
if (!(CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_IN_DESTRUCTION))
{

View File

@ -49,10 +49,13 @@
#include "config.h"
#endif
#include <math.h>
#include "clutter-alpha.h"
#include "clutter-main.h"
#include "clutter-marshal.h"
#include <math.h>
#include "clutter-private.h"
#include "clutter-debug.h"
G_DEFINE_TYPE (ClutterAlpha, clutter_alpha, G_TYPE_OBJECT);
@ -506,7 +509,7 @@ clutter_sine_func (ClutterAlpha *alpha,
{
ClutterTimeline *timeline;
gint current_frame_num, n_frames;
gdouble x;
gdouble x, sine;
timeline = clutter_alpha_get_timeline (alpha);
@ -516,9 +519,9 @@ clutter_sine_func (ClutterAlpha *alpha,
/* FIXME: fixed point, and fixed point sine() */
x = (gdouble) (current_frame_num * 2.0f * M_PI) / n_frames ;
sine = (sin (x - (M_PI / 2.0f)) + 1.0f) * 0.5f;
CLUTTER_DBG ("%2f\n", ((sin (x - (M_PI / 2.0f)) + 1.0f) * 0.5f));
CLUTTER_NOTE (ALPHA, g_message ("sine: %2f\n", sine));
return (guint32) (((sin (x - (M_PI / 2.0f)) + 1.0f) * 0.5f)
* (gdouble) CLUTTER_ALPHA_MAX_ALPHA);
return (guint32) (sine * (gdouble) CLUTTER_ALPHA_MAX_ALPHA);
}

View File

@ -41,6 +41,8 @@
#include "clutter-behaviour-opacity.h"
#include "clutter-enum-types.h"
#include "clutter-main.h"
#include "clutter-private.h"
#include "clutter-debug.h"
#include <math.h>
@ -95,7 +97,8 @@ opacity_frame_foreach (ClutterActor *actor,
opacity += priv->opacity_start;
CLUTTER_DBG ("alpha %i opacity %i\n", alpha, opacity);
CLUTTER_NOTE (BEHAVIOUR, g_message ("alpha %i opacity %i\n",
alpha, opacity));
clutter_actor_set_opacity (actor, opacity);
}
@ -109,12 +112,6 @@ clutter_behaviour_alpha_notify (ClutterBehaviour *behave,
CLUTTER_BEHAVIOUR_OPACITY (behave));
}
static void
clutter_behaviour_opacity_finalize (GObject *object)
{
G_OBJECT_CLASS (clutter_behaviour_opacity_parent_class)->finalize (object);
}
static void
clutter_behaviour_opacity_set_property (GObject *gobject,
guint prop_id,

View File

@ -42,6 +42,8 @@
#include "clutter-main.h"
#include "clutter-fixed.h"
#include "clutter-behaviour-scale.h"
#include "clutter-private.h"
#include "clutter-debug.h"
#include <math.h>
@ -121,7 +123,7 @@ scale_frame_foreach (ClutterActor *actor,
case CLUTTER_GRAVITY_WEST:
break;
case CLUTTER_GRAVITY_CENTER:
CLUTTER_DBG ("%i vs %i\n", sw, w);
CLUTTER_NOTE (MISC, g_message (G_STRLOC ": gravity %i vs %i\n", sw, w));
clutter_actor_move_by (actor, sw - w, sh - h);
default:
break;

View File

@ -37,7 +37,8 @@
#include "clutter-feature.h"
#include "clutter-util.h"
#include "clutter-enum-types.h"
#include "clutter-private.h" /* for DBG */
#include "clutter-private.h"
#include "clutter-debug.h"
enum
{
@ -149,8 +150,10 @@ clone_texture_render_to_gl_quad (ClutterCloneTexture *ctexture,
qy1 = y1 + lasty;
qy2 = qy1 + ((qheight * actual_h) / pheight );
CLUTTER_DBG("rendering text tile x: %i, y: %i - %ix%i",
x, y, actual_w, actual_h);
CLUTTER_NOTE (TEXTURE,
g_message ("rendering text tile x: %i, y: %i - %ix%i",
x, y,
actual_w, actual_h));
glBegin (GL_QUADS);
glTexCoord2f (tx, ty); glVertex2i (qx2, qy2);
@ -201,8 +204,10 @@ clutter_clone_texture_paint (ClutterActor *self)
clutter_actor_get_coords (self, &x1, &y1, &x2, &y2);
CLUTTER_DBG("paint to x1: %i, y1: %i x2: %i, y2: %i opacity: %i",
x1, y1, x2, y2, clutter_actor_get_opacity(self) );
CLUTTER_NOTE (PAINT, g_message ("paint to x1: %i, y1: %i x2: %i, y2: %i "
"opacity: %i",
x1, y1, x2, y2,
clutter_actor_get_opacity (self)));
/* Parent paint translated us into position */
clone_texture_render_to_gl_quad (CLUTTER_CLONE_TEXTURE(self),

48
clutter/clutter-debug.h Normal file
View File

@ -0,0 +1,48 @@
#ifndef __CLUTTER_DEBUG_H__
#define __CLUTTER_DEBUG_H__
#include <glib.h>
G_BEGIN_DECLS
typedef enum {
CLUTTER_DEBUG_MISC = 1 << 0,
CLUTTER_DEBUG_ACTOR = 1 << 1,
CLUTTER_DEBUG_TEXTURE = 1 << 2,
CLUTTER_DEBUG_EVENT = 1 << 3,
CLUTTER_DEBUG_PAINT = 1 << 4,
CLUTTER_DEBUG_GL = 1 << 5,
CLUTTER_DEBUG_ALPHA = 1 << 6,
CLUTTER_DEBUG_BEHAVIOUR = 1 << 7,
CLUTTER_DEBUG_PANGO = 1 << 8
} ClutterDebugFlag;
#ifdef CLUTTER_ENABLE_DEBUG
#define CLUTTER_NOTE(type,action) G_STMT_START { \
if (clutter_debug_flags & CLUTTER_DEBUG_##type) \
{ action; } } G_STMT_END
#define CLUTTER_MARK() CLUTTER_NOTE(MISC, g_message (G_STRLOC ": mark"))
#define CLUTTER_DBG(x,a...) CLUTTER_NOTE(MISC, g_message (x, ##a))
#define CLUTTER_GLERR() G_STMT_START { \
if (clutter_debug_flags & CLUTTER_DEBUG_GL) \
{ GLenum _err = glGetError (); /* roundtrip */ \
if (_err != GL_NO_ERROR) \
g_warning (G_STRLOC ": GL Error %x", _err); \
} } G_STMT_END
#else /* !CLUTTER_ENABLE_DEBUG */
#define CLUTTER_NOTE(type,action)
#define CLUTTER_DBG(x,a...)
#define CLUTTER_GLERR()
#endif /* CLUTTER_ENABLE_DEBUG */
extern guint clutter_debug_flags;
G_END_DECLS
#endif /* __CLUTTER_DEBUG_H__ */

View File

@ -31,8 +31,6 @@
*/
#include "config.h"
#include "clutter-main.h"
#include "clutter-feature.h"
#include <stdlib.h>
#include <string.h>
@ -42,7 +40,12 @@
#include <fcntl.h>
#include <errno.h>
#include <dlfcn.h>
#include <dlfcn.h>
#include "clutter-feature.h"
#include "clutter-main.h"
#include "clutter-private.h"
#include "clutter-debug.h"
typedef void (*FuncPtr) (void);
typedef int (*GLXGetVideoSyncProc) (unsigned int *count);
@ -221,7 +224,7 @@ clutter_feature_init (void)
if (getenv("__GL_SYNC_TO_VBLANK") || check_vblank_env("none"))
{
CLUTTER_DBG("vblank sync: disabled at user request");
CLUTTER_NOTE (MISC, g_message ("vblank sync: disabled at user request"));
}
else
{
@ -237,8 +240,9 @@ clutter_feature_init (void)
if (__features->funcs.get_video_sync != NULL
&& __features->funcs.wait_video_sync != NULL)
{
CLUTTER_DBG("vblank sync: using glx");
__features->vblank_type = CLUTTER_VBLANK_GLX;
CLUTTER_NOTE (MISC, g_message ("vblank sync: using glx"));
__features->vblank_type = CLUTTER_VBLANK_GLX;
__features->flags |= CLUTTER_FEATURE_SYNC_TO_VBLANK;
}
}
@ -248,14 +252,18 @@ clutter_feature_init (void)
__features->dri_fd = open("/dev/dri/card0", O_RDWR);
if (__features->dri_fd >= 0)
{
CLUTTER_DBG("vblank sync: using dri");
CLUTTER_NOTE (MISC, g_message ("vblank sync: using dri"));
__features->vblank_type = CLUTTER_VBLANK_DRI;
__features->flags |= CLUTTER_FEATURE_SYNC_TO_VBLANK;
}
}
if (!(__features->flags & CLUTTER_FEATURE_SYNC_TO_VBLANK))
CLUTTER_DBG("vblank sync: no use-able mechanism found");
{
CLUTTER_NOTE (MISC,
g_message ("vblank sync: no use-able mechanism found"));
}
}
}

View File

@ -35,7 +35,8 @@
#include "clutter-label.h"
#include "clutter-main.h"
#include "clutter-enum-types.h"
#include "clutter-private.h" /* for DBG */
#include "clutter-private.h"
#include "clutter-debug.h"
#include "pangoclutter.h"
@ -243,8 +244,10 @@ clutter_label_paint (ClutterActor *self)
if (priv->desc == NULL || priv->text == NULL)
{
CLUTTER_DBG("*** FAIL: layout: %p , desc: %p, text %p ***",
priv->layout, priv->desc, priv->text);
CLUTTER_NOTE (ACTOR, g_warning ("layout: %p , desc: %p, text %p",
priv->layout,
priv->desc,
priv->text));
return;
}

View File

@ -30,8 +30,9 @@
* functions for mainloops, events and threads
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
@ -40,6 +41,28 @@
#include "clutter-actor.h"
#include "clutter-stage.h"
#include "clutter-private.h"
#include "clutter-debug.h"
static gboolean clutter_is_initialized = FALSE;
static gboolean clutter_show_fps = FALSE;
static gchar *clutter_display_name = NULL;
static int clutter_screen = 0;
guint clutter_debug_flags = 0; /* global clutter debug flag */
#ifdef CLUTTER_ENABLE_DEBUG
static const GDebugKey clutter_debug_keys[] = {
{ "misc", CLUTTER_DEBUG_MISC },
{ "actor", CLUTTER_DEBUG_ACTOR },
{ "texture", CLUTTER_DEBUG_TEXTURE },
{ "event", CLUTTER_DEBUG_EVENT },
{ "paint", CLUTTER_DEBUG_PAINT },
{ "gl", CLUTTER_DEBUG_GL },
{ "alpha", CLUTTER_DEBUG_ALPHA },
{ "behaviour", CLUTTER_DEBUG_BEHAVIOUR },
{ "pango", CLUTTER_DEBUG_PANGO },
};
#endif /* CLUTTER_ENABLE_DEBUG */
typedef struct
{
@ -51,9 +74,6 @@ ClutterXEventSource;
typedef void (*ClutterXEventFunc) (XEvent *xev, gpointer user_data);
static gboolean __clutter_has_debug = FALSE;
static gboolean __clutter_has_fps = FALSE;
static ClutterMainContext *ClutterCntx = NULL;
static gboolean
@ -113,8 +133,8 @@ static void
translate_key_event (ClutterKeyEvent *event,
XEvent *xevent)
{
event->type = xevent->xany.type
== KeyPress ? CLUTTER_KEY_PRESS : CLUTTER_KEY_RELEASE;
event->type = xevent->xany.type == KeyPress ? CLUTTER_KEY_PRESS
: CLUTTER_KEY_RELEASE;
event->time = xevent->xkey.time;
event->modifier_state = xevent->xkey.state; /* FIXME: handle modifiers */
event->hardware_keycode = xevent->xkey.keycode;
@ -128,10 +148,12 @@ translate_button_event (ClutterButtonEvent *event,
XEvent *xevent)
{
/* FIXME: catch double click */
CLUTTER_DBG("button event at %ix%i", xevent->xbutton.x, xevent->xbutton.y);
CLUTTER_NOTE (EVENT, g_message (G_STRLOC ": button event at %ix%i",
xevent->xbutton.x,
xevent->xbutton.y));
event->type = xevent->xany.type
== ButtonPress ? CLUTTER_BUTTON_PRESS : CLUTTER_BUTTON_RELEASE;
event->type = xevent->xany.type == ButtonPress ? CLUTTER_BUTTON_PRESS
: CLUTTER_BUTTON_RELEASE;
event->time = xevent->xbutton.time;
event->x = xevent->xbutton.x;
event->y = xevent->xbutton.y;
@ -173,7 +195,7 @@ clutter_dispatch_x_event (XEvent *xevent,
/* FIXME: need to make stage an 'actor' so can que
* a paint direct from there rather than hack here...
*/
*/
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
}
break;
@ -244,9 +266,9 @@ events_init()
}
static gboolean
clutter_want_fps(void)
clutter_want_fps (void)
{
return __clutter_has_fps;
return clutter_show_fps;
}
/**
@ -267,7 +289,7 @@ clutter_redraw (void)
/* FIXME: Should move all this into stage...
*/
CLUTTER_DBG("@@@ Redraw enter @@@");
CLUTTER_NOTE (PAINT, g_message (G_STRLOC ": Redraw enter"));
if (clutter_want_fps ())
{
@ -311,7 +333,7 @@ clutter_redraw (void)
}
}
CLUTTER_DBG("@@@ Redraw leave @@@");
CLUTTER_NOTE (PAINT, g_message (G_STRLOC ": Redraw leave"));
}
/**
@ -355,7 +377,7 @@ clutter_main (void)
ClutterMainContext *context = CLUTTER_CONTEXT ();
GMainLoop *loop;
if (!context->is_initialized)
if (!clutter_is_initialized)
{
g_warning ("Called clutter_main() but Clutter wasn't initialised. "
"You must call clutter_init() first.");
@ -460,7 +482,7 @@ clutter_root_xwindow (void)
gboolean
clutter_want_debug (void)
{
return __clutter_has_debug;
return clutter_debug_flags != 0;
}
ClutterMainContext*
@ -487,7 +509,7 @@ is_gl_version_at_least_12 (void)
const gchar *version;
gint i = 0;
version = (const gchar*)glGetString(GL_VERSION);
version = (const gchar*) glGetString (GL_VERSION);
while ( ((version[i] <= '9' && version[i] >= '0') || version[i] == '.')
&& i < NON_VENDOR_VERSION_MAX_LEN)
@ -506,81 +528,394 @@ is_gl_version_at_least_12 (void)
}
/**
* clutter_init:
* @argc: The number of arguments in @argv
* @argv: A pointer to an array of arguments.
*
* Initialises Clutter.
*
* Return value: 1 on success, < 0 on failure.
*/
ClutterInitError
clutter_init (int *argc, char ***argv)
#ifdef CLUTTER_ENABLE_DEBUG
static gboolean
clutter_arg_debug_cb (const char *key,
const char *value,
gpointer user_data)
{
ClutterMainContext *context;
static gboolean is_initialized = FALSE;
clutter_debug_flags |=
g_parse_debug_string (value,
clutter_debug_keys,
G_N_ELEMENTS (clutter_debug_keys));
return TRUE;
}
if (is_initialized)
return CLUTTER_INIT_SUCCESS;
static gboolean
clutter_arg_no_debug_cb (const char *key,
const char *value,
gpointer user_data)
{
clutter_debug_flags &=
~g_parse_debug_string (value,
clutter_debug_keys,
G_N_ELEMENTS (clutter_debug_keys));
return TRUE;
}
#endif /* CLUTTER_ENABLE_DEBUG */
context = clutter_context_get_default ();
static GOptionEntry clutter_args[] = {
{ "display", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_STRING, &clutter_display_name,
"X display to use", "DISPLAY" },
{ "screen", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_INT, &clutter_screen,
"X screen to use", "SCREEN" },
{ "clutter-show-fps", 0, 0, G_OPTION_ARG_NONE, &clutter_show_fps,
"Show frames per second", NULL },
#ifdef CLUTTER_ENABLE_DEBUG
{ "clutter-debug", 0, 0, G_OPTION_ARG_CALLBACK, clutter_arg_debug_cb,
"Clutter debugging flags to set", "FLAGS" },
{ "clutter-no-debug", 0, 0, G_OPTION_ARG_CALLBACK, clutter_arg_no_debug_cb,
"Clutter debugging flags to unset", "FLAGS" },
#endif /* CLUTTER_ENABLE_DEBUG */
{ NULL, },
};
if (g_getenv ("CLUTTER_DEBUG"))
__clutter_has_debug = TRUE;
/* pre_parse_hook: initialise variables depending on environment
* variables; these variables might be overridden by the command
* line arguments that are going to be parsed after.
*/
static gboolean
pre_parse_hook (GOptionContext *context,
GOptionGroup *group,
gpointer data,
GError **error)
{
const char *env_string;
if (g_getenv ("CLUTTER_SHOW_FPS"))
__clutter_has_fps = TRUE;
if (clutter_is_initialized)
return TRUE;
g_type_init();
g_type_init ();
if (!g_thread_supported ())
g_thread_init (NULL);
if (!XInitThreads())
return CLUTTER_INIT_ERROR_THREADS;
context->main_loops = NULL;
context->main_loop_level = 0;
if ((context->xdpy = XOpenDisplay (g_getenv ("DISPLAY"))) == NULL)
#ifdef CLUTTER_ENABLE_DEBUG
env_string = g_getenv ("CLUTTER_DEBUG");
if (env_string != NULL)
{
g_critical ("Unable to connect to X DISPLAY.");
return CLUTTER_INIT_ERROR_DISPLAY;
clutter_debug_flags =
g_parse_debug_string (env_string,
clutter_debug_keys,
G_N_ELEMENTS (clutter_debug_keys));
env_string = NULL;
}
#endif /* CLUTTER_ENABLE_DEBUG */
env_string = g_getenv ("CLUTTER_SHOW_FPS");
if (env_string)
clutter_show_fps = TRUE;
env_string = g_getenv ("DISPLAY");
if (env_string)
clutter_display_name = g_strdup (env_string);
return TRUE;
}
/* post_parse_hook: initialise the context and data structures
* and opens the X display
*/
static gboolean
post_parse_hook (GOptionContext *context,
GOptionGroup *group,
gpointer data,
GError **error)
{
ClutterMainContext *clutter_context;
clutter_context = clutter_context_get_default ();
clutter_context->main_loops = NULL;
clutter_context->main_loop_level = 0;
/* either we got this with the DISPLAY envvar or via the
* --display command line switch; if both failed, then
* we'll fail later when we return in clutter_init()
*/
if (clutter_display_name)
clutter_context->xdpy = XOpenDisplay (clutter_display_name);
if (clutter_context->xdpy)
{
if (clutter_screen == 0)
clutter_context->xscreen = DefaultScreen (clutter_context->xdpy);
else
{
Screen *xscreen;
xscreen = ScreenOfDisplay (clutter_context->xdpy, clutter_screen);
clutter_context->xscreen = XScreenNumberOfScreen (xscreen);
}
clutter_context->xwin_root = RootWindow (clutter_context->xdpy,
clutter_context->xscreen);
/* we don't need it anymore */
g_free (clutter_display_name);
}
context->xscreen = DefaultScreen(context->xdpy);
context->xwin_root = RootWindow(context->xdpy,
context->xscreen);
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);
context->font_map = PANGO_FT2_FONT_MAP (pango_ft2_font_map_new ());
pango_ft2_font_map_set_resolution (context->font_map, 96.0, 96.0);
clutter_context->gl_lock = g_mutex_new ();
context->gl_lock = g_mutex_new ();
clutter_is_initialized = TRUE;
return TRUE;
}
/**
* clutter_get_option_group:
*
* Returns a #GOptionGroup for the command line arguments recognized
* by Clutter. You should add this group to your #GOptionContext with
* g_option_context_add_group(), if you are using g_option_context_parse()
* to parse your commandline arguments.
*
* Return value: a GOptionGroup for the commandline arguments
* recognized by Clutter
*
* Since: 0.2
*/
GOptionGroup *
clutter_get_option_group (void)
{
GOptionGroup *group;
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);
return group;
}
static gboolean
clutter_parse_args (int *argc,
char ***argv)
{
GOptionContext *option_context;
GOptionGroup *clutter_group;
GError *error = NULL;
if (clutter_is_initialized)
return TRUE;
option_context = g_option_context_new (NULL);
g_option_context_set_ignore_unknown_options (option_context, TRUE);
g_option_context_set_help_enabled (option_context, FALSE);
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))
{
g_warning ("%s", error->message);
g_error_free (error);
}
g_option_context_free (option_context);
return TRUE;
}
GQuark
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 ());
g_return_val_if_fail (CLUTTER_IS_STAGE (context->stage), -3);
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;
}
g_return_val_if_fail
(CLUTTER_ACTOR_IS_REALIZED(CLUTTER_ACTOR(context->stage)),
CLUTTER_INIT_ERROR_INTERNAL);
return TRUE;
}
/**
* clutter_init_with_args:
* @argc: a pointer to the number of command line arguments
* @argv: a pointer to the array of comman line arguments
* @parameter_string: a string which is displayed in the
* first line of <option>--help</option> output, after
* <literal><replaceable>programname</replaceable [OPTION...]</literal>
* @entries: a %NULL terminated array of #GOptionEntry<!-- -->s
* describing the options of your program
* @translation_domain: a translation domain to use for translating
* the <option>--help</option> output for the options in @entries
* with gettext(), or %NULL
* @error: a return location for a #GError
*
* This function does the same work as clutter_init(). Additionally,
* it allows you to add your own command line options, and it
* automatically generates nicely formatted <option>--help</option>
* output. Note that your program will be terminated after writing
* out the help output. Also note that, in case of error, the
* error message will be placed inside @error instead of being
* printed on the display.
*
* Return value: %CLUTTER_INIT_SUCCESS if Clutter has been successfully
* initialised, or other values or #ClutterInitError in case of
* error.
*
* Since: 0.2
*/
ClutterInitError
clutter_init_with_args (int *argc,
char ***argv,
char *parameter_string,
GOptionEntry *entries,
char *translation_domain,
GError **error)
{
ClutterMainContext *clutter_context;
GOptionContext *context;
GOptionGroup *group;
gboolean res;
GError *stage_error;
if (clutter_is_initialized)
return CLUTTER_INIT_SUCCESS;
if (!XInitThreads())
{
g_set_error (error, clutter_init_error_quark (),
CLUTTER_INIT_ERROR_THREADS,
"Unable to initialise the X threading");
return CLUTTER_INIT_ERROR_THREADS;
}
group = clutter_get_option_group ();
context = g_option_context_new (parameter_string);
g_option_context_add_group (context, group);
if (entries)
g_option_context_add_main_entries (context, entries, translation_domain);
res = g_option_context_parse (context, argc, argv, error);
g_option_context_free (context);
/* if res is FALSE, the error is filled for
* us by g_option_context_parse()
*/
if (!res)
return CLUTTER_INIT_ERROR_INTERNAL;
clutter_context = clutter_context_get_default ();
if (!clutter_context->xdpy)
{
g_set_error (error, clutter_init_error_quark (),
CLUTTER_INIT_ERROR_DISPLAY,
"Unable to connect to X DISPLAY. You should either "
"set the DISPLAY environment variable or use the "
"--display command line switch");
return CLUTTER_INIT_ERROR_DISPLAY;
}
stage_error = NULL;
if (!clutter_stage_init (clutter_context, &stage_error))
{
g_propagate_error (error, stage_error);
return CLUTTER_INIT_ERROR_INTERNAL;
}
/* At least GL 1.2 is needed for CLAMP_TO_EDGE */
g_return_val_if_fail(is_gl_version_at_least_12 (),
CLUTTER_INIT_ERROR_OPENGL);
if (!is_gl_version_at_least_12 ())
{
g_set_error (error, clutter_init_error_quark (),
CLUTTER_INIT_ERROR_OPENGL,
"Clutter needs at least version 1.2 of OpenGL");
return CLUTTER_INIT_ERROR_OPENGL;
}
/* Check available features */
clutter_feature_init ();
events_init ();
return CLUTTER_INIT_SUCCESS;
}
context->is_initialized = TRUE;
/**
* clutter_init:
* @argc: The number of arguments in @argv
* @argv: A pointer to an array of arguments.
*
* It will initialise everything needed to operate with Clutter and
* parses some standard command line options. @argc and @argv are
* adjusted accordingly so your own code will never see those standard
* arguments.
*
* Return value: 1 on success, < 0 on failure.
*/
ClutterInitError
clutter_init (int *argc,
char ***argv)
{
ClutterMainContext *context;
GError *stage_error;
if (clutter_is_initialized)
return CLUTTER_INIT_SUCCESS;
if (!XInitThreads())
return CLUTTER_INIT_ERROR_THREADS;
clutter_parse_args (argc, argv);
context = clutter_context_get_default ();
if (!context->xdpy)
{
g_critical ("Unable to connect to X DISPLAY. You should either "
"set the DISPLAY environment variable or use the "
"--display command line switch");
return CLUTTER_INIT_ERROR_DISPLAY;
}
stage_error = NULL;
if (!clutter_stage_init (context, &stage_error))
{
g_critical (stage_error->message);
g_error_free (stage_error);
return CLUTTER_INIT_ERROR_INTERNAL;
}
/* 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;
}
/* Check available features */
clutter_feature_init ();
events_init ();
return 1;
}

View File

@ -36,30 +36,7 @@
G_BEGIN_DECLS
#define CLUTTER_HAS_DEBUG_MESSGES 1
#if (CLUTTER_HAS_DEBUG_MESSGES)
#define CLUTTER_DBG(x, a...) \
if (clutter_want_debug()) \
{ g_printerr ( __FILE__ ":%d,%s() " x "\n", __LINE__, __func__, ##a); }
#define CLUTTER_GLERR() \
if (clutter_want_debug()) \
{ \
GLenum err = glGetError (); /* Roundtrip */ \
if (err != GL_NO_ERROR) \
{ \
g_printerr (__FILE__ ": GL Error: %x [at %s:%d]\n", \
err, __func__, __LINE__); \
} \
}
#else
#define CLUTTER_DBG(x, a...) do {} while (0)
#define CLUTTER_GLERR() do {} while (0)
#endif /* CLUTTER_HAS_DEBUG */
#define CLUTTER_MARK() CLUTTER_DBG("mark")
#define CLUTTER_INIT_ERROR (clutter_init_error_quark ())
typedef enum {
CLUTTER_INIT_SUCCESS = 1,
@ -70,38 +47,29 @@ typedef enum {
CLUTTER_INIT_ERROR_OPENGL = -4
} ClutterInitError;
ClutterInitError
clutter_init (int *argc, char ***argv);
GQuark clutter_init_error_quark (void);
void
clutter_main (void);
ClutterInitError clutter_init (int *argc,
char ***argv);
ClutterInitError clutter_init_with_args (int *argc,
char ***argv,
char *parameter_string,
GOptionEntry *entries,
char *translation_domain,
GError **error);
void
clutter_main_quit (void);
GOptionGroup * clutter_get_option_group (void);
gint
clutter_main_level (void);
void
clutter_redraw ();
Display*
clutter_xdisplay (void);
int
clutter_xscreen (void);
Window
clutter_root_xwindow (void);
gboolean
clutter_want_debug (void);
void
clutter_threads_enter (void);
void
clutter_threads_leave (void);
void clutter_main (void);
void clutter_main_quit (void);
gint clutter_main_level (void);
void clutter_redraw (void);
Display * clutter_xdisplay (void);
gint clutter_xscreen (void);
Window clutter_root_xwindow (void);
gboolean clutter_want_debug (void);
void clutter_threads_enter (void);
void clutter_threads_leave (void);
G_END_DECLS

View File

@ -43,6 +43,7 @@
#include <pango/pangoft2.h>
#include <clutter/clutter-debug.h>
G_BEGIN_DECLS

View File

@ -39,7 +39,8 @@
#include "clutter-util.h"
#include "clutter-marshal.h"
#include "clutter-enum-types.h"
#include "clutter-private.h" /* for DBG */
#include "clutter-private.h"
#include "clutter-debug.h"
#include <GL/glx.h>
#include <GL/gl.h>
@ -435,12 +436,18 @@ clutter_stage_realize (ClutterActor *actor)
glXMakeCurrent(clutter_xdisplay(), priv->xwin, priv->gl_context);
}
CLUTTER_DBG("===========================================")
CLUTTER_DBG("GL_VENDOR: %s\n", glGetString(GL_VENDOR));
CLUTTER_DBG("GL_RENDERER: %s\n", glGetString(GL_RENDERER));
CLUTTER_DBG("GL_VERSION: %s\n", glGetString(GL_VERSION));
CLUTTER_DBG("GL_EXTENSIONS: %s\n", glGetString(GL_EXTENSIONS));
CLUTTER_DBG("===========================================")
CLUTTER_NOTE (GL,
g_message ("\n"
"==========================================="
"GL_VENDOR: %s\n"
"GL_RENDERER: %s\n"
"GL_VERSION: %s\n"
"GL_EXTENSIONS: %s\n"
"===========================================",
glGetString (GL_VENDOR),
glGetString (GL_RENDERER),
glGetString (GL_VERSION),
glGetString (GL_EXTENSIONS)));
sync_gl_viewport (stage);
}

View File

@ -43,7 +43,8 @@
#include "clutter-marshal.h"
#include "clutter-feature.h"
#include "clutter-util.h"
#include "clutter-private.h" /* for DBG */
#include "clutter-private.h"
#include "clutter-debug.h"
#include <GL/glx.h>
#include <GL/gl.h>
@ -114,7 +115,7 @@ can_create (int width,
{
GLint new_width = 0;
CLUTTER_DBG("checking %ix%i", width, height);
CLUTTER_NOTE (TEXTURE, g_message ("checking %ix%i", width, height));
glTexImage2D (GL_PROXY_TEXTURE_2D, 0, GL_RGBA,
width, height, 0 /* border */,
@ -194,11 +195,15 @@ texture_init_tiles (ClutterTexture *texture)
&& (x_pot - priv->width < priv->max_tile_waste)
&& (y_pot - priv->height < priv->max_tile_waste)))
{
CLUTTER_DBG("x_pot:%i - width:%i < max_waste:%i",
x_pot, priv->width, priv->max_tile_waste);
CLUTTER_NOTE (TEXTURE, g_message ("x_pot:%i - width:%i < max_waste:%i",
x_pot,
priv->width,
priv->max_tile_waste));
CLUTTER_DBG("y_pot:%i - height:%i < max_waste:%i",
y_pot, priv->height, priv->max_tile_waste);
CLUTTER_NOTE (TEXTURE, g_message ("y_pot:%i - height:%i < max_waste:%i",
y_pot,
priv->height,
priv->max_tile_waste));
if (x_pot > y_pot)
x_pot /= 2;
@ -222,10 +227,12 @@ texture_init_tiles (ClutterTexture *texture)
priv->y_tiles = g_new (ClutterTextureTileDimention, priv->n_y_tiles);
tile_dimension (priv->height, y_pot, priv->max_tile_waste, priv->y_tiles);
CLUTTER_DBG("x_pot:%i, width:%i, y_pot:%i, height: %i max_waste:%i, "
" n_x_tiles: %i, n_y_tiles: %i",
x_pot, priv->width, y_pot, priv->height, priv->max_tile_waste,
priv->n_x_tiles, priv->n_y_tiles);
CLUTTER_NOTE (TEXTURE,
g_message ("x_pot:%i, width:%i, y_pot:%i, height: %i "
"max_waste:%i, n_x_tiles: %i, n_y_tiles: %i",
x_pot, priv->width, y_pot, priv->height,
priv->max_tile_waste,
priv->n_x_tiles, priv->n_y_tiles));
}
@ -301,8 +308,9 @@ texture_render_to_gl_quad (ClutterTexture *texture,
actual_w = priv->x_tiles[x].size - priv->x_tiles[x].waste;
actual_h = priv->y_tiles[y].size - priv->y_tiles[y].waste;
CLUTTER_DBG("rendering text tile x: %i, y: %i - %ix%i",
x, y, actual_w, actual_h);
CLUTTER_NOTE (TEXTURE,
g_message ("rendering text tile x: %i, y: %i - %ix%i",
x, y, actual_w, actual_h));
tx = (float) actual_w / priv->x_tiles[x].size;
ty = (float) actual_h / priv->y_tiles[y].size;
@ -390,7 +398,7 @@ texture_upload_data (ClutterTexture *texture,
create_textures = TRUE;
}
CLUTTER_DBG("syncing for single tile");
CLUTTER_NOTE (TEXTURE, g_message ("syncing for single tile"));
glBindTexture(priv->target_type, priv->tiles[0]);
@ -449,8 +457,9 @@ texture_upload_data (ClutterTexture *texture,
/* Multiple tiled texture */
CLUTTER_DBG("syncing for multiple tiles for %ix%i pixbuf",
priv->width, priv->height);
CLUTTER_NOTE (TEXTURE,
g_message ("syncing for multiple tiles for %ix%i pixbuf",
priv->width, priv->height));
g_return_if_fail (priv->x_tiles != NULL && priv->y_tiles != NULL);
@ -485,13 +494,12 @@ texture_upload_data (ClutterTexture *texture,
src_h = priv->height - priv->y_tiles[y].pos;
}
CLUTTER_DBG("copying tile %i,%i - %ix%i to 0,0 %ix%i",
priv->x_tiles[x].pos,
priv->y_tiles[y].pos,
src_w,
src_h,
priv->x_tiles[x].size,
priv->y_tiles[y].size);
CLUTTER_NOTE (TEXTURE,
g_message ("copying tile %i,%i - %ix%i to 0,0 %ix%i",
priv->x_tiles[x].pos, priv->y_tiles[y].pos,
src_w, src_h,
priv->x_tiles[x].size,
priv->y_tiles[y].size));
for (dy = 0; dy < src_h; dy++)
{
@ -588,7 +596,7 @@ clutter_texture_unrealize (ClutterActor *actor)
texture_free_gl_resources (texture);
CLUTTER_DBG("Texture unrealized");
CLUTTER_NOTE (TEXTURE, g_message ("Texture unrealized"));
}
static void
@ -616,14 +624,16 @@ clutter_texture_realize (ClutterActor *actor)
/* Dont allow realization with no pixbuf - note set_pixbuf/data
* will set realize flags.
*/
CLUTTER_DBG("*** Texture has no image data cannot realize ***");
CLUTTER_DBG("*** flags %i ***", actor->flags);
CLUTTER_NOTE (TEXTURE,
g_warning ("Texture has no image data cannot realize"));
CLUTTER_NOTE (TEXTURE, g_message ("flags %i", actor->flags));
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
CLUTTER_DBG("*** flags %i ***", actor->flags);
CLUTTER_NOTE (TEXTURE, g_message ("flags %i", actor->flags));
return;
}
CLUTTER_DBG("Texture realized");
CLUTTER_NOTE (TEXTURE, g_message ("Texture realized"));
}
static void
@ -645,9 +655,10 @@ clutter_texture_paint (ClutterActor *self)
gint x1, y1, x2, y2;
guint8 opacity;
CLUTTER_DBG("@@@ for '%s' @@@",
clutter_actor_get_name(self) ?
clutter_actor_get_name(self) : "unknown");
CLUTTER_NOTE (PAINT,
g_message ("@@@ for '%s' @@@",
clutter_actor_get_name (self) ? clutter_actor_get_name (self)
: "unknown"));
glPushMatrix();
glEnable(GL_BLEND);
@ -656,7 +667,7 @@ clutter_texture_paint (ClutterActor *self)
opacity = clutter_actor_get_opacity(self);
CLUTTER_DBG("setting opacity to %i\n", opacity);
CLUTTER_NOTE (PAINT, g_message ("setting opacity to %i\n", opacity));
glColor4ub(255, 255, 255, opacity);
clutter_actor_get_coords (self, &x1, &y1, &x2, &y2);
@ -730,7 +741,8 @@ clutter_texture_set_property (GObject *object,
&& priv->tiled == TRUE)
priv->target_type = GL_TEXTURE_2D;
CLUTTER_DBG("Texture is tiled ? %i", priv->tiled);
CLUTTER_NOTE (TEXTURE, g_message ("Texture is tiled ? %s",
priv->tiled ? "yes" : "no"));
break;
case PROP_MAX_TILE_WASTE:
priv->max_tile_waste = g_value_get_int (value);
@ -1167,7 +1179,9 @@ clutter_texture_set_from_data (ClutterTexture *texture,
texture_init_tiles (texture);
}
CLUTTER_DBG("set size %ix%i\n", priv->width, priv->height);
CLUTTER_NOTE (TEXTURE, g_message ("set size %ix%i\n",
priv->width,
priv->height));
texture_upload_data (texture, data, has_alpha,
width, height, rowstride, bpp);

View File

@ -38,12 +38,13 @@
#include "clutter-timeline.h"
#include "clutter-main.h"
#include "clutter-private.h" /* for DBG */
#include "clutter-marshal.h"
#include "clutter-private.h"
#include "clutter-debug.h"
G_DEFINE_TYPE (ClutterTimeline, clutter_timeline, G_TYPE_OBJECT);
#define FPS_TO_INTERVAL(f) (1000/f)
#define FPS_TO_INTERVAL(f) (1000 / (f))
struct _ClutterTimelinePrivate
{
@ -292,7 +293,7 @@ timeline_timeout_func (gpointer data)
n_frames = 1;
if (n_frames > 1)
CLUTTER_DBG("*** Skipping %i frames ***", n_frames);
CLUTTER_NOTE (MISC, g_message ("Skipping %i frames", n_frames));
}
else
{

View File

@ -22,10 +22,15 @@
* Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <math.h>
#include "pangoclutter.h"
#include "pangoclutter-private.h"
#include "../clutter-debug.h"
/*
* Texture cache support code
@ -99,7 +104,8 @@ tc_get (tc_area *area, int width, int height)
/* create a new texture if necessary */
if (!match)
{
CLUTTER_DBG("creating new texture %i x %i\n", TC_WIDTH, TC_HEIGHT);
CLUTTER_NOTE (PANGO, g_message ("creating new texture %i x %i\n",
TC_WIDTH, TC_HEIGHT));
match = g_slice_new (tc_texture);
match->next = first_texture;
@ -332,7 +338,7 @@ draw_glyph (PangoRenderer *renderer_,
g->left = bm.left;
g->top = bm.top;
CLUTTER_DBG("cache fail; subimage2d %i\n", glyph);
CLUTTER_NOTE (PANGO, g_message ("cache fail; subimage2d %i\n", glyph));
glBindTexture (GL_TEXTURE_2D, g->tex.name);
glPixelStorei (GL_UNPACK_ROW_LENGTH, bm.stride);
@ -352,7 +358,7 @@ draw_glyph (PangoRenderer *renderer_,
renderer->curtex = g->tex.name;
glBegin (GL_QUADS);
}
else CLUTTER_DBG("cache succsess %i\n", glyph);
else CLUTTER_NOTE (PANGO, g_message ("cache succsess %i\n", glyph));
x += g->left;
y -= g->top;

View File

@ -137,8 +137,8 @@ else
if test "x$enable_debug" = "xno"; then
CLUTTER_DEBUG_CFLAGS="-DG_DISABLE_ASSERT -DG_DISABLE_CHECKS -DG_DISABLE_CAST
_CHECKS"
else
CLUTTER_DEBUG_CFLAGS="-DG_DISABLE_CAST_CHECKS"
else # minimum
CLUTTER_DEBUG_CFLAGS="-DG_ENABLE_DEBUG -DG_DISABLE_CAST_CHECKS"
fi
fi

View File

@ -48,6 +48,7 @@ CFILE_GLOB=$(top_srcdir)/clutter/*.c
# Header files to ignore when scanning.
# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
IGNORE_HFILES=\
clutter-debug.h \
clutter-private.h \
clutter-marshal.h \
clutter-keysyms.h \

View File

@ -493,11 +493,6 @@ clutter_root_xwindow
clutter_want_debug
clutter_threads_enter
clutter_threads_leave
<SUBSECTION Private>
CLUTTER_HAS_DEBUG_MESSGES
CLUTTER_DBG
CLUTTER_GLERR
CLUTTER_MARK
</SECTION>
<SECTION>

View File

@ -2,19 +2,38 @@
#include <math.h>
#include <errno.h>
#include <stdlib.h>
#include <glib.h>
#define TRAILS 0
#define NHANDS 6
#define RADIUS ((CLUTTER_STAGE_WIDTH()+CLUTTER_STAGE_HEIGHT())/6)
#define RADIUS ((CLUTTER_STAGE_WIDTH()+CLUTTER_STAGE_HEIGHT())/NHANDS)
typedef struct SuperOH
{
ClutterActor *hand[NHANDS], *bgtex;
ClutterActor **hand, *bgtex;
ClutterActor *group;
GdkPixbuf *bgpixb;
} SuperOH;
static gint n_hands = NHANDS;
static GOptionEntry super_oh_entries[] = {
{
"num-hands", 'n',
0,
G_OPTION_ARG_INT, &n_hands,
"Number of hands", "HANDS"
},
{ NULL }
};
static gint
get_radius (void)
{
return (CLUTTER_STAGE_WIDTH() + CLUTTER_STAGE_HEIGHT()) / n_hands;
}
void
screensaver_setup (void)
{
@ -98,17 +117,17 @@ frame_cb (ClutterTimeline *timeline,
#endif
/* Rotate everything clockwise about stage center*/
clutter_actor_rotate_z (CLUTTER_ACTOR(oh->group),
frame_num,
CLUTTER_STAGE_WIDTH()/2,
CLUTTER_STAGE_HEIGHT()/2);
for (i = 0; i < NHANDS; i++)
clutter_actor_rotate_z (CLUTTER_ACTOR (oh->group),
frame_num,
CLUTTER_STAGE_WIDTH() / 2,
CLUTTER_STAGE_HEIGHT() / 2);
for (i = 0; i < n_hands; i++)
{
/* rotate each hand around there centers */
clutter_actor_rotate_z (oh->hand[i],
- 6.0 * frame_num,
clutter_actor_get_width (oh->hand[i])/2,
clutter_actor_get_height (oh->hand[i])/2);
- 6.0 * frame_num,
clutter_actor_get_width (oh->hand[i]) / 2,
clutter_actor_get_height (oh->hand[i]) / 2);
}
/*
@ -128,8 +147,22 @@ main (int argc, char *argv[])
GdkPixbuf *pixbuf;
SuperOH *oh;
gint i;
GError *error;
clutter_init (&argc, &argv);
error = NULL;
clutter_init_with_args (&argc, &argv,
NULL,
super_oh_entries,
NULL,
&error);
if (error)
{
g_warning ("Unable to initialise Clutter:\n%s",
error->message);
g_error_free (error);
exit (1);
}
stage = clutter_stage_get_default ();
@ -160,10 +193,12 @@ main (int argc, char *argv[])
/* create a new group to hold multiple actors in a group */
oh->group = clutter_group_new();
for (i = 0; i < NHANDS; i++)
oh->hand = g_new (ClutterActor*, n_hands);
for (i = 0; i < n_hands; i++)
{
gint x, y, w, h;
gint radius = get_radius ();
/* Create a texture from pixbuf, then clone in to same resources */
if (i == 0)
@ -175,10 +210,14 @@ main (int argc, char *argv[])
w = clutter_actor_get_width (oh->hand[0]);
h = clutter_actor_get_height (oh->hand[0]);
x = CLUTTER_STAGE_WIDTH() / 2
+ RADIUS * cos (i * M_PI / (NHANDS/2)) - w/2;
y = CLUTTER_STAGE_HEIGHT() / 2
+ RADIUS * sin (i * M_PI / (NHANDS/2)) - h/2;
x = CLUTTER_STAGE_WIDTH () / 2
+ radius
* cos (i * M_PI / (n_hands / 2))
- w / 2;
y = CLUTTER_STAGE_HEIGHT () / 2
+ radius
* sin (i * M_PI / (n_hands / 2))
- h / 2;
clutter_actor_set_position (oh->hand[i], x, y);
@ -218,12 +257,16 @@ main (int argc, char *argv[])
g_object_set(timeline, "loop", TRUE, 0); /* have it loop */
/* fire a callback for frame change */
g_signal_connect(timeline, "new-frame", G_CALLBACK (frame_cb), oh);
g_signal_connect (timeline, "new-frame",
G_CALLBACK (frame_cb), oh);
/* and start it */
clutter_timeline_start (timeline);
clutter_main();
g_free (oh->hand);
g_free (oh);
return 0;
}