2007-09-27 Matthew Allum <mallum@openedhand.com>

* clutter/clutter-event.c:
        * clutter/clutter-event.h:
        * clutter/clutter-main.c:
        Further event tweaks;
        - Ref the event actor source
        - Protect against off stage events (button releases)
        - Move more into ClutterEventAny
        - Add a click count to button event (as yet unused)
        - Minor cleanups

        * clutter/clutter-actor.c:
        Make scale x/y a property.

        * clutter/clutter-private.h:
        Remove _clutter_actor_apply_modelview*

        * clutter/eglx/clutter-backend-egl.c:
        Warning cleanup

        * clutter/eglx/clutter-stage-egl.c:
        * clutter/glx/clutter-stage-glx.c:
        * clutter/sdl/clutter-stage-sdl.c:
        Avoid setting viewport directly, but set sync flag.

        * clutter/pango/pangoclutter-render.c: (draw_glyph):
        Minor cleanups.

        * clutter/Makefile.am:
        * tests/Makefile.am:
        * tests/test-score.c
        * clutter/clutter.h:
        * clutter/clutter-score.h:
        * clutter/clutter-score.c:
        Add very initial (broken) ClutterScore implementation.
This commit is contained in:
Matthew Allum 2007-09-27 21:38:38 +00:00
parent bc7b1b3a16
commit 5ab0ed5a00
18 changed files with 833 additions and 63 deletions

View File

@ -1,3 +1,40 @@
2007-09-27 Matthew Allum <mallum@openedhand.com>
* clutter/clutter-event.c:
* clutter/clutter-event.h:
* clutter/clutter-main.c:
Further event tweaks;
- Ref the event actor source
- Protect against off stage events (button releases)
- Move more into ClutterEventAny
- Add a click count to button event (as yet unused)
- Minor cleanups
* clutter/clutter-actor.c:
Make scale x/y a property.
* clutter/clutter-private.h:
Remove _clutter_actor_apply_modelview*
* clutter/eglx/clutter-backend-egl.c:
Warning cleanup
* clutter/eglx/clutter-stage-egl.c:
* clutter/glx/clutter-stage-glx.c:
* clutter/sdl/clutter-stage-sdl.c:
Avoid setting viewport directly, but set sync flag.
* clutter/pango/pangoclutter-render.c: (draw_glyph):
Minor cleanups.
* clutter/Makefile.am:
* tests/Makefile.am:
* tests/test-score.c
* clutter/clutter.h:
* clutter/clutter-score.h:
* clutter/clutter-score.c:
Add very initial (broken) ClutterScore implementation.
2007-09-25 Ross Burton <ross@openedhand.com>
Merge from stable.

View File

@ -68,6 +68,7 @@ source_h = \
$(srcdir)/clutter-stage.h \
$(srcdir)/clutter-texture.h \
$(srcdir)/clutter-timeline.h \
$(srcdir)/clutter-score.h \
$(srcdir)/clutter-timeout-pool.h \
$(srcdir)/clutter-types.h \
$(srcdir)/clutter-units.h \
@ -151,6 +152,7 @@ source_c = \
clutter-rectangle.c \
clutter-texture.c \
clutter-timeline.c \
clutter-score.c \
clutter-timeout-pool.c \
clutter-util.c \
clutter-vbox.c \

View File

