Compare commits
106 Commits
wip/cally-
...
wip/smcv/c
Author | SHA1 | Date | |
---|---|---|---|
![]() |
2efd0dfc06 | ||
![]() |
0b6a3166ed | ||
![]() |
066bc5986d | ||
![]() |
e8b09df8d2 | ||
![]() |
1571f8078a | ||
![]() |
510cbef15a | ||
![]() |
99c9a14bc8 | ||
![]() |
b8003807b0 | ||
![]() |
8e1bd64e05 | ||
![]() |
5aa56aa7f5 | ||
![]() |
c2c4f74923 | ||
![]() |
f8daa6bc70 | ||
![]() |
5b07ccd0a7 | ||
![]() |
ae4d299499 | ||
![]() |
8798325489 | ||
![]() |
9e34028742 | ||
![]() |
258f859e8d | ||
![]() |
9d3e4fd402 | ||
![]() |
03c65b93e6 | ||
![]() |
db975bd2a8 | ||
![]() |
4e27a4ea1d | ||
![]() |
346cadeddb | ||
![]() |
f60c485117 | ||
![]() |
19550c28f9 | ||
![]() |
c4949b553d | ||
![]() |
675a2d13b9 | ||
![]() |
f4d9953b9c | ||
![]() |
6db94a0b77 | ||
![]() |
9bf6faf639 | ||
![]() |
4434a17d08 | ||
![]() |
c65f63b647 | ||
![]() |
79d981aac9 | ||
![]() |
2791f5b466 | ||
![]() |
e68bb27df2 | ||
![]() |
e12b2c417e | ||
![]() |
0fbda366e8 | ||
![]() |
106d332c71 | ||
![]() |
c42c11583d | ||
![]() |
8c131b32b1 | ||
![]() |
c8e12ead08 | ||
![]() |
8a541c08fb | ||
![]() |
dfed5f6a11 | ||
![]() |
96dd794fd1 | ||
![]() |
73a436362a | ||
![]() |
7343b8d817 | ||
![]() |
dbf47b652e | ||
![]() |
b97a6e62a3 | ||
![]() |
4fac1a4862 | ||
![]() |
70ba844c3c | ||
![]() |
bc0b9f7628 | ||
![]() |
c971d6ea1f | ||
![]() |
dac09a8e23 | ||
![]() |
11f224f4b0 | ||
![]() |
a1be7cdbd7 | ||
![]() |
82d96aebe1 | ||
![]() |
c14ba5937f | ||
![]() |
e50e14af82 | ||
![]() |
787d9a5a15 | ||
![]() |
3c29bf7491 | ||
![]() |
dc8e5c7f8b | ||
![]() |
0a986fc885 | ||
![]() |
04e983383f | ||
![]() |
7ae6e0101c | ||
![]() |
affb3de829 | ||
![]() |
24d7a7ad0b | ||
![]() |
4729cb779e | ||
![]() |
c8837a8de5 | ||
![]() |
283cccbe9f | ||
![]() |
a7bf6322e3 | ||
![]() |
1d5f9b6917 | ||
![]() |
3c068ef135 | ||
![]() |
2becb3dd29 | ||
![]() |
55f5177fe0 | ||
![]() |
037b68ab8e | ||
![]() |
b45d5ef3f5 | ||
![]() |
7e4e371466 | ||
![]() |
fbfa136bbb | ||
![]() |
434845dbe5 | ||
![]() |
967511be61 | ||
![]() |
43c7a82461 | ||
![]() |
066e78c9b3 | ||
![]() |
08f47fee16 | ||
![]() |
afe4cd482e | ||
![]() |
3fed768db4 | ||
![]() |
8c52b431bb | ||
![]() |
d9ffbf0576 | ||
![]() |
b0953b92ba | ||
![]() |
819f9afa31 | ||
![]() |
7a0bc5af7f | ||
![]() |
c5fbab6bad | ||
![]() |
f4301b77fa | ||
![]() |
a3f27dfd89 | ||
![]() |
73ce9c2e81 | ||
![]() |
fd27c7c444 | ||
![]() |
a51807fc1e | ||
![]() |
3c35a78769 | ||
![]() |
ae7cb7a3bf | ||
![]() |
531b0ab300 | ||
![]() |
7cc604b9e5 | ||
![]() |
f3a65c9b32 | ||
![]() |
dec97a6541 | ||
![]() |
cfa2d1abf7 | ||
![]() |
d9fb6b5ca2 | ||
![]() |
696b534570 | ||
![]() |
38db4a5a65 | ||
![]() |
6f62c5b575 |
@@ -33,28 +33,11 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_ACTION (clutter_action_get_type ())
|
||||
#define CLUTTER_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ACTION, ClutterAction))
|
||||
#define CLUTTER_IS_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ACTION))
|
||||
#define CLUTTER_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ACTION, ClutterActionClass))
|
||||
#define CLUTTER_IS_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ACTION))
|
||||
#define CLUTTER_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ACTION, ClutterActionClass))
|
||||
#define CLUTTER_TYPE_ACTION (clutter_action_get_type ())
|
||||
|
||||
typedef struct _ClutterActionClass ClutterActionClass;
|
||||
|
||||
/**
|
||||
* ClutterAction:
|
||||
*
|
||||
* The #ClutterAction structure contains only private data and
|
||||
* should be accessed using the provided API.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
struct _ClutterAction
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterActorMeta parent_instance;
|
||||
};
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterAction, clutter_action,
|
||||
CLUTTER, ACTION, ClutterActorMeta);
|
||||
|
||||
/**
|
||||
* ClutterActionClass:
|
||||
@@ -78,9 +61,6 @@ struct _ClutterActionClass
|
||||
void (* _clutter_action8) (void);
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType clutter_action_get_type (void) G_GNUC_CONST;
|
||||
|
||||
/* ClutterActor API */
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_add_action (ClutterActor *self,
|
||||
|
@@ -81,38 +81,47 @@ static void
|
||||
on_actor_destroy (ClutterActor *actor,
|
||||
ClutterActorMeta *meta)
|
||||
{
|
||||
meta->priv->actor = NULL;
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
priv->actor = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_actor_meta_real_set_actor (ClutterActorMeta *meta,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
g_warn_if_fail (!meta->priv->actor ||
|
||||
!CLUTTER_ACTOR_IN_PAINT (meta->priv->actor));
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
g_warn_if_fail (!priv->actor ||
|
||||
!CLUTTER_ACTOR_IN_PAINT (priv->actor));
|
||||
g_warn_if_fail (!actor || !CLUTTER_ACTOR_IN_PAINT (actor));
|
||||
|
||||
if (meta->priv->actor == actor)
|
||||
if (priv->actor == actor)
|
||||
return;
|
||||
|
||||
g_clear_signal_handler (&meta->priv->destroy_id, meta->priv->actor);
|
||||
g_clear_signal_handler (&priv->destroy_id, priv->actor);
|
||||
|
||||
meta->priv->actor = actor;
|
||||
priv->actor = actor;
|
||||
|
||||
if (meta->priv->actor != NULL)
|
||||
meta->priv->destroy_id = g_signal_connect (meta->priv->actor, "destroy",
|
||||
G_CALLBACK (on_actor_destroy),
|
||||
meta);
|
||||
if (priv->actor != NULL)
|
||||
priv->destroy_id = g_signal_connect (priv->actor, "destroy",
|
||||
G_CALLBACK (on_actor_destroy),
|
||||
meta);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_actor_meta_real_set_enabled (ClutterActorMeta *meta,
|
||||
gboolean is_enabled)
|
||||
{
|
||||
g_warn_if_fail (!meta->priv->actor ||
|
||||
!CLUTTER_ACTOR_IN_PAINT (meta->priv->actor));
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
meta->priv->is_enabled = is_enabled;
|
||||
g_warn_if_fail (!priv->actor ||
|
||||
!CLUTTER_ACTOR_IN_PAINT (priv->actor));
|
||||
|
||||
priv->is_enabled = is_enabled;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_ENABLED]);
|
||||
}
|
||||
@@ -147,20 +156,21 @@ clutter_actor_meta_get_property (GObject *gobject,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterActorMeta *meta = CLUTTER_ACTOR_META (gobject);
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (CLUTTER_ACTOR_META (gobject));
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ACTOR:
|
||||
g_value_set_object (value, meta->priv->actor);
|
||||
g_value_set_object (value, priv->actor);
|
||||
break;
|
||||
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, meta->priv->name);
|
||||
g_value_set_string (value, priv->name);
|
||||
break;
|
||||
|
||||
case PROP_ENABLED:
|
||||
g_value_set_boolean (value, meta->priv->is_enabled);
|
||||
g_value_set_boolean (value, priv->is_enabled);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -172,7 +182,8 @@ clutter_actor_meta_get_property (GObject *gobject,
|
||||
static void
|
||||
clutter_actor_meta_finalize (GObject *gobject)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv = CLUTTER_ACTOR_META (gobject)->priv;
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (CLUTTER_ACTOR_META (gobject));
|
||||
|
||||
if (priv->actor != NULL)
|
||||
g_clear_signal_handler (&priv->destroy_id, priv->actor);
|
||||
@@ -243,9 +254,11 @@ clutter_actor_meta_class_init (ClutterActorMetaClass *klass)
|
||||
void
|
||||
clutter_actor_meta_init (ClutterActorMeta *self)
|
||||
{
|
||||
self->priv = clutter_actor_meta_get_instance_private (self);
|
||||
self->priv->is_enabled = TRUE;
|
||||
self->priv->priority = CLUTTER_ACTOR_META_PRIORITY_DEFAULT;
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (self);
|
||||
|
||||
priv->is_enabled = TRUE;
|
||||
priv->priority = CLUTTER_ACTOR_META_PRIORITY_DEFAULT;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -263,13 +276,17 @@ void
|
||||
clutter_actor_meta_set_name (ClutterActorMeta *meta,
|
||||
const gchar *name)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR_META (meta));
|
||||
|
||||
if (g_strcmp0 (meta->priv->name, name) == 0)
|
||||
priv = clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
if (g_strcmp0 (priv->name, name) == 0)
|
||||
return;
|
||||
|
||||
g_free (meta->priv->name);
|
||||
meta->priv->name = g_strdup (name);
|
||||
g_free (priv->name);
|
||||
priv->name = g_strdup (name);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_NAME]);
|
||||
}
|
||||
@@ -290,9 +307,13 @@ clutter_actor_meta_set_name (ClutterActorMeta *meta,
|
||||
const gchar *
|
||||
clutter_actor_meta_get_name (ClutterActorMeta *meta)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), NULL);
|
||||
|
||||
return meta->priv->name;
|
||||
priv = clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
return priv->name;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -308,11 +329,14 @@ void
|
||||
clutter_actor_meta_set_enabled (ClutterActorMeta *meta,
|
||||
gboolean is_enabled)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR_META (meta));
|
||||
|
||||
priv = clutter_actor_meta_get_instance_private (meta);
|
||||
is_enabled = !!is_enabled;
|
||||
|
||||
if (meta->priv->is_enabled == is_enabled)
|
||||
if (priv->is_enabled == is_enabled)
|
||||
return;
|
||||
|
||||
CLUTTER_ACTOR_META_GET_CLASS (meta)->set_enabled (meta, is_enabled);
|
||||
@@ -331,9 +355,13 @@ clutter_actor_meta_set_enabled (ClutterActorMeta *meta,
|
||||
gboolean
|
||||
clutter_actor_meta_get_enabled (ClutterActorMeta *meta)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), FALSE);
|
||||
|
||||
return meta->priv->is_enabled;
|
||||
priv = clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
return priv->is_enabled;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -369,40 +397,54 @@ _clutter_actor_meta_set_actor (ClutterActorMeta *meta,
|
||||
ClutterActor *
|
||||
clutter_actor_meta_get_actor (ClutterActorMeta *meta)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), NULL);
|
||||
|
||||
return meta->priv->actor;
|
||||
priv = clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
return priv->actor;
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_actor_meta_set_priority (ClutterActorMeta *meta,
|
||||
gint priority)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR_META (meta));
|
||||
|
||||
priv = clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
/* This property shouldn't be modified after the actor meta is in
|
||||
use because ClutterMetaGroup doesn't resort the list when it
|
||||
changes. If we made the priority public then we could either make
|
||||
the priority a construct-only property or listen for
|
||||
notifications on the property from the ClutterMetaGroup and
|
||||
resort. */
|
||||
g_return_if_fail (meta->priv->actor == NULL);
|
||||
g_return_if_fail (priv->actor == NULL);
|
||||
|
||||
meta->priv->priority = priority;
|
||||
priv->priority = priority;
|
||||
}
|
||||
|
||||
gint
|
||||
_clutter_actor_meta_get_priority (ClutterActorMeta *meta)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), 0);
|
||||
|
||||
return meta->priv->priority;
|
||||
priv = clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
return priv->priority;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_clutter_actor_meta_is_internal (ClutterActorMeta *meta)
|
||||
{
|
||||
gint priority = meta->priv->priority;
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (meta);
|
||||
gint priority = priv->priority;
|
||||
|
||||
return (priority <= CLUTTER_ACTOR_META_PRIORITY_INTERNAL_LOW ||
|
||||
priority >= CLUTTER_ACTOR_META_PRIORITY_INTERNAL_HIGH);
|
||||
@@ -449,19 +491,21 @@ void
|
||||
_clutter_meta_group_add_meta (ClutterMetaGroup *group,
|
||||
ClutterActorMeta *meta)
|
||||
{
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (meta);
|
||||
GList *prev = NULL, *l;
|
||||
|
||||
if (meta->priv->actor != NULL)
|
||||
if (priv->actor != NULL)
|
||||
{
|
||||
g_warning ("The meta of type '%s' with name '%s' is "
|
||||
"already attached to actor '%s'",
|
||||
G_OBJECT_TYPE_NAME (meta),
|
||||
meta->priv->name != NULL
|
||||
? meta->priv->name
|
||||
priv->name != NULL
|
||||
? priv->name
|
||||
: "<unknown>",
|
||||
clutter_actor_get_name (meta->priv->actor) != NULL
|
||||
? clutter_actor_get_name (meta->priv->actor)
|
||||
: G_OBJECT_TYPE_NAME (meta->priv->actor));
|
||||
clutter_actor_get_name (priv->actor) != NULL
|
||||
? clutter_actor_get_name (priv->actor)
|
||||
: G_OBJECT_TYPE_NAME (priv->actor));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -497,13 +541,16 @@ void
|
||||
_clutter_meta_group_remove_meta (ClutterMetaGroup *group,
|
||||
ClutterActorMeta *meta)
|
||||
{
|
||||
if (meta->priv->actor != group->actor)
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
if (priv->actor != group->actor)
|
||||
{
|
||||
g_warning ("The meta of type '%s' with name '%s' is not "
|
||||
"attached to the actor '%s'",
|
||||
G_OBJECT_TYPE_NAME (meta),
|
||||
meta->priv->name != NULL
|
||||
? meta->priv->name
|
||||
priv->name != NULL
|
||||
? priv->name
|
||||
: "<unknown>",
|
||||
clutter_actor_get_name (group->actor) != NULL
|
||||
? clutter_actor_get_name (group->actor)
|
||||
@@ -646,8 +693,10 @@ _clutter_meta_group_get_meta (ClutterMetaGroup *group,
|
||||
for (l = group->meta; l != NULL; l = l->next)
|
||||
{
|
||||
ClutterActorMeta *meta = l->data;
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
if (g_strcmp0 (meta->priv->name, name) == 0)
|
||||
if (g_strcmp0 (priv->name, name) == 0)
|
||||
return meta;
|
||||
}
|
||||
|
||||
@@ -667,6 +716,8 @@ _clutter_meta_group_get_meta (ClutterMetaGroup *group,
|
||||
const gchar *
|
||||
_clutter_actor_meta_get_debug_name (ClutterActorMeta *meta)
|
||||
{
|
||||
return meta->priv->name != NULL ? meta->priv->name
|
||||
: G_OBJECT_TYPE_NAME (meta);
|
||||
ClutterActorMetaPrivate *priv =
|
||||
clutter_actor_meta_get_instance_private (meta);
|
||||
|
||||
return priv->name != NULL ? priv->name : G_OBJECT_TYPE_NAME (meta);
|
||||
}
|
||||
|
@@ -33,31 +33,13 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_ACTOR_META (clutter_actor_meta_get_type ())
|
||||
#define CLUTTER_ACTOR_META(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ACTOR_META, ClutterActorMeta))
|
||||
#define CLUTTER_IS_ACTOR_META(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ACTOR_META))
|
||||
#define CLUTTER_ACTOR_META_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ACTOR_META, ClutterActorMetaClass))
|
||||
#define CLUTTER_IS_ACTOR_META_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ACTOR_META))
|
||||
#define CLUTTER_ACTOR_META_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ACTOR_META, ClutterActorMetaClass))
|
||||
#define CLUTTER_TYPE_ACTOR_META (clutter_actor_meta_get_type ())
|
||||
|
||||
typedef struct _ClutterActorMetaPrivate ClutterActorMetaPrivate;
|
||||
typedef struct _ClutterActorMetaClass ClutterActorMetaClass;
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterActorMeta, clutter_actor_meta,
|
||||
CLUTTER, ACTOR_META, GInitiallyUnowned);
|
||||
|
||||
/**
|
||||
* ClutterActorMeta:
|
||||
*
|
||||
* The #ClutterActorMeta structure contains only
|
||||
* private data and should be accessed using the provided API
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
struct _ClutterActorMeta
|
||||
{
|
||||
/*< private >*/
|
||||
GInitiallyUnowned parent_instance;
|
||||
|
||||
ClutterActorMetaPrivate *priv;
|
||||
};
|
||||
typedef struct _ClutterActorMetaPrivate ClutterActorMetaPrivate;
|
||||
|
||||
/**
|
||||
* ClutterActorMetaClass:
|
||||
@@ -99,9 +81,6 @@ struct _ClutterActorMetaClass
|
||||
void (* _clutter_meta6) (void);
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType clutter_actor_meta_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_meta_set_name (ClutterActorMeta *meta,
|
||||
const gchar *name);
|
||||
|
@@ -698,7 +698,6 @@ struct _ClutterActorPrivate
|
||||
* allocation
|
||||
*/
|
||||
ClutterActorBox allocation;
|
||||
ClutterAllocationFlags allocation_flags;
|
||||
|
||||
/* clip, in actor coordinates */
|
||||
graphene_rect_t clip;
|
||||
@@ -854,6 +853,7 @@ struct _ClutterActorPrivate
|
||||
guint needs_paint_volume_update : 1;
|
||||
guint had_effects_on_last_paint_volume_update : 1;
|
||||
guint needs_compute_resource_scale : 1;
|
||||
guint absolute_origin_changed : 1;
|
||||
};
|
||||
|
||||
enum
|
||||
@@ -1013,7 +1013,6 @@ enum
|
||||
MOTION_EVENT,
|
||||
ENTER_EVENT,
|
||||
LEAVE_EVENT,
|
||||
ALLOCATION_CHANGED,
|
||||
TRANSITIONS_COMPLETED,
|
||||
TOUCH_EVENT,
|
||||
TRANSITION_STOPPED,
|
||||
@@ -2577,15 +2576,13 @@ clutter_actor_notify_if_geometry_changed (ClutterActor *self,
|
||||
* Return value: %TRUE if the allocation of the #ClutterActor has been
|
||||
* changed, and %FALSE otherwise
|
||||
*/
|
||||
static inline gboolean
|
||||
static inline void
|
||||
clutter_actor_set_allocation_internal (ClutterActor *self,
|
||||
const ClutterActorBox *box,
|
||||
ClutterAllocationFlags flags)
|
||||
const ClutterActorBox *box)
|
||||
{
|
||||
ClutterActorPrivate *priv = self->priv;
|
||||
GObject *obj;
|
||||
gboolean x1_changed, y1_changed, x2_changed, y2_changed;
|
||||
gboolean retval;
|
||||
ClutterActorBox old_alloc = { 0, };
|
||||
|
||||
obj = G_OBJECT (self);
|
||||
@@ -2600,7 +2597,6 @@ clutter_actor_set_allocation_internal (ClutterActor *self,
|
||||
y2_changed = priv->allocation.y2 != box->y2;
|
||||
|
||||
priv->allocation = *box;
|
||||
priv->allocation_flags = flags;
|
||||
|
||||
/* allocation is authoritative */
|
||||
priv->needs_width_request = FALSE;
|
||||
@@ -2625,88 +2621,37 @@ clutter_actor_set_allocation_internal (ClutterActor *self,
|
||||
priv->content_box_valid = FALSE;
|
||||
g_object_notify_by_pspec (obj, obj_props[PROP_CONTENT_BOX]);
|
||||
}
|
||||
|
||||
retval = TRUE;
|
||||
}
|
||||
else
|
||||
retval = FALSE;
|
||||
|
||||
clutter_actor_notify_if_geometry_changed (self, &old_alloc);
|
||||
|
||||
g_object_thaw_notify (obj);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void clutter_actor_real_allocate (ClutterActor *self,
|
||||
const ClutterActorBox *box,
|
||||
ClutterAllocationFlags flags);
|
||||
|
||||
static inline void
|
||||
clutter_actor_maybe_layout_children (ClutterActor *self,
|
||||
const ClutterActorBox *allocation,
|
||||
ClutterAllocationFlags flags)
|
||||
static void
|
||||
clutter_actor_real_allocate (ClutterActor *self,
|
||||
const ClutterActorBox *box)
|
||||
{
|
||||
ClutterActorPrivate *priv = self->priv;
|
||||
|
||||
/* this is going to be a bit hard to follow, so let's put an explanation
|
||||
* here.
|
||||
*
|
||||
* we want ClutterActor to have a default layout manager if the actor was
|
||||
* created using "g_object_new (CLUTTER_TYPE_ACTOR, NULL)".
|
||||
*
|
||||
* we also want any subclass of ClutterActor that does not override the
|
||||
* ::allocate() virtual function to delegate to a layout manager.
|
||||
*
|
||||
* finally, we want to allow people subclassing ClutterActor and overriding
|
||||
* the ::allocate() vfunc to let Clutter delegate to the layout manager.
|
||||
*
|
||||
* on the other hand, we want existing actor subclasses overriding the
|
||||
* ::allocate() virtual function and chaining up to the parent's
|
||||
* implementation to continue working without allocating their children
|
||||
* twice, or without entering an allocation loop.
|
||||
*
|
||||
* for the first two points, we check if the class of the actor is
|
||||
* overridding the ::allocate() virtual function; if it isn't, then we
|
||||
* follow through with checking whether we have children and a layout
|
||||
* manager, and eventually calling clutter_layout_manager_allocate().
|
||||
*
|
||||
* for the third point, we check the CLUTTER_DELEGATE_LAYOUT flag in the
|
||||
* allocation flags that we got passed, and if it is present, we continue
|
||||
* with the check above.
|
||||
*
|
||||
* if neither of these two checks yields a positive result, we just
|
||||
* assume that the ::allocate() virtual function that resulted in this
|
||||
* function being called will also allocate the children of the actor.
|
||||
g_object_freeze_notify (G_OBJECT (self));
|
||||
|
||||
clutter_actor_set_allocation_internal (self, box);
|
||||
|
||||
/* we allocate our children before we notify changes in our geometry,
|
||||
* so that people connecting to properties will be able to get valid
|
||||
* data out of the sub-tree of the scene graph that has this actor at
|
||||
* the root.
|
||||
*/
|
||||
|
||||
if (CLUTTER_ACTOR_GET_CLASS (self)->allocate == clutter_actor_real_allocate)
|
||||
goto check_layout;
|
||||
|
||||
if ((flags & CLUTTER_DELEGATE_LAYOUT) != 0)
|
||||
goto check_layout;
|
||||
|
||||
return;
|
||||
|
||||
check_layout:
|
||||
if (priv->n_children != 0 &&
|
||||
priv->layout_manager != NULL)
|
||||
{
|
||||
ClutterContainer *container = CLUTTER_CONTAINER (self);
|
||||
ClutterAllocationFlags children_flags;
|
||||
ClutterActorBox children_box;
|
||||
|
||||
/* normalize the box passed to the layout manager */
|
||||
children_box.x1 = children_box.y1 = 0.f;
|
||||
children_box.x2 = (allocation->x2 - allocation->x1);
|
||||
children_box.y2 = (allocation->y2 - allocation->y1);
|
||||
|
||||
/* remove the DELEGATE_LAYOUT flag; this won't be passed to
|
||||
* the actor's children, since it refers only to the current
|
||||
* actor's allocation.
|
||||
*/
|
||||
children_flags = flags;
|
||||
children_flags &= ~CLUTTER_DELEGATE_LAYOUT;
|
||||
children_box.x2 = box->x2 - box->x1;
|
||||
children_box.y2 = box->y2 - box->y1;
|
||||
|
||||
CLUTTER_NOTE (LAYOUT,
|
||||
"Allocating %d children of %s "
|
||||
@@ -2714,46 +2659,15 @@ check_layout:
|
||||
"using %s",
|
||||
priv->n_children,
|
||||
_clutter_actor_get_debug_name (self),
|
||||
allocation->x1,
|
||||
allocation->y1,
|
||||
(allocation->x2 - allocation->x1),
|
||||
(allocation->y2 - allocation->y1),
|
||||
box->x1,
|
||||
box->y1,
|
||||
(box->x2 - box->x1),
|
||||
(box->y2 - box->y1),
|
||||
G_OBJECT_TYPE_NAME (priv->layout_manager));
|
||||
|
||||
clutter_layout_manager_allocate (priv->layout_manager,
|
||||
container,
|
||||
&children_box,
|
||||
children_flags);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_actor_real_allocate (ClutterActor *self,
|
||||
const ClutterActorBox *box,
|
||||
ClutterAllocationFlags flags)
|
||||
{
|
||||
ClutterActorPrivate *priv = self->priv;
|
||||
gboolean changed;
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (self));
|
||||
|
||||
changed = clutter_actor_set_allocation_internal (self, box, flags);
|
||||
|
||||
/* we allocate our children before we notify changes in our geometry,
|
||||
* so that people connecting to properties will be able to get valid
|
||||
* data out of the sub-tree of the scene graph that has this actor at
|
||||
* the root.
|
||||
*/
|
||||
clutter_actor_maybe_layout_children (self, box, flags);
|
||||
|
||||
if (changed)
|
||||
{
|
||||
ClutterActorBox signal_box = priv->allocation;
|
||||
ClutterAllocationFlags signal_flags = priv->allocation_flags;
|
||||
|
||||
g_signal_emit (self, actor_signals[ALLOCATION_CHANGED], 0,
|
||||
&signal_box,
|
||||
signal_flags);
|
||||
CLUTTER_CONTAINER (self),
|
||||
&children_box);
|
||||
}
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (self));
|
||||
@@ -2792,7 +2706,7 @@ _clutter_actor_propagate_queue_redraw (ClutterActor *self,
|
||||
if (stop)
|
||||
break;
|
||||
|
||||
self = clutter_actor_get_parent (self);
|
||||
self = self->priv->parent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3310,8 +3224,6 @@ _clutter_actor_apply_relative_transformation_matrix (ClutterActor *self,
|
||||
ClutterActor *ancestor,
|
||||
CoglMatrix *matrix)
|
||||
{
|
||||
ClutterActor *parent;
|
||||
|
||||
/* Note we terminate before ever calling stage->apply_transform()
|
||||
* since that would conceptually be relative to the underlying
|
||||
* window OpenGL coordinates so we'd need a special @ancestor
|
||||
@@ -3319,10 +3231,9 @@ _clutter_actor_apply_relative_transformation_matrix (ClutterActor *self,
|
||||
if (self == ancestor)
|
||||
return;
|
||||
|
||||
parent = clutter_actor_get_parent (self);
|
||||
|
||||
if (parent != NULL)
|
||||
_clutter_actor_apply_relative_transformation_matrix (parent, ancestor,
|
||||
if (self->priv->parent != NULL)
|
||||
_clutter_actor_apply_relative_transformation_matrix (self->priv->parent,
|
||||
ancestor,
|
||||
matrix);
|
||||
|
||||
_clutter_actor_apply_modelview_transform (self, matrix);
|
||||
@@ -8608,35 +8519,6 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_PICK_CONTEXT);
|
||||
|
||||
/**
|
||||
* ClutterActor::allocation-changed:
|
||||
* @actor: the #ClutterActor that emitted the signal
|
||||
* @box: a #ClutterActorBox with the new allocation
|
||||
* @flags: #ClutterAllocationFlags for the allocation
|
||||
*
|
||||
* The ::allocation-changed signal is emitted when the
|
||||
* #ClutterActor:allocation property changes. Usually, application
|
||||
* code should just use the notifications for the :allocation property
|
||||
* but if you want to track the allocation flags as well, for instance
|
||||
* to know whether the absolute origin of @actor changed, then you might
|
||||
* want use this signal instead.
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
actor_signals[ALLOCATION_CHANGED] =
|
||||
g_signal_new (I_("allocation-changed"),
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL,
|
||||
_clutter_marshal_VOID__BOXED_FLAGS,
|
||||
G_TYPE_NONE, 2,
|
||||
CLUTTER_TYPE_ACTOR_BOX | G_SIGNAL_TYPE_STATIC_SCOPE,
|
||||
CLUTTER_TYPE_ALLOCATION_FLAGS);
|
||||
g_signal_set_va_marshaller (actor_signals[ALLOCATION_CHANGED],
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
_clutter_marshal_VOID__BOXED_FLAGSv);
|
||||
|
||||
/**
|
||||
* ClutterActor::transitions-completed:
|
||||
* @actor: a #ClutterActor
|
||||
@@ -8868,26 +8750,15 @@ static void
|
||||
_clutter_actor_get_allocation_clip (ClutterActor *self,
|
||||
ClutterActorBox *clip)
|
||||
{
|
||||
ClutterActorBox allocation;
|
||||
|
||||
/* XXX: we don't care if we get an out of date allocation here
|
||||
* because clutter_actor_queue_redraw_with_clip knows to ignore
|
||||
* the clip if the actor's allocation is invalid.
|
||||
*
|
||||
* This is noted because clutter_actor_get_allocation_box does some
|
||||
* unnecessary work to support buggy code with a comment suggesting
|
||||
* that it could be changed later which would be good for this use
|
||||
* case!
|
||||
*/
|
||||
clutter_actor_get_allocation_box (self, &allocation);
|
||||
ClutterActorPrivate *priv = self->priv;
|
||||
|
||||
/* NB: clutter_actor_queue_redraw_with_clip expects a box in the
|
||||
* actor's own coordinate space but the allocation is in parent
|
||||
* coordinates */
|
||||
clip->x1 = 0;
|
||||
clip->y1 = 0;
|
||||
clip->x2 = allocation.x2 - allocation.x1;
|
||||
clip->y2 = allocation.y2 - allocation.y1;
|
||||
clip->x2 = priv->allocation.x2 - priv->allocation.x1;
|
||||
clip->y2 = priv->allocation.y2 - priv->allocation.y1;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -8976,25 +8847,21 @@ _clutter_actor_queue_redraw_full (ClutterActor *self,
|
||||
if (CLUTTER_ACTOR_IN_DESTRUCTION (self))
|
||||
return;
|
||||
|
||||
/* we can ignore unmapped actors, unless they have at least one
|
||||
* mapped clone or they are inside a cloned branch of the scene
|
||||
* graph, as unmapped actors will simply be left unpainted.
|
||||
/* we can ignore unmapped actors, unless they are inside a cloned branch
|
||||
* of the scene graph, as unmapped actors will simply be left unpainted.
|
||||
*
|
||||
* this allows us to ignore redraws queued on leaf nodes when one
|
||||
* of their parents has been hidden
|
||||
*/
|
||||
if (!CLUTTER_ACTOR_IS_MAPPED (self) &&
|
||||
self->priv->in_cloned_branch == 0 &&
|
||||
!clutter_actor_has_mapped_clones (self))
|
||||
{
|
||||
CLUTTER_NOTE (PAINT,
|
||||
"Skipping queue_redraw('%s'): mapped=%s, "
|
||||
"mapped_clones=%s, "
|
||||
"in_cloned_branch=%s",
|
||||
"has_mapped_clones=%s",
|
||||
_clutter_actor_get_debug_name (self),
|
||||
CLUTTER_ACTOR_IS_MAPPED (self) ? "yes" : "no",
|
||||
clutter_actor_has_mapped_clones (self) ? "yes" : "no",
|
||||
self->priv->in_cloned_branch != 0 ? "yes" : "no");
|
||||
clutter_actor_has_mapped_clones (self) ? "yes" : "no");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -10174,8 +10041,7 @@ clutter_actor_adjust_allocation (ClutterActor *self,
|
||||
|
||||
static void
|
||||
clutter_actor_allocate_internal (ClutterActor *self,
|
||||
const ClutterActorBox *allocation,
|
||||
ClutterAllocationFlags flags)
|
||||
const ClutterActorBox *allocation)
|
||||
{
|
||||
ClutterActorClass *klass;
|
||||
|
||||
@@ -10185,7 +10051,7 @@ clutter_actor_allocate_internal (ClutterActor *self,
|
||||
_clutter_actor_get_debug_name (self));
|
||||
|
||||
klass = CLUTTER_ACTOR_GET_CLASS (self);
|
||||
klass->allocate (self, allocation, flags);
|
||||
klass->allocate (self, allocation);
|
||||
|
||||
CLUTTER_UNSET_PRIVATE_FLAGS (self, CLUTTER_IN_RELAYOUT);
|
||||
|
||||
@@ -10198,7 +10064,6 @@ clutter_actor_allocate_internal (ClutterActor *self,
|
||||
* clutter_actor_allocate:
|
||||
* @self: A #ClutterActor
|
||||
* @box: new allocation of the actor, in parent-relative coordinates
|
||||
* @flags: flags that control the allocation
|
||||
*
|
||||
* Assigns the size of a #ClutterActor from the given @box.
|
||||
*
|
||||
@@ -10224,12 +10089,11 @@ clutter_actor_allocate_internal (ClutterActor *self,
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
clutter_actor_allocate (ClutterActor *self,
|
||||
const ClutterActorBox *box,
|
||||
ClutterAllocationFlags flags)
|
||||
clutter_actor_allocate (ClutterActor *self,
|
||||
const ClutterActorBox *box)
|
||||
{
|
||||
ClutterActorBox old_allocation, real_allocation;
|
||||
gboolean origin_changed, child_moved, size_changed;
|
||||
gboolean origin_changed, size_changed;
|
||||
gboolean stage_allocation_changed;
|
||||
ClutterActorPrivate *priv;
|
||||
|
||||
@@ -10272,18 +10136,19 @@ clutter_actor_allocate (ClutterActor *self,
|
||||
real_allocation.x2 = MAX (real_allocation.x2, real_allocation.x1);
|
||||
real_allocation.y2 = MAX (real_allocation.y2, real_allocation.y1);
|
||||
|
||||
origin_changed = (flags & CLUTTER_ABSOLUTE_ORIGIN_CHANGED);
|
||||
|
||||
child_moved = (real_allocation.x1 != old_allocation.x1 ||
|
||||
real_allocation.y1 != old_allocation.y1);
|
||||
origin_changed = (real_allocation.x1 != old_allocation.x1 ||
|
||||
real_allocation.y1 != old_allocation.y1);
|
||||
|
||||
size_changed = (real_allocation.x2 != old_allocation.x2 ||
|
||||
real_allocation.y2 != old_allocation.y2);
|
||||
|
||||
if (origin_changed || child_moved || size_changed)
|
||||
stage_allocation_changed = TRUE;
|
||||
else
|
||||
stage_allocation_changed = FALSE;
|
||||
priv->absolute_origin_changed = priv->parent
|
||||
? priv->parent->priv->absolute_origin_changed
|
||||
: FALSE;
|
||||
|
||||
priv->absolute_origin_changed |= origin_changed;
|
||||
|
||||
stage_allocation_changed = priv->absolute_origin_changed || size_changed;
|
||||
|
||||
/* If we get an allocation "out of the blue"
|
||||
* (we did not queue relayout), then we want to
|
||||
@@ -10313,24 +10178,10 @@ clutter_actor_allocate (ClutterActor *self,
|
||||
{
|
||||
/* If the actor didn't move but needs_allocation is set, we just
|
||||
* need to allocate the children */
|
||||
clutter_actor_allocate_internal (self, &real_allocation, flags);
|
||||
clutter_actor_allocate_internal (self, &real_allocation);
|
||||
return;
|
||||
}
|
||||
|
||||
/* When ABSOLUTE_ORIGIN_CHANGED is passed in to
|
||||
* clutter_actor_allocate(), it indicates whether the parent has its
|
||||
* absolute origin moved; when passed in to ClutterActor::allocate()
|
||||
* virtual method though, it indicates whether the child has its
|
||||
* absolute origin moved. So we set it when child_moved is TRUE
|
||||
*/
|
||||
if (child_moved)
|
||||
flags |= CLUTTER_ABSOLUTE_ORIGIN_CHANGED;
|
||||
|
||||
/* store the flags here, so that they can be propagated by the
|
||||
* transition code
|
||||
*/
|
||||
self->priv->allocation_flags = flags;
|
||||
|
||||
_clutter_actor_create_transition (self, obj_props[PROP_ALLOCATION],
|
||||
&priv->allocation,
|
||||
&real_allocation);
|
||||
@@ -10340,20 +10191,14 @@ clutter_actor_allocate (ClutterActor *self,
|
||||
* clutter_actor_set_allocation:
|
||||
* @self: a #ClutterActor
|
||||
* @box: a #ClutterActorBox
|
||||
* @flags: allocation flags
|
||||
*
|
||||
* Stores the allocation of @self as defined by @box.
|
||||
*
|
||||
* This function can only be called from within the implementation of
|
||||
* the #ClutterActorClass.allocate() virtual function.
|
||||
*
|
||||
* The allocation should have been adjusted to take into account constraints,
|
||||
* alignment, and margin properties. If you are implementing a #ClutterActor
|
||||
* subclass that provides its own layout management policy for its children
|
||||
* instead of using a #ClutterLayoutManager delegate, you should not call
|
||||
* this function on the children of @self; instead, you should call
|
||||
* clutter_actor_allocate(), which will adjust the allocation box for
|
||||
* you.
|
||||
* The allocation @box should have been adjusted to take into account
|
||||
* constraints, alignment, and margin properties.
|
||||
*
|
||||
* This function should only be used by subclasses of #ClutterActor
|
||||
* that wish to store their allocation but cannot chain up to the
|
||||
@@ -10361,69 +10206,12 @@ clutter_actor_allocate (ClutterActor *self,
|
||||
* #ClutterActorClass.allocate() virtual function will call this
|
||||
* function.
|
||||
*
|
||||
* It is important to note that, while chaining up was the recommended
|
||||
* behaviour for #ClutterActor subclasses prior to the introduction of
|
||||
* this function, it is recommended to call clutter_actor_set_allocation()
|
||||
* instead.
|
||||
*
|
||||
* If the #ClutterActor is using a #ClutterLayoutManager delegate object
|
||||
* to handle the allocation of its children, this function will call
|
||||
* the clutter_layout_manager_allocate() function only if the
|
||||
* %CLUTTER_DELEGATE_LAYOUT flag is set on @flags, otherwise it is
|
||||
* expected that the subclass will call clutter_layout_manager_allocate()
|
||||
* by itself. For instance, the following code:
|
||||
*
|
||||
* |[<!-- language="C" -->
|
||||
* static void
|
||||
* my_actor_allocate (ClutterActor *actor,
|
||||
* const ClutterActorBox *allocation,
|
||||
* ClutterAllocationFlags flags)
|
||||
* {
|
||||
* ClutterActorBox new_alloc;
|
||||
* ClutterAllocationFlags new_flags;
|
||||
*
|
||||
* adjust_allocation (allocation, &new_alloc);
|
||||
*
|
||||
* new_flags = flags | CLUTTER_DELEGATE_LAYOUT;
|
||||
*
|
||||
* // this will use the layout manager set on the actor
|
||||
* clutter_actor_set_allocation (actor, &new_alloc, new_flags);
|
||||
* }
|
||||
* ]|
|
||||
*
|
||||
* is equivalent to this:
|
||||
*
|
||||
* |[<!-- language="C" -->
|
||||
* static void
|
||||
* my_actor_allocate (ClutterActor *actor,
|
||||
* const ClutterActorBox *allocation,
|
||||
* ClutterAllocationFlags flags)
|
||||
* {
|
||||
* ClutterLayoutManager *layout;
|
||||
* ClutterActorBox new_alloc;
|
||||
*
|
||||
* adjust_allocation (allocation, &new_alloc);
|
||||
*
|
||||
* clutter_actor_set_allocation (actor, &new_alloc, flags);
|
||||
*
|
||||
* layout = clutter_actor_get_layout_manager (actor);
|
||||
* clutter_layout_manager_allocate (layout,
|
||||
* CLUTTER_CONTAINER (actor),
|
||||
* &new_alloc,
|
||||
* flags);
|
||||
* }
|
||||
* ]|
|
||||
*
|
||||
* Since: 1.10
|
||||
*/
|
||||
void
|
||||
clutter_actor_set_allocation (ClutterActor *self,
|
||||
const ClutterActorBox *box,
|
||||
ClutterAllocationFlags flags)
|
||||
const ClutterActorBox *box)
|
||||
{
|
||||
ClutterActorPrivate *priv;
|
||||
gboolean changed;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR (self));
|
||||
g_return_if_fail (box != NULL);
|
||||
|
||||
@@ -10435,28 +10223,9 @@ clutter_actor_set_allocation (ClutterActor *self,
|
||||
return;
|
||||
}
|
||||
|
||||
priv = self->priv;
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (self));
|
||||
|
||||
changed = clutter_actor_set_allocation_internal (self, box, flags);
|
||||
|
||||
/* we allocate our children before we notify changes in our geometry,
|
||||
* so that people connecting to properties will be able to get valid
|
||||
* data out of the sub-tree of the scene graph that has this actor at
|
||||
* the root.
|
||||
*/
|
||||
clutter_actor_maybe_layout_children (self, box, flags);
|
||||
|
||||
if (changed)
|
||||
{
|
||||
ClutterActorBox signal_box = priv->allocation;
|
||||
ClutterAllocationFlags signal_flags = priv->allocation_flags;
|
||||
|
||||
g_signal_emit (self, actor_signals[ALLOCATION_CHANGED], 0,
|
||||
&signal_box,
|
||||
signal_flags);
|
||||
}
|
||||
clutter_actor_set_allocation_internal (self, box);
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (self));
|
||||
}
|
||||
@@ -14929,9 +14698,7 @@ clutter_actor_set_animatable_property (ClutterActor *actor,
|
||||
break;
|
||||
|
||||
case PROP_ALLOCATION:
|
||||
clutter_actor_allocate_internal (actor,
|
||||
g_value_get_boxed (value),
|
||||
actor->priv->allocation_flags);
|
||||
clutter_actor_allocate_internal (actor, g_value_get_boxed (value));
|
||||
clutter_actor_queue_redraw (actor);
|
||||
break;
|
||||
|
||||
@@ -15325,7 +15092,6 @@ clutter_actor_get_stage (ClutterActor *actor)
|
||||
* actor's natural width
|
||||
* @available_height: the maximum available height, or -1 to use the
|
||||
* actor's natural height
|
||||
* @flags: flags controlling the allocation
|
||||
*
|
||||
* Allocates @self taking into account the #ClutterActor's
|
||||
* preferred size, but limiting it to the maximum available width
|
||||
@@ -15372,7 +15138,7 @@ clutter_actor_get_stage (ClutterActor *actor)
|
||||
* box.x1 = x; box.y1 = y;
|
||||
* box.x2 = box.x1 + available_width;
|
||||
* box.y2 = box.y1 + available_height;
|
||||
* clutter_actor_allocate (self, &box, flags);
|
||||
* clutter_actor_allocate (self, &box);
|
||||
* ]|
|
||||
*
|
||||
* This function can be used by fluid layout managers to allocate
|
||||
@@ -15386,8 +15152,7 @@ clutter_actor_allocate_available_size (ClutterActor *self,
|
||||
gfloat x,
|
||||
gfloat y,
|
||||
gfloat available_width,
|
||||
gfloat available_height,
|
||||
ClutterAllocationFlags flags)
|
||||
gfloat available_height)
|
||||
{
|
||||
ClutterActorPrivate *priv;
|
||||
gfloat width, height;
|
||||
@@ -15443,13 +15208,12 @@ clutter_actor_allocate_available_size (ClutterActor *self,
|
||||
box.y1 = y;
|
||||
box.x2 = box.x1 + width;
|
||||
box.y2 = box.y1 + height;
|
||||
clutter_actor_allocate (self, &box, flags);
|
||||
clutter_actor_allocate (self, &box);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_allocate_preferred_size:
|
||||
* @self: a #ClutterActor
|
||||
* @flags: flags controlling the allocation
|
||||
*
|
||||
* Allocates the natural size of @self.
|
||||
*
|
||||
@@ -15467,8 +15231,7 @@ clutter_actor_allocate_available_size (ClutterActor *self,
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
clutter_actor_allocate_preferred_size (ClutterActor *self,
|
||||
ClutterAllocationFlags flags)
|
||||
clutter_actor_allocate_preferred_size (ClutterActor *self)
|
||||
{
|
||||
gfloat actor_x, actor_y;
|
||||
gfloat natural_width, natural_height;
|
||||
@@ -15502,7 +15265,7 @@ clutter_actor_allocate_preferred_size (ClutterActor *self,
|
||||
actor_box.x2 = actor_box.x1 + natural_width;
|
||||
actor_box.y2 = actor_box.y1 + natural_height;
|
||||
|
||||
clutter_actor_allocate (self, &actor_box, flags);
|
||||
clutter_actor_allocate (self, &actor_box);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -15513,7 +15276,6 @@ clutter_actor_allocate_preferred_size (ClutterActor *self,
|
||||
* @y_align: the vertical alignment, between 0 and 1
|
||||
* @x_fill: whether the actor should fill horizontally
|
||||
* @y_fill: whether the actor should fill vertically
|
||||
* @flags: allocation flags to be passed to clutter_actor_allocate()
|
||||
*
|
||||
* Allocates @self by taking into consideration the available allocation
|
||||
* area; an alignment factor on either axis; and whether the actor should
|
||||
@@ -15540,8 +15302,7 @@ clutter_actor_allocate_align_fill (ClutterActor *self,
|
||||
gdouble x_align,
|
||||
gdouble y_align,
|
||||
gboolean x_fill,
|
||||
gboolean y_fill,
|
||||
ClutterAllocationFlags flags)
|
||||
gboolean y_fill)
|
||||
{
|
||||
ClutterActorPrivate *priv;
|
||||
ClutterActorBox allocation = CLUTTER_ACTOR_BOX_INIT_ZERO;
|
||||
@@ -15657,7 +15418,7 @@ out:
|
||||
allocation.x2 = ceilf (allocation.x1 + MAX (child_width, 0));
|
||||
allocation.y2 = ceilf (allocation.y1 + MAX (child_height, 0));
|
||||
|
||||
clutter_actor_allocate (self, &allocation, flags);
|
||||
clutter_actor_allocate (self, &allocation);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -19319,7 +19080,6 @@ should_skip_implicit_transition (ClutterActor *self,
|
||||
* when those transitions happen
|
||||
*/
|
||||
if (!CLUTTER_ACTOR_IS_MAPPED (self) &&
|
||||
priv->in_cloned_branch == 0 &&
|
||||
!clutter_actor_has_mapped_clones (self))
|
||||
return TRUE;
|
||||
|
||||
@@ -20939,31 +20699,41 @@ _clutter_actor_queue_relayout_on_clones (ClutterActor *self)
|
||||
* clutter_actor_has_mapped_clones:
|
||||
* @self: a #ClutterActor
|
||||
*
|
||||
* Returns whether a #ClutterActor has any mapped clones.
|
||||
* Returns whether a #ClutterActor or any parent actors have mapped clones
|
||||
* that are clone-painting @self.
|
||||
*
|
||||
* Return: %TRUE if the actor has mapped clones, and %FALSE otherwise
|
||||
*
|
||||
* Since: 1.16
|
||||
* Returns: %TRUE if the actor has mapped clones, %FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
clutter_actor_has_mapped_clones (ClutterActor *self)
|
||||
{
|
||||
ClutterActorPrivate *priv;
|
||||
ClutterActor *actor;
|
||||
GHashTableIter iter;
|
||||
gpointer key;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE);
|
||||
|
||||
priv = self->priv;
|
||||
|
||||
if (priv->clones == NULL)
|
||||
if (self->priv->in_cloned_branch == 0)
|
||||
return FALSE;
|
||||
|
||||
g_hash_table_iter_init (&iter, priv->clones);
|
||||
while (g_hash_table_iter_next (&iter, &key, NULL))
|
||||
for (actor = self; actor; actor = actor->priv->parent)
|
||||
{
|
||||
if (CLUTTER_ACTOR_IS_MAPPED (key))
|
||||
return TRUE;
|
||||
if (actor->priv->clones)
|
||||
{
|
||||
g_hash_table_iter_init (&iter, actor->priv->clones);
|
||||
while (g_hash_table_iter_next (&iter, &key, NULL))
|
||||
{
|
||||
if (CLUTTER_ACTOR_IS_MAPPED (key))
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clones will force-show their own source actor but not children of
|
||||
* it, so if we're hidden and an actor up the hierarchy has a clone,
|
||||
* we won't be visisble.
|
||||
*/
|
||||
if (!CLUTTER_ACTOR_IS_VISIBLE (actor))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
@@ -175,9 +175,12 @@ struct _ClutterActor
|
||||
* @get_preferred_height: virtual function, used when querying the minimum
|
||||
* and natural heights of an actor for a given width; it is used by
|
||||
* clutter_actor_get_preferred_height()
|
||||
* @allocate: virtual function, used when settings the coordinates of an
|
||||
* actor; it is used by clutter_actor_allocate(); it must chain up to
|
||||
* the parent's implementation, or call clutter_actor_set_allocation()
|
||||
* @allocate: virtual function, used when setting the coordinates of an
|
||||
* actor; it is used by clutter_actor_allocate(); when overriding this
|
||||
* function without chaining up, clutter_actor_set_allocation() must be
|
||||
* called and children must be allocated by the implementation, when
|
||||
* chaining up though, those things will be done by the parent's
|
||||
* implementation.
|
||||
* @apply_transform: virtual function, used when applying the transformations
|
||||
* to an actor before painting it or when transforming coordinates or
|
||||
* the allocation; it must chain up to the parent's implementation
|
||||
@@ -253,8 +256,7 @@ struct _ClutterActorClass
|
||||
gfloat *min_height_p,
|
||||
gfloat *natural_height_p);
|
||||
void (* allocate) (ClutterActor *self,
|
||||
const ClutterActorBox *box,
|
||||
ClutterAllocationFlags flags);
|
||||
const ClutterActorBox *box);
|
||||
|
||||
/* transformations */
|
||||
void (* apply_transform) (ClutterActor *actor,
|
||||
@@ -415,30 +417,25 @@ void clutter_actor_get_preferred_size
|
||||
gfloat *natural_height_p);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_allocate (ClutterActor *self,
|
||||
const ClutterActorBox *box,
|
||||
ClutterAllocationFlags flags);
|
||||
const ClutterActorBox *box);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_allocate_preferred_size (ClutterActor *self,
|
||||
ClutterAllocationFlags flags);
|
||||
void clutter_actor_allocate_preferred_size (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_allocate_available_size (ClutterActor *self,
|
||||
gfloat x,
|
||||
gfloat y,
|
||||
gfloat available_width,
|
||||
gfloat available_height,
|
||||
ClutterAllocationFlags flags);
|
||||
gfloat available_height);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_allocate_align_fill (ClutterActor *self,
|
||||
const ClutterActorBox *box,
|
||||
gdouble x_align,
|
||||
gdouble y_align,
|
||||
gboolean x_fill,
|
||||
gboolean y_fill,
|
||||
ClutterAllocationFlags flags);
|
||||
gboolean y_fill);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_allocation (ClutterActor *self,
|
||||
const ClutterActorBox *box,
|
||||
ClutterAllocationFlags flags);
|
||||
const ClutterActorBox *box);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_allocation_box (ClutterActor *self,
|
||||
ClutterActorBox *box);
|
||||
|
@@ -85,8 +85,7 @@ G_DEFINE_TYPE (ClutterAlignConstraint,
|
||||
|
||||
static void
|
||||
source_position_changed (ClutterActor *actor,
|
||||
const ClutterActorBox *allocation,
|
||||
ClutterAllocationFlags flags,
|
||||
GParamSpec *pspec,
|
||||
ClutterAlignConstraint *align)
|
||||
{
|
||||
if (align->actor != NULL)
|
||||
@@ -410,7 +409,7 @@ clutter_align_constraint_set_source (ClutterAlignConstraint *align,
|
||||
align->source = source;
|
||||
if (align->source != NULL)
|
||||
{
|
||||
g_signal_connect (align->source, "allocation-changed",
|
||||
g_signal_connect (align->source, "notify::allocation",
|
||||
G_CALLBACK (source_position_changed),
|
||||
align);
|
||||
g_signal_connect (align->source, "destroy",
|
||||
|
@@ -30,9 +30,7 @@
|
||||
|
||||
#ifndef __GI_SCANNER__
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterAction, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActor, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActorMeta, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterAlignConstraint, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBackend, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBindConstraint, g_object_unref)
|
||||
@@ -43,7 +41,6 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBoxLayout, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBrightnessContrastEffect, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterCanvas, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterChildMeta, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterClickAction, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterClone, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterColorizeEffect, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterConstraint, g_object_unref)
|
||||
@@ -53,7 +50,6 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDesaturateEffect, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterEffect, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterFixedLayout, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterFlowLayout, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterGestureAction, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterGridLayout, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterImage, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterInputDevice, g_object_unref)
|
||||
|
@@ -406,8 +406,7 @@ get_actor_align_factor (ClutterActorAlign alignment)
|
||||
static void
|
||||
clutter_bin_layout_allocate (ClutterLayoutManager *manager,
|
||||
ClutterContainer *container,
|
||||
const ClutterActorBox *allocation,
|
||||
ClutterAllocationFlags flags)
|
||||
const ClutterActorBox *allocation)
|
||||
{
|
||||
gfloat allocation_x, allocation_y;
|
||||
gfloat available_w, available_h;
|
||||
@@ -515,8 +514,7 @@ clutter_bin_layout_allocate (ClutterLayoutManager *manager,
|
||||
|
||||
clutter_actor_allocate_align_fill (child, &child_alloc,
|
||||
x_align, y_align,
|
||||
x_fill, y_fill,
|
||||
flags);
|
||||
x_fill, y_fill);
|
||||
}
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -105,64 +105,6 @@ void clutter_box_layout_set_pack_start (ClutterBoxLayou
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_box_layout_get_pack_start (ClutterBoxLayout *layout);
|
||||
|
||||
CLUTTER_DEPRECATED_FOR(clutter_box_layout_set_orientation)
|
||||
void clutter_box_layout_set_vertical (ClutterBoxLayout *layout,
|
||||
gboolean vertical);
|
||||
CLUTTER_DEPRECATED_FOR(clutter_box_layout_get_orientation)
|
||||
gboolean clutter_box_layout_get_vertical (ClutterBoxLayout *layout);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_box_layout_pack (ClutterBoxLayout *layout,
|
||||
ClutterActor *actor,
|
||||
gboolean expand,
|
||||
gboolean x_fill,
|
||||
gboolean y_fill,
|
||||
ClutterBoxAlignment x_align,
|
||||
ClutterBoxAlignment y_align);
|
||||
CLUTTER_DEPRECATED
|
||||
void clutter_box_layout_set_alignment (ClutterBoxLayout *layout,
|
||||
ClutterActor *actor,
|
||||
ClutterBoxAlignment x_align,
|
||||
ClutterBoxAlignment y_align);
|
||||
CLUTTER_DEPRECATED
|
||||
void clutter_box_layout_get_alignment (ClutterBoxLayout *layout,
|
||||
ClutterActor *actor,
|
||||
ClutterBoxAlignment *x_align,
|
||||
ClutterBoxAlignment *y_align);
|
||||
CLUTTER_DEPRECATED
|
||||
void clutter_box_layout_set_fill (ClutterBoxLayout *layout,
|
||||
ClutterActor *actor,
|
||||
gboolean x_fill,
|
||||
gboolean y_fill);
|
||||
CLUTTER_DEPRECATED
|
||||
void clutter_box_layout_get_fill (ClutterBoxLayout *layout,
|
||||
ClutterActor *actor,
|
||||
gboolean *x_fill,
|
||||
gboolean *y_fill);
|
||||
CLUTTER_DEPRECATED
|
||||
void clutter_box_layout_set_expand (ClutterBoxLayout *layout,
|
||||
ClutterActor *actor,
|
||||
gboolean expand);
|
||||
CLUTTER_DEPRECATED
|
||||
gboolean clutter_box_layout_get_expand (ClutterBoxLayout *layout,
|
||||
ClutterActor *actor);
|
||||
|
||||
CLUTTER_DEPRECATED
|
||||
void clutter_box_layout_set_use_animations (ClutterBoxLayout *layout,
|
||||
gboolean animate);
|
||||
CLUTTER_DEPRECATED
|
||||
gboolean clutter_box_layout_get_use_animations (ClutterBoxLayout *layout);
|
||||
CLUTTER_DEPRECATED
|
||||
void clutter_box_layout_set_easing_mode (ClutterBoxLayout *layout,
|
||||
ClutterAnimationMode mode);
|
||||
CLUTTER_DEPRECATED
|
||||
ClutterAnimationMode clutter_box_layout_get_easing_mode (ClutterBoxLayout *layout);
|
||||
CLUTTER_DEPRECATED
|
||||
void clutter_box_layout_set_easing_duration (ClutterBoxLayout *layout,
|
||||
guint msecs);
|
||||
CLUTTER_DEPRECATED
|
||||
guint clutter_box_layout_get_easing_duration (ClutterBoxLayout *layout);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_BOX_LAYOUT_H__ */
|
||||
|
@@ -159,7 +159,8 @@ static inline void
|
||||
click_action_set_pressed (ClutterClickAction *action,
|
||||
gboolean is_pressed)
|
||||
{
|
||||
ClutterClickActionPrivate *priv = action->priv;
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (action);
|
||||
|
||||
is_pressed = !!is_pressed;
|
||||
|
||||
@@ -174,7 +175,8 @@ static inline void
|
||||
click_action_set_held (ClutterClickAction *action,
|
||||
gboolean is_held)
|
||||
{
|
||||
ClutterClickActionPrivate *priv = action->priv;
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (action);
|
||||
|
||||
is_held = !!is_held;
|
||||
|
||||
@@ -189,7 +191,8 @@ static gboolean
|
||||
click_action_emit_long_press (gpointer data)
|
||||
{
|
||||
ClutterClickAction *action = data;
|
||||
ClutterClickActionPrivate *priv = action->priv;
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (action);
|
||||
ClutterActor *actor;
|
||||
gboolean result;
|
||||
|
||||
@@ -213,7 +216,8 @@ click_action_emit_long_press (gpointer data)
|
||||
static inline void
|
||||
click_action_query_long_press (ClutterClickAction *action)
|
||||
{
|
||||
ClutterClickActionPrivate *priv = action->priv;
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (action);
|
||||
ClutterActor *actor;
|
||||
gboolean result = FALSE;
|
||||
gint timeout;
|
||||
@@ -249,7 +253,8 @@ click_action_query_long_press (ClutterClickAction *action)
|
||||
static inline void
|
||||
click_action_cancel_long_press (ClutterClickAction *action)
|
||||
{
|
||||
ClutterClickActionPrivate *priv = action->priv;
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (action);
|
||||
|
||||
if (priv->long_press_id != 0)
|
||||
{
|
||||
@@ -272,7 +277,8 @@ on_event (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
ClutterClickAction *action)
|
||||
{
|
||||
ClutterClickActionPrivate *priv = action->priv;
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (action);
|
||||
gboolean has_button = TRUE;
|
||||
|
||||
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (action)))
|
||||
@@ -342,7 +348,8 @@ on_captured_event (ClutterActor *stage,
|
||||
ClutterEvent *event,
|
||||
ClutterClickAction *action)
|
||||
{
|
||||
ClutterClickActionPrivate *priv = action->priv;
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (action);
|
||||
ClutterActor *actor;
|
||||
ClutterModifierType modifier_state;
|
||||
gboolean has_button = TRUE;
|
||||
@@ -434,7 +441,8 @@ clutter_click_action_set_actor (ClutterActorMeta *meta,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
ClutterClickAction *action = CLUTTER_CLICK_ACTION (meta);
|
||||
ClutterClickActionPrivate *priv = action->priv;
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (action);
|
||||
|
||||
if (priv->event_id != 0)
|
||||
{
|
||||
@@ -488,7 +496,8 @@ clutter_click_action_set_property (GObject *gobject,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterClickActionPrivate *priv = CLUTTER_CLICK_ACTION (gobject)->priv;
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (CLUTTER_CLICK_ACTION (gobject));
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
@@ -512,7 +521,8 @@ clutter_click_action_get_property (GObject *gobject,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterClickActionPrivate *priv = CLUTTER_CLICK_ACTION (gobject)->priv;
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (CLUTTER_CLICK_ACTION (gobject));
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
@@ -541,7 +551,8 @@ clutter_click_action_get_property (GObject *gobject,
|
||||
static void
|
||||
clutter_click_action_dispose (GObject *gobject)
|
||||
{
|
||||
ClutterClickActionPrivate *priv = CLUTTER_CLICK_ACTION (gobject)->priv;
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (CLUTTER_CLICK_ACTION (gobject));
|
||||
|
||||
g_clear_signal_handler (&priv->event_id,
|
||||
clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (gobject)));
|
||||
@@ -699,9 +710,11 @@ clutter_click_action_class_init (ClutterClickActionClass *klass)
|
||||
static void
|
||||
clutter_click_action_init (ClutterClickAction *self)
|
||||
{
|
||||
self->priv = clutter_click_action_get_instance_private (self);
|
||||
self->priv->long_press_threshold = -1;
|
||||
self->priv->long_press_duration = -1;
|
||||
ClutterClickActionPrivate *priv =
|
||||
clutter_click_action_get_instance_private (self);
|
||||
|
||||
priv->long_press_threshold = -1;
|
||||
priv->long_press_duration = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -741,7 +754,7 @@ clutter_click_action_release (ClutterClickAction *action)
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_CLICK_ACTION (action));
|
||||
|
||||
priv = action->priv;
|
||||
priv = clutter_click_action_get_instance_private (action);
|
||||
|
||||
if (!priv->is_held)
|
||||
return;
|
||||
@@ -767,9 +780,13 @@ clutter_click_action_release (ClutterClickAction *action)
|
||||
guint
|
||||
clutter_click_action_get_button (ClutterClickAction *action)
|
||||
{
|
||||
ClutterClickActionPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_CLICK_ACTION (action), 0);
|
||||
|
||||
return action->priv->press_button;
|
||||
priv = clutter_click_action_get_instance_private (action);
|
||||
|
||||
return priv->press_button;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -785,9 +802,13 @@ clutter_click_action_get_button (ClutterClickAction *action)
|
||||
ClutterModifierType
|
||||
clutter_click_action_get_state (ClutterClickAction *action)
|
||||
{
|
||||
ClutterClickActionPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_CLICK_ACTION (action), 0);
|
||||
|
||||
return action->priv->modifier_state;
|
||||
priv = clutter_click_action_get_instance_private (action);
|
||||
|
||||
return priv->modifier_state;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -805,11 +826,15 @@ clutter_click_action_get_coords (ClutterClickAction *action,
|
||||
gfloat *press_x,
|
||||
gfloat *press_y)
|
||||
{
|
||||
ClutterClickActionPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ACTION (action));
|
||||
|
||||
priv = clutter_click_action_get_instance_private (action);
|
||||
|
||||
if (press_x != NULL)
|
||||
*press_x = action->priv->press_x;
|
||||
*press_x = priv->press_x;
|
||||
|
||||
if (press_y != NULL)
|
||||
*press_y = action->priv->press_y;
|
||||
*press_y = priv->press_y;
|
||||
}
|
||||
|
@@ -37,32 +37,13 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_CLICK_ACTION (clutter_click_action_get_type ())
|
||||
#define CLUTTER_CLICK_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_CLICK_ACTION, ClutterClickAction))
|
||||
#define CLUTTER_IS_CLICK_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_CLICK_ACTION))
|
||||
#define CLUTTER_CLICK_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_CLICK_ACTION, ClutterClickActionClass))
|
||||
#define CLUTTER_IS_CLICK_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_CLICK_ACTION))
|
||||
#define CLUTTER_CLICK_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_CLICK_ACTION, ClutterClickActionClass))
|
||||
#define CLUTTER_TYPE_CLICK_ACTION (clutter_click_action_get_type ())
|
||||
|
||||
typedef struct _ClutterClickAction ClutterClickAction;
|
||||
typedef struct _ClutterClickActionPrivate ClutterClickActionPrivate;
|
||||
typedef struct _ClutterClickActionClass ClutterClickActionClass;
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterClickAction, clutter_click_action,
|
||||
CLUTTER, CLICK_ACTION, ClutterAction);
|
||||
|
||||
/**
|
||||
* ClutterClickAction:
|
||||
*
|
||||
* The #ClutterClickAction structure contains
|
||||
* only private data and should be accessed using the provided API
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
struct _ClutterClickAction
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterAction parent_instance;
|
||||
|
||||
ClutterClickActionPrivate *priv;
|
||||
};
|
||||
typedef struct _ClutterClickActionPrivate ClutterClickActionPrivate;
|
||||
|
||||
/**
|
||||
* ClutterClickActionClass:
|
||||
@@ -97,9 +78,6 @@ struct _ClutterClickActionClass
|
||||
void (* _clutter_click_action7) (void);
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType clutter_click_action_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterAction * clutter_click_action_new (void);
|
||||
|
||||
|
@@ -240,15 +240,14 @@ clutter_clone_has_overlaps (ClutterActor *actor)
|
||||
|
||||
static void
|
||||
clutter_clone_allocate (ClutterActor *self,
|
||||
const ClutterActorBox *box,
|
||||
ClutterAllocationFlags flags)
|
||||
const ClutterActorBox *box)
|
||||
{
|
||||
ClutterClonePrivate *priv = CLUTTER_CLONE (self)->priv;
|
||||
ClutterActorClass *parent_class;
|
||||
|
||||
/* chain up */
|
||||
parent_class = CLUTTER_ACTOR_CLASS (clutter_clone_parent_class);
|
||||
parent_class->allocate (self, box, flags);
|
||||
parent_class->allocate (self, box);
|
||||
|
||||
if (priv->clone_source == NULL)
|
||||
return;
|
||||
@@ -258,7 +257,7 @@ clutter_clone_allocate (ClutterActor *self,
|
||||
*/
|
||||
if (clutter_actor_get_parent (priv->clone_source) != NULL &&
|
||||
!clutter_actor_has_allocation (priv->clone_source))
|
||||
clutter_actor_allocate_preferred_size (priv->clone_source, flags);
|
||||
clutter_actor_allocate_preferred_size (priv->clone_source);
|
||||
|
||||
#if 0
|
||||
/* XXX - this is wrong: ClutterClone cannot clone unparented
|
||||
@@ -273,7 +272,7 @@ clutter_clone_allocate (ClutterActor *self,
|
||||
* paint cycle, we can safely give it as much size as it requires
|
||||
*/
|
||||
if (clutter_actor_get_parent (priv->clone_source) == NULL)
|
||||
clutter_actor_allocate_preferred_size (priv->clone_source, flags);
|
||||
clutter_actor_allocate_preferred_size (priv->clone_source);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
92
clutter/clutter/clutter-damage-history.c
Normal file
92
clutter/clutter/clutter-damage-history.c
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2007,2008,2009,2010,2011 Intel Corporation.
|
||||
* Copyright (C) 2020 Red Hat Inc
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "clutter-damage-history.h"
|
||||
|
||||
#define DAMAGE_HISTORY_LENGTH 0x10
|
||||
|
||||
struct _ClutterDamageHistory
|
||||
{
|
||||
cairo_region_t *damages[DAMAGE_HISTORY_LENGTH];
|
||||
int index;
|
||||
};
|
||||
|
||||
ClutterDamageHistory *
|
||||
clutter_damage_history_new (void)
|
||||
{
|
||||
ClutterDamageHistory *history;
|
||||
|
||||
history = g_new0 (ClutterDamageHistory, 1);
|
||||
|
||||
return history;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_damage_history_free (ClutterDamageHistory *history)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (history->damages); i++)
|
||||
g_clear_pointer (&history->damages[i], cairo_region_destroy);
|
||||
|
||||
g_free (history);
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_damage_history_is_age_valid (ClutterDamageHistory *history,
|
||||
int age)
|
||||
{
|
||||
if (age >= DAMAGE_HISTORY_LENGTH ||
|
||||
age < 1)
|
||||
return FALSE;
|
||||
|
||||
if (!clutter_damage_history_lookup (history, age))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_damage_history_record (ClutterDamageHistory *history,
|
||||
const cairo_region_t *damage)
|
||||
{
|
||||
g_clear_pointer (&history->damages[history->index], cairo_region_destroy);
|
||||
history->damages[history->index] = cairo_region_copy (damage);
|
||||
}
|
||||
|
||||
static inline int
|
||||
step_damage_index (int current,
|
||||
int diff)
|
||||
{
|
||||
return (current + diff) & (DAMAGE_HISTORY_LENGTH - 1);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_damage_history_step (ClutterDamageHistory *history)
|
||||
{
|
||||
history->index = step_damage_index (history->index, 1);
|
||||
}
|
||||
|
||||
const cairo_region_t *
|
||||
clutter_damage_history_lookup (ClutterDamageHistory *history,
|
||||
int age)
|
||||
{
|
||||
return history->damages[step_damage_index (history->index, -age)];
|
||||
}
|
42
clutter/clutter/clutter-damage-history.h
Normal file
42
clutter/clutter/clutter-damage-history.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2007,2008,2009,2010,2011 Intel Corporation.
|
||||
* Copyright (C) 2020 Red Hat Inc
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CLUTTER_DAMAGE_HISTORY_H
|
||||
#define CLUTTER_DAMAGE_HISTORY_H
|
||||
|
||||
#include <cairo.h>
|
||||
#include <glib.h>
|
||||
|
||||
typedef struct _ClutterDamageHistory ClutterDamageHistory;
|
||||
|
||||
ClutterDamageHistory * clutter_damage_history_new (void);
|
||||
|
||||
void clutter_damage_history_free (ClutterDamageHistory *history);
|
||||
|
||||
gboolean clutter_damage_history_is_age_valid (ClutterDamageHistory *history,
|
||||
int age);
|
||||
|
||||
void clutter_damage_history_record (ClutterDamageHistory *history,
|
||||
const cairo_region_t *damage);
|
||||
|
||||
void clutter_damage_history_step (ClutterDamageHistory *history);
|
||||
|
||||
const cairo_region_t * clutter_damage_history_lookup (ClutterDamageHistory *history,
|
||||
int age);
|
||||
|
||||
#endif /* CLUTTER_DAMAGE_HISTORY_H */
|
@@ -128,10 +128,9 @@ clutter_deform_effect_deform_vertex (ClutterDeformEffect *effect,
|
||||
}
|
||||
|
||||
static void
|
||||
vbo_invalidate (ClutterActor *actor,
|
||||
const ClutterActorBox *allocation,
|
||||
ClutterAllocationFlags flags,
|
||||
ClutterDeformEffect *effect)
|
||||
vbo_invalidate (ClutterActor *actor,
|
||||
GParamSpec *pspec,
|
||||
ClutterDeformEffect *effect)
|
||||
{
|
||||
effect->priv->is_dirty = TRUE;
|
||||
}
|
||||
@@ -156,7 +155,7 @@ clutter_deform_effect_set_actor (ClutterActorMeta *meta,
|
||||
* changes
|
||||
*/
|
||||
if (actor != NULL)
|
||||
priv->allocation_id = g_signal_connect (actor, "allocation-changed",
|
||||
priv->allocation_id = g_signal_connect (actor, "notify::allocation",
|
||||
G_CALLBACK (vbo_invalidate),
|
||||
meta);
|
||||
|
||||
|
@@ -554,32 +554,6 @@ typedef enum /*< prefix=CLUTTER_OFFSCREEN_REDIRECT >*/
|
||||
CLUTTER_OFFSCREEN_REDIRECT_ON_IDLE = 1 << 2
|
||||
} ClutterOffscreenRedirect;
|
||||
|
||||
/**
|
||||
* ClutterAllocationFlags:
|
||||
* @CLUTTER_ALLOCATION_NONE: No flag set
|
||||
* @CLUTTER_ABSOLUTE_ORIGIN_CHANGED: Whether the absolute origin of the
|
||||
* actor has changed; this implies that any ancestor of the actor has
|
||||
* been moved.
|
||||
* @CLUTTER_DELEGATE_LAYOUT: Whether the allocation should be delegated
|
||||
* to the #ClutterLayoutManager instance stored inside the
|
||||
* #ClutterActor:layout-manager property of #ClutterActor. This flag
|
||||
* should only be used if you are subclassing #ClutterActor and
|
||||
* overriding the #ClutterActorClass.allocate() virtual function, but
|
||||
* you wish to use the default implementation of the virtual function
|
||||
* inside #ClutterActor. Added in Clutter 1.10.
|
||||
*
|
||||
* Flags passed to the #ClutterActorClass.allocate() virtual function
|
||||
* and to the clutter_actor_allocate() function.
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
CLUTTER_ALLOCATION_NONE = 0,
|
||||
CLUTTER_ABSOLUTE_ORIGIN_CHANGED = 1 << 1,
|
||||
CLUTTER_DELEGATE_LAYOUT = 1 << 2
|
||||
} ClutterAllocationFlags;
|
||||
|
||||
/**
|
||||
* ClutterAlignAxis:
|
||||
* @CLUTTER_ALIGN_X_AXIS: Maintain the alignment on the X axis
|
||||
|
@@ -131,8 +131,7 @@ clutter_fixed_layout_get_preferred_height (ClutterLayoutManager *manager,
|
||||
static void
|
||||
clutter_fixed_layout_allocate (ClutterLayoutManager *manager,
|
||||
ClutterContainer *container,
|
||||
const ClutterActorBox *allocation,
|
||||
ClutterAllocationFlags flags)
|
||||
const ClutterActorBox *allocation)
|
||||
{
|
||||
ClutterActor *child;
|
||||
|
||||
@@ -140,7 +139,7 @@ clutter_fixed_layout_allocate (ClutterLayoutManager *manager,
|
||||
child != NULL;
|
||||
child = clutter_actor_get_next_sibling (child))
|
||||
{
|
||||
clutter_actor_allocate_preferred_size (child, flags);
|
||||
clutter_actor_allocate_preferred_size (child);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -566,8 +566,7 @@ clutter_flow_layout_get_preferred_height (ClutterLayoutManager *manager,
|
||||
static void
|
||||
clutter_flow_layout_allocate (ClutterLayoutManager *manager,
|
||||
ClutterContainer *container,
|
||||
const ClutterActorBox *allocation,
|
||||
ClutterAllocationFlags flags)
|
||||
const ClutterActorBox *allocation)
|
||||
{
|
||||
ClutterFlowLayoutPrivate *priv = CLUTTER_FLOW_LAYOUT (manager)->priv;
|
||||
ClutterActor *actor, *child;
|
||||
@@ -729,7 +728,7 @@ clutter_flow_layout_allocate (ClutterLayoutManager *manager,
|
||||
child_alloc.y1 = ceil (item_y);
|
||||
child_alloc.x2 = ceil (child_alloc.x1 + item_width);
|
||||
child_alloc.y2 = ceil (child_alloc.y1 + item_height);
|
||||
clutter_actor_allocate (child, &child_alloc, flags);
|
||||
clutter_actor_allocate (child, &child_alloc);
|
||||
|
||||
if (priv->orientation == CLUTTER_FLOW_HORIZONTAL)
|
||||
item_x = new_x;
|
||||
|
@@ -157,7 +157,8 @@ G_DEFINE_TYPE_WITH_PRIVATE (ClutterGestureAction, clutter_gesture_action, CLUTTE
|
||||
static GesturePoint *
|
||||
gesture_register_point (ClutterGestureAction *action, ClutterEvent *event)
|
||||
{
|
||||
ClutterGestureActionPrivate *priv = action->priv;
|
||||
ClutterGestureActionPrivate *priv =
|
||||
clutter_gesture_action_get_instance_private (action);
|
||||
GesturePoint *point = NULL;
|
||||
|
||||
if (priv->points->len >= MAX_GESTURE_POINTS)
|
||||
@@ -190,7 +191,8 @@ gesture_find_point (ClutterGestureAction *action,
|
||||
ClutterEvent *event,
|
||||
gint *position)
|
||||
{
|
||||
ClutterGestureActionPrivate *priv = action->priv;
|
||||
ClutterGestureActionPrivate *priv =
|
||||
clutter_gesture_action_get_instance_private (action);
|
||||
GesturePoint *point = NULL;
|
||||
ClutterEventType type = clutter_event_type (event);
|
||||
ClutterInputDevice *device = clutter_event_get_device (event);
|
||||
@@ -220,9 +222,10 @@ gesture_find_point (ClutterGestureAction *action,
|
||||
static void
|
||||
gesture_unregister_point (ClutterGestureAction *action, gint position)
|
||||
{
|
||||
ClutterGestureActionPrivate *priv = action->priv;
|
||||
ClutterGestureActionPrivate *priv =
|
||||
clutter_gesture_action_get_instance_private (action);
|
||||
|
||||
if (action->priv->points->len == 0)
|
||||
if (priv->points->len == 0)
|
||||
return;
|
||||
|
||||
g_array_remove_index (priv->points, position);
|
||||
@@ -303,7 +306,8 @@ gesture_point_unset (GesturePoint *point)
|
||||
static void
|
||||
cancel_gesture (ClutterGestureAction *action)
|
||||
{
|
||||
ClutterGestureActionPrivate *priv = action->priv;
|
||||
ClutterGestureActionPrivate *priv =
|
||||
clutter_gesture_action_get_instance_private (action);
|
||||
ClutterActor *actor;
|
||||
|
||||
priv->in_gesture = FALSE;
|
||||
@@ -313,14 +317,15 @@ cancel_gesture (ClutterGestureAction *action)
|
||||
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
|
||||
g_signal_emit (action, gesture_signals[GESTURE_CANCEL], 0, actor);
|
||||
|
||||
g_array_set_size (action->priv->points, 0);
|
||||
g_array_set_size (priv->points, 0);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
begin_gesture (ClutterGestureAction *action,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
ClutterGestureActionPrivate *priv = action->priv;
|
||||
ClutterGestureActionPrivate *priv =
|
||||
clutter_gesture_action_get_instance_private (action);
|
||||
gboolean return_value;
|
||||
|
||||
priv->in_gesture = TRUE;
|
||||
@@ -353,7 +358,8 @@ stage_captured_event_cb (ClutterActor *stage,
|
||||
ClutterEvent *event,
|
||||
ClutterGestureAction *action)
|
||||
{
|
||||
ClutterGestureActionPrivate *priv = action->priv;
|
||||
ClutterGestureActionPrivate *priv =
|
||||
clutter_gesture_action_get_instance_private (action);
|
||||
ClutterActor *actor;
|
||||
gint position;
|
||||
float threshold_x, threshold_y;
|
||||
@@ -488,7 +494,8 @@ actor_captured_event_cb (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
ClutterGestureAction *action)
|
||||
{
|
||||
ClutterGestureActionPrivate *priv = action->priv;
|
||||
ClutterGestureActionPrivate *priv =
|
||||
clutter_gesture_action_get_instance_private (action);
|
||||
GesturePoint *point G_GNUC_UNUSED;
|
||||
|
||||
if ((clutter_event_type (event) != CLUTTER_BUTTON_PRESS) &&
|
||||
@@ -522,7 +529,8 @@ static void
|
||||
clutter_gesture_action_set_actor (ClutterActorMeta *meta,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
ClutterGestureActionPrivate *priv = CLUTTER_GESTURE_ACTION (meta)->priv;
|
||||
ClutterGestureActionPrivate *priv =
|
||||
clutter_gesture_action_get_instance_private (CLUTTER_GESTURE_ACTION (meta));
|
||||
ClutterActorMetaClass *meta_class =
|
||||
CLUTTER_ACTOR_META_CLASS (clutter_gesture_action_parent_class);
|
||||
|
||||
@@ -563,7 +571,8 @@ clutter_gesture_action_set_enabled (ClutterActorMeta *meta,
|
||||
ClutterActorMetaClass *meta_class =
|
||||
CLUTTER_ACTOR_META_CLASS (clutter_gesture_action_parent_class);
|
||||
ClutterGestureAction *gesture_action = CLUTTER_GESTURE_ACTION (meta);
|
||||
ClutterGestureActionPrivate *priv = gesture_action->priv;
|
||||
ClutterGestureActionPrivate *priv =
|
||||
clutter_gesture_action_get_instance_private (gesture_action);
|
||||
|
||||
if (!is_enabled && priv->in_gesture)
|
||||
cancel_gesture (gesture_action);
|
||||
@@ -585,6 +594,8 @@ clutter_gesture_action_set_property (GObject *gobject,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterGestureAction *self = CLUTTER_GESTURE_ACTION (gobject);
|
||||
ClutterGestureActionPrivate *priv =
|
||||
clutter_gesture_action_get_instance_private (self);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
@@ -597,11 +608,15 @@ clutter_gesture_action_set_property (GObject *gobject,
|
||||
break;
|
||||
|
||||
case PROP_THRESHOLD_TRIGGER_DISTANCE_X:
|
||||
clutter_gesture_action_set_threshold_trigger_distance (self, g_value_get_float (value), self->priv->distance_y);
|
||||
clutter_gesture_action_set_threshold_trigger_distance (self,
|
||||
g_value_get_float (value),
|
||||
priv->distance_y);
|
||||
break;
|
||||
|
||||
case PROP_THRESHOLD_TRIGGER_DISTANCE_Y:
|
||||
clutter_gesture_action_set_threshold_trigger_distance (self, self->priv->distance_x, g_value_get_float (value));
|
||||
clutter_gesture_action_set_threshold_trigger_distance (self,
|
||||
priv->distance_x,
|
||||
g_value_get_float (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -616,28 +631,29 @@ clutter_gesture_action_get_property (GObject *gobject,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterGestureAction *self = CLUTTER_GESTURE_ACTION (gobject);
|
||||
ClutterGestureActionPrivate *priv =
|
||||
clutter_gesture_action_get_instance_private (CLUTTER_GESTURE_ACTION (gobject));
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_N_TOUCH_POINTS:
|
||||
g_value_set_int (value, self->priv->requested_nb_points);
|
||||
g_value_set_int (value, priv->requested_nb_points);
|
||||
break;
|
||||
|
||||
case PROP_THRESHOLD_TRIGGER_EDGE:
|
||||
g_value_set_enum (value, self->priv->edge);
|
||||
g_value_set_enum (value, priv->edge);
|
||||
break;
|
||||
|
||||
case PROP_THRESHOLD_TRIGGER_DISTANCE_X:
|
||||
if (self->priv->distance_x > 0.0)
|
||||
g_value_set_float (value, self->priv->distance_x);
|
||||
if (priv->distance_x > 0.0)
|
||||
g_value_set_float (value, priv->distance_x);
|
||||
else
|
||||
g_value_set_float (value, gesture_get_default_threshold ());
|
||||
break;
|
||||
|
||||
case PROP_THRESHOLD_TRIGGER_DISTANCE_Y:
|
||||
if (self->priv->distance_y > 0.0)
|
||||
g_value_set_float (value, self->priv->distance_y);
|
||||
if (priv->distance_y > 0.0)
|
||||
g_value_set_float (value, priv->distance_y);
|
||||
else
|
||||
g_value_set_float (value, gesture_get_default_threshold ());
|
||||
break;
|
||||
@@ -651,7 +667,8 @@ clutter_gesture_action_get_property (GObject *gobject,
|
||||
static void
|
||||
clutter_gesture_action_finalize (GObject *gobject)
|
||||
{
|
||||
ClutterGestureActionPrivate *priv = CLUTTER_GESTURE_ACTION (gobject)->priv;
|
||||
ClutterGestureActionPrivate *priv =
|
||||
clutter_gesture_action_get_instance_private (CLUTTER_GESTURE_ACTION (gobject));
|
||||
|
||||
g_array_unref (priv->points);
|
||||
|
||||
@@ -843,13 +860,14 @@ clutter_gesture_action_class_init (ClutterGestureActionClass *klass)
|
||||
static void
|
||||
clutter_gesture_action_init (ClutterGestureAction *self)
|
||||
{
|
||||
self->priv = clutter_gesture_action_get_instance_private (self);
|
||||
ClutterGestureActionPrivate *priv =
|
||||
clutter_gesture_action_get_instance_private (self);
|
||||
|
||||
self->priv->points = g_array_sized_new (FALSE, TRUE, sizeof (GesturePoint), 3);
|
||||
g_array_set_clear_func (self->priv->points, (GDestroyNotify) gesture_point_unset);
|
||||
priv->points = g_array_sized_new (FALSE, TRUE, sizeof (GesturePoint), 3);
|
||||
g_array_set_clear_func (priv->points, (GDestroyNotify) gesture_point_unset);
|
||||
|
||||
self->priv->requested_nb_points = 1;
|
||||
self->priv->edge = CLUTTER_GESTURE_TRIGGER_EDGE_NONE;
|
||||
priv->requested_nb_points = 1;
|
||||
priv->edge = CLUTTER_GESTURE_TRIGGER_EDGE_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -888,16 +906,21 @@ clutter_gesture_action_get_press_coords (ClutterGestureAction *action,
|
||||
gfloat *press_x,
|
||||
gfloat *press_y)
|
||||
{
|
||||
ClutterGestureActionPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action));
|
||||
g_return_if_fail (action->priv->points->len > point);
|
||||
|
||||
priv = clutter_gesture_action_get_instance_private (action);
|
||||
|
||||
g_return_if_fail (priv->points->len > point);
|
||||
|
||||
if (press_x)
|
||||
*press_x = g_array_index (action->priv->points,
|
||||
*press_x = g_array_index (priv->points,
|
||||
GesturePoint,
|
||||
point).press_x;
|
||||
|
||||
if (press_y)
|
||||
*press_y = g_array_index (action->priv->points,
|
||||
*press_y = g_array_index (priv->points,
|
||||
GesturePoint,
|
||||
point).press_y;
|
||||
}
|
||||
@@ -923,16 +946,21 @@ clutter_gesture_action_get_motion_coords (ClutterGestureAction *action,
|
||||
gfloat *motion_x,
|
||||
gfloat *motion_y)
|
||||
{
|
||||
ClutterGestureActionPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action));
|
||||
g_return_if_fail (action->priv->points->len > point);
|
||||
|
||||
priv = clutter_gesture_action_get_instance_private (action);
|
||||
|
||||
g_return_if_fail (priv->points->len > point);
|
||||
|
||||
if (motion_x)
|
||||
*motion_x = g_array_index (action->priv->points,
|
||||
*motion_x = g_array_index (priv->points,
|
||||
GesturePoint,
|
||||
point).last_motion_x;
|
||||
|
||||
if (motion_y)
|
||||
*motion_y = g_array_index (action->priv->points,
|
||||
*motion_y = g_array_index (priv->points,
|
||||
GesturePoint,
|
||||
point).last_motion_y;
|
||||
}
|
||||
@@ -960,15 +988,19 @@ clutter_gesture_action_get_motion_delta (ClutterGestureAction *action,
|
||||
gfloat *delta_x,
|
||||
gfloat *delta_y)
|
||||
{
|
||||
ClutterGestureActionPrivate *priv;
|
||||
gfloat d_x, d_y;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), 0);
|
||||
g_return_val_if_fail (action->priv->points->len > point, 0);
|
||||
|
||||
d_x = g_array_index (action->priv->points,
|
||||
priv = clutter_gesture_action_get_instance_private (action);
|
||||
|
||||
g_return_val_if_fail (priv->points->len > point, 0);
|
||||
|
||||
d_x = g_array_index (priv->points,
|
||||
GesturePoint,
|
||||
point).last_delta_x;
|
||||
d_y = g_array_index (action->priv->points,
|
||||
d_y = g_array_index (priv->points,
|
||||
GesturePoint,
|
||||
point).last_delta_y;
|
||||
|
||||
@@ -1002,16 +1034,21 @@ clutter_gesture_action_get_release_coords (ClutterGestureAction *action,
|
||||
gfloat *release_x,
|
||||
gfloat *release_y)
|
||||
{
|
||||
ClutterGestureActionPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action));
|
||||
g_return_if_fail (action->priv->points->len > point);
|
||||
|
||||
priv = clutter_gesture_action_get_instance_private (action);
|
||||
|
||||
g_return_if_fail (priv->points->len > point);
|
||||
|
||||
if (release_x)
|
||||
*release_x = g_array_index (action->priv->points,
|
||||
*release_x = g_array_index (priv->points,
|
||||
GesturePoint,
|
||||
point).release_x;
|
||||
|
||||
if (release_y)
|
||||
*release_y = g_array_index (action->priv->points,
|
||||
*release_y = g_array_index (priv->points,
|
||||
GesturePoint,
|
||||
point).release_y;
|
||||
}
|
||||
@@ -1037,16 +1074,20 @@ clutter_gesture_action_get_velocity (ClutterGestureAction *action,
|
||||
gfloat *velocity_x,
|
||||
gfloat *velocity_y)
|
||||
{
|
||||
ClutterGestureActionPrivate *priv;
|
||||
gfloat d_x, d_y, distance, velocity;
|
||||
gint64 d_t;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), 0);
|
||||
g_return_val_if_fail (action->priv->points->len > point, 0);
|
||||
|
||||
priv = clutter_gesture_action_get_instance_private (action);
|
||||
|
||||
g_return_val_if_fail (priv->points->len > point, 0);
|
||||
|
||||
distance = clutter_gesture_action_get_motion_delta (action, point,
|
||||
&d_x, &d_y);
|
||||
|
||||
d_t = g_array_index (action->priv->points,
|
||||
d_t = g_array_index (priv->points,
|
||||
GesturePoint,
|
||||
point).last_delta_time;
|
||||
|
||||
@@ -1073,9 +1114,13 @@ clutter_gesture_action_get_velocity (ClutterGestureAction *action,
|
||||
gint
|
||||
clutter_gesture_action_get_n_touch_points (ClutterGestureAction *action)
|
||||
{
|
||||
ClutterGestureActionPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), 0);
|
||||
|
||||
return action->priv->requested_nb_points;
|
||||
priv = clutter_gesture_action_get_instance_private (action);
|
||||
|
||||
return priv->requested_nb_points;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1096,7 +1141,7 @@ clutter_gesture_action_set_n_touch_points (ClutterGestureAction *action,
|
||||
g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action));
|
||||
g_return_if_fail (nb_points >= 1);
|
||||
|
||||
priv = action->priv;
|
||||
priv = clutter_gesture_action_get_instance_private (action);
|
||||
|
||||
if (priv->requested_nb_points == nb_points)
|
||||
return;
|
||||
@@ -1150,9 +1195,13 @@ clutter_gesture_action_set_n_touch_points (ClutterGestureAction *action,
|
||||
guint
|
||||
clutter_gesture_action_get_n_current_points (ClutterGestureAction *action)
|
||||
{
|
||||
ClutterGestureActionPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), 0);
|
||||
|
||||
return action->priv->points->len;
|
||||
priv = clutter_gesture_action_get_instance_private (action);
|
||||
|
||||
return priv->points->len;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1170,10 +1219,15 @@ ClutterEventSequence *
|
||||
clutter_gesture_action_get_sequence (ClutterGestureAction *action,
|
||||
guint point)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), NULL);
|
||||
g_return_val_if_fail (action->priv->points->len > point, NULL);
|
||||
ClutterGestureActionPrivate *priv;
|
||||
|
||||
return g_array_index (action->priv->points, GesturePoint, point).sequence;
|
||||
g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), NULL);
|
||||
|
||||
priv = clutter_gesture_action_get_instance_private (action);
|
||||
|
||||
g_return_val_if_fail (priv->points->len > point, NULL);
|
||||
|
||||
return g_array_index (priv->points, GesturePoint, point).sequence;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1192,10 +1246,15 @@ ClutterInputDevice *
|
||||
clutter_gesture_action_get_device (ClutterGestureAction *action,
|
||||
guint point)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), NULL);
|
||||
g_return_val_if_fail (action->priv->points->len > point, NULL);
|
||||
ClutterGestureActionPrivate *priv;
|
||||
|
||||
return g_array_index (action->priv->points, GesturePoint, point).device;
|
||||
g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), NULL);
|
||||
|
||||
priv = clutter_gesture_action_get_instance_private (action);
|
||||
|
||||
g_return_val_if_fail (priv->points->len > point, NULL);
|
||||
|
||||
return g_array_index (priv->points, GesturePoint, point).device;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1215,11 +1274,15 @@ clutter_gesture_action_get_last_event (ClutterGestureAction *action,
|
||||
guint point)
|
||||
{
|
||||
GesturePoint *gesture_point;
|
||||
ClutterGestureActionPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), NULL);
|
||||
g_return_val_if_fail (action->priv->points->len > point, NULL);
|
||||
|
||||
gesture_point = &g_array_index (action->priv->points, GesturePoint, point);
|
||||
priv = clutter_gesture_action_get_instance_private (action);
|
||||
|
||||
g_return_val_if_fail (priv->points->len > point, NULL);
|
||||
|
||||
gesture_point = &g_array_index (priv->points, GesturePoint, point);
|
||||
|
||||
return gesture_point->last_event;
|
||||
}
|
||||
@@ -1256,12 +1319,16 @@ void
|
||||
clutter_gesture_action_set_threshold_trigger_edge (ClutterGestureAction *action,
|
||||
ClutterGestureTriggerEdge edge)
|
||||
{
|
||||
ClutterGestureActionPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action));
|
||||
|
||||
if (action->priv->edge == edge)
|
||||
priv = clutter_gesture_action_get_instance_private (action);
|
||||
|
||||
if (priv->edge == edge)
|
||||
return;
|
||||
|
||||
action->priv->edge = edge;
|
||||
priv->edge = edge;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (action), gesture_props[PROP_THRESHOLD_TRIGGER_EDGE]);
|
||||
}
|
||||
@@ -1280,10 +1347,14 @@ clutter_gesture_action_set_threshold_trigger_edge (ClutterGestureAction *ac
|
||||
ClutterGestureTriggerEdge
|
||||
clutter_gesture_action_get_threshold_trigger_edge (ClutterGestureAction *action)
|
||||
{
|
||||
ClutterGestureActionPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action),
|
||||
CLUTTER_GESTURE_TRIGGER_EDGE_NONE);
|
||||
|
||||
return action->priv->edge;
|
||||
priv = clutter_gesture_action_get_instance_private (action);
|
||||
|
||||
return priv->edge;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1323,17 +1394,21 @@ clutter_gesture_action_set_threshold_trigger_distance (ClutterGestureAction
|
||||
float x,
|
||||
float y)
|
||||
{
|
||||
ClutterGestureActionPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action));
|
||||
|
||||
if (fabsf (x - action->priv->distance_x) > FLOAT_EPSILON)
|
||||
priv = clutter_gesture_action_get_instance_private (action);
|
||||
|
||||
if (fabsf (x - priv->distance_x) > FLOAT_EPSILON)
|
||||
{
|
||||
action->priv->distance_x = x;
|
||||
priv->distance_x = x;
|
||||
g_object_notify_by_pspec (G_OBJECT (action), gesture_props[PROP_THRESHOLD_TRIGGER_DISTANCE_X]);
|
||||
}
|
||||
|
||||
if (fabsf (y - action->priv->distance_y) > FLOAT_EPSILON)
|
||||
if (fabsf (y - priv->distance_y) > FLOAT_EPSILON)
|
||||
{
|
||||
action->priv->distance_y = y;
|
||||
priv->distance_y = y;
|
||||
g_object_notify_by_pspec (G_OBJECT (action), gesture_props[PROP_THRESHOLD_TRIGGER_DISTANCE_Y]);
|
||||
}
|
||||
}
|
||||
@@ -1354,19 +1429,23 @@ clutter_gesture_action_get_threshold_trigger_distance (ClutterGestureAction *act
|
||||
float *x,
|
||||
float *y)
|
||||
{
|
||||
ClutterGestureActionPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action));
|
||||
|
||||
priv = clutter_gesture_action_get_instance_private (action);
|
||||
|
||||
if (x != NULL)
|
||||
{
|
||||
if (action->priv->distance_x > 0.0)
|
||||
*x = action->priv->distance_x;
|
||||
if (priv->distance_x > 0.0)
|
||||
*x = priv->distance_x;
|
||||
else
|
||||
*x = gesture_get_default_threshold ();
|
||||
}
|
||||
if (y != NULL)
|
||||
{
|
||||
if (action->priv->distance_y > 0.0)
|
||||
*y = action->priv->distance_y;
|
||||
if (priv->distance_y > 0.0)
|
||||
*y = priv->distance_y;
|
||||
else
|
||||
*y = gesture_get_default_threshold ();
|
||||
}
|
||||
|
@@ -34,32 +34,13 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_GESTURE_ACTION (clutter_gesture_action_get_type ())
|
||||
#define CLUTTER_GESTURE_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_GESTURE_ACTION, ClutterGestureAction))
|
||||
#define CLUTTER_IS_GESTURE_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_GESTURE_ACTION))
|
||||
#define CLUTTER_GESTURE_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_GESTURE_ACTION, ClutterGestureActionClass))
|
||||
#define CLUTTER_IS_GESTURE_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_GESTURE_ACTION))
|
||||
#define CLUTTER_GESTURE_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_GESTURE_ACTION, ClutterGestureActionClass))
|
||||
#define CLUTTER_TYPE_GESTURE_ACTION (clutter_gesture_action_get_type ())
|
||||
|
||||
typedef struct _ClutterGestureAction ClutterGestureAction;
|
||||
typedef struct _ClutterGestureActionPrivate ClutterGestureActionPrivate;
|
||||
typedef struct _ClutterGestureActionClass ClutterGestureActionClass;
|
||||
CLUTTER_EXPORT
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterGestureAction, clutter_gesture_action,
|
||||
CLUTTER, GESTURE_ACTION, ClutterAction);
|
||||
|
||||
/**
|
||||
* ClutterGestureAction:
|
||||
*
|
||||
* The #ClutterGestureAction structure contains
|
||||
* only private data and should be accessed using the provided API
|
||||
*
|
||||
* Since: 1.8
|
||||
*/
|
||||
struct _ClutterGestureAction
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterAction parent_instance;
|
||||
|
||||
ClutterGestureActionPrivate *priv;
|
||||
};
|
||||
typedef struct _ClutterGestureActionPrivate ClutterGestureActionPrivate;
|
||||
|
||||
/**
|
||||
* ClutterGestureActionClass:
|
||||
@@ -101,9 +82,6 @@ struct _ClutterGestureActionClass
|
||||
void (* _clutter_gesture_action6) (void);
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType clutter_gesture_action_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterAction * clutter_gesture_action_new (void);
|
||||
|
||||
|
@@ -1391,8 +1391,7 @@ allocate_child (ClutterGridRequest *request,
|
||||
static void
|
||||
clutter_grid_layout_allocate (ClutterLayoutManager *layout,
|
||||
ClutterContainer *container,
|
||||
const ClutterActorBox *allocation,
|
||||
ClutterAllocationFlags flags)
|
||||
const ClutterActorBox *allocation)
|
||||
{
|
||||
ClutterGridLayout *self = CLUTTER_GRID_LAYOUT (layout);
|
||||
ClutterOrientation orientation;
|
||||
@@ -1453,7 +1452,7 @@ clutter_grid_layout_allocate (ClutterLayoutManager *layout,
|
||||
child_allocation.x2 = child_allocation.x1 + width;
|
||||
child_allocation.y2 = child_allocation.y1 + height;
|
||||
|
||||
clutter_actor_allocate (child, &child_allocation, flags);
|
||||
clutter_actor_allocate (child, &child_allocation);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -253,8 +253,7 @@ layout_manager_real_get_preferred_height (ClutterLayoutManager *manager,
|
||||
static void
|
||||
layout_manager_real_allocate (ClutterLayoutManager *manager,
|
||||
ClutterContainer *container,
|
||||
const ClutterActorBox *allocation,
|
||||
ClutterAllocationFlags flags)
|
||||
const ClutterActorBox *allocation)
|
||||
{
|
||||
LAYOUT_MANAGER_WARN_NOT_IMPLEMENTED (manager, "allocate");
|
||||
}
|
||||
@@ -434,7 +433,6 @@ clutter_layout_manager_get_preferred_height (ClutterLayoutManager *manager,
|
||||
* @container: the #ClutterContainer using @manager
|
||||
* @allocation: the #ClutterActorBox containing the allocated area
|
||||
* of @container
|
||||
* @flags: the allocation flags
|
||||
*
|
||||
* Allocates the children of @container given an area
|
||||
*
|
||||
@@ -445,8 +443,7 @@ clutter_layout_manager_get_preferred_height (ClutterLayoutManager *manager,
|
||||
void
|
||||
clutter_layout_manager_allocate (ClutterLayoutManager *manager,
|
||||
ClutterContainer *container,
|
||||
const ClutterActorBox *allocation,
|
||||
ClutterAllocationFlags flags)
|
||||
const ClutterActorBox *allocation)
|
||||
{
|
||||
ClutterLayoutManagerClass *klass;
|
||||
|
||||
@@ -455,7 +452,7 @@ clutter_layout_manager_allocate (ClutterLayoutManager *manager,
|
||||
g_return_if_fail (allocation != NULL);
|
||||
|
||||
klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager);
|
||||
klass->allocate (manager, container, allocation, flags);
|
||||
klass->allocate (manager, container, allocation);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -115,8 +115,7 @@ struct _ClutterLayoutManagerClass
|
||||
gfloat *nat_height_p);
|
||||
void (* allocate) (ClutterLayoutManager *manager,
|
||||
ClutterContainer *container,
|
||||
const ClutterActorBox *allocation,
|
||||
ClutterAllocationFlags flags);
|
||||
const ClutterActorBox *allocation);
|
||||
|
||||
void (* set_container) (ClutterLayoutManager *manager,
|
||||
ClutterContainer *container);
|
||||
@@ -158,8 +157,7 @@ void clutter_layout_manager_get_preferred_height (ClutterLayoutMa
|
||||
CLUTTER_EXPORT
|
||||
void clutter_layout_manager_allocate (ClutterLayoutManager *manager,
|
||||
ClutterContainer *container,
|
||||
const ClutterActorBox *allocation,
|
||||
ClutterAllocationFlags flags);
|
||||
const ClutterActorBox *allocation);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_layout_manager_set_container (ClutterLayoutManager *manager,
|
||||
|
@@ -199,7 +199,7 @@ master_clock_schedule_stage_updates (ClutterMasterClockDefault *master_clock)
|
||||
stages = clutter_stage_manager_peek_stages (stage_manager);
|
||||
|
||||
for (l = stages; l != NULL; l = l->next)
|
||||
_clutter_stage_schedule_update (l->data);
|
||||
clutter_stage_schedule_update (l->data);
|
||||
}
|
||||
|
||||
static GSList *
|
||||
@@ -252,7 +252,7 @@ master_clock_reschedule_stage_updates (ClutterMasterClockDefault *master_clock,
|
||||
if (master_clock->timelines ||
|
||||
_clutter_stage_has_queued_events (l->data) ||
|
||||
_clutter_stage_needs_update (l->data))
|
||||
_clutter_stage_schedule_update (l->data);
|
||||
clutter_stage_schedule_update (l->data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -74,7 +74,6 @@ void _clutter_stage_queue_event (ClutterStage *stage,
|
||||
gboolean _clutter_stage_has_queued_events (ClutterStage *stage);
|
||||
void _clutter_stage_process_queued_events (ClutterStage *stage);
|
||||
void _clutter_stage_update_input_devices (ClutterStage *stage);
|
||||
void _clutter_stage_schedule_update (ClutterStage *stage);
|
||||
gint64 _clutter_stage_get_update_time (ClutterStage *stage);
|
||||
void _clutter_stage_clear_update_time (ClutterStage *stage);
|
||||
gboolean _clutter_stage_has_full_redraw_queued (ClutterStage *stage);
|
||||
|
@@ -20,17 +20,28 @@
|
||||
|
||||
#include "clutter/clutter-stage-view.h"
|
||||
|
||||
void clutter_stage_view_after_paint (ClutterStageView *view);
|
||||
void clutter_stage_view_after_paint (ClutterStageView *view,
|
||||
cairo_region_t *redraw_clip);
|
||||
|
||||
void clutter_stage_view_before_swap_buffer (ClutterStageView *view,
|
||||
const cairo_region_t *swap_region);
|
||||
|
||||
gboolean clutter_stage_view_is_dirty_viewport (ClutterStageView *view);
|
||||
|
||||
void clutter_stage_view_set_dirty_viewport (ClutterStageView *view,
|
||||
gboolean dirty);
|
||||
void clutter_stage_view_invalidate_viewport (ClutterStageView *view);
|
||||
|
||||
void clutter_stage_view_set_viewport (ClutterStageView *view,
|
||||
float x,
|
||||
float y,
|
||||
float width,
|
||||
float height);
|
||||
|
||||
gboolean clutter_stage_view_is_dirty_projection (ClutterStageView *view);
|
||||
|
||||
void clutter_stage_view_set_dirty_projection (ClutterStageView *view,
|
||||
gboolean dirty);
|
||||
void clutter_stage_view_invalidate_projection (ClutterStageView *view);
|
||||
|
||||
void clutter_stage_view_set_projection (ClutterStageView *view,
|
||||
const CoglMatrix *matrix);
|
||||
|
||||
void clutter_stage_view_add_redraw_clip (ClutterStageView *view,
|
||||
const cairo_rectangle_int_t *clip);
|
||||
@@ -45,4 +56,10 @@ cairo_region_t * clutter_stage_view_take_redraw_clip (ClutterStageView *view);
|
||||
|
||||
CoglScanout * clutter_stage_view_take_scanout (ClutterStageView *view);
|
||||
|
||||
void clutter_stage_view_transform_rect_to_onscreen (ClutterStageView *view,
|
||||
const cairo_rectangle_int_t *src_rect,
|
||||
int dst_width,
|
||||
int dst_height,
|
||||
cairo_rectangle_int_t *dst_rect);
|
||||
|
||||
#endif /* __CLUTTER_STAGE_VIEW_PRIVATE_H__ */
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#include <cairo-gobject.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "clutter/clutter-damage-history.h"
|
||||
#include "clutter/clutter-private.h"
|
||||
#include "clutter/clutter-mutter.h"
|
||||
#include "cogl/cogl.h"
|
||||
@@ -31,10 +32,11 @@ enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_NAME,
|
||||
PROP_LAYOUT,
|
||||
PROP_FRAMEBUFFER,
|
||||
PROP_OFFSCREEN,
|
||||
PROP_SHADOWFB,
|
||||
PROP_USE_SHADOWFB,
|
||||
PROP_SCALE,
|
||||
|
||||
PROP_LAST
|
||||
@@ -44,6 +46,8 @@ static GParamSpec *obj_props[PROP_LAST];
|
||||
|
||||
typedef struct _ClutterStageViewPrivate
|
||||
{
|
||||
char *name;
|
||||
|
||||
cairo_rectangle_int_t layout;
|
||||
float scale;
|
||||
CoglFramebuffer *framebuffer;
|
||||
@@ -51,8 +55,16 @@ typedef struct _ClutterStageViewPrivate
|
||||
CoglOffscreen *offscreen;
|
||||
CoglPipeline *offscreen_pipeline;
|
||||
|
||||
CoglOffscreen *shadowfb;
|
||||
CoglPipeline *shadowfb_pipeline;
|
||||
gboolean use_shadowfb;
|
||||
struct {
|
||||
struct {
|
||||
CoglDmaBufHandle *handles[2];
|
||||
int current_idx;
|
||||
ClutterDamageHistory *damage_history;
|
||||
} dma_buf;
|
||||
|
||||
CoglOffscreen *framebuffer;
|
||||
} shadow;
|
||||
|
||||
CoglScanout *next_scanout;
|
||||
|
||||
@@ -91,8 +103,8 @@ clutter_stage_view_get_framebuffer (ClutterStageView *view)
|
||||
|
||||
if (priv->offscreen)
|
||||
return priv->offscreen;
|
||||
else if (priv->shadowfb)
|
||||
return priv->shadowfb;
|
||||
else if (priv->shadow.framebuffer)
|
||||
return priv->shadow.framebuffer;
|
||||
else
|
||||
return priv->framebuffer;
|
||||
}
|
||||
@@ -152,19 +164,6 @@ clutter_stage_view_ensure_offscreen_blit_pipeline (ClutterStageView *view)
|
||||
view_class->setup_offscreen_blit_pipeline (view, priv->offscreen_pipeline);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_view_ensure_shadowfb_blit_pipeline (ClutterStageView *view)
|
||||
{
|
||||
ClutterStageViewPrivate *priv =
|
||||
clutter_stage_view_get_instance_private (view);
|
||||
|
||||
if (priv->shadowfb_pipeline)
|
||||
return;
|
||||
|
||||
priv->shadowfb_pipeline =
|
||||
clutter_stage_view_create_framebuffer_pipeline (priv->shadowfb);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_stage_view_invalidate_offscreen_blit_pipeline (ClutterStageView *view)
|
||||
{
|
||||
@@ -174,85 +173,563 @@ clutter_stage_view_invalidate_offscreen_blit_pipeline (ClutterStageView *view)
|
||||
g_clear_pointer (&priv->offscreen_pipeline, cogl_object_unref);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_stage_view_transform_rect_to_onscreen (ClutterStageView *view,
|
||||
const cairo_rectangle_int_t *src_rect,
|
||||
int dst_width,
|
||||
int dst_height,
|
||||
cairo_rectangle_int_t *dst_rect)
|
||||
{
|
||||
ClutterStageViewClass *view_class = CLUTTER_STAGE_VIEW_GET_CLASS (view);
|
||||
|
||||
return view_class->transform_rect_to_onscreen (view,
|
||||
src_rect,
|
||||
dst_width,
|
||||
dst_height,
|
||||
dst_rect);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_view_copy_to_framebuffer (ClutterStageView *view,
|
||||
CoglPipeline *pipeline,
|
||||
CoglFramebuffer *src_framebuffer,
|
||||
CoglFramebuffer *dst_framebuffer,
|
||||
gboolean can_blit)
|
||||
paint_transformed_framebuffer (ClutterStageView *view,
|
||||
CoglPipeline *pipeline,
|
||||
CoglFramebuffer *src_framebuffer,
|
||||
CoglFramebuffer *dst_framebuffer,
|
||||
const cairo_region_t *redraw_clip)
|
||||
{
|
||||
CoglMatrix matrix;
|
||||
unsigned int n_rectangles, i;
|
||||
int dst_width, dst_height;
|
||||
cairo_rectangle_int_t view_layout;
|
||||
cairo_rectangle_int_t onscreen_layout;
|
||||
float view_scale;
|
||||
float *coordinates;
|
||||
|
||||
/* First, try with blit */
|
||||
if (can_blit)
|
||||
{
|
||||
if (cogl_blit_framebuffer (src_framebuffer,
|
||||
dst_framebuffer,
|
||||
0, 0,
|
||||
0, 0,
|
||||
cogl_framebuffer_get_width (dst_framebuffer),
|
||||
cogl_framebuffer_get_height (dst_framebuffer),
|
||||
NULL))
|
||||
return;
|
||||
}
|
||||
dst_width = cogl_framebuffer_get_width (dst_framebuffer);
|
||||
dst_height = cogl_framebuffer_get_height (dst_framebuffer);
|
||||
clutter_stage_view_get_layout (view, &view_layout);
|
||||
clutter_stage_view_transform_rect_to_onscreen (view,
|
||||
&(cairo_rectangle_int_t) {
|
||||
.width = view_layout.width,
|
||||
.height = view_layout.height,
|
||||
},
|
||||
view_layout.width,
|
||||
view_layout.height,
|
||||
&onscreen_layout);
|
||||
view_scale = clutter_stage_view_get_scale (view);
|
||||
|
||||
/* If blit fails, fallback to the slower painting method */
|
||||
cogl_framebuffer_push_matrix (dst_framebuffer);
|
||||
|
||||
cogl_matrix_init_identity (&matrix);
|
||||
cogl_matrix_translate (&matrix, -1, 1, 0);
|
||||
cogl_matrix_scale (&matrix, 2, -2, 0);
|
||||
cogl_matrix_scale (&matrix,
|
||||
1.0 / (dst_width / 2.0),
|
||||
-1.0 / (dst_height / 2.0), 0);
|
||||
cogl_matrix_translate (&matrix,
|
||||
-(dst_width / 2.0),
|
||||
-(dst_height / 2.0), 0);
|
||||
cogl_framebuffer_set_projection_matrix (dst_framebuffer, &matrix);
|
||||
cogl_framebuffer_set_viewport (dst_framebuffer,
|
||||
0, 0, dst_width, dst_height);
|
||||
|
||||
cogl_framebuffer_draw_rectangle (dst_framebuffer,
|
||||
pipeline,
|
||||
0, 0, 1, 1);
|
||||
n_rectangles = cairo_region_num_rectangles (redraw_clip);
|
||||
coordinates = g_newa (float, 2 * 4 * n_rectangles);
|
||||
|
||||
for (i = 0; i < n_rectangles; i++)
|
||||
{
|
||||
cairo_rectangle_int_t src_rect;
|
||||
cairo_rectangle_int_t dst_rect;
|
||||
|
||||
cairo_region_get_rectangle (redraw_clip, i, &src_rect);
|
||||
_clutter_util_rectangle_offset (&src_rect,
|
||||
-view_layout.x,
|
||||
-view_layout.y,
|
||||
&src_rect);
|
||||
|
||||
clutter_stage_view_transform_rect_to_onscreen (view,
|
||||
&src_rect,
|
||||
onscreen_layout.width,
|
||||
onscreen_layout.height,
|
||||
&dst_rect);
|
||||
|
||||
coordinates[i * 8 + 0] = (float) dst_rect.x * view_scale;
|
||||
coordinates[i * 8 + 1] = (float) dst_rect.y * view_scale;
|
||||
coordinates[i * 8 + 2] = ((float) (dst_rect.x + dst_rect.width) *
|
||||
view_scale);
|
||||
coordinates[i * 8 + 3] = ((float) (dst_rect.y + dst_rect.height) *
|
||||
view_scale);
|
||||
|
||||
coordinates[i * 8 + 4] = (((float) dst_rect.x / (float) dst_width) *
|
||||
view_scale);
|
||||
coordinates[i * 8 + 5] = (((float) dst_rect.y / (float) dst_height) *
|
||||
view_scale);
|
||||
coordinates[i * 8 + 6] = ((float) (dst_rect.x + dst_rect.width) /
|
||||
(float) dst_width) * view_scale;
|
||||
coordinates[i * 8 + 7] = ((float) (dst_rect.y + dst_rect.height) /
|
||||
(float) dst_height) * view_scale;
|
||||
}
|
||||
|
||||
cogl_framebuffer_draw_textured_rectangles (dst_framebuffer,
|
||||
pipeline,
|
||||
coordinates,
|
||||
n_rectangles);
|
||||
|
||||
cogl_framebuffer_pop_matrix (dst_framebuffer);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_shadowfb_double_buffered (ClutterStageView *view)
|
||||
{
|
||||
ClutterStageViewPrivate *priv =
|
||||
clutter_stage_view_get_instance_private (view);
|
||||
|
||||
return priv->shadow.dma_buf.handles[0] && priv->shadow.dma_buf.handles[1];
|
||||
}
|
||||
|
||||
static gboolean
|
||||
init_dma_buf_shadowfbs (ClutterStageView *view,
|
||||
CoglContext *cogl_context,
|
||||
int width,
|
||||
int height,
|
||||
GError **error)
|
||||
{
|
||||
ClutterStageViewPrivate *priv =
|
||||
clutter_stage_view_get_instance_private (view);
|
||||
CoglRenderer *cogl_renderer = cogl_context_get_renderer (cogl_context);
|
||||
CoglFramebuffer *initial_shadowfb;
|
||||
|
||||
if (!cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE))
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
"Buffer age not supported");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!cogl_is_onscreen (priv->framebuffer))
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
"Tried to use shadow buffer without onscreen");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
priv->shadow.dma_buf.handles[0] = cogl_renderer_create_dma_buf (cogl_renderer,
|
||||
width, height,
|
||||
error);
|
||||
if (!priv->shadow.dma_buf.handles[0])
|
||||
return FALSE;
|
||||
|
||||
priv->shadow.dma_buf.handles[1] = cogl_renderer_create_dma_buf (cogl_renderer,
|
||||
width, height,
|
||||
error);
|
||||
if (!priv->shadow.dma_buf.handles[1])
|
||||
{
|
||||
g_clear_pointer (&priv->shadow.dma_buf.handles[0],
|
||||
cogl_dma_buf_handle_free);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
priv->shadow.dma_buf.damage_history = clutter_damage_history_new ();
|
||||
|
||||
initial_shadowfb =
|
||||
cogl_dma_buf_handle_get_framebuffer (priv->shadow.dma_buf.handles[0]);
|
||||
priv->shadow.framebuffer = cogl_object_ref (initial_shadowfb);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static CoglOffscreen *
|
||||
create_offscreen_framebuffer (CoglContext *context,
|
||||
int width,
|
||||
int height,
|
||||
GError **error)
|
||||
{
|
||||
CoglOffscreen *framebuffer;
|
||||
CoglTexture2D *texture;
|
||||
|
||||
texture = cogl_texture_2d_new_with_size (context, width, height);
|
||||
cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (texture),
|
||||
FALSE);
|
||||
|
||||
if (!cogl_texture_allocate (COGL_TEXTURE (texture), error))
|
||||
{
|
||||
cogl_object_unref (texture);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
framebuffer = cogl_offscreen_new_with_texture (COGL_TEXTURE (texture));
|
||||
cogl_object_unref (texture);
|
||||
if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (framebuffer), error))
|
||||
{
|
||||
cogl_object_unref (framebuffer);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return framebuffer;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
init_fallback_shadowfb (ClutterStageView *view,
|
||||
CoglContext *cogl_context,
|
||||
int width,
|
||||
int height,
|
||||
GError **error)
|
||||
{
|
||||
ClutterStageViewPrivate *priv =
|
||||
clutter_stage_view_get_instance_private (view);
|
||||
CoglOffscreen *offscreen;
|
||||
|
||||
offscreen = create_offscreen_framebuffer (cogl_context, width, height, error);
|
||||
if (!offscreen)
|
||||
return FALSE;
|
||||
|
||||
priv->shadow.framebuffer = offscreen;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
init_shadowfb (ClutterStageView *view)
|
||||
{
|
||||
ClutterStageViewPrivate *priv =
|
||||
clutter_stage_view_get_instance_private (view);
|
||||
g_autoptr (GError) error = NULL;
|
||||
int width;
|
||||
int height;
|
||||
CoglContext *cogl_context;
|
||||
|
||||
width = cogl_framebuffer_get_width (priv->framebuffer);
|
||||
height = cogl_framebuffer_get_height (priv->framebuffer);
|
||||
cogl_context = cogl_framebuffer_get_context (priv->framebuffer);
|
||||
|
||||
if (init_dma_buf_shadowfbs (view, cogl_context, width, height, &error))
|
||||
{
|
||||
g_message ("Initialized double buffered shadow fb for %s", priv->name);
|
||||
return;
|
||||
}
|
||||
|
||||
g_warning ("Failed to initialize double buffered shadow fb for %s: %s",
|
||||
priv->name, error->message);
|
||||
g_clear_error (&error);
|
||||
|
||||
if (!init_fallback_shadowfb (view, cogl_context, width, height, &error))
|
||||
{
|
||||
g_warning ("Failed to initialize single buffered shadow fb for %s: %s",
|
||||
priv->name, error->message);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_message ("Initialized single buffered shadow fb for %s", priv->name);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
clutter_stage_view_after_paint (ClutterStageView *view)
|
||||
clutter_stage_view_after_paint (ClutterStageView *view,
|
||||
cairo_region_t *redraw_clip)
|
||||
{
|
||||
ClutterStageViewPrivate *priv =
|
||||
clutter_stage_view_get_instance_private (view);
|
||||
|
||||
if (priv->offscreen)
|
||||
{
|
||||
gboolean can_blit;
|
||||
CoglMatrix matrix;
|
||||
|
||||
clutter_stage_view_ensure_offscreen_blit_pipeline (view);
|
||||
clutter_stage_view_get_offscreen_transformation_matrix (view, &matrix);
|
||||
can_blit = cogl_matrix_is_identity (&matrix);
|
||||
|
||||
if (priv->shadowfb)
|
||||
if (priv->shadow.framebuffer)
|
||||
{
|
||||
clutter_stage_view_copy_to_framebuffer (view,
|
||||
priv->offscreen_pipeline,
|
||||
priv->offscreen,
|
||||
priv->shadowfb,
|
||||
can_blit);
|
||||
paint_transformed_framebuffer (view,
|
||||
priv->offscreen_pipeline,
|
||||
priv->offscreen,
|
||||
priv->shadow.framebuffer,
|
||||
redraw_clip);
|
||||
}
|
||||
else
|
||||
{
|
||||
clutter_stage_view_copy_to_framebuffer (view,
|
||||
priv->offscreen_pipeline,
|
||||
priv->offscreen,
|
||||
priv->framebuffer,
|
||||
can_blit);
|
||||
paint_transformed_framebuffer (view,
|
||||
priv->offscreen_pipeline,
|
||||
priv->offscreen,
|
||||
priv->framebuffer,
|
||||
redraw_clip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_tile_dirty (cairo_rectangle_int_t *tile,
|
||||
uint8_t *current_data,
|
||||
uint8_t *prev_data,
|
||||
int bpp,
|
||||
int stride)
|
||||
{
|
||||
int y;
|
||||
|
||||
for (y = tile->y; y < tile->y + tile->height; y++)
|
||||
{
|
||||
if (memcmp (prev_data + y * stride + tile->x * bpp,
|
||||
current_data + y * stride + tile->x * bpp,
|
||||
tile->width * bpp) != 0)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int
|
||||
flip_dma_buf_idx (int idx)
|
||||
{
|
||||
return (idx + 1) % 2;
|
||||
}
|
||||
|
||||
static cairo_region_t *
|
||||
find_damaged_tiles (ClutterStageView *view,
|
||||
const cairo_region_t *damage_region,
|
||||
GError **error)
|
||||
{
|
||||
ClutterStageViewPrivate *priv =
|
||||
clutter_stage_view_get_instance_private (view);
|
||||
cairo_region_t *tile_damage_region;
|
||||
cairo_rectangle_int_t damage_extents;
|
||||
cairo_rectangle_int_t fb_rect;
|
||||
int prev_dma_buf_idx;
|
||||
CoglDmaBufHandle *prev_dma_buf_handle;
|
||||
uint8_t *prev_data;
|
||||
int current_dma_buf_idx;
|
||||
CoglDmaBufHandle *current_dma_buf_handle;
|
||||
uint8_t *current_data;
|
||||
int width, height, stride, bpp;
|
||||
int tile_x_min, tile_x_max;
|
||||
int tile_y_min, tile_y_max;
|
||||
int tile_x, tile_y;
|
||||
const int tile_size = 16;
|
||||
|
||||
prev_dma_buf_idx = flip_dma_buf_idx (priv->shadow.dma_buf.current_idx);
|
||||
prev_dma_buf_handle = priv->shadow.dma_buf.handles[prev_dma_buf_idx];
|
||||
|
||||
current_dma_buf_idx = priv->shadow.dma_buf.current_idx;
|
||||
current_dma_buf_handle = priv->shadow.dma_buf.handles[current_dma_buf_idx];
|
||||
|
||||
width = cogl_dma_buf_handle_get_width (current_dma_buf_handle);
|
||||
height = cogl_dma_buf_handle_get_height (current_dma_buf_handle);
|
||||
stride = cogl_dma_buf_handle_get_stride (current_dma_buf_handle);
|
||||
bpp = cogl_dma_buf_handle_get_bpp (current_dma_buf_handle);
|
||||
|
||||
cogl_framebuffer_finish (priv->shadow.framebuffer);
|
||||
|
||||
if (!cogl_dma_buf_handle_sync_read_start (prev_dma_buf_handle, error))
|
||||
return NULL;
|
||||
|
||||
if (!cogl_dma_buf_handle_sync_read_start (current_dma_buf_handle, error))
|
||||
goto err_sync_read_current;
|
||||
|
||||
prev_data = cogl_dma_buf_handle_mmap (prev_dma_buf_handle, error);
|
||||
if (!prev_data)
|
||||
goto err_mmap_prev;
|
||||
current_data = cogl_dma_buf_handle_mmap (current_dma_buf_handle, error);
|
||||
if (!current_data)
|
||||
goto err_mmap_current;
|
||||
|
||||
fb_rect = (cairo_rectangle_int_t) {
|
||||
.width = width,
|
||||
.height = height,
|
||||
};
|
||||
|
||||
cairo_region_get_extents (damage_region, &damage_extents);
|
||||
|
||||
tile_x_min = damage_extents.x / tile_size;
|
||||
tile_x_max = ((damage_extents.x + damage_extents.width + tile_size - 1) /
|
||||
tile_size);
|
||||
tile_y_min = damage_extents.y / tile_size;
|
||||
tile_y_max = ((damage_extents.y + damage_extents.height + tile_size - 1) /
|
||||
tile_size);
|
||||
|
||||
tile_damage_region = cairo_region_create ();
|
||||
|
||||
for (tile_y = tile_y_min; tile_y <= tile_y_max; tile_y++)
|
||||
{
|
||||
for (tile_x = tile_x_min; tile_x <= tile_x_max; tile_x++)
|
||||
{
|
||||
cairo_rectangle_int_t tile = {
|
||||
.x = tile_x * tile_size,
|
||||
.y = tile_y * tile_size,
|
||||
.width = tile_size,
|
||||
.height = tile_size,
|
||||
};
|
||||
|
||||
if (cairo_region_contains_rectangle (damage_region, &tile) ==
|
||||
CAIRO_REGION_OVERLAP_OUT)
|
||||
continue;
|
||||
|
||||
_clutter_util_rectangle_intersection (&tile, &fb_rect, &tile);
|
||||
|
||||
if (is_tile_dirty (&tile, current_data, prev_data, bpp, stride))
|
||||
cairo_region_union_rectangle (tile_damage_region, &tile);
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->shadowfb)
|
||||
if (!cogl_dma_buf_handle_sync_read_end (prev_dma_buf_handle, error))
|
||||
{
|
||||
clutter_stage_view_ensure_shadowfb_blit_pipeline (view);
|
||||
clutter_stage_view_copy_to_framebuffer (view,
|
||||
priv->shadowfb_pipeline,
|
||||
priv->shadowfb,
|
||||
priv->framebuffer,
|
||||
TRUE);
|
||||
g_warning ("Failed to end DMA buffer read synchronization: %s",
|
||||
(*error)->message);
|
||||
g_clear_error (error);
|
||||
}
|
||||
|
||||
if (!cogl_dma_buf_handle_sync_read_end (current_dma_buf_handle, error))
|
||||
{
|
||||
g_warning ("Failed to end DMA buffer read synchronization: %s",
|
||||
(*error)->message);
|
||||
g_clear_error (error);
|
||||
}
|
||||
|
||||
cogl_dma_buf_handle_munmap (prev_dma_buf_handle, prev_data, NULL);
|
||||
cogl_dma_buf_handle_munmap (current_dma_buf_handle, current_data, NULL);
|
||||
|
||||
cairo_region_intersect (tile_damage_region, damage_region);
|
||||
|
||||
return tile_damage_region;
|
||||
|
||||
err_mmap_current:
|
||||
cogl_dma_buf_handle_munmap (prev_dma_buf_handle, prev_data, NULL);
|
||||
|
||||
err_mmap_prev:
|
||||
cogl_dma_buf_handle_sync_read_end (current_dma_buf_handle, NULL);
|
||||
|
||||
err_sync_read_current:
|
||||
cogl_dma_buf_handle_sync_read_end (prev_dma_buf_handle, NULL);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
swap_dma_buf_framebuffer (ClutterStageView *view)
|
||||
{
|
||||
ClutterStageViewPrivate *priv =
|
||||
clutter_stage_view_get_instance_private (view);
|
||||
int next_idx;
|
||||
CoglDmaBufHandle *next_dma_buf_handle;
|
||||
CoglOffscreen *next_framebuffer;
|
||||
|
||||
next_idx = ((priv->shadow.dma_buf.current_idx + 1) %
|
||||
G_N_ELEMENTS (priv->shadow.dma_buf.handles));
|
||||
priv->shadow.dma_buf.current_idx = next_idx;
|
||||
|
||||
next_dma_buf_handle = priv->shadow.dma_buf.handles[next_idx];
|
||||
next_framebuffer =
|
||||
cogl_dma_buf_handle_get_framebuffer (next_dma_buf_handle);
|
||||
cogl_clear_object (&priv->shadow.framebuffer);
|
||||
priv->shadow.framebuffer = cogl_object_ref (next_framebuffer);
|
||||
}
|
||||
|
||||
static void
|
||||
copy_shadowfb_to_onscreen (ClutterStageView *view,
|
||||
const cairo_region_t *swap_region)
|
||||
{
|
||||
ClutterStageViewPrivate *priv =
|
||||
clutter_stage_view_get_instance_private (view);
|
||||
ClutterDamageHistory *damage_history = priv->shadow.dma_buf.damage_history;
|
||||
cairo_region_t *damage_region;
|
||||
int age;
|
||||
int i;
|
||||
|
||||
if (cairo_region_is_empty (swap_region))
|
||||
{
|
||||
cairo_rectangle_int_t full_damage = {
|
||||
.width = cogl_framebuffer_get_width (priv->framebuffer),
|
||||
.height = cogl_framebuffer_get_height (priv->framebuffer),
|
||||
};
|
||||
damage_region = cairo_region_create_rectangle (&full_damage);
|
||||
}
|
||||
else
|
||||
{
|
||||
damage_region = cairo_region_copy (swap_region);
|
||||
}
|
||||
|
||||
if (is_shadowfb_double_buffered (view))
|
||||
{
|
||||
CoglOnscreen *onscreen = COGL_ONSCREEN (priv->framebuffer);
|
||||
cairo_region_t *changed_region;
|
||||
|
||||
if (cogl_onscreen_get_frame_counter (onscreen) >= 1)
|
||||
{
|
||||
g_autoptr (GError) error = NULL;
|
||||
|
||||
changed_region = find_damaged_tiles (view, damage_region, &error);
|
||||
if (!changed_region)
|
||||
{
|
||||
int other_dma_buf_idx;
|
||||
|
||||
g_warning ("Disabling actual damage detection: %s",
|
||||
error->message);
|
||||
|
||||
other_dma_buf_idx =
|
||||
flip_dma_buf_idx (priv->shadow.dma_buf.current_idx);
|
||||
g_clear_pointer (&priv->shadow.dma_buf.handles[other_dma_buf_idx],
|
||||
cogl_dma_buf_handle_free);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
changed_region = cairo_region_copy (damage_region);
|
||||
}
|
||||
|
||||
if (changed_region)
|
||||
{
|
||||
int buffer_age;
|
||||
|
||||
clutter_damage_history_record (damage_history, changed_region);
|
||||
|
||||
buffer_age = cogl_onscreen_get_buffer_age (onscreen);
|
||||
if (clutter_damage_history_is_age_valid (damage_history, buffer_age))
|
||||
{
|
||||
for (age = 1; age <= buffer_age; age++)
|
||||
{
|
||||
const cairo_region_t *old_damage;
|
||||
|
||||
old_damage = clutter_damage_history_lookup (damage_history, age);
|
||||
cairo_region_union (changed_region, old_damage);
|
||||
}
|
||||
|
||||
cairo_region_destroy (damage_region);
|
||||
damage_region = g_steal_pointer (&changed_region);
|
||||
}
|
||||
else
|
||||
{
|
||||
cairo_region_destroy (changed_region);
|
||||
}
|
||||
|
||||
clutter_damage_history_step (damage_history);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < cairo_region_num_rectangles (damage_region); i++)
|
||||
{
|
||||
g_autoptr (GError) error = NULL;
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
cairo_region_get_rectangle (damage_region, i, &rect);
|
||||
|
||||
if (!cogl_blit_framebuffer (priv->shadow.framebuffer,
|
||||
priv->framebuffer,
|
||||
rect.x, rect.y,
|
||||
rect.x, rect.y,
|
||||
rect.width, rect.height,
|
||||
&error))
|
||||
{
|
||||
g_warning ("Failed to blit shadow buffer: %s", error->message);
|
||||
cairo_region_destroy (damage_region);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
cairo_region_destroy (damage_region);
|
||||
|
||||
if (is_shadowfb_double_buffered (view))
|
||||
swap_dma_buf_framebuffer (view);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_stage_view_before_swap_buffer (ClutterStageView *view,
|
||||
const cairo_region_t *swap_region)
|
||||
{
|
||||
ClutterStageViewPrivate *priv =
|
||||
clutter_stage_view_get_instance_private (view);
|
||||
|
||||
if (priv->shadow.framebuffer)
|
||||
copy_shadowfb_to_onscreen (view, swap_region);
|
||||
}
|
||||
|
||||
float
|
||||
@@ -264,6 +741,47 @@ clutter_stage_view_get_scale (ClutterStageView *view)
|
||||
return priv->scale;
|
||||
}
|
||||
|
||||
typedef void (*FrontBufferCallback) (CoglFramebuffer *framebuffer,
|
||||
gconstpointer user_data);
|
||||
|
||||
static void
|
||||
clutter_stage_view_foreach_front_buffer (ClutterStageView *view,
|
||||
FrontBufferCallback callback,
|
||||
gconstpointer user_data)
|
||||
{
|
||||
ClutterStageViewPrivate *priv =
|
||||
clutter_stage_view_get_instance_private (view);
|
||||
|
||||
if (priv->offscreen)
|
||||
{
|
||||
callback (priv->offscreen, user_data);
|
||||
}
|
||||
else if (priv->shadow.framebuffer)
|
||||
{
|
||||
if (is_shadowfb_double_buffered (view))
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (priv->shadow.dma_buf.handles); i++)
|
||||
{
|
||||
CoglDmaBufHandle *handle = priv->shadow.dma_buf.handles[i];
|
||||
CoglFramebuffer *framebuffer =
|
||||
cogl_dma_buf_handle_get_framebuffer (handle);
|
||||
|
||||
callback (framebuffer, user_data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
callback (priv->shadow.framebuffer, user_data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
callback (priv->framebuffer, user_data);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_stage_view_is_dirty_viewport (ClutterStageView *view)
|
||||
{
|
||||
@@ -274,13 +792,47 @@ clutter_stage_view_is_dirty_viewport (ClutterStageView *view)
|
||||
}
|
||||
|
||||
void
|
||||
clutter_stage_view_set_dirty_viewport (ClutterStageView *view,
|
||||
gboolean dirty)
|
||||
clutter_stage_view_invalidate_viewport (ClutterStageView *view)
|
||||
{
|
||||
ClutterStageViewPrivate *priv =
|
||||
clutter_stage_view_get_instance_private (view);
|
||||
|
||||
priv->dirty_viewport = dirty;
|
||||
priv->dirty_viewport = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
set_framebuffer_viewport (CoglFramebuffer *framebuffer,
|
||||
gconstpointer user_data)
|
||||
{
|
||||
const graphene_rect_t *rect = user_data;
|
||||
|
||||
cogl_framebuffer_set_viewport (framebuffer,
|
||||
rect->origin.x,
|
||||
rect->origin.y,
|
||||
rect->size.width,
|
||||
rect->size.height);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_stage_view_set_viewport (ClutterStageView *view,
|
||||
float x,
|
||||
float y,
|
||||
float width,
|
||||
float height)
|
||||
{
|
||||
ClutterStageViewPrivate *priv =
|
||||
clutter_stage_view_get_instance_private (view);
|
||||
graphene_rect_t rect;
|
||||
|
||||
priv->dirty_viewport = FALSE;
|
||||
|
||||
rect = (graphene_rect_t) {
|
||||
.origin = { .x = x, .y = y },
|
||||
.size = { .width = width, .height = height },
|
||||
};
|
||||
clutter_stage_view_foreach_front_buffer (view,
|
||||
set_framebuffer_viewport,
|
||||
&rect);
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -292,14 +844,33 @@ clutter_stage_view_is_dirty_projection (ClutterStageView *view)
|
||||
return priv->dirty_projection;
|
||||
}
|
||||
|
||||
static void
|
||||
set_framebuffer_projection_matrix (CoglFramebuffer *framebuffer,
|
||||
gconstpointer user_data)
|
||||
{
|
||||
cogl_framebuffer_set_projection_matrix (framebuffer, user_data);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_stage_view_set_dirty_projection (ClutterStageView *view,
|
||||
gboolean dirty)
|
||||
clutter_stage_view_invalidate_projection (ClutterStageView *view)
|
||||
{
|
||||
ClutterStageViewPrivate *priv =
|
||||
clutter_stage_view_get_instance_private (view);
|
||||
|
||||
priv->dirty_projection = dirty;
|
||||
priv->dirty_projection = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_stage_view_set_projection (ClutterStageView *view,
|
||||
const CoglMatrix *matrix)
|
||||
{
|
||||
ClutterStageViewPrivate *priv =
|
||||
clutter_stage_view_get_instance_private (view);
|
||||
|
||||
priv->dirty_projection = FALSE;
|
||||
clutter_stage_view_foreach_front_buffer (view,
|
||||
set_framebuffer_projection_matrix,
|
||||
matrix);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -391,19 +962,6 @@ clutter_stage_view_take_redraw_clip (ClutterStageView *view)
|
||||
return g_steal_pointer (&priv->redraw_clip);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_stage_view_transform_to_onscreen (ClutterStageView *view,
|
||||
gfloat *x,
|
||||
gfloat *y)
|
||||
{
|
||||
gfloat z = 0, w = 1;
|
||||
CoglMatrix matrix;
|
||||
|
||||
clutter_stage_view_get_offscreen_transformation_matrix (view, &matrix);
|
||||
cogl_matrix_get_inverse (&matrix, &matrix);
|
||||
cogl_matrix_transform_point (&matrix, x, y, &z, &w);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_default_get_offscreen_transformation_matrix (ClutterStageView *view,
|
||||
CoglMatrix *matrix)
|
||||
@@ -442,6 +1000,9 @@ clutter_stage_view_get_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, priv->name);
|
||||
break;
|
||||
case PROP_LAYOUT:
|
||||
g_value_set_boxed (value, &priv->layout);
|
||||
break;
|
||||
@@ -451,8 +1012,8 @@ clutter_stage_view_get_property (GObject *object,
|
||||
case PROP_OFFSCREEN:
|
||||
g_value_set_boxed (value, priv->offscreen);
|
||||
break;
|
||||
case PROP_SHADOWFB:
|
||||
g_value_set_boxed (value, priv->shadowfb);
|
||||
case PROP_USE_SHADOWFB:
|
||||
g_value_set_boolean (value, priv->use_shadowfb);
|
||||
break;
|
||||
case PROP_SCALE:
|
||||
g_value_set_float (value, priv->scale);
|
||||
@@ -475,6 +1036,9 @@ clutter_stage_view_set_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_NAME:
|
||||
priv->name = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_LAYOUT:
|
||||
layout = g_value_get_boxed (value);
|
||||
priv->layout = *layout;
|
||||
@@ -499,8 +1063,8 @@ clutter_stage_view_set_property (GObject *object,
|
||||
case PROP_OFFSCREEN:
|
||||
priv->offscreen = g_value_dup_boxed (value);
|
||||
break;
|
||||
case PROP_SHADOWFB:
|
||||
priv->shadowfb = g_value_dup_boxed (value);
|
||||
case PROP_USE_SHADOWFB:
|
||||
priv->use_shadowfb = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_SCALE:
|
||||
priv->scale = g_value_get_float (value);
|
||||
@@ -511,17 +1075,40 @@ clutter_stage_view_set_property (GObject *object,
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_view_dispose (GObject *object)
|
||||
clutter_stage_view_constructed (GObject *object)
|
||||
{
|
||||
ClutterStageView *view = CLUTTER_STAGE_VIEW (object);
|
||||
ClutterStageViewPrivate *priv =
|
||||
clutter_stage_view_get_instance_private (view);
|
||||
|
||||
if (priv->use_shadowfb)
|
||||
init_shadowfb (view);
|
||||
|
||||
G_OBJECT_CLASS (clutter_stage_view_parent_class)->constructed (object);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_view_dispose (GObject *object)
|
||||
{
|
||||
ClutterStageView *view = CLUTTER_STAGE_VIEW (object);
|
||||
ClutterStageViewPrivate *priv =
|
||||
clutter_stage_view_get_instance_private (view);
|
||||
int i;
|
||||
|
||||
g_clear_pointer (&priv->name, g_free);
|
||||
g_clear_pointer (&priv->framebuffer, cogl_object_unref);
|
||||
g_clear_pointer (&priv->shadowfb, cogl_object_unref);
|
||||
|
||||
g_clear_pointer (&priv->shadow.framebuffer, cogl_object_unref);
|
||||
for (i = 0; i < G_N_ELEMENTS (priv->shadow.dma_buf.handles); i++)
|
||||
{
|
||||
g_clear_pointer (&priv->shadow.dma_buf.handles[i],
|
||||
cogl_dma_buf_handle_free);
|
||||
}
|
||||
g_clear_pointer (&priv->shadow.dma_buf.damage_history,
|
||||
clutter_damage_history_free);
|
||||
|
||||
g_clear_pointer (&priv->offscreen, cogl_object_unref);
|
||||
g_clear_pointer (&priv->offscreen_pipeline, cogl_object_unref);
|
||||
g_clear_pointer (&priv->shadowfb_pipeline, cogl_object_unref);
|
||||
g_clear_pointer (&priv->redraw_clip, cairo_region_destroy);
|
||||
|
||||
G_OBJECT_CLASS (clutter_stage_view_parent_class)->dispose (object);
|
||||
@@ -548,8 +1135,17 @@ clutter_stage_view_class_init (ClutterStageViewClass *klass)
|
||||
|
||||
object_class->get_property = clutter_stage_view_get_property;
|
||||
object_class->set_property = clutter_stage_view_set_property;
|
||||
object_class->constructed = clutter_stage_view_constructed;
|
||||
object_class->dispose = clutter_stage_view_dispose;
|
||||
|
||||
obj_props[PROP_NAME] =
|
||||
g_param_spec_string ("name",
|
||||
"Name",
|
||||
"Name of view",
|
||||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
obj_props[PROP_LAYOUT] =
|
||||
g_param_spec_boxed ("layout",
|
||||
"View layout",
|
||||
@@ -577,14 +1173,14 @@ clutter_stage_view_class_init (ClutterStageViewClass *klass)
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
obj_props[PROP_SHADOWFB] =
|
||||
g_param_spec_boxed ("shadowfb",
|
||||
"Shadow framebuffer",
|
||||
"Framebuffer used as intermediate shadow buffer",
|
||||
COGL_TYPE_HANDLE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
obj_props[PROP_USE_SHADOWFB] =
|
||||
g_param_spec_boolean ("use-shadowfb",
|
||||
"Use shadowfb",
|
||||
"Whether to use one or more shadow framebuffers",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
obj_props[PROP_SCALE] =
|
||||
g_param_spec_float ("scale",
|
||||
|
@@ -43,6 +43,12 @@ struct _ClutterStageViewClass
|
||||
|
||||
void (* get_offscreen_transformation_matrix) (ClutterStageView *view,
|
||||
CoglMatrix *matrix);
|
||||
|
||||
void (* transform_rect_to_onscreen) (ClutterStageView *view,
|
||||
const cairo_rectangle_int_t *src_rect,
|
||||
int dst_width,
|
||||
int dst_height,
|
||||
cairo_rectangle_int_t *dst_rect);
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
@@ -56,11 +62,6 @@ CoglFramebuffer *clutter_stage_view_get_onscreen (ClutterStageView *view);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_stage_view_invalidate_offscreen_blit_pipeline (ClutterStageView *view);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_stage_view_transform_to_onscreen (ClutterStageView *view,
|
||||
gfloat *x,
|
||||
gfloat *y);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
float clutter_stage_view_get_scale (ClutterStageView *view);
|
||||
|
||||
|
@@ -142,6 +142,8 @@ struct _ClutterStagePrivate
|
||||
|
||||
int update_freeze_count;
|
||||
|
||||
gboolean needs_update;
|
||||
|
||||
guint redraw_pending : 1;
|
||||
guint throttle_motion_events : 1;
|
||||
guint min_size_changed : 1;
|
||||
@@ -613,8 +615,7 @@ stage_is_default (ClutterStage *stage)
|
||||
|
||||
static void
|
||||
clutter_stage_allocate (ClutterActor *self,
|
||||
const ClutterActorBox *box,
|
||||
ClutterAllocationFlags flags)
|
||||
const ClutterActorBox *box)
|
||||
{
|
||||
ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv;
|
||||
ClutterActorBox alloc = CLUTTER_ACTOR_BOX_INIT_ZERO;
|
||||
@@ -622,6 +623,7 @@ clutter_stage_allocate (ClutterActor *self,
|
||||
float new_width, new_height;
|
||||
float width, height;
|
||||
cairo_rectangle_int_t window_size;
|
||||
ClutterLayoutManager *layout_manager = clutter_actor_get_layout_manager (self);
|
||||
|
||||
if (priv->impl == NULL)
|
||||
return;
|
||||
@@ -643,15 +645,21 @@ clutter_stage_allocate (ClutterActor *self,
|
||||
*/
|
||||
if (!clutter_feature_available (CLUTTER_FEATURE_STAGE_STATIC))
|
||||
{
|
||||
CLUTTER_NOTE (LAYOUT,
|
||||
"Following allocation to %.2fx%.2f (absolute origin %s)",
|
||||
width, height,
|
||||
(flags & CLUTTER_ABSOLUTE_ORIGIN_CHANGED)
|
||||
? "changed"
|
||||
: "not changed");
|
||||
ClutterActorBox children_box;
|
||||
|
||||
clutter_actor_set_allocation (self, box,
|
||||
flags | CLUTTER_DELEGATE_LAYOUT);
|
||||
children_box.x1 = children_box.y1 = 0.f;
|
||||
children_box.x2 = box->x2 - box->x1;
|
||||
children_box.y2 = box->y2 - box->y1;
|
||||
|
||||
CLUTTER_NOTE (LAYOUT,
|
||||
"Following allocation to %.2fx%.2f",
|
||||
width, height);
|
||||
|
||||
clutter_actor_set_allocation (self, box);
|
||||
|
||||
clutter_layout_manager_allocate (layout_manager,
|
||||
CLUTTER_CONTAINER (self),
|
||||
&children_box);
|
||||
|
||||
/* Ensure the window is sized correctly */
|
||||
if (priv->min_size_changed)
|
||||
@@ -699,16 +707,16 @@ clutter_stage_allocate (ClutterActor *self,
|
||||
|
||||
CLUTTER_NOTE (LAYOUT,
|
||||
"Overriding original allocation of %.2fx%.2f "
|
||||
"with %.2fx%.2f (absolute origin %s)",
|
||||
"with %.2fx%.2f",
|
||||
width, height,
|
||||
override.x2, override.y2,
|
||||
(flags & CLUTTER_ABSOLUTE_ORIGIN_CHANGED)
|
||||
? "changed"
|
||||
: "not changed");
|
||||
override.x2, override.y2);
|
||||
|
||||
/* and store the overridden allocation */
|
||||
clutter_actor_set_allocation (self, &override,
|
||||
flags | CLUTTER_DELEGATE_LAYOUT);
|
||||
clutter_actor_set_allocation (self, &override);
|
||||
|
||||
clutter_layout_manager_allocate (layout_manager,
|
||||
CLUTTER_CONTAINER (self),
|
||||
&override);
|
||||
}
|
||||
|
||||
/* reset the viewport if the allocation effectively changed */
|
||||
@@ -1170,7 +1178,7 @@ _clutter_stage_queue_event (ClutterStage *stage,
|
||||
{
|
||||
ClutterMasterClock *master_clock = _clutter_master_clock_get_default ();
|
||||
_clutter_master_clock_start_running (master_clock);
|
||||
_clutter_stage_schedule_update (stage);
|
||||
clutter_stage_schedule_update (stage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1302,7 +1310,9 @@ _clutter_stage_needs_update (ClutterStage *stage)
|
||||
|
||||
priv = stage->priv;
|
||||
|
||||
return priv->redraw_pending || g_hash_table_size (priv->pending_relayouts) > 0;
|
||||
return (priv->redraw_pending ||
|
||||
priv->needs_update ||
|
||||
g_hash_table_size (priv->pending_relayouts) > 0);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1312,7 +1322,7 @@ clutter_stage_queue_actor_relayout (ClutterStage *stage,
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
|
||||
if (g_hash_table_size (priv->pending_relayouts) == 0)
|
||||
_clutter_stage_schedule_update (stage);
|
||||
clutter_stage_schedule_update (stage);
|
||||
|
||||
g_hash_table_add (priv->pending_relayouts, g_object_ref (actor));
|
||||
priv->pending_relayouts_version++;
|
||||
@@ -1359,8 +1369,7 @@ _clutter_stage_maybe_relayout (ClutterActor *actor)
|
||||
CLUTTER_SET_PRIVATE_FLAGS (queued_actor, CLUTTER_IN_RELAYOUT);
|
||||
|
||||
old_version = priv->pending_relayouts_version;
|
||||
clutter_actor_allocate_preferred_size (queued_actor,
|
||||
CLUTTER_ALLOCATION_NONE);
|
||||
clutter_actor_allocate_preferred_size (queued_actor);
|
||||
|
||||
CLUTTER_UNSET_PRIVATE_FLAGS (queued_actor, CLUTTER_IN_RELAYOUT);
|
||||
|
||||
@@ -1494,6 +1503,8 @@ _clutter_stage_do_update (ClutterStage *stage)
|
||||
|
||||
priv->stage_was_relayout = FALSE;
|
||||
|
||||
priv->needs_update = FALSE;
|
||||
|
||||
/* if the stage is being destroyed, or if the destruction already
|
||||
* happened and we don't have an StageWindow any more, then we
|
||||
* should bail out
|
||||
@@ -2429,7 +2440,7 @@ _clutter_stage_dirty_projection (ClutterStage *stage)
|
||||
{
|
||||
ClutterStageView *view = l->data;
|
||||
|
||||
clutter_stage_view_set_dirty_projection (view, TRUE);
|
||||
clutter_stage_view_invalidate_projection (view);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2519,7 +2530,7 @@ _clutter_stage_dirty_viewport (ClutterStage *stage)
|
||||
{
|
||||
ClutterStageView *view = l->data;
|
||||
|
||||
clutter_stage_view_set_dirty_viewport (view, TRUE);
|
||||
clutter_stage_view_invalidate_viewport (view);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3142,7 +3153,6 @@ _clutter_stage_maybe_setup_viewport (ClutterStage *stage,
|
||||
ClutterStageView *view)
|
||||
{
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
CoglFramebuffer *fb = clutter_stage_view_get_framebuffer (view);
|
||||
|
||||
if (clutter_stage_view_is_dirty_viewport (view))
|
||||
{
|
||||
@@ -3169,19 +3179,14 @@ _clutter_stage_maybe_setup_viewport (ClutterStage *stage,
|
||||
viewport_y = roundf (priv->viewport[1] * fb_scale - viewport_offset_y);
|
||||
viewport_width = roundf (priv->viewport[2] * fb_scale);
|
||||
viewport_height = roundf (priv->viewport[3] * fb_scale);
|
||||
cogl_framebuffer_set_viewport (fb,
|
||||
viewport_x, viewport_y,
|
||||
viewport_width, viewport_height);
|
||||
|
||||
clutter_stage_view_set_dirty_viewport (view, FALSE);
|
||||
clutter_stage_view_set_viewport (view,
|
||||
viewport_x, viewport_y,
|
||||
viewport_width, viewport_height);
|
||||
}
|
||||
|
||||
if (clutter_stage_view_is_dirty_projection (view))
|
||||
{
|
||||
cogl_framebuffer_set_projection_matrix (fb, &priv->projection);
|
||||
|
||||
clutter_stage_view_set_dirty_projection (view, FALSE);
|
||||
}
|
||||
clutter_stage_view_set_projection (view, &priv->projection);
|
||||
}
|
||||
|
||||
#undef _DEG_TO_RAD
|
||||
@@ -3209,7 +3214,7 @@ clutter_stage_ensure_redraw (ClutterStage *stage)
|
||||
priv = stage->priv;
|
||||
|
||||
if (!_clutter_stage_needs_update (stage))
|
||||
_clutter_stage_schedule_update (stage);
|
||||
clutter_stage_schedule_update (stage);
|
||||
|
||||
priv->redraw_pending = TRUE;
|
||||
|
||||
@@ -3437,13 +3442,13 @@ clutter_stage_get_minimum_size (ClutterStage *stage,
|
||||
}
|
||||
|
||||
/**
|
||||
* _clutter_stage_schedule_update:
|
||||
* @window: a #ClutterStage actor
|
||||
* clutter_stage_schedule_update:
|
||||
* @stage: a #ClutterStage actor
|
||||
*
|
||||
* Schedules a redraw of the #ClutterStage at the next optimal timestamp.
|
||||
*/
|
||||
void
|
||||
_clutter_stage_schedule_update (ClutterStage *stage)
|
||||
clutter_stage_schedule_update (ClutterStage *stage)
|
||||
{
|
||||
ClutterStageWindow *stage_window;
|
||||
|
||||
@@ -3454,6 +3459,8 @@ _clutter_stage_schedule_update (ClutterStage *stage)
|
||||
if (stage_window == NULL)
|
||||
return;
|
||||
|
||||
stage->priv->needs_update = TRUE;
|
||||
|
||||
return _clutter_stage_window_schedule_update (stage_window,
|
||||
stage->priv->sync_delay);
|
||||
}
|
||||
@@ -3463,7 +3470,7 @@ _clutter_stage_schedule_update (ClutterStage *stage)
|
||||
* @stage: a #ClutterStage actor
|
||||
*
|
||||
* Returns the earliest time in which the stage is ready to update. The update
|
||||
* time is set when _clutter_stage_schedule_update() is called. This can then
|
||||
* time is set when clutter_stage_schedule_update() is called. This can then
|
||||
* be used by e.g. the #ClutterMasterClock to know when the stage needs to be
|
||||
* redrawn.
|
||||
*
|
||||
@@ -3573,7 +3580,7 @@ _clutter_stage_queue_actor_redraw (ClutterStage *stage,
|
||||
|
||||
CLUTTER_NOTE (PAINT, "First redraw request");
|
||||
|
||||
_clutter_stage_schedule_update (stage);
|
||||
clutter_stage_schedule_update (stage);
|
||||
priv->redraw_pending = TRUE;
|
||||
|
||||
master_clock = _clutter_master_clock_get_default ();
|
||||
|
@@ -209,6 +209,9 @@ CLUTTER_EXPORT
|
||||
void clutter_stage_skip_sync_delay (ClutterStage *stage);
|
||||
#endif
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_stage_schedule_update (ClutterStage *stage);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_stage_get_capture_final_size (ClutterStage *stage,
|
||||
cairo_rectangle_int_t *rect,
|
||||
|
@@ -3037,8 +3037,7 @@ clutter_text_get_preferred_height (ClutterActor *self,
|
||||
|
||||
static void
|
||||
clutter_text_allocate (ClutterActor *self,
|
||||
const ClutterActorBox *box,
|
||||
ClutterAllocationFlags flags)
|
||||
const ClutterActorBox *box)
|
||||
{
|
||||
ClutterText *text = CLUTTER_TEXT (self);
|
||||
ClutterActorClass *parent_class;
|
||||
@@ -3058,7 +3057,7 @@ clutter_text_allocate (ClutterActor *self,
|
||||
box->y2 - box->y1);
|
||||
|
||||
parent_class = CLUTTER_ACTOR_CLASS (clutter_text_parent_class);
|
||||
parent_class->allocate (self, box, flags);
|
||||
parent_class->allocate (self, box);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -4787,11 +4786,11 @@ clutter_text_queue_redraw_or_relayout (ClutterText *self)
|
||||
clutter_text_get_preferred_height (actor, preferred_width, NULL, &preferred_height);
|
||||
|
||||
if (clutter_actor_has_allocation (actor) &&
|
||||
(fabsf (preferred_width - clutter_actor_get_width (actor)) > 0.001 ||
|
||||
fabsf (preferred_height - clutter_actor_get_height (actor)) > 0.001))
|
||||
clutter_actor_queue_relayout (actor);
|
||||
else
|
||||
fabsf (preferred_width - clutter_actor_get_width (actor)) <= 0.001 &&
|
||||
fabsf (preferred_height - clutter_actor_get_height (actor)) <= 0.001)
|
||||
clutter_text_queue_redraw (actor);
|
||||
else
|
||||
clutter_actor_queue_relayout (actor);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -38,6 +38,7 @@
|
||||
|
||||
#include "clutter-actor-private.h"
|
||||
#include "clutter-backend-private.h"
|
||||
#include "clutter-damage-history.h"
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-event.h"
|
||||
#include "clutter-enum-types.h"
|
||||
@@ -51,13 +52,9 @@
|
||||
|
||||
typedef struct _ClutterStageViewCoglPrivate
|
||||
{
|
||||
/*
|
||||
* List of previous damaged areas in stage view framebuffer coordinate space.
|
||||
/* Damage history, in stage view render target framebuffer coordinate space.
|
||||
*/
|
||||
#define DAMAGE_HISTORY_MAX 16
|
||||
#define DAMAGE_HISTORY(x) ((x) & (DAMAGE_HISTORY_MAX - 1))
|
||||
cairo_region_t * damage_history[DAMAGE_HISTORY_MAX];
|
||||
unsigned int damage_index;
|
||||
ClutterDamageHistory *damage_history;
|
||||
} ClutterStageViewCoglPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (ClutterStageViewCogl, clutter_stage_view_cogl,
|
||||
@@ -288,26 +285,13 @@ clutter_stage_cogl_resize (ClutterStageWindow *stage_window,
|
||||
{
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
valid_buffer_age (ClutterStageViewCogl *view_cogl,
|
||||
int age)
|
||||
{
|
||||
ClutterStageViewCoglPrivate *view_priv =
|
||||
clutter_stage_view_cogl_get_instance_private (view_cogl);
|
||||
|
||||
if (age <= 0)
|
||||
return FALSE;
|
||||
|
||||
return age < MIN (view_priv->damage_index, DAMAGE_HISTORY_MAX);
|
||||
}
|
||||
|
||||
static void
|
||||
paint_damage_region (ClutterStageWindow *stage_window,
|
||||
ClutterStageView *view,
|
||||
cairo_region_t *swap_region,
|
||||
cairo_region_t *queued_redraw_clip)
|
||||
{
|
||||
CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (view);
|
||||
CoglFramebuffer *framebuffer = clutter_stage_view_get_framebuffer (view);
|
||||
CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
|
||||
static CoglPipeline *overlay_blue = NULL;
|
||||
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
|
||||
@@ -378,24 +362,26 @@ swap_framebuffer (ClutterStageWindow *stage_window,
|
||||
gboolean swap_with_damage)
|
||||
{
|
||||
CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (view);
|
||||
int *damage, n_rects, i;
|
||||
|
||||
n_rects = cairo_region_num_rectangles (swap_region);
|
||||
damage = g_newa (int, n_rects * 4);
|
||||
for (i = 0; i < n_rects; i++)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
cairo_region_get_rectangle (swap_region, i, &rect);
|
||||
damage[i * 4] = rect.x;
|
||||
damage[i * 4 + 1] = rect.y;
|
||||
damage[i * 4 + 2] = rect.width;
|
||||
damage[i * 4 + 3] = rect.height;
|
||||
}
|
||||
clutter_stage_view_before_swap_buffer (view, swap_region);
|
||||
|
||||
if (cogl_is_onscreen (framebuffer))
|
||||
{
|
||||
CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
|
||||
int *damage, n_rects, i;
|
||||
|
||||
n_rects = cairo_region_num_rectangles (swap_region);
|
||||
damage = g_newa (int, n_rects * 4);
|
||||
for (i = 0; i < n_rects; i++)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
cairo_region_get_rectangle (swap_region, i, &rect);
|
||||
damage[i * 4] = rect.x;
|
||||
damage[i * 4 + 1] = rect.y;
|
||||
damage[i * 4 + 2] = rect.width;
|
||||
damage[i * 4 + 3] = rect.height;
|
||||
}
|
||||
|
||||
/* push on the screen */
|
||||
if (n_rects > 0 && !swap_with_damage)
|
||||
@@ -430,18 +416,6 @@ swap_framebuffer (ClutterStageWindow *stage_window,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
scale_and_clamp_rect (const graphene_rect_t *rect,
|
||||
float scale,
|
||||
cairo_rectangle_int_t *dest)
|
||||
|
||||
{
|
||||
graphene_rect_t tmp = *rect;
|
||||
|
||||
graphene_rect_scale (&tmp, scale, scale, &tmp);
|
||||
_clutter_util_rectangle_int_extents (&tmp, dest);
|
||||
}
|
||||
|
||||
static cairo_region_t *
|
||||
offset_scale_and_clamp_region (const cairo_region_t *region,
|
||||
int offset_x,
|
||||
@@ -463,15 +437,52 @@ offset_scale_and_clamp_region (const cairo_region_t *region,
|
||||
rects = freeme = g_new (cairo_rectangle_int_t, n_rects);
|
||||
|
||||
for (i = 0; i < n_rects; i++)
|
||||
cairo_region_get_rectangle (region, i, &rects[i]);
|
||||
{
|
||||
cairo_rectangle_int_t *rect = &rects[i];
|
||||
graphene_rect_t tmp;
|
||||
|
||||
cairo_region_get_rectangle (region, i, rect);
|
||||
|
||||
_clutter_util_rect_from_rectangle (rect, &tmp);
|
||||
graphene_rect_offset (&tmp, offset_x, offset_y);
|
||||
graphene_rect_scale (&tmp, scale, scale, &tmp);
|
||||
_clutter_util_rectangle_int_extents (&tmp, rect);
|
||||
}
|
||||
|
||||
return cairo_region_create_rectangles (rects, n_rects);
|
||||
}
|
||||
|
||||
static cairo_region_t *
|
||||
scale_offset_and_clamp_region (const cairo_region_t *region,
|
||||
float scale,
|
||||
int offset_x,
|
||||
int offset_y)
|
||||
{
|
||||
int n_rects, i;
|
||||
cairo_rectangle_int_t *rects;
|
||||
g_autofree cairo_rectangle_int_t *freeme = NULL;
|
||||
|
||||
n_rects = cairo_region_num_rectangles (region);
|
||||
|
||||
if (n_rects == 0)
|
||||
return cairo_region_create ();
|
||||
|
||||
if (n_rects < MAX_STACK_RECTS)
|
||||
rects = g_newa (cairo_rectangle_int_t, n_rects);
|
||||
else
|
||||
rects = freeme = g_new (cairo_rectangle_int_t, n_rects);
|
||||
|
||||
for (i = 0; i < n_rects; i++)
|
||||
{
|
||||
cairo_rectangle_int_t *rect = &rects[i];
|
||||
graphene_rect_t tmp;
|
||||
|
||||
_clutter_util_rect_from_rectangle (&rects[i], &tmp);
|
||||
cairo_region_get_rectangle (region, i, rect);
|
||||
|
||||
_clutter_util_rect_from_rectangle (rect, &tmp);
|
||||
graphene_rect_scale (&tmp, scale, scale, &tmp);
|
||||
graphene_rect_offset (&tmp, offset_x, offset_y);
|
||||
scale_and_clamp_rect (&tmp, scale, &rects[i]);
|
||||
_clutter_util_rectangle_int_extents (&tmp, rect);
|
||||
}
|
||||
|
||||
return cairo_region_create_rectangles (rects, n_rects);
|
||||
@@ -487,107 +498,38 @@ paint_stage (ClutterStageCogl *stage_cogl,
|
||||
_clutter_stage_maybe_setup_viewport (stage, view);
|
||||
clutter_stage_paint_view (stage, view, redraw_clip);
|
||||
|
||||
clutter_stage_view_after_paint (view);
|
||||
}
|
||||
|
||||
static void
|
||||
fill_current_damage_history (ClutterStageView *view,
|
||||
cairo_region_t *damage)
|
||||
{
|
||||
ClutterStageViewCogl *view_cogl = CLUTTER_STAGE_VIEW_COGL (view);
|
||||
ClutterStageViewCoglPrivate *view_priv =
|
||||
clutter_stage_view_cogl_get_instance_private (view_cogl);
|
||||
cairo_region_t **current_fb_damage;
|
||||
|
||||
current_fb_damage =
|
||||
&view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index)];
|
||||
|
||||
g_clear_pointer (current_fb_damage, cairo_region_destroy);
|
||||
*current_fb_damage = cairo_region_copy (damage);
|
||||
view_priv->damage_index++;
|
||||
}
|
||||
|
||||
static void
|
||||
fill_current_damage_history_rectangle (ClutterStageView *view,
|
||||
const cairo_rectangle_int_t *rect)
|
||||
{
|
||||
cairo_region_t *damage;
|
||||
|
||||
damage = cairo_region_create_rectangle (rect);
|
||||
fill_current_damage_history (view, damage);
|
||||
cairo_region_destroy (damage);
|
||||
clutter_stage_view_after_paint (view, redraw_clip);
|
||||
}
|
||||
|
||||
static cairo_region_t *
|
||||
transform_swap_region_to_onscreen (ClutterStageView *view,
|
||||
cairo_region_t *swap_region)
|
||||
{
|
||||
CoglFramebuffer *framebuffer;
|
||||
cairo_rectangle_int_t layout;
|
||||
gint width, height;
|
||||
CoglFramebuffer *onscreen = clutter_stage_view_get_onscreen (view);
|
||||
int n_rects, i;
|
||||
cairo_rectangle_int_t *rects;
|
||||
cairo_region_t *transformed_region;
|
||||
int width, height;
|
||||
|
||||
framebuffer = clutter_stage_view_get_onscreen (view);
|
||||
clutter_stage_view_get_layout (view, &layout);
|
||||
|
||||
width = cogl_framebuffer_get_width (framebuffer);
|
||||
height = cogl_framebuffer_get_height (framebuffer);
|
||||
width = cogl_framebuffer_get_width (onscreen);
|
||||
height = cogl_framebuffer_get_height (onscreen);
|
||||
|
||||
n_rects = cairo_region_num_rectangles (swap_region);
|
||||
rects = g_newa (cairo_rectangle_int_t, n_rects);
|
||||
for (i = 0; i < n_rects; i++)
|
||||
{
|
||||
gfloat x1, y1, x2, y2;
|
||||
|
||||
cairo_region_get_rectangle (swap_region, i, &rects[i]);
|
||||
|
||||
x1 = (float) rects[i].x / layout.width;
|
||||
y1 = (float) rects[i].y / layout.height;
|
||||
x2 = (float) (rects[i].x + rects[i].width) / layout.width;
|
||||
y2 = (float) (rects[i].y + rects[i].height) / layout.height;
|
||||
|
||||
clutter_stage_view_transform_to_onscreen (view, &x1, &y1);
|
||||
clutter_stage_view_transform_to_onscreen (view, &x2, &y2);
|
||||
|
||||
x1 = floor (x1 * width);
|
||||
y1 = floor (height - (y1 * height));
|
||||
x2 = ceil (x2 * width);
|
||||
y2 = ceil (height - (y2 * height));
|
||||
|
||||
rects[i].x = x1;
|
||||
rects[i].y = y1;
|
||||
rects[i].width = x2 - x1;
|
||||
rects[i].height = y2 - y1;
|
||||
clutter_stage_view_transform_rect_to_onscreen (view,
|
||||
&rects[i],
|
||||
width,
|
||||
height,
|
||||
&rects[i]);
|
||||
}
|
||||
transformed_region = cairo_region_create_rectangles (rects, n_rects);
|
||||
|
||||
return transformed_region;
|
||||
}
|
||||
|
||||
static void
|
||||
calculate_scissor_region (cairo_rectangle_int_t *fb_clip_region,
|
||||
int subpixel_compensation,
|
||||
int fb_width,
|
||||
int fb_height,
|
||||
cairo_rectangle_int_t *out_scissor_rect)
|
||||
{
|
||||
*out_scissor_rect = *fb_clip_region;
|
||||
|
||||
if (subpixel_compensation == 0)
|
||||
return;
|
||||
|
||||
if (fb_clip_region->x > 0)
|
||||
out_scissor_rect->x += subpixel_compensation;
|
||||
if (fb_clip_region->y > 0)
|
||||
out_scissor_rect->y += subpixel_compensation;
|
||||
if (fb_clip_region->x + fb_clip_region->width < fb_width)
|
||||
out_scissor_rect->width -= 2 * subpixel_compensation;
|
||||
if (fb_clip_region->y + fb_clip_region->height < fb_height)
|
||||
out_scissor_rect->height -= 2 * subpixel_compensation;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
is_buffer_age_enabled (void)
|
||||
{
|
||||
@@ -606,27 +548,21 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
ClutterStageViewCoglPrivate *view_priv =
|
||||
clutter_stage_view_cogl_get_instance_private (view_cogl);
|
||||
CoglFramebuffer *fb = clutter_stage_view_get_framebuffer (view);
|
||||
CoglFramebuffer *onscreen = clutter_stage_view_get_onscreen (view);
|
||||
cairo_rectangle_int_t view_rect;
|
||||
gboolean is_full_redraw;
|
||||
gboolean may_use_clipped_redraw;
|
||||
gboolean use_clipped_redraw;
|
||||
gboolean can_blit_sub_buffer;
|
||||
gboolean has_buffer_age;
|
||||
gboolean do_swap_buffer;
|
||||
gboolean swap_with_damage;
|
||||
ClutterActor *wrapper;
|
||||
cairo_region_t *redraw_clip;
|
||||
cairo_region_t *queued_redraw_clip = NULL;
|
||||
cairo_region_t *fb_clip_region;
|
||||
cairo_region_t *swap_region;
|
||||
cairo_rectangle_int_t redraw_rect;
|
||||
gboolean clip_region_empty;
|
||||
float fb_scale;
|
||||
int subpixel_compensation = 0;
|
||||
int fb_width, fb_height;
|
||||
int buffer_age;
|
||||
|
||||
wrapper = CLUTTER_ACTOR (stage_cogl->wrapper);
|
||||
gboolean res;
|
||||
|
||||
clutter_stage_view_get_layout (view, &view_rect);
|
||||
fb_scale = clutter_stage_view_get_scale (view);
|
||||
@@ -634,10 +570,10 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
fb_height = cogl_framebuffer_get_height (fb);
|
||||
|
||||
can_blit_sub_buffer =
|
||||
cogl_is_onscreen (fb) &&
|
||||
cogl_is_onscreen (onscreen) &&
|
||||
cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_REGION);
|
||||
|
||||
has_buffer_age = cogl_is_onscreen (fb) && is_buffer_age_enabled ();
|
||||
has_buffer_age = cogl_is_onscreen (onscreen) && is_buffer_age_enabled ();
|
||||
|
||||
redraw_clip = clutter_stage_view_take_redraw_clip (view);
|
||||
if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION))
|
||||
@@ -649,51 +585,35 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
else
|
||||
is_full_redraw = FALSE;
|
||||
|
||||
may_use_clipped_redraw =
|
||||
if (has_buffer_age)
|
||||
{
|
||||
buffer_age = cogl_onscreen_get_buffer_age (COGL_ONSCREEN (onscreen));
|
||||
if (!clutter_damage_history_is_age_valid (view_priv->damage_history,
|
||||
buffer_age))
|
||||
{
|
||||
CLUTTER_NOTE (CLIPPING,
|
||||
"Invalid back buffer(age=%d): forcing full redraw\n",
|
||||
buffer_age);
|
||||
use_clipped_redraw = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
use_clipped_redraw =
|
||||
use_clipped_redraw &&
|
||||
!(clutter_paint_debug_flags & CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS) &&
|
||||
_clutter_stage_window_can_clip_redraws (stage_window) &&
|
||||
(can_blit_sub_buffer || has_buffer_age) &&
|
||||
!is_full_redraw &&
|
||||
/* some drivers struggle to get going and produce some junk
|
||||
* frames when starting up... */
|
||||
cogl_onscreen_get_frame_counter (COGL_ONSCREEN (fb)) > 3;
|
||||
cogl_onscreen_get_frame_counter (COGL_ONSCREEN (onscreen)) > 3;
|
||||
|
||||
if (has_buffer_age)
|
||||
{
|
||||
buffer_age = cogl_onscreen_get_buffer_age (COGL_ONSCREEN (fb));
|
||||
if (!valid_buffer_age (view_cogl, buffer_age))
|
||||
{
|
||||
CLUTTER_NOTE (CLIPPING, "Invalid back buffer(age=%d): forcing full redraw\n", buffer_age);
|
||||
may_use_clipped_redraw = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (may_use_clipped_redraw)
|
||||
if (use_clipped_redraw)
|
||||
{
|
||||
fb_clip_region = offset_scale_and_clamp_region (redraw_clip,
|
||||
-view_rect.x,
|
||||
-view_rect.y,
|
||||
fb_scale);
|
||||
|
||||
if (fb_scale != floorf (fb_scale))
|
||||
{
|
||||
int n_rects, i;
|
||||
cairo_rectangle_int_t *rects;
|
||||
|
||||
subpixel_compensation = ceilf (fb_scale);
|
||||
|
||||
n_rects = cairo_region_num_rectangles (fb_clip_region);
|
||||
rects = g_newa (cairo_rectangle_int_t, n_rects);
|
||||
for (i = 0; i < n_rects; i++)
|
||||
{
|
||||
cairo_region_get_rectangle (fb_clip_region, i, &rects[i]);
|
||||
rects[i].x -= subpixel_compensation;
|
||||
rects[i].y -= subpixel_compensation;
|
||||
rects[i].width += 2 * subpixel_compensation;
|
||||
rects[i].height += 2 * subpixel_compensation;
|
||||
}
|
||||
cairo_region_destroy (fb_clip_region);
|
||||
fb_clip_region = cairo_region_create_rectangles (rects, n_rects);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -709,46 +629,40 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
redraw_clip = cairo_region_create_rectangle (&view_rect);
|
||||
}
|
||||
|
||||
if (may_use_clipped_redraw &&
|
||||
G_LIKELY (!(clutter_paint_debug_flags & CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS)))
|
||||
use_clipped_redraw = TRUE;
|
||||
else
|
||||
use_clipped_redraw = FALSE;
|
||||
|
||||
clip_region_empty = may_use_clipped_redraw && cairo_region_is_empty (fb_clip_region);
|
||||
g_return_val_if_fail (!cairo_region_is_empty (fb_clip_region), FALSE);
|
||||
|
||||
swap_with_damage = FALSE;
|
||||
if (has_buffer_age)
|
||||
{
|
||||
if (use_clipped_redraw && !clip_region_empty)
|
||||
clutter_damage_history_record (view_priv->damage_history,
|
||||
fb_clip_region);
|
||||
|
||||
if (use_clipped_redraw)
|
||||
{
|
||||
cairo_region_t *fb_damage;
|
||||
cairo_region_t *view_damage;
|
||||
int i;
|
||||
|
||||
fill_current_damage_history (view, fb_clip_region);
|
||||
int age;
|
||||
|
||||
fb_damage = cairo_region_create ();
|
||||
|
||||
for (i = 1; i <= buffer_age; i++)
|
||||
for (age = 1; age <= buffer_age; age++)
|
||||
{
|
||||
int damage_index;
|
||||
const cairo_region_t *old_damage;
|
||||
|
||||
damage_index = DAMAGE_HISTORY (view_priv->damage_index - i - 1);
|
||||
cairo_region_union (fb_damage,
|
||||
view_priv->damage_history[damage_index]);
|
||||
old_damage =
|
||||
clutter_damage_history_lookup (view_priv->damage_history, age);
|
||||
cairo_region_union (fb_damage, old_damage);
|
||||
}
|
||||
|
||||
/* Update the fb clip region with the extra damage. */
|
||||
cairo_region_union (fb_clip_region, fb_damage);
|
||||
|
||||
view_damage = offset_scale_and_clamp_region (fb_damage,
|
||||
0, 0,
|
||||
1.0f / fb_scale);
|
||||
cairo_region_translate (view_damage, view_rect.x, view_rect.y);
|
||||
cairo_region_intersect_rectangle (view_damage, &view_rect);
|
||||
/* Update the redraw clip with the extra damage done to the view */
|
||||
view_damage = scale_offset_and_clamp_region (fb_damage,
|
||||
1.0f / fb_scale,
|
||||
view_rect.x,
|
||||
view_rect.y);
|
||||
|
||||
/* Update the redraw clip region with the extra damage. */
|
||||
cairo_region_union (redraw_clip, view_damage);
|
||||
|
||||
cairo_region_destroy (view_damage);
|
||||
@@ -760,55 +674,13 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
|
||||
swap_with_damage = TRUE;
|
||||
}
|
||||
else if (!use_clipped_redraw)
|
||||
{
|
||||
cairo_rectangle_int_t fb_damage;
|
||||
|
||||
fb_damage = (cairo_rectangle_int_t) {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = ceilf (view_rect.width * fb_scale),
|
||||
.height = ceilf (view_rect.height * fb_scale)
|
||||
};
|
||||
fill_current_damage_history_rectangle (view, &fb_damage);
|
||||
}
|
||||
clutter_damage_history_step (view_priv->damage_history);
|
||||
}
|
||||
|
||||
if (use_clipped_redraw && clip_region_empty)
|
||||
if (use_clipped_redraw)
|
||||
{
|
||||
CLUTTER_NOTE (CLIPPING, "Empty stage output paint\n");
|
||||
}
|
||||
else if (use_clipped_redraw)
|
||||
{
|
||||
cairo_rectangle_int_t clip_rect;
|
||||
cairo_rectangle_int_t scissor_rect;
|
||||
|
||||
if (cairo_region_num_rectangles (fb_clip_region) == 1)
|
||||
{
|
||||
cairo_region_get_extents (fb_clip_region, &clip_rect);
|
||||
|
||||
calculate_scissor_region (&clip_rect,
|
||||
subpixel_compensation,
|
||||
fb_width, fb_height,
|
||||
&scissor_rect);
|
||||
|
||||
CLUTTER_NOTE (CLIPPING,
|
||||
"Stage clip pushed: x=%d, y=%d, width=%d, height=%d\n",
|
||||
scissor_rect.x,
|
||||
scissor_rect.y,
|
||||
scissor_rect.width,
|
||||
scissor_rect.height);
|
||||
|
||||
cogl_framebuffer_push_scissor_clip (fb,
|
||||
scissor_rect.x,
|
||||
scissor_rect.y,
|
||||
scissor_rect.width,
|
||||
scissor_rect.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
cogl_framebuffer_push_region_clip (fb, fb_clip_region);
|
||||
}
|
||||
cogl_framebuffer_push_region_clip (fb, fb_clip_region);
|
||||
|
||||
paint_stage (stage_cogl, view, redraw_clip);
|
||||
|
||||
@@ -818,77 +690,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
{
|
||||
CLUTTER_NOTE (CLIPPING, "Unclipped stage paint\n");
|
||||
|
||||
/* If we are trying to debug redraw issues then we want to pass
|
||||
* the redraw_clip so it can be visualized */
|
||||
if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS) &&
|
||||
may_use_clipped_redraw &&
|
||||
!clip_region_empty)
|
||||
{
|
||||
cairo_rectangle_int_t clip_rect;
|
||||
cairo_rectangle_int_t scissor_rect;
|
||||
|
||||
cairo_region_get_extents (fb_clip_region, &clip_rect);
|
||||
|
||||
calculate_scissor_region (&clip_rect,
|
||||
subpixel_compensation,
|
||||
fb_width, fb_height,
|
||||
&scissor_rect);
|
||||
|
||||
cogl_framebuffer_push_scissor_clip (fb,
|
||||
scissor_rect.x,
|
||||
scissor_rect.y,
|
||||
scissor_rect.width,
|
||||
scissor_rect.height);
|
||||
|
||||
paint_stage (stage_cogl, view, redraw_clip);
|
||||
|
||||
cogl_framebuffer_pop_clip (fb);
|
||||
}
|
||||
else
|
||||
{
|
||||
paint_stage (stage_cogl, view, redraw_clip);
|
||||
}
|
||||
}
|
||||
|
||||
cairo_region_get_extents (redraw_clip, &redraw_rect);
|
||||
|
||||
if (may_use_clipped_redraw &&
|
||||
G_UNLIKELY ((clutter_paint_debug_flags & CLUTTER_DEBUG_REDRAWS)))
|
||||
{
|
||||
CoglContext *ctx = cogl_framebuffer_get_context (fb);
|
||||
static CoglPipeline *outline = NULL;
|
||||
ClutterActor *actor = CLUTTER_ACTOR (wrapper);
|
||||
float x_1 = redraw_rect.x;
|
||||
float x_2 = redraw_rect.x + redraw_rect.width;
|
||||
float y_1 = redraw_rect.y;
|
||||
float y_2 = redraw_rect.y + redraw_rect.height;
|
||||
CoglVertexP2 quad[4] = {
|
||||
{ x_1, y_1 },
|
||||
{ x_2, y_1 },
|
||||
{ x_2, y_2 },
|
||||
{ x_1, y_2 }
|
||||
};
|
||||
CoglPrimitive *prim;
|
||||
CoglMatrix modelview;
|
||||
|
||||
if (outline == NULL)
|
||||
{
|
||||
outline = cogl_pipeline_new (ctx);
|
||||
cogl_pipeline_set_color4ub (outline, 0xff, 0x00, 0x00, 0xff);
|
||||
}
|
||||
|
||||
prim = cogl_primitive_new_p2 (ctx,
|
||||
COGL_VERTICES_MODE_LINE_LOOP,
|
||||
4, /* n_vertices */
|
||||
quad);
|
||||
|
||||
cogl_framebuffer_push_matrix (fb);
|
||||
cogl_matrix_init_identity (&modelview);
|
||||
_clutter_actor_apply_modelview_transform (actor, &modelview);
|
||||
cogl_framebuffer_set_modelview_matrix (fb, &modelview);
|
||||
cogl_framebuffer_draw_primitive (fb, outline, prim);
|
||||
cogl_framebuffer_pop_matrix (fb);
|
||||
cogl_object_unref (prim);
|
||||
paint_stage (stage_cogl, view, redraw_clip);
|
||||
}
|
||||
|
||||
/* XXX: It seems there will be a race here in that the stage
|
||||
@@ -900,65 +702,42 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
* artefacts.
|
||||
*/
|
||||
if (use_clipped_redraw)
|
||||
{
|
||||
if (clip_region_empty)
|
||||
{
|
||||
do_swap_buffer = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
swap_region = cairo_region_copy (fb_clip_region);
|
||||
do_swap_buffer = TRUE;
|
||||
}
|
||||
}
|
||||
swap_region = cairo_region_copy (fb_clip_region);
|
||||
else
|
||||
{
|
||||
swap_region = cairo_region_create ();
|
||||
do_swap_buffer = TRUE;
|
||||
}
|
||||
swap_region = cairo_region_create ();
|
||||
|
||||
g_clear_pointer (&redraw_clip, cairo_region_destroy);
|
||||
g_clear_pointer (&fb_clip_region, cairo_region_destroy);
|
||||
|
||||
if (do_swap_buffer)
|
||||
COGL_TRACE_BEGIN_SCOPED (ClutterStageCoglRedrawViewSwapFramebuffer,
|
||||
"Paint (swap framebuffer)");
|
||||
|
||||
if (clutter_stage_view_get_onscreen (view) !=
|
||||
clutter_stage_view_get_framebuffer (view))
|
||||
{
|
||||
gboolean res;
|
||||
|
||||
COGL_TRACE_BEGIN_SCOPED (ClutterStageCoglRedrawViewSwapFramebuffer,
|
||||
"Paint (swap framebuffer)");
|
||||
|
||||
if (clutter_stage_view_get_onscreen (view) !=
|
||||
clutter_stage_view_get_framebuffer (view))
|
||||
{
|
||||
cairo_region_t *transformed_swap_region;
|
||||
|
||||
transformed_swap_region =
|
||||
transform_swap_region_to_onscreen (view, swap_region);
|
||||
cairo_region_destroy (swap_region);
|
||||
swap_region = transformed_swap_region;
|
||||
}
|
||||
|
||||
if (queued_redraw_clip)
|
||||
{
|
||||
paint_damage_region (stage_window, view,
|
||||
swap_region, queued_redraw_clip);
|
||||
cairo_region_destroy (queued_redraw_clip);
|
||||
}
|
||||
|
||||
res = swap_framebuffer (stage_window,
|
||||
view,
|
||||
swap_region,
|
||||
swap_with_damage);
|
||||
cairo_region_t *transformed_swap_region;
|
||||
|
||||
transformed_swap_region =
|
||||
transform_swap_region_to_onscreen (view, swap_region);
|
||||
cairo_region_destroy (swap_region);
|
||||
swap_region = transformed_swap_region;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
else
|
||||
if (queued_redraw_clip)
|
||||
{
|
||||
g_clear_pointer (&queued_redraw_clip, cairo_region_destroy);
|
||||
return FALSE;
|
||||
paint_damage_region (stage_window, view,
|
||||
swap_region, queued_redraw_clip);
|
||||
cairo_region_destroy (queued_redraw_clip);
|
||||
}
|
||||
|
||||
res = swap_framebuffer (stage_window,
|
||||
view,
|
||||
swap_region,
|
||||
swap_with_damage);
|
||||
|
||||
cairo_region_destroy (swap_region);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1083,12 +862,31 @@ _clutter_stage_cogl_init (ClutterStageCogl *stage)
|
||||
stage->update_time = -1;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_view_cogl_finalize (GObject *object)
|
||||
{
|
||||
ClutterStageViewCogl *view_cogl = CLUTTER_STAGE_VIEW_COGL (object);
|
||||
ClutterStageViewCoglPrivate *view_priv =
|
||||
clutter_stage_view_cogl_get_instance_private (view_cogl);
|
||||
|
||||
clutter_damage_history_free (view_priv->damage_history);
|
||||
|
||||
G_OBJECT_CLASS (clutter_stage_view_cogl_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_view_cogl_init (ClutterStageViewCogl *view_cogl)
|
||||
{
|
||||
ClutterStageViewCoglPrivate *view_priv =
|
||||
clutter_stage_view_cogl_get_instance_private (view_cogl);
|
||||
|
||||
view_priv->damage_history = clutter_damage_history_new ();
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_view_cogl_class_init (ClutterStageViewCoglClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = clutter_stage_view_cogl_finalize;
|
||||
}
|
||||
|
@@ -333,21 +333,20 @@ clutter_group_real_get_preferred_height (ClutterActor *actor,
|
||||
|
||||
static void
|
||||
clutter_group_real_allocate (ClutterActor *actor,
|
||||
const ClutterActorBox *allocation,
|
||||
ClutterAllocationFlags flags)
|
||||
const ClutterActorBox *allocation)
|
||||
{
|
||||
ClutterGroupPrivate *priv = CLUTTER_GROUP (actor)->priv;
|
||||
ClutterActorClass *klass;
|
||||
|
||||
klass = CLUTTER_ACTOR_CLASS (clutter_group_parent_class);
|
||||
klass->allocate (actor, allocation, flags);
|
||||
klass->allocate (actor, allocation);
|
||||
|
||||
if (priv->children == NULL)
|
||||
return;
|
||||
|
||||
clutter_layout_manager_allocate (priv->layout,
|
||||
CLUTTER_CONTAINER (actor),
|
||||
allocation, flags);
|
||||
allocation);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -114,6 +114,7 @@ clutter_sources = [
|
||||
'clutter-constraint.c',
|
||||
'clutter-container.c',
|
||||
'clutter-content.c',
|
||||
'clutter-damage-history.c',
|
||||
'clutter-deform-effect.c',
|
||||
'clutter-desaturate-effect.c',
|
||||
'clutter-effect.c',
|
||||
@@ -185,6 +186,7 @@ clutter_private_headers = [
|
||||
'clutter-bezier.h',
|
||||
'clutter-constraint-private.h',
|
||||
'clutter-content-private.h',
|
||||
'clutter-damage-history.h',
|
||||
'clutter-debug.h',
|
||||
'clutter-easing.h',
|
||||
'clutter-effect-private.h',
|
||||
|
@@ -158,7 +158,7 @@ _cogl_blit_framebuffer_begin (CoglBlitData *data)
|
||||
supported. */
|
||||
if ((_cogl_texture_get_format (data->src_tex) & COGL_PREMULT_BIT) !=
|
||||
(_cogl_texture_get_format (data->dst_tex) & COGL_PREMULT_BIT) ||
|
||||
!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER))
|
||||
!cogl_has_feature (ctx, COGL_FEATURE_ID_BLIT_FRAMEBUFFER))
|
||||
return FALSE;
|
||||
|
||||
dst_offscreen = _cogl_offscreen_new_with_texture_full
|
||||
|
@@ -193,6 +193,8 @@ cogl_is_context (void *object);
|
||||
* expected to return age values other than 0.
|
||||
* @COGL_FEATURE_ID_PRESENTATION_TIME: Whether frame presentation
|
||||
* time stamps will be recorded in #CoglFrameInfo objects.
|
||||
* @COGL_FEATURE_ID_BLIT_FRAMEBUFFER: Whether blitting using
|
||||
* cogl_blit_framebuffer() is supported.
|
||||
*
|
||||
* All the capabilities that can vary between different GPUs supported
|
||||
* by Cogl. Applications that depend on any of these features should explicitly
|
||||
@@ -211,6 +213,7 @@ typedef enum _CoglFeatureID
|
||||
COGL_FEATURE_ID_TEXTURE_RG,
|
||||
COGL_FEATURE_ID_BUFFER_AGE,
|
||||
COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL,
|
||||
COGL_FEATURE_ID_BLIT_FRAMEBUFFER,
|
||||
|
||||
/*< private >*/
|
||||
_COGL_N_FEATURE_IDS /*< skip >*/
|
||||
|
@@ -34,12 +34,22 @@
|
||||
#include "cogl-dma-buf-handle.h"
|
||||
#include "cogl-object.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <gio/gio.h>
|
||||
#include <linux/dma-buf.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
|
||||
struct _CoglDmaBufHandle
|
||||
{
|
||||
CoglFramebuffer *framebuffer;
|
||||
int dmabuf_fd;
|
||||
int width;
|
||||
int height;
|
||||
int stride;
|
||||
int offset;
|
||||
int bpp;
|
||||
gpointer user_data;
|
||||
GDestroyNotify destroy_func;
|
||||
};
|
||||
@@ -47,6 +57,11 @@ struct _CoglDmaBufHandle
|
||||
CoglDmaBufHandle *
|
||||
cogl_dma_buf_handle_new (CoglFramebuffer *framebuffer,
|
||||
int dmabuf_fd,
|
||||
int width,
|
||||
int height,
|
||||
int stride,
|
||||
int offset,
|
||||
int bpp,
|
||||
gpointer user_data,
|
||||
GDestroyNotify destroy_func)
|
||||
{
|
||||
@@ -61,6 +76,12 @@ cogl_dma_buf_handle_new (CoglFramebuffer *framebuffer,
|
||||
dmabuf_handle->user_data = user_data;
|
||||
dmabuf_handle->destroy_func = destroy_func;
|
||||
|
||||
dmabuf_handle->width = width;
|
||||
dmabuf_handle->height = height;
|
||||
dmabuf_handle->stride = stride;
|
||||
dmabuf_handle->offset = offset;
|
||||
dmabuf_handle->bpp = bpp;
|
||||
|
||||
return dmabuf_handle;
|
||||
}
|
||||
|
||||
@@ -80,6 +101,93 @@ cogl_dma_buf_handle_free (CoglDmaBufHandle *dmabuf_handle)
|
||||
g_free (dmabuf_handle);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
sync_read (CoglDmaBufHandle *dmabuf_handle,
|
||||
uint64_t start_or_end,
|
||||
GError **error)
|
||||
{
|
||||
struct dma_buf_sync sync = { 0 };
|
||||
|
||||
sync.flags = start_or_end | DMA_BUF_SYNC_READ;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ioctl (dmabuf_handle->dmabuf_fd, DMA_BUF_IOCTL_SYNC, &sync);
|
||||
if (ret == -1 && errno == EINTR)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (ret == -1)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
|
||||
"ioctl: %s", g_strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
cogl_dma_buf_handle_sync_read_start (CoglDmaBufHandle *dmabuf_handle,
|
||||
GError **error)
|
||||
{
|
||||
return sync_read (dmabuf_handle, DMA_BUF_SYNC_START, error);
|
||||
}
|
||||
|
||||
gboolean
|
||||
cogl_dma_buf_handle_sync_read_end (CoglDmaBufHandle *dmabuf_handle,
|
||||
GError **error)
|
||||
{
|
||||
return sync_read (dmabuf_handle, DMA_BUF_SYNC_END, error);
|
||||
}
|
||||
|
||||
gpointer
|
||||
cogl_dma_buf_handle_mmap (CoglDmaBufHandle *dmabuf_handle,
|
||||
GError **error)
|
||||
{
|
||||
size_t size;
|
||||
gpointer data;
|
||||
|
||||
size = dmabuf_handle->height * dmabuf_handle->stride;
|
||||
|
||||
data = mmap (NULL, size, PROT_READ, MAP_PRIVATE,
|
||||
dmabuf_handle->dmabuf_fd,
|
||||
dmabuf_handle->offset);
|
||||
if (data == MAP_FAILED)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
|
||||
"mmap failed: %s", g_strerror (errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
gboolean
|
||||
cogl_dma_buf_handle_munmap (CoglDmaBufHandle *dmabuf_handle,
|
||||
gpointer data,
|
||||
GError **error)
|
||||
{
|
||||
size_t size;
|
||||
|
||||
size = dmabuf_handle->height * dmabuf_handle->stride;
|
||||
if (munmap (data, size) != 0)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
|
||||
"munmap failed: %s", g_strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
CoglFramebuffer *
|
||||
cogl_dma_buf_handle_get_framebuffer (CoglDmaBufHandle *dmabuf_handle)
|
||||
{
|
||||
@@ -92,3 +200,32 @@ cogl_dma_buf_handle_get_fd (CoglDmaBufHandle *dmabuf_handle)
|
||||
return dmabuf_handle->dmabuf_fd;
|
||||
}
|
||||
|
||||
int
|
||||
cogl_dma_buf_handle_get_width (CoglDmaBufHandle *dmabuf_handle)
|
||||
{
|
||||
return dmabuf_handle->width;
|
||||
}
|
||||
|
||||
int
|
||||
cogl_dma_buf_handle_get_height (CoglDmaBufHandle *dmabuf_handle)
|
||||
{
|
||||
return dmabuf_handle->height;
|
||||
}
|
||||
|
||||
int
|
||||
cogl_dma_buf_handle_get_stride (CoglDmaBufHandle *dmabuf_handle)
|
||||
{
|
||||
return dmabuf_handle->stride;
|
||||
}
|
||||
|
||||
int
|
||||
cogl_dma_buf_handle_get_offset (CoglDmaBufHandle *dmabuf_handle)
|
||||
{
|
||||
return dmabuf_handle->offset;
|
||||
}
|
||||
|
||||
int
|
||||
cogl_dma_buf_handle_get_bpp (CoglDmaBufHandle *dmabuf_handle)
|
||||
{
|
||||
return dmabuf_handle->bpp;
|
||||
}
|
||||
|
@@ -46,7 +46,12 @@
|
||||
COGL_EXPORT CoglDmaBufHandle *
|
||||
cogl_dma_buf_handle_new (CoglFramebuffer *framebuffer,
|
||||
int dmabuf_fd,
|
||||
gpointer data,
|
||||
int width,
|
||||
int height,
|
||||
int stride,
|
||||
int offset,
|
||||
int bpp,
|
||||
gpointer user_data,
|
||||
GDestroyNotify destroy_func);
|
||||
|
||||
/**
|
||||
@@ -58,6 +63,23 @@ cogl_dma_buf_handle_new (CoglFramebuffer *framebuffer,
|
||||
COGL_EXPORT void
|
||||
cogl_dma_buf_handle_free (CoglDmaBufHandle *dmabuf_handle);
|
||||
|
||||
COGL_EXPORT gboolean
|
||||
cogl_dma_buf_handle_sync_read_start (CoglDmaBufHandle *dmabuf_handle,
|
||||
GError **error);
|
||||
|
||||
COGL_EXPORT gboolean
|
||||
cogl_dma_buf_handle_sync_read_end (CoglDmaBufHandle *dmabuf_handle,
|
||||
GError **error);
|
||||
|
||||
COGL_EXPORT gpointer
|
||||
cogl_dma_buf_handle_mmap (CoglDmaBufHandle *dmabuf_handle,
|
||||
GError **error);
|
||||
|
||||
COGL_EXPORT gboolean
|
||||
cogl_dma_buf_handle_munmap (CoglDmaBufHandle *dmabuf_handle,
|
||||
gpointer data,
|
||||
GError **error);
|
||||
|
||||
/**
|
||||
* cogl_dma_buf_handle_get_framebuffer: (skip)
|
||||
*
|
||||
@@ -79,5 +101,44 @@ cogl_dma_buf_handle_get_framebuffer (CoglDmaBufHandle *dmabuf_handle);
|
||||
COGL_EXPORT int
|
||||
cogl_dma_buf_handle_get_fd (CoglDmaBufHandle *dmabuf_handle);
|
||||
|
||||
/**
|
||||
* cogl_dmabuf_handle_get_width: (skip)
|
||||
*
|
||||
* Returns: the buffer width
|
||||
*/
|
||||
COGL_EXPORT int
|
||||
cogl_dma_buf_handle_get_width (CoglDmaBufHandle *dmabuf_handle);
|
||||
|
||||
/**
|
||||
* cogl_dmabuf_handle_get_height: (skip)
|
||||
*
|
||||
* Returns: the buffer height
|
||||
*/
|
||||
COGL_EXPORT int
|
||||
cogl_dma_buf_handle_get_height (CoglDmaBufHandle *dmabuf_handle);
|
||||
|
||||
/**
|
||||
* cogl_dmabuf_handle_get_stride: (skip)
|
||||
*
|
||||
* Returns: the buffer stride
|
||||
*/
|
||||
COGL_EXPORT int
|
||||
cogl_dma_buf_handle_get_stride (CoglDmaBufHandle *dmabuf_handle);
|
||||
|
||||
/**
|
||||
* cogl_dmabuf_handle_get_offset: (skip)
|
||||
*
|
||||
* Returns: the buffer offset
|
||||
*/
|
||||
COGL_EXPORT int
|
||||
cogl_dma_buf_handle_get_offset (CoglDmaBufHandle *dmabuf_handle);
|
||||
|
||||
/**
|
||||
* cogl_dmabuf_handle_get_bpp: (skip)
|
||||
*
|
||||
* Returns: the number of bytes per pixel
|
||||
*/
|
||||
COGL_EXPORT int
|
||||
cogl_dma_buf_handle_get_bpp (CoglDmaBufHandle *dmabuf_handle);
|
||||
|
||||
#endif /* __COGL_DMA_BUF_HANDLE_H__ */
|
||||
|
@@ -1292,7 +1292,7 @@ cogl_blit_framebuffer (CoglFramebuffer *src,
|
||||
int src_x1, src_y1, src_x2, src_y2;
|
||||
int dst_x1, dst_y1, dst_x2, dst_y2;
|
||||
|
||||
if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER))
|
||||
if (!cogl_has_feature (ctx, COGL_FEATURE_ID_BLIT_FRAMEBUFFER))
|
||||
{
|
||||
g_set_error_literal (error, COGL_SYSTEM_ERROR,
|
||||
COGL_SYSTEM_ERROR_UNSUPPORTED,
|
||||
|
@@ -1509,7 +1509,7 @@ cogl_is_framebuffer (void *object);
|
||||
*
|
||||
* This blits a region of the color buffer of the source buffer
|
||||
* to the destination buffer. This function should only be
|
||||
* called if the COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER feature is
|
||||
* called if the COGL_FEATURE_ID_BLIT_FRAMEBUFFER feature is
|
||||
* advertised.
|
||||
*
|
||||
* The source and destination rectangles are defined in offscreen
|
||||
|
@@ -1361,6 +1361,17 @@ cogl_pipeline_set_layer_filters (CoglPipeline *pipeline,
|
||||
sampler_state);
|
||||
}
|
||||
|
||||
void
|
||||
cogl_pipeline_set_layer_max_mipmap_level (CoglPipeline *pipeline,
|
||||
int layer,
|
||||
int max_level)
|
||||
{
|
||||
CoglTexture *texture = cogl_pipeline_get_layer_texture (pipeline, layer);
|
||||
|
||||
if (texture != NULL)
|
||||
cogl_texture_set_max_level (texture, max_level);
|
||||
}
|
||||
|
||||
const CoglSamplerCacheEntry *
|
||||
_cogl_pipeline_layer_get_sampler_state (CoglPipelineLayer *layer)
|
||||
{
|
||||
|
@@ -568,6 +568,11 @@ cogl_pipeline_add_layer_snippet (CoglPipeline *pipeline,
|
||||
int layer,
|
||||
CoglSnippet *snippet);
|
||||
|
||||
COGL_EXPORT void
|
||||
cogl_pipeline_set_layer_max_mipmap_level (CoglPipeline *pipeline,
|
||||
int layer,
|
||||
int max_level);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __COGL_PIPELINE_LAYER_STATE_H__ */
|
||||
|
@@ -42,7 +42,6 @@ typedef enum
|
||||
{
|
||||
COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE,
|
||||
COGL_PRIVATE_FEATURE_MESA_PACK_INVERT,
|
||||
COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER,
|
||||
COGL_PRIVATE_FEATURE_PBOS,
|
||||
COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL,
|
||||
COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL,
|
||||
|
@@ -204,7 +204,8 @@ struct _CoglTexture
|
||||
CoglContext *context;
|
||||
CoglTextureLoader *loader;
|
||||
GList *framebuffers;
|
||||
int max_level;
|
||||
int max_level_set;
|
||||
int max_level_requested;
|
||||
int width;
|
||||
int height;
|
||||
gboolean allocated;
|
||||
@@ -377,6 +378,10 @@ _cogl_texture_needs_premult_conversion (CoglPixelFormat src_format,
|
||||
int
|
||||
_cogl_texture_get_n_levels (CoglTexture *texture);
|
||||
|
||||
void
|
||||
cogl_texture_set_max_level (CoglTexture *texture,
|
||||
int max_level);
|
||||
|
||||
void
|
||||
_cogl_texture_get_level_size (CoglTexture *texture,
|
||||
int level,
|
||||
|
@@ -115,7 +115,8 @@ _cogl_texture_init (CoglTexture *texture,
|
||||
const CoglTextureVtable *vtable)
|
||||
{
|
||||
texture->context = context;
|
||||
texture->max_level = 0;
|
||||
texture->max_level_set = 0;
|
||||
texture->max_level_requested = 1000; /* OpenGL default GL_TEXTURE_MAX_LEVEL */
|
||||
texture->width = width;
|
||||
texture->height = height;
|
||||
texture->allocated = FALSE;
|
||||
@@ -229,8 +230,16 @@ _cogl_texture_get_n_levels (CoglTexture *texture)
|
||||
int width = cogl_texture_get_width (texture);
|
||||
int height = cogl_texture_get_height (texture);
|
||||
int max_dimension = MAX (width, height);
|
||||
int n_levels = _cogl_util_fls (max_dimension);
|
||||
|
||||
return _cogl_util_fls (max_dimension);
|
||||
return MIN (n_levels, texture->max_level_requested + 1);
|
||||
}
|
||||
|
||||
void
|
||||
cogl_texture_set_max_level (CoglTexture *texture,
|
||||
int max_level)
|
||||
{
|
||||
texture->max_level_requested = max_level;
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -388,8 +388,8 @@ _cogl_framebuffer_gl_flush_state (CoglFramebuffer *draw_buffer,
|
||||
{
|
||||
/* NB: Currently we only take advantage of binding separate
|
||||
* read/write buffers for framebuffer blit purposes. */
|
||||
g_return_if_fail (_cogl_has_private_feature
|
||||
(ctx, COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER));
|
||||
g_return_if_fail (cogl_has_feature
|
||||
(ctx, COGL_FEATURE_ID_BLIT_FRAMEBUFFER));
|
||||
|
||||
_cogl_framebuffer_gl_bind (draw_buffer, GL_DRAW_FRAMEBUFFER);
|
||||
_cogl_framebuffer_gl_bind (read_buffer, GL_READ_FRAMEBUFFER);
|
||||
|
@@ -567,6 +567,9 @@ _cogl_texture_2d_gl_copy_from_bitmap (CoglTexture2D *tex_2d,
|
||||
&gl_format,
|
||||
&gl_type);
|
||||
|
||||
if (tex->max_level_set < level)
|
||||
cogl_texture_gl_set_max_level (tex, level);
|
||||
|
||||
status = ctx->texture_driver->upload_subregion_to_gl (ctx,
|
||||
tex,
|
||||
src_x, src_y,
|
||||
@@ -580,8 +583,6 @@ _cogl_texture_2d_gl_copy_from_bitmap (CoglTexture2D *tex_2d,
|
||||
|
||||
cogl_object_unref (upload_bmp);
|
||||
|
||||
_cogl_texture_gl_maybe_update_max_level (tex, level);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@@ -53,8 +53,8 @@ _cogl_texture_gl_flush_legacy_texobj_filters (CoglTexture *texture,
|
||||
unsigned int mag_filter);
|
||||
|
||||
void
|
||||
_cogl_texture_gl_maybe_update_max_level (CoglTexture *texture,
|
||||
int max_level);
|
||||
cogl_texture_gl_set_max_level (CoglTexture *texture,
|
||||
int max_level);
|
||||
|
||||
void
|
||||
_cogl_texture_gl_generate_mipmaps (CoglTexture *texture);
|
||||
|
@@ -97,32 +97,36 @@ _cogl_texture_gl_flush_legacy_texobj_filters (CoglTexture *texture,
|
||||
min_filter, mag_filter);
|
||||
}
|
||||
|
||||
/* GL and GLES3 have this by default, but GLES2 does not except via extension.
|
||||
* So really it's probably always available. Even if we used it and it wasn't
|
||||
* available in some driver then there are no adverse consequences to the
|
||||
* command simply being ignored...
|
||||
*/
|
||||
#ifndef GL_TEXTURE_MAX_LEVEL
|
||||
#define GL_TEXTURE_MAX_LEVEL 0x813D
|
||||
#endif
|
||||
|
||||
void
|
||||
_cogl_texture_gl_maybe_update_max_level (CoglTexture *texture,
|
||||
int max_level)
|
||||
cogl_texture_gl_set_max_level (CoglTexture *texture,
|
||||
int max_level)
|
||||
{
|
||||
/* This isn't supported on GLES */
|
||||
#ifdef HAVE_COGL_GL
|
||||
CoglContext *ctx = texture->context;
|
||||
|
||||
if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL) &&
|
||||
texture->max_level < max_level)
|
||||
if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL))
|
||||
{
|
||||
CoglContext *ctx = texture->context;
|
||||
GLuint gl_handle;
|
||||
GLenum gl_target;
|
||||
|
||||
cogl_texture_get_gl_texture (texture, &gl_handle, &gl_target);
|
||||
|
||||
texture->max_level = max_level;
|
||||
texture->max_level_set = max_level;
|
||||
|
||||
_cogl_bind_gl_texture_transient (gl_target,
|
||||
gl_handle);
|
||||
|
||||
GE( ctx, glTexParameteri (gl_target,
|
||||
GL_TEXTURE_MAX_LEVEL, texture->max_level));
|
||||
GL_TEXTURE_MAX_LEVEL, texture->max_level_set));
|
||||
}
|
||||
#endif /* HAVE_COGL_GL */
|
||||
}
|
||||
|
||||
void
|
||||
@@ -133,7 +137,8 @@ _cogl_texture_gl_generate_mipmaps (CoglTexture *texture)
|
||||
GLuint gl_handle;
|
||||
GLenum gl_target;
|
||||
|
||||
_cogl_texture_gl_maybe_update_max_level (texture, n_levels - 1);
|
||||
if (texture->max_level_set != n_levels - 1)
|
||||
cogl_texture_gl_set_max_level (texture, n_levels - 1);
|
||||
|
||||
cogl_texture_get_gl_texture (texture, &gl_handle, &gl_target);
|
||||
|
||||
|
@@ -455,8 +455,8 @@ _cogl_driver_update_features (CoglContext *ctx,
|
||||
TRUE);
|
||||
|
||||
if (ctx->glBlitFramebuffer)
|
||||
COGL_FLAGS_SET (private_features,
|
||||
COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER, TRUE);
|
||||
COGL_FLAGS_SET (ctx->features,
|
||||
COGL_FEATURE_ID_BLIT_FRAMEBUFFER, TRUE);
|
||||
|
||||
COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_PBOS, TRUE);
|
||||
|
||||
|
@@ -255,7 +255,7 @@ _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx,
|
||||
* glTexImage2D first to assert that the storage for this
|
||||
* level exists.
|
||||
*/
|
||||
if (texture->max_level < level)
|
||||
if (texture->max_level_set < level)
|
||||
{
|
||||
ctx->glTexImage2D (gl_target,
|
||||
level,
|
||||
|
@@ -318,8 +318,8 @@ _cogl_driver_update_features (CoglContext *context,
|
||||
COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS, TRUE);
|
||||
|
||||
if (context->glBlitFramebuffer)
|
||||
COGL_FLAGS_SET (private_features,
|
||||
COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER, TRUE);
|
||||
COGL_FLAGS_SET (context->features,
|
||||
COGL_FEATURE_ID_BLIT_FRAMEBUFFER, TRUE);
|
||||
|
||||
if (_cogl_check_extension ("GL_OES_element_index_uint", gl_extensions))
|
||||
{
|
||||
|
@@ -303,7 +303,7 @@ _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx,
|
||||
* glTexImage2D first to assert that the storage for this
|
||||
* level exists.
|
||||
*/
|
||||
if (texture->max_level < level)
|
||||
if (texture->max_level_set < level)
|
||||
{
|
||||
ctx->glTexImage2D (gl_target,
|
||||
level,
|
||||
|
@@ -17,6 +17,7 @@ cogl_config_h = configure_file(
|
||||
|
||||
cogl_pkg_deps = [
|
||||
glib_dep,
|
||||
gio_dep,
|
||||
gobject_dep,
|
||||
graphene_dep,
|
||||
]
|
||||
|
@@ -1,5 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -o pipefail
|
||||
|
||||
if test -z "$G_DEBUG"; then
|
||||
G_DEBUG=fatal-warnings
|
||||
else
|
||||
@@ -69,7 +71,12 @@ get_status()
|
||||
|
||||
run_test()
|
||||
{
|
||||
$("$TEST_BINARY" "$1" &> "$LOG")
|
||||
if [ -n "${VERBOSE-}" ]; then
|
||||
echo "running $TEST_BINARY $1:"
|
||||
$TEST_BINARY $1 2>&1 | tee "$LOG"
|
||||
else
|
||||
$($TEST_BINARY $1 &> "$LOG")
|
||||
fi
|
||||
TMP=$?
|
||||
var_name=$2_result
|
||||
eval "$var_name=$TMP"
|
||||
|
@@ -108,6 +108,14 @@ struct _MetaBackendClass
|
||||
|
||||
void meta_init_backend (GType backend_gtype);
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
MetaWaylandCompositor * meta_backend_get_wayland_compositor (MetaBackend *backend);
|
||||
|
||||
void meta_backend_init_wayland_display (MetaBackend *backend);
|
||||
|
||||
void meta_backend_init_wayland (MetaBackend *backend);
|
||||
#endif
|
||||
|
||||
ClutterBackend * meta_backend_get_clutter_backend (MetaBackend *backend);
|
||||
|
||||
MetaIdleMonitor * meta_backend_get_idle_monitor (MetaBackend *backend,
|
||||
|
@@ -54,4 +54,6 @@ typedef struct _MetaScreenCast MetaScreenCast;
|
||||
typedef struct _MetaScreenCastSession MetaScreenCastSession;
|
||||
typedef struct _MetaScreenCastStream MetaScreenCastStream;
|
||||
|
||||
typedef struct _MetaWaylandCompositor MetaWaylandCompositor;
|
||||
|
||||
#endif /* META_BACKEND_TYPE_H */
|
||||
|
@@ -81,6 +81,10 @@
|
||||
#include "backends/native/meta-backend-native.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include "wayland/meta-wayland.h"
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
KEYMAP_CHANGED,
|
||||
@@ -130,6 +134,10 @@ struct _MetaBackendPrivate
|
||||
MetaRemoteDesktop *remote_desktop;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
MetaWaylandCompositor *wayland_compositor;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PROFILER
|
||||
MetaProfiler *profiler;
|
||||
#endif
|
||||
@@ -864,6 +872,120 @@ system_bus_gotten_cb (GObject *object,
|
||||
NULL);
|
||||
}
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
MetaWaylandCompositor *
|
||||
meta_backend_get_wayland_compositor (MetaBackend *backend)
|
||||
{
|
||||
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||
|
||||
return priv->wayland_compositor;
|
||||
}
|
||||
|
||||
void
|
||||
meta_backend_init_wayland_display (MetaBackend *backend)
|
||||
{
|
||||
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||
|
||||
priv->wayland_compositor = meta_wayland_compositor_new (backend);
|
||||
}
|
||||
|
||||
void
|
||||
meta_backend_init_wayland (MetaBackend *backend)
|
||||
{
|
||||
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||
|
||||
meta_wayland_compositor_setup (priv->wayland_compositor);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Mutter is responsible for pulling events off the X queue, so Clutter
|
||||
* doesn't need (and shouldn't) run its normal event source which polls
|
||||
* the X fd, but we do have to deal with dispatching events that accumulate
|
||||
* in the clutter queue. This happens, for example, when clutter generate
|
||||
* enter/leave events on mouse motion - several events are queued in the
|
||||
* clutter queue but only one dispatched. It could also happen because of
|
||||
* explicit calls to clutter_event_put(). We add a very simple custom
|
||||
* event loop source which is simply responsible for pulling events off
|
||||
* of the queue and dispatching them before we block for new events.
|
||||
*/
|
||||
|
||||
static gboolean
|
||||
clutter_source_prepare (GSource *source,
|
||||
int *timeout)
|
||||
{
|
||||
*timeout = -1;
|
||||
|
||||
return clutter_events_pending ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_source_check (GSource *source)
|
||||
{
|
||||
return clutter_events_pending ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_source_dispatch (GSource *source,
|
||||
GSourceFunc callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
ClutterEvent *event = clutter_event_get ();
|
||||
|
||||
if (event)
|
||||
{
|
||||
clutter_do_event (event);
|
||||
clutter_event_free (event);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GSourceFuncs clutter_source_funcs = {
|
||||
clutter_source_prepare,
|
||||
clutter_source_check,
|
||||
clutter_source_dispatch
|
||||
};
|
||||
|
||||
static ClutterBackend *
|
||||
meta_get_clutter_backend (void)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
|
||||
return meta_backend_get_clutter_backend (backend);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
init_clutter (MetaBackend *backend,
|
||||
GError **error)
|
||||
{
|
||||
GSource *source;
|
||||
|
||||
clutter_set_custom_backend_func (meta_get_clutter_backend);
|
||||
|
||||
if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Unable to initialize Clutter");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
source = g_source_new (&clutter_source_funcs, sizeof (GSource));
|
||||
g_source_attach (source, NULL);
|
||||
g_source_unref (source);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_post_init (MetaBackend *backend)
|
||||
{
|
||||
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||
|
||||
META_BACKEND_GET_CLASS (backend)->post_init (backend);
|
||||
|
||||
meta_settings_post_init (priv->settings);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_backend_initable_init (GInitable *initable,
|
||||
GCancellable *cancellable,
|
||||
@@ -902,6 +1024,11 @@ meta_backend_initable_init (GInitable *initable,
|
||||
priv->profiler = meta_profiler_new ();
|
||||
#endif
|
||||
|
||||
if (!init_clutter (backend, error))
|
||||
return FALSE;
|
||||
|
||||
meta_backend_post_init (backend);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -917,16 +1044,6 @@ meta_backend_init (MetaBackend *backend)
|
||||
_backend = backend;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_post_init (MetaBackend *backend)
|
||||
{
|
||||
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||
|
||||
META_BACKEND_GET_CLASS (backend)->post_init (backend);
|
||||
|
||||
meta_settings_post_init (priv->settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_backend_get_idle_monitor: (skip)
|
||||
*/
|
||||
@@ -1258,54 +1375,6 @@ meta_backend_set_client_pointer_constraint (MetaBackend *backend,
|
||||
priv->client_pointer_constraint = g_object_ref (constraint);
|
||||
}
|
||||
|
||||
/* Mutter is responsible for pulling events off the X queue, so Clutter
|
||||
* doesn't need (and shouldn't) run its normal event source which polls
|
||||
* the X fd, but we do have to deal with dispatching events that accumulate
|
||||
* in the clutter queue. This happens, for example, when clutter generate
|
||||
* enter/leave events on mouse motion - several events are queued in the
|
||||
* clutter queue but only one dispatched. It could also happen because of
|
||||
* explicit calls to clutter_event_put(). We add a very simple custom
|
||||
* event loop source which is simply responsible for pulling events off
|
||||
* of the queue and dispatching them before we block for new events.
|
||||
*/
|
||||
|
||||
static gboolean
|
||||
event_prepare (GSource *source,
|
||||
gint *timeout_)
|
||||
{
|
||||
*timeout_ = -1;
|
||||
|
||||
return clutter_events_pending ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
event_check (GSource *source)
|
||||
{
|
||||
return clutter_events_pending ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
event_dispatch (GSource *source,
|
||||
GSourceFunc callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
ClutterEvent *event = clutter_event_get ();
|
||||
|
||||
if (event)
|
||||
{
|
||||
clutter_do_event (event);
|
||||
clutter_event_free (event);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GSourceFuncs event_funcs = {
|
||||
event_prepare,
|
||||
event_check,
|
||||
event_dispatch
|
||||
};
|
||||
|
||||
ClutterBackend *
|
||||
meta_backend_get_clutter_backend (MetaBackend *backend)
|
||||
{
|
||||
@@ -1320,14 +1389,6 @@ meta_backend_get_clutter_backend (MetaBackend *backend)
|
||||
return priv->clutter_backend;
|
||||
}
|
||||
|
||||
static ClutterBackend *
|
||||
meta_get_clutter_backend (void)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
|
||||
return meta_backend_get_clutter_backend (backend);
|
||||
}
|
||||
|
||||
void
|
||||
meta_init_backend (GType backend_gtype)
|
||||
{
|
||||
@@ -1344,29 +1405,6 @@ meta_init_backend (GType backend_gtype)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_clutter_init: (skip)
|
||||
*/
|
||||
void
|
||||
meta_clutter_init (void)
|
||||
{
|
||||
GSource *source;
|
||||
|
||||
clutter_set_custom_backend_func (meta_get_clutter_backend);
|
||||
|
||||
if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS)
|
||||
{
|
||||
g_warning ("Unable to initialize Clutter.\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
source = g_source_new (&event_funcs, sizeof (GSource));
|
||||
g_source_attach (source, NULL);
|
||||
g_source_unref (source);
|
||||
|
||||
meta_backend_post_init (_backend);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_is_stage_views_enabled:
|
||||
*
|
||||
|
@@ -84,6 +84,7 @@ translate_meta_cursor (MetaCursor cursor)
|
||||
return "crosshair";
|
||||
case META_CURSOR_IBEAM:
|
||||
return "xterm";
|
||||
case META_CURSOR_BLANK:
|
||||
case META_CURSOR_NONE:
|
||||
case META_CURSOR_LAST:
|
||||
break;
|
||||
@@ -93,6 +94,48 @@ translate_meta_cursor (MetaCursor cursor)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Cursor
|
||||
create_blank_cursor (Display *xdisplay)
|
||||
{
|
||||
Pixmap pixmap;
|
||||
XColor color;
|
||||
Cursor cursor;
|
||||
XGCValues gc_values;
|
||||
GC gc;
|
||||
|
||||
pixmap = XCreatePixmap (xdisplay, DefaultRootWindow (xdisplay), 1, 1, 1);
|
||||
|
||||
gc_values.foreground = BlackPixel (xdisplay, DefaultScreen (xdisplay));
|
||||
gc = XCreateGC (xdisplay, pixmap, GCForeground, &gc_values);
|
||||
|
||||
XFillRectangle (xdisplay, pixmap, gc, 0, 0, 1, 1);
|
||||
|
||||
color.pixel = 0;
|
||||
color.red = color.blue = color.green = 0;
|
||||
|
||||
cursor = XCreatePixmapCursor (xdisplay, pixmap, pixmap, &color, &color, 1, 1);
|
||||
|
||||
XFreeGC (xdisplay, gc);
|
||||
XFreePixmap (xdisplay, pixmap);
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
static XcursorImages *
|
||||
create_blank_cursor_images (void)
|
||||
{
|
||||
XcursorImages *images;
|
||||
|
||||
images = XcursorImagesCreate (1);
|
||||
images->images[0] = XcursorImageCreate (1, 1);
|
||||
|
||||
images->images[0]->xhot = 0;
|
||||
images->images[0]->yhot = 0;
|
||||
memset (images->images[0]->pixels, 0, sizeof(int32_t));
|
||||
|
||||
return images;
|
||||
}
|
||||
|
||||
MetaCursor
|
||||
meta_cursor_sprite_xcursor_get_cursor (MetaCursorSpriteXcursor *sprite_xcursor)
|
||||
{
|
||||
@@ -103,12 +146,18 @@ Cursor
|
||||
meta_create_x_cursor (Display *xdisplay,
|
||||
MetaCursor cursor)
|
||||
{
|
||||
if (cursor == META_CURSOR_BLANK)
|
||||
return create_blank_cursor (xdisplay);
|
||||
|
||||
return XcursorLibraryLoadCursor (xdisplay, translate_meta_cursor (cursor));
|
||||
}
|
||||
|
||||
static XcursorImages *
|
||||
load_cursor_on_client (MetaCursor cursor, int scale)
|
||||
{
|
||||
if (cursor == META_CURSOR_BLANK)
|
||||
return create_blank_cursor_images ();
|
||||
|
||||
return XcursorLibraryLoadImages (translate_meta_cursor (cursor),
|
||||
meta_prefs_get_cursor_theme (),
|
||||
meta_prefs_get_cursor_size () * scale);
|
||||
|
@@ -52,6 +52,7 @@ meta_monitor_transform_is_flipped (MetaMonitorTransform transform)
|
||||
return (transform >= META_MONITOR_TRANSFORM_FLIPPED);
|
||||
}
|
||||
|
||||
META_EXPORT_TEST
|
||||
MetaMonitorTransform meta_monitor_transform_invert (MetaMonitorTransform transform);
|
||||
|
||||
META_EXPORT_TEST
|
||||
|
@@ -35,6 +35,12 @@ meta_output_get_gpu (MetaOutput *output)
|
||||
return output->gpu;
|
||||
}
|
||||
|
||||
const char *
|
||||
meta_output_get_name (MetaOutput *output)
|
||||
{
|
||||
return output->name;
|
||||
}
|
||||
|
||||
void
|
||||
meta_output_assign_crtc (MetaOutput *output,
|
||||
MetaCrtc *crtc)
|
||||
|
@@ -122,6 +122,8 @@ META_EXPORT_TEST G_DECLARE_FINAL_TYPE (MetaOutput, meta_output, META, OUTPUT, GO
|
||||
META_EXPORT_TEST
|
||||
MetaGpu * meta_output_get_gpu (MetaOutput *output);
|
||||
|
||||
const char * meta_output_get_name (MetaOutput *output);
|
||||
|
||||
META_EXPORT_TEST
|
||||
void meta_output_assign_crtc (MetaOutput *output,
|
||||
MetaCrtc *crtc);
|
||||
|
@@ -55,6 +55,7 @@ struct _MetaRemoteDesktopSession
|
||||
|
||||
MetaScreenCastSession *screen_cast_session;
|
||||
gulong screen_cast_session_closed_handler_id;
|
||||
guint started : 1;
|
||||
|
||||
ClutterVirtualInputDevice *virtual_pointer;
|
||||
ClutterVirtualInputDevice *virtual_keyboard;
|
||||
@@ -119,7 +120,7 @@ meta_remote_desktop_session_start (MetaRemoteDesktopSession *session,
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterSeat *seat = clutter_backend_get_default_seat (backend);
|
||||
|
||||
g_assert (!session->virtual_pointer && !session->virtual_keyboard);
|
||||
g_assert (!session->started);
|
||||
|
||||
if (session->screen_cast_session)
|
||||
{
|
||||
@@ -135,6 +136,7 @@ meta_remote_desktop_session_start (MetaRemoteDesktopSession *session,
|
||||
clutter_seat_create_virtual_device (seat, CLUTTER_TOUCHSCREEN_DEVICE);
|
||||
|
||||
init_remote_access_handle (session);
|
||||
session->started = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -145,6 +147,8 @@ meta_remote_desktop_session_close (MetaRemoteDesktopSession *session)
|
||||
MetaDBusRemoteDesktopSession *skeleton =
|
||||
META_DBUS_REMOTE_DESKTOP_SESSION (session);
|
||||
|
||||
session->started = FALSE;
|
||||
|
||||
if (session->screen_cast_session)
|
||||
{
|
||||
g_clear_signal_handler (&session->screen_cast_session_closed_handler_id,
|
||||
@@ -249,6 +253,37 @@ check_permission (MetaRemoteDesktopSession *session,
|
||||
g_dbus_method_invocation_get_sender (invocation)) == 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_remote_desktop_session_check_can_notify (MetaRemoteDesktopSession *session,
|
||||
GDBusMethodInvocation *invocation)
|
||||
{
|
||||
if (!session->started)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_FAILED,
|
||||
"Session not started");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!session->screen_cast_session)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_FAILED,
|
||||
"No screen cast active");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_start (MetaDBusRemoteDesktopSession *skeleton,
|
||||
GDBusMethodInvocation *invocation)
|
||||
@@ -256,6 +291,14 @@ handle_start (MetaDBusRemoteDesktopSession *skeleton,
|
||||
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
|
||||
GError *error = NULL;
|
||||
|
||||
if (session->started)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_FAILED,
|
||||
"Already started");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
@@ -288,6 +331,14 @@ handle_stop (MetaDBusRemoteDesktopSession *skeleton,
|
||||
{
|
||||
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
|
||||
|
||||
if (!session->started)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_FAILED,
|
||||
"Session not started");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
@@ -312,13 +363,8 @@ handle_notify_keyboard_keycode (MetaDBusRemoteDesktopSession *skeleton,
|
||||
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
|
||||
ClutterKeyState state;
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
if (pressed)
|
||||
state = CLUTTER_KEY_STATE_PRESSED;
|
||||
@@ -344,13 +390,8 @@ handle_notify_keyboard_keysym (MetaDBusRemoteDesktopSession *skeleton,
|
||||
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
|
||||
ClutterKeyState state;
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
if (pressed)
|
||||
state = CLUTTER_KEY_STATE_PRESSED;
|
||||
@@ -398,13 +439,8 @@ handle_notify_pointer_button (MetaDBusRemoteDesktopSession *skeleton,
|
||||
uint32_t button;
|
||||
ClutterButtonState state;
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
button = translate_to_clutter_button (button_code);
|
||||
|
||||
@@ -434,13 +470,8 @@ handle_notify_pointer_axis (MetaDBusRemoteDesktopSession *skeleton,
|
||||
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
|
||||
ClutterScrollFinishFlags finish_flags = CLUTTER_SCROLL_FINISHED_NONE;
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
if (flags & META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_FINISH)
|
||||
{
|
||||
@@ -487,13 +518,8 @@ handle_notify_pointer_axis_discrete (MetaDBusRemoteDesktopSession *skeleton,
|
||||
ClutterScrollDirection direction;
|
||||
int step_count;
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
if (axis > 1)
|
||||
{
|
||||
@@ -538,13 +564,8 @@ handle_notify_pointer_motion_relative (MetaDBusRemoteDesktopSession *skeleton,
|
||||
{
|
||||
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
clutter_virtual_input_device_notify_relative_motion (session->virtual_pointer,
|
||||
CLUTTER_CURRENT_TIME,
|
||||
@@ -567,21 +588,8 @@ handle_notify_pointer_motion_absolute (MetaDBusRemoteDesktopSession *skeleton,
|
||||
MetaScreenCastStream *stream;
|
||||
double abs_x, abs_y;
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!session->screen_cast_session)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_FAILED,
|
||||
"No screen cast active");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
stream = meta_screen_cast_session_get_stream (session->screen_cast_session,
|
||||
stream_path);
|
||||
@@ -617,21 +625,8 @@ handle_notify_touch_down (MetaDBusRemoteDesktopSession *skeleton,
|
||||
MetaScreenCastStream *stream;
|
||||
double abs_x, abs_y;
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!session->screen_cast_session)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_FAILED,
|
||||
"No screen cast active");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
stream = meta_screen_cast_session_get_stream (session->screen_cast_session,
|
||||
stream_path);
|
||||
@@ -668,21 +663,8 @@ handle_notify_touch_motion (MetaDBusRemoteDesktopSession *skeleton,
|
||||
MetaScreenCastStream *stream;
|
||||
double abs_x, abs_y;
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!session->screen_cast_session)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_FAILED,
|
||||
"No screen cast active");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
stream = meta_screen_cast_session_get_stream (session->screen_cast_session,
|
||||
stream_path);
|
||||
@@ -714,13 +696,8 @@ handle_notify_touch_up (MetaDBusRemoteDesktopSession *skeleton,
|
||||
{
|
||||
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
clutter_virtual_input_device_notify_touch_up (session->virtual_touchscreen,
|
||||
CLUTTER_CURRENT_TIME,
|
||||
|
@@ -34,6 +34,7 @@
|
||||
|
||||
#include "backends/meta-renderer.h"
|
||||
#include "clutter/clutter-mutter.h"
|
||||
#include "compositor/region-utils.h"
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -117,6 +118,25 @@ meta_renderer_view_setup_offscreen_blit_pipeline (ClutterStageView *view,
|
||||
cogl_pipeline_set_layer_matrix (pipeline, 0, &matrix);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_renderer_view_transform_rect_to_onscreen (ClutterStageView *view,
|
||||
const cairo_rectangle_int_t *src_rect,
|
||||
int dst_width,
|
||||
int dst_height,
|
||||
cairo_rectangle_int_t *dst_rect)
|
||||
{
|
||||
MetaRendererView *renderer_view = META_RENDERER_VIEW (view);
|
||||
MetaMonitorTransform inverted_transform;
|
||||
|
||||
inverted_transform =
|
||||
meta_monitor_transform_invert (renderer_view->transform);
|
||||
return meta_rectangle_transform (src_rect,
|
||||
inverted_transform,
|
||||
dst_width,
|
||||
dst_height,
|
||||
dst_rect);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_renderer_view_set_transform (MetaRendererView *view,
|
||||
MetaMonitorTransform transform)
|
||||
@@ -181,6 +201,8 @@ meta_renderer_view_class_init (MetaRendererViewClass *klass)
|
||||
meta_renderer_view_setup_offscreen_blit_pipeline;
|
||||
view_class->get_offscreen_transformation_matrix =
|
||||
meta_renderer_view_get_offscreen_transformation_matrix;
|
||||
view_class->transform_rect_to_onscreen =
|
||||
meta_renderer_view_transform_rect_to_onscreen;
|
||||
|
||||
object_class->get_property = meta_renderer_view_get_property;
|
||||
object_class->set_property = meta_renderer_view_set_property;
|
||||
|
@@ -160,14 +160,12 @@ meta_renderer_real_rebuild_views (MetaRenderer *renderer)
|
||||
}
|
||||
|
||||
void
|
||||
meta_renderer_set_legacy_view (MetaRenderer *renderer,
|
||||
MetaRendererView *legacy_view)
|
||||
meta_renderer_add_view (MetaRenderer *renderer,
|
||||
MetaRendererView *view)
|
||||
{
|
||||
MetaRendererPrivate *priv = meta_renderer_get_instance_private (renderer);
|
||||
|
||||
g_assert (!priv->views);
|
||||
|
||||
priv->views = g_list_append (priv->views, legacy_view);
|
||||
priv->views = g_list_append (priv->views, view);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -54,8 +54,8 @@ CoglRenderer * meta_renderer_create_cogl_renderer (MetaRenderer *renderer);
|
||||
|
||||
void meta_renderer_rebuild_views (MetaRenderer *renderer);
|
||||
|
||||
void meta_renderer_set_legacy_view (MetaRenderer *renderer,
|
||||
MetaRendererView *legacy_view);
|
||||
void meta_renderer_add_view (MetaRenderer *renderer,
|
||||
MetaRendererView *view);
|
||||
|
||||
META_EXPORT_TEST
|
||||
GList * meta_renderer_get_views (MetaRenderer *renderer);
|
||||
|
@@ -68,6 +68,7 @@ typedef struct _MetaPipeWireSource
|
||||
{
|
||||
GSource base;
|
||||
|
||||
MetaScreenCastStreamSrc *src;
|
||||
struct pw_loop *pipewire_loop;
|
||||
} MetaPipeWireSource;
|
||||
|
||||
@@ -81,6 +82,7 @@ typedef struct _MetaScreenCastStreamSrcPrivate
|
||||
struct spa_hook pipewire_core_listener;
|
||||
|
||||
gboolean is_enabled;
|
||||
gboolean emit_closed_after_dispatch;
|
||||
|
||||
struct pw_stream *pipewire_stream;
|
||||
struct spa_hook pipewire_stream_listener;
|
||||
@@ -445,7 +447,8 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src)
|
||||
uint64_t now_us;
|
||||
|
||||
now_us = g_get_monotonic_time ();
|
||||
if (priv->last_frame_timestamp_us != 0 &&
|
||||
if (priv->video_format.max_framerate.num > 0 &&
|
||||
priv->last_frame_timestamp_us != 0 &&
|
||||
(now_us - priv->last_frame_timestamp_us <
|
||||
((1000000 * priv->video_format.max_framerate.denom) /
|
||||
priv->video_format.max_framerate.num)))
|
||||
@@ -539,12 +542,6 @@ meta_screen_cast_stream_src_disable (MetaScreenCastStreamSrc *src)
|
||||
priv->is_enabled = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_cast_stream_src_notify_closed (MetaScreenCastStreamSrc *src)
|
||||
{
|
||||
g_signal_emit (src, signals[CLOSED], 0);
|
||||
}
|
||||
|
||||
static void
|
||||
on_stream_state_changed (void *data,
|
||||
enum pw_stream_state old,
|
||||
@@ -559,7 +556,9 @@ on_stream_state_changed (void *data,
|
||||
{
|
||||
case PW_STREAM_STATE_ERROR:
|
||||
g_warning ("pipewire stream error: %s", error_message);
|
||||
meta_screen_cast_stream_src_notify_closed (src);
|
||||
if (meta_screen_cast_stream_src_is_enabled (src))
|
||||
meta_screen_cast_stream_src_disable (src);
|
||||
priv->emit_closed_after_dispatch = TRUE;
|
||||
break;
|
||||
case PW_STREAM_STATE_PAUSED:
|
||||
if (priv->node_id == SPA_ID_INVALID && priv->pipewire_stream)
|
||||
@@ -827,11 +826,17 @@ on_core_error (void *data,
|
||||
const char *message)
|
||||
{
|
||||
MetaScreenCastStreamSrc *src = data;
|
||||
MetaScreenCastStreamSrcPrivate *priv =
|
||||
meta_screen_cast_stream_src_get_instance_private (src);
|
||||
|
||||
g_warning ("pipewire remote error: id:%u %s", id, message);
|
||||
|
||||
if (id == PW_ID_CORE && res == -EPIPE)
|
||||
meta_screen_cast_stream_src_notify_closed (src);
|
||||
{
|
||||
if (meta_screen_cast_stream_src_is_enabled (src))
|
||||
meta_screen_cast_stream_src_disable (src);
|
||||
priv->emit_closed_after_dispatch = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -848,12 +853,18 @@ pipewire_loop_source_dispatch (GSource *source,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaPipeWireSource *pipewire_source = (MetaPipeWireSource *) source;
|
||||
MetaScreenCastStreamSrc *src = pipewire_source->src;
|
||||
MetaScreenCastStreamSrcPrivate *priv =
|
||||
meta_screen_cast_stream_src_get_instance_private (src);
|
||||
int result;
|
||||
|
||||
result = pw_loop_iterate (pipewire_source->pipewire_loop, 0);
|
||||
if (result < 0)
|
||||
g_warning ("pipewire_loop_iterate failed: %s", spa_strerror (result));
|
||||
|
||||
if (priv->emit_closed_after_dispatch)
|
||||
g_signal_emit (src, signals[CLOSED], 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -875,13 +886,14 @@ static GSourceFuncs pipewire_source_funcs =
|
||||
};
|
||||
|
||||
static MetaPipeWireSource *
|
||||
create_pipewire_source (void)
|
||||
create_pipewire_source (MetaScreenCastStreamSrc *src)
|
||||
{
|
||||
MetaPipeWireSource *pipewire_source;
|
||||
|
||||
pipewire_source =
|
||||
(MetaPipeWireSource *) g_source_new (&pipewire_source_funcs,
|
||||
sizeof (MetaPipeWireSource));
|
||||
pipewire_source->src = src;
|
||||
pipewire_source->pipewire_loop = pw_loop_new (NULL);
|
||||
if (!pipewire_source->pipewire_loop)
|
||||
{
|
||||
@@ -913,7 +925,7 @@ meta_screen_cast_stream_src_initable_init (GInitable *initable,
|
||||
MetaScreenCastStreamSrcPrivate *priv =
|
||||
meta_screen_cast_stream_src_get_instance_private (src);
|
||||
|
||||
priv->pipewire_source = create_pipewire_source ();
|
||||
priv->pipewire_source = create_pipewire_source (src);
|
||||
if (!priv->pipewire_source)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
|
@@ -366,6 +366,10 @@ meta_backend_native_post_init (MetaBackend *backend)
|
||||
if (retval != 0)
|
||||
g_warning ("Failed to set RT scheduler: %m");
|
||||
}
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
meta_backend_init_wayland (backend);
|
||||
#endif
|
||||
}
|
||||
|
||||
static MetaMonitorManager *
|
||||
@@ -647,6 +651,10 @@ meta_backend_native_initable_init (GInitable *initable,
|
||||
if (!native->launcher)
|
||||
return FALSE;
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
meta_backend_init_wayland_display (META_BACKEND (native));
|
||||
#endif
|
||||
|
||||
native->udev = meta_udev_new (native);
|
||||
native->barrier_manager = meta_barrier_manager_native_new ();
|
||||
|
||||
|
@@ -2169,6 +2169,9 @@ meta_renderer_native_create_dma_buf (CoglRenderer *cogl_renderer,
|
||||
{
|
||||
CoglFramebuffer *dmabuf_fb;
|
||||
struct gbm_bo *new_bo;
|
||||
int stride;
|
||||
int offset;
|
||||
int bpp;
|
||||
int dmabuf_fd = -1;
|
||||
|
||||
new_bo = gbm_bo_create (renderer_gpu_data->gbm.device,
|
||||
@@ -2192,11 +2195,14 @@ meta_renderer_native_create_dma_buf (CoglRenderer *cogl_renderer,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
stride = gbm_bo_get_stride (new_bo);
|
||||
offset = gbm_bo_get_offset (new_bo, 0);
|
||||
bpp = 4;
|
||||
dmabuf_fb = create_dma_buf_framebuffer (renderer_native,
|
||||
dmabuf_fd,
|
||||
width, height,
|
||||
gbm_bo_get_stride (new_bo),
|
||||
gbm_bo_get_offset (new_bo, 0),
|
||||
stride,
|
||||
offset,
|
||||
DRM_FORMAT_MOD_LINEAR,
|
||||
DRM_FORMAT_XRGB8888,
|
||||
error);
|
||||
@@ -2204,7 +2210,9 @@ meta_renderer_native_create_dma_buf (CoglRenderer *cogl_renderer,
|
||||
if (!dmabuf_fb)
|
||||
return NULL;
|
||||
|
||||
return cogl_dma_buf_handle_new (dmabuf_fb, dmabuf_fd, new_bo,
|
||||
return cogl_dma_buf_handle_new (dmabuf_fb, dmabuf_fd,
|
||||
width, height, stride, offset, bpp,
|
||||
new_bo,
|
||||
(GDestroyNotify) gbm_bo_destroy);
|
||||
}
|
||||
break;
|
||||
@@ -3097,12 +3105,17 @@ should_force_shadow_fb (MetaRendererNative *renderer_native,
|
||||
MetaGpuKms *primary_gpu)
|
||||
{
|
||||
MetaRenderer *renderer = META_RENDERER (renderer_native);
|
||||
CoglContext *cogl_context =
|
||||
cogl_context_from_renderer_native (renderer_native);
|
||||
int kms_fd;
|
||||
uint64_t prefer_shadow = 0;
|
||||
|
||||
if (meta_renderer_is_hardware_accelerated (renderer))
|
||||
return FALSE;
|
||||
|
||||
if (!cogl_has_feature (cogl_context, COGL_FEATURE_ID_BLIT_FRAMEBUFFER))
|
||||
return FALSE;
|
||||
|
||||
kms_fd = meta_gpu_kms_get_fd (primary_gpu);
|
||||
if (drmGetCap (kms_fd, DRM_CAP_DUMB_PREFER_SHADOW, &prefer_shadow) == 0)
|
||||
{
|
||||
@@ -3142,7 +3155,7 @@ meta_renderer_native_create_view (MetaRenderer *renderer,
|
||||
MetaMonitorTransform view_transform;
|
||||
CoglOnscreen *onscreen = NULL;
|
||||
CoglOffscreen *offscreen = NULL;
|
||||
CoglOffscreen *shadowfb = NULL;
|
||||
gboolean use_shadowfb;
|
||||
float scale;
|
||||
int onscreen_width;
|
||||
int onscreen_height;
|
||||
@@ -3194,24 +3207,8 @@ meta_renderer_native_create_view (MetaRenderer *renderer,
|
||||
g_error ("Failed to allocate back buffer texture: %s", error->message);
|
||||
}
|
||||
|
||||
if (should_force_shadow_fb (renderer_native,
|
||||
renderer_native->primary_gpu_kms))
|
||||
{
|
||||
int shadow_width;
|
||||
int shadow_height;
|
||||
|
||||
/* The shadowfb must be the same size as the on-screen framebuffer */
|
||||
shadow_width = cogl_framebuffer_get_width (COGL_FRAMEBUFFER (onscreen));
|
||||
shadow_height = cogl_framebuffer_get_height (COGL_FRAMEBUFFER (onscreen));
|
||||
|
||||
shadowfb = meta_renderer_native_create_offscreen (renderer_native,
|
||||
cogl_context,
|
||||
shadow_width,
|
||||
shadow_height,
|
||||
&error);
|
||||
if (!shadowfb)
|
||||
g_error ("Failed to allocate shadow buffer texture: %s", error->message);
|
||||
}
|
||||
use_shadowfb = should_force_shadow_fb (renderer_native,
|
||||
renderer_native->primary_gpu_kms);
|
||||
|
||||
if (meta_is_stage_views_scaled ())
|
||||
scale = meta_logical_monitor_get_scale (logical_monitor);
|
||||
@@ -3222,15 +3219,15 @@ meta_renderer_native_create_view (MetaRenderer *renderer,
|
||||
META_ROUNDING_STRATEGY_ROUND,
|
||||
&view_layout);
|
||||
view = g_object_new (META_TYPE_RENDERER_VIEW,
|
||||
"name", meta_output_get_name (output),
|
||||
"layout", &view_layout,
|
||||
"scale", scale,
|
||||
"framebuffer", onscreen,
|
||||
"offscreen", offscreen,
|
||||
"shadowfb", shadowfb,
|
||||
"use-shadowfb", use_shadowfb,
|
||||
"transform", view_transform,
|
||||
NULL);
|
||||
g_clear_pointer (&offscreen, cogl_object_unref);
|
||||
g_clear_pointer (&shadowfb, cogl_object_unref);
|
||||
|
||||
meta_onscreen_native_set_view (onscreen, view);
|
||||
|
||||
|
@@ -148,6 +148,13 @@ meta_udev_list_drm_devices (MetaUdev *udev,
|
||||
l = l_next;
|
||||
}
|
||||
|
||||
if (!devices)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"No DRM devices found");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
|
@@ -24,14 +24,76 @@
|
||||
|
||||
#include "backends/x11/cm/meta-renderer-x11-cm.h"
|
||||
|
||||
#include "backends/meta-renderer-view.h"
|
||||
|
||||
struct _MetaRendererX11Cm
|
||||
{
|
||||
MetaRendererX11 parent;
|
||||
|
||||
MetaRendererView *screen_view;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaRendererX11Cm, meta_renderer_x11_cm,
|
||||
META_TYPE_RENDERER_X11)
|
||||
|
||||
void
|
||||
meta_renderer_x11_cm_ensure_screen_view (MetaRendererX11Cm *renderer_x11_cm,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_rectangle_int_t view_layout;
|
||||
|
||||
if (renderer_x11_cm->screen_view)
|
||||
return;
|
||||
|
||||
view_layout = (cairo_rectangle_int_t) {
|
||||
.width = width,
|
||||
.height = height,
|
||||
};
|
||||
renderer_x11_cm->screen_view = g_object_new (META_TYPE_RENDERER_VIEW,
|
||||
"name", "X11 screen",
|
||||
"layout", &view_layout,
|
||||
NULL);
|
||||
meta_renderer_add_view (META_RENDERER (renderer_x11_cm),
|
||||
renderer_x11_cm->screen_view);
|
||||
}
|
||||
|
||||
void
|
||||
meta_renderer_x11_cm_resize (MetaRendererX11Cm *renderer_x11_cm,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_rectangle_int_t view_layout;
|
||||
|
||||
view_layout = (cairo_rectangle_int_t) {
|
||||
.width = width,
|
||||
.height = height,
|
||||
};
|
||||
|
||||
g_object_set (G_OBJECT (renderer_x11_cm->screen_view),
|
||||
"layout", &view_layout,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
meta_renderer_x11_cm_set_onscreen (MetaRendererX11Cm *renderer_x11_cm,
|
||||
CoglOnscreen *onscreen)
|
||||
{
|
||||
g_object_set (G_OBJECT (renderer_x11_cm->screen_view),
|
||||
"framebuffer", onscreen,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_renderer_x11_cm_rebuild_views (MetaRenderer *renderer)
|
||||
{
|
||||
MetaRendererX11Cm *renderer_x11_cm = META_RENDERER_X11_CM (renderer);
|
||||
|
||||
g_return_if_fail (!meta_renderer_get_views (renderer));
|
||||
|
||||
meta_renderer_add_view (renderer, renderer_x11_cm->screen_view);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_renderer_x11_cm_init (MetaRendererX11Cm *renderer_x11_cm)
|
||||
{
|
||||
@@ -40,4 +102,7 @@ meta_renderer_x11_cm_init (MetaRendererX11Cm *renderer_x11_cm)
|
||||
static void
|
||||
meta_renderer_x11_cm_class_init (MetaRendererX11CmClass *klass)
|
||||
{
|
||||
MetaRendererClass *renderer_class = META_RENDERER_CLASS (klass);
|
||||
|
||||
renderer_class->rebuild_views = meta_renderer_x11_cm_rebuild_views;
|
||||
}
|
||||
|
@@ -30,4 +30,15 @@ G_DECLARE_FINAL_TYPE (MetaRendererX11Cm, meta_renderer_x11_cm,
|
||||
META, RENDERER_X11_CM,
|
||||
MetaRendererX11)
|
||||
|
||||
void meta_renderer_x11_cm_ensure_screen_view (MetaRendererX11Cm *renderer_x11_cm,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
void meta_renderer_x11_cm_resize (MetaRendererX11Cm *renderer_x11_cm,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
void meta_renderer_x11_cm_set_onscreen (MetaRendererX11Cm *renderer_x11_cm,
|
||||
CoglOnscreen *onscreen);
|
||||
|
||||
#endif /* META_RENDERER_X11_CM_H */
|
||||
|
@@ -855,6 +855,7 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass)
|
||||
static void
|
||||
meta_backend_x11_init (MetaBackendX11 *x11)
|
||||
{
|
||||
XInitThreads ();
|
||||
}
|
||||
|
||||
Display *
|
||||
|
@@ -26,15 +26,17 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "backends/x11/cm/meta-backend-x11-cm.h"
|
||||
#include "backends/x11/cm/meta-renderer-x11-cm.h"
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
#include "backends/x11/meta-seat-x11.h"
|
||||
#include "backends/x11/meta-stage-x11.h"
|
||||
#include "clutter/clutter-mutter.h"
|
||||
#include "clutter/x11/clutter-x11.h"
|
||||
#include "clutter/x11/clutter-backend-x11.h"
|
||||
#include "cogl/cogl.h"
|
||||
#include "core/display-private.h"
|
||||
#include "meta/meta-x11-errors.h"
|
||||
#include "meta-backend-x11.h"
|
||||
#include "meta-seat-x11.h"
|
||||
#include "meta-stage-x11.h"
|
||||
|
||||
#define STAGE_X11_IS_MAPPED(s) ((((MetaStageX11 *) (s))->wm_state & STAGE_X11_WITHDRAWN) == 0)
|
||||
|
||||
@@ -254,8 +256,6 @@ meta_stage_x11_unrealize (ClutterStageWindow *stage_window)
|
||||
|
||||
clutter_stage_window_parent_iface->unrealize (stage_window);
|
||||
|
||||
g_list_free (stage_x11->legacy_views);
|
||||
g_clear_object (&stage_x11->legacy_view);
|
||||
g_clear_pointer (&stage_x11->onscreen, cogl_object_unref);
|
||||
}
|
||||
|
||||
@@ -297,10 +297,13 @@ meta_stage_x11_realize (ClutterStageWindow *stage_window)
|
||||
stage_cogl,
|
||||
NULL);
|
||||
|
||||
if (stage_x11->legacy_view)
|
||||
g_object_set (G_OBJECT (stage_x11->legacy_view),
|
||||
"framebuffer", stage_x11->onscreen,
|
||||
NULL);
|
||||
if (META_IS_BACKEND_X11_CM (stage_x11->backend))
|
||||
{
|
||||
MetaRenderer *renderer = meta_backend_get_renderer (stage_x11->backend);
|
||||
MetaRendererX11Cm *renderer_x11_cm = META_RENDERER_X11_CM (renderer);
|
||||
|
||||
meta_renderer_x11_cm_set_onscreen (renderer_x11_cm, stage_x11->onscreen);
|
||||
}
|
||||
|
||||
/* We just created a window of the size of the actor. No need to fix
|
||||
the size of the stage, just update it. */
|
||||
@@ -468,34 +471,13 @@ meta_stage_x11_can_clip_redraws (ClutterStageWindow *stage_window)
|
||||
return stage_x11->clipped_redraws_cool_off == 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_legacy_view (ClutterStageWindow *stage_window)
|
||||
{
|
||||
MetaStageX11 *stage_x11 = META_STAGE_X11 (stage_window);
|
||||
cairo_rectangle_int_t view_layout;
|
||||
CoglFramebuffer *framebuffer;
|
||||
|
||||
if (stage_x11->legacy_view)
|
||||
return;
|
||||
|
||||
_clutter_stage_window_get_geometry (stage_window, &view_layout);
|
||||
framebuffer = COGL_FRAMEBUFFER (stage_x11->onscreen);
|
||||
stage_x11->legacy_view = g_object_new (CLUTTER_TYPE_STAGE_VIEW_COGL,
|
||||
"layout", &view_layout,
|
||||
"framebuffer", framebuffer,
|
||||
NULL);
|
||||
stage_x11->legacy_views = g_list_append (stage_x11->legacy_views,
|
||||
stage_x11->legacy_view);
|
||||
}
|
||||
|
||||
static GList *
|
||||
meta_stage_x11_get_views (ClutterStageWindow *stage_window)
|
||||
{
|
||||
MetaStageX11 *stage_x11 = META_STAGE_X11 (stage_window);
|
||||
MetaRenderer *renderer = meta_backend_get_renderer (stage_x11->backend);
|
||||
|
||||
ensure_legacy_view (stage_window);
|
||||
|
||||
return stage_x11->legacy_views;
|
||||
return meta_renderer_get_views (renderer);
|
||||
}
|
||||
|
||||
static int64_t
|
||||
@@ -527,6 +509,9 @@ meta_stage_x11_class_init (MetaStageX11Class *klass)
|
||||
static void
|
||||
meta_stage_x11_init (MetaStageX11 *stage)
|
||||
{
|
||||
MetaRenderer *renderer;
|
||||
MetaRendererX11Cm *renderer_x11_cm;
|
||||
|
||||
stage->xwin = None;
|
||||
stage->xwin_width = 640;
|
||||
stage->xwin_height = 480;
|
||||
@@ -534,6 +519,19 @@ meta_stage_x11_init (MetaStageX11 *stage)
|
||||
stage->wm_state = STAGE_X11_WITHDRAWN;
|
||||
|
||||
stage->title = NULL;
|
||||
|
||||
stage->backend = meta_get_backend ();
|
||||
g_assert (stage->backend);
|
||||
|
||||
if (META_IS_BACKEND_X11_CM (stage->backend))
|
||||
{
|
||||
renderer = meta_backend_get_renderer (stage->backend);
|
||||
renderer_x11_cm = META_RENDERER_X11_CM (renderer);
|
||||
|
||||
meta_renderer_x11_cm_ensure_screen_view (renderer_x11_cm,
|
||||
stage->xwin_width,
|
||||
stage->xwin_height);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -719,16 +717,16 @@ meta_stage_x11_translate_event (MetaStageX11 *stage_x11,
|
||||
* X11 compositing manager, we need to reset the legacy
|
||||
* stage view, now that it has a new size.
|
||||
*/
|
||||
if (stage_x11->legacy_view)
|
||||
if (META_IS_BACKEND_X11_CM (stage_x11->backend))
|
||||
{
|
||||
cairo_rectangle_int_t view_layout = {
|
||||
.width = stage_width,
|
||||
.height = stage_height
|
||||
};
|
||||
MetaBackend *backend = stage_x11->backend;
|
||||
MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
||||
MetaRendererX11Cm *renderer_x11_cm =
|
||||
META_RENDERER_X11_CM (renderer);
|
||||
|
||||
g_object_set (G_OBJECT (stage_x11->legacy_view),
|
||||
"layout", &view_layout,
|
||||
NULL);
|
||||
meta_renderer_x11_cm_resize (renderer_x11_cm,
|
||||
stage_width,
|
||||
stage_height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
#include "backends/meta-backend-private.h"
|
||||
#include "clutter/clutter-mutter.h"
|
||||
#include "clutter/x11/clutter-x11.h"
|
||||
|
||||
@@ -51,14 +52,13 @@ struct _MetaStageX11
|
||||
{
|
||||
ClutterStageCogl parent_instance;
|
||||
|
||||
MetaBackend *backend;
|
||||
|
||||
CoglOnscreen *onscreen;
|
||||
Window xwin;
|
||||
gint xwin_width;
|
||||
gint xwin_height; /* FIXME target_width / height */
|
||||
|
||||
ClutterStageView *legacy_view;
|
||||
GList *legacy_views;
|
||||
|
||||
CoglFrameClosure *frame_closure;
|
||||
|
||||
gchar *title;
|
||||
|
@@ -33,8 +33,16 @@ typedef struct _MetaBackendX11NestedPrivate
|
||||
MetaGpu *gpu;
|
||||
} MetaBackendX11NestedPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaBackendX11Nested, meta_backend_x11_nested,
|
||||
META_TYPE_BACKEND_X11)
|
||||
static GInitableIface *initable_parent_iface;
|
||||
|
||||
static void
|
||||
initable_iface_init (GInitableIface *initable_iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (MetaBackendX11Nested, meta_backend_x11_nested,
|
||||
META_TYPE_BACKEND_X11,
|
||||
G_ADD_PRIVATE (MetaBackendX11Nested)
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
|
||||
initable_iface_init));
|
||||
|
||||
static MetaRenderer *
|
||||
meta_backend_x11_nested_create_renderer (MetaBackend *backend,
|
||||
@@ -201,6 +209,39 @@ meta_backend_x11_nested_real_init_gpus (MetaBackendX11Nested *backend_x11_nested
|
||||
meta_backend_add_gpu (META_BACKEND (backend_x11_nested), priv->gpu);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_x11_nested_post_init (MetaBackend *backend)
|
||||
{
|
||||
MetaBackendClass *backend_class =
|
||||
META_BACKEND_CLASS (meta_backend_x11_nested_parent_class);
|
||||
|
||||
backend_class->post_init (backend);
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
meta_backend_init_wayland (backend);
|
||||
#endif
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_backend_x11_nested_initable_init (GInitable *initable,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
#ifdef HAVE_WAYLAND
|
||||
meta_backend_init_wayland_display (META_BACKEND (initable));
|
||||
#endif
|
||||
|
||||
return initable_parent_iface->init (initable, cancellable, error);
|
||||
}
|
||||
|
||||
static void
|
||||
initable_iface_init (GInitableIface *initable_iface)
|
||||
{
|
||||
initable_parent_iface = g_type_interface_peek_parent (initable_iface);
|
||||
|
||||
initable_iface->init = meta_backend_x11_nested_initable_init;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_x11_nested_constructed (GObject *object)
|
||||
{
|
||||
@@ -229,6 +270,7 @@ meta_backend_x11_nested_class_init (MetaBackendX11NestedClass *klass)
|
||||
|
||||
object_class->constructed = meta_backend_x11_nested_constructed;
|
||||
|
||||
backend_class->post_init = meta_backend_x11_nested_post_init;
|
||||
backend_class->create_renderer = meta_backend_x11_nested_create_renderer;
|
||||
backend_class->create_monitor_manager = meta_backend_x11_nested_create_monitor_manager;
|
||||
backend_class->create_cursor_renderer = meta_backend_x11_nested_create_cursor_renderer;
|
||||
|
@@ -163,11 +163,13 @@ meta_renderer_x11_nested_ensure_legacy_view (MetaRendererX11Nested *renderer_x11
|
||||
.height = height
|
||||
};
|
||||
legacy_view = g_object_new (META_TYPE_RENDERER_VIEW,
|
||||
"name", "legacy nested",
|
||||
"layout", &view_layout,
|
||||
"framebuffer", COGL_FRAMEBUFFER (fake_onscreen),
|
||||
NULL);
|
||||
|
||||
meta_renderer_set_legacy_view (renderer, legacy_view);
|
||||
g_assert (!meta_renderer_get_views (renderer));
|
||||
meta_renderer_add_view (renderer, legacy_view);
|
||||
}
|
||||
|
||||
static MetaRendererView *
|
||||
@@ -211,6 +213,7 @@ meta_renderer_x11_nested_create_view (MetaRenderer *renderer,
|
||||
&view_layout);
|
||||
|
||||
view = g_object_new (META_TYPE_RENDERER_VIEW,
|
||||
"name", meta_output_get_name (output),
|
||||
"layout", &view_layout,
|
||||
"framebuffer", COGL_FRAMEBUFFER (fake_onscreen),
|
||||
"offscreen", COGL_FRAMEBUFFER (offscreen),
|
||||
|
@@ -502,11 +502,6 @@ after_stage_paint (ClutterStage *stage,
|
||||
|
||||
for (l = priv->windows; l; l = l->next)
|
||||
meta_window_actor_post_paint (l->data);
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
if (meta_is_wayland_compositor ())
|
||||
meta_wayland_compositor_paint_finished (meta_wayland_compositor_get_default ());
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1154,6 +1149,11 @@ meta_compositor_real_post_paint (MetaCompositor *compositor)
|
||||
meta_compositor_get_instance_private (compositor);
|
||||
CoglGraphicsResetStatus status;
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
if (meta_is_wayland_compositor ())
|
||||
meta_wayland_compositor_paint_finished (meta_wayland_compositor_get_default ());
|
||||
#endif
|
||||
|
||||
status = cogl_get_graphics_reset_status (priv->context);
|
||||
switch (status)
|
||||
{
|
||||
|
@@ -747,6 +747,25 @@ get_wrap_mode (GDesktopBackgroundStyle style)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
get_best_mipmap_level (CoglTexture *texture,
|
||||
int visible_width,
|
||||
int visible_height)
|
||||
{
|
||||
int mipmap_width = cogl_texture_get_width (texture);
|
||||
int mipmap_height = cogl_texture_get_height (texture);
|
||||
int halves = 0;
|
||||
|
||||
while (mipmap_width >= visible_width && mipmap_height >= visible_height)
|
||||
{
|
||||
halves++;
|
||||
mipmap_width /= 2;
|
||||
mipmap_height /= 2;
|
||||
}
|
||||
|
||||
return MAX (0, halves - 1);
|
||||
}
|
||||
|
||||
CoglTexture *
|
||||
meta_background_get_texture (MetaBackground *self,
|
||||
int monitor_index,
|
||||
@@ -854,10 +873,17 @@ meta_background_get_texture (MetaBackground *self,
|
||||
if (texture2 != NULL && self->blend_factor != 0.0)
|
||||
{
|
||||
CoglPipeline *pipeline = create_pipeline (PIPELINE_REPLACE);
|
||||
int mipmap_level;
|
||||
|
||||
mipmap_level = get_best_mipmap_level (texture2,
|
||||
texture_width,
|
||||
texture_height);
|
||||
|
||||
cogl_pipeline_set_color4f (pipeline,
|
||||
self->blend_factor, self->blend_factor, self->blend_factor, self->blend_factor);
|
||||
cogl_pipeline_set_layer_texture (pipeline, 0, texture2);
|
||||
cogl_pipeline_set_layer_wrap_mode (pipeline, 0, get_wrap_mode (self->style));
|
||||
cogl_pipeline_set_layer_max_mipmap_level (pipeline, 0, mipmap_level);
|
||||
|
||||
bare_region_visible = draw_texture (self,
|
||||
monitor->fbo, pipeline,
|
||||
@@ -876,6 +902,12 @@ meta_background_get_texture (MetaBackground *self,
|
||||
if (texture1 != NULL && self->blend_factor != 1.0)
|
||||
{
|
||||
CoglPipeline *pipeline = create_pipeline (PIPELINE_ADD);
|
||||
int mipmap_level;
|
||||
|
||||
mipmap_level = get_best_mipmap_level (texture1,
|
||||
texture_width,
|
||||
texture_height);
|
||||
|
||||
cogl_pipeline_set_color4f (pipeline,
|
||||
(1 - self->blend_factor),
|
||||
(1 - self->blend_factor),
|
||||
@@ -883,6 +915,7 @@ meta_background_get_texture (MetaBackground *self,
|
||||
(1 - self->blend_factor));;
|
||||
cogl_pipeline_set_layer_texture (pipeline, 0, texture1);
|
||||
cogl_pipeline_set_layer_wrap_mode (pipeline, 0, get_wrap_mode (self->style));
|
||||
cogl_pipeline_set_layer_max_mipmap_level (pipeline, 0, mipmap_level);
|
||||
|
||||
bare_region_visible = bare_region_visible || draw_texture (self,
|
||||
monitor->fbo, pipeline,
|
||||
|
@@ -22,7 +22,12 @@
|
||||
/**
|
||||
* SECTION:meta-shaped-texture
|
||||
* @title: MetaShapedTexture
|
||||
* @short_description: An actor to draw a masked texture.
|
||||
* @short_description: A ClutterContent which draws a shaped texture
|
||||
*
|
||||
* A MetaShapedTexture draws a #CoglTexture (often provided from a client
|
||||
* surface) in such a way that it matches any required transformations that
|
||||
* give its final shape, such as a #MetaMonitorTransform, y-invertedness, or a
|
||||
* crop-and-scale operation.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -1122,6 +1127,24 @@ meta_shaped_texture_set_transform (MetaShapedTexture *stex,
|
||||
invalidate_size (stex);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_shaped_texture_set_viewport_src_rect:
|
||||
* @stex: A #MetaShapedTexture
|
||||
* @src_rect: The viewport source rectangle
|
||||
*
|
||||
* Sets the viewport area that can be used to crop the original texture. The
|
||||
* cropped result can then be optionally scaled afterwards using
|
||||
* meta_shaped_texture_set_viewport_dst_size() as part of a crop-and-scale
|
||||
* operation.
|
||||
*
|
||||
* Note that the viewport's geometry should be provided in the coordinate space
|
||||
* of the texture received by the client, which might've been scaled as noted by
|
||||
* meta_shaped_texture_set_buffer_scale().
|
||||
*
|
||||
* %NULL is an invalid value for @src_rect. Use
|
||||
* meta_shaped_texture_reset_viewport_src_rect() if you want to remove the
|
||||
* cropping source rectangle.
|
||||
*/
|
||||
void
|
||||
meta_shaped_texture_set_viewport_src_rect (MetaShapedTexture *stex,
|
||||
graphene_rect_t *src_rect)
|
||||
@@ -1150,6 +1173,21 @@ meta_shaped_texture_reset_viewport_src_rect (MetaShapedTexture *stex)
|
||||
invalidate_size (stex);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_shaped_texture_set_viewport_dst_size:
|
||||
* @stex: #MetaShapedTexture
|
||||
* @dst_width: The final viewport width (> 0)
|
||||
* @dst_height: The final viewport height (> 0)
|
||||
*
|
||||
* Sets a viewport size on @stex of the given @width and @height, which may
|
||||
* lead to scaling the texture. If you need to have cropping, use
|
||||
* meta_shaped_texture_set_viewport_src_rect() first, after which the scaling
|
||||
* stemming from this method will be applied.
|
||||
*
|
||||
* If you no longer want to have any scaling, use
|
||||
* meta_shaped_texture_reset_viewport_dst_size() to clear the current
|
||||
* parameters.
|
||||
*/
|
||||
void
|
||||
meta_shaped_texture_set_viewport_dst_size (MetaShapedTexture *stex,
|
||||
int dst_width,
|
||||
@@ -1445,6 +1483,15 @@ meta_shaped_texture_new (void)
|
||||
return g_object_new (META_TYPE_SHAPED_TEXTURE, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_shaped_texture_set_buffer_scale:
|
||||
* @stex: A #MetaShapedTexture
|
||||
* @buffer_scale: The scale that should be applied to coorsinate space
|
||||
*
|
||||
* Instructs @stex to intepret the geometry of the input texture by scaling it
|
||||
* with @buffer_scale. This means that the #CoglTexture that is provided by a
|
||||
* client is alreay scaled by that factor.
|
||||
*/
|
||||
void
|
||||
meta_shaped_texture_set_buffer_scale (MetaShapedTexture *stex,
|
||||
int buffer_scale)
|
||||
@@ -1467,6 +1514,12 @@ meta_shaped_texture_get_buffer_scale (MetaShapedTexture *stex)
|
||||
return stex->buffer_scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_shaped_texture_get_width:
|
||||
* @stex: A #MetaShapedTexture
|
||||
*
|
||||
* Returns: The final width of @stex after its shaping operations are applied.
|
||||
*/
|
||||
int
|
||||
meta_shaped_texture_get_width (MetaShapedTexture *stex)
|
||||
{
|
||||
@@ -1477,6 +1530,12 @@ meta_shaped_texture_get_width (MetaShapedTexture *stex)
|
||||
return stex->dst_width;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_shaped_texture_get_height:
|
||||
* @stex: A #MetaShapedTexture
|
||||
*
|
||||
* Returns: The final height of @stex after its shaping operations are applied.
|
||||
*/
|
||||
int
|
||||
meta_shaped_texture_get_height (MetaShapedTexture *stex)
|
||||
{
|
||||
|
@@ -42,7 +42,6 @@ struct _MetaSurfaceActorWayland
|
||||
MetaSurfaceActor parent;
|
||||
|
||||
MetaWaylandSurface *surface;
|
||||
struct wl_list frame_callback_list;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaSurfaceActorWayland,
|
||||
@@ -56,6 +55,7 @@ meta_surface_actor_wayland_process_damage (MetaSurfaceActor *actor,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
meta_surface_actor_update_area (actor, x, y, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -63,14 +63,6 @@ meta_surface_actor_wayland_pre_paint (MetaSurfaceActor *actor)
|
||||
{
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_surface_actor_wayland_is_visible (MetaSurfaceActor *actor)
|
||||
{
|
||||
/* TODO: ensure that the buffer isn't NULL, implement
|
||||
* wayland mapping semantics */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_surface_actor_wayland_is_opaque (MetaSurfaceActor *actor)
|
||||
{
|
||||
@@ -79,23 +71,6 @@ meta_surface_actor_wayland_is_opaque (MetaSurfaceActor *actor)
|
||||
return meta_shaped_texture_is_opaque (stex);
|
||||
}
|
||||
|
||||
static void
|
||||
queue_frame_callbacks (MetaSurfaceActorWayland *self)
|
||||
{
|
||||
MetaWaylandCompositor *wayland_compositor;
|
||||
|
||||
if (!self->surface)
|
||||
return;
|
||||
|
||||
if (meta_surface_actor_is_obscured (META_SURFACE_ACTOR (self)))
|
||||
return;
|
||||
|
||||
wayland_compositor = self->surface->compositor;
|
||||
wl_list_insert_list (&wayland_compositor->frame_callbacks,
|
||||
&self->frame_callback_list);
|
||||
wl_list_init (&self->frame_callback_list);
|
||||
}
|
||||
|
||||
CoglScanout *
|
||||
meta_surface_actor_wayland_try_acquire_scanout (MetaSurfaceActorWayland *self,
|
||||
CoglOnscreen *onscreen)
|
||||
@@ -108,35 +83,13 @@ meta_surface_actor_wayland_try_acquire_scanout (MetaSurfaceActorWayland *self,
|
||||
if (!scanout)
|
||||
return NULL;
|
||||
|
||||
queue_frame_callbacks (self);
|
||||
|
||||
return scanout;
|
||||
}
|
||||
|
||||
void
|
||||
meta_surface_actor_wayland_add_frame_callbacks (MetaSurfaceActorWayland *self,
|
||||
struct wl_list *frame_callbacks)
|
||||
{
|
||||
wl_list_insert_list (&self->frame_callback_list, frame_callbacks);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_actor_wayland_paint (ClutterActor *actor,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (actor);
|
||||
|
||||
queue_frame_callbacks (self);
|
||||
|
||||
CLUTTER_ACTOR_CLASS (meta_surface_actor_wayland_parent_class)->paint (actor,
|
||||
paint_context);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_actor_wayland_dispose (GObject *object)
|
||||
{
|
||||
MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (object);
|
||||
MetaWaylandFrameCallback *cb, *next;
|
||||
MetaShapedTexture *stex;
|
||||
|
||||
stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
|
||||
@@ -150,9 +103,6 @@ meta_surface_actor_wayland_dispose (GObject *object)
|
||||
self->surface = NULL;
|
||||
}
|
||||
|
||||
wl_list_for_each_safe (cb, next, &self->frame_callback_list, link)
|
||||
wl_resource_destroy (cb->resource);
|
||||
|
||||
G_OBJECT_CLASS (meta_surface_actor_wayland_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
@@ -160,14 +110,10 @@ static void
|
||||
meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass)
|
||||
{
|
||||
MetaSurfaceActorClass *surface_actor_class = META_SURFACE_ACTOR_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
actor_class->paint = meta_surface_actor_wayland_paint;
|
||||
|
||||
surface_actor_class->process_damage = meta_surface_actor_wayland_process_damage;
|
||||
surface_actor_class->pre_paint = meta_surface_actor_wayland_pre_paint;
|
||||
surface_actor_class->is_visible = meta_surface_actor_wayland_is_visible;
|
||||
surface_actor_class->is_opaque = meta_surface_actor_wayland_is_opaque;
|
||||
|
||||
object_class->dispose = meta_surface_actor_wayland_dispose;
|
||||
@@ -185,7 +131,6 @@ meta_surface_actor_wayland_new (MetaWaylandSurface *surface)
|
||||
|
||||
g_assert (meta_is_wayland_compositor ());
|
||||
|
||||
wl_list_init (&self->frame_callback_list);
|
||||
self->surface = surface;
|
||||
g_object_add_weak_pointer (G_OBJECT (self->surface),
|
||||
(gpointer *) &self->surface);
|
||||
|
@@ -181,8 +181,8 @@ update_pixmap (MetaSurfaceActorX11 *self)
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_visible (MetaSurfaceActorX11 *self)
|
||||
gboolean
|
||||
meta_surface_actor_x11_is_visible (MetaSurfaceActorX11 *self)
|
||||
{
|
||||
return (self->pixmap != None) && !self->unredirected;
|
||||
}
|
||||
@@ -212,11 +212,12 @@ meta_surface_actor_x11_process_damage (MetaSurfaceActor *actor,
|
||||
self->does_full_damage = TRUE;
|
||||
}
|
||||
|
||||
if (!is_visible (self))
|
||||
if (!meta_surface_actor_x11_is_visible (self))
|
||||
return;
|
||||
|
||||
cogl_texture_pixmap_x11_update_area (COGL_TEXTURE_PIXMAP_X11 (self->texture),
|
||||
x, y, width, height);
|
||||
meta_surface_actor_update_area (actor, x, y, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -238,13 +239,6 @@ meta_surface_actor_x11_pre_paint (MetaSurfaceActor *actor)
|
||||
update_pixmap (self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_surface_actor_x11_is_visible (MetaSurfaceActor *actor)
|
||||
{
|
||||
MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (actor);
|
||||
return is_visible (self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_surface_actor_x11_is_opaque (MetaSurfaceActor *actor)
|
||||
{
|
||||
@@ -339,7 +333,6 @@ meta_surface_actor_x11_class_init (MetaSurfaceActorX11Class *klass)
|
||||
|
||||
surface_actor_class->process_damage = meta_surface_actor_x11_process_damage;
|
||||
surface_actor_class->pre_paint = meta_surface_actor_x11_pre_paint;
|
||||
surface_actor_class->is_visible = meta_surface_actor_x11_is_visible;
|
||||
surface_actor_class->is_opaque = meta_surface_actor_x11_is_opaque;
|
||||
}
|
||||
|
||||
|
@@ -53,6 +53,8 @@ void meta_surface_actor_x11_set_unredirected (MetaSurfaceActorX11 *self,
|
||||
|
||||
gboolean meta_surface_actor_x11_is_unredirected (MetaSurfaceActorX11 *self);
|
||||
|
||||
gboolean meta_surface_actor_x11_is_visible (MetaSurfaceActorX11 *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __META_SURFACE_ACTOR_X11_H__ */
|
||||
|
@@ -63,17 +63,11 @@ effective_unobscured_region (MetaSurfaceActor *surface_actor)
|
||||
{
|
||||
MetaSurfaceActorPrivate *priv =
|
||||
meta_surface_actor_get_instance_private (surface_actor);
|
||||
ClutterActor *actor;
|
||||
ClutterActor *actor = CLUTTER_ACTOR (surface_actor);
|
||||
|
||||
/* Fail if we have any mapped clones. */
|
||||
actor = CLUTTER_ACTOR (surface_actor);
|
||||
do
|
||||
{
|
||||
if (clutter_actor_has_mapped_clones (actor))
|
||||
return NULL;
|
||||
actor = clutter_actor_get_parent (actor);
|
||||
}
|
||||
while (actor != NULL);
|
||||
if (clutter_actor_has_mapped_clones (actor))
|
||||
return NULL;
|
||||
|
||||
return priv->unobscured_region;
|
||||
}
|
||||
@@ -419,9 +413,12 @@ meta_surface_actor_get_texture (MetaSurfaceActor *self)
|
||||
return priv->texture;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
meta_surface_actor_update_area (MetaSurfaceActor *self,
|
||||
int x, int y, int width, int height)
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
MetaSurfaceActorPrivate *priv =
|
||||
meta_surface_actor_get_instance_private (self);
|
||||
@@ -546,9 +543,6 @@ meta_surface_actor_process_damage (MetaSurfaceActor *self,
|
||||
}
|
||||
|
||||
META_SURFACE_ACTOR_GET_CLASS (self)->process_damage (self, x, y, width, height);
|
||||
|
||||
if (meta_surface_actor_is_visible (self))
|
||||
meta_surface_actor_update_area (self, x, y, width, height);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -557,12 +551,6 @@ meta_surface_actor_pre_paint (MetaSurfaceActor *self)
|
||||
META_SURFACE_ACTOR_GET_CLASS (self)->pre_paint (self);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_surface_actor_is_visible (MetaSurfaceActor *self)
|
||||
{
|
||||
return META_SURFACE_ACTOR_GET_CLASS (self)->is_visible (self);
|
||||
}
|
||||
|
||||
void
|
||||
meta_surface_actor_set_frozen (MetaSurfaceActor *self,
|
||||
gboolean frozen)
|
||||
|
@@ -25,7 +25,6 @@ struct _MetaSurfaceActorClass
|
||||
void (* process_damage) (MetaSurfaceActor *actor,
|
||||
int x, int y, int width, int height);
|
||||
void (* pre_paint) (MetaSurfaceActor *actor);
|
||||
gboolean (* is_visible) (MetaSurfaceActor *actor);
|
||||
gboolean (* is_opaque) (MetaSurfaceActor *actor);
|
||||
};
|
||||
|
||||
@@ -34,6 +33,12 @@ cairo_surface_t *meta_surface_actor_get_image (MetaSurfaceActor *self,
|
||||
|
||||
MetaShapedTexture *meta_surface_actor_get_texture (MetaSurfaceActor *self);
|
||||
|
||||
void meta_surface_actor_update_area (MetaSurfaceActor *self,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
gboolean meta_surface_actor_is_obscured (MetaSurfaceActor *self);
|
||||
|
||||
void meta_surface_actor_set_input_region (MetaSurfaceActor *self,
|
||||
@@ -45,7 +50,6 @@ cairo_region_t * meta_surface_actor_get_opaque_region (MetaSurfaceActor *self);
|
||||
void meta_surface_actor_process_damage (MetaSurfaceActor *actor,
|
||||
int x, int y, int width, int height);
|
||||
void meta_surface_actor_pre_paint (MetaSurfaceActor *actor);
|
||||
gboolean meta_surface_actor_is_visible (MetaSurfaceActor *actor);
|
||||
gboolean meta_surface_actor_is_opaque (MetaSurfaceActor *actor);
|
||||
|
||||
gboolean meta_surface_actor_is_frozen (MetaSurfaceActor *actor);
|
||||
|
@@ -1211,7 +1211,8 @@ handle_updates (MetaWindowActorX11 *actor_x11)
|
||||
|
||||
meta_surface_actor_pre_paint (surface);
|
||||
|
||||
if (!meta_surface_actor_is_visible (surface))
|
||||
if (!META_IS_SURFACE_ACTOR_X11 (surface) ||
|
||||
!meta_surface_actor_x11_is_visible (META_SURFACE_ACTOR_X11 (surface)))
|
||||
return;
|
||||
|
||||
update_frame_bounds (actor_x11);
|
||||
|
@@ -376,7 +376,7 @@ meta_make_border_region (cairo_region_t *region,
|
||||
}
|
||||
|
||||
cairo_region_t *
|
||||
meta_region_transform (cairo_region_t *region,
|
||||
meta_region_transform (const cairo_region_t *region,
|
||||
MetaMonitorTransform transform,
|
||||
int width,
|
||||
int height)
|
||||
|
@@ -106,7 +106,7 @@ cairo_region_t * meta_make_border_region (cairo_region_t *region,
|
||||
int y_amount,
|
||||
gboolean flip);
|
||||
|
||||
cairo_region_t * meta_region_transform (cairo_region_t *region,
|
||||
cairo_region_t * meta_region_transform (const cairo_region_t *region,
|
||||
MetaMonitorTransform transform,
|
||||
int width,
|
||||
int height);
|
||||
|
@@ -95,7 +95,7 @@ meta_window_delete (MetaWindow *window,
|
||||
void
|
||||
meta_window_kill (MetaWindow *window)
|
||||
{
|
||||
pid_t pid = meta_window_get_client_pid (window);
|
||||
pid_t pid = meta_window_get_pid (window);
|
||||
|
||||
if (pid > 0)
|
||||
{
|
||||
|
@@ -586,11 +586,6 @@ meta_init (void)
|
||||
g_irepository_prepend_search_path (MUTTER_PKGLIBDIR);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
if (meta_is_wayland_compositor ())
|
||||
meta_wayland_pre_clutter_init ();
|
||||
#endif
|
||||
|
||||
/* NB: When running as a hybrid wayland compositor we run our own headless X
|
||||
* server so the user can't control the X display to connect too. */
|
||||
if (!meta_is_wayland_compositor ())
|
||||
@@ -598,14 +593,6 @@ meta_init (void)
|
||||
|
||||
meta_init_backend (backend_gtype);
|
||||
|
||||
meta_clutter_init ();
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
/* Bring up Wayland. This also launches Xwayland and sets DISPLAY as well... */
|
||||
if (meta_is_wayland_compositor ())
|
||||
meta_wayland_init ();
|
||||
#endif
|
||||
|
||||
meta_set_syncing (opt_sync || (g_getenv ("MUTTER_SYNC") != NULL));
|
||||
|
||||
if (opt_replace_wm)
|
||||
|
@@ -802,22 +802,19 @@ meta_window_place (MetaWindow *window,
|
||||
if (window_place_centered (window))
|
||||
{
|
||||
/* Center on current monitor */
|
||||
int w, h;
|
||||
MetaRectangle work_area;
|
||||
MetaRectangle frame_rect;
|
||||
|
||||
meta_window_get_frame_rect (window, &frame_rect);
|
||||
|
||||
/* Warning, this function is a round trip! */
|
||||
logical_monitor = meta_backend_get_current_logical_monitor (backend);
|
||||
|
||||
w = logical_monitor->rect.width;
|
||||
h = logical_monitor->rect.height;
|
||||
meta_window_get_work_area_for_logical_monitor (window,
|
||||
logical_monitor,
|
||||
&work_area);
|
||||
meta_window_get_frame_rect (window, &frame_rect);
|
||||
|
||||
x = (w - frame_rect.width) / 2;
|
||||
y = (h - frame_rect.height) / 2;
|
||||
|
||||
x += logical_monitor->rect.x;
|
||||
y += logical_monitor->rect.y;
|
||||
x = work_area.x + (work_area.width - frame_rect.width) / 2;
|
||||
y = work_area.y + (work_area.height - frame_rect.height) / 2;
|
||||
|
||||
meta_topic (META_DEBUG_PLACEMENT, "Centered window %s on monitor %d\n",
|
||||
window->desc, logical_monitor->number);
|
||||
|
@@ -201,8 +201,6 @@ struct _MetaWindow
|
||||
char *gtk_app_menu_object_path;
|
||||
char *gtk_menubar_object_path;
|
||||
|
||||
int net_wm_pid;
|
||||
|
||||
Window xtransient_for;
|
||||
Window xgroup_leader;
|
||||
Window xclient_leader;
|
||||
@@ -550,6 +548,8 @@ struct _MetaWindow
|
||||
} placement;
|
||||
|
||||
guint unmanage_idle_id;
|
||||
|
||||
pid_t client_pid;
|
||||
};
|
||||
|
||||
struct _MetaWindowClass
|
||||
@@ -586,7 +586,7 @@ struct _MetaWindowClass
|
||||
gboolean (*update_icon) (MetaWindow *window,
|
||||
cairo_surface_t **icon,
|
||||
cairo_surface_t **mini_icon);
|
||||
uint32_t (*get_client_pid) (MetaWindow *window);
|
||||
pid_t (*get_client_pid) (MetaWindow *window);
|
||||
void (*update_main_monitor) (MetaWindow *window,
|
||||
MetaWindowUpdateMonitorFlags flags);
|
||||
void (*main_monitor_changed) (MetaWindow *window,
|
||||
@@ -821,8 +821,6 @@ gboolean meta_window_handle_ui_frame_event (MetaWindow *window,
|
||||
void meta_window_handle_ungrabbed_event (MetaWindow *window,
|
||||
const ClutterEvent *event);
|
||||
|
||||
uint32_t meta_window_get_client_pid (MetaWindow *window);
|
||||
|
||||
void meta_window_get_client_area_rect (const MetaWindow *window,
|
||||
cairo_rectangle_int_t *rect);
|
||||
void meta_window_get_titlebar_rect (MetaWindow *window,
|
||||
|
@@ -296,7 +296,7 @@ meta_window_real_update_icon (MetaWindow *window,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
static pid_t
|
||||
meta_window_real_get_client_pid (MetaWindow *window)
|
||||
{
|
||||
return 0;
|
||||
@@ -898,13 +898,13 @@ meta_window_update_snap_id (MetaWindow *window,
|
||||
static void
|
||||
meta_window_update_sandboxed_app_id (MetaWindow *window)
|
||||
{
|
||||
uint32_t pid;
|
||||
pid_t pid;
|
||||
|
||||
g_clear_pointer (&window->sandboxed_app_id, g_free);
|
||||
|
||||
pid = meta_window_get_client_pid (window);
|
||||
pid = meta_window_get_pid (window);
|
||||
|
||||
if (pid == 0)
|
||||
if (pid < 1)
|
||||
return;
|
||||
|
||||
if (meta_window_update_flatpak_id (window, pid))
|
||||
@@ -1149,7 +1149,7 @@ _meta_window_shared_new (MetaDisplay *display,
|
||||
window->is_remote = FALSE;
|
||||
window->startup_id = NULL;
|
||||
|
||||
window->net_wm_pid = -1;
|
||||
window->client_pid = 0;
|
||||
|
||||
window->xtransient_for = None;
|
||||
window->xclient_leader = None;
|
||||
@@ -7584,35 +7584,26 @@ meta_window_get_transient_for (MetaWindow *window)
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_get_client_pid:
|
||||
* meta_window_get_pid:
|
||||
* @window: a #MetaWindow
|
||||
*
|
||||
* Returns the pid of the process that created this window, if available
|
||||
* to the windowing system.
|
||||
*
|
||||
* Note that the value returned by this is vulnerable to spoofing attacks
|
||||
* by the client.
|
||||
*
|
||||
* Return value: the pid, or 0 if not known.
|
||||
*/
|
||||
uint32_t
|
||||
meta_window_get_client_pid (MetaWindow *window)
|
||||
{
|
||||
return META_WINDOW_GET_CLASS (window)->get_client_pid (window);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_get_pid:
|
||||
* @window: a #MetaWindow
|
||||
*
|
||||
* Returns pid of the process that created this window, if known (obtained from
|
||||
* the _NET_WM_PID property).
|
||||
*
|
||||
* Return value: the pid, or -1 if not known.
|
||||
*/
|
||||
int
|
||||
pid_t
|
||||
meta_window_get_pid (MetaWindow *window)
|
||||
{
|
||||
g_return_val_if_fail (META_IS_WINDOW (window), -1);
|
||||
g_return_val_if_fail (META_IS_WINDOW (window), 0);
|
||||
|
||||
return window->net_wm_pid;
|
||||
if (window->client_pid == 0)
|
||||
window->client_pid = META_WINDOW_GET_CLASS (window)->get_client_pid (window);
|
||||
|
||||
return window->client_pid;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -504,14 +504,20 @@ if have_wayland
|
||||
'wayland/meta-wayland-data-device.h',
|
||||
'wayland/meta-wayland-data-device-primary.c',
|
||||
'wayland/meta-wayland-data-device-primary.h',
|
||||
'wayland/meta-wayland-data-device-primary-legacy.c',
|
||||
'wayland/meta-wayland-data-device-primary-legacy.h',
|
||||
'wayland/meta-wayland-data-offer.c',
|
||||
'wayland/meta-wayland-data-offer.h',
|
||||
'wayland/meta-wayland-data-offer-primary.c',
|
||||
'wayland/meta-wayland-data-offer-primary.h',
|
||||
'wayland/meta-wayland-data-offer-primary-legacy.c',
|
||||
'wayland/meta-wayland-data-offer-primary-legacy.h',
|
||||
'wayland/meta-wayland-data-source.c',
|
||||
'wayland/meta-wayland-data-source.h',
|
||||
'wayland/meta-wayland-data-source-primary.c',
|
||||
'wayland/meta-wayland-data-source-primary.h',
|
||||
'wayland/meta-wayland-data-source-primary-legacy.c',
|
||||
'wayland/meta-wayland-data-source-primary-legacy.h',
|
||||
'wayland/meta-wayland-dma-buf.c',
|
||||
'wayland/meta-wayland-dma-buf.h',
|
||||
'wayland/meta-wayland-dnd-surface.c',
|
||||
@@ -808,6 +814,7 @@ if have_wayland
|
||||
['linux-dmabuf', 'unstable', 'v1', ],
|
||||
['pointer-constraints', 'unstable', 'v1', ],
|
||||
['pointer-gestures', 'unstable', 'v1', ],
|
||||
['primary-selection', 'unstable', 'v1', ],
|
||||
['relative-pointer', 'unstable', 'v1', ],
|
||||
['tablet', 'unstable', 'v2', ],
|
||||
['text-input', 'unstable', 'v3', ],
|
||||
|
@@ -204,6 +204,7 @@ typedef enum
|
||||
* @META_CURSOR_POINTING_HAND: pointing hand
|
||||
* @META_CURSOR_CROSSHAIR: crosshair (action forbidden)
|
||||
* @META_CURSOR_IBEAM: I-beam (text input)
|
||||
* @META_CURSOR_BLANK: Invisible cursor
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
@@ -226,6 +227,7 @@ typedef enum
|
||||
META_CURSOR_POINTING_HAND,
|
||||
META_CURSOR_CROSSHAIR,
|
||||
META_CURSOR_IBEAM,
|
||||
META_CURSOR_BLANK,
|
||||
META_CURSOR_LAST
|
||||
} MetaCursor;
|
||||
|
||||
|
@@ -328,7 +328,7 @@ META_EXPORT
|
||||
guint32 meta_window_get_user_time (MetaWindow *window);
|
||||
|
||||
META_EXPORT
|
||||
int meta_window_get_pid (MetaWindow *window);
|
||||
pid_t meta_window_get_pid (MetaWindow *window);
|
||||
|
||||
META_EXPORT
|
||||
const char *meta_window_get_client_machine (MetaWindow *window);
|
||||
|
@@ -716,8 +716,8 @@ actor_pivot (void)
|
||||
clutter_actor_add_child (stage, actor_explicit);
|
||||
|
||||
/* Fake allocation or pivot-point will not have any effect */
|
||||
clutter_actor_allocate (actor_implicit, &allocation, CLUTTER_ALLOCATION_NONE);
|
||||
clutter_actor_allocate (actor_explicit, &allocation, CLUTTER_ALLOCATION_NONE);
|
||||
clutter_actor_allocate (actor_implicit, &allocation);
|
||||
clutter_actor_allocate (actor_explicit, &allocation);
|
||||
|
||||
clutter_actor_set_pivot_point (actor_implicit, 0.5, 0.5);
|
||||
clutter_actor_set_pivot_point (actor_explicit, 0.5, 0.5);
|
||||
|
@@ -82,7 +82,7 @@ on_timeout (gpointer data)
|
||||
/* Only allocated actors can be picked, so force an allocation
|
||||
* of the overlay actor here.
|
||||
*/
|
||||
clutter_actor_allocate (over_actor, &over_actor_box, 0);
|
||||
clutter_actor_allocate (over_actor, &over_actor_box);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("Clipped covering actor:\n");
|
||||
|
@@ -245,75 +245,12 @@ script_named_object (void)
|
||||
|
||||
manager = clutter_box_get_layout_manager (CLUTTER_BOX (actor));
|
||||
g_assert (CLUTTER_IS_BOX_LAYOUT (manager));
|
||||
g_assert (clutter_box_layout_get_vertical (CLUTTER_BOX_LAYOUT (manager)));
|
||||
g_assert (clutter_box_layout_get_orientation (CLUTTER_BOX_LAYOUT (manager)) == CLUTTER_ORIENTATION_VERTICAL);
|
||||
|
||||
g_object_unref (script);
|
||||
g_free (test_file);
|
||||
}
|
||||
|
||||
static void
|
||||
script_layout_property (void)
|
||||
{
|
||||
ClutterScript *script = clutter_script_new ();
|
||||
GObject *manager, *container, *actor1, *actor2;
|
||||
GError *error = NULL;
|
||||
gchar *test_file;
|
||||
gboolean x_fill, expand;
|
||||
ClutterBoxAlignment y_align;
|
||||
|
||||
test_file = g_test_build_filename (G_TEST_DIST, "scripts", "test-script-layout-property.json", NULL);
|
||||
clutter_script_load_from_file (script, test_file, &error);
|
||||
if (g_test_verbose () && error)
|
||||
g_print ("Error: %s", error->message);
|
||||
|
||||
g_assert_no_error (error);
|
||||
|
||||
manager = container = actor1 = actor2 = NULL;
|
||||
clutter_script_get_objects (script,
|
||||
"manager", &manager,
|
||||
"container", &container,
|
||||
"actor-1", &actor1,
|
||||
"actor-2", &actor2,
|
||||
NULL);
|
||||
|
||||
g_assert (CLUTTER_IS_LAYOUT_MANAGER (manager));
|
||||
g_assert (CLUTTER_IS_CONTAINER (container));
|
||||
g_assert (CLUTTER_IS_ACTOR (actor1));
|
||||
g_assert (CLUTTER_IS_ACTOR (actor2));
|
||||
|
||||
x_fill = FALSE;
|
||||
y_align = CLUTTER_BOX_ALIGNMENT_START;
|
||||
expand = FALSE;
|
||||
clutter_layout_manager_child_get (CLUTTER_LAYOUT_MANAGER (manager),
|
||||
CLUTTER_CONTAINER (container),
|
||||
CLUTTER_ACTOR (actor1),
|
||||
"x-fill", &x_fill,
|
||||
"y-align", &y_align,
|
||||
"expand", &expand,
|
||||
NULL);
|
||||
|
||||
g_assert (x_fill);
|
||||
g_assert (y_align == CLUTTER_BOX_ALIGNMENT_CENTER);
|
||||
g_assert (expand);
|
||||
|
||||
x_fill = TRUE;
|
||||
y_align = CLUTTER_BOX_ALIGNMENT_START;
|
||||
expand = TRUE;
|
||||
clutter_layout_manager_child_get (CLUTTER_LAYOUT_MANAGER (manager),
|
||||
CLUTTER_CONTAINER (container),
|
||||
CLUTTER_ACTOR (actor2),
|
||||
"x-fill", &x_fill,
|
||||
"y-align", &y_align,
|
||||
"expand", &expand,
|
||||
NULL);
|
||||
|
||||
g_assert (x_fill == FALSE);
|
||||
g_assert (y_align == CLUTTER_BOX_ALIGNMENT_END);
|
||||
g_assert (expand == FALSE);
|
||||
|
||||
g_object_unref (script);
|
||||
}
|
||||
|
||||
static void
|
||||
script_margin (void)
|
||||
{
|
||||
@@ -362,6 +299,5 @@ CLUTTER_TEST_SUITE (
|
||||
CLUTTER_TEST_UNIT ("/script/container-child", script_child)
|
||||
CLUTTER_TEST_UNIT ("/script/named-object", script_named_object)
|
||||
CLUTTER_TEST_UNIT ("/script/object-property", script_object_property)
|
||||
CLUTTER_TEST_UNIT ("/script/layout-property", script_layout_property)
|
||||
CLUTTER_TEST_UNIT ("/script/actor-margin", script_margin)
|
||||
)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user