diff --git a/ChangeLog b/ChangeLog index fd2ad18d4..68d758d8f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,36 @@ +2007-08-24 Matthew Allum + + * 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 * clutter/clutter-actor.c: diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index e11c78a89..5bddecc11 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -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; } diff --git a/clutter/clutter-effect.c b/clutter/clutter-effect.c index 96f61d195..76e893d9e 100644 --- a/clutter/clutter-effect.c +++ b/clutter/clutter-effect.c @@ -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, diff --git a/clutter/clutter-effect.h b/clutter/clutter-effect.h index dabd0b35f..f77da4ef0 100644 --- a/clutter/clutter-effect.h +++ b/clutter/clutter-effect.h @@ -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 */ diff --git a/clutter/clutter-event.h b/clutter/clutter-event.h index 3badad41f..fcedc3175 100644 --- a/clutter/clutter-event.h +++ b/clutter/clutter-event.h @@ -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; diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c index 3bddfab85..6537e0ee8 100644 --- a/clutter/clutter-main.c +++ b/clutter/clutter-main.c @@ -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; diff --git a/clutter/clutter-stage.c b/clutter/clutter-stage.c index 276c6436f..5aeca38e2 100644 --- a/clutter/clutter-stage.c +++ b/clutter/clutter-stage.c @@ -82,9 +82,10 @@ enum enum { - STAGE_STATE_EVENT, - ACTIVATE_STAGE, - DEACTIVATE_STAGE, + FULLSCREEN, + UNFULLSCREEN, + ACTIVATE, + DEACTIVATE, LAST_SIGNAL }; @@ -295,6 +296,78 @@ clutter_stage_class_init (ClutterStageClass *klass) "Stage Title", 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; } diff --git a/clutter/clutter-stage.h b/clutter/clutter-stage.h index d10d2ade2..462fcf110 100644 --- a/clutter/clutter-stage.h +++ b/clutter/clutter-stage.h @@ -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 */ diff --git a/clutter/cogl/gles/cogl.c b/clutter/cogl/gles/cogl.c index 088c4eb7a..6725975f3 100644 --- a/clutter/cogl/gles/cogl.c +++ b/clutter/cogl/gles/cogl.c @@ -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) ); diff --git a/clutter/glx/clutter-backend-glx.c b/clutter/glx/clutter-backend-glx.c index 5269b2d42..084844022 100644 --- a/clutter/glx/clutter-backend-glx.c +++ b/clutter/glx/clutter-backend-glx.c @@ -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); diff --git a/clutter/glx/clutter-backend-glx.h b/clutter/glx/clutter-backend-glx.h index 8da36d112..db4791806 100644 --- a/clutter/glx/clutter-backend-glx.h +++ b/clutter/glx/clutter-backend-glx.h @@ -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 diff --git a/clutter/glx/clutter-event-glx.c b/clutter/glx/clutter-event-glx.c index 86366019d..0941af0ca 100644 --- a/clutter/glx/clutter-event-glx.c +++ b/clutter/glx/clutter-event-glx.c @@ -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; diff --git a/clutter/glx/clutter-stage-glx.c b/clutter/glx/clutter-stage-glx.c index b969765f6..8cc8d2b34 100644 --- a/clutter/glx/clutter-stage-glx.c +++ b/clutter/glx/clutter-stage-glx.c @@ -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); diff --git a/clutter/glx/clutter-stage-glx.h b/clutter/glx/clutter-stage-glx.h index 9ff59490b..c81b674ca 100644 --- a/clutter/glx/clutter-stage-glx.h +++ b/clutter/glx/clutter-stage-glx.h @@ -65,6 +65,7 @@ struct _ClutterStageGLX ClutterBackendGLX *backend; + ClutterStageState state; }; struct _ClutterStageGLXClass diff --git a/configure.ac b/configure.ac index aed891e6a..3b11b27dd 100644 --- a/configure.ac +++ b/configure.ac @@ -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_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 - - EGL_LIBS="-lGLES_CM" fi EGL_LIBS="$EGL_LIBS $X11_LIBS" diff --git a/tests/test-events.c b/tests/test-events.c index 11dc13103..e56b3464a 100644 --- a/tests/test-events.c +++ b/tests/test-events.c @@ -1,6 +1,32 @@ #include +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); diff --git a/tests/test-timeline.c b/tests/test-timeline.c index 7942e7fc1..9b2b74caa 100644 --- a/tests/test-timeline.c +++ b/tests/test-timeline.c @@ -2,6 +2,24 @@ #include #include +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);