@ -82,7 +82,9 @@ enum
PROP_HAS_CLIP,
PROP_OPACITY,
PROP_NAME,
PROP_VISIBLE
PROP_VISIBLE,
PROP_SCALE_X,
PROP_SCALE_Y
};
enum
@ -106,6 +108,12 @@ enum
static guint actor_signals[LAST_SIGNAL] = { 0, };
static
void _clutter_actor_apply_modelview_transform (ClutterActor * self);
static
void _clutter_actor_apply_modelview_transform_recursive (ClutterActor * self);
static gboolean
redraw_update_idle (gpointer data)
{
@ -397,7 +405,8 @@ clutter_actor_transform_point (ClutterActor *actor,
* @vertex: The translated #ClutterVertex
*
* Transforms point in coordinates relative to the actor
* into screen coordiances
* into screen coordiances with the current actor tranform
* (i.e. scale, rotation etc)
*
* Since: 0.4
**/
@ -582,7 +591,7 @@ clutter_actor_get_vertices (ClutterActor *self,
* This function does not push/pop matrix; it is the responsibility
* of the caller to do so as appropriate
*/
void
static void
_clutter_actor_apply_modelview_transform (ClutterActor * self)
{
ClutterActorPrivate *priv = self->priv;
@ -640,7 +649,7 @@ _clutter_actor_apply_modelview_transform (ClutterActor * self)
* This function does not push/pop matrix; it is the responsibility
* of the caller to do so as appropriate
*/
void
static void
_clutter_actor_apply_modelview_transform_recursive (ClutterActor * self)
{
ClutterActor * parent;
@ -878,6 +887,18 @@ clutter_actor_set_property (GObject *object,
else
clutter_actor_hide (actor);
break;
case PROP_SCALE_X:
clutter_actor_set_scalex
(actor,
CLUTTER_FLOAT_TO_FIXED (g_value_get_double (value)),
priv->scale_y);
break;
case PROP_SCALE_Y:
clutter_actor_set_scalex
(actor,
priv->scale_x,
CLUTTER_FLOAT_TO_FIXED (g_value_get_double (value)));
break;
case PROP_CLIP:
{
ClutterGeometry *geom = g_value_get_boxed (value);
@ -935,6 +956,12 @@ clutter_actor_get_property (GObject *object,
case PROP_CLIP:
g_value_set_boxed (value, &(priv->clip));
break;
case PROP_SCALE_X:
g_value_set_double (value, CLUTTER_FIXED_TO_DOUBLE (priv->scale_x));
break;
case PROP_SCALE_Y:
g_value_set_double (value, CLUTTER_FIXED_TO_DOUBLE (priv->scale_y));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -1100,6 +1127,43 @@ clutter_actor_class_init (ClutterActorClass *klass)
NULL,
CLUTTER_PARAM_READWRITE));
/**
* ClutterActor::scale-x:
*
* The horizontal scale of the actor
*
* Since: 0.6
*/
g_object_class_install_property
(object_class,
PROP_SCALE_X,
g_param_spec_double ("scale-x",
"Scale-X",
"Scale X",
0.0,
G_MAXDOUBLE,
1.0,
CLUTTER_PARAM_READWRITE));
/**
* ClutterActor::scale-y:
*
* The vertical scale of the actor
*
* Since: 0.6
*/
g_object_class_install_property
(object_class,
PROP_SCALE_Y,
g_param_spec_double ("scale-y",
"Scale-Y",
"Scale Y",
0.0,
G_MAXDOUBLE,
1.0,
CLUTTER_PARAM_READWRITE));
/**
* ClutterActor::destroy:
* @actor: the object which received the signal
@ -1887,6 +1951,15 @@ clutter_actor_set_scalex (ClutterActor *self,
self->priv->scale_x = scale_x;
self->priv->scale_y = scale_y;
g_object_ref (self);
g_object_freeze_notify (G_OBJECT (self));
g_object_notify (G_OBJECT (self), "scale-x");
g_object_notify (G_OBJECT (self), "scale-y");
g_object_thaw_notify (G_OBJECT (self));
g_object_unref (self);
if (CLUTTER_ACTOR_IS_VISIBLE (self))
clutter_actor_queue_redraw (self);
}

View File

@ -404,6 +404,11 @@ clutter_event_free (ClutterEvent *event)
{
if (G_LIKELY (event))
{
ClutterActor *source = NULL;
source = clutter_event_get_source (event);
if (source)
g_object_unref (source);
g_slice_free (ClutterEvent, event);
}
}
@ -422,7 +427,6 @@ ClutterEvent *
clutter_event_get (void)
{
ClutterMainContext *context = clutter_context_get_default ();
GList *item;
if (!context->events_queue)
return NULL;

View File

@ -51,6 +51,10 @@ typedef enum {
CLUTTER_BUTTON5_MASK = 1 << 12
} ClutterModifierType;
typedef enum {
CLUTTER_EVENT_FLAG_COOKED = 1 << 0,
} ClutterEventFlags;
typedef enum
{
CLUTTER_NOTHING = 0,
@ -100,12 +104,15 @@ typedef struct _ClutterInputDevice ClutterInputDevice;
struct _ClutterAnyEvent
{
ClutterEventType type;
guint32 time;
ClutterEventFlags flags;
};
struct _ClutterKeyEvent
{
ClutterEventType type;
guint32 time;
ClutterEventFlags flags;
ClutterModifierType modifier_state;
guint keyval;
guint16 hardware_keycode;
@ -116,10 +123,12 @@ struct _ClutterButtonEvent
{
ClutterEventType type;
guint32 time;
ClutterEventFlags flags;
gint x;
gint y;
ClutterModifierType modifier_state;
guint32 button;
guint click_count;
gdouble *axes; /* Future use */
ClutterInputDevice *device; /* Future use */
ClutterActor *source;
@ -129,6 +138,7 @@ struct _ClutterMotionEvent
{
ClutterEventType type;
guint32 time;
ClutterEventFlags flags;
gint x;
gint y;
ClutterModifierType modifier_state;
@ -141,6 +151,7 @@ struct _ClutterScrollEvent
{
ClutterEventType type;
guint32 time;
ClutterEventFlags flags;
gint x;
gint y;
ClutterScrollDirection direction;
@ -153,6 +164,8 @@ struct _ClutterScrollEvent
struct _ClutterStageStateEvent
{
ClutterEventType type;
guint32 time;
ClutterEventFlags flags;
ClutterStageState changed_mask;
ClutterStageState new_state;
};

View File

@ -406,8 +406,8 @@ sort_z_order (gconstpointer a,
{
int depth_a, depth_b;
depth_a = clutter_actor_get_depth (a);
depth_b = clutter_actor_get_depth (b);
depth_a = clutter_actor_get_depth (CLUTTER_ACTOR(a));
depth_b = clutter_actor_get_depth (CLUTTER_ACTOR(b));
if (depth_a == depth_b)
return 0;

View File

@ -148,7 +148,7 @@ clutter_redraw (void)
CLUTTER_UNSET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_SYNC_MATRICES);
}
/* Call through ti the actual backend to do the painting down from
/* Call through to the actual backend to do the painting down from
* the stage. It will likely need to swap buffers, vblank sync etc
* which will be windowing system dependant.
*/
@ -200,6 +200,10 @@ clutter_get_motion_events_enabled (void)
void
clutter_do_event (ClutterEvent *event)
{
/* FIXME: This should probably be clutter_cook_event() - it would
* take a raw event from the backend and 'cook' it so its more tasty.
*
*/
ClutterMainContext *context;
ClutterBackend *backend;
ClutterActor *stage;
@ -208,15 +212,12 @@ clutter_do_event (ClutterEvent *event)
context = clutter_context_get_default ();
backend = context->backend;
stage = _clutter_backend_get_stage (backend);
if (!stage)
return;
CLUTTER_TIMESTAMP (EVENT, "Event received");
/* TODO:
*
*/
switch (event->type)
{
case CLUTTER_NOTHING:
@ -224,7 +225,6 @@ clutter_do_event (ClutterEvent *event)
case CLUTTER_DESTROY_NOTIFY:
case CLUTTER_DELETE:
/* FIXME: handle delete working in stage */
if (clutter_stage_event (CLUTTER_STAGE (stage), event))
clutter_main_quit ();
break;
@ -237,8 +237,7 @@ clutter_do_event (ClutterEvent *event)
g_return_if_fail (actor != NULL);
/* FIXME: should we ref ? */
event->key.source = actor;
event->key.source = g_object_ref(actor);
/* bubble up */
do
@ -253,7 +252,7 @@ clutter_do_event (ClutterEvent *event)
if (context->motion_events_per_actor == FALSE)
{
/* Only stage gets motion events */
event->motion.source = stage;
event->motion.source = g_object_ref(stage);
clutter_actor_event (stage, event);
break;
}
@ -268,6 +267,15 @@ clutter_do_event (ClutterEvent *event)
clutter_event_get_coords (event, &x, &y);
/* Safety on - probably a release off stage ?
* FIXME: should likely deliver the release somehow - grabs ?
*/
if (x > CLUTTER_STAGE_WIDTH()
|| y > CLUTTER_STAGE_HEIGHT()
|| x < 0
|| y < 0)
break;
/* Map the event to a reactive actor */
actor = _clutter_do_pick (CLUTTER_STAGE (stage),
x, y,
@ -277,9 +285,9 @@ clutter_do_event (ClutterEvent *event)
x, y, actor);
if (event->type == CLUTTER_SCROLL)
event->scroll.source = actor;
event->scroll.source = g_object_ref(actor);
else
event->button.source = actor;
event->button.source = g_object_ref(actor);
/* Motion enter leave events */
if (event->type == CLUTTER_MOTION)
@ -300,6 +308,8 @@ clutter_do_event (ClutterEvent *event)
* FIXME: for an optimisation should check if there are
* actually any reactive actors and avoid the pick all togeather
* (signalling just the stage). Should be big help for gles.
*
* FIXME: Actors be able to stop emission.
*/
while (actor)
{

View File

@ -137,10 +137,6 @@ ClutterActor* _clutter_do_pick (ClutterStage *stage,
/* Does this need to be private ? */
void clutter_do_event (ClutterEvent *event);
void _clutter_actor_apply_modelview_transform (ClutterActor * self);
void _clutter_actor_apply_modelview_transform_recursive (ClutterActor * self);
G_END_DECLS
#endif /* _HAVE_CLUTTER_PRIVATE_H */

501
clutter/clutter-score.c Normal file
View File

@ -0,0 +1,501 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Authored By Matthew Allum <mallum@openedhand.com>
*
* Copyright (C) 2007 OpenedHand
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* IDEAS:
* API;
* - add()
* + an new timeline to beginning of score
* - append (timeline_existing, timeline_new, delay)
* + appends a new timeline to an existing one
*
* ScoreEntry
* {
* Timeline *base;
* GList *next_timelines; - to start on completion of base,
* (points to score entrys)
* Callback id;
* delay
* }
*
* start()/stop(),remove(),remove_all() ?
*/
/**
* SECTION:clutter-score @short_description: A class for sequencing
* multiple #ClutterTimelines in order
*
* #ClutterScore is a base class for sequencing multiple timelines in order.
*/
#ifndef HAVE_CONFIG_H
#include "config.h"
#endif
#include "clutter-score.h"
#include "clutter-main.h"
#include "clutter-marshal.h"
#include "clutter-private.h"
#include "clutter-debug.h"
G_DEFINE_TYPE (ClutterScore, clutter_score, G_TYPE_OBJECT);
typedef struct ClutterScoreEntry
{
ClutterTimeline *timeline;
gulong handler_id;
GSList *child_entries;
ClutterScore *score;
}
ClutterScoreEntry;
struct _ClutterScorePrivate
{
GSList *entries;
GHashTable *running_timelines;
guint loop : 1;
};
enum
{
PROP_0,
PROP_LOOP
};
enum
{
NEW_TIMELINE,
STARTED,
PAUSED,
COMPLETED,
LAST_SIGNAL
};
static int score_signals[LAST_SIGNAL] = { 0 };
static void start_entry (ClutterScoreEntry *entry);
/* Object */
static void
clutter_score_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
ClutterScore *score;
ClutterScorePrivate *priv;
score = CLUTTER_SCORE(object);
priv = score->priv;
switch (prop_id)
{
case PROP_LOOP:
priv->loop = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
clutter_score_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
ClutterScore *score;
ClutterScorePrivate *priv;
score = CLUTTER_SCORE(object);
priv = score->priv;
switch (prop_id)
{
case PROP_LOOP:
g_value_set_boolean (value, priv->loop);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
clutter_score_finalize (GObject *object)
{
G_OBJECT_CLASS (clutter_score_parent_class)->finalize (object);
}
static void
clutter_score_dispose (GObject *object)
{
ClutterScore *self = CLUTTER_SCORE(object);
ClutterScorePrivate *priv;
priv = self->priv;
if (priv != NULL)
{
}
G_OBJECT_CLASS (clutter_score_parent_class)->dispose (object);
}
static void
clutter_score_class_init (ClutterScoreClass *klass)
{
GObjectClass *object_class;
object_class = (GObjectClass*) klass;
object_class->set_property = clutter_score_set_property;
object_class->get_property = clutter_score_get_property;
object_class->finalize = clutter_score_finalize;
object_class->dispose = clutter_score_dispose;
g_type_class_add_private (klass, sizeof (ClutterScorePrivate));
#if 0
/**
* ClutterScore::new-frame:
* @score: the score which received the signal
* @timeline: the number of the new frame
*
* The ::new-timeline signal is emitted each time a new timeline in the
* score is reached.
*/
score_signals[NEW_TIMELINE] =
g_signal_new ("new-timeline",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ClutterScoreClass, new_frame),
NULL, NULL,
clutter_marshal_VOID__OBJECT,
G_TYPE_NONE,
1, CLUTTER_TYPE_TIMELINE);
score_signals[COMPLETED] =
g_signal_new ("completed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ClutterScoreClass, completed),
NULL, NULL,
clutter_marshal_VOID__VOID,
G_TYPE_NONE, 0);
score_signals[STARTED] =
g_signal_new ("started",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ClutterScoreClass, started),
NULL, NULL,
clutter_marshal_VOID__VOID,
G_TYPE_NONE, 0);
score_signals[PAUSED] =
g_signal_new ("paused",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ClutterScoreClass, paused),
NULL, NULL,
clutter_marshal_VOID__VOID,
G_TYPE_NONE, 0);
#endif
}
static void
clutter_score_init (ClutterScore *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self,
CLUTTER_TYPE_SCORE,
ClutterScorePrivate);
self->priv->running_timelines = g_hash_table_new(NULL, NULL);
}
/**
* clutter_score_set_loop:
* @score: a #ClutterScore
* @loop: %TRUE for enable looping
*
* Sets whether @score should loop.
*/
void
clutter_score_set_loop (ClutterScore *score,
gboolean loop)
{
g_return_if_fail (CLUTTER_IS_SCORE (score));
if (score->priv->loop != loop)
{
g_object_ref (score);
score->priv->loop = loop;
g_object_notify (G_OBJECT (score), "loop");
g_object_unref (score);
}
}
/**
* clutter_score_get_loop:
* @score: a #ClutterScore
*
* Gets whether @score is looping
*
* Return value: %TRUE if the score is looping
*/
gboolean
clutter_score_get_loop (ClutterScore *score)
{
g_return_val_if_fail (CLUTTER_IS_SCORE (score), FALSE);
return score->priv->loop;
}
/**
* clutter_score_rewind:
* @score: A #ClutterScore
*
* Rewinds #ClutterScore to frame 0.
**/
void
clutter_score_rewind (ClutterScore *score)
{
g_return_if_fail (CLUTTER_IS_SCORE (score));
}
/**
* clutter_score_is_playing:
* @score: A #ClutterScore
*
* Query state of a #ClutterScore instance.
*
* Return Value: TRUE if score is currently playing, FALSE if not.
*/
gboolean
clutter_score_is_playing (ClutterScore *score)
{
g_return_val_if_fail (CLUTTER_IS_SCORE (score), FALSE);
return !!g_hash_table_size(score->priv->running_timelines);
}
static void
on_timeline_finish (ClutterTimeline *timeline,
ClutterScoreEntry *entry)
{
GSList *item;
g_hash_table_remove (entry->score->priv->running_timelines,
GINT_TO_POINTER(entry->handler_id));
g_signal_handler_disconnect (timeline, entry->handler_id);
printf("completed %li\n", entry->handler_id);
for (item = entry->child_entries; item != NULL; item = item->next)
{
ClutterScoreEntry *child_entry = item->data;
start_entry (child_entry);
}
if (clutter_score_is_playing (entry->score) == FALSE)
{
/* Score has finished - fire 'completed' signal */
/* Also check if looped etc */
printf("looks like we finished\n");
}
}
static void
start_entry (ClutterScoreEntry *entry)
{
entry->handler_id = g_signal_connect (entry->timeline,
"completed",
G_CALLBACK (on_timeline_finish),
entry);
printf("started %li\n", entry->handler_id);
g_hash_table_insert (entry->score->priv->running_timelines,
GINT_TO_POINTER(entry->handler_id),
entry);
clutter_timeline_start (entry->timeline);
}
/**
* clutter_score_start:
* @score: A #ClutterScore
*
* Query state of a #ClutterScore instance.
*
* Return Value: TRUE if score is currently playing, FALSE if not.
*/
void
clutter_score_start (ClutterScore *score)
{
GSList *item;
ClutterScorePrivate *priv;
g_return_if_fail (CLUTTER_IS_SCORE (score));
priv = score->priv;
for (item = priv->entries; item != NULL; item = item->next)
{
ClutterScoreEntry *entry = item->data;
start_entry (entry);
}
}
/**
* clutter_score_start:
* @score: A #ClutterScore
*
* Query state of a #ClutterScore instance.
*
* Return Value: TRUE if score is currently playing, FALSE if not.
*/
void
clutter_score_stop (ClutterScore *score)
{
g_return_if_fail (CLUTTER_IS_SCORE (score));
/* foreach hash / pause */
}
static ClutterScoreEntry*
find_entry (GSList *list, ClutterTimeline *timeline)
{
GSList *item;
ClutterScoreEntry *res = NULL;
if (list == NULL)
return NULL;
for (item = list; item != NULL && res == NULL; item = item->next)
{
ClutterScoreEntry *entry = item->data;
g_assert (entry != NULL);
if (entry->timeline == timeline)
return entry;
if (entry->child_entries)
res = find_entry (entry->child_entries, timeline);
}
return res;
}
/**
* clutter_score_append:
* @score: A #ClutterScore
* @timeline_existing: A #ClutterTimeline in the score
* @timeline_new: A new #ClutterTimeline to start when #timeline_existing has
* completed,
*
* Appends a new timeline to an one existing in the score.
*
*/
void
clutter_score_append (ClutterScore *score,
ClutterTimeline *timeline_existing,
ClutterTimeline *timeline_new)
{
ClutterScorePrivate *priv;
ClutterScoreEntry *entry, *entry_new;
priv = score->priv;
/* Appends a timeline to the end of another */
if ((entry = find_entry (priv->entries, timeline_existing)) != NULL)
{
entry_new = g_new0(ClutterScoreEntry, 1);
entry->timeline = g_object_ref (timeline_new);
entry->score = score;
entry->child_entries = g_slist_append (entry->child_entries, entry);
}
}
/**
* clutter_score_add:
* @score: A #ClutterScore
* @timeline: A #ClutterTimeline
*
* Adds a new initial timeline to start when the score is started.
*
*/
void
clutter_score_add (ClutterScore *score,
ClutterTimeline *timeline)
{
ClutterScorePrivate *priv;
ClutterScoreEntry *entry;
priv = score->priv;
/* Added timelines are always started first */
entry = g_new0(ClutterScoreEntry, 1);
entry->timeline = g_object_ref (timeline);
entry->score = score;
score->priv->entries = g_slist_append (score->priv->entries, entry);
}
void
clutter_score_remove (ClutterScore *score,
ClutterTimeline *timeline_parent,
ClutterTimeline *timeline)
{
}
void
clutter_score_remove_all (ClutterScore *score)
{
}
/**
* clutter_score_new:
*
* Create a new #ClutterScore instance.
*
* Return Value: a new #ClutterScore
*/
ClutterScore*
clutter_score_new ()
{
return g_object_new (CLUTTER_TYPE_SCORE, NULL);
}

126
clutter/clutter-score.h Normal file
View File

@ -0,0 +1,126 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Authored By Matthew Allum <mallum@openedhand.com>
*
* Copyright (C) 2006 OpenedHand
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef _HAVE_CLUTTER_SCORE_H
#define _HAVE_CLUTTER_SCORE_H
/* clutter-score.h */
#include <glib-object.h>
#include <clutter/clutter-timeline.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_SCORE clutter_score_get_type()
#define CLUTTER_SCORE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
CLUTTER_TYPE_SCORE, ClutterScore))
#define CLUTTER_SCORE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), \
CLUTTER_TYPE_SCORE, ClutterScoreClass))
#define CLUTTER_IS_SCORE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
CLUTTER_TYPE_SCORE))
#define CLUTTER_IS_SCORE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
CLUTTER_TYPE_SCORE))
#define CLUTTER_SCORE_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
CLUTTER_TYPE_SCORE, ClutterScoreClass))
typedef struct _ClutterScore ClutterScore;
typedef struct _ClutterScoreClass ClutterScoreClass;
typedef struct _ClutterScorePrivate ClutterScorePrivate;
struct _ClutterScore
{
/*< private >*/
GObject parent;
ClutterScorePrivate *priv;
};
struct _ClutterScoreClass
{
GObjectClass parent_class;
void (*started) (ClutterScore *score);
void (*completed) (ClutterScore *score);
void (*paused) (ClutterScore *score);
void (*_clutter_score_1) (void);
void (*_clutter_score_2) (void);
void (*_clutter_score_3) (void);
void (*_clutter_score_4) (void);
void (*_clutter_score_5) (void);
};
GType clutter_score_get_type (void) G_GNUC_CONST;
ClutterScore *clutter_score_new (void);
void
clutter_score_set_loop (ClutterScore *score,
gboolean loop);
gboolean
clutter_score_get_loop (ClutterScore *score);
void
clutter_score_rewind (ClutterScore *score);
gboolean
clutter_score_is_playing (ClutterScore *score);
void
clutter_score_start (ClutterScore *score);
void
clutter_score_stop (ClutterScore *score);
void
clutter_score_append (ClutterScore *score,
ClutterTimeline *timeline_existing,
ClutterTimeline *timeline_new);
void
clutter_score_add (ClutterScore *score,
ClutterTimeline *timeline);
void
clutter_score_remove (ClutterScore *score,
ClutterTimeline *timeline_parent,
ClutterTimeline *timeline);
void
clutter_score_remove_all (ClutterScore *score);
G_END_DECLS
#endif

