mirror of
https://github.com/brl/mutter.git
synced 2024-11-22 16:10:41 -05:00
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:
parent
e0f609e8aa
commit
1ceaf04ac7
33
ChangeLog
33
ChangeLog
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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) );
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -65,6 +65,7 @@ struct _ClutterStageGLX
|
||||
|
||||
ClutterBackendGLX *backend;
|
||||
|
||||
ClutterStageState state;
|
||||
};
|
||||
|
||||
struct _ClutterStageGLXClass
|
||||
|
17
configure.ac
17
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_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"
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user