2007-08-24 Matthew Allum <mallum@openedhand.com>

* clutter/clutter-actor.c:
        * clutter/clutter-event.h:
        * clutter/clutter-main.c:
        * clutter/clutter-stage.c:
        * clutter/clutter-stage.h:
        * clutter/glx/clutter-backend-glx.c:
        * clutter/glx/clutter-backend-glx.h:
        * clutter/glx/clutter-event-glx.c:
        * clutter/glx/clutter-stage-glx.c:
        * clutter/glx/clutter-stage-glx.h:
        Add initial support for stage state events.
        Fix fullscreening for an already mapped stage.

        * tests/test-events.c:
        Print out info from the above. Blue button now toggles
        fullscreen.

        * clutter/clutter-effect.c:
        * clutter/clutter-effect.h:
        Add a setting for templates to ref or clone underlying
        timelines. (As to improve sync issues like those in foofone)

        * tests/test-timeline.c:
        Also add completed signals.

        * clutter/cogl/gles/cogl.c: (cogl_texture_image_2d):
        * configure.ac:
        Forward port from stable branch. RGB Image fixes gles
        and check for lower case libgles_cm.
This commit is contained in:
Matthew Allum 2007-08-24 15:12:52 +00:00
parent e0f609e8aa
commit 1ceaf04ac7
17 changed files with 510 additions and 49 deletions

View File

@ -1,3 +1,36 @@
2007-08-24 Matthew Allum <mallum@openedhand.com>
* clutter/clutter-actor.c:
* clutter/clutter-event.h:
* clutter/clutter-main.c:
* clutter/clutter-stage.c:
* clutter/clutter-stage.h:
* clutter/glx/clutter-backend-glx.c:
* clutter/glx/clutter-backend-glx.h:
* clutter/glx/clutter-event-glx.c:
* clutter/glx/clutter-stage-glx.c:
* clutter/glx/clutter-stage-glx.h:
Add initial support for stage state events.
Fix fullscreening for an already mapped stage.
* tests/test-events.c:
Print out info from the above. Blue button now toggles
fullscreen.
* clutter/clutter-effect.c:
* clutter/clutter-effect.h:
Add a setting for templates to ref or clone underlying
timelines. (As to improve sync issues like those in foofone)
* tests/test-timeline.c:
Also add completed signals.
* clutter/cogl/gles/cogl.c: (cogl_texture_image_2d):
* configure.ac:
Forward port from stable branch. RGB Image fixes gles
and check for lower case libgles_cm.
2007-08-24 Tomas Frydrych <tf@openedhand.com>
* clutter/clutter-actor.c:

View File

@ -2861,15 +2861,10 @@ clutter_actor_event (ClutterActor *actor,
signal_num = MOTION_EVENT;
break;
case CLUTTER_DELETE:
signal_num = -1;
break;
case CLUTTER_DESTROY_NOTIFY:
signal_num = -1;
break;
case CLUTTER_CLIENT_MESSAGE:
signal_num = -1;
break;
default:
signal_num = -1;
break;
}

View File