View File

@ -57,6 +57,7 @@
#include "clutter-texture.h"
#include "clutter-timeout-pool.h"
#include "clutter-timeline.h"
#include "clutter-score.h"
#include "clutter-types.h"
#include "clutter-units.h"
#include "clutter-util.h"

View File

@ -76,7 +76,7 @@ clutter_backend_egl_post_parse (ClutterBackend *backend,
backend_egl->display_name = g_strdup (clutter_display_name);
backend_egl->edpy = eglGetDisplay(backend_egl->xdpy);
backend_egl->edpy = eglGetDisplay((NativeDisplayType)backend_egl->xdpy);
dpi = (((double) DisplayHeight (backend_egl->xdpy, backend_egl->xscreen_num) * 25.4)
/ (double) DisplayHeightMM (backend_egl->xdpy, backend_egl->xscreen_num));

View File

@ -89,7 +89,6 @@ clutter_stage_egl_realize (ClutterActor *actor)
EGLConfig configs[2];
EGLint config_count;
EGLBoolean status;
ClutterPerspective perspective;
gboolean is_offscreen;
@ -183,13 +182,7 @@ clutter_stage_egl_realize (ClutterActor *actor)
/* FIXME */
}
clutter_stage_get_perspectivex (CLUTTER_STAGE (actor), &perspective);
cogl_setup_viewport (clutter_actor_get_width (actor),
clutter_actor_get_height (actor),
perspective.fovy,
perspective.aspect,
perspective.z_near,
perspective.z_far);
CLUTTER_SET_PRIVATE_FLAGS(actor, CLUTTER_ACTOR_SYNC_MATRICES);
}
static void

