diff --git a/ChangeLog b/ChangeLog index 7245667d9..f69d40f2b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,66 @@ +2006-11-21 Emmanuele Bassi + + * 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 * configure.ac: Rename G_ENABLE_DEBUG to CLUTTER_ENABLE_DEBUG. diff --git a/clutter/Makefile.am b/clutter/Makefile.am index 44d4a3d28..aec8cd630 100644 --- a/clutter/Makefile.am +++ b/clutter/Makefile.am @@ -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) diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index a10772d8c..b13b2fe76 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -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)) { diff --git a/clutter/clutter-alpha.c b/clutter/clutter-alpha.c index 86a069f2e..665086415 100644 --- a/clutter/clutter-alpha.c +++ b/clutter/clutter-alpha.c @@ -49,10 +49,13 @@ #include "config.h" #endif +#include + #include "clutter-alpha.h" #include "clutter-main.h" #include "clutter-marshal.h" -#include +#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); } diff --git a/clutter/clutter-behaviour-opacity.c b/clutter/clutter-behaviour-opacity.c index 96b2d350e..75a6c5cf0 100644 --- a/clutter/clutter-behaviour-opacity.c +++ b/clutter/clutter-behaviour-opacity.c @@ -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 @@ -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, diff --git a/clutter/clutter-behaviour-scale.c b/clutter/clutter-behaviour-scale.c index afc52f31d..2f9288606 100644 --- a/clutter/clutter-behaviour-scale.c +++ b/clutter/clutter-behaviour-scale.c @@ -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 @@ -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; diff --git a/clutter/clutter-clone-texture.c b/clutter/clutter-clone-texture.c index e22f409da..b27500852 100644 --- a/clutter/clutter-clone-texture.c +++ b/clutter/clutter-clone-texture.c @@ -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), diff --git a/clutter/clutter-debug.h b/clutter/clutter-debug.h new file mode 100644 index 000000000..13b9750c9 --- /dev/null +++ b/clutter/clutter-debug.h @@ -0,0 +1,48 @@ +#ifndef __CLUTTER_DEBUG_H__ +#define __CLUTTER_DEBUG_H__ + +#include + +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__ */ diff --git a/clutter/clutter-feature.c b/clutter/clutter-feature.c index 02c42400d..4655a8251 100644 --- a/clutter/clutter-feature.c +++ b/clutter/clutter-feature.c @@ -31,8 +31,6 @@ */ #include "config.h" -#include "clutter-main.h" -#include "clutter-feature.h" #include #include @@ -42,7 +40,12 @@ #include #include - #include +#include + +#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")); + } } } diff --git a/clutter/clutter-label.c b/clutter/clutter-label.c index 99aed1650..9b089c49f 100644 --- a/clutter/clutter-label.c +++ b/clutter/clutter-label.c @@ -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; } diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c index 7db74a77d..2f99cab5f 100644 --- a/clutter/clutter-main.c +++ b/clutter/clutter-main.c @@ -30,8 +30,9 @@ * functions for mainloops, events and threads */ - +#ifdef HAVE_CONFIG_H #include "config.h" +#endif #include @@ -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 output, after + * programname + * @entries: a %NULL terminated array of #GOptionEntrys + * describing the options of your program + * @translation_domain: a translation domain to use for translating + * the 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 + * 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; } - diff --git a/clutter/clutter-main.h b/clutter/clutter-main.h index 8cc7f6968..51f7211d8 100644 --- a/clutter/clutter-main.h +++ b/clutter/clutter-main.h @@ -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 diff --git a/clutter/clutter-private.h b/clutter/clutter-private.h index 781d58b00..2bc8edb27 100644 --- a/clutter/clutter-private.h +++ b/clutter/clutter-private.h @@ -43,6 +43,7 @@ #include +#include G_BEGIN_DECLS diff --git a/clutter/clutter-stage.c b/clutter/clutter-stage.c index 655904346..ca9c77f9c 100644 --- a/clutter/clutter-stage.c +++ b/clutter/clutter-stage.c @@ -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 #include @@ -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); } diff --git a/clutter/clutter-texture.c b/clutter/clutter-texture.c index 6f8216572..d7e0fcc61 100644 --- a/clutter/clutter-texture.c +++ b/clutter/clutter-texture.c @@ -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 #include @@ -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); diff --git a/clutter/clutter-timeline.c b/clutter/clutter-timeline.c index aa428afc4..93a6e38c0 100644 --- a/clutter/clutter-timeline.c +++ b/clutter/clutter-timeline.c @@ -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 { diff --git a/clutter/pango/pangoclutter-render.c b/clutter/pango/pangoclutter-render.c index 3bdec3625..e65de9ba7 100644 --- a/clutter/pango/pangoclutter-render.c +++ b/clutter/pango/pangoclutter-render.c @@ -22,10 +22,15 @@ * Boston, MA 02111-1307, USA. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #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; diff --git a/configure.ac b/configure.ac index 79929ecd5..f2f99e68f 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/doc/reference/Makefile.am b/doc/reference/Makefile.am index a3070f8ad..9e5caa106 100644 --- a/doc/reference/Makefile.am +++ b/doc/reference/Makefile.am @@ -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 \ diff --git a/doc/reference/clutter-sections.txt b/doc/reference/clutter-sections.txt index b2fb07753..49186b643 100644 --- a/doc/reference/clutter-sections.txt +++ b/doc/reference/clutter-sections.txt @@ -493,11 +493,6 @@ clutter_root_xwindow clutter_want_debug clutter_threads_enter clutter_threads_leave - -CLUTTER_HAS_DEBUG_MESSGES -CLUTTER_DBG -CLUTTER_GLERR -CLUTTER_MARK
diff --git a/examples/super-oh.c b/examples/super-oh.c index 52eb77276..6d17036ca 100644 --- a/examples/super-oh.c +++ b/examples/super-oh.c @@ -2,19 +2,38 @@ #include #include #include +#include #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; }