@ -82,6 +82,7 @@ G_DEFINE_TYPE (ClutterEffectTemplate, clutter_effect_template, G_TYPE_OBJECT);
struct _ClutterEffectTemplatePrivate
{
ClutterTimeline *timeline;
gboolean do_clone;
ClutterAlphaFunc alpha_func;
gpointer alpha_data;
@ -94,6 +95,7 @@ enum
PROP_ALPHA_FUNC,
PROP_TIMELINE,
PROP_DO_CLONE
};
static void
@ -152,6 +154,9 @@ clutter_effect_template_set_property (GObject *object,
case PROP_TIMELINE:
priv->timeline = g_value_get_object (value);
g_object_ref(priv->timeline);
case PROP_DO_CLONE:
clutter_effect_template_set_timeline_clone (template,
g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -179,6 +184,9 @@ clutter_effect_template_get_property (GObject *object,
case PROP_TIMELINE:
g_value_set_object (value, priv->timeline);
break;
case PROP_DO_CLONE:
g_value_set_boolean (value, priv->do_clone);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -228,12 +236,31 @@ clutter_effect_template_class_init (ClutterEffectTemplateClass *klass)
CLUTTER_TYPE_TIMELINE,
G_PARAM_CONSTRUCT_ONLY |
CLUTTER_PARAM_READWRITE));
/**
* ClutterEffectTemplate:clone:
*
* Controls if effects should clone or reference the templated timeline
*
* Since: 0.6
*/
g_object_class_install_property
(object_class,
PROP_DO_CLONE,
g_param_spec_boolean ("clone",
"Clone",
"controls if effects should clone or reference the templated timeline",
TRUE,
G_PARAM_CONSTRUCT |
CLUTTER_PARAM_READWRITE));
}
static void
clutter_effect_template_init (ClutterEffectTemplate *self)
{
self->priv = EFFECT_TEMPLATE_PRIVATE (self);
self->priv->do_clone = TRUE;
}
static void
@ -257,6 +284,40 @@ clutter_effect_template_set_alpha_func (ClutterEffectTemplate *self,
priv->alpha_func = alpha_func;
}
/**
* clutter_effect_template_set_timeline_clone:
* @template_: A #ClutterEffectTemplate
* @setting: A boolean indicating if effects should clone the timeline.
*
* Sets if effects using this template should make a copy of the
* templates timeline (default) or reference the effects timeline.
*
* Since: 0.6
*/
void
clutter_effect_template_set_timeline_clone (ClutterEffectTemplate *template_,
gboolean setting)
{
template_->priv->do_clone = setting;
}
/**
* clutter_effect_template_get_timeline_clone:
* @template: A #ClutterEffectTemplate
*
*
*
* Return value: TRUE if the templates timeline is to be cloned.
*
* Since: 0.6
*/
gboolean
clutter_effect_template_get_timeline_clone (ClutterEffectTemplate *template_)
{
return template_->priv->do_clone;
}
/**
* clutter_effect_template_new:
* @timeline: A #ClutterTimeline for the template (will be cloned)
@ -276,7 +337,7 @@ clutter_effect_template_set_alpha_func (ClutterEffectTemplate *self,
*
* Since: 0.4
*/
ClutterEffectTemplate *
ClutterEffectTemplate*
clutter_effect_template_new (ClutterTimeline *timeline,
ClutterAlphaFunc alpha_func)
{
@ -368,7 +429,15 @@ clutter_effect_closure_new (ClutterEffectTemplate *template,
c->template = template;
c->actor = actor;
c->timeline = clutter_timeline_clone (priv->timeline);
if (clutter_effect_template_get_timeline_clone (template))
c->timeline = clutter_timeline_clone (priv->timeline);
else
{
c->timeline = priv->timeline;
g_object_ref (priv->timeline);
}
c->alpha = clutter_alpha_new_full (c->timeline,
priv->alpha_func,
priv->alpha_data,

View File

@ -101,6 +101,11 @@ ClutterEffectTemplate *clutter_effect_template_new_full (ClutterTimeline *timel
gpointer user_data,
GDestroyNotify notify);
void clutter_effect_template_set_timeline_clone (ClutterEffectTemplate *template_,
gboolean setting);
gboolean clutter_effect_template_get_timeline_clone (ClutterEffectTemplate *template_);
/*
* Clutter effects
*/

View File

@ -83,8 +83,7 @@ typedef enum
CLUTTER_STAGE_STATE_OFFSCREEN = (1<<2),
CLUTTER_STAGE_STATE_POINTER_ENTER = (1<<3),
CLUTTER_STAGE_STATE_POINTER_LEAVE = (1<<4),
CLUTTER_STAGE_STATE_FOCUS_ACTIVATE = (1<<5),
CLUTTER_STAGE_STATE_FOCUS_DEACTIVATE = (1<<6),
CLUTTER_STAGE_STATE_ACTIVATED = (1<<5),
} ClutterStageState;
typedef union _ClutterEvent ClutterEvent;

View File

@ -315,7 +315,8 @@ clutter_do_event (ClutterEvent *event)
}
break;
case CLUTTER_STAGE_STATE:
/* FIXME: fullscreen / focus / mouse - forward to stage */
/* fullscreen / focus - forward to stage */
clutter_stage_event (CLUTTER_STAGE(stage), event);
break;
case CLUTTER_CLIENT_MESSAGE:
break;

View File

@ -82,9 +82,10 @@ enum
enum
{
STAGE_STATE_EVENT,
ACTIVATE_STAGE,
DEACTIVATE_STAGE,
FULLSCREEN,
UNFULLSCREEN,
ACTIVATE,
DEACTIVATE,
LAST_SIGNAL
};
@ -296,6 +297,78 @@ clutter_stage_class_init (ClutterStageClass *klass)
NULL,
CLUTTER_PARAM_READWRITE));
/**
* ClutterStage::fullscreen
* @stage: the stage which was fullscreened
*
* The ::fullscreen signal is emitted when the stage is made fullscreen.
*
* Since: 0.6
*/
stage_signals[FULLSCREEN] =
g_signal_new ("fullscreen",
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ClutterStageClass, fullscreen),
NULL, NULL,
clutter_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
* ClutterStage::unfullscreen
* @stage: the stage which has left a fullscreen state.
*
* The ::unfullscreen signal is emitted when the stage leaves a fullscreen
* state.
*
* Since: 0.6
*/
stage_signals[UNFULLSCREEN] =
g_signal_new ("unfullscreen",
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ClutterStageClass, unfullscreen),
NULL, NULL,
clutter_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
* ClutterStage::activate
* @stage: the stage which was activated
*
* The ::activate signal is emitted when the stage recieves key focus
* from the underlying window system.
*
* Since: 0.6
*/
stage_signals[ACTIVATE] =
g_signal_new ("activate",
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ClutterStageClass, activate),
NULL, NULL,
clutter_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
* ClutterStage::deactivate
* @stage: the stage which was deactivated
*
* The ::activate signal is emitted when the stage loses key focus
* from the underlying window system.
*
* Since: 0.6
*/
stage_signals[DEACTIVATE] =
g_signal_new ("deactivate",
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ClutterStageClass, deactivate),
NULL, NULL,
clutter_marshal_VOID__VOID,
G_TYPE_NONE, 0);
g_type_class_add_private (gobject_class, sizeof (ClutterStagePrivate));
}
@ -750,7 +823,30 @@ clutter_stage_event (ClutterStage *stage,
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
/* FIXME: Handle StageState Changes and Delete events */
if (event->type == CLUTTER_DELETE)
return TRUE;
if (event->type != CLUTTER_STAGE_STATE)
return FALSE;
/* emit raw event */
clutter_actor_event (CLUTTER_ACTOR(stage), event);
if (event->stage_state.changed_mask & CLUTTER_STAGE_STATE_FULLSCREEN)
{
if (event->stage_state.new_state & CLUTTER_STAGE_STATE_FULLSCREEN)
g_signal_emit (stage, stage_signals[FULLSCREEN], 0);
else
g_signal_emit (stage, stage_signals[UNFULLSCREEN], 0);
}
if (event->stage_state.changed_mask & CLUTTER_STAGE_STATE_ACTIVATED)
{
if (event->stage_state.new_state & CLUTTER_STAGE_STATE_ACTIVATED)
g_signal_emit (stage, stage_signals[ACTIVATE], 0);
else
g_signal_emit (stage, stage_signals[DEACTIVATE], 0);
}
return TRUE;
}