View File

@ -392,14 +392,8 @@ clutter_stage_glx_realize (ClutterActor *actor)
}
clutter_stage_get_perspectivex (CLUTTER_STAGE (actor), &perspective);
cogl_setup_viewport (clutter_actor_get_width (actor),
clutter_actor_get_height (actor),
perspective.fovy,
perspective.aspect,
perspective.z_near,
perspective.z_far);
/* Make sure the viewport gets set up correctly */
CLUTTER_SET_PRIVATE_FLAGS(actor, CLUTTER_ACTOR_SYNC_MATRICES);
return;
fail:

View File

@ -58,7 +58,7 @@ typedef struct tc_slice {
int avail, y;
} tc_slice;
static int tc_generation;
static int tc_generation = 0;
static tc_slice slices[TC_HEIGHT / TC_ROUND];
static tc_texture *first_texture;
@ -339,11 +339,6 @@ draw_glyph (PangoRenderer *renderer_,
_pango_clutter_font_set_cache_glyph_data (font, glyph, g);
}
/*
if (renderer->curtex)
glEnd ();
*/
tc_get (&g->tex, bm.width, bm.height);
g->left = bm.left;
@ -365,8 +360,9 @@ draw_glyph (PangoRenderer *renderer_,
CGL_UNSIGNED_BYTE,
bm.bitmap);
glTexParameteri (CGL_TEXTURE_2D, GL_GENERATE_MIPMAP, FALSE);
renderer->curtex = g->tex.name;
/* glBegin (GL_QUADS); */
}
else CLUTTER_NOTE (PANGO, g_message ("cache succsess %i\n", glyph));
@ -380,15 +376,8 @@ draw_glyph (PangoRenderer *renderer_,
if (g->tex.name != renderer->curtex)
{
/*
if (renderer->curtex)
glEnd ();
*/
cogl_texture_bind (CGL_TEXTURE_2D, g->tex.name);
renderer->curtex = g->tex.name;
/* glBegin (GL_QUADS); */
}
cogl_texture_quad (x,

View File

@ -78,13 +78,7 @@ clutter_stage_sdl_realize (ClutterActor *actor)
return;
}
clutter_stage_get_perspectivex (CLUTTER_STAGE (actor), &perspective);
cogl_setup_viewport (clutter_actor_get_width (actor),
clutter_actor_get_height (actor),
perspective.fovy,
perspective.aspect,
perspective.z_near,
perspective.z_far);
CLUTTER_SET_PRIVATE_FLAGS(actor, CLUTTER_ACTOR_SYNC_MATRICES);
}
static void

View File

@ -1,7 +1,7 @@
noinst_PROGRAMS = test-textures test-events test-offscreen test-scale \
test-actors test-behave test-text test-entry test-project \
test-boxes test-perspective test-rotate test-depth \
test-threads test-timeline
test-threads test-timeline test-score
INCLUDES = -I$(top_srcdir)/
LDADD = $(top_builddir)/clutter/libclutter-@CLUTTER_FLAVOUR@-@CLUTTER_MAJORMINOR@.la
@ -23,5 +23,6 @@ test_rotate_SOURCES = test-rotate.c
test_depth_SOURCES = test-depth.c
test_threads_SOURCES = test-threads.c
test_timeline_SOURCES = test-timeline.c
test_score_SOURCES = test-score.c
EXTRA_DIST = redhand.png

36
tests/test-score.c Normal file
View File

@ -0,0 +1,36 @@
#include <stdio.h>
#include <stdlib.h>
#include <clutter/clutter.h>
int
main (int argc, char **argv)
{
ClutterScore *score;
ClutterTimeline *timeline_1;
ClutterTimeline *timeline_2;
ClutterTimeline *timeline_3;
clutter_init (&argc, &argv);
timeline_1 = clutter_timeline_new (10, 120);
timeline_2 = clutter_timeline_clone (timeline_1);
timeline_3 = clutter_timeline_clone (timeline_1);
score = clutter_score_new();
clutter_score_add (score, timeline_1);
clutter_score_append (score, timeline_1, timeline_2);
#if 0
clutter_score_append (score, timeline_2, timeline_3);
#endif
clutter_score_start (score);
clutter_main ();
g_object_unref (score);
g_object_unref (timeline_1);
g_object_unref (timeline_2);
g_object_unref (timeline_3);
return EXIT_SUCCESS;
}