View File

@ -99,8 +99,10 @@ struct _ClutterStageClass
gboolean value);
/* events */
void (* stage_state_event) (ClutterStage *stage,
ClutterStageStateEvent *event);
void (* fullscreen) (ClutterStage *stage);
void (* unfullscreen) (ClutterStage *stage);
void (* activate) (ClutterStage *stage);
void (* deactivate) (ClutterStage *stage);
/*< private >*/
/* padding for future expansion */

View File

@ -374,11 +374,17 @@ cogl_texture_image_2d (COGLenum target,
const guchar* pixels)
{
GE( glTexImage2D (target,
0, /* No mipmap support as yet */
internal_format,
0,
format, /* HACK: For gles we set the internal_format equal
* to the pixel format. This is for RGB data (i.e
* jpgs) which seem to need a matching internal
* format rather than RGBA (which is used by GL)
*.
* This fix isn't ideal..
*/
width,
height,
0, /* 0 pixel border */
0,
format,
type,
pixels) );

View File

@ -210,6 +210,11 @@ clutter_backend_glx_post_parse (ClutterBackend *backend,
if (clutter_synchronise)
XSynchronize (backend_glx->xdpy, True);
backend_glx->atom_WM_STATE
= XInternAtom (backend_glx->xdpy, "_NET_WM_STATE", False);
backend_glx->atom_WM_STATE_FULLSCREEN
= XInternAtom (backend_glx->xdpy, "_NET_WM_STATE_FULLSCREEN", False);
}
g_free (clutter_display_name);

View File

@ -89,6 +89,10 @@ struct _ClutterBackendGLX
SwapIntervalProc swap_interval;
gint dri_fd;
ClutterGLXVBlankType vblank_type;
/* props */
Atom atom_WM_STATE;
Atom atom_WM_STATE_FULLSCREEN;
};
struct _ClutterBackendGLXClass

View File

@ -355,13 +355,15 @@ event_translate (ClutterBackend *backend,
XEvent *xevent)
{
ClutterBackendGLX *backend_glx;
ClutterStage *stage;
gboolean res;
Window xwindow, stage_xwindow;
ClutterStageGLX *stage_glx;
ClutterStage *stage;
gboolean res;
Window xwindow, stage_xwindow;
backend_glx = CLUTTER_BACKEND_GLX (backend);
stage = CLUTTER_STAGE (_clutter_backend_get_stage (backend));
stage_xwindow = clutter_glx_get_stage_window (stage);
backend_glx = CLUTTER_BACKEND_GLX (backend);
stage = CLUTTER_STAGE (_clutter_backend_get_stage (backend));
stage_glx = CLUTTER_STAGE_GLX (stage);
stage_xwindow = clutter_glx_get_stage_window (stage);
xwindow = xevent->xany.window;
if (xwindow == None)
@ -397,6 +399,99 @@ event_translate (ClutterBackend *backend,
switch (xevent->type)
{
case ConfigureNotify:
if (xevent->xconfigure.width
!= clutter_actor_get_width (CLUTTER_ACTOR (stage))
||
xevent->xconfigure.height
!= clutter_actor_get_height (CLUTTER_ACTOR (stage)))
clutter_actor_set_size (CLUTTER_ACTOR (stage),
xevent->xconfigure.width,
xevent->xconfigure.height);
res = FALSE;
break;
case PropertyNotify:
{
if (xevent->xproperty.atom == backend_glx->atom_WM_STATE)
{
Atom type;
gint format;
gulong nitems, bytes_after;
guchar *data = NULL;
Atom *atoms = NULL;
gulong i;
gboolean fullscreen_set = FALSE;
clutter_glx_trap_x_errors ();
XGetWindowProperty (backend_glx->xdpy,
stage_xwindow,
backend_glx->atom_WM_STATE,
0, G_MAXLONG,
False, XA_ATOM,
&type, &format, &nitems,
&bytes_after, &data);
clutter_glx_untrap_x_errors ();
if (type != None && data != NULL)
{
atoms = (Atom *)data;
i = 0;
while (i < nitems)
{
if (atoms[i] == backend_glx->atom_WM_STATE_FULLSCREEN)
fullscreen_set = TRUE;
i++;
}
if (fullscreen_set
!= !!(stage_glx->state & CLUTTER_STAGE_STATE_FULLSCREEN))
{
if (fullscreen_set)
stage_glx->state |= CLUTTER_STAGE_STATE_FULLSCREEN;
else
stage_glx->state &= ~CLUTTER_STAGE_STATE_FULLSCREEN;
event->type = CLUTTER_STAGE_STATE;
event->stage_state.changed_mask
= CLUTTER_STAGE_STATE_FULLSCREEN;
event->stage_state.new_state = stage_glx->state;
}
else
res = FALSE;
XFree (data);
}
}
else
res = FALSE;
}
break;
case FocusIn:
if (!(stage_glx->state & CLUTTER_STAGE_STATE_ACTIVATED))
{
/* TODO: check xevent->xfocus.detail ? */
stage_glx->state |= CLUTTER_STAGE_STATE_ACTIVATED;
event->type = CLUTTER_STAGE_STATE;
event->stage_state.changed_mask = CLUTTER_STAGE_STATE_ACTIVATED;
event->stage_state.new_state = stage_glx->state;
}
else
res = FALSE;
break;
case FocusOut:
if (stage_glx->state & CLUTTER_STAGE_STATE_ACTIVATED)
{
stage_glx->state &= ~CLUTTER_STAGE_STATE_ACTIVATED;
event->type = CLUTTER_STAGE_STATE;
event->stage_state.changed_mask = CLUTTER_STAGE_STATE_ACTIVATED;
event->stage_state.new_state = stage_glx->state;
}
else
res = FALSE;
break;
case Expose:
{
XEvent foo_xev;

View File

@ -50,6 +50,38 @@
G_DEFINE_TYPE (ClutterStageGLX, clutter_stage_glx, CLUTTER_TYPE_STAGE);
#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
#define _NET_WM_STATE_ADD 1 /* add/set property */
#define _NET_WM_STATE_TOGGLE 2 /* toggle property */
static void
send_wmspec_change_state (ClutterBackendGLX *backend_glx,
Window window,
Atom state,
gboolean add)
{
XClientMessageEvent xclient;
memset (&xclient, 0, sizeof (xclient));
xclient.type = ClientMessage;
xclient.window = window;
xclient.message_type = backend_glx->atom_WM_STATE;
xclient.format = 32;
xclient.data.l[0] = add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
xclient.data.l[1] = state;
xclient.data.l[2] = 0;
xclient.data.l[3] = 0;
xclient.data.l[4] = 0;
XSendEvent (backend_glx->xdpy,
DefaultRootWindow(backend_glx->xdpy),
False,
SubstructureRedirectMask|SubstructureNotifyMask,
(XEvent *)&xclient);
}
static void
fix_window_size (ClutterStageGLX *stage_glx)
{
@ -83,6 +115,9 @@ clutter_stage_glx_show (ClutterActor *actor)
{
ClutterStageGLX *stage_glx = CLUTTER_STAGE_GLX (actor);
/* Chain up to set mapped flags */
CLUTTER_ACTOR_CLASS (clutter_stage_glx_parent_class)->show(actor);
if (stage_glx->xwin)
{
/* Fire off a redraw to avoid flicker on first map.
@ -236,6 +271,7 @@ clutter_stage_glx_realize (ClutterActor *actor)
CLUTTER_NOTE (MISC, "XSelectInput");
XSelectInput (stage_glx->xdpy, stage_glx->xwin,
StructureNotifyMask |
FocusChangeMask |
ExposureMask |
/* FIXME: we may want to eplicity enable MotionMask */
PointerMotionMask |
@ -434,33 +470,76 @@ clutter_stage_glx_set_fullscreen (ClutterStage *stage,
gboolean fullscreen)
{
ClutterStageGLX *stage_glx = CLUTTER_STAGE_GLX (stage);
Atom atom_WM_STATE, atom_WM_STATE_FULLSCREEN;
ClutterBackendGLX *backend_glx = stage_glx->backend;
atom_WM_STATE = XInternAtom (stage_glx->xdpy, "_NET_WM_STATE", False);
atom_WM_STATE_FULLSCREEN = XInternAtom (stage_glx->xdpy,
"_NET_WM_STATE_FULLSCREEN",
False);
static gboolean was_resizeable = FALSE;
if (fullscreen)
{
gint width, height;
width = DisplayWidth (stage_glx->xdpy, stage_glx->xscreen);
height = DisplayHeight (stage_glx->xdpy, stage_glx->xscreen);
clutter_actor_set_size (CLUTTER_ACTOR (stage_glx), width, height);
if (stage_glx->xwin != None)
XChangeProperty (stage_glx->xdpy,
stage_glx->xwin,
atom_WM_STATE, XA_ATOM, 32,
PropModeReplace,
(unsigned char *) &atom_WM_STATE_FULLSCREEN, 1);
{
if (!CLUTTER_ACTOR_IS_MAPPED(CLUTTER_ACTOR (stage_glx)))
{
gint width, height;
width = DisplayWidth (stage_glx->xdpy, stage_glx->xscreen);
height = DisplayHeight (stage_glx->xdpy, stage_glx->xscreen);
clutter_actor_set_size (CLUTTER_ACTOR (stage_glx),
width, height);
/* FIXME: This wont work if we support more states */
XChangeProperty
(stage_glx->xdpy,
stage_glx->xwin,
backend_glx->atom_WM_STATE, XA_ATOM, 32,
PropModeReplace,
(unsigned char *)&backend_glx->atom_WM_STATE_FULLSCREEN,
1);
}
else
{
/* We need to set window user resize-able for metacity at
* at least to allow the window to fullscreen *sigh*
*/
if (clutter_stage_get_user_resizable (stage) == TRUE)
was_resizeable = TRUE;
else
clutter_stage_set_user_resizable (stage, TRUE);
send_wmspec_change_state(backend_glx,
stage_glx->xwin,
backend_glx->atom_WM_STATE_FULLSCREEN,
TRUE);
}
}
}
else
{
if (stage_glx->xwin != None)
XDeleteProperty (stage_glx->xdpy, stage_glx->xwin, atom_WM_STATE);
{
if (!CLUTTER_ACTOR_IS_MAPPED(CLUTTER_ACTOR (stage_glx)))
{
/* FIXME: This wont work if we support more states */
XDeleteProperty (stage_glx->xdpy,
stage_glx->xwin,
backend_glx->atom_WM_STATE);
}
else
{
clutter_stage_set_user_resizable (stage, TRUE);
send_wmspec_change_state(backend_glx,
stage_glx->xwin,
backend_glx->atom_WM_STATE_FULLSCREEN,
FALSE);
/* reset the windows state - this isn't fun - see above */
if (!was_resizeable)
clutter_stage_set_user_resizable (stage, FALSE);
was_resizeable = FALSE;
}
}
}
CLUTTER_SET_PRIVATE_FLAGS(stage, CLUTTER_ACTOR_SYNC_MATRICES);

View File

@ -65,6 +65,7 @@ struct _ClutterStageGLX
ClutterBackendGLX *backend;
ClutterStageState state;
};
struct _ClutterStageGLXClass

View File

@ -205,19 +205,26 @@ case $clutterbackend in
CLUTTER_COGL="gles"
AC_DEFINE([HAVE_COGL_GLES], 1, [Have GL/ES for rendering])
# try for libvincent first
# try for libvincent first (though its not so good)
PKG_CHECK_MODULES(EGL, libvincent, HAVE_OGLES=yes, HAVE_OGLES=no)
if test "x$HAVE_OGLES" = "xno"; then
AC_CHECK_HEADERS([GLES/egl.h GLES/gl.h],,
[AC_MSG_ERROR([Unable to locate required GLES headers])])
# No libvincent so start checking for upper/lower case libgles_em
# The powervr sdk uses lower case.
AC_CHECK_LIB(GLES_CM, eglInitialize, HAVE_LIBGLES=yes, HAVE_LIBGLES=no)
if test "x$HAVE_LIBGLES" = "xno"; then
AC_MSG_ERROR([GLES library not found and egl backend requested.]);
fi
EGL_LIBS="-lGLES_CM"
AC_CHECK_LIB(gles_cm, eglInitialize, HAVE_LIBGLES=yes, HAVE_LIBGLES=no)
if test "x$HAVE_LIBGLES" = "xno"; then
AC_MSG_ERROR([GLES library not found and egl backend requested.]);
fi
EGL_LIBS="-lgles_cm"
else
EGL_LIBS="-lGLES_CM"
fi
fi
EGL_LIBS="$EGL_LIBS $X11_LIBS"

View File

@ -1,6 +1,32 @@
#include <clutter/clutter.h>
gboolean IsFullScreen = FALSE;
static void
stage_state_cb (ClutterStage *stage,
gpointer data)
{
gchar *detail = (gchar*)data;
printf("[stage signal] %s\n", detail);
}
static void
blue_button_cb (ClutterActor *actor,
ClutterEvent *event,
gpointer data)
{
ClutterActor *stage;
stage = clutter_stage_get_default ();
if (IsFullScreen)
IsFullScreen = FALSE;
else
IsFullScreen = TRUE;
g_object_set (stage, "fullscreen", IsFullScreen, NULL);
}
void
key_focus_in_cb (ClutterActor *actor,
@ -104,6 +130,14 @@ main (int argc, char *argv[])
stage = clutter_stage_get_default ();
g_signal_connect (stage, "event", G_CALLBACK (input_cb), "stage");
g_signal_connect (stage, "fullscreen",
G_CALLBACK (stage_state_cb), "fullscreen");
g_signal_connect (stage, "unfullscreen",
G_CALLBACK (stage_state_cb), "unfullscreen");
g_signal_connect (stage, "activate",
G_CALLBACK (stage_state_cb), "activate");
g_signal_connect (stage, "deactivate",
G_CALLBACK (stage_state_cb), "deactivate");
focus_box = clutter_rectangle_new_with_color (&ncol);
clutter_container_add (CLUTTER_CONTAINER(stage), focus_box, NULL);
@ -145,6 +179,7 @@ main (int argc, char *argv[])
g_signal_connect (actor, "event", G_CALLBACK (input_cb), "blue box");
g_signal_connect (actor, "focus-in", G_CALLBACK (key_focus_in_cb),
focus_box);
g_signal_connect (actor, "button-press-event", G_CALLBACK (blue_button_cb), NULL);
actor = clutter_rectangle_new_with_color (&ncol);
clutter_actor_set_size (actor, 400, 50);

View File

@ -2,6 +2,24 @@
#include <stdlib.h>
#include <clutter/clutter.h>
static void
timeline_1_complete (ClutterTimeline *timeline)
{
g_debug ("1: Completed");
}
static void
timeline_2_complete (ClutterTimeline *timeline)
{
g_debug ("2: Completed");
}
static void
timeline_3_complete (ClutterTimeline *timeline)
{
g_debug ("3: Completed");
}
static void
timeline_1_new_frame_cb (ClutterTimeline *timeline, gint frame_no)
{
@ -29,19 +47,30 @@ main (int argc, char **argv)
clutter_init (&argc, &argv);
timeline_1 = clutter_timeline_new (100, 50);
timeline_1 = clutter_timeline_new (10, 120);
timeline_2 = clutter_timeline_clone (timeline_1);
timeline_3 = clutter_timeline_clone (timeline_1);
g_signal_connect (timeline_1,
"new-frame", G_CALLBACK (timeline_1_new_frame_cb),
NULL);
g_signal_connect (timeline_1,
"completed", G_CALLBACK (timeline_1_complete),
NULL);
g_signal_connect (timeline_2,
"new-frame", G_CALLBACK (timeline_2_new_frame_cb),
NULL);
g_signal_connect (timeline_2,
"completed", G_CALLBACK (timeline_2_complete),
NULL);
g_signal_connect (timeline_3,
"new-frame", G_CALLBACK (timeline_3_new_frame_cb),
NULL);
g_signal_connect (timeline_3,
"completed", G_CALLBACK (timeline_3_complete),
NULL);
clutter_timeline_start (timeline_1);
clutter_timeline_start (timeline_2);