Compare commits
66 Commits
wip/carlos
...
wip/cally-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b856008914 | ||
|
|
d823a54b5d | ||
|
|
e06daa58c3 | ||
|
|
1880e22229 | ||
|
|
bd28581471 | ||
|
|
82470cd40d | ||
|
|
b4972f573c | ||
|
|
c97c409c50 | ||
|
|
989e2ccc46 | ||
|
|
e09e62d585 | ||
|
|
033f0d11bf | ||
|
|
668eb318c7 | ||
|
|
449cbe153b | ||
|
|
9b8e5a05f5 | ||
|
|
d14c8cf9a4 | ||
|
|
4571de5772 | ||
|
|
62f449d7d5 | ||
|
|
476ef76de6 | ||
|
|
48de81b63e | ||
|
|
2ee3d5392b | ||
|
|
0f2a33cc9c | ||
|
|
2ce622f057 | ||
|
|
76083d76af | ||
|
|
132060db21 | ||
|
|
c7f2ae1b16 | ||
|
|
24a0e72ae9 | ||
|
|
5c4938e479 | ||
|
|
322b51cded | ||
|
|
b46bc98d44 | ||
|
|
da5be1fdea | ||
|
|
bc18438cb0 | ||
|
|
e3c0fcf7d5 | ||
|
|
73cb96ddb9 | ||
|
|
1cb59f44ab | ||
|
|
a55a286b15 | ||
|
|
18e7b814f2 | ||
|
|
e073076119 | ||
|
|
5d58156134 | ||
|
|
c38fa4fa5c | ||
|
|
5201d77b0b | ||
|
|
aedf692e0c | ||
|
|
5dfd86ebe7 | ||
|
|
9e41f687a0 | ||
|
|
61356caa06 | ||
|
|
4300f1f91d | ||
|
|
d26dc4ae44 | ||
|
|
bd45a00fa3 | ||
|
|
793a9d45e1 | ||
|
|
43295bdcc4 | ||
|
|
43e12dab7b | ||
|
|
c4535fdf85 | ||
|
|
d2c3272eb7 | ||
|
|
90c4b6492f | ||
|
|
b7bf42e778 | ||
|
|
e849667be6 | ||
|
|
424016d66c | ||
|
|
a4f55d4986 | ||
|
|
1b33a5a3a7 | ||
|
|
36111270aa | ||
|
|
6e0cfd3e55 | ||
|
|
5671f0a284 | ||
|
|
a7e63bea6c | ||
|
|
94b3c334e5 | ||
|
|
efb0addb62 | ||
|
|
988da215c8 | ||
|
|
551a57ed7f |
@@ -4,6 +4,7 @@ stages:
|
||||
- review
|
||||
- build
|
||||
- test
|
||||
- coverage
|
||||
|
||||
check-commit-log:
|
||||
stage: review
|
||||
@@ -17,7 +18,7 @@ check-commit-log:
|
||||
build-mutter:
|
||||
stage: build
|
||||
script:
|
||||
- meson . build -Dbuildtype=debugoptimized -Degl_device=true -Dwayland_eglstream=true --werror --prefix /usr
|
||||
- meson . build -Dbuildtype=debugoptimized -Db_coverage=true -Degl_device=true -Dwayland_eglstream=true --werror --prefix /usr
|
||||
- ninja -C build
|
||||
- ninja -C build install
|
||||
artifacts:
|
||||
@@ -35,9 +36,8 @@ build-without-opengl-and-glx:
|
||||
- ninja -C build
|
||||
- ninja -C build install
|
||||
artifacts:
|
||||
expire_in: 1 day
|
||||
paths:
|
||||
- build
|
||||
- build/meson-logs
|
||||
only:
|
||||
- merge_requests
|
||||
- /^.*$/
|
||||
@@ -49,9 +49,8 @@ build-without-native-backend-and-wayland:
|
||||
- ninja -C build
|
||||
- ninja -C build install
|
||||
artifacts:
|
||||
expire_in: 1 day
|
||||
paths:
|
||||
- build
|
||||
- build/meson-logs
|
||||
only:
|
||||
- merge_requests
|
||||
- /^.*$/
|
||||
@@ -66,7 +65,6 @@ test-mutter:
|
||||
G_SLICE: "always-malloc"
|
||||
MALLOC_CHECK_: "3"
|
||||
NO_AT_BRIDGE: "1"
|
||||
MALLOC_PERTURB_: "123"
|
||||
script:
|
||||
- dconf update
|
||||
- mkdir -m 700 $XDG_RUNTIME_DIR
|
||||
@@ -74,10 +72,30 @@ test-mutter:
|
||||
- >
|
||||
dbus-run-session -- xvfb-run -s '+iglx -noreset'
|
||||
meson test -C build --no-rebuild -t 10 --verbose --no-stdsplit --print-errorlogs --wrap catchsegv
|
||||
artifacts:
|
||||
expire_in: 1 day
|
||||
paths:
|
||||
- build
|
||||
only:
|
||||
- merge_requests
|
||||
- /^.*$/
|
||||
|
||||
test-mutter-coverage:
|
||||
stage: coverage
|
||||
dependencies:
|
||||
- test-mutter
|
||||
script:
|
||||
- ninja -C build coverage
|
||||
- cat build/meson-logs/coverage.txt
|
||||
artifacts:
|
||||
paths:
|
||||
- build/meson-logs
|
||||
when: manual
|
||||
except:
|
||||
refs:
|
||||
- tags
|
||||
- master
|
||||
|
||||
can-build-gnome-shell:
|
||||
stage: test
|
||||
dependencies:
|
||||
|
||||
@@ -16,7 +16,7 @@ RUN dnf -y update && dnf -y upgrade && \
|
||||
|
||||
# For running unit tests
|
||||
dnf install -y xorg-x11-server-Xvfb mesa-dri-drivers dbus dbus-x11 \
|
||||
'*/xvfb-run' gdm-lib accountsservice-libs gnome-control-center \
|
||||
'*/xvfb-run' gdm-lib accountsservice-libs gnome-control-center gcovr \
|
||||
--setopt=install_weak_deps=False && \
|
||||
|
||||
# GNOME Shell
|
||||
|
||||
33
NEWS
33
NEWS
@@ -1,3 +1,36 @@
|
||||
3.37.1
|
||||
======
|
||||
* Fix screencasting non-maximized windows [Jonas Å.; !1174]
|
||||
* Make window-aliveness checks less aggressive [Jonas Å.; !1182]
|
||||
* Fix stylus coordinates when using screen rotation [Jonas T.; #1118]
|
||||
* Preserve keyboard state on VT switch [Olivier; !1185]
|
||||
* Remove Clutter's drag and drop actions [Jonas D.; !789]
|
||||
* Cancel clicks/gestures actions on disable [Georges; !1188]
|
||||
* Fix various clipboard issues [Carlos; !1186, !1198, !1203, !1204, !1206]
|
||||
* Fix trackball button scrolling [Phillip; #1120]
|
||||
* Fix tiled monitor support [Jonas; !1199]
|
||||
* Support unredirecting fullscreen wayland surfaces [Jonas Å.; !798]
|
||||
* Support area screencasts [Jonas Å.; !1207]
|
||||
* Synchronize shadows to server-side decorations [Olivier; !1214]
|
||||
* Allow inhibiting remote access [Jonas Å.; !1212]
|
||||
* Fix overview key on X11 when using multiple keyboard layouts [Olivier; !1219]
|
||||
* Fixed crashes [Jonas, D., Carlos; !1173, !1183, !1012]
|
||||
* Misc. bug fixes and cleanups [Andre, Georges, Christian, Jonas Å., Andre,
|
||||
Simon, Florian, Carlos, Adam, Marco, Thomas, Elias, Pekka, Jonas D.,
|
||||
Laurent; !1169, !1168, !1166, !1170, !1167, !1172, !1175, !1176, !1184,
|
||||
!1126, !1187, !1191, !1195, !1179, !1200, !1193, !1209, !1213, !1208,
|
||||
#1074, !1223]
|
||||
|
||||
Contributors:
|
||||
Marco Trevisan (Treviño), Elias Aebi, Thomas Hindoe Paaboel Andersen,
|
||||
Laurent Bigonville, Jonas Dreßler, Olivier Fourdan, Carlos Garnacho,
|
||||
Adam Jackson, Andre Moreira Magalhaes, Simon McVittie, Florian Müllner,
|
||||
Georges Basile Stavracas Neto, Pekka Paalanen, Christian Rauch, Jonas Troeger,
|
||||
Phillip Wood, Jonas Ådahl
|
||||
|
||||
Translators:
|
||||
Dušan Kazik [sk], Christian Kirbach [de]
|
||||
|
||||
3.36.0
|
||||
======
|
||||
* Fix placement of popup windows in multi-monitor setups [Jonas; !1110]
|
||||
|
||||
@@ -767,10 +767,10 @@ static gboolean
|
||||
cally_actor_action_do_action (AtkAction *action,
|
||||
gint index)
|
||||
{
|
||||
CallyActor *cally_actor = NULL;
|
||||
AtkStateSet *set = NULL;
|
||||
CallyActorPrivate *priv = NULL;
|
||||
CallyActorActionInfo *info = NULL;
|
||||
CallyActor *cally_actor = NULL;
|
||||
g_autoptr (AtkStateSet) set = NULL;
|
||||
CallyActorPrivate *priv = NULL;
|
||||
CallyActorActionInfo *info = NULL;
|
||||
|
||||
cally_actor = CALLY_ACTOR (action);
|
||||
priv = cally_actor->priv;
|
||||
@@ -784,8 +784,6 @@ cally_actor_action_do_action (AtkAction *action,
|
||||
!atk_state_set_contains_state (set, ATK_STATE_SHOWING))
|
||||
return FALSE;
|
||||
|
||||
g_object_unref (set);
|
||||
|
||||
info = _cally_actor_get_action_info (cally_actor, index);
|
||||
|
||||
if (info == NULL)
|
||||
|
||||
@@ -1198,28 +1198,21 @@ clutter_actor_verify_map_state (ClutterActor *self)
|
||||
|
||||
if (CLUTTER_ACTOR_IS_REALIZED (self))
|
||||
{
|
||||
/* all bets are off during reparent when we're potentially realized,
|
||||
* but should not be according to invariants
|
||||
*/
|
||||
if (!CLUTTER_ACTOR_IN_REPARENT (self))
|
||||
if (priv->parent == NULL)
|
||||
{
|
||||
if (priv->parent == NULL)
|
||||
if (!CLUTTER_ACTOR_IS_TOPLEVEL (self))
|
||||
{
|
||||
if (CLUTTER_ACTOR_IS_TOPLEVEL (self))
|
||||
{
|
||||
}
|
||||
else
|
||||
g_warning ("Realized non-toplevel actor '%s' should "
|
||||
"have a parent",
|
||||
_clutter_actor_get_debug_name (self));
|
||||
}
|
||||
else if (!CLUTTER_ACTOR_IS_REALIZED (priv->parent))
|
||||
{
|
||||
g_warning ("Realized actor %s has an unrealized parent %s",
|
||||
_clutter_actor_get_debug_name (self),
|
||||
_clutter_actor_get_debug_name (priv->parent));
|
||||
g_warning ("Realized non-toplevel actor '%s' should "
|
||||
"have a parent",
|
||||
_clutter_actor_get_debug_name (self));
|
||||
}
|
||||
}
|
||||
else if (!CLUTTER_ACTOR_IS_REALIZED (priv->parent))
|
||||
{
|
||||
g_warning ("Realized actor %s has an unrealized parent %s",
|
||||
_clutter_actor_get_debug_name (self),
|
||||
_clutter_actor_get_debug_name (priv->parent));
|
||||
}
|
||||
}
|
||||
|
||||
if (CLUTTER_ACTOR_IS_MAPPED (self))
|
||||
@@ -1228,70 +1221,64 @@ clutter_actor_verify_map_state (ClutterActor *self)
|
||||
g_warning ("Actor '%s' is mapped but not realized",
|
||||
_clutter_actor_get_debug_name (self));
|
||||
|
||||
/* remaining bets are off during reparent when we're potentially
|
||||
* mapped, but should not be according to invariants
|
||||
*/
|
||||
if (!CLUTTER_ACTOR_IN_REPARENT (self))
|
||||
if (priv->parent == NULL)
|
||||
{
|
||||
if (priv->parent == NULL)
|
||||
if (CLUTTER_ACTOR_IS_TOPLEVEL (self))
|
||||
{
|
||||
if (CLUTTER_ACTOR_IS_TOPLEVEL (self))
|
||||
if (!CLUTTER_ACTOR_IS_VISIBLE (self) &&
|
||||
!CLUTTER_ACTOR_IN_DESTRUCTION (self))
|
||||
{
|
||||
if (!CLUTTER_ACTOR_IS_VISIBLE (self) &&
|
||||
!CLUTTER_ACTOR_IN_DESTRUCTION (self))
|
||||
{
|
||||
g_warning ("Toplevel actor '%s' is mapped "
|
||||
"but not visible",
|
||||
_clutter_actor_get_debug_name (self));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Mapped actor '%s' should have a parent",
|
||||
g_warning ("Toplevel actor '%s' is mapped "
|
||||
"but not visible",
|
||||
_clutter_actor_get_debug_name (self));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ClutterActor *iter = self;
|
||||
g_warning ("Mapped actor '%s' should have a parent",
|
||||
_clutter_actor_get_debug_name (self));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ClutterActor *iter = self;
|
||||
|
||||
/* check for the enable_paint_unmapped flag on the actor
|
||||
* and parents; if the flag is enabled at any point of this
|
||||
* branch of the scene graph then all the later checks
|
||||
* become pointless
|
||||
*/
|
||||
while (iter != NULL)
|
||||
{
|
||||
if (iter->priv->enable_paint_unmapped)
|
||||
return;
|
||||
/* check for the enable_paint_unmapped flag on the actor
|
||||
* and parents; if the flag is enabled at any point of this
|
||||
* branch of the scene graph then all the later checks
|
||||
* become pointless
|
||||
*/
|
||||
while (iter != NULL)
|
||||
{
|
||||
if (iter->priv->enable_paint_unmapped)
|
||||
return;
|
||||
|
||||
iter = iter->priv->parent;
|
||||
}
|
||||
iter = iter->priv->parent;
|
||||
}
|
||||
|
||||
if (!CLUTTER_ACTOR_IS_VISIBLE (priv->parent))
|
||||
{
|
||||
g_warning ("Actor '%s' should not be mapped if parent '%s'"
|
||||
"is not visible",
|
||||
_clutter_actor_get_debug_name (self),
|
||||
_clutter_actor_get_debug_name (priv->parent));
|
||||
}
|
||||
if (!CLUTTER_ACTOR_IS_VISIBLE (priv->parent))
|
||||
{
|
||||
g_warning ("Actor '%s' should not be mapped if parent '%s'"
|
||||
"is not visible",
|
||||
_clutter_actor_get_debug_name (self),
|
||||
_clutter_actor_get_debug_name (priv->parent));
|
||||
}
|
||||
|
||||
if (!CLUTTER_ACTOR_IS_REALIZED (priv->parent))
|
||||
{
|
||||
g_warning ("Actor '%s' should not be mapped if parent '%s'"
|
||||
"is not realized",
|
||||
_clutter_actor_get_debug_name (self),
|
||||
_clutter_actor_get_debug_name (priv->parent));
|
||||
}
|
||||
if (!CLUTTER_ACTOR_IS_REALIZED (priv->parent))
|
||||
{
|
||||
g_warning ("Actor '%s' should not be mapped if parent '%s'"
|
||||
"is not realized",
|
||||
_clutter_actor_get_debug_name (self),
|
||||
_clutter_actor_get_debug_name (priv->parent));
|
||||
}
|
||||
|
||||
if (!CLUTTER_ACTOR_IS_TOPLEVEL (priv->parent))
|
||||
{
|
||||
if (!CLUTTER_ACTOR_IS_MAPPED (priv->parent))
|
||||
g_warning ("Actor '%s' is mapped but its non-toplevel "
|
||||
"parent '%s' is not mapped",
|
||||
_clutter_actor_get_debug_name (self),
|
||||
_clutter_actor_get_debug_name (priv->parent));
|
||||
}
|
||||
if (!CLUTTER_ACTOR_IS_TOPLEVEL (priv->parent))
|
||||
{
|
||||
if (!CLUTTER_ACTOR_IS_MAPPED (priv->parent))
|
||||
g_warning ("Actor '%s' is mapped but its non-toplevel "
|
||||
"parent '%s' is not mapped",
|
||||
_clutter_actor_get_debug_name (self),
|
||||
_clutter_actor_get_debug_name (priv->parent));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1586,13 +1573,10 @@ clutter_actor_update_map_state (ClutterActor *self,
|
||||
_clutter_actor_get_debug_name (priv->parent));
|
||||
}
|
||||
|
||||
/* If in reparent, we temporarily suspend unmap and unrealize.
|
||||
*
|
||||
* We want to go in the order "realize, map" and "unmap, unrealize"
|
||||
*/
|
||||
/* We want to go in the order "realize, map" and "unmap, unrealize" */
|
||||
|
||||
/* Unmap */
|
||||
if (!should_be_mapped && !CLUTTER_ACTOR_IN_REPARENT (self))
|
||||
if (!should_be_mapped)
|
||||
clutter_actor_set_mapped (self, FALSE);
|
||||
|
||||
/* Realize */
|
||||
@@ -1603,7 +1587,7 @@ clutter_actor_update_map_state (ClutterActor *self,
|
||||
g_assert (!(must_be_realized && !may_be_realized));
|
||||
|
||||
/* Unrealize */
|
||||
if (!may_be_realized && !CLUTTER_ACTOR_IN_REPARENT (self))
|
||||
if (!may_be_realized)
|
||||
clutter_actor_unrealize_not_hiding (self);
|
||||
|
||||
/* Map */
|
||||
@@ -3092,96 +3076,6 @@ _clutter_actor_transform_and_project_box (ClutterActor *self,
|
||||
_clutter_actor_fully_transform_vertices (self, box_vertices, verts, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_get_allocation_vertices:
|
||||
* @self: A #ClutterActor
|
||||
* @ancestor: (allow-none): A #ClutterActor to calculate the vertices
|
||||
* against, or %NULL to use the #ClutterStage
|
||||
* @verts: (out) (array fixed-size=4): return
|
||||
* location for an array of 4 #graphene_point3d_t in which to store the result
|
||||
*
|
||||
* Calculates the transformed coordinates of the four corners of the
|
||||
* actor in the plane of @ancestor. The returned vertices relate to
|
||||
* the #ClutterActorBox coordinates as follows:
|
||||
*
|
||||
* - @verts[0] contains (x1, y1)
|
||||
* - @verts[1] contains (x2, y1)
|
||||
* - @verts[2] contains (x1, y2)
|
||||
* - @verts[3] contains (x2, y2)
|
||||
*
|
||||
* If @ancestor is %NULL the ancestor will be the #ClutterStage. In
|
||||
* this case, the coordinates returned will be the coordinates on
|
||||
* the stage before the projection is applied. This is different from
|
||||
* the behaviour of clutter_actor_get_abs_allocation_vertices().
|
||||
*
|
||||
* Since: 0.6
|
||||
*/
|
||||
void
|
||||
clutter_actor_get_allocation_vertices (ClutterActor *self,
|
||||
ClutterActor *ancestor,
|
||||
graphene_point3d_t *verts)
|
||||
{
|
||||
ClutterActorPrivate *priv;
|
||||
ClutterActorBox box;
|
||||
graphene_point3d_t vertices[4];
|
||||
CoglMatrix modelview;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR (self));
|
||||
g_return_if_fail (ancestor == NULL || CLUTTER_IS_ACTOR (ancestor));
|
||||
|
||||
if (ancestor == NULL)
|
||||
ancestor = _clutter_actor_get_stage_internal (self);
|
||||
|
||||
/* Fallback to a NOP transform if the actor isn't parented under a
|
||||
* stage. */
|
||||
if (ancestor == NULL)
|
||||
ancestor = self;
|
||||
|
||||
priv = self->priv;
|
||||
|
||||
/* if the actor needs to be allocated we force a relayout, so that
|
||||
* we will have valid values to use in the transformations */
|
||||
if (priv->needs_allocation)
|
||||
{
|
||||
ClutterActor *stage = _clutter_actor_get_stage_internal (self);
|
||||
if (stage)
|
||||
_clutter_stage_maybe_relayout (stage);
|
||||
else
|
||||
{
|
||||
box.x1 = box.y1 = 0;
|
||||
/* The result isn't really meaningful in this case but at
|
||||
* least try to do something *vaguely* reasonable... */
|
||||
clutter_actor_get_size (self, &box.x2, &box.y2);
|
||||
}
|
||||
}
|
||||
|
||||
clutter_actor_get_allocation_box (self, &box);
|
||||
|
||||
vertices[0].x = box.x1;
|
||||
vertices[0].y = box.y1;
|
||||
vertices[0].z = 0;
|
||||
vertices[1].x = box.x2;
|
||||
vertices[1].y = box.y1;
|
||||
vertices[1].z = 0;
|
||||
vertices[2].x = box.x1;
|
||||
vertices[2].y = box.y2;
|
||||
vertices[2].z = 0;
|
||||
vertices[3].x = box.x2;
|
||||
vertices[3].y = box.y2;
|
||||
vertices[3].z = 0;
|
||||
|
||||
_clutter_actor_get_relative_transformation_matrix (self, ancestor,
|
||||
&modelview);
|
||||
|
||||
cogl_matrix_transform_points (&modelview,
|
||||
3,
|
||||
sizeof (graphene_point3d_t),
|
||||
vertices,
|
||||
sizeof (graphene_point3d_t),
|
||||
vertices,
|
||||
4);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_get_abs_allocation_vertices:
|
||||
* @self: A #ClutterActor
|
||||
@@ -4578,8 +4472,7 @@ clutter_actor_remove_child_internal (ClutterActor *self,
|
||||
clutter_actor_queue_compute_expand (self);
|
||||
}
|
||||
|
||||
if (emit_parent_set && !CLUTTER_ACTOR_IN_REPARENT (child) &&
|
||||
!CLUTTER_ACTOR_IN_DESTRUCTION (child))
|
||||
if (emit_parent_set && !CLUTTER_ACTOR_IN_DESTRUCTION (child))
|
||||
{
|
||||
child->priv->needs_compute_resource_scale = TRUE;
|
||||
g_signal_emit (child, actor_signals[PARENT_SET], 0, self);
|
||||
@@ -13193,7 +13086,7 @@ clutter_actor_add_child_internal (ClutterActor *self,
|
||||
clutter_actor_queue_compute_expand (self);
|
||||
}
|
||||
|
||||
if (emit_parent_set && !CLUTTER_ACTOR_IN_REPARENT (child))
|
||||
if (emit_parent_set)
|
||||
{
|
||||
child->priv->needs_compute_resource_scale = TRUE;
|
||||
g_signal_emit (child, actor_signals[PARENT_SET], 0, NULL);
|
||||
|
||||
@@ -443,10 +443,6 @@ CLUTTER_EXPORT
|
||||
void clutter_actor_get_allocation_box (ClutterActor *self,
|
||||
ClutterActorBox *box);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_get_allocation_vertices (ClutterActor *self,
|
||||
ClutterActor *ancestor,
|
||||
graphene_point3d_t *verts);
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_actor_has_allocation (ClutterActor *self);
|
||||
CLUTTER_EXPORT
|
||||
void clutter_actor_set_size (ClutterActor *self,
|
||||
|
||||
@@ -27,35 +27,23 @@
|
||||
* @short_description: Interface for animatable classes
|
||||
*
|
||||
* #ClutterAnimatable is an interface that allows a #GObject class
|
||||
* to control how a #ClutterAnimation will animate a property.
|
||||
* to control how an actor will animate a property.
|
||||
*
|
||||
* Each #ClutterAnimatable should implement the
|
||||
* #ClutterAnimatableInterface.interpolate_property() virtual function of the
|
||||
* interface to compute the animation state between two values of an interval
|
||||
* depending on a progress factor, expressed as a floating point value.
|
||||
*
|
||||
* If a #ClutterAnimatable is animated by a #ClutterAnimation
|
||||
* instance, the #ClutterAnimation will call
|
||||
* clutter_animatable_interpolate_property() passing the name of the
|
||||
* currently animated property; the values interval; and the progress factor.
|
||||
* The #ClutterAnimatable implementation should return the computed value for
|
||||
* the animated
|
||||
* property.
|
||||
*
|
||||
* #ClutterAnimatable is available since Clutter 1.0
|
||||
*/
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
|
||||
|
||||
#include "clutter-animatable.h"
|
||||
#include "clutter-interval.h"
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-private.h"
|
||||
|
||||
#include "deprecated/clutter-animation.h"
|
||||
|
||||
G_DEFINE_INTERFACE (ClutterAnimatable, clutter_animatable, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
|
||||
@@ -42,8 +42,6 @@ G_DECLARE_INTERFACE (ClutterAnimatable, clutter_animatable,
|
||||
|
||||
/**
|
||||
* ClutterAnimatableInterface:
|
||||
* @animate_property: virtual function for custom interpolation of a
|
||||
* property. This virtual function is deprecated
|
||||
* @find_property: virtual function for retrieving the #GParamSpec of
|
||||
* an animatable property
|
||||
* @get_initial_state: virtual function for retrieving the initial
|
||||
@@ -53,9 +51,6 @@ G_DECLARE_INTERFACE (ClutterAnimatable, clutter_animatable,
|
||||
* @interpolate_value: virtual function for interpolating the progress
|
||||
* of a property
|
||||
*
|
||||
* Base interface for #GObject<!-- -->s that can be animated by a
|
||||
* a #ClutterAnimation.
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
struct _ClutterAnimatableInterface
|
||||
@@ -64,13 +59,6 @@ struct _ClutterAnimatableInterface
|
||||
GTypeInterface parent_iface;
|
||||
|
||||
/*< public >*/
|
||||
gboolean (* animate_property) (ClutterAnimatable *animatable,
|
||||
ClutterAnimation *animation,
|
||||
const gchar *property_name,
|
||||
const GValue *initial_value,
|
||||
const GValue *final_value,
|
||||
gdouble progress,
|
||||
GValue *value);
|
||||
GParamSpec *(* find_property) (ClutterAnimatable *animatable,
|
||||
const gchar *property_name);
|
||||
void (* get_initial_state) (ClutterAnimatable *animatable,
|
||||
|
||||
@@ -54,7 +54,6 @@
|
||||
|
||||
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
|
||||
#include "deprecated/clutter-container.h"
|
||||
#include "deprecated/clutter-alpha.h"
|
||||
|
||||
#include "clutter-box-layout.h"
|
||||
|
||||
@@ -78,7 +77,7 @@ struct _ClutterBoxLayoutPrivate
|
||||
|
||||
guint spacing;
|
||||
|
||||
gulong easing_mode;
|
||||
ClutterAnimationMode easing_mode;
|
||||
guint easing_duration;
|
||||
|
||||
ClutterOrientation orientation;
|
||||
@@ -1267,7 +1266,7 @@ clutter_box_layout_set_property (GObject *gobject,
|
||||
break;
|
||||
|
||||
case PROP_EASING_MODE:
|
||||
clutter_box_layout_set_easing_mode (self, g_value_get_ulong (value));
|
||||
clutter_box_layout_set_easing_mode (self, g_value_get_enum (value));
|
||||
break;
|
||||
|
||||
case PROP_EASING_DURATION:
|
||||
@@ -1316,7 +1315,7 @@ clutter_box_layout_get_property (GObject *gobject,
|
||||
break;
|
||||
|
||||
case PROP_EASING_MODE:
|
||||
g_value_set_ulong (value, priv->easing_mode);
|
||||
g_value_set_enum (value, priv->easing_mode);
|
||||
break;
|
||||
|
||||
case PROP_EASING_DURATION:
|
||||
@@ -1449,11 +1448,6 @@ clutter_box_layout_class_init (ClutterBoxLayoutClass *klass)
|
||||
* The easing mode for the animations, in case
|
||||
* #ClutterBoxLayout:use-animations is set to %TRUE.
|
||||
*
|
||||
* The easing mode has the same semantics of #ClutterAnimation:mode: it can
|
||||
* either be a value from the #ClutterAnimationMode enumeration, like
|
||||
* %CLUTTER_EASE_OUT_CUBIC, or a logical id as returned by
|
||||
* clutter_alpha_register_func().
|
||||
*
|
||||
* The default value is %CLUTTER_EASE_OUT_CUBIC.
|
||||
*
|
||||
* Since: 1.2
|
||||
@@ -1462,12 +1456,12 @@ clutter_box_layout_class_init (ClutterBoxLayoutClass *klass)
|
||||
* the children when allocating them.
|
||||
*/
|
||||
obj_props[PROP_EASING_MODE] =
|
||||
g_param_spec_ulong ("easing-mode",
|
||||
P_("Easing Mode"),
|
||||
P_("The easing mode of the animations"),
|
||||
0, G_MAXULONG,
|
||||
CLUTTER_EASE_OUT_CUBIC,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
g_param_spec_enum ("easing-mode",
|
||||
P_("Easing Mode"),
|
||||
P_("The easing mode of the animations"),
|
||||
CLUTTER_TYPE_ANIMATION_MODE,
|
||||
CLUTTER_EASE_OUT_CUBIC,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* ClutterBoxLayout:easing-duration:
|
||||
@@ -2244,8 +2238,7 @@ clutter_box_layout_get_use_animations (ClutterBoxLayout *layout)
|
||||
/**
|
||||
* clutter_box_layout_set_easing_mode:
|
||||
* @layout: a #ClutterBoxLayout
|
||||
* @mode: an easing mode, either from #ClutterAnimationMode or a logical id
|
||||
* from clutter_alpha_register_func()
|
||||
* @mode: a #ClutterAnimationMode
|
||||
*
|
||||
* Sets the easing mode to be used by @layout when animating changes in layout
|
||||
* properties.
|
||||
@@ -2256,8 +2249,8 @@ clutter_box_layout_get_use_animations (ClutterBoxLayout *layout)
|
||||
* of the children when allocating them.
|
||||
*/
|
||||
void
|
||||
clutter_box_layout_set_easing_mode (ClutterBoxLayout *layout,
|
||||
gulong mode)
|
||||
clutter_box_layout_set_easing_mode (ClutterBoxLayout *layout,
|
||||
ClutterAnimationMode mode)
|
||||
{
|
||||
ClutterBoxLayoutPrivate *priv;
|
||||
|
||||
@@ -2285,7 +2278,7 @@ clutter_box_layout_set_easing_mode (ClutterBoxLayout *layout,
|
||||
*
|
||||
* Deprecated: 1.12
|
||||
*/
|
||||
gulong
|
||||
ClutterAnimationMode
|
||||
clutter_box_layout_get_easing_mode (ClutterBoxLayout *layout)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_BOX_LAYOUT (layout),
|
||||
|
||||
@@ -153,10 +153,10 @@ void clutter_box_layout_set_use_animations (ClutterBoxLayou
|
||||
CLUTTER_DEPRECATED
|
||||
gboolean clutter_box_layout_get_use_animations (ClutterBoxLayout *layout);
|
||||
CLUTTER_DEPRECATED
|
||||
void clutter_box_layout_set_easing_mode (ClutterBoxLayout *layout,
|
||||
gulong mode);
|
||||
void clutter_box_layout_set_easing_mode (ClutterBoxLayout *layout,
|
||||
ClutterAnimationMode mode);
|
||||
CLUTTER_DEPRECATED
|
||||
gulong clutter_box_layout_get_easing_mode (ClutterBoxLayout *layout);
|
||||
ClutterAnimationMode clutter_box_layout_get_easing_mode (ClutterBoxLayout *layout);
|
||||
CLUTTER_DEPRECATED
|
||||
void clutter_box_layout_set_easing_duration (ClutterBoxLayout *layout,
|
||||
guint msecs);
|
||||
|
||||
@@ -4,14 +4,11 @@
|
||||
#define __CLUTTER_DEPRECATED_H_INSIDE__
|
||||
|
||||
#include "deprecated/clutter-actor.h"
|
||||
#include "deprecated/clutter-alpha.h"
|
||||
#include "deprecated/clutter-animation.h"
|
||||
#include "deprecated/clutter-box.h"
|
||||
#include "deprecated/clutter-container.h"
|
||||
#include "deprecated/clutter-group.h"
|
||||
#include "deprecated/clutter-rectangle.h"
|
||||
#include "deprecated/clutter-stage.h"
|
||||
#include "deprecated/clutter-state.h"
|
||||
#include "deprecated/clutter-timeline.h"
|
||||
|
||||
#undef __CLUTTER_DEPRECATED_H_INSIDE__
|
||||
|
||||
@@ -190,7 +190,7 @@ typedef enum /*< prefix=CLUTTER_REQUEST >*/
|
||||
* @CLUTTER_ANIMATION_LAST: last animation mode, used as a guard for
|
||||
* registered global alpha functions
|
||||
*
|
||||
* The animation modes used by #ClutterAlpha and #ClutterAnimation. This
|
||||
* The animation modes used by #ClutterAnimatable. This
|
||||
* enumeration can be expanded in later versions of Clutter.
|
||||
*
|
||||
* <figure id="easing-modes">
|
||||
|
||||
@@ -37,9 +37,6 @@
|
||||
* any object taking a reference on a #ClutterInterval instance should
|
||||
* also take ownership of the interval by using g_object_ref_sink().
|
||||
*
|
||||
* #ClutterInterval is used by #ClutterAnimation to define the
|
||||
* interval of values that an implicit animation should tween over.
|
||||
*
|
||||
* #ClutterInterval can be subclassed to override the validation
|
||||
* and value computation.
|
||||
*
|
||||
|
||||
@@ -136,7 +136,6 @@
|
||||
|
||||
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
|
||||
#include "deprecated/clutter-container.h"
|
||||
#include "deprecated/clutter-alpha.h"
|
||||
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-layout-manager.h"
|
||||
@@ -164,7 +163,6 @@ G_DEFINE_ABSTRACT_TYPE (ClutterLayoutManager,
|
||||
G_TYPE_INITIALLY_UNOWNED)
|
||||
|
||||
static GQuark quark_layout_meta = 0;
|
||||
static GQuark quark_layout_alpha = 0;
|
||||
|
||||
static guint manager_signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
@@ -301,96 +299,12 @@ layout_manager_real_get_child_meta_type (ClutterLayoutManager *manager)
|
||||
return G_TYPE_INVALID;
|
||||
}
|
||||
|
||||
/* XXX:2.0 - Remove */
|
||||
static ClutterAlpha *
|
||||
layout_manager_real_begin_animation (ClutterLayoutManager *manager,
|
||||
guint duration,
|
||||
gulong mode)
|
||||
{
|
||||
ClutterTimeline *timeline;
|
||||
ClutterAlpha *alpha;
|
||||
|
||||
alpha = g_object_get_qdata (G_OBJECT (manager), quark_layout_alpha);
|
||||
if (alpha != NULL)
|
||||
{
|
||||
clutter_alpha_set_mode (alpha, mode);
|
||||
|
||||
timeline = clutter_alpha_get_timeline (alpha);
|
||||
clutter_timeline_set_duration (timeline, duration);
|
||||
clutter_timeline_rewind (timeline);
|
||||
|
||||
return alpha;
|
||||
};
|
||||
|
||||
timeline = clutter_timeline_new (duration);
|
||||
|
||||
alpha = clutter_alpha_new_full (timeline, mode);
|
||||
|
||||
/* let the alpha take ownership of the timeline */
|
||||
g_object_unref (timeline);
|
||||
|
||||
g_signal_connect_swapped (timeline, "new-frame",
|
||||
G_CALLBACK (clutter_layout_manager_layout_changed),
|
||||
manager);
|
||||
|
||||
g_object_set_qdata_full (G_OBJECT (manager),
|
||||
quark_layout_alpha, alpha,
|
||||
(GDestroyNotify) g_object_unref);
|
||||
|
||||
clutter_timeline_start (timeline);
|
||||
|
||||
return alpha;
|
||||
}
|
||||
|
||||
/* XXX:2.0 - Remove */
|
||||
static gdouble
|
||||
layout_manager_real_get_animation_progress (ClutterLayoutManager *manager)
|
||||
{
|
||||
ClutterAlpha *alpha;
|
||||
|
||||
alpha = g_object_get_qdata (G_OBJECT (manager), quark_layout_alpha);
|
||||
if (alpha == NULL)
|
||||
return 1.0;
|
||||
|
||||
return clutter_alpha_get_alpha (alpha);
|
||||
}
|
||||
|
||||
/* XXX:2.0 - Remove */
|
||||
static void
|
||||
layout_manager_real_end_animation (ClutterLayoutManager *manager)
|
||||
{
|
||||
ClutterTimeline *timeline;
|
||||
ClutterAlpha *alpha;
|
||||
|
||||
alpha = g_object_get_qdata (G_OBJECT (manager), quark_layout_alpha);
|
||||
if (alpha == NULL)
|
||||
return;
|
||||
|
||||
timeline = clutter_alpha_get_timeline (alpha);
|
||||
g_assert (timeline != NULL);
|
||||
|
||||
if (clutter_timeline_is_playing (timeline))
|
||||
clutter_timeline_stop (timeline);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (timeline,
|
||||
G_CALLBACK (clutter_layout_manager_layout_changed),
|
||||
manager);
|
||||
|
||||
g_object_set_qdata (G_OBJECT (manager), quark_layout_alpha, NULL);
|
||||
|
||||
clutter_layout_manager_layout_changed (manager);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_layout_manager_class_init (ClutterLayoutManagerClass *klass)
|
||||
{
|
||||
quark_layout_meta =
|
||||
g_quark_from_static_string ("clutter-layout-manager-child-meta");
|
||||
|
||||
/* XXX:2.0 - Remove */
|
||||
quark_layout_alpha =
|
||||
g_quark_from_static_string ("clutter-layout-manager-alpha");
|
||||
|
||||
klass->get_preferred_width = layout_manager_real_get_preferred_width;
|
||||
klass->get_preferred_height = layout_manager_real_get_preferred_height;
|
||||
klass->allocate = layout_manager_real_allocate;
|
||||
@@ -398,9 +312,6 @@ clutter_layout_manager_class_init (ClutterLayoutManagerClass *klass)
|
||||
klass->get_child_meta_type = layout_manager_real_get_child_meta_type;
|
||||
|
||||
/* XXX:2.0 - Remove */
|
||||
klass->begin_animation = layout_manager_real_begin_animation;
|
||||
klass->get_animation_progress = layout_manager_real_get_animation_progress;
|
||||
klass->end_animation = layout_manager_real_end_animation;
|
||||
klass->set_container = layout_manager_real_set_container;
|
||||
|
||||
/**
|
||||
|
||||
@@ -126,15 +126,6 @@ struct _ClutterLayoutManagerClass
|
||||
ClutterContainer *container,
|
||||
ClutterActor *actor);
|
||||
|
||||
/* deprecated */
|
||||
ClutterAlpha * (* begin_animation) (ClutterLayoutManager *manager,
|
||||
guint duration,
|
||||
gulong mode);
|
||||
/* deprecated */
|
||||
gdouble (* get_animation_progress) (ClutterLayoutManager *manager);
|
||||
/* deprecated */
|
||||
void (* end_animation) (ClutterLayoutManager *manager);
|
||||
|
||||
void (* layout_changed) (ClutterLayoutManager *manager);
|
||||
|
||||
/*< private >*/
|
||||
|
||||
@@ -36,6 +36,9 @@
|
||||
#include "cogl/clutter-stage-cogl.h"
|
||||
#include "clutter/x11/clutter-backend-x11.h"
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GList * clutter_stage_peek_stage_views (ClutterStage *stage);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_set_custom_backend_func (ClutterBackend *(* func) (void));
|
||||
|
||||
@@ -48,6 +51,23 @@ void clutter_stage_capture_into (ClutterStage *stage,
|
||||
cairo_rectangle_int_t *rect,
|
||||
uint8_t *data);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_stage_paint_to_framebuffer (ClutterStage *stage,
|
||||
CoglFramebuffer *framebuffer,
|
||||
const cairo_rectangle_int_t *rect,
|
||||
float scale,
|
||||
ClutterPaintFlag paint_flags);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_stage_paint_to_buffer (ClutterStage *stage,
|
||||
const cairo_rectangle_int_t *rect,
|
||||
float scale,
|
||||
uint8_t *data,
|
||||
int stride,
|
||||
CoglPixelFormat format,
|
||||
ClutterPaintFlag paint_flags,
|
||||
GError **error);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_stage_freeze_updates (ClutterStage *stage);
|
||||
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
#include "clutter-paint-context.h"
|
||||
|
||||
ClutterPaintContext * clutter_paint_context_new_for_view (ClutterStageView *view,
|
||||
const cairo_region_t *redraw_clip);
|
||||
const cairo_region_t *redraw_clip,
|
||||
ClutterPaintFlag paint_flags);
|
||||
|
||||
gboolean clutter_paint_context_is_drawing_off_stage (ClutterPaintContext *paint_context);
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ struct _ClutterPaintContext
|
||||
{
|
||||
grefcount ref_count;
|
||||
|
||||
ClutterPaintFlag paint_flags;
|
||||
|
||||
GList *framebuffers;
|
||||
|
||||
ClutterStageView *view;
|
||||
@@ -36,7 +38,8 @@ G_DEFINE_BOXED_TYPE (ClutterPaintContext, clutter_paint_context,
|
||||
|
||||
ClutterPaintContext *
|
||||
clutter_paint_context_new_for_view (ClutterStageView *view,
|
||||
const cairo_region_t *redraw_clip)
|
||||
const cairo_region_t *redraw_clip,
|
||||
ClutterPaintFlag paint_flags)
|
||||
{
|
||||
ClutterPaintContext *paint_context;
|
||||
CoglFramebuffer *framebuffer;
|
||||
@@ -45,6 +48,7 @@ clutter_paint_context_new_for_view (ClutterStageView *view,
|
||||
g_ref_count_init (&paint_context->ref_count);
|
||||
paint_context->view = view;
|
||||
paint_context->redraw_clip = cairo_region_copy (redraw_clip);
|
||||
paint_context->paint_flags = paint_flags;
|
||||
|
||||
framebuffer = clutter_stage_view_get_framebuffer (view);
|
||||
clutter_paint_context_push_framebuffer (paint_context, framebuffer);
|
||||
@@ -56,12 +60,16 @@ clutter_paint_context_new_for_view (ClutterStageView *view,
|
||||
* clutter_paint_context_new_for_framebuffer: (skip)
|
||||
*/
|
||||
ClutterPaintContext *
|
||||
clutter_paint_context_new_for_framebuffer (CoglFramebuffer *framebuffer)
|
||||
clutter_paint_context_new_for_framebuffer (CoglFramebuffer *framebuffer,
|
||||
const cairo_region_t *redraw_clip,
|
||||
ClutterPaintFlag paint_flags)
|
||||
{
|
||||
ClutterPaintContext *paint_context;
|
||||
|
||||
paint_context = g_new0 (ClutterPaintContext, 1);
|
||||
g_ref_count_init (&paint_context->ref_count);
|
||||
paint_context->redraw_clip = cairo_region_copy (redraw_clip);
|
||||
paint_context->paint_flags = paint_flags;
|
||||
|
||||
clutter_paint_context_push_framebuffer (paint_context, framebuffer);
|
||||
|
||||
@@ -170,3 +178,12 @@ clutter_paint_context_is_drawing_off_stage (ClutterPaintContext *paint_context)
|
||||
|
||||
return !paint_context->view;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_paint_context_get_paint_flags: (skip)
|
||||
*/
|
||||
ClutterPaintFlag
|
||||
clutter_paint_context_get_paint_flags (ClutterPaintContext *paint_context)
|
||||
{
|
||||
return paint_context->paint_flags;
|
||||
}
|
||||
|
||||
@@ -29,13 +29,21 @@
|
||||
|
||||
typedef struct _ClutterPaintContext ClutterPaintContext;
|
||||
|
||||
typedef enum _ClutterPaintFlag
|
||||
{
|
||||
CLUTTER_PAINT_FLAG_NONE = 0,
|
||||
CLUTTER_PAINT_FLAG_NO_CURSORS = 1 << 0,
|
||||
} ClutterPaintFlag;
|
||||
|
||||
#define CLUTTER_TYPE_PAINT_CONTEXT (clutter_paint_context_get_type ())
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType clutter_paint_context_get_type (void);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterPaintContext * clutter_paint_context_new_for_framebuffer (CoglFramebuffer *framebuffer);
|
||||
ClutterPaintContext * clutter_paint_context_new_for_framebuffer (CoglFramebuffer *framebuffer,
|
||||
const cairo_region_t *redraw_clip,
|
||||
ClutterPaintFlag paint_flags);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterPaintContext * clutter_paint_context_ref (ClutterPaintContext *paint_context);
|
||||
@@ -62,4 +70,7 @@ void clutter_paint_context_pop_framebuffer (ClutterPaintContext *paint_context);
|
||||
CLUTTER_EXPORT
|
||||
const cairo_region_t * clutter_paint_context_get_redraw_clip (ClutterPaintContext *paint_context);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterPaintFlag clutter_paint_context_get_paint_flags (ClutterPaintContext *paint_context);
|
||||
|
||||
#endif /* CLUTTER_PAINT_CONTEXT_H */
|
||||
|
||||
@@ -65,7 +65,6 @@ typedef struct _ClutterVertex4 ClutterVertex4;
|
||||
|
||||
#define CLUTTER_ACTOR_IS_TOPLEVEL(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IS_TOPLEVEL) != FALSE)
|
||||
#define CLUTTER_ACTOR_IN_DESTRUCTION(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_DESTRUCTION) != FALSE)
|
||||
#define CLUTTER_ACTOR_IN_REPARENT(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_REPARENT) != FALSE)
|
||||
#define CLUTTER_ACTOR_IN_PAINT(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_PAINT) != FALSE)
|
||||
#define CLUTTER_ACTOR_IN_PICK(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_PICK) != FALSE)
|
||||
#define CLUTTER_ACTOR_IN_RELAYOUT(a) ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_RELAYOUT) != FALSE)
|
||||
@@ -99,7 +98,6 @@ typedef enum
|
||||
|
||||
CLUTTER_IN_DESTRUCTION = 1 << 0,
|
||||
CLUTTER_IS_TOPLEVEL = 1 << 1,
|
||||
CLUTTER_IN_REPARENT = 1 << 2,
|
||||
CLUTTER_IN_PREF_WIDTH = 1 << 3,
|
||||
CLUTTER_IN_PREF_HEIGHT = 1 << 4,
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
|
||||
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
|
||||
#include "deprecated/clutter-container.h"
|
||||
#include "deprecated/clutter-alpha.h"
|
||||
|
||||
#include "clutter-actor.h"
|
||||
#include "clutter-debug.h"
|
||||
@@ -799,232 +798,6 @@ parse_signals (ClutterScript *script,
|
||||
return retval;
|
||||
}
|
||||
|
||||
static ClutterTimeline *
|
||||
construct_timeline (ClutterScript *script,
|
||||
JsonObject *object)
|
||||
{
|
||||
ClutterTimeline *retval = NULL;
|
||||
ObjectInfo *oinfo;
|
||||
GList *members, *l;
|
||||
|
||||
/* we fake an ObjectInfo so we can reuse clutter_script_construct_object()
|
||||
* here; we do not save it inside the hash table, because if this had
|
||||
* been a named object then we wouldn't have ended up here in the first
|
||||
* place
|
||||
*/
|
||||
oinfo = g_slice_new0 (ObjectInfo);
|
||||
oinfo->gtype = CLUTTER_TYPE_TIMELINE;
|
||||
oinfo->id = g_strdup ("dummy");
|
||||
|
||||
members = json_object_get_members (object);
|
||||
for (l = members; l != NULL; l = l->next)
|
||||
{
|
||||
const gchar *name = l->data;
|
||||
JsonNode *node = json_object_get_member (object, name);
|
||||
PropertyInfo *pinfo = g_slice_new0 (PropertyInfo);
|
||||
|
||||
pinfo->name = g_strdelimit (g_strdup (name), G_STR_DELIMITERS, '-');
|
||||
pinfo->node = json_node_copy (node);
|
||||
|
||||
oinfo->properties = g_list_prepend (oinfo->properties, pinfo);
|
||||
}
|
||||
|
||||
g_list_free (members);
|
||||
|
||||
_clutter_script_construct_object (script, oinfo);
|
||||
_clutter_script_apply_properties (script, oinfo);
|
||||
retval = CLUTTER_TIMELINE (oinfo->object);
|
||||
|
||||
/* we transfer ownership to the alpha function, so we ref before
|
||||
* destroying the ObjectInfo to avoid the timeline going away
|
||||
*/
|
||||
g_object_ref (retval);
|
||||
object_info_free (oinfo);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* define the names of the animation modes to match the ones
|
||||
* that developers might be more accustomed to
|
||||
*/
|
||||
static const struct
|
||||
{
|
||||
const gchar *name;
|
||||
ClutterAnimationMode mode;
|
||||
} animation_modes[] = {
|
||||
{ "linear", CLUTTER_LINEAR },
|
||||
{ "easeInQuad", CLUTTER_EASE_IN_QUAD },
|
||||
{ "easeOutQuad", CLUTTER_EASE_OUT_QUAD },
|
||||
{ "easeInOutQuad", CLUTTER_EASE_IN_OUT_QUAD },
|
||||
{ "easeInCubic", CLUTTER_EASE_IN_CUBIC },
|
||||
{ "easeOutCubic", CLUTTER_EASE_OUT_CUBIC },
|
||||
{ "easeInOutCubic", CLUTTER_EASE_IN_OUT_CUBIC },
|
||||
{ "easeInQuart", CLUTTER_EASE_IN_QUART },
|
||||
{ "easeOutQuart", CLUTTER_EASE_OUT_QUART },
|
||||
{ "easeInOutQuart", CLUTTER_EASE_IN_OUT_QUART },
|
||||
{ "easeInQuint", CLUTTER_EASE_IN_QUINT },
|
||||
{ "easeOutQuint", CLUTTER_EASE_OUT_QUINT },
|
||||
{ "easeInOutQuint", CLUTTER_EASE_IN_OUT_QUINT },
|
||||
{ "easeInSine", CLUTTER_EASE_IN_SINE },
|
||||
{ "easeOutSine", CLUTTER_EASE_OUT_SINE },
|
||||
{ "easeInOutSine", CLUTTER_EASE_IN_OUT_SINE },
|
||||
{ "easeInExpo", CLUTTER_EASE_IN_EXPO },
|
||||
{ "easeOutExpo", CLUTTER_EASE_OUT_EXPO },
|
||||
{ "easeInOutExpo", CLUTTER_EASE_IN_OUT_EXPO },
|
||||
{ "easeInCirc", CLUTTER_EASE_IN_CIRC },
|
||||
{ "easeOutCirc", CLUTTER_EASE_OUT_CIRC },
|
||||
{ "easeInOutCirc", CLUTTER_EASE_IN_OUT_CIRC },
|
||||
{ "easeInElastic", CLUTTER_EASE_IN_ELASTIC },
|
||||
{ "easeOutElastic", CLUTTER_EASE_OUT_ELASTIC },
|
||||
{ "easeInOutElastic", CLUTTER_EASE_IN_OUT_ELASTIC },
|
||||
{ "easeInBack", CLUTTER_EASE_IN_BACK },
|
||||
{ "easeOutBack", CLUTTER_EASE_OUT_BACK },
|
||||
{ "easeInOutBack", CLUTTER_EASE_IN_OUT_BACK },
|
||||
{ "easeInBounce", CLUTTER_EASE_IN_BOUNCE },
|
||||
{ "easeOutBounce", CLUTTER_EASE_OUT_BOUNCE },
|
||||
{ "easeInOutBounce", CLUTTER_EASE_IN_OUT_BOUNCE },
|
||||
};
|
||||
|
||||
static const gint n_animation_modes = G_N_ELEMENTS (animation_modes);
|
||||
|
||||
gulong
|
||||
_clutter_script_resolve_animation_mode (JsonNode *node)
|
||||
{
|
||||
gint i, res = CLUTTER_CUSTOM_MODE;
|
||||
|
||||
if (JSON_NODE_TYPE (node) != JSON_NODE_VALUE)
|
||||
return CLUTTER_CUSTOM_MODE;
|
||||
|
||||
if (json_node_get_value_type (node) == G_TYPE_INT64)
|
||||
return json_node_get_int (node);
|
||||
|
||||
if (json_node_get_value_type (node) == G_TYPE_STRING)
|
||||
{
|
||||
const gchar *name = json_node_get_string (node);
|
||||
|
||||
/* XXX - we might be able to optimize by changing the ordering
|
||||
* of the animation_modes array, e.g.
|
||||
* - special casing linear
|
||||
* - tokenizing ('ease', 'In', 'Sine') and matching on token
|
||||
* - binary searching?
|
||||
*/
|
||||
for (i = 0; i < n_animation_modes; i++)
|
||||
{
|
||||
if (strcmp (animation_modes[i].name, name) == 0)
|
||||
return animation_modes[i].mode;
|
||||
}
|
||||
|
||||
if (_clutter_script_enum_from_string (CLUTTER_TYPE_ANIMATION_MODE,
|
||||
name,
|
||||
&res))
|
||||
return res;
|
||||
|
||||
g_warning ("Unable to find the animation mode '%s'", name);
|
||||
}
|
||||
|
||||
return CLUTTER_CUSTOM_MODE;
|
||||
}
|
||||
|
||||
static ClutterAlphaFunc
|
||||
resolve_alpha_func (const gchar *name)
|
||||
{
|
||||
static GModule *module = NULL;
|
||||
ClutterAlphaFunc func;
|
||||
|
||||
CLUTTER_NOTE (SCRIPT, "Looking up '%s' alpha function", name);
|
||||
|
||||
if (G_UNLIKELY (!module))
|
||||
module = g_module_open (NULL, 0);
|
||||
|
||||
if (g_module_symbol (module, name, (gpointer) &func))
|
||||
{
|
||||
CLUTTER_NOTE (SCRIPT, "Found '%s' alpha function in the symbols table",
|
||||
name);
|
||||
return func;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GObject *
|
||||
_clutter_script_parse_alpha (ClutterScript *script,
|
||||
JsonNode *node)
|
||||
{
|
||||
GObject *retval = NULL;
|
||||
JsonObject *object;
|
||||
ClutterTimeline *timeline = NULL;
|
||||
ClutterAlphaFunc alpha_func = NULL;
|
||||
ClutterAnimationMode mode = CLUTTER_CUSTOM_MODE;
|
||||
JsonNode *val;
|
||||
gboolean unref_timeline = FALSE;
|
||||
|
||||
if (JSON_NODE_TYPE (node) != JSON_NODE_OBJECT)
|
||||
return NULL;
|
||||
|
||||
object = json_node_get_object (node);
|
||||
|
||||
val = json_object_get_member (object, "timeline");
|
||||
if (val)
|
||||
{
|
||||
if (JSON_NODE_TYPE (val) == JSON_NODE_VALUE &&
|
||||
json_node_get_string (val) != NULL)
|
||||
{
|
||||
const gchar *id_ = json_node_get_string (val);
|
||||
|
||||
timeline =
|
||||
CLUTTER_TIMELINE (clutter_script_get_object (script, id_));
|
||||
}
|
||||
else if (JSON_NODE_TYPE (val) == JSON_NODE_OBJECT)
|
||||
{
|
||||
timeline = construct_timeline (script, json_node_get_object (val));
|
||||
unref_timeline = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
val = json_object_get_member (object, "mode");
|
||||
if (val != NULL)
|
||||
mode = _clutter_script_resolve_animation_mode (val);
|
||||
|
||||
if (mode == CLUTTER_CUSTOM_MODE)
|
||||
{
|
||||
val = json_object_get_member (object, "function");
|
||||
if (val && json_node_get_string (val) != NULL)
|
||||
{
|
||||
alpha_func = resolve_alpha_func (json_node_get_string (val));
|
||||
if (!alpha_func)
|
||||
{
|
||||
g_warning ("Unable to find the function '%s' in the "
|
||||
"Clutter alpha functions or the symbols table",
|
||||
json_node_get_string (val));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CLUTTER_NOTE (SCRIPT, "Parsed alpha: %s timeline (%p) (mode:%d, func:%p)",
|
||||
unref_timeline ? "implicit" : "explicit",
|
||||
timeline ? timeline : 0x0,
|
||||
mode != CLUTTER_CUSTOM_MODE ? mode : 0,
|
||||
alpha_func ? alpha_func : 0x0);
|
||||
|
||||
retval = g_object_new (CLUTTER_TYPE_ALPHA, NULL);
|
||||
|
||||
if (mode != CLUTTER_CUSTOM_MODE)
|
||||
clutter_alpha_set_mode (CLUTTER_ALPHA (retval), mode);
|
||||
|
||||
if (alpha_func != NULL)
|
||||
clutter_alpha_set_func (CLUTTER_ALPHA (retval), alpha_func, NULL, NULL);
|
||||
|
||||
clutter_alpha_set_timeline (CLUTTER_ALPHA (retval), timeline);
|
||||
|
||||
/* if we created an implicit timeline, the Alpha has full ownership
|
||||
* of it now, since it won't be accessible from ClutterScript
|
||||
*/
|
||||
if (unref_timeline)
|
||||
g_object_unref (timeline);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_script_parser_object_end (JsonParser *json_parser,
|
||||
JsonObject *object)
|
||||
|
||||
@@ -110,8 +110,6 @@ gboolean _clutter_script_parse_node (ClutterScript *script,
|
||||
GType _clutter_script_get_type_from_symbol (const gchar *symbol);
|
||||
GType _clutter_script_get_type_from_class (const gchar *name);
|
||||
|
||||
gulong _clutter_script_resolve_animation_mode (JsonNode *node);
|
||||
|
||||
gboolean _clutter_script_enum_from_string (GType gtype,
|
||||
const gchar *string,
|
||||
gint *enum_value);
|
||||
@@ -128,8 +126,6 @@ gboolean _clutter_script_parse_rect (ClutterScript *script,
|
||||
gboolean _clutter_script_parse_color (ClutterScript *script,
|
||||
JsonNode *node,
|
||||
ClutterColor *color);
|
||||
GObject *_clutter_script_parse_alpha (ClutterScript *script,
|
||||
JsonNode *node);
|
||||
gboolean _clutter_script_parse_point (ClutterScript *script,
|
||||
JsonNode *node,
|
||||
graphene_point_t *point);
|
||||
|
||||
@@ -98,49 +98,6 @@
|
||||
* respectively) and the "object" string member for calling
|
||||
* g_signal_connect_object() instead of g_signal_connect().
|
||||
*
|
||||
* Signals can also be directly attached to a specific state defined
|
||||
* inside a #ClutterState instance, for instance:
|
||||
*
|
||||
* |[
|
||||
* ...
|
||||
* "signals" : [
|
||||
* {
|
||||
* "name" : "enter-event",
|
||||
* "states" : "button-states",
|
||||
* "target-state" : "hover"
|
||||
* },
|
||||
* {
|
||||
* "name" : "leave-event",
|
||||
* "states" : "button-states",
|
||||
* "target-state" : "base"
|
||||
* },
|
||||
* {
|
||||
* "name" : "button-press-event",
|
||||
* "states" : "button-states",
|
||||
* "target-state" : "active",
|
||||
* },
|
||||
* {
|
||||
* "name" : "key-press-event",
|
||||
* "states" : "button-states",
|
||||
* "target-state" : "key-focus",
|
||||
* "warp" : true
|
||||
* }
|
||||
* ],
|
||||
* ...
|
||||
* ]|
|
||||
*
|
||||
* The "states" key defines the #ClutterState instance to be used to
|
||||
* resolve the "target-state" key; it can be either a script id for a
|
||||
* #ClutterState built by the same #ClutterScript instance, or to a
|
||||
* #ClutterState built in code and associated to the #ClutterScript
|
||||
* instance through the clutter_script_add_states() function. If no
|
||||
* "states" key is present, then the default #ClutterState associated to
|
||||
* the #ClutterScript instance will be used; the default #ClutterState
|
||||
* can be set using clutter_script_add_states() using a %NULL name. The
|
||||
* "warp" key can be used to warp to a specific state instead of
|
||||
* animating to it. State changes on signal emission will not affect
|
||||
* the signal emission chain.
|
||||
*
|
||||
* Clutter reserves the following names, so classes defining properties
|
||||
* through the usual GObject registration process should avoid using these
|
||||
* names to avoid collisions:
|
||||
@@ -184,9 +141,7 @@
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-debug.h"
|
||||
|
||||
#include "deprecated/clutter-alpha.h"
|
||||
#include "deprecated/clutter-container.h"
|
||||
#include "deprecated/clutter-state.h"
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -210,8 +165,6 @@ struct _ClutterScriptPrivate
|
||||
|
||||
ClutterScriptParser *parser;
|
||||
|
||||
GHashTable *states;
|
||||
|
||||
gchar **search_paths;
|
||||
|
||||
gchar *translation_domain;
|
||||
@@ -264,7 +217,6 @@ signal_info_free (gpointer data)
|
||||
g_free (sinfo->name);
|
||||
g_free (sinfo->handler);
|
||||
g_free (sinfo->object);
|
||||
g_free (sinfo->state);
|
||||
g_free (sinfo->target);
|
||||
|
||||
g_slice_free (SignalInfo, sinfo);
|
||||
@@ -319,7 +271,6 @@ clutter_script_finalize (GObject *gobject)
|
||||
g_hash_table_destroy (priv->objects);
|
||||
g_strfreev (priv->search_paths);
|
||||
g_free (priv->filename);
|
||||
g_hash_table_destroy (priv->states);
|
||||
g_free (priv->translation_domain);
|
||||
|
||||
G_OBJECT_CLASS (clutter_script_parent_class)->finalize (gobject);
|
||||
@@ -454,9 +405,6 @@ clutter_script_init (ClutterScript *script)
|
||||
priv->objects = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
NULL,
|
||||
object_info_free);
|
||||
priv->states = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
g_free,
|
||||
(GDestroyNotify) g_object_unref);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -972,65 +920,12 @@ clutter_script_connect_signals (ClutterScript *script,
|
||||
g_free (cd);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
ClutterState *state;
|
||||
GObject *emitter;
|
||||
gchar *target;
|
||||
gulong signal_id;
|
||||
gulong hook_id;
|
||||
gboolean warp_to;
|
||||
} HookData;
|
||||
|
||||
typedef struct {
|
||||
ClutterScript *script;
|
||||
ClutterScriptConnectFunc func;
|
||||
gpointer user_data;
|
||||
} SignalConnectData;
|
||||
|
||||
static void
|
||||
hook_data_free (gpointer data)
|
||||
{
|
||||
if (G_LIKELY (data != NULL))
|
||||
{
|
||||
HookData *hook_data = data;
|
||||
|
||||
g_free (hook_data->target);
|
||||
g_slice_free (HookData, hook_data);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_script_state_change_hook (GSignalInvocationHint *ihint,
|
||||
guint n_params,
|
||||
const GValue *params,
|
||||
gpointer user_data)
|
||||
{
|
||||
HookData *hook_data = user_data;
|
||||
GObject *emitter;
|
||||
|
||||
emitter = g_value_get_object (¶ms[0]);
|
||||
|
||||
if (emitter == hook_data->emitter)
|
||||
{
|
||||
if (hook_data->warp_to)
|
||||
clutter_state_warp_to_state (hook_data->state, hook_data->target);
|
||||
else
|
||||
clutter_state_set_state (hook_data->state, hook_data->target);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_script_remove_state_change_hook (gpointer user_data,
|
||||
GObject *object_p)
|
||||
{
|
||||
HookData *hook_data = user_data;
|
||||
|
||||
g_signal_remove_emission_hook (hook_data->signal_id,
|
||||
hook_data->hook_id);
|
||||
}
|
||||
|
||||
static void
|
||||
connect_each_object (gpointer key,
|
||||
gpointer value,
|
||||
@@ -1070,64 +965,7 @@ connect_each_object (gpointer key,
|
||||
}
|
||||
else
|
||||
{
|
||||
GObject *state_object = NULL;
|
||||
const gchar *signal_name, *signal_detail;
|
||||
gchar **components;
|
||||
GQuark signal_quark;
|
||||
guint signal_id;
|
||||
HookData *hook_data;
|
||||
|
||||
if (sinfo->state == NULL)
|
||||
state_object = (GObject *) clutter_script_get_states (script, NULL);
|
||||
else
|
||||
{
|
||||
state_object = clutter_script_get_object (script, sinfo->state);
|
||||
if (state_object == NULL)
|
||||
state_object = (GObject *) clutter_script_get_states (script, sinfo->state);
|
||||
}
|
||||
|
||||
if (state_object == NULL)
|
||||
continue;
|
||||
|
||||
components = g_strsplit (sinfo->name, "::", 2);
|
||||
if (g_strv_length (components) == 2)
|
||||
{
|
||||
signal_name = components[0];
|
||||
signal_detail = components[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
signal_name = components[0];
|
||||
signal_detail = NULL;
|
||||
}
|
||||
|
||||
signal_id = g_signal_lookup (signal_name, G_OBJECT_TYPE (object));
|
||||
if (signal_id == 0)
|
||||
{
|
||||
g_strfreev (components);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (signal_detail != NULL)
|
||||
signal_quark = g_quark_from_string (signal_detail);
|
||||
else
|
||||
signal_quark = 0;
|
||||
|
||||
hook_data = g_slice_new (HookData);
|
||||
hook_data->emitter = object;
|
||||
hook_data->state = CLUTTER_STATE (state_object);
|
||||
hook_data->target = g_strdup (sinfo->target);
|
||||
hook_data->warp_to = sinfo->warp_to;
|
||||
hook_data->signal_id = signal_id;
|
||||
hook_data->hook_id =
|
||||
g_signal_add_emission_hook (signal_id, signal_quark,
|
||||
clutter_script_state_change_hook,
|
||||
hook_data,
|
||||
hook_data_free);
|
||||
|
||||
g_object_weak_ref (hook_data->emitter,
|
||||
clutter_script_remove_state_change_hook,
|
||||
hook_data);
|
||||
g_warn_if_reached ();
|
||||
}
|
||||
|
||||
signal_info_free (sinfo);
|
||||
@@ -1352,72 +1190,6 @@ clutter_script_list_objects (ClutterScript *script)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_script_add_states:
|
||||
* @script: a #ClutterScript
|
||||
* @name: (allow-none): a name for the @state, or %NULL to
|
||||
* set the default #ClutterState
|
||||
* @state: a #ClutterState
|
||||
*
|
||||
* Associates a #ClutterState to the #ClutterScript instance using the given
|
||||
* name.
|
||||
*
|
||||
* The #ClutterScript instance will use @state to resolve target states when
|
||||
* connecting signal handlers.
|
||||
*
|
||||
* The #ClutterScript instance will take a reference on the #ClutterState
|
||||
* passed to this function.
|
||||
*
|
||||
* Since: 1.8
|
||||
*
|
||||
* Deprecated: 1.12
|
||||
*/
|
||||
void
|
||||
clutter_script_add_states (ClutterScript *script,
|
||||
const gchar *name,
|
||||
ClutterState *state)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_SCRIPT (script));
|
||||
g_return_if_fail (CLUTTER_IS_STATE (state));
|
||||
|
||||
if (name == NULL || *name == '\0')
|
||||
name = "__clutter_script_default_state";
|
||||
|
||||
g_hash_table_replace (script->priv->states,
|
||||
g_strdup (name),
|
||||
g_object_ref (state));
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_script_get_states:
|
||||
* @script: a #ClutterScript
|
||||
* @name: (allow-none): the name of the #ClutterState, or %NULL
|
||||
*
|
||||
* Retrieves the #ClutterState for the given @state_name.
|
||||
*
|
||||
* If @name is %NULL, this function will return the default
|
||||
* #ClutterState instance.
|
||||
*
|
||||
* Return value: (transfer none): a pointer to the #ClutterState for the
|
||||
* given name. The #ClutterState is owned by the #ClutterScript instance
|
||||
* and it should not be unreferenced
|
||||
*
|
||||
* Since: 1.8
|
||||
*
|
||||
* Deprecated: 1.12
|
||||
*/
|
||||
ClutterState *
|
||||
clutter_script_get_states (ClutterScript *script,
|
||||
const gchar *name)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_SCRIPT (script), NULL);
|
||||
|
||||
if (name == NULL || *name == '\0')
|
||||
name = "__clutter_script_default_state";
|
||||
|
||||
return g_hash_table_lookup (script->priv->states, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_script_set_translation_domain:
|
||||
* @script: a #ClutterScript
|
||||
|
||||
@@ -179,15 +179,6 @@ void clutter_script_unmerge_objects (ClutterScript
|
||||
CLUTTER_EXPORT
|
||||
void clutter_script_ensure_objects (ClutterScript *script);
|
||||
|
||||
CLUTTER_DEPRECATED
|
||||
void clutter_script_add_states (ClutterScript *script,
|
||||
const gchar *name,
|
||||
ClutterState *state);
|
||||
|
||||
CLUTTER_DEPRECATED
|
||||
ClutterState * clutter_script_get_states (ClutterScript *script,
|
||||
const gchar *name);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_script_connect_signals (ClutterScript *script,
|
||||
gpointer user_data);
|
||||
|
||||
@@ -139,8 +139,6 @@ void _clutter_stage_presented (ClutterStage *stag
|
||||
CoglFrameEvent frame_event,
|
||||
ClutterFrameInfo *frame_info);
|
||||
|
||||
GList * _clutter_stage_peek_stage_views (ClutterStage *stage);
|
||||
|
||||
void clutter_stage_queue_actor_relayout (ClutterStage *stage,
|
||||
ClutterActor *actor);
|
||||
|
||||
|
||||
@@ -552,7 +552,7 @@ clutter_stage_add_redraw_clip (ClutterStage *stage,
|
||||
{
|
||||
GList *l;
|
||||
|
||||
for (l = _clutter_stage_peek_stage_views (stage); l; l = l->next)
|
||||
for (l = clutter_stage_peek_stage_views (stage); l; l = l->next)
|
||||
{
|
||||
ClutterStageView *view = l->data;
|
||||
|
||||
@@ -924,7 +924,8 @@ clutter_stage_do_paint_view (ClutterStage *stage,
|
||||
ClutterPaintContext *paint_context;
|
||||
cairo_rectangle_int_t clip_rect;
|
||||
|
||||
paint_context = clutter_paint_context_new_for_view (view, redraw_clip);
|
||||
paint_context = clutter_paint_context_new_for_view (view, redraw_clip,
|
||||
CLUTTER_PAINT_FLAG_NONE);
|
||||
|
||||
cairo_region_get_extents (redraw_clip, &clip_rect);
|
||||
setup_view_for_pick_or_paint (stage, view, &clip_rect);
|
||||
@@ -1572,7 +1573,7 @@ is_full_stage_redraw_queued (ClutterStage *stage)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
for (l = _clutter_stage_peek_stage_views (stage); l; l = l->next)
|
||||
for (l = clutter_stage_peek_stage_views (stage); l; l = l->next)
|
||||
{
|
||||
ClutterStageView *view = l->data;
|
||||
|
||||
@@ -4163,6 +4164,97 @@ clutter_stage_get_capture_final_size (ClutterStage *stage,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_stage_paint_to_framebuffer (ClutterStage *stage,
|
||||
CoglFramebuffer *framebuffer,
|
||||
const cairo_rectangle_int_t *rect,
|
||||
float scale,
|
||||
ClutterPaintFlag paint_flags)
|
||||
{
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
ClutterPaintContext *paint_context;
|
||||
cairo_region_t *redraw_clip;
|
||||
|
||||
redraw_clip = cairo_region_create_rectangle (rect);
|
||||
paint_context =
|
||||
clutter_paint_context_new_for_framebuffer (framebuffer,
|
||||
redraw_clip,
|
||||
paint_flags);
|
||||
cairo_region_destroy (redraw_clip);
|
||||
|
||||
cogl_framebuffer_push_matrix (framebuffer);
|
||||
cogl_framebuffer_set_projection_matrix (framebuffer, &priv->projection);
|
||||
cogl_framebuffer_set_viewport (framebuffer,
|
||||
-(rect->x * scale),
|
||||
-(rect->y * scale),
|
||||
priv->viewport[2] * scale,
|
||||
priv->viewport[3] * scale);
|
||||
clutter_actor_paint (CLUTTER_ACTOR (stage), paint_context);
|
||||
cogl_framebuffer_pop_matrix (framebuffer);
|
||||
|
||||
clutter_paint_context_destroy (paint_context);
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_stage_paint_to_buffer (ClutterStage *stage,
|
||||
const cairo_rectangle_int_t *rect,
|
||||
float scale,
|
||||
uint8_t *data,
|
||||
int stride,
|
||||
CoglPixelFormat format,
|
||||
ClutterPaintFlag paint_flags,
|
||||
GError **error)
|
||||
{
|
||||
ClutterBackend *clutter_backend = clutter_get_default_backend ();
|
||||
CoglContext *cogl_context =
|
||||
clutter_backend_get_cogl_context (clutter_backend);
|
||||
int texture_width, texture_height;
|
||||
CoglTexture2D *texture;
|
||||
CoglOffscreen *offscreen;
|
||||
CoglFramebuffer *framebuffer;
|
||||
CoglBitmap *bitmap;
|
||||
|
||||
texture_width = (int) ceilf (rect->width * scale);
|
||||
texture_height = (int) ceilf (rect->height * scale);
|
||||
texture = cogl_texture_2d_new_with_size (cogl_context,
|
||||
texture_width,
|
||||
texture_height);
|
||||
if (!texture)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Failed to create %dx%d texture",
|
||||
texture_width, texture_height);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
offscreen = cogl_offscreen_new_with_texture (COGL_TEXTURE (texture));
|
||||
framebuffer = COGL_FRAMEBUFFER (offscreen);
|
||||
|
||||
cogl_object_unref (texture);
|
||||
|
||||
if (!cogl_framebuffer_allocate (framebuffer, error))
|
||||
return FALSE;
|
||||
|
||||
clutter_stage_paint_to_framebuffer (stage, framebuffer,
|
||||
rect, scale, paint_flags);
|
||||
|
||||
bitmap = cogl_bitmap_new_for_data (cogl_context,
|
||||
texture_width, texture_height,
|
||||
format,
|
||||
stride,
|
||||
data);
|
||||
|
||||
cogl_framebuffer_read_pixels_into_bitmap (framebuffer,
|
||||
0, 0,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
bitmap);
|
||||
|
||||
cogl_object_unref (bitmap);
|
||||
cogl_object_unref (framebuffer);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
capture_view_into (ClutterStage *stage,
|
||||
gboolean paint,
|
||||
@@ -4310,8 +4402,11 @@ clutter_stage_thaw_updates (ClutterStage *stage)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_stage_peek_stage_views: (skip)
|
||||
*/
|
||||
GList *
|
||||
_clutter_stage_peek_stage_views (ClutterStage *stage)
|
||||
clutter_stage_peek_stage_views (ClutterStage *stage)
|
||||
{
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
/**
|
||||
* SECTION:clutter-timeline
|
||||
* @short_description: A class for time-based events
|
||||
* @see_also: #ClutterAnimation, #ClutterAnimator, #ClutterState
|
||||
*
|
||||
* #ClutterTimeline is a base class for managing time-based event that cause
|
||||
* Clutter to redraw a stage, such as animations.
|
||||
@@ -71,7 +70,7 @@
|
||||
* when reaching completion by using the #ClutterTimeline:auto-reverse property.
|
||||
*
|
||||
* Timelines are used in the Clutter animation framework by classes like
|
||||
* #ClutterAnimation, #ClutterAnimator, and #ClutterState.
|
||||
* #ClutterTransition.
|
||||
*
|
||||
* ## Defining Timelines in ClutterScript
|
||||
*
|
||||
|
||||
@@ -79,10 +79,6 @@ typedef struct _ClutterKnot ClutterKnot;
|
||||
typedef struct _ClutterMargin ClutterMargin;
|
||||
typedef struct _ClutterPerspective ClutterPerspective;
|
||||
|
||||
typedef struct _ClutterAlpha ClutterAlpha;
|
||||
typedef struct _ClutterAnimation ClutterAnimation;
|
||||
typedef struct _ClutterState ClutterState;
|
||||
|
||||
typedef struct _ClutterInputDeviceTool ClutterInputDeviceTool;
|
||||
typedef struct _ClutterInputDevice ClutterInputDevice;
|
||||
typedef struct _ClutterVirtualInputDevice ClutterVirtualInputDevice;
|
||||
|
||||
@@ -375,15 +375,11 @@ static gboolean
|
||||
swap_framebuffer (ClutterStageWindow *stage_window,
|
||||
ClutterStageView *view,
|
||||
cairo_region_t *swap_region,
|
||||
gboolean swap_with_damage,
|
||||
cairo_region_t *queued_redraw_clip)
|
||||
gboolean swap_with_damage)
|
||||
{
|
||||
CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (view);
|
||||
int *damage, n_rects, i;
|
||||
|
||||
if (G_UNLIKELY ((clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION)))
|
||||
paint_damage_region (stage_window, view, swap_region, queued_redraw_clip);
|
||||
|
||||
n_rects = cairo_region_num_rectangles (swap_region);
|
||||
damage = g_newa (int, n_rects * 4);
|
||||
for (i = 0; i < n_rects; i++)
|
||||
@@ -620,7 +616,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
gboolean swap_with_damage;
|
||||
ClutterActor *wrapper;
|
||||
cairo_region_t *redraw_clip;
|
||||
cairo_region_t *queued_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;
|
||||
@@ -644,6 +640,8 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
has_buffer_age = cogl_is_onscreen (fb) && 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))
|
||||
queued_redraw_clip = cairo_region_copy (redraw_clip);
|
||||
|
||||
/* NB: a NULL redraw clip == full stage redraw */
|
||||
if (!redraw_clip)
|
||||
@@ -711,8 +709,6 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
redraw_clip = cairo_region_create_rectangle (&view_rect);
|
||||
}
|
||||
|
||||
queued_redraw_clip = cairo_region_copy (redraw_clip);
|
||||
|
||||
if (may_use_clipped_redraw &&
|
||||
G_LIKELY (!(clutter_paint_debug_flags & CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS)))
|
||||
use_clipped_redraw = TRUE;
|
||||
@@ -922,7 +918,6 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
}
|
||||
|
||||
g_clear_pointer (&redraw_clip, cairo_region_destroy);
|
||||
g_clear_pointer (&queued_redraw_clip, cairo_region_destroy);
|
||||
g_clear_pointer (&fb_clip_region, cairo_region_destroy);
|
||||
|
||||
if (do_swap_buffer)
|
||||
@@ -943,11 +938,17 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
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,
|
||||
queued_redraw_clip);
|
||||
swap_with_damage);
|
||||
|
||||
cairo_region_destroy (swap_region);
|
||||
|
||||
@@ -955,6 +956,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
}
|
||||
else
|
||||
{
|
||||
g_clear_pointer (&queued_redraw_clip, cairo_region_destroy);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,819 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Authored By Matthew Allum <mallum@openedhand.com>
|
||||
* Jorn Baayen <jorn@openedhand.com>
|
||||
* Emmanuele Bassi <ebassi@openedhand.com>
|
||||
* Tomas Frydrych <tf@openedhand.com>
|
||||
*
|
||||
* Copyright (C) 2006, 2007, 2008 OpenedHand
|
||||
* Copyright (C) 2009, 2010 Intel Corp.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:clutter-alpha
|
||||
* @short_description: A class for calculating a value as a function of time
|
||||
*
|
||||
* #ClutterAlpha is a class for calculating an floating point value
|
||||
* dependent only on the position of a #ClutterTimeline.
|
||||
*
|
||||
* For newly written code, it is recommended to use the
|
||||
* #ClutterTimeline:progress-mode property of #ClutterTimeline, or the
|
||||
* clutter_timeline_set_progress_func() function instead of #ClutterAlpha.
|
||||
* The #ClutterAlpha class will be deprecated in the future, and will not
|
||||
* be available any more in the next major version of Clutter.
|
||||
*
|
||||
* A #ClutterAlpha binds a #ClutterTimeline to a progress function which
|
||||
* translates the time T into an adimensional factor alpha.
|
||||
*
|
||||
* You should provide a #ClutterTimeline and bind it to the #ClutterAlpha
|
||||
* instance using clutter_alpha_set_timeline(). You should also set an
|
||||
* "animation mode", by using the #ClutterAnimationMode values that
|
||||
* Clutter provides.
|
||||
*
|
||||
* Instead of a #ClutterAnimationMode you may provide a function returning
|
||||
* the alpha value depending on the progress of the timeline, using
|
||||
* clutter_alpha_set_func() or clutter_alpha_set_closure(). The alpha
|
||||
* function will be executed each time a new frame in the #ClutterTimeline
|
||||
* is reached.
|
||||
*
|
||||
* Since the alpha function is controlled by the timeline instance, you can
|
||||
* pause, stop or resume the #ClutterAlpha from calling the alpha function by
|
||||
* using the appropriate functions of the #ClutterTimeline object.
|
||||
*
|
||||
* #ClutterAlpha is available since Clutter 0.2.
|
||||
*
|
||||
* #ClutterAlpha is deprecated since Clutter 1.12. #ClutterTimeline and
|
||||
* the #ClutterTimeline:progress-mode property replace this whole class.
|
||||
*
|
||||
* ## ClutterAlpha custom properties for #ClutterScript
|
||||
*
|
||||
* #ClutterAlpha defines a custom `function` property for
|
||||
* #ClutterScript which allows to reference a custom alpha function
|
||||
* available in the source code. Setting the `function` property
|
||||
* is equivalent to calling clutter_alpha_set_func() with the
|
||||
* specified function name. No user data or #GDestroyNotify is
|
||||
* available to be passed.
|
||||
*
|
||||
* The following JSON fragment defines a #ClutterAlpha
|
||||
* using a #ClutterTimeline with id "sine-timeline" and an alpha
|
||||
* function called `my_sine_alpha`.
|
||||
*
|
||||
* |[
|
||||
* {
|
||||
* "id" : "sine-alpha",
|
||||
* "timeline" : {
|
||||
* "id" : "sine-timeline",
|
||||
* "duration" : 500,
|
||||
* "loop" : true
|
||||
* },
|
||||
* "function" : "my_sine_alpha"
|
||||
* }
|
||||
* ]|
|
||||
*/
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <gmodule.h>
|
||||
|
||||
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
|
||||
|
||||
#include "clutter-alpha.h"
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-enum-types.h"
|
||||
#include "clutter-easing.h"
|
||||
#include "clutter-main.h"
|
||||
#include "clutter-marshal.h"
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-scriptable.h"
|
||||
#include "clutter-script-private.h"
|
||||
|
||||
struct _ClutterAlphaPrivate
|
||||
{
|
||||
ClutterTimeline *timeline;
|
||||
guint timeline_new_frame_id;
|
||||
|
||||
gdouble alpha;
|
||||
|
||||
GClosure *closure;
|
||||
|
||||
ClutterAlphaFunc func;
|
||||
gpointer user_data;
|
||||
GDestroyNotify notify;
|
||||
|
||||
gulong mode;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_TIMELINE,
|
||||
PROP_ALPHA,
|
||||
PROP_MODE,
|
||||
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
static GParamSpec *obj_props[PROP_LAST];
|
||||
|
||||
static void clutter_scriptable_iface_init (ClutterScriptableIface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (ClutterAlpha,
|
||||
clutter_alpha,
|
||||
G_TYPE_INITIALLY_UNOWNED,
|
||||
G_ADD_PRIVATE (ClutterAlpha)
|
||||
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_SCRIPTABLE,
|
||||
clutter_scriptable_iface_init));
|
||||
|
||||
static void
|
||||
timeline_new_frame_cb (ClutterTimeline *timeline,
|
||||
guint msecs,
|
||||
ClutterAlpha *alpha)
|
||||
{
|
||||
ClutterAlphaPrivate *priv = alpha->priv;
|
||||
|
||||
/* Update alpha value and notify */
|
||||
priv->alpha = clutter_alpha_get_alpha (alpha);
|
||||
g_object_notify_by_pspec (G_OBJECT (alpha), obj_props[PROP_ALPHA]);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_alpha_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterAlpha *alpha = CLUTTER_ALPHA (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_TIMELINE:
|
||||
clutter_alpha_set_timeline (alpha, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_MODE:
|
||||
clutter_alpha_set_mode (alpha, g_value_get_ulong (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_alpha_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterAlphaPrivate *priv = CLUTTER_ALPHA (object)->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_TIMELINE:
|
||||
g_value_set_object (value, priv->timeline);
|
||||
break;
|
||||
|
||||
case PROP_ALPHA:
|
||||
g_value_set_double (value, priv->alpha);
|
||||
break;
|
||||
|
||||
case PROP_MODE:
|
||||
g_value_set_ulong (value, priv->mode);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_alpha_finalize (GObject *object)
|
||||
{
|
||||
ClutterAlphaPrivate *priv = CLUTTER_ALPHA (object)->priv;
|
||||
|
||||
if (priv->notify != NULL)
|
||||
priv->notify (priv->user_data);
|
||||
else if (priv->closure != NULL)
|
||||
g_closure_unref (priv->closure);
|
||||
|
||||
G_OBJECT_CLASS (clutter_alpha_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_alpha_dispose (GObject *object)
|
||||
{
|
||||
ClutterAlpha *self = CLUTTER_ALPHA(object);
|
||||
|
||||
clutter_alpha_set_timeline (self, NULL);
|
||||
|
||||
G_OBJECT_CLASS (clutter_alpha_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static ClutterAlphaFunc
|
||||
resolve_alpha_func (const gchar *name)
|
||||
{
|
||||
static GModule *module = NULL;
|
||||
ClutterAlphaFunc func;
|
||||
|
||||
CLUTTER_NOTE (SCRIPT, "Looking up '%s' alpha function", name);
|
||||
|
||||
if (G_UNLIKELY (module == NULL))
|
||||
module = g_module_open (NULL, 0);
|
||||
|
||||
if (g_module_symbol (module, name, (gpointer) &func))
|
||||
{
|
||||
CLUTTER_NOTE (SCRIPT, "Found '%s' alpha function in the symbols table",
|
||||
name);
|
||||
return func;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_alpha_set_custom_property (ClutterScriptable *scriptable,
|
||||
ClutterScript *script,
|
||||
const gchar *name,
|
||||
const GValue *value)
|
||||
{
|
||||
if (strncmp (name, "function", 8) == 0)
|
||||
{
|
||||
g_assert (G_VALUE_HOLDS (value, G_TYPE_POINTER));
|
||||
if (g_value_get_pointer (value) != NULL)
|
||||
{
|
||||
clutter_alpha_set_func (CLUTTER_ALPHA (scriptable),
|
||||
g_value_get_pointer (value),
|
||||
NULL, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
g_object_set_property (G_OBJECT (scriptable), name, value);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_alpha_parse_custom_node (ClutterScriptable *scriptable,
|
||||
ClutterScript *script,
|
||||
GValue *value,
|
||||
const gchar *name,
|
||||
JsonNode *node)
|
||||
{
|
||||
if (strncmp (name, "function", 8) == 0)
|
||||
{
|
||||
const gchar *func_name = json_node_get_string (node);
|
||||
|
||||
g_value_init (value, G_TYPE_POINTER);
|
||||
g_value_set_pointer (value, resolve_alpha_func (func_name));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* we need to do this because we use gulong in place
|
||||
* of ClutterAnimationMode for ClutterAlpha:mode
|
||||
*/
|
||||
if (strncmp (name, "mode", 4) == 0)
|
||||
{
|
||||
gulong mode;
|
||||
|
||||
mode = _clutter_script_resolve_animation_mode (node);
|
||||
|
||||
g_value_init (value, G_TYPE_ULONG);
|
||||
g_value_set_ulong (value, mode);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_scriptable_iface_init (ClutterScriptableIface *iface)
|
||||
{
|
||||
iface->parse_custom_node = clutter_alpha_parse_custom_node;
|
||||
iface->set_custom_property = clutter_alpha_set_custom_property;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_alpha_class_init (ClutterAlphaClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->set_property = clutter_alpha_set_property;
|
||||
object_class->get_property = clutter_alpha_get_property;
|
||||
object_class->finalize = clutter_alpha_finalize;
|
||||
object_class->dispose = clutter_alpha_dispose;
|
||||
|
||||
/**
|
||||
* ClutterAlpha:timeline:
|
||||
*
|
||||
* A #ClutterTimeline instance used to drive the alpha function.
|
||||
*
|
||||
* Since: 0.2
|
||||
*
|
||||
* Deprecated: 1.12
|
||||
*/
|
||||
obj_props[PROP_TIMELINE] =
|
||||
g_param_spec_object ("timeline",
|
||||
P_("Timeline"),
|
||||
P_("Timeline used by the alpha"),
|
||||
CLUTTER_TYPE_TIMELINE,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* ClutterAlpha:alpha:
|
||||
*
|
||||
* The alpha value as computed by the alpha function. The linear
|
||||
* interval is 0.0 to 1.0, but the Alpha allows overshooting by
|
||||
* one unit in each direction, so the valid interval is -1.0 to 2.0.
|
||||
*
|
||||
* Since: 0.2
|
||||
* Deprecated: 1.12: Use #ClutterTimeline::new-frame and
|
||||
* clutter_timeline_get_progress() instead
|
||||
*/
|
||||
obj_props[PROP_ALPHA] =
|
||||
g_param_spec_double ("alpha",
|
||||
P_("Alpha value"),
|
||||
P_("Alpha value as computed by the alpha"),
|
||||
-1.0, 2.0,
|
||||
0.0,
|
||||
CLUTTER_PARAM_READABLE);
|
||||
|
||||
/**
|
||||
* ClutterAlpha:mode:
|
||||
*
|
||||
* The progress function logical id - a value from the
|
||||
* #ClutterAnimationMode enumeration.
|
||||
*
|
||||
* If %CLUTTER_CUSTOM_MODE is used then the function set using
|
||||
* clutter_alpha_set_closure() or clutter_alpha_set_func()
|
||||
* will be used.
|
||||
*
|
||||
* Since: 1.0
|
||||
* Deprecated: 1.12: Use #ClutterTimeline:progress-mode
|
||||
*/
|
||||
obj_props[PROP_MODE] =
|
||||
g_param_spec_ulong ("mode",
|
||||
P_("Mode"),
|
||||
P_("Progress mode"),
|
||||
0, G_MAXULONG,
|
||||
CLUTTER_CUSTOM_MODE,
|
||||
G_PARAM_CONSTRUCT | CLUTTER_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_properties (object_class,
|
||||
PROP_LAST,
|
||||
obj_props);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_alpha_init (ClutterAlpha *self)
|
||||
{
|
||||
self->priv = clutter_alpha_get_instance_private (self);
|
||||
self->priv->mode = CLUTTER_CUSTOM_MODE;
|
||||
self->priv->alpha = 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_alpha_get_alpha:
|
||||
* @alpha: A #ClutterAlpha
|
||||
*
|
||||
* Query the current alpha value.
|
||||
*
|
||||
* Return Value: The current alpha value for the alpha
|
||||
*
|
||||
* Since: 0.2
|
||||
*
|
||||
* Deprecated: 1.12: Use clutter_timeline_get_progress()
|
||||
*/
|
||||
gdouble
|
||||
clutter_alpha_get_alpha (ClutterAlpha *alpha)
|
||||
{
|
||||
ClutterAlphaPrivate *priv;
|
||||
gdouble retval = 0;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_ALPHA (alpha), 0);
|
||||
|
||||
priv = alpha->priv;
|
||||
|
||||
if (G_LIKELY (priv->func))
|
||||
{
|
||||
return priv->func (alpha, priv->user_data);
|
||||
}
|
||||
else if (priv->closure)
|
||||
{
|
||||
GValue params = G_VALUE_INIT;
|
||||
GValue result_value = G_VALUE_INIT;
|
||||
|
||||
g_object_ref (alpha);
|
||||
|
||||
g_value_init (&result_value, G_TYPE_DOUBLE);
|
||||
|
||||
g_value_init (¶ms, CLUTTER_TYPE_ALPHA);
|
||||
g_value_set_object (¶ms, alpha);
|
||||
|
||||
g_closure_invoke (priv->closure, &result_value, 1, ¶ms, NULL);
|
||||
|
||||
retval = g_value_get_double (&result_value);
|
||||
|
||||
g_value_unset (&result_value);
|
||||
g_value_unset (¶ms);
|
||||
|
||||
g_object_unref (alpha);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* clutter_alpha_set_closure_internal:
|
||||
* @alpha: a #ClutterAlpha
|
||||
* @closure: a #GClosure
|
||||
*
|
||||
* Sets the @closure for @alpha. This function does not
|
||||
* set the #ClutterAlpha:mode property and does not emit
|
||||
* the #GObject::notify signal for it.
|
||||
*/
|
||||
static inline void
|
||||
clutter_alpha_set_closure_internal (ClutterAlpha *alpha,
|
||||
GClosure *closure)
|
||||
{
|
||||
ClutterAlphaPrivate *priv = alpha->priv;
|
||||
|
||||
if (priv->notify != NULL)
|
||||
priv->notify (priv->user_data);
|
||||
else if (priv->closure != NULL)
|
||||
g_closure_unref (priv->closure);
|
||||
|
||||
priv->func = NULL;
|
||||
priv->user_data = NULL;
|
||||
priv->notify = NULL;
|
||||
|
||||
if (closure == NULL)
|
||||
return;
|
||||
|
||||
/* need to take ownership of the closure before sinking it */
|
||||
priv->closure = g_closure_ref (closure);
|
||||
g_closure_sink (closure);
|
||||
|
||||
/* set the marshaller */
|
||||
if (G_CLOSURE_NEEDS_MARSHAL (closure))
|
||||
{
|
||||
GClosureMarshal marshal = _clutter_marshal_DOUBLE__VOID;
|
||||
|
||||
g_closure_set_marshal (priv->closure, marshal);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_alpha_set_closure:
|
||||
* @alpha: A #ClutterAlpha
|
||||
* @closure: A #GClosure
|
||||
*
|
||||
* Sets the #GClosure used to compute the alpha value at each
|
||||
* frame of the #ClutterTimeline bound to @alpha.
|
||||
*
|
||||
* Since: 0.8
|
||||
*
|
||||
* Deprecated: 1.12: Use clutter_timeline_set_progress_func()
|
||||
*/
|
||||
void
|
||||
clutter_alpha_set_closure (ClutterAlpha *alpha,
|
||||
GClosure *closure)
|
||||
{
|
||||
ClutterAlphaPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ALPHA (alpha));
|
||||
g_return_if_fail (closure != NULL);
|
||||
|
||||
priv = alpha->priv;
|
||||
|
||||
clutter_alpha_set_closure_internal (alpha, closure);
|
||||
|
||||
priv->mode = CLUTTER_CUSTOM_MODE;
|
||||
g_object_notify_by_pspec (G_OBJECT (alpha), obj_props[PROP_MODE]);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_alpha_set_func:
|
||||
* @alpha: A #ClutterAlpha
|
||||
* @func: A #ClutterAlphaFunc
|
||||
* @data: user data to be passed to the alpha function, or %NULL
|
||||
* @destroy: notify function used when disposing the alpha function
|
||||
*
|
||||
* Sets the #ClutterAlphaFunc function used to compute
|
||||
* the alpha value at each frame of the #ClutterTimeline
|
||||
* bound to @alpha.
|
||||
*
|
||||
* This function will not register @func as a global alpha function.
|
||||
*
|
||||
* Since: 0.2
|
||||
*
|
||||
* Deprecated: 1.12: Use clutter_timeline_set_progress_func()
|
||||
*/
|
||||
void
|
||||
clutter_alpha_set_func (ClutterAlpha *alpha,
|
||||
ClutterAlphaFunc func,
|
||||
gpointer data,
|
||||
GDestroyNotify destroy)
|
||||
{
|
||||
ClutterAlphaPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ALPHA (alpha));
|
||||
g_return_if_fail (func != NULL);
|
||||
|
||||
priv = alpha->priv;
|
||||
|
||||
if (priv->notify != NULL)
|
||||
{
|
||||
priv->notify (priv->user_data);
|
||||
}
|
||||
else if (priv->closure != NULL)
|
||||
{
|
||||
g_closure_unref (priv->closure);
|
||||
priv->closure = NULL;
|
||||
}
|
||||
|
||||
priv->func = func;
|
||||
priv->user_data = data;
|
||||
priv->notify = destroy;
|
||||
|
||||
priv->mode = CLUTTER_CUSTOM_MODE;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (alpha), obj_props[PROP_MODE]);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_alpha_set_timeline:
|
||||
* @alpha: A #ClutterAlpha
|
||||
* @timeline: A #ClutterTimeline
|
||||
*
|
||||
* Binds @alpha to @timeline.
|
||||
*
|
||||
* Since: 0.2
|
||||
*
|
||||
* Deprecated: 1.12: Use #ClutterTimeline directly
|
||||
*/
|
||||
void
|
||||
clutter_alpha_set_timeline (ClutterAlpha *alpha,
|
||||
ClutterTimeline *timeline)
|
||||
{
|
||||
ClutterAlphaPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ALPHA (alpha));
|
||||
g_return_if_fail (timeline == NULL || CLUTTER_IS_TIMELINE (timeline));
|
||||
|
||||
priv = alpha->priv;
|
||||
|
||||
if (priv->timeline == timeline)
|
||||
return;
|
||||
|
||||
if (priv->timeline)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (priv->timeline,
|
||||
timeline_new_frame_cb,
|
||||
alpha);
|
||||
|
||||
g_object_unref (priv->timeline);
|
||||
priv->timeline = NULL;
|
||||
}
|
||||
|
||||
if (timeline)
|
||||
{
|
||||
priv->timeline = g_object_ref (timeline);
|
||||
|
||||
g_signal_connect (priv->timeline, "new-frame",
|
||||
G_CALLBACK (timeline_new_frame_cb),
|
||||
alpha);
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (alpha), obj_props[PROP_TIMELINE]);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_alpha_get_timeline:
|
||||
* @alpha: A #ClutterAlpha
|
||||
*
|
||||
* Gets the #ClutterTimeline bound to @alpha.
|
||||
*
|
||||
* Return value: (transfer none): a #ClutterTimeline instance
|
||||
*
|
||||
* Since: 0.2
|
||||
*
|
||||
* Deprecated: 1.12: Use #ClutterTimeline directlry
|
||||
*/
|
||||
ClutterTimeline *
|
||||
clutter_alpha_get_timeline (ClutterAlpha *alpha)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_ALPHA (alpha), NULL);
|
||||
|
||||
return alpha->priv->timeline;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_alpha_new:
|
||||
*
|
||||
* Creates a new #ClutterAlpha instance. You must set a function
|
||||
* to compute the alpha value using clutter_alpha_set_func() and
|
||||
* bind a #ClutterTimeline object to the #ClutterAlpha instance
|
||||
* using clutter_alpha_set_timeline().
|
||||
*
|
||||
* Return value: the newly created empty #ClutterAlpha instance.
|
||||
*
|
||||
* Since: 0.2
|
||||
*
|
||||
* Deprecated: 1.12: Use #ClutterTimeline instead
|
||||
*/
|
||||
ClutterAlpha *
|
||||
clutter_alpha_new (void)
|
||||
{
|
||||
return g_object_new (CLUTTER_TYPE_ALPHA, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_alpha_new_full:
|
||||
* @timeline: #ClutterTimeline timeline
|
||||
* @mode: animation mode
|
||||
*
|
||||
* Creates a new #ClutterAlpha instance and sets the timeline
|
||||
* and animation mode.
|
||||
*
|
||||
* See also clutter_alpha_set_timeline() and clutter_alpha_set_mode().
|
||||
*
|
||||
* Return Value: the newly created #ClutterAlpha
|
||||
*
|
||||
* Since: 1.0
|
||||
*
|
||||
* Deprecated: 1.12: Use #ClutterTimeline instead
|
||||
*/
|
||||
ClutterAlpha *
|
||||
clutter_alpha_new_full (ClutterTimeline *timeline,
|
||||
gulong mode)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_TIMELINE (timeline), NULL);
|
||||
g_return_val_if_fail (mode != CLUTTER_ANIMATION_LAST, NULL);
|
||||
|
||||
return g_object_new (CLUTTER_TYPE_ALPHA,
|
||||
"timeline", timeline,
|
||||
"mode", mode,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_alpha_get_mode:
|
||||
* @alpha: a #ClutterAlpha
|
||||
*
|
||||
* Retrieves the #ClutterAnimationMode used by @alpha.
|
||||
*
|
||||
* Return value: the animation mode
|
||||
*
|
||||
* Since: 1.0
|
||||
*
|
||||
* Deprecated: 1.12: Use #ClutterTimeline instead
|
||||
*/
|
||||
gulong
|
||||
clutter_alpha_get_mode (ClutterAlpha *alpha)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_ALPHA (alpha), CLUTTER_CUSTOM_MODE);
|
||||
|
||||
return alpha->priv->mode;
|
||||
}
|
||||
|
||||
typedef struct _AlphaData {
|
||||
guint closure_set : 1;
|
||||
|
||||
ClutterAlphaFunc func;
|
||||
gpointer data;
|
||||
|
||||
GClosure *closure;
|
||||
} AlphaData;
|
||||
|
||||
static GPtrArray *clutter_alphas = NULL;
|
||||
|
||||
static gdouble
|
||||
clutter_alpha_easing_func (ClutterAlpha *alpha,
|
||||
gpointer data G_GNUC_UNUSED)
|
||||
{
|
||||
ClutterAlphaPrivate *priv = alpha->priv;
|
||||
ClutterTimeline *timeline = priv->timeline;
|
||||
gdouble t, d;
|
||||
|
||||
if (G_UNLIKELY (priv->timeline == NULL))
|
||||
return 0.0;
|
||||
|
||||
t = clutter_timeline_get_elapsed_time (timeline);
|
||||
d = clutter_timeline_get_duration (timeline);
|
||||
|
||||
return clutter_easing_for_mode (priv->mode, t, d);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_alpha_set_mode:
|
||||
* @alpha: a #ClutterAlpha
|
||||
* @mode: a #ClutterAnimationMode
|
||||
*
|
||||
* Sets the progress function of @alpha using the symbolic value
|
||||
* of @mode, as taken by the #ClutterAnimationMode enumeration.
|
||||
*
|
||||
* Since: 1.0
|
||||
*
|
||||
* Deprecated: 1.12: Use #ClutterTimeline and
|
||||
* clutter_timeline_set_progress_mode() instead
|
||||
*/
|
||||
void
|
||||
clutter_alpha_set_mode (ClutterAlpha *alpha,
|
||||
gulong mode)
|
||||
{
|
||||
ClutterAlphaPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ALPHA (alpha));
|
||||
g_return_if_fail (mode != CLUTTER_ANIMATION_LAST);
|
||||
|
||||
priv = alpha->priv;
|
||||
|
||||
if (mode == CLUTTER_CUSTOM_MODE)
|
||||
{
|
||||
priv->mode = mode;
|
||||
}
|
||||
else if (mode < CLUTTER_ANIMATION_LAST)
|
||||
{
|
||||
if (priv->mode == mode)
|
||||
return;
|
||||
|
||||
/* sanity check to avoid getting an out of sync
|
||||
* enum/function mapping
|
||||
*/
|
||||
g_assert (clutter_get_easing_func_for_mode (mode) != NULL);
|
||||
|
||||
clutter_alpha_set_closure_internal (alpha, NULL);
|
||||
|
||||
priv->mode = mode;
|
||||
|
||||
CLUTTER_NOTE (ANIMATION, "New easing mode '%s'[%lu]\n",
|
||||
clutter_get_easing_name_for_mode (priv->mode),
|
||||
priv->mode);
|
||||
|
||||
priv->func = clutter_alpha_easing_func;
|
||||
priv->user_data = NULL;
|
||||
priv->notify = NULL;
|
||||
}
|
||||
else if (mode > CLUTTER_ANIMATION_LAST)
|
||||
{
|
||||
AlphaData *alpha_data = NULL;
|
||||
gulong real_index = 0;
|
||||
|
||||
if (priv->mode == mode)
|
||||
return;
|
||||
|
||||
if (G_UNLIKELY (clutter_alphas == NULL))
|
||||
{
|
||||
g_warning ("No alpha functions defined for ClutterAlpha to use. ");
|
||||
return;
|
||||
}
|
||||
|
||||
real_index = mode - CLUTTER_ANIMATION_LAST - 1;
|
||||
|
||||
alpha_data = g_ptr_array_index (clutter_alphas, real_index);
|
||||
if (G_UNLIKELY (alpha_data == NULL))
|
||||
{
|
||||
g_warning ("No alpha function registered for mode %lu.",
|
||||
mode);
|
||||
return;
|
||||
}
|
||||
|
||||
if (alpha_data->closure_set)
|
||||
clutter_alpha_set_closure (alpha, alpha_data->closure);
|
||||
else
|
||||
{
|
||||
clutter_alpha_set_closure_internal (alpha, NULL);
|
||||
|
||||
priv->func = alpha_data->func;
|
||||
priv->user_data = alpha_data->data;
|
||||
priv->notify = NULL;
|
||||
}
|
||||
|
||||
priv->mode = mode;
|
||||
}
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (alpha), obj_props[PROP_MODE]);
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Authored By Matthew Allum <mallum@openedhand.com>
|
||||
* Jorn Baayen <jorn@openedhand.com>
|
||||
* Emmanuele Bassi <ebassi@openedhand.com>
|
||||
* Tomas Frydrych <tf@openedhand.com>
|
||||
*
|
||||
* Copyright (C) 2006, 2007, 2008 OpenedHand
|
||||
* Copyright (C) 2009 Intel Corp.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __CLUTTER_ALPHA_H__
|
||||
#define __CLUTTER_ALPHA_H__
|
||||
|
||||
#include <clutter/clutter-timeline.h>
|
||||
#include <clutter/clutter-types.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_ALPHA (clutter_alpha_get_type ())
|
||||
#define CLUTTER_ALPHA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ALPHA, ClutterAlpha))
|
||||
#define CLUTTER_ALPHA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ALPHA, ClutterAlphaClass))
|
||||
#define CLUTTER_IS_ALPHA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ALPHA))
|
||||
#define CLUTTER_IS_ALPHA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ALPHA))
|
||||
#define CLUTTER_ALPHA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ALPHA, ClutterAlphaClass))
|
||||
|
||||
typedef struct _ClutterAlphaClass ClutterAlphaClass;
|
||||
typedef struct _ClutterAlphaPrivate ClutterAlphaPrivate;
|
||||
|
||||
/**
|
||||
* ClutterAlphaFunc:
|
||||
* @alpha: a #ClutterAlpha
|
||||
* @user_data: user data passed to the function
|
||||
*
|
||||
* A function returning a value depending on the position of
|
||||
* the #ClutterTimeline bound to @alpha.
|
||||
*
|
||||
* Return value: a floating point value
|
||||
*
|
||||
* Since: 0.2
|
||||
*
|
||||
* Deprecated: 1.12: Use #ClutterTimelineProgressFunc instead.
|
||||
*/
|
||||
typedef gdouble (*ClutterAlphaFunc) (ClutterAlpha *alpha,
|
||||
gpointer user_data);
|
||||
|
||||
/**
|
||||
* ClutterAlpha:
|
||||
*
|
||||
* #ClutterAlpha combines a #ClutterTimeline and a function.
|
||||
* The contents of the #ClutterAlpha structure are private and should
|
||||
* only be accessed using the provided API.
|
||||
*
|
||||
* Since: 0.2
|
||||
*
|
||||
* Deprecated: 1.12: Use #ClutterTimeline instead
|
||||
*/
|
||||
struct _ClutterAlpha
|
||||
{
|
||||
/*< private >*/
|
||||
GInitiallyUnowned parent;
|
||||
|
||||
ClutterAlphaPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* ClutterAlphaClass:
|
||||
*
|
||||
* Base class for #ClutterAlpha
|
||||
*
|
||||
* Since: 0.2
|
||||
*
|
||||
* Deprecated: 1.12: Use #ClutterTimeline instead
|
||||
*/
|
||||
struct _ClutterAlphaClass
|
||||
{
|
||||
/*< private >*/
|
||||
GInitiallyUnownedClass parent_class;
|
||||
|
||||
void (*_clutter_alpha_1) (void);
|
||||
void (*_clutter_alpha_2) (void);
|
||||
void (*_clutter_alpha_3) (void);
|
||||
void (*_clutter_alpha_4) (void);
|
||||
void (*_clutter_alpha_5) (void);
|
||||
};
|
||||
|
||||
CLUTTER_DEPRECATED
|
||||
GType clutter_alpha_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_DEPRECATED
|
||||
ClutterAlpha * clutter_alpha_new (void);
|
||||
CLUTTER_DEPRECATED
|
||||
ClutterAlpha * clutter_alpha_new_full (ClutterTimeline *timeline,
|
||||
gulong mode);
|
||||
CLUTTER_DEPRECATED
|
||||
gdouble clutter_alpha_get_alpha (ClutterAlpha *alpha);
|
||||
CLUTTER_DEPRECATED
|
||||
void clutter_alpha_set_func (ClutterAlpha *alpha,
|
||||
ClutterAlphaFunc func,
|
||||
gpointer data,
|
||||
GDestroyNotify destroy);
|
||||
CLUTTER_DEPRECATED
|
||||
void clutter_alpha_set_closure (ClutterAlpha *alpha,
|
||||
GClosure *closure);
|
||||
CLUTTER_DEPRECATED
|
||||
void clutter_alpha_set_timeline (ClutterAlpha *alpha,
|
||||
ClutterTimeline *timeline);
|
||||
CLUTTER_DEPRECATED
|
||||
ClutterTimeline *clutter_alpha_get_timeline (ClutterAlpha *alpha);
|
||||
CLUTTER_DEPRECATED
|
||||
void clutter_alpha_set_mode (ClutterAlpha *alpha,
|
||||
gulong mode);
|
||||
CLUTTER_DEPRECATED
|
||||
gulong clutter_alpha_get_mode (ClutterAlpha *alpha);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_ALPHA_H__ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,152 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright (C) 2008 Intel Corporation.
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
|
||||
#error "Only <clutter/clutter.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __CLUTTER_ANIMATION_H__
|
||||
#define __CLUTTER_ANIMATION_H__
|
||||
|
||||
#include <clutter/clutter-types.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_ANIMATION (clutter_animation_get_type ())
|
||||
#define CLUTTER_ANIMATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ANIMATION, ClutterAnimation))
|
||||
#define CLUTTER_IS_ANIMATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ANIMATION))
|
||||
#define CLUTTER_ANIMATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ANIMATION, ClutterAnimationClass))
|
||||
#define CLUTTER_IS_ANIMATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ANIMATION))
|
||||
#define CLUTTER_ANIMATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ANIMATION, ClutterAnimationClass))
|
||||
|
||||
typedef struct _ClutterAnimationPrivate ClutterAnimationPrivate;
|
||||
typedef struct _ClutterAnimationClass ClutterAnimationClass;
|
||||
|
||||
/**
|
||||
* ClutterAnimation:
|
||||
*
|
||||
* The #ClutterAnimation structure contains only private data and should
|
||||
* be accessed using the provided functions.
|
||||
*
|
||||
* Since: 1.0
|
||||
*
|
||||
* Deprecated: 1.12: Use the implicit animation on #ClutterActor
|
||||
*/
|
||||
struct _ClutterAnimation
|
||||
{
|
||||
/*< private >*/
|
||||
GObject parent_instance;
|
||||
|
||||
ClutterAnimationPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* ClutterAnimationClass:
|
||||
* @started: class handler for the #ClutterAnimation::started signal
|
||||
* @completed: class handler for the #ClutterAnimation::completed signal
|
||||
*
|
||||
* The #ClutterAnimationClass structure contains only private data and
|
||||
* should be accessed using the provided functions.
|
||||
*
|
||||
* Since: 1.0
|
||||
*
|
||||
* Deprecated: 1.12: Use the implicit animation on #ClutterActor
|
||||
*/
|
||||
struct _ClutterAnimationClass
|
||||
{
|
||||
/*< private >*/
|
||||
GObjectClass parent_class;
|
||||
|
||||
/*< public >*/
|
||||
void (* started) (ClutterAnimation *animation);
|
||||
void (* completed) (ClutterAnimation *animation);
|
||||
|
||||
/*< private >*/
|
||||
/* padding for future expansion */
|
||||
void (*_clutter_reserved1) (void);
|
||||
void (*_clutter_reserved2) (void);
|
||||
void (*_clutter_reserved3) (void);
|
||||
void (*_clutter_reserved4) (void);
|
||||
void (*_clutter_reserved5) (void);
|
||||
void (*_clutter_reserved6) (void);
|
||||
void (*_clutter_reserved7) (void);
|
||||
void (*_clutter_reserved8) (void);
|
||||
};
|
||||
|
||||
CLUTTER_DEPRECATED
|
||||
GType clutter_animation_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_DEPRECATED_FOR(clutter_property_transition_new)
|
||||
ClutterAnimation * clutter_animation_new (void);
|
||||
|
||||
CLUTTER_DEPRECATED_FOR(clutter_transition_set_animatable)
|
||||
void clutter_animation_set_object (ClutterAnimation *animation,
|
||||
GObject *object);
|
||||
CLUTTER_DEPRECATED_FOR(clutter_timeline_set_progress_mode)
|
||||
void clutter_animation_set_mode (ClutterAnimation *animation,
|
||||
gulong mode);
|
||||
CLUTTER_DEPRECATED_FOR(clutter_timeline_get_progress_mode)
|
||||
gulong clutter_animation_get_mode (ClutterAnimation *animation);
|
||||
CLUTTER_DEPRECATED_FOR(clutter_timeline_set_duration)
|
||||
void clutter_animation_set_duration (ClutterAnimation *animation,
|
||||
guint msecs);
|
||||
CLUTTER_DEPRECATED_FOR(clutter_timeline_get_duration)
|
||||
guint clutter_animation_get_duration (ClutterAnimation *animation);
|
||||
CLUTTER_DEPRECATED_FOR(clutter_timeline_set_repeat_count)
|
||||
void clutter_animation_set_loop (ClutterAnimation *animation,
|
||||
gboolean loop);
|
||||
CLUTTER_DEPRECATED_FOR(clutter_timeline_get_repeat_count)
|
||||
gboolean clutter_animation_get_loop (ClutterAnimation *animation);
|
||||
CLUTTER_DEPRECATED
|
||||
void clutter_animation_set_timeline (ClutterAnimation *animation,
|
||||
ClutterTimeline *timeline);
|
||||
CLUTTER_DEPRECATED
|
||||
ClutterTimeline * clutter_animation_get_timeline (ClutterAnimation *animation);
|
||||
CLUTTER_DEPRECATED
|
||||
gboolean clutter_animation_has_property (ClutterAnimation *animation,
|
||||
const gchar *property_name);
|
||||
CLUTTER_DEPRECATED
|
||||
ClutterInterval * clutter_animation_get_interval (ClutterAnimation *animation,
|
||||
const gchar *property_name);
|
||||
|
||||
/*
|
||||
* ClutterActor API
|
||||
*/
|
||||
|
||||
CLUTTER_DEPRECATED
|
||||
ClutterAnimation * clutter_actor_animate (ClutterActor *actor,
|
||||
gulong mode,
|
||||
guint duration,
|
||||
const gchar *first_property_name,
|
||||
...) G_GNUC_NULL_TERMINATED;
|
||||
CLUTTER_DEPRECATED
|
||||
ClutterAnimation * clutter_actor_animate_with_timeline (ClutterActor *actor,
|
||||
gulong mode,
|
||||
ClutterTimeline *timeline,
|
||||
const gchar *first_property_name,
|
||||
...) G_GNUC_NULL_TERMINATED;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_ANIMATION_DEPRECATED_H__ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,147 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Authored By Øyvind Kolås <pippin@linux.intel.com>
|
||||
*
|
||||
* Copyright (C) 2009 Intel Corporation
|
||||
*
|
||||
* 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_STATE_H__
|
||||
#define __CLUTTER_STATE_H__
|
||||
|
||||
#include <clutter/clutter-types.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_STATE_KEY (clutter_state_key_get_type ())
|
||||
#define CLUTTER_TYPE_STATE (clutter_state_get_type ())
|
||||
#define CLUTTER_STATE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_STATE, ClutterState))
|
||||
#define CLUTTER_STATE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_STATE, ClutterStateClass))
|
||||
#define CLUTTER_IS_STATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_STATE))
|
||||
#define CLUTTER_IS_STATE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_STATE))
|
||||
#define CLUTTER_STATE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_STATE, ClutterStateClass))
|
||||
|
||||
typedef struct _ClutterStatePrivate ClutterStatePrivate;
|
||||
typedef struct _ClutterStateClass ClutterStateClass;
|
||||
|
||||
/**
|
||||
* ClutterStateKey:
|
||||
*
|
||||
* #ClutterStateKey is an opaque structure whose
|
||||
* members cannot be accessed directly
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
typedef struct _ClutterStateKey ClutterStateKey;
|
||||
|
||||
/**
|
||||
* ClutterState:
|
||||
*
|
||||
* The #ClutterState structure contains only
|
||||
* private data and should be accessed using the provided API
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
struct _ClutterState
|
||||
{
|
||||
/*< private >*/
|
||||
GObject parent;
|
||||
ClutterStatePrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* ClutterStateClass:
|
||||
* @completed: class handler for the #ClutterState::completed signal
|
||||
*
|
||||
* The #ClutterStateClass structure contains
|
||||
* only private data
|
||||
*
|
||||
* Since: 1.4
|
||||
*
|
||||
* Deprecated: 1.12
|
||||
*/
|
||||
struct _ClutterStateClass
|
||||
{
|
||||
/*< private >*/
|
||||
GObjectClass parent_class;
|
||||
|
||||
/*< public >*/
|
||||
void (* completed) (ClutterState *state);
|
||||
|
||||
/*< private >*/
|
||||
/* padding for future expansion */
|
||||
gpointer _padding_dummy[8];
|
||||
};
|
||||
|
||||
CLUTTER_DEPRECATED
|
||||
GType clutter_state_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_DEPRECATED
|
||||
ClutterState *clutter_state_new (void);
|
||||
|
||||
|
||||
CLUTTER_DEPRECATED
|
||||
ClutterTimeline * clutter_state_set_state (ClutterState *state,
|
||||
const gchar *target_state_name);
|
||||
CLUTTER_DEPRECATED
|
||||
ClutterTimeline * clutter_state_warp_to_state (ClutterState *state,
|
||||
const gchar *target_state_name);
|
||||
CLUTTER_DEPRECATED
|
||||
ClutterState * clutter_state_set_key (ClutterState *state,
|
||||
const gchar *source_state_name,
|
||||
const gchar *target_state_name,
|
||||
GObject *object,
|
||||
const gchar *property_name,
|
||||
guint mode,
|
||||
const GValue *value,
|
||||
gdouble pre_delay,
|
||||
gdouble post_delay);
|
||||
CLUTTER_DEPRECATED
|
||||
void clutter_state_set_duration (ClutterState *state,
|
||||
const gchar *source_state_name,
|
||||
const gchar *target_state_name,
|
||||
guint duration);
|
||||
CLUTTER_DEPRECATED
|
||||
guint clutter_state_get_duration (ClutterState *state,
|
||||
const gchar *source_state_name,
|
||||
const gchar *target_state_name);
|
||||
CLUTTER_DEPRECATED
|
||||
void clutter_state_set (ClutterState *state,
|
||||
const gchar *source_state_name,
|
||||
const gchar *target_state_name,
|
||||
gpointer first_object,
|
||||
const gchar *first_property_name,
|
||||
gulong first_mode,
|
||||
...) G_GNUC_NULL_TERMINATED;
|
||||
CLUTTER_DEPRECATED
|
||||
GList * clutter_state_get_states (ClutterState *state);
|
||||
CLUTTER_DEPRECATED
|
||||
const gchar * clutter_state_get_state (ClutterState *state);
|
||||
|
||||
/*
|
||||
* ClutterStateKey
|
||||
*/
|
||||
|
||||
CLUTTER_DEPRECATED
|
||||
GType clutter_state_key_get_type (void) G_GNUC_CONST;
|
||||
CLUTTER_DEPRECATED
|
||||
GType clutter_state_key_get_property_type (const ClutterStateKey *key);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_STATE_H__ */
|
||||
@@ -219,24 +219,18 @@ clutter_nonintrospected_sources = [
|
||||
|
||||
clutter_deprecated_headers = [
|
||||
'deprecated/clutter-actor.h',
|
||||
'deprecated/clutter-alpha.h',
|
||||
'deprecated/clutter-animation.h',
|
||||
'deprecated/clutter-box.h',
|
||||
'deprecated/clutter-container.h',
|
||||
'deprecated/clutter-group.h',
|
||||
'deprecated/clutter-rectangle.h',
|
||||
'deprecated/clutter-stage.h',
|
||||
'deprecated/clutter-state.h',
|
||||
'deprecated/clutter-timeline.h',
|
||||
]
|
||||
|
||||
clutter_deprecated_sources = [
|
||||
'deprecated/clutter-alpha.c',
|
||||
'deprecated/clutter-animation.c',
|
||||
'deprecated/clutter-box.c',
|
||||
'deprecated/clutter-group.c',
|
||||
'deprecated/clutter-rectangle.c',
|
||||
'deprecated/clutter-state.c',
|
||||
]
|
||||
|
||||
clutter_backend_sources = []
|
||||
|
||||
@@ -70,3 +70,12 @@
|
||||
|
||||
/* Whether Xwayland has -initfd option */
|
||||
#mesondefine HAVE_XWAYLAND_INITFD
|
||||
|
||||
/* Whether the mkostemp function exists */
|
||||
#mesondefine HAVE_MKOSTEMP
|
||||
|
||||
/* Whether the posix_fallocate function exists */
|
||||
#mesondefine HAVE_POSIX_FALLOCATE
|
||||
|
||||
/* Whether the memfd_create function exists */
|
||||
#mesondefine HAVE_MEMFD_CREATE
|
||||
|
||||
17
meson.build
17
meson.build
@@ -1,5 +1,5 @@
|
||||
project('mutter', 'c',
|
||||
version: '3.37.0',
|
||||
version: '3.37.1',
|
||||
meson_version: '>= 0.50.0',
|
||||
license: 'GPLv2+'
|
||||
)
|
||||
@@ -408,6 +408,20 @@ if have_wayland
|
||||
endif
|
||||
endif
|
||||
|
||||
optional_functions = [
|
||||
'mkostemp',
|
||||
'posix_fallocate',
|
||||
'memfd_create',
|
||||
]
|
||||
|
||||
foreach function : optional_functions
|
||||
if cc.has_function(function)
|
||||
cdata.set('HAVE_' + function.to_upper(), 1)
|
||||
else
|
||||
message('Optional function ' + function + ' missing')
|
||||
endif
|
||||
endforeach
|
||||
|
||||
xwayland_grab_default_access_rules = get_option('xwayland_grab_default_access_rules')
|
||||
cdata.set_quoted('XWAYLAND_GRAB_DEFAULT_ACCESS_RULES',
|
||||
xwayland_grab_default_access_rules)
|
||||
@@ -473,6 +487,7 @@ output = [
|
||||
' Cogl tests............... ' + have_cogl_tests.to_string(),
|
||||
' Clutter tests............ ' + have_clutter_tests.to_string(),
|
||||
' Installed tests.......... ' + have_installed_tests.to_string(),
|
||||
' Coverage................. ' + get_option('b_coverage').to_string(),
|
||||
'',
|
||||
' Now type \'ninja -C ' + meson.build_root() + '\' to build ' + meson.project_name(),
|
||||
'',
|
||||
|
||||
85
po/de.po
85
po/de.po
@@ -13,8 +13,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: mutter master\n"
|
||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n"
|
||||
"POT-Creation-Date: 2019-08-06 00:49+0000\n"
|
||||
"PO-Revision-Date: 2019-09-05 23:42+0200\n"
|
||||
"POT-Creation-Date: 2020-03-30 20:11+0000\n"
|
||||
"PO-Revision-Date: 2020-04-06 23:13+0200\n"
|
||||
"Last-Translator: Christian Kirbach <christian.kirbach@gmail.com>\n"
|
||||
"Language-Team: Deutsch <gnome-de@gnome.org>\n"
|
||||
"Language: de\n"
|
||||
@@ -22,7 +22,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 2.2.1\n"
|
||||
"X-Generator: Poedit 2.3\n"
|
||||
|
||||
#: data/50-mutter-navigation.xml:6
|
||||
msgid "Navigation"
|
||||
@@ -435,20 +435,33 @@ msgstr "Zusatztaste zum Finden des Zeigers"
|
||||
msgid "This key will initiate the “locate pointer” action."
|
||||
msgstr "Diese Taste wird die Aktion »Zeiger finden« auslösen."
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:155
|
||||
#: data/org.gnome.mutter.gschema.xml.in:142
|
||||
msgid "Timeout for check-alive ping"
|
||||
msgstr "Reaktionsschwellwert bei Kontaktkontrolle"
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:143
|
||||
msgid ""
|
||||
"Number of milliseconds a client has to respond to a ping request in order to "
|
||||
"not be detected as frozen. Using 0 will disable the alive check completely."
|
||||
msgstr ""
|
||||
"Zeit in Millisekunden, innerhalb welcher ein Client auf eine "
|
||||
"Kontaktkontrolle antworten muss, um nicht als abgestürzt zu gelten. »0« "
|
||||
"bedeutet, dass die Kontaktkontrolle ausgeschaltet wird."
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:165
|
||||
msgid "Select window from tab popup"
|
||||
msgstr "Fenster aus Tab-Anzeige auswählen"
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:160
|
||||
#: data/org.gnome.mutter.gschema.xml.in:170
|
||||
msgid "Cancel tab popup"
|
||||
msgstr "Tab-Anzeige abbrechen"
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:165
|
||||
#: data/org.gnome.mutter.gschema.xml.in:175
|
||||
msgid "Switch monitor configurations"
|
||||
msgstr "Bildschirmkonfigurationen wechseln"
|
||||
|
||||
# Ich denke nicht, dass »rotate« hier die Bildschirmdrehung meint, sondern eher eine Liste aus Konfigurationen rotiert (d.h. umgewälzt) wird.
|
||||
#: data/org.gnome.mutter.gschema.xml.in:170
|
||||
#: data/org.gnome.mutter.gschema.xml.in:180
|
||||
msgid "Rotates the built-in monitor configuration"
|
||||
msgstr "Wechselt die Konfiguration des eingebauten Bildschirms"
|
||||
|
||||
@@ -569,7 +582,7 @@ msgstr ""
|
||||
#. TRANSLATORS: This string refers to a button that switches between
|
||||
#. * different modes.
|
||||
#.
|
||||
#: src/backends/meta-input-settings.c:2531
|
||||
#: src/backends/meta-input-settings.c:2631
|
||||
#, c-format
|
||||
msgid "Mode Switch (Group %d)"
|
||||
msgstr "Moduswechsel (Gruppe %d)"
|
||||
@@ -577,34 +590,34 @@ msgstr "Moduswechsel (Gruppe %d)"
|
||||
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
|
||||
#. * mapping through the available outputs.
|
||||
#.
|
||||
#: src/backends/meta-input-settings.c:2554
|
||||
#: src/backends/meta-input-settings.c:2654
|
||||
msgid "Switch monitor"
|
||||
msgstr "Bildschirm wechseln"
|
||||
|
||||
#: src/backends/meta-input-settings.c:2556
|
||||
#: src/backends/meta-input-settings.c:2656
|
||||
msgid "Show on-screen help"
|
||||
msgstr "Bildschirmhilfe anzeigen"
|
||||
|
||||
#: src/backends/meta-monitor.c:223
|
||||
#: src/backends/meta-monitor.c:226
|
||||
msgid "Built-in display"
|
||||
msgstr "Eingebaute Anzeige"
|
||||
|
||||
#: src/backends/meta-monitor.c:252
|
||||
#: src/backends/meta-monitor.c:255
|
||||
msgid "Unknown"
|
||||
msgstr "Unbekannt"
|
||||
|
||||
#: src/backends/meta-monitor.c:254
|
||||
#: src/backends/meta-monitor.c:257
|
||||
msgid "Unknown Display"
|
||||
msgstr "Unbekannte Anzeige"
|
||||
|
||||
#: src/backends/meta-monitor.c:262
|
||||
#: src/backends/meta-monitor.c:265
|
||||
#, c-format
|
||||
msgctxt ""
|
||||
"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
|
||||
msgid "%s %s"
|
||||
msgstr "%s %s"
|
||||
|
||||
#: src/backends/meta-monitor.c:270
|
||||
#: src/backends/meta-monitor.c:273
|
||||
#, c-format
|
||||
msgctxt ""
|
||||
"This is a monitor vendor name followed by product/model name where size in "
|
||||
@@ -614,13 +627,13 @@ msgstr "%s %s"
|
||||
|
||||
# https://de.wikipedia.org/wiki/Composition-Manager
|
||||
#. Translators: this string will appear in Sysprof
|
||||
#: src/backends/meta-profiler.c:82
|
||||
#: src/backends/meta-profiler.c:79
|
||||
msgid "Compositor"
|
||||
msgstr "Compositor"
|
||||
|
||||
#. This probably means that a non-WM compositor like xcompmgr is running;
|
||||
#. * we have no way to get it to exit
|
||||
#: src/compositor/compositor.c:510
|
||||
#: src/compositor/compositor.c:533
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Another compositing manager is already running on screen %i on display “%s”."
|
||||
@@ -632,47 +645,47 @@ msgstr ""
|
||||
msgid "Bell event"
|
||||
msgstr "Klangereignis"
|
||||
|
||||
#: src/core/main.c:185
|
||||
#: src/core/main.c:190
|
||||
msgid "Disable connection to session manager"
|
||||
msgstr "Verbindung zur Sitzungsverwaltung deaktivieren"
|
||||
|
||||
#: src/core/main.c:191
|
||||
#: src/core/main.c:196
|
||||
msgid "Replace the running window manager"
|
||||
msgstr "Den aktuellen Fensterverwalter ersetzen"
|
||||
|
||||
#: src/core/main.c:197
|
||||
#: src/core/main.c:202
|
||||
msgid "Specify session management ID"
|
||||
msgstr "Kennung der Sitzungsverwaltung angeben"
|
||||
|
||||
#: src/core/main.c:202
|
||||
#: src/core/main.c:207
|
||||
msgid "X Display to use"
|
||||
msgstr "Zu verwendende X-Anzeige"
|
||||
|
||||
#: src/core/main.c:208
|
||||
#: src/core/main.c:213
|
||||
msgid "Initialize session from savefile"
|
||||
msgstr "Sitzung anhand gespeicherter Datei starten"
|
||||
|
||||
#: src/core/main.c:214
|
||||
#: src/core/main.c:219
|
||||
msgid "Make X calls synchronous"
|
||||
msgstr "X-Aufrufe abgleichen"
|
||||
|
||||
#: src/core/main.c:221
|
||||
#: src/core/main.c:226
|
||||
msgid "Run as a wayland compositor"
|
||||
msgstr "Als Wayland-Compositor ausführen"
|
||||
|
||||
#: src/core/main.c:227
|
||||
#: src/core/main.c:232
|
||||
msgid "Run as a nested compositor"
|
||||
msgstr "Als eingebetteten Compositor ausführen"
|
||||
|
||||
#: src/core/main.c:233
|
||||
#: src/core/main.c:238
|
||||
msgid "Run wayland compositor without starting Xwayland"
|
||||
msgstr "Wayland-Compositor ausführen, ohne Xwayland zu starten"
|
||||
|
||||
#: src/core/main.c:241
|
||||
#: src/core/main.c:246
|
||||
msgid "Run as a full display server, rather than nested"
|
||||
msgstr "Als vollwertigen Display-Server verwenden (nicht eingebettet)"
|
||||
|
||||
#: src/core/main.c:247
|
||||
#: src/core/main.c:252
|
||||
msgid "Run with X11 backend"
|
||||
msgstr "Mit X11-Backend ausführen"
|
||||
|
||||
@@ -728,21 +741,21 @@ msgstr "Version ausgeben"
|
||||
msgid "Mutter plugin to use"
|
||||
msgstr "Zu benutzendes Mutter-Plugin"
|
||||
|
||||
#: src/core/prefs.c:1849
|
||||
#: src/core/prefs.c:1911
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "Arbeitsfläche %d"
|
||||
|
||||
#: src/core/util.c:121
|
||||
#: src/core/util.c:122
|
||||
msgid "Mutter was compiled without support for verbose mode\n"
|
||||
msgstr "Mutter wurde ohne Unterstützung für den redseligen Modus kompiliert\n"
|
||||
|
||||
#: src/wayland/meta-wayland-tablet-pad.c:567
|
||||
#: src/wayland/meta-wayland-tablet-pad.c:568
|
||||
#, c-format
|
||||
msgid "Mode Switch: Mode %d"
|
||||
msgstr "Moduswechsel: Modus %d"
|
||||
|
||||
#: src/x11/meta-x11-display.c:671
|
||||
#: src/x11/meta-x11-display.c:676
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Display “%s” already has a window manager; try using the --replace option to "
|
||||
@@ -751,21 +764,21 @@ msgstr ""
|
||||
"Bildschirm »%s« hat bereits einen Fensterverwalter. Versuchen Sie die Option "
|
||||
"»--replace«, um den aktuellen Fensterverwalter zu ersetzen."
|
||||
|
||||
#: src/x11/meta-x11-display.c:1032
|
||||
#: src/x11/meta-x11-display.c:1089
|
||||
msgid "Failed to initialize GDK\n"
|
||||
msgstr "GDK konnte nicht initialisiert werden\n"
|
||||
|
||||
#: src/x11/meta-x11-display.c:1056
|
||||
#: src/x11/meta-x11-display.c:1113
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display “%s”\n"
|
||||
msgstr "X-Window-Systemanzeige »%s« konnte nicht geöffnet werden\n"
|
||||
|
||||
#: src/x11/meta-x11-display.c:1140
|
||||
#: src/x11/meta-x11-display.c:1196
|
||||
#, c-format
|
||||
msgid "Screen %d on display “%s” is invalid\n"
|
||||
msgstr "Bildschirm %d auf Anzeige »%s« ist ungültig\n"
|
||||
|
||||
#: src/x11/meta-x11-selection-input-stream.c:445
|
||||
#: src/x11/meta-x11-selection-input-stream.c:460
|
||||
#, c-format
|
||||
msgid "Format %s not supported"
|
||||
msgstr "Format %s wird nicht unterstützt"
|
||||
|
||||
@@ -49,6 +49,7 @@ typedef struct _MetaTileInfo MetaTileInfo;
|
||||
typedef struct _MetaRenderer MetaRenderer;
|
||||
typedef struct _MetaRendererView MetaRendererView;
|
||||
|
||||
typedef struct _MetaRemoteDesktop MetaRemoteDesktop;
|
||||
typedef struct _MetaScreenCast MetaScreenCast;
|
||||
typedef struct _MetaScreenCastSession MetaScreenCastSession;
|
||||
typedef struct _MetaScreenCastStream MetaScreenCastStream;
|
||||
|
||||
@@ -552,12 +552,12 @@ meta_backend_real_post_init (MetaBackend *backend)
|
||||
}
|
||||
|
||||
#ifdef HAVE_REMOTE_DESKTOP
|
||||
priv->remote_access_controller =
|
||||
g_object_new (META_TYPE_REMOTE_ACCESS_CONTROLLER, NULL);
|
||||
priv->dbus_session_watcher = g_object_new (META_TYPE_DBUS_SESSION_WATCHER, NULL);
|
||||
priv->screen_cast = meta_screen_cast_new (backend,
|
||||
priv->dbus_session_watcher);
|
||||
priv->remote_desktop = meta_remote_desktop_new (priv->dbus_session_watcher);
|
||||
priv->remote_access_controller =
|
||||
meta_remote_access_controller_new (priv->remote_desktop, priv->screen_cast);
|
||||
#endif /* HAVE_REMOTE_DESKTOP */
|
||||
|
||||
if (!meta_monitor_manager_is_headless (priv->monitor_manager))
|
||||
@@ -809,9 +809,6 @@ static MetaMonitorManager *
|
||||
meta_backend_create_monitor_manager (MetaBackend *backend,
|
||||
GError **error)
|
||||
{
|
||||
if (g_getenv ("META_DUMMY_MONITORS"))
|
||||
return g_object_new (META_TYPE_MONITOR_MANAGER_DUMMY, NULL);
|
||||
|
||||
return META_BACKEND_GET_CLASS (backend)->create_monitor_manager (backend,
|
||||
error);
|
||||
}
|
||||
|
||||
@@ -54,8 +54,8 @@ meta_input_device_init (MetaInputDevice *input_device)
|
||||
static void
|
||||
meta_input_device_constructed (GObject *object)
|
||||
{
|
||||
MetaInputDevice *input_device = META_INPUT_DEVICE (object);
|
||||
#ifdef HAVE_LIBWACOM
|
||||
MetaInputDevice *input_device;
|
||||
WacomDeviceDatabase *wacom_db;
|
||||
MetaInputDevicePrivate *priv;
|
||||
const char *node;
|
||||
@@ -64,6 +64,7 @@ meta_input_device_constructed (GObject *object)
|
||||
G_OBJECT_CLASS (meta_input_device_parent_class)->constructed (object);
|
||||
|
||||
#ifdef HAVE_LIBWACOM
|
||||
input_device = META_INPUT_DEVICE (object);
|
||||
priv = meta_input_device_get_instance_private (input_device);
|
||||
wacom_db = meta_backend_get_wacom_database (meta_get_backend ());
|
||||
node = clutter_input_device_get_device_node (CLUTTER_INPUT_DEVICE (input_device));
|
||||
|
||||
@@ -90,6 +90,7 @@ float meta_logical_monitor_get_scale (MetaLogicalMonitor *logical_monitor);
|
||||
|
||||
MetaMonitorTransform meta_logical_monitor_get_transform (MetaLogicalMonitor *logical_monitor);
|
||||
|
||||
META_EXPORT_TEST
|
||||
MetaRectangle meta_logical_monitor_get_layout (MetaLogicalMonitor *logical_monitor);
|
||||
|
||||
META_EXPORT_TEST
|
||||
|
||||
@@ -49,7 +49,7 @@ meta_monitor_transform_is_rotated (MetaMonitorTransform transform)
|
||||
static inline gboolean
|
||||
meta_monitor_transform_is_flipped (MetaMonitorTransform transform)
|
||||
{
|
||||
return (abs(transform) >= META_MONITOR_TRANSFORM_FLIPPED);
|
||||
return (transform >= META_MONITOR_TRANSFORM_FLIPPED);
|
||||
}
|
||||
|
||||
MetaMonitorTransform meta_monitor_transform_invert (MetaMonitorTransform transform);
|
||||
|
||||
@@ -21,8 +21,12 @@
|
||||
#ifndef META_REMOTE_ACCESS_CONTROLLER_PRIVATE_H
|
||||
#define META_REMOTE_ACCESS_CONTROLLER_PRIVATE_H
|
||||
|
||||
#include "backends/meta-backend-types.h"
|
||||
#include "meta/meta-remote-access-controller.h"
|
||||
|
||||
MetaRemoteAccessController * meta_remote_access_controller_new (MetaRemoteDesktop *remote_desktop,
|
||||
MetaScreenCast *screen_cast);
|
||||
|
||||
void meta_remote_access_controller_notify_new_handle (MetaRemoteAccessController *controller,
|
||||
MetaRemoteAccessHandle *handle);
|
||||
|
||||
|
||||
@@ -22,6 +22,11 @@
|
||||
|
||||
#include "backends/meta-remote-access-controller-private.h"
|
||||
|
||||
#ifdef HAVE_REMOTE_DESKTOP
|
||||
#include "backends/meta-remote-desktop.h"
|
||||
#include "backends/meta-screen-cast.h"
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
HANDLE_STOPPED,
|
||||
@@ -54,6 +59,9 @@ G_DEFINE_TYPE_WITH_PRIVATE (MetaRemoteAccessHandle,
|
||||
struct _MetaRemoteAccessController
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
MetaRemoteDesktop *remote_desktop;
|
||||
MetaScreenCast *screen_cast;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaRemoteAccessController,
|
||||
@@ -122,6 +130,53 @@ meta_remote_access_controller_notify_new_handle (MetaRemoteAccessController *con
|
||||
handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_remote_access_controller_inhibit_remote_access:
|
||||
* @controller: a #MetaRemoteAccessController
|
||||
*
|
||||
* Inhibits remote access sessions from being created and running. Any active
|
||||
* remote access session will be terminated.
|
||||
*/
|
||||
void
|
||||
meta_remote_access_controller_inhibit_remote_access (MetaRemoteAccessController *controller)
|
||||
{
|
||||
#ifdef HAVE_REMOTE_DESKTOP
|
||||
meta_remote_desktop_inhibit (controller->remote_desktop);
|
||||
meta_screen_cast_inhibit (controller->screen_cast);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_remote_access_controller_uninhibit_remote_access:
|
||||
* @controller: a #MetaRemoteAccessController
|
||||
*
|
||||
* Uninhibits remote access sessions from being created and running. If this was
|
||||
* the last inhibitation that was inhibited, new remote access sessions can now
|
||||
* be created.
|
||||
*/
|
||||
void
|
||||
meta_remote_access_controller_uninhibit_remote_access (MetaRemoteAccessController *controller)
|
||||
{
|
||||
#ifdef HAVE_REMOTE_DESKTOP
|
||||
meta_screen_cast_uninhibit (controller->screen_cast);
|
||||
meta_remote_desktop_uninhibit (controller->remote_desktop);
|
||||
#endif
|
||||
}
|
||||
|
||||
MetaRemoteAccessController *
|
||||
meta_remote_access_controller_new (MetaRemoteDesktop *remote_desktop,
|
||||
MetaScreenCast *screen_cast)
|
||||
{
|
||||
MetaRemoteAccessController *remote_access_controller;
|
||||
|
||||
remote_access_controller = g_object_new (META_TYPE_REMOTE_ACCESS_CONTROLLER,
|
||||
NULL);
|
||||
remote_access_controller->remote_desktop = remote_desktop;
|
||||
remote_access_controller->screen_cast = screen_cast;
|
||||
|
||||
return remote_access_controller;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_remote_access_handle_init (MetaRemoteAccessHandle *handle)
|
||||
{
|
||||
|
||||
@@ -56,6 +56,8 @@ struct _MetaRemoteDesktop
|
||||
|
||||
int dbus_name_id;
|
||||
|
||||
int inhibit_count;
|
||||
|
||||
GHashTable *sessions;
|
||||
|
||||
MetaDbusSessionWatcher *session_watcher;
|
||||
@@ -70,6 +72,34 @@ G_DEFINE_TYPE_WITH_CODE (MetaRemoteDesktop,
|
||||
G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_REMOTE_DESKTOP,
|
||||
meta_remote_desktop_init_iface));
|
||||
|
||||
void
|
||||
meta_remote_desktop_inhibit (MetaRemoteDesktop *remote_desktop)
|
||||
{
|
||||
remote_desktop->inhibit_count++;
|
||||
if (remote_desktop->inhibit_count == 1)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
|
||||
g_hash_table_iter_init (&iter, remote_desktop->sessions);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
MetaRemoteDesktopSession *session = value;
|
||||
|
||||
g_hash_table_iter_steal (&iter);
|
||||
meta_remote_desktop_session_close (session);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_remote_desktop_uninhibit (MetaRemoteDesktop *remote_desktop)
|
||||
{
|
||||
g_return_if_fail (remote_desktop->inhibit_count > 0);
|
||||
|
||||
remote_desktop->inhibit_count--;
|
||||
}
|
||||
|
||||
GDBusConnection *
|
||||
meta_remote_desktop_get_connection (MetaRemoteDesktop *remote_desktop)
|
||||
{
|
||||
@@ -108,6 +138,15 @@ handle_create_session (MetaDBusRemoteDesktop *skeleton,
|
||||
char *session_path;
|
||||
const char *client_dbus_name;
|
||||
|
||||
if (remote_desktop->inhibit_count > 0)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Session creation inhibited");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
peer_name = g_dbus_method_invocation_get_sender (invocation);
|
||||
session = meta_remote_desktop_session_new (remote_desktop,
|
||||
peer_name,
|
||||
|
||||
@@ -36,6 +36,10 @@ G_DECLARE_FINAL_TYPE (MetaRemoteDesktop, meta_remote_desktop,
|
||||
META, REMOTE_DESKTOP,
|
||||
MetaDBusRemoteDesktopSkeleton)
|
||||
|
||||
void meta_remote_desktop_inhibit (MetaRemoteDesktop *remote_desktop);
|
||||
|
||||
void meta_remote_desktop_uninhibit (MetaRemoteDesktop *remote_desktop);
|
||||
|
||||
MetaRemoteDesktopSession * meta_remote_desktop_get_session (MetaRemoteDesktop *remote_desktop,
|
||||
const char *session_id);
|
||||
|
||||
|
||||
570
src/backends/meta-screen-cast-area-stream-src.c
Normal file
570
src/backends/meta-screen-cast-area-stream-src.c
Normal file
@@ -0,0 +1,570 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Red Hat Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "backends/meta-screen-cast-area-stream-src.h"
|
||||
|
||||
#include <spa/buffer/meta.h>
|
||||
|
||||
#include "backends/meta-backend-private.h"
|
||||
#include "backends/meta-cursor-tracker-private.h"
|
||||
#include "backends/meta-screen-cast-area-stream.h"
|
||||
#include "backends/meta-screen-cast-session.h"
|
||||
#include "backends/meta-stage-private.h"
|
||||
#include "clutter/clutter.h"
|
||||
#include "clutter/clutter-mutter.h"
|
||||
#include "core/boxes-private.h"
|
||||
|
||||
struct _MetaScreenCastAreaStreamSrc
|
||||
{
|
||||
MetaScreenCastStreamSrc parent;
|
||||
|
||||
gboolean cursor_bitmap_invalid;
|
||||
gboolean hw_cursor_inhibited;
|
||||
|
||||
GList *watches;
|
||||
|
||||
gulong cursor_moved_handler_id;
|
||||
gulong cursor_changed_handler_id;
|
||||
|
||||
guint maybe_record_idle_id;
|
||||
};
|
||||
|
||||
static void
|
||||
hw_cursor_inhibitor_iface_init (MetaHwCursorInhibitorInterface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (MetaScreenCastAreaStreamSrc,
|
||||
meta_screen_cast_area_stream_src,
|
||||
META_TYPE_SCREEN_CAST_STREAM_SRC,
|
||||
G_IMPLEMENT_INTERFACE (META_TYPE_HW_CURSOR_INHIBITOR,
|
||||
hw_cursor_inhibitor_iface_init))
|
||||
|
||||
static ClutterStage *
|
||||
get_stage (MetaScreenCastAreaStreamSrc *area_src)
|
||||
{
|
||||
MetaScreenCastStreamSrc *src;
|
||||
MetaScreenCastStream *stream;
|
||||
MetaScreenCastAreaStream *area_stream;
|
||||
|
||||
src = META_SCREEN_CAST_STREAM_SRC (area_src);
|
||||
stream = meta_screen_cast_stream_src_get_stream (src);
|
||||
area_stream = META_SCREEN_CAST_AREA_STREAM (stream);
|
||||
|
||||
return meta_screen_cast_area_stream_get_stage (area_stream);
|
||||
}
|
||||
|
||||
static MetaBackend *
|
||||
get_backend (MetaScreenCastAreaStreamSrc *area_src)
|
||||
{
|
||||
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_src);
|
||||
MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
|
||||
MetaScreenCastSession *session = meta_screen_cast_stream_get_session (stream);
|
||||
MetaScreenCast *screen_cast =
|
||||
meta_screen_cast_session_get_screen_cast (session);
|
||||
|
||||
return meta_screen_cast_get_backend (screen_cast);
|
||||
}
|
||||
|
||||
static MetaCursorRenderer *
|
||||
get_cursor_renderer (MetaScreenCastAreaStreamSrc *area_src)
|
||||
{
|
||||
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_src);
|
||||
MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
|
||||
MetaScreenCastSession *session = meta_screen_cast_stream_get_session (stream);
|
||||
MetaScreenCast *screen_cast =
|
||||
meta_screen_cast_session_get_screen_cast (session);
|
||||
MetaBackend *backend = meta_screen_cast_get_backend (screen_cast);
|
||||
|
||||
return meta_backend_get_cursor_renderer (backend);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_cast_area_stream_src_get_specs (MetaScreenCastStreamSrc *src,
|
||||
int *width,
|
||||
int *height,
|
||||
float *frame_rate)
|
||||
{
|
||||
MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
|
||||
MetaScreenCastAreaStream *area_stream = META_SCREEN_CAST_AREA_STREAM (stream);
|
||||
MetaRectangle *area;
|
||||
float scale;
|
||||
|
||||
area = meta_screen_cast_area_stream_get_area (area_stream);
|
||||
scale = meta_screen_cast_area_stream_get_scale (area_stream);
|
||||
|
||||
*width = (int) roundf (area->width * scale);
|
||||
*height = (int) roundf (area->height * scale);
|
||||
*frame_rate = 60.0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_cursor_in_stream (MetaScreenCastAreaStreamSrc *area_src)
|
||||
{
|
||||
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_src);
|
||||
MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
|
||||
MetaScreenCastAreaStream *area_stream = META_SCREEN_CAST_AREA_STREAM (stream);
|
||||
MetaBackend *backend = get_backend (area_src);
|
||||
MetaCursorRenderer *cursor_renderer =
|
||||
meta_backend_get_cursor_renderer (backend);
|
||||
MetaRectangle *area;
|
||||
graphene_rect_t area_rect;
|
||||
MetaCursorSprite *cursor_sprite;
|
||||
|
||||
area = meta_screen_cast_area_stream_get_area (area_stream);
|
||||
area_rect = meta_rectangle_to_graphene_rect (area);
|
||||
|
||||
cursor_sprite = meta_cursor_renderer_get_cursor (cursor_renderer);
|
||||
if (cursor_sprite)
|
||||
{
|
||||
graphene_rect_t cursor_rect;
|
||||
|
||||
cursor_rect = meta_cursor_renderer_calculate_rect (cursor_renderer,
|
||||
cursor_sprite);
|
||||
return graphene_rect_intersection (&cursor_rect, &area_rect, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
graphene_point_t cursor_position;
|
||||
|
||||
cursor_position = meta_cursor_renderer_get_position (cursor_renderer);
|
||||
return graphene_rect_contains_point (&area_rect, &cursor_position);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sync_cursor_state (MetaScreenCastAreaStreamSrc *area_src)
|
||||
{
|
||||
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_src);
|
||||
ClutterStage *stage = get_stage (area_src);
|
||||
|
||||
if (!is_cursor_in_stream (area_src))
|
||||
return;
|
||||
|
||||
if (clutter_stage_is_redraw_queued (stage))
|
||||
return;
|
||||
|
||||
meta_screen_cast_stream_src_maybe_record_frame (src);
|
||||
}
|
||||
|
||||
static void
|
||||
cursor_moved (MetaCursorTracker *cursor_tracker,
|
||||
float x,
|
||||
float y,
|
||||
MetaScreenCastAreaStreamSrc *area_src)
|
||||
{
|
||||
sync_cursor_state (area_src);
|
||||
}
|
||||
|
||||
static void
|
||||
cursor_changed (MetaCursorTracker *cursor_tracker,
|
||||
MetaScreenCastAreaStreamSrc *area_src)
|
||||
{
|
||||
area_src->cursor_bitmap_invalid = TRUE;
|
||||
sync_cursor_state (area_src);
|
||||
}
|
||||
|
||||
static void
|
||||
inhibit_hw_cursor (MetaScreenCastAreaStreamSrc *area_src)
|
||||
{
|
||||
MetaCursorRenderer *cursor_renderer;
|
||||
MetaHwCursorInhibitor *inhibitor;
|
||||
|
||||
g_return_if_fail (!area_src->hw_cursor_inhibited);
|
||||
|
||||
cursor_renderer = get_cursor_renderer (area_src);
|
||||
inhibitor = META_HW_CURSOR_INHIBITOR (area_src);
|
||||
meta_cursor_renderer_add_hw_cursor_inhibitor (cursor_renderer, inhibitor);
|
||||
|
||||
area_src->hw_cursor_inhibited = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
uninhibit_hw_cursor (MetaScreenCastAreaStreamSrc *area_src)
|
||||
{
|
||||
MetaCursorRenderer *cursor_renderer;
|
||||
MetaHwCursorInhibitor *inhibitor;
|
||||
|
||||
g_return_if_fail (area_src->hw_cursor_inhibited);
|
||||
|
||||
cursor_renderer = get_cursor_renderer (area_src);
|
||||
inhibitor = META_HW_CURSOR_INHIBITOR (area_src);
|
||||
meta_cursor_renderer_remove_hw_cursor_inhibitor (cursor_renderer, inhibitor);
|
||||
|
||||
area_src->hw_cursor_inhibited = FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
maybe_record_frame_on_idle (gpointer user_data)
|
||||
{
|
||||
MetaScreenCastAreaStreamSrc *area_src =
|
||||
META_SCREEN_CAST_AREA_STREAM_SRC (user_data);
|
||||
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_src);
|
||||
|
||||
area_src->maybe_record_idle_id = 0;
|
||||
|
||||
meta_screen_cast_stream_src_maybe_record_frame (src);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
stage_painted (MetaStage *stage,
|
||||
ClutterStageView *view,
|
||||
ClutterPaintContext *paint_context,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaScreenCastAreaStreamSrc *area_src =
|
||||
META_SCREEN_CAST_AREA_STREAM_SRC (user_data);
|
||||
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_src);
|
||||
MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
|
||||
MetaScreenCastAreaStream *area_stream = META_SCREEN_CAST_AREA_STREAM (stream);
|
||||
const cairo_region_t *redraw_clip;
|
||||
MetaRectangle *area;
|
||||
|
||||
if (area_src->maybe_record_idle_id)
|
||||
return;
|
||||
|
||||
area = meta_screen_cast_area_stream_get_area (area_stream);
|
||||
redraw_clip = clutter_paint_context_get_redraw_clip (paint_context);
|
||||
|
||||
if (redraw_clip)
|
||||
{
|
||||
switch (cairo_region_contains_rectangle (redraw_clip, area))
|
||||
{
|
||||
case CAIRO_REGION_OVERLAP_IN:
|
||||
case CAIRO_REGION_OVERLAP_PART:
|
||||
break;
|
||||
case CAIRO_REGION_OVERLAP_OUT:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
area_src->maybe_record_idle_id = g_idle_add (maybe_record_frame_on_idle, src);
|
||||
}
|
||||
|
||||
static void
|
||||
add_view_painted_watches (MetaScreenCastAreaStreamSrc *area_src,
|
||||
MetaStageWatchPhase watch_phase)
|
||||
{
|
||||
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_src);
|
||||
MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
|
||||
MetaScreenCastAreaStream *area_stream = META_SCREEN_CAST_AREA_STREAM (stream);
|
||||
MetaBackend *backend = get_backend (area_src);
|
||||
MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
||||
ClutterStage *stage;
|
||||
MetaStage *meta_stage;
|
||||
MetaRectangle *area;
|
||||
GList *l;
|
||||
|
||||
stage = get_stage (area_src);
|
||||
meta_stage = META_STAGE (stage);
|
||||
area = meta_screen_cast_area_stream_get_area (area_stream);
|
||||
|
||||
for (l = meta_renderer_get_views (renderer); l; l = l->next)
|
||||
{
|
||||
MetaRendererView *view = l->data;
|
||||
MetaRectangle view_layout;
|
||||
|
||||
clutter_stage_view_get_layout (CLUTTER_STAGE_VIEW (view), &view_layout);
|
||||
if (meta_rectangle_overlap (area, &view_layout))
|
||||
{
|
||||
MetaStageWatch *watch;
|
||||
|
||||
watch = meta_stage_watch_view (meta_stage,
|
||||
CLUTTER_STAGE_VIEW (view),
|
||||
watch_phase,
|
||||
stage_painted,
|
||||
area_src);
|
||||
|
||||
area_src->watches = g_list_prepend (area_src->watches, watch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_cast_area_stream_src_enable (MetaScreenCastStreamSrc *src)
|
||||
{
|
||||
MetaScreenCastAreaStreamSrc *area_src =
|
||||
META_SCREEN_CAST_AREA_STREAM_SRC (src);
|
||||
MetaBackend *backend = get_backend (area_src);
|
||||
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
|
||||
ClutterStage *stage;
|
||||
MetaScreenCastStream *stream;
|
||||
|
||||
stream = meta_screen_cast_stream_src_get_stream (src);
|
||||
stage = get_stage (area_src);
|
||||
|
||||
switch (meta_screen_cast_stream_get_cursor_mode (stream))
|
||||
{
|
||||
case META_SCREEN_CAST_CURSOR_MODE_METADATA:
|
||||
area_src->cursor_moved_handler_id =
|
||||
g_signal_connect_after (cursor_tracker, "cursor-moved",
|
||||
G_CALLBACK (cursor_moved),
|
||||
area_src);
|
||||
area_src->cursor_changed_handler_id =
|
||||
g_signal_connect_after (cursor_tracker, "cursor-changed",
|
||||
G_CALLBACK (cursor_changed),
|
||||
area_src);
|
||||
G_GNUC_FALLTHROUGH;
|
||||
case META_SCREEN_CAST_CURSOR_MODE_HIDDEN:
|
||||
add_view_painted_watches (area_src,
|
||||
META_STAGE_WATCH_AFTER_ACTOR_PAINT);
|
||||
break;
|
||||
case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED:
|
||||
inhibit_hw_cursor (area_src);
|
||||
add_view_painted_watches (area_src,
|
||||
META_STAGE_WATCH_AFTER_ACTOR_PAINT);
|
||||
break;
|
||||
}
|
||||
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_cast_area_stream_src_disable (MetaScreenCastStreamSrc *src)
|
||||
{
|
||||
MetaScreenCastAreaStreamSrc *area_src =
|
||||
META_SCREEN_CAST_AREA_STREAM_SRC (src);
|
||||
MetaBackend *backend = get_backend (area_src);
|
||||
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
|
||||
ClutterStage *stage;
|
||||
MetaStage *meta_stage;
|
||||
GList *l;
|
||||
|
||||
stage = get_stage (area_src);
|
||||
meta_stage = META_STAGE (stage);
|
||||
|
||||
for (l = area_src->watches; l; l = l->next)
|
||||
{
|
||||
MetaStageWatch *watch = l->data;
|
||||
|
||||
meta_stage_remove_watch (meta_stage, watch);
|
||||
}
|
||||
g_clear_pointer (&area_src->watches, g_list_free);
|
||||
|
||||
if (area_src->hw_cursor_inhibited)
|
||||
uninhibit_hw_cursor (area_src);
|
||||
|
||||
g_clear_signal_handler (&area_src->cursor_moved_handler_id,
|
||||
cursor_tracker);
|
||||
g_clear_signal_handler (&area_src->cursor_changed_handler_id,
|
||||
cursor_tracker);
|
||||
|
||||
g_clear_handle_id (&area_src->maybe_record_idle_id, g_source_remove);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_screen_cast_area_stream_src_record_frame (MetaScreenCastStreamSrc *src,
|
||||
uint8_t *data)
|
||||
{
|
||||
MetaScreenCastAreaStreamSrc *area_src =
|
||||
META_SCREEN_CAST_AREA_STREAM_SRC (src);
|
||||
MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
|
||||
MetaScreenCastAreaStream *area_stream = META_SCREEN_CAST_AREA_STREAM (stream);
|
||||
ClutterStage *stage;
|
||||
MetaRectangle *area;
|
||||
float scale;
|
||||
int stride;
|
||||
ClutterPaintFlag paint_flags = CLUTTER_PAINT_FLAG_NONE;
|
||||
g_autoptr (GError) error = NULL;
|
||||
|
||||
stage = get_stage (area_src);
|
||||
area = meta_screen_cast_area_stream_get_area (area_stream);
|
||||
scale = meta_screen_cast_area_stream_get_scale (area_stream);
|
||||
stride = meta_screen_cast_stream_src_get_stride (src);
|
||||
|
||||
switch (meta_screen_cast_stream_get_cursor_mode (stream))
|
||||
{
|
||||
case META_SCREEN_CAST_CURSOR_MODE_METADATA:
|
||||
case META_SCREEN_CAST_CURSOR_MODE_HIDDEN:
|
||||
paint_flags |= CLUTTER_PAINT_FLAG_NO_CURSORS;
|
||||
break;
|
||||
case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!clutter_stage_paint_to_buffer (stage, area, scale,
|
||||
data,
|
||||
stride,
|
||||
CLUTTER_CAIRO_FORMAT_ARGB32,
|
||||
paint_flags,
|
||||
&error))
|
||||
{
|
||||
g_warning ("Failed to record area: %s", error->message);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_screen_cast_area_stream_src_blit_to_framebuffer (MetaScreenCastStreamSrc *src,
|
||||
CoglFramebuffer *framebuffer)
|
||||
{
|
||||
MetaScreenCastAreaStreamSrc *area_src =
|
||||
META_SCREEN_CAST_AREA_STREAM_SRC (src);
|
||||
MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
|
||||
MetaScreenCastAreaStream *area_stream = META_SCREEN_CAST_AREA_STREAM (stream);
|
||||
MetaBackend *backend = get_backend (area_src);
|
||||
ClutterStage *stage;
|
||||
MetaRectangle *area;
|
||||
float scale;
|
||||
ClutterPaintFlag paint_flags = CLUTTER_PAINT_FLAG_NONE;
|
||||
|
||||
stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
|
||||
area = meta_screen_cast_area_stream_get_area (area_stream);
|
||||
scale = meta_screen_cast_area_stream_get_scale (area_stream);
|
||||
|
||||
switch (meta_screen_cast_stream_get_cursor_mode (stream))
|
||||
{
|
||||
case META_SCREEN_CAST_CURSOR_MODE_METADATA:
|
||||
case META_SCREEN_CAST_CURSOR_MODE_HIDDEN:
|
||||
paint_flags |= CLUTTER_PAINT_FLAG_NO_CURSORS;
|
||||
break;
|
||||
case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED:
|
||||
break;
|
||||
}
|
||||
clutter_stage_paint_to_framebuffer (stage, framebuffer,
|
||||
area, scale,
|
||||
paint_flags);
|
||||
|
||||
cogl_framebuffer_finish (framebuffer);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_cast_area_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc *src,
|
||||
struct spa_meta_cursor *spa_meta_cursor)
|
||||
{
|
||||
MetaScreenCastAreaStreamSrc *area_src =
|
||||
META_SCREEN_CAST_AREA_STREAM_SRC (src);
|
||||
MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
|
||||
MetaScreenCastAreaStream *area_stream = META_SCREEN_CAST_AREA_STREAM (stream);
|
||||
MetaBackend *backend = get_backend (area_src);
|
||||
MetaCursorRenderer *cursor_renderer =
|
||||
meta_backend_get_cursor_renderer (backend);
|
||||
MetaCursorSprite *cursor_sprite;
|
||||
MetaRectangle *area;
|
||||
float scale;
|
||||
graphene_point_t cursor_position;
|
||||
int x, y;
|
||||
|
||||
cursor_sprite = meta_cursor_renderer_get_cursor (cursor_renderer);
|
||||
|
||||
if (!is_cursor_in_stream (area_src))
|
||||
{
|
||||
meta_screen_cast_stream_src_unset_cursor_metadata (src,
|
||||
spa_meta_cursor);
|
||||
return;
|
||||
}
|
||||
|
||||
area = meta_screen_cast_area_stream_get_area (area_stream);
|
||||
scale = meta_screen_cast_area_stream_get_scale (area_stream);
|
||||
|
||||
cursor_position = meta_cursor_renderer_get_position (cursor_renderer);
|
||||
cursor_position.x -= area->x;
|
||||
cursor_position.y -= area->y;
|
||||
cursor_position.x *= scale;
|
||||
cursor_position.y *= scale;
|
||||
|
||||
x = (int) roundf (cursor_position.x);
|
||||
y = (int) roundf (cursor_position.y);
|
||||
|
||||
if (area_src->cursor_bitmap_invalid)
|
||||
{
|
||||
if (cursor_sprite)
|
||||
{
|
||||
float cursor_scale;
|
||||
float metadata_scale;
|
||||
|
||||
cursor_scale = meta_cursor_sprite_get_texture_scale (cursor_sprite);
|
||||
metadata_scale = scale * cursor_scale;
|
||||
meta_screen_cast_stream_src_set_cursor_sprite_metadata (src,
|
||||
spa_meta_cursor,
|
||||
cursor_sprite,
|
||||
x, y,
|
||||
metadata_scale);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_screen_cast_stream_src_set_empty_cursor_sprite_metadata (src,
|
||||
spa_meta_cursor,
|
||||
x, y);
|
||||
}
|
||||
|
||||
area_src->cursor_bitmap_invalid = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_screen_cast_stream_src_set_cursor_position_metadata (src,
|
||||
spa_meta_cursor,
|
||||
x, y);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_screen_cast_area_stream_src_is_cursor_sprite_inhibited (MetaHwCursorInhibitor *inhibitor,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaScreenCastAreaStreamSrc *area_src =
|
||||
META_SCREEN_CAST_AREA_STREAM_SRC (inhibitor);
|
||||
|
||||
return is_cursor_in_stream (area_src);
|
||||
}
|
||||
|
||||
static void
|
||||
hw_cursor_inhibitor_iface_init (MetaHwCursorInhibitorInterface *iface)
|
||||
{
|
||||
iface->is_cursor_sprite_inhibited =
|
||||
meta_screen_cast_area_stream_src_is_cursor_sprite_inhibited;
|
||||
}
|
||||
|
||||
MetaScreenCastAreaStreamSrc *
|
||||
meta_screen_cast_area_stream_src_new (MetaScreenCastAreaStream *area_stream,
|
||||
GError **error)
|
||||
{
|
||||
return g_initable_new (META_TYPE_SCREEN_CAST_AREA_STREAM_SRC, NULL, error,
|
||||
"stream", area_stream,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_cast_area_stream_src_init (MetaScreenCastAreaStreamSrc *area_src)
|
||||
{
|
||||
area_src->cursor_bitmap_invalid = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_cast_area_stream_src_class_init (MetaScreenCastAreaStreamSrcClass *klass)
|
||||
{
|
||||
MetaScreenCastStreamSrcClass *src_class =
|
||||
META_SCREEN_CAST_STREAM_SRC_CLASS (klass);
|
||||
|
||||
src_class->get_specs = meta_screen_cast_area_stream_src_get_specs;
|
||||
src_class->enable = meta_screen_cast_area_stream_src_enable;
|
||||
src_class->disable = meta_screen_cast_area_stream_src_disable;
|
||||
src_class->record_frame = meta_screen_cast_area_stream_src_record_frame;
|
||||
src_class->blit_to_framebuffer =
|
||||
meta_screen_cast_area_stream_src_blit_to_framebuffer;
|
||||
src_class->set_cursor_metadata =
|
||||
meta_screen_cast_area_stream_src_set_cursor_metadata;
|
||||
}
|
||||
37
src/backends/meta-screen-cast-area-stream-src.h
Normal file
37
src/backends/meta-screen-cast-area-stream-src.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Red Hat Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef META_SCREEN_CAST_AREA_STREAM_SRC_H
|
||||
#define META_SCREEN_CAST_AREA_STREAM_SRC_H
|
||||
|
||||
#include "backends/meta-screen-cast-stream-src.h"
|
||||
|
||||
typedef struct _MetaScreenCastAreaStream MetaScreenCastAreaStream;
|
||||
|
||||
#define META_TYPE_SCREEN_CAST_AREA_STREAM_SRC (meta_screen_cast_area_stream_src_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaScreenCastAreaStreamSrc,
|
||||
meta_screen_cast_area_stream_src,
|
||||
META, SCREEN_CAST_AREA_STREAM_SRC,
|
||||
MetaScreenCastStreamSrc)
|
||||
|
||||
MetaScreenCastAreaStreamSrc * meta_screen_cast_area_stream_src_new (MetaScreenCastAreaStream *area_stream,
|
||||
GError **error);
|
||||
|
||||
#endif /* META_SCREEN_CAST_AREA_STREAM_SRC_H */
|
||||
177
src/backends/meta-screen-cast-area-stream.c
Normal file
177
src/backends/meta-screen-cast-area-stream.c
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Red Hat Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "backends/meta-screen-cast-area-stream.h"
|
||||
|
||||
#include "backends/meta-screen-cast-area-stream-src.h"
|
||||
|
||||
struct _MetaScreenCastAreaStream
|
||||
{
|
||||
MetaScreenCastStream parent;
|
||||
|
||||
ClutterStage *stage;
|
||||
|
||||
MetaRectangle area;
|
||||
float scale;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaScreenCastAreaStream,
|
||||
meta_screen_cast_area_stream,
|
||||
META_TYPE_SCREEN_CAST_STREAM)
|
||||
|
||||
ClutterStage *
|
||||
meta_screen_cast_area_stream_get_stage (MetaScreenCastAreaStream *area_stream)
|
||||
{
|
||||
return area_stream->stage;
|
||||
}
|
||||
|
||||
MetaRectangle *
|
||||
meta_screen_cast_area_stream_get_area (MetaScreenCastAreaStream *area_stream)
|
||||
{
|
||||
return &area_stream->area;
|
||||
}
|
||||
|
||||
float
|
||||
meta_screen_cast_area_stream_get_scale (MetaScreenCastAreaStream *area_stream)
|
||||
{
|
||||
return area_stream->scale;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
calculate_scale (ClutterStage *stage,
|
||||
MetaRectangle *area,
|
||||
float *out_scale)
|
||||
{
|
||||
GList *l;
|
||||
float scale = 0.0;
|
||||
|
||||
for (l = clutter_stage_peek_stage_views (stage); l; l = l->next)
|
||||
{
|
||||
ClutterStageView *stage_view = l->data;
|
||||
MetaRectangle view_layout;
|
||||
|
||||
clutter_stage_view_get_layout (stage_view, &view_layout);
|
||||
if (meta_rectangle_overlap (area, &view_layout))
|
||||
scale = MAX (clutter_stage_view_get_scale (stage_view), scale);
|
||||
}
|
||||
|
||||
if (scale == 0.0)
|
||||
return FALSE;
|
||||
|
||||
*out_scale = scale;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
MetaScreenCastAreaStream *
|
||||
meta_screen_cast_area_stream_new (MetaScreenCastSession *session,
|
||||
GDBusConnection *connection,
|
||||
MetaRectangle *area,
|
||||
ClutterStage *stage,
|
||||
MetaScreenCastCursorMode cursor_mode,
|
||||
GError **error)
|
||||
{
|
||||
MetaScreenCastAreaStream *area_stream;
|
||||
float scale;
|
||||
|
||||
if (!calculate_scale (stage, area, &scale))
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Area is off-screen");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
area_stream = g_initable_new (META_TYPE_SCREEN_CAST_AREA_STREAM,
|
||||
NULL,
|
||||
error,
|
||||
"session", session,
|
||||
"connection", connection,
|
||||
"cursor-mode", cursor_mode,
|
||||
NULL);
|
||||
if (!area_stream)
|
||||
return NULL;
|
||||
|
||||
area_stream->area = *area;
|
||||
area_stream->scale = scale;
|
||||
area_stream->stage = stage;
|
||||
|
||||
return area_stream;
|
||||
}
|
||||
|
||||
static MetaScreenCastStreamSrc *
|
||||
meta_screen_cast_area_stream_create_src (MetaScreenCastStream *stream,
|
||||
GError **error)
|
||||
{
|
||||
MetaScreenCastAreaStream *area_stream =
|
||||
META_SCREEN_CAST_AREA_STREAM (stream);
|
||||
MetaScreenCastAreaStreamSrc *area_stream_src;
|
||||
|
||||
area_stream_src = meta_screen_cast_area_stream_src_new (area_stream,
|
||||
error);
|
||||
if (!area_stream_src)
|
||||
return NULL;
|
||||
|
||||
return META_SCREEN_CAST_STREAM_SRC (area_stream_src);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_cast_area_stream_set_parameters (MetaScreenCastStream *stream,
|
||||
GVariantBuilder *parameters_builder)
|
||||
{
|
||||
MetaScreenCastAreaStream *area_stream =
|
||||
META_SCREEN_CAST_AREA_STREAM (stream);
|
||||
|
||||
g_variant_builder_add (parameters_builder, "{sv}",
|
||||
"size",
|
||||
g_variant_new ("(ii)",
|
||||
area_stream->area.width,
|
||||
area_stream->area.height));
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_cast_area_stream_transform_position (MetaScreenCastStream *stream,
|
||||
double stream_x,
|
||||
double stream_y,
|
||||
double *x,
|
||||
double *y)
|
||||
{
|
||||
MetaScreenCastAreaStream *area_stream =
|
||||
META_SCREEN_CAST_AREA_STREAM (stream);
|
||||
|
||||
*x = area_stream->area.x + (int) roundf (stream_x / area_stream->scale);
|
||||
*y = area_stream->area.y + (int) roundf (stream_y / area_stream->scale);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_cast_area_stream_init (MetaScreenCastAreaStream *area_stream)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_cast_area_stream_class_init (MetaScreenCastAreaStreamClass *klass)
|
||||
{
|
||||
MetaScreenCastStreamClass *stream_class =
|
||||
META_SCREEN_CAST_STREAM_CLASS (klass);
|
||||
|
||||
stream_class->create_src = meta_screen_cast_area_stream_create_src;
|
||||
stream_class->set_parameters = meta_screen_cast_area_stream_set_parameters;
|
||||
stream_class->transform_position = meta_screen_cast_area_stream_transform_position;
|
||||
}
|
||||
48
src/backends/meta-screen-cast-area-stream.h
Normal file
48
src/backends/meta-screen-cast-area-stream.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Red Hat Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef META_SCREEN_CAST_AREA_STREAM_H
|
||||
#define META_SCREEN_CAST_AREA_STREAM_H
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "backends/meta-screen-cast-stream.h"
|
||||
#include "backends/meta-screen-cast.h"
|
||||
|
||||
#define META_TYPE_SCREEN_CAST_AREA_STREAM (meta_screen_cast_area_stream_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaScreenCastAreaStream,
|
||||
meta_screen_cast_area_stream,
|
||||
META, SCREEN_CAST_AREA_STREAM,
|
||||
MetaScreenCastStream)
|
||||
|
||||
MetaScreenCastAreaStream * meta_screen_cast_area_stream_new (MetaScreenCastSession *session,
|
||||
GDBusConnection *connection,
|
||||
MetaRectangle *area,
|
||||
ClutterStage *stage,
|
||||
MetaScreenCastCursorMode cursor_mode,
|
||||
GError **error);
|
||||
|
||||
ClutterStage * meta_screen_cast_area_stream_get_stage (MetaScreenCastAreaStream *area_stream);
|
||||
|
||||
MetaRectangle * meta_screen_cast_area_stream_get_area (MetaScreenCastAreaStream *area_stream);
|
||||
|
||||
float meta_screen_cast_area_stream_get_scale (MetaScreenCastAreaStream *area_stream);
|
||||
|
||||
#endif /* META_SCREEN_CAST_AREA_STREAM_H */
|
||||
@@ -115,9 +115,10 @@ meta_screen_cast_monitor_stream_src_get_specs (MetaScreenCastStreamSrc *src,
|
||||
}
|
||||
|
||||
static void
|
||||
stage_painted (MetaStage *stage,
|
||||
ClutterStageView *view,
|
||||
gpointer user_data)
|
||||
stage_painted (MetaStage *stage,
|
||||
ClutterStageView *view,
|
||||
ClutterPaintContext *paint_context,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (user_data);
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "backends/meta-backend-private.h"
|
||||
#include "backends/meta-dbus-session-watcher.h"
|
||||
#include "backends/meta-remote-access-controller-private.h"
|
||||
#include "backends/meta-screen-cast-area-stream.h"
|
||||
#include "backends/meta-screen-cast-monitor-stream.h"
|
||||
#include "backends/meta-screen-cast-stream.h"
|
||||
#include "backends/meta-screen-cast-window-stream.h"
|
||||
@@ -485,6 +486,90 @@ handle_record_window (MetaDBusScreenCastSession *skeleton,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_record_area (MetaDBusScreenCastSession *skeleton,
|
||||
GDBusMethodInvocation *invocation,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
GVariant *properties_variant)
|
||||
{
|
||||
MetaScreenCastSession *session = META_SCREEN_CAST_SESSION (skeleton);
|
||||
GDBusInterfaceSkeleton *interface_skeleton;
|
||||
GDBusConnection *connection;
|
||||
MetaBackend *backend;
|
||||
ClutterStage *stage;
|
||||
MetaScreenCastCursorMode cursor_mode;
|
||||
g_autoptr (GError) error = NULL;
|
||||
MetaRectangle rect;
|
||||
MetaScreenCastAreaStream *area_stream;
|
||||
MetaScreenCastStream *stream;
|
||||
char *stream_path;
|
||||
|
||||
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 (!g_variant_lookup (properties_variant, "cursor-mode", "u", &cursor_mode))
|
||||
{
|
||||
cursor_mode = META_SCREEN_CAST_CURSOR_MODE_HIDDEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!is_valid_cursor_mode (cursor_mode))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_FAILED,
|
||||
"Unknown cursor mode");
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
interface_skeleton = G_DBUS_INTERFACE_SKELETON (skeleton);
|
||||
connection = g_dbus_interface_skeleton_get_connection (interface_skeleton);
|
||||
backend = meta_screen_cast_get_backend (session->screen_cast);
|
||||
stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
|
||||
|
||||
rect = (MetaRectangle) {
|
||||
.x = x,
|
||||
.y = y,
|
||||
.width = width,
|
||||
.height = height
|
||||
};
|
||||
area_stream = meta_screen_cast_area_stream_new (session,
|
||||
connection,
|
||||
&rect,
|
||||
stage,
|
||||
cursor_mode,
|
||||
&error);
|
||||
if (!area_stream)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_FAILED,
|
||||
"Failed to record area: %s",
|
||||
error->message);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
stream = META_SCREEN_CAST_STREAM (area_stream);
|
||||
stream_path = meta_screen_cast_stream_get_object_path (stream);
|
||||
|
||||
session->streams = g_list_append (session->streams, stream);
|
||||
|
||||
g_signal_connect (stream, "closed", G_CALLBACK (on_stream_closed), session);
|
||||
|
||||
meta_dbus_screen_cast_session_complete_record_area (skeleton,
|
||||
invocation,
|
||||
stream_path);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_cast_session_init_iface (MetaDBusScreenCastSessionIface *iface)
|
||||
{
|
||||
@@ -492,6 +577,7 @@ meta_screen_cast_session_init_iface (MetaDBusScreenCastSessionIface *iface)
|
||||
iface->handle_stop = handle_stop;
|
||||
iface->handle_record_monitor = handle_record_monitor;
|
||||
iface->handle_record_window = handle_record_window;
|
||||
iface->handle_record_area = handle_record_area;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -956,6 +956,15 @@ meta_screen_cast_stream_src_init_initable_iface (GInitableIface *iface)
|
||||
iface->init = meta_screen_cast_stream_src_initable_init;
|
||||
}
|
||||
|
||||
int
|
||||
meta_screen_cast_stream_src_get_stride (MetaScreenCastStreamSrc *src)
|
||||
{
|
||||
MetaScreenCastStreamSrcPrivate *priv =
|
||||
meta_screen_cast_stream_src_get_instance_private (src);
|
||||
|
||||
return priv->video_stride;
|
||||
}
|
||||
|
||||
MetaScreenCastStream *
|
||||
meta_screen_cast_stream_src_get_stream (MetaScreenCastStreamSrc *src)
|
||||
{
|
||||
|
||||
@@ -65,6 +65,8 @@ struct _MetaScreenCastStreamSrcClass
|
||||
|
||||
void meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src);
|
||||
|
||||
int meta_screen_cast_stream_src_get_stride (MetaScreenCastStreamSrc *src);
|
||||
|
||||
MetaScreenCastStream * meta_screen_cast_stream_src_get_stream (MetaScreenCastStreamSrc *src);
|
||||
|
||||
gboolean meta_screen_cast_stream_src_draw_cursor_into (MetaScreenCastStreamSrc *src,
|
||||
|
||||
@@ -40,6 +40,8 @@ struct _MetaScreenCast
|
||||
|
||||
int dbus_name_id;
|
||||
|
||||
int inhibit_count;
|
||||
|
||||
GList *sessions;
|
||||
|
||||
MetaDbusSessionWatcher *session_watcher;
|
||||
@@ -54,6 +56,29 @@ G_DEFINE_TYPE_WITH_CODE (MetaScreenCast, meta_screen_cast,
|
||||
G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_SCREEN_CAST,
|
||||
meta_screen_cast_init_iface))
|
||||
|
||||
void
|
||||
meta_screen_cast_inhibit (MetaScreenCast *screen_cast)
|
||||
{
|
||||
screen_cast->inhibit_count++;
|
||||
if (screen_cast->inhibit_count == 1)
|
||||
{
|
||||
while (screen_cast->sessions)
|
||||
{
|
||||
MetaScreenCastSession *session = screen_cast->sessions->data;
|
||||
|
||||
meta_screen_cast_session_close (session);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_cast_uninhibit (MetaScreenCast *screen_cast)
|
||||
{
|
||||
g_return_if_fail (screen_cast->inhibit_count > 0);
|
||||
|
||||
screen_cast->inhibit_count--;
|
||||
}
|
||||
|
||||
GDBusConnection *
|
||||
meta_screen_cast_get_connection (MetaScreenCast *screen_cast)
|
||||
{
|
||||
@@ -119,6 +144,15 @@ handle_create_session (MetaDBusScreenCast *skeleton,
|
||||
gboolean disable_animations;
|
||||
MetaScreenCastSessionType session_type;
|
||||
|
||||
if (screen_cast->inhibit_count > 0)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Session creation inhibited");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
g_variant_lookup (properties, "remote-desktop-session-id", "s",
|
||||
&remote_desktop_session_id);
|
||||
|
||||
|
||||
@@ -42,6 +42,10 @@ G_DECLARE_FINAL_TYPE (MetaScreenCast, meta_screen_cast,
|
||||
META, SCREEN_CAST,
|
||||
MetaDBusScreenCastSkeleton)
|
||||
|
||||
void meta_screen_cast_inhibit (MetaScreenCast *screen_cast);
|
||||
|
||||
void meta_screen_cast_uninhibit (MetaScreenCast *screen_cast);
|
||||
|
||||
GDBusConnection * meta_screen_cast_get_connection (MetaScreenCast *screen_cast);
|
||||
|
||||
MetaBackend * meta_screen_cast_get_backend (MetaScreenCast *screen_cast);
|
||||
|
||||
@@ -38,9 +38,10 @@ typedef enum
|
||||
META_STAGE_WATCH_AFTER_PAINT,
|
||||
} MetaStageWatchPhase;
|
||||
|
||||
typedef void (* MetaStageWatchFunc) (MetaStage *stage,
|
||||
ClutterStageView *view,
|
||||
gpointer user_data);
|
||||
typedef void (* MetaStageWatchFunc) (MetaStage *stage,
|
||||
ClutterStageView *view,
|
||||
ClutterPaintContext *paint_context,
|
||||
gpointer user_data);
|
||||
|
||||
ClutterActor *meta_stage_new (MetaBackend *backend);
|
||||
|
||||
|
||||
@@ -65,7 +65,6 @@ struct _MetaStage
|
||||
ClutterStage parent;
|
||||
|
||||
GPtrArray *watchers[N_WATCH_MODES];
|
||||
ClutterStageView *current_view;
|
||||
|
||||
GList *overlays;
|
||||
gboolean is_active;
|
||||
@@ -169,6 +168,7 @@ meta_stage_finalize (GObject *object)
|
||||
static void
|
||||
notify_watchers_for_mode (MetaStage *stage,
|
||||
ClutterStageView *view,
|
||||
ClutterPaintContext *paint_context,
|
||||
MetaStageWatchPhase watch_phase)
|
||||
{
|
||||
GPtrArray *watchers;
|
||||
@@ -183,7 +183,7 @@ notify_watchers_for_mode (MetaStage *stage,
|
||||
if (watch->view && view != watch->view)
|
||||
continue;
|
||||
|
||||
watch->callback (stage, view, watch->user_data);
|
||||
watch->callback (stage, view, paint_context, watch->user_data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,20 +192,32 @@ meta_stage_paint (ClutterActor *actor,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
MetaStage *stage = META_STAGE (actor);
|
||||
ClutterStageView *view;
|
||||
GList *l;
|
||||
|
||||
CLUTTER_ACTOR_CLASS (meta_stage_parent_class)->paint (actor, paint_context);
|
||||
|
||||
notify_watchers_for_mode (stage, stage->current_view,
|
||||
META_STAGE_WATCH_AFTER_ACTOR_PAINT);
|
||||
view = clutter_paint_context_get_stage_view (paint_context);
|
||||
if (view)
|
||||
{
|
||||
notify_watchers_for_mode (stage, view, paint_context,
|
||||
META_STAGE_WATCH_AFTER_ACTOR_PAINT);
|
||||
}
|
||||
|
||||
g_signal_emit (stage, signals[ACTORS_PAINTED], 0);
|
||||
|
||||
for (l = stage->overlays; l; l = l->next)
|
||||
meta_overlay_paint (l->data, paint_context);
|
||||
if (!(clutter_paint_context_get_paint_flags (paint_context) &
|
||||
CLUTTER_PAINT_FLAG_NO_CURSORS))
|
||||
{
|
||||
for (l = stage->overlays; l; l = l->next)
|
||||
meta_overlay_paint (l->data, paint_context);
|
||||
}
|
||||
|
||||
notify_watchers_for_mode (stage, stage->current_view,
|
||||
META_STAGE_WATCH_AFTER_OVERLAY_PAINT);
|
||||
if (view)
|
||||
{
|
||||
notify_watchers_for_mode (stage, view, paint_context,
|
||||
META_STAGE_WATCH_AFTER_OVERLAY_PAINT);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -215,13 +227,14 @@ meta_stage_paint_view (ClutterStage *stage,
|
||||
{
|
||||
MetaStage *meta_stage = META_STAGE (stage);
|
||||
|
||||
notify_watchers_for_mode (meta_stage, view, META_STAGE_WATCH_BEFORE_PAINT);
|
||||
notify_watchers_for_mode (meta_stage, view, NULL,
|
||||
META_STAGE_WATCH_BEFORE_PAINT);
|
||||
|
||||
meta_stage->current_view = view;
|
||||
CLUTTER_STAGE_CLASS (meta_stage_parent_class)->paint_view (stage, view,
|
||||
redraw_clip);
|
||||
|
||||
notify_watchers_for_mode (meta_stage, view, META_STAGE_WATCH_AFTER_PAINT);
|
||||
notify_watchers_for_mode (meta_stage, view, NULL,
|
||||
META_STAGE_WATCH_AFTER_PAINT);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2019 Red Hat
|
||||
* Copyright (C) 2019 DisplayLink (UK) Ltd.
|
||||
* Copyright (C) 2019-2020 DisplayLink (UK) Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
@@ -660,6 +660,9 @@ process_page_flip (MetaKmsImpl *impl,
|
||||
meta_kms_page_flip_data_ref (page_flip_data));
|
||||
}
|
||||
|
||||
if (ret != 0)
|
||||
meta_kms_page_flip_data_unref (page_flip_data);
|
||||
|
||||
if (ret == -EBUSY)
|
||||
{
|
||||
CachedModeSet *cached_mode_set;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Red Hat
|
||||
* Copyright 2020 DisplayLink (UK) Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
@@ -383,6 +384,7 @@ meta_kms_add_source_in_impl (MetaKms *kms,
|
||||
simple_impl_source->kms = kms;
|
||||
|
||||
g_source_set_callback (source, func, user_data, user_data_destroy);
|
||||
g_source_set_ready_time (source, 0);
|
||||
g_source_attach (source, g_main_context_get_thread_default ());
|
||||
|
||||
return source;
|
||||
|
||||
@@ -129,20 +129,25 @@ release_pressed_buttons (ClutterVirtualInputDevice *virtual_device)
|
||||
switch (get_button_type (code))
|
||||
{
|
||||
case EVDEV_BUTTON_TYPE_KEY:
|
||||
clutter_virtual_input_device_notify_key (virtual_device,
|
||||
time_us,
|
||||
code,
|
||||
CLUTTER_KEY_STATE_RELEASED);
|
||||
meta_seat_native_notify_key (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
code,
|
||||
CLUTTER_KEY_STATE_RELEASED,
|
||||
TRUE);
|
||||
break;
|
||||
case EVDEV_BUTTON_TYPE_BUTTON:
|
||||
clutter_virtual_input_device_notify_button (virtual_device,
|
||||
time_us,
|
||||
code,
|
||||
CLUTTER_BUTTON_STATE_RELEASED);
|
||||
meta_seat_native_notify_button (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
code,
|
||||
CLUTTER_BUTTON_STATE_RELEASED);
|
||||
break;
|
||||
case EVDEV_BUTTON_TYPE_NONE:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
update_button_count (virtual_evdev, code, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,6 @@
|
||||
#include "cogl/cogl.h"
|
||||
#include "compositor/meta-later-private.h"
|
||||
#include "compositor/meta-window-actor-x11.h"
|
||||
#include "compositor/meta-window-actor-wayland.h"
|
||||
#include "compositor/meta-window-actor-private.h"
|
||||
#include "compositor/meta-window-group-private.h"
|
||||
#include "core/display-private.h"
|
||||
@@ -83,6 +82,7 @@
|
||||
#include "x11/meta-x11-display-private.h"
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include "compositor/meta-window-actor-wayland.h"
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1270,7 +1270,9 @@ get_image_via_offscreen (MetaShapedTexture *stex,
|
||||
root_node = clutter_root_node_new (fb, &clear_color, COGL_BUFFER_BIT_COLOR);
|
||||
clutter_paint_node_set_static_name (root_node, "MetaShapedTexture.offscreen");
|
||||
|
||||
paint_context = clutter_paint_context_new_for_framebuffer (fb);
|
||||
paint_context =
|
||||
clutter_paint_context_new_for_framebuffer (fb, NULL,
|
||||
CLUTTER_PAINT_FLAG_NONE);
|
||||
|
||||
do_paint_content (stex, root_node, paint_context,
|
||||
stex->texture,
|
||||
|
||||
@@ -86,6 +86,8 @@ struct _MetaWindowActorX11
|
||||
cairo_region_t *shape_region;
|
||||
/* The region we should clip to when painting the shadow */
|
||||
cairo_region_t *shadow_clip;
|
||||
/* The frame region */
|
||||
cairo_region_t *frame_bounds;
|
||||
|
||||
/* Extracted size-invariant shape used for shadows */
|
||||
MetaWindowShape *shadow_shape;
|
||||
@@ -709,11 +711,8 @@ set_clip_region_beneath (MetaWindowActorX11 *actor_x11,
|
||||
|
||||
if (clip_shadow_under_window (actor_x11))
|
||||
{
|
||||
cairo_region_t *frame_bounds;
|
||||
|
||||
frame_bounds = meta_window_get_frame_bounds (window);
|
||||
if (frame_bounds)
|
||||
cairo_region_subtract (actor_x11->shadow_clip, frame_bounds);
|
||||
if (actor_x11->frame_bounds)
|
||||
cairo_region_subtract (actor_x11->shadow_clip, actor_x11->frame_bounds);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1133,6 +1132,17 @@ update_opaque_region (MetaWindowActorX11 *actor_x11)
|
||||
cairo_region_destroy (opaque_region);
|
||||
}
|
||||
|
||||
static void
|
||||
update_frame_bounds (MetaWindowActorX11 *actor_x11)
|
||||
{
|
||||
MetaWindow *window =
|
||||
meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
|
||||
|
||||
g_clear_pointer (&actor_x11->frame_bounds, cairo_region_destroy);
|
||||
actor_x11->frame_bounds =
|
||||
cairo_region_copy (meta_window_get_frame_bounds (window));
|
||||
}
|
||||
|
||||
static void
|
||||
update_regions (MetaWindowActorX11 *actor_x11)
|
||||
{
|
||||
@@ -1204,6 +1214,7 @@ handle_updates (MetaWindowActorX11 *actor_x11)
|
||||
if (!meta_surface_actor_is_visible (surface))
|
||||
return;
|
||||
|
||||
update_frame_bounds (actor_x11);
|
||||
check_needs_reshape (actor_x11);
|
||||
check_needs_shadow (actor_x11);
|
||||
}
|
||||
@@ -1257,15 +1268,13 @@ meta_window_actor_x11_paint (ClutterActor *actor,
|
||||
*/
|
||||
if (!clip && clip_shadow_under_window (actor_x11))
|
||||
{
|
||||
cairo_region_t *frame_bounds;
|
||||
cairo_rectangle_int_t bounds;
|
||||
|
||||
get_shadow_bounds (actor_x11, appears_focused, &bounds);
|
||||
clip = cairo_region_create_rectangle (&bounds);
|
||||
|
||||
frame_bounds = meta_window_get_frame_bounds (window);
|
||||
if (frame_bounds)
|
||||
cairo_region_subtract (clip, frame_bounds);
|
||||
if (actor_x11->frame_bounds)
|
||||
cairo_region_subtract (clip, actor_x11->frame_bounds);
|
||||
}
|
||||
|
||||
framebuffer = clutter_paint_context_get_framebuffer (paint_context);
|
||||
@@ -1552,6 +1561,7 @@ meta_window_actor_x11_dispose (GObject *object)
|
||||
|
||||
g_clear_pointer (&actor_x11->shape_region, cairo_region_destroy);
|
||||
g_clear_pointer (&actor_x11->shadow_clip, cairo_region_destroy);
|
||||
g_clear_pointer (&actor_x11->frame_bounds, cairo_region_destroy);
|
||||
|
||||
g_clear_pointer (&actor_x11->shadow_class, g_free);
|
||||
g_clear_pointer (&actor_x11->focused_shadow, meta_shadow_unref);
|
||||
|
||||
@@ -1321,7 +1321,9 @@ meta_window_actor_blit_to_framebuffer (MetaScreenCastWindow *screen_cast_window,
|
||||
cogl_framebuffer_scale (framebuffer, resource_scale, resource_scale, 1);
|
||||
cogl_framebuffer_translate (framebuffer, -x, -y, 0);
|
||||
|
||||
paint_context = clutter_paint_context_new_for_framebuffer (framebuffer);
|
||||
paint_context =
|
||||
clutter_paint_context_new_for_framebuffer (framebuffer, NULL,
|
||||
CLUTTER_PAINT_FLAG_NONE);
|
||||
clutter_actor_paint (actor, paint_context);
|
||||
clutter_paint_context_destroy (paint_context);
|
||||
|
||||
@@ -1479,7 +1481,9 @@ meta_window_actor_get_image (MetaWindowActor *self,
|
||||
cogl_framebuffer_scale (framebuffer, resource_scale, resource_scale, 1);
|
||||
cogl_framebuffer_translate (framebuffer, -x, -y, 0);
|
||||
|
||||
paint_context = clutter_paint_context_new_for_framebuffer (framebuffer);
|
||||
paint_context =
|
||||
clutter_paint_context_new_for_framebuffer (framebuffer, NULL,
|
||||
CLUTTER_PAINT_FLAG_NONE);
|
||||
clutter_actor_paint (actor, paint_context);
|
||||
clutter_paint_context_destroy (paint_context);
|
||||
|
||||
|
||||
@@ -2129,7 +2129,7 @@ process_special_modifier_key (MetaDisplay *display,
|
||||
return TRUE;
|
||||
}
|
||||
else if (event->type == CLUTTER_KEY_PRESS &&
|
||||
(event->modifier_state & ~(IGNORED_MODIFIERS)) == 0 &&
|
||||
((event->modifier_state & ~(IGNORED_MODIFIERS)) & CLUTTER_MODIFIER_MASK) == 0 &&
|
||||
resolved_key_combo_has_keycode (resolved_key_combo,
|
||||
event->hardware_keycode))
|
||||
{
|
||||
@@ -3112,7 +3112,7 @@ handle_move_to_center (MetaDisplay *display,
|
||||
MetaRectangle work_area;
|
||||
MetaRectangle frame_rect;
|
||||
|
||||
meta_window_get_work_area_all_monitors (window, &work_area);
|
||||
meta_window_get_work_area_current_monitor (window, &work_area);
|
||||
meta_window_get_frame_rect (window, &frame_rect);
|
||||
|
||||
meta_window_move_frame (window,
|
||||
@@ -3302,15 +3302,7 @@ handle_toggle_tiled (MetaDisplay *display,
|
||||
if ((META_WINDOW_TILED_LEFT (window) && mode == META_TILE_LEFT) ||
|
||||
(META_WINDOW_TILED_RIGHT (window) && mode == META_TILE_RIGHT))
|
||||
{
|
||||
window->tile_monitor_number = window->saved_maximize ? window->monitor->number
|
||||
: -1;
|
||||
window->tile_mode = window->saved_maximize ? META_TILE_MAXIMIZED
|
||||
: META_TILE_NONE;
|
||||
|
||||
if (window->saved_maximize)
|
||||
meta_window_maximize (window, META_MAXIMIZE_BOTH);
|
||||
else
|
||||
meta_window_unmaximize (window, META_MAXIMIZE_BOTH);
|
||||
meta_window_untile (window);
|
||||
}
|
||||
else if (meta_window_can_tile_side_by_side (window))
|
||||
{
|
||||
|
||||
368
src/core/meta-anonymous-file.c
Normal file
368
src/core/meta-anonymous-file.c
Normal file
@@ -0,0 +1,368 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Sebastian Wick
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Author: Sebastian Wick <sebastian@sebastianwick.net>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "core/meta-anonymous-file.h"
|
||||
|
||||
struct _MetaAnonymousFile
|
||||
{
|
||||
int fd;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
#define READONLY_SEALS (F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE)
|
||||
|
||||
static int
|
||||
create_tmpfile_cloexec (char *tmpname)
|
||||
{
|
||||
int fd;
|
||||
|
||||
#if defined(HAVE_MKOSTEMP)
|
||||
fd = mkostemp (tmpname, O_CLOEXEC);
|
||||
if (fd >= 0)
|
||||
unlink (tmpname);
|
||||
#else
|
||||
fd = mkstemp (tmpname);
|
||||
if (fd >= 0)
|
||||
{
|
||||
long flags;
|
||||
|
||||
unlink (tmpname);
|
||||
|
||||
flags = fcntl (fd, F_GETFD);
|
||||
if (flags == -1 ||
|
||||
fcntl (fd, F_SETFD, flags | FD_CLOEXEC) == -1)
|
||||
{
|
||||
close (fd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a new, unique, anonymous file of the given size, and
|
||||
* return the file descriptor for it. The file descriptor is set
|
||||
* CLOEXEC. The file is immediately suitable for mmap()'ing
|
||||
* the given size at offset zero.
|
||||
*
|
||||
* The file should not have a permanent backing store like a disk,
|
||||
* but may have if XDG_RUNTIME_DIR is not properly implemented in OS.
|
||||
*
|
||||
* The file name is deleted from the file system.
|
||||
*
|
||||
* The file is suitable for buffer sharing between processes by
|
||||
* transmitting the file descriptor over Unix sockets using the
|
||||
* SCM_RIGHTS methods.
|
||||
*
|
||||
* If the C library implements posix_fallocate(), it is used to
|
||||
* guarantee that disk space is available for the file at the
|
||||
* given size. If disk space is insufficient, errno is set to ENOSPC.
|
||||
* If posix_fallocate() is not supported, program may receive
|
||||
* SIGBUS on accessing mmap()'ed file contents instead.
|
||||
*
|
||||
* If the C library implements memfd_create(), it is used to create the
|
||||
* file purely in memory, without any backing file name on the file
|
||||
* system, and then sealing off the possibility of shrinking it. This
|
||||
* can then be checked before accessing mmap()'ed file contents, to make
|
||||
* sure SIGBUS can't happen. It also avoids requiring XDG_RUNTIME_DIR.
|
||||
*/
|
||||
static int
|
||||
create_anonymous_file (off_t size)
|
||||
{
|
||||
int fd, ret;
|
||||
|
||||
#if defined(HAVE_MEMFD_CREATE)
|
||||
fd = memfd_create ("mutter-shared", MFD_CLOEXEC | MFD_ALLOW_SEALING);
|
||||
if (fd >= 0)
|
||||
{
|
||||
/* We can add this seal before calling posix_fallocate(), as
|
||||
* the file is currently zero-sized anyway.
|
||||
*
|
||||
* There is also no need to check for the return value, we
|
||||
* couldn't do anything with it anyway.
|
||||
*/
|
||||
fcntl (fd, F_ADD_SEALS, F_SEAL_SHRINK);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
static const char template[] = "/mutter-shared-XXXXXX";
|
||||
const char *path;
|
||||
char *name;
|
||||
|
||||
path = getenv ("XDG_RUNTIME_DIR");
|
||||
if (!path)
|
||||
{
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
name = g_malloc (strlen (path) + sizeof (template));
|
||||
if (!name)
|
||||
return -1;
|
||||
|
||||
strcpy (name, path);
|
||||
strcat (name, template);
|
||||
|
||||
fd = create_tmpfile_cloexec (name);
|
||||
|
||||
g_free (name);
|
||||
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined(HAVE_POSIX_FALLOCATE)
|
||||
do
|
||||
{
|
||||
ret = posix_fallocate (fd, 0, size);
|
||||
}
|
||||
while (ret == EINTR);
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
close (fd);
|
||||
errno = ret;
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
do
|
||||
{
|
||||
ret = ftruncate (fd, size);
|
||||
}
|
||||
while (ret < 0 && errno == EINTR);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
close (fd);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_anonymous_file_new: (skip)
|
||||
* @size: The size of @data
|
||||
* @data: The data of the file with the size @size
|
||||
*
|
||||
* Create a new anonymous read-only file of the given size and the given data
|
||||
* The intended use-case is for sending mid-sized data from the compositor
|
||||
* to clients.
|
||||
*
|
||||
* When done, free the data using meta_anonymous_file_free().
|
||||
*
|
||||
* If this function fails errno is set.
|
||||
*
|
||||
* Returns: The newly created #MetaAnonymousFile, or NULL on failure. Use
|
||||
* meta_anonymous_file_free() to free the resources when done.
|
||||
*/
|
||||
MetaAnonymousFile *
|
||||
meta_anonymous_file_new (size_t size,
|
||||
const uint8_t *data)
|
||||
{
|
||||
MetaAnonymousFile *file;
|
||||
void *map;
|
||||
|
||||
file = g_malloc0 (sizeof *file);
|
||||
if (!file)
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
file->size = size;
|
||||
file->fd = create_anonymous_file (size);
|
||||
if (file->fd == -1)
|
||||
goto err_free;
|
||||
|
||||
map = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, file->fd, 0);
|
||||
if (map == MAP_FAILED)
|
||||
goto err_close;
|
||||
|
||||
memcpy (map, data, size);
|
||||
|
||||
munmap (map, size);
|
||||
|
||||
#if defined(HAVE_MEMFD_CREATE)
|
||||
/* try to put seals on the file to make it read-only so that we can
|
||||
* return the fd later directly when MAPMODE_SHARED is not set.
|
||||
* meta_anonymous_file_open_fd can handle the fd even if it is not
|
||||
* sealed read-only and will instead create a new anonymous file on
|
||||
* each invocation.
|
||||
*/
|
||||
fcntl (file->fd, F_ADD_SEALS, READONLY_SEALS);
|
||||
#endif
|
||||
|
||||
return file;
|
||||
|
||||
err_close:
|
||||
close (file->fd);
|
||||
err_free:
|
||||
g_free (file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* meta_anonymous_file_free: (skip)
|
||||
* @file: the #MetaAnonymousFile
|
||||
*
|
||||
* Free the resources used by an anonymous read-only file.
|
||||
*/
|
||||
void
|
||||
meta_anonymous_file_free (MetaAnonymousFile *file)
|
||||
{
|
||||
close (file->fd);
|
||||
g_free (file);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_anonymous_file_size: (skip)
|
||||
* @file: the #MetaAnonymousFile
|
||||
*
|
||||
* Get the size of an anonymous read-only file.
|
||||
*
|
||||
* Returns: The size of the anonymous read-only file.
|
||||
*/
|
||||
size_t
|
||||
meta_anonymous_file_size (MetaAnonymousFile *file)
|
||||
{
|
||||
return file->size;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_anonymous_file_open_fd: (skip)
|
||||
* @file: the #MetaAnonymousFile to get a file descriptor for
|
||||
* @mapmode: describes the ways in which the returned file descriptor can
|
||||
* be used with mmap
|
||||
*
|
||||
* Returns a file descriptor for the given file, ready to be sent to a client.
|
||||
* The returned file descriptor must not be shared between multiple clients.
|
||||
* If @mapmode is %META_ANONYMOUS_FILE_MAPMODE_PRIVATE the file descriptor is
|
||||
* only guaranteed to be mmapable with MAP_PRIVATE. If @mapmode is
|
||||
* %META_ANONYMOUS_FILE_MAPMODE_SHARED the file descriptor can be mmaped with
|
||||
* either MAP_PRIVATE or MAP_SHARED.
|
||||
*
|
||||
* In case %META_ANONYMOUS_FILE_MAPMODE_PRIVATE is used, it is important to
|
||||
* only read the returned fd using mmap() since using read() will move the
|
||||
* read cursor of the fd and thus may cause read() calls on other returned
|
||||
* fds to fail.
|
||||
*
|
||||
* When done using the fd, it is required to call meta_anonymous_file_close_fd()
|
||||
* instead of close().
|
||||
*
|
||||
* If this function fails errno is set.
|
||||
*
|
||||
* Returns: A file descriptor for the given file that can be sent to a client
|
||||
* or -1 on failure. Use meta_anonymous_file_close_fd() to release the fd
|
||||
* when done.
|
||||
*/
|
||||
int
|
||||
meta_anonymous_file_open_fd (MetaAnonymousFile *file,
|
||||
MetaAnonymousFileMapmode mapmode)
|
||||
{
|
||||
void *src, *dst;
|
||||
int fd;
|
||||
|
||||
#if defined(HAVE_MEMFD_CREATE)
|
||||
int seals;
|
||||
|
||||
seals = fcntl (file->fd, F_GET_SEALS);
|
||||
|
||||
/* file was sealed for read-only and we don't have to support MAP_SHARED
|
||||
* so we can simply pass the memfd fd
|
||||
*/
|
||||
if (seals != -1 && mapmode == META_ANONYMOUS_FILE_MAPMODE_PRIVATE &&
|
||||
(seals & READONLY_SEALS) == READONLY_SEALS)
|
||||
return file->fd;
|
||||
#endif
|
||||
|
||||
/* for all other cases we create a new anonymous file that can be mapped
|
||||
* with MAP_SHARED and copy the contents to it and return that instead
|
||||
*/
|
||||
fd = create_anonymous_file (file->size);
|
||||
if (fd == -1)
|
||||
return fd;
|
||||
|
||||
src = mmap (NULL, file->size, PROT_READ, MAP_PRIVATE, file->fd, 0);
|
||||
if (src == MAP_FAILED)
|
||||
{
|
||||
close (fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dst = mmap (NULL, file->size, PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
if (dst == MAP_FAILED)
|
||||
{
|
||||
close (fd);
|
||||
munmap (src, file->size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy (dst, src, file->size);
|
||||
munmap (src, file->size);
|
||||
munmap (dst, file->size);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_anonymous_file_close_fd: (skip)
|
||||
* @fd: A file descriptor obtained using meta_anonymous_file_open_fd()
|
||||
*
|
||||
* Release a file descriptor returned by meta_anonymous_file_open_fd().
|
||||
* This function must be called for every file descriptor created with
|
||||
* meta_anonymous_file_open_fd() to not leak any resources.
|
||||
*
|
||||
* If this function fails errno is set.
|
||||
*/
|
||||
void
|
||||
meta_anonymous_file_close_fd (int fd)
|
||||
{
|
||||
#if defined(HAVE_MEMFD_CREATE)
|
||||
int seals;
|
||||
|
||||
seals = fcntl (fd, F_GET_SEALS);
|
||||
if (seals == -1 && errno != EINVAL)
|
||||
{
|
||||
g_warning ("Reading seals of anonymous file %d failed", fd);
|
||||
return;
|
||||
}
|
||||
|
||||
/* The only case in which we do NOT have to close the file is when the file
|
||||
* was sealed for read-only
|
||||
*/
|
||||
if (seals != -1 && (seals & READONLY_SEALS) == READONLY_SEALS)
|
||||
return;
|
||||
#endif
|
||||
|
||||
close (fd);
|
||||
}
|
||||
53
src/core/meta-anonymous-file.h
Normal file
53
src/core/meta-anonymous-file.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Sebastian Wick
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Author: Sebastian Wick <sebastian@sebastianwick.net>
|
||||
*/
|
||||
|
||||
#ifndef META_ANONYMOUS_FILE_H
|
||||
#define META_ANONYMOUS_FILE_H
|
||||
|
||||
#include "meta/common.h"
|
||||
#include "core/util-private.h"
|
||||
|
||||
typedef struct _MetaAnonymousFile MetaAnonymousFile;
|
||||
|
||||
typedef enum _MetaAnonymousFileMapmode
|
||||
{
|
||||
META_ANONYMOUS_FILE_MAPMODE_PRIVATE,
|
||||
META_ANONYMOUS_FILE_MAPMODE_SHARED,
|
||||
} MetaAnonymousFileMapmode;
|
||||
|
||||
META_EXPORT_TEST
|
||||
MetaAnonymousFile * meta_anonymous_file_new (size_t size,
|
||||
const uint8_t *data);
|
||||
|
||||
META_EXPORT_TEST
|
||||
void meta_anonymous_file_free (MetaAnonymousFile *file);
|
||||
|
||||
META_EXPORT_TEST
|
||||
size_t meta_anonymous_file_size (MetaAnonymousFile *file);
|
||||
|
||||
META_EXPORT_TEST
|
||||
int meta_anonymous_file_open_fd (MetaAnonymousFile *file,
|
||||
MetaAnonymousFileMapmode mapmode);
|
||||
|
||||
META_EXPORT_TEST
|
||||
void meta_anonymous_file_close_fd (int fd);
|
||||
|
||||
#endif /* META_ANONYMOUS_FILE_H */
|
||||
@@ -646,6 +646,9 @@ void meta_window_unmanage (MetaWindow *window,
|
||||
void meta_window_unmanage_on_idle (MetaWindow *window);
|
||||
void meta_window_queue (MetaWindow *window,
|
||||
guint queuebits);
|
||||
META_EXPORT_TEST
|
||||
void meta_window_untile (MetaWindow *window);
|
||||
|
||||
META_EXPORT_TEST
|
||||
void meta_window_tile (MetaWindow *window,
|
||||
MetaTileMode mode);
|
||||
@@ -830,6 +833,7 @@ void meta_window_activate_full (MetaWindow *window,
|
||||
MetaClientType source_indication,
|
||||
MetaWorkspace *workspace);
|
||||
|
||||
META_EXPORT_TEST
|
||||
MetaLogicalMonitor * meta_window_calculate_main_logical_monitor (MetaWindow *window);
|
||||
|
||||
MetaLogicalMonitor * meta_window_get_main_logical_monitor (MetaWindow *window);
|
||||
|
||||
@@ -3124,6 +3124,22 @@ update_edge_constraints (MetaWindow *window)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_untile (MetaWindow *window)
|
||||
{
|
||||
window->tile_monitor_number =
|
||||
window->saved_maximize ? window->monitor->number
|
||||
: -1;
|
||||
window->tile_mode =
|
||||
window->saved_maximize ? META_TILE_MAXIMIZED
|
||||
: META_TILE_NONE;
|
||||
|
||||
if (window->saved_maximize)
|
||||
meta_window_maximize (window, META_MAXIMIZE_BOTH);
|
||||
else
|
||||
meta_window_unmaximize (window, META_MAXIMIZE_BOTH);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_tile (MetaWindow *window,
|
||||
MetaTileMode tile_mode)
|
||||
@@ -3140,6 +3156,10 @@ meta_window_tile (MetaWindow *window,
|
||||
window->tile_monitor_number = -1;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
window->tile_monitor_number = window->monitor->number;
|
||||
}
|
||||
|
||||
if (window->tile_mode == META_TILE_MAXIMIZED)
|
||||
directions = META_MAXIMIZE_BOTH;
|
||||
|
||||
@@ -349,6 +349,8 @@ mutter_sources = [
|
||||
'core/main-private.h',
|
||||
'core/meta-accel-parse.c',
|
||||
'core/meta-accel-parse.h',
|
||||
'core/meta-anonymous-file.c',
|
||||
'core/meta-anonymous-file.h',
|
||||
'core/meta-border.c',
|
||||
'core/meta-border.h',
|
||||
'core/meta-clipboard-manager.c',
|
||||
@@ -456,6 +458,10 @@ if have_remote_desktop
|
||||
'backends/meta-remote-desktop-session.h',
|
||||
'backends/meta-screen-cast.c',
|
||||
'backends/meta-screen-cast.h',
|
||||
'backends/meta-screen-cast-area-stream.c',
|
||||
'backends/meta-screen-cast-area-stream.h',
|
||||
'backends/meta-screen-cast-area-stream-src.c',
|
||||
'backends/meta-screen-cast-area-stream-src.h',
|
||||
'backends/meta-screen-cast-monitor-stream.c',
|
||||
'backends/meta-screen-cast-monitor-stream.h',
|
||||
'backends/meta-screen-cast-monitor-stream-src.c',
|
||||
|
||||
@@ -54,4 +54,10 @@ G_DECLARE_FINAL_TYPE (MetaRemoteAccessController,
|
||||
META, REMOTE_ACCESS_CONTROLLER,
|
||||
GObject)
|
||||
|
||||
META_EXPORT
|
||||
void meta_remote_access_controller_inhibit_remote_access (MetaRemoteAccessController *controller);
|
||||
|
||||
META_EXPORT
|
||||
void meta_remote_access_controller_uninhibit_remote_access (MetaRemoteAccessController *controller);
|
||||
|
||||
#endif /* META_REMOTE_ACCESS_CONTROLLER_H */
|
||||
|
||||
@@ -375,8 +375,6 @@
|
||||
|
||||
Possible @properties are:
|
||||
|
||||
* "supports-mirroring" (b): FALSE if mirroring not supported; TRUE or not
|
||||
present if mirroring is supported.
|
||||
* "layout-mode" (u): Represents in what way logical monitors are laid
|
||||
out on the screen. The layout mode can be either
|
||||
of the ones listed below. Absence of this property
|
||||
|
||||
@@ -111,6 +111,39 @@
|
||||
<arg name="properties" type="a{sv}" direction="in" />
|
||||
<arg name="stream_path" type="o" direction="out" />
|
||||
</method>
|
||||
|
||||
<!--
|
||||
RecordArea:
|
||||
@x: X position of the recorded area
|
||||
@y: Y position of the recorded area
|
||||
@width: width of the recorded area
|
||||
@height: height of the recorded area
|
||||
@properties: Properties
|
||||
@stream_path: Path to the new stream object
|
||||
|
||||
Record an area of the stage. The coordinates are in stage coordinates.
|
||||
The size of the stream does not necessarily match the size of the
|
||||
recorded area, and will depend on DPI scale of the affected monitors.
|
||||
|
||||
Available @properties include:
|
||||
|
||||
* "cursor-mode" (u): Cursor mode. Default: 'hidden' (see below)
|
||||
Available since API version 2.
|
||||
|
||||
Available cursor mode values:
|
||||
|
||||
0: hidden - cursor is not included in the stream
|
||||
1: embedded - cursor is included in the framebuffer
|
||||
2: metadata - cursor is included as metadata in the PipeWire stream
|
||||
-->
|
||||
<method name="RecordArea">
|
||||
<arg name="x" type="i" direction="in" />
|
||||
<arg name="y" type="i" direction="in" />
|
||||
<arg name="width" type="i" direction="in" />
|
||||
<arg name="height" type="i" direction="in" />
|
||||
<arg name="properties" type="a{sv}" direction="in" />
|
||||
<arg name="stream_path" type="o" direction="out" />
|
||||
</method>
|
||||
</interface>
|
||||
|
||||
<!--
|
||||
|
||||
@@ -251,28 +251,6 @@ script_named_object (void)
|
||||
g_free (test_file);
|
||||
}
|
||||
|
||||
static void
|
||||
script_animation (void)
|
||||
{
|
||||
ClutterScript *script = clutter_script_new ();
|
||||
GObject *animation = NULL;
|
||||
GError *error = NULL;
|
||||
gchar *test_file;
|
||||
|
||||
test_file = g_test_build_filename (G_TEST_DIST, "scripts", "test-script-animation.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);
|
||||
|
||||
animation = clutter_script_get_object (script, "test");
|
||||
g_assert (CLUTTER_IS_ANIMATION (animation));
|
||||
|
||||
g_object_unref (script);
|
||||
g_free (test_file);
|
||||
}
|
||||
|
||||
static void
|
||||
script_layout_property (void)
|
||||
{
|
||||
@@ -383,7 +361,6 @@ CLUTTER_TEST_SUITE (
|
||||
CLUTTER_TEST_UNIT ("/script/single-object", script_single)
|
||||
CLUTTER_TEST_UNIT ("/script/container-child", script_child)
|
||||
CLUTTER_TEST_UNIT ("/script/named-object", script_named_object)
|
||||
CLUTTER_TEST_UNIT ("/script/animation", script_animation)
|
||||
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)
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"type" : "ClutterAnimator",
|
||||
"id" : "animator",
|
||||
"duration" : 1000
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
[
|
||||
{
|
||||
"type" : "ClutterRectangle",
|
||||
"id" : "foo",
|
||||
"x" : 0,
|
||||
"y" : 0,
|
||||
"width" : 100,
|
||||
"height" : 100
|
||||
},
|
||||
{
|
||||
"type" : "ClutterAnimator",
|
||||
"id" : "animator",
|
||||
"duration" : 1000,
|
||||
|
||||
"properties" : [
|
||||
{
|
||||
"object" : "foo",
|
||||
"name" : "x",
|
||||
"ease-in" : true,
|
||||
"interpolation" : "linear",
|
||||
"keys" : [
|
||||
[ 0.0, "easeInCubic", 100.0 ],
|
||||
[ 0.2, "easeOutCubic", 150.0 ],
|
||||
[ 0.8, "linear", 200.0 ]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,40 +0,0 @@
|
||||
[
|
||||
{
|
||||
"type" : "ClutterRectangle",
|
||||
"id" : "foo",
|
||||
"x" : 0,
|
||||
"y" : 0,
|
||||
"width" : 100,
|
||||
"height" : 100
|
||||
},
|
||||
{
|
||||
"type" : "ClutterAnimator",
|
||||
"id" : "animator",
|
||||
"duration" : 1000,
|
||||
|
||||
"properties" : [
|
||||
{
|
||||
"object" : "foo",
|
||||
"name" : "x",
|
||||
"ease-in" : true,
|
||||
"interpolation" : "linear",
|
||||
"keys" : [
|
||||
[ 0.0, "easeInCubic", 100.0 ],
|
||||
[ 0.2, "easeOutCubic", 150.0 ],
|
||||
[ 0.8, "linear", 200.0 ]
|
||||
]
|
||||
},
|
||||
{
|
||||
"object" : "foo",
|
||||
"name" : "y",
|
||||
"ease-in" : true,
|
||||
"interpolation" : "linear",
|
||||
"keys" : [
|
||||
[ 0.0, "easeInCubic", 100.0 ],
|
||||
[ 0.2, "easeOutCubic", 150.0 ],
|
||||
[ 0.8, "linear", 200.0 ]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"type" : "ClutterAnimation",
|
||||
"id" : "test",
|
||||
"mode" : "easeInCubic",
|
||||
"duration" : 500,
|
||||
"object" : {
|
||||
"type" : "ClutterRectangle",
|
||||
"id" : "rect",
|
||||
"opacity" : 128,
|
||||
"width" : 100,
|
||||
"height" : 16,
|
||||
"color" : "white"
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
[
|
||||
{
|
||||
"type" : "ClutterRectangle",
|
||||
"id" : "rect",
|
||||
"width" : 100,
|
||||
"height" : 100
|
||||
},
|
||||
{
|
||||
"type" : "ClutterState",
|
||||
"id" : "state",
|
||||
|
||||
"transitions" : [
|
||||
{
|
||||
"source" : "base",
|
||||
"target" : "clicked",
|
||||
"duration" : 250,
|
||||
|
||||
"keys" : [
|
||||
[ "rect", "opacity", "linear", 128 ]
|
||||
]
|
||||
},
|
||||
{
|
||||
"source" : "clicked",
|
||||
"target" : "base",
|
||||
"duration" : 150,
|
||||
|
||||
"keys" : [
|
||||
[ "rect", "opacity", "linear", 255 ]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,87 +0,0 @@
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include "test-conform-common.h"
|
||||
|
||||
void
|
||||
state_base (TestConformSimpleFixture *fixture G_GNUC_UNUSED,
|
||||
gconstpointer dummy G_GNUC_UNUSED)
|
||||
{
|
||||
ClutterScript *script = clutter_script_new ();
|
||||
GObject *state = NULL;
|
||||
GError *error = NULL;
|
||||
gchar *test_file;
|
||||
GList *states, *keys;
|
||||
ClutterStateKey *state_key;
|
||||
guint duration;
|
||||
|
||||
test_file = clutter_test_get_data_file ("test-state-1.json");
|
||||
clutter_script_load_from_file (script, test_file, &error);
|
||||
if (g_test_verbose () && error)
|
||||
g_print ("Error: %s\n", error->message);
|
||||
|
||||
g_free (test_file);
|
||||
|
||||
#if GLIB_CHECK_VERSION (2, 20, 0)
|
||||
g_assert_no_error (error);
|
||||
#else
|
||||
g_assert (error == NULL);
|
||||
#endif
|
||||
|
||||
state = clutter_script_get_object (script, "state");
|
||||
g_assert (CLUTTER_IS_STATE (state));
|
||||
|
||||
states = clutter_state_get_states (CLUTTER_STATE (state));
|
||||
g_assert (states != NULL);
|
||||
|
||||
g_assert (g_list_find (states, g_intern_static_string ("clicked")));
|
||||
g_list_free (states);
|
||||
|
||||
duration = clutter_state_get_duration (CLUTTER_STATE (state), "base", "clicked");
|
||||
g_assert_cmpint (duration, ==, 250);
|
||||
|
||||
duration = clutter_state_get_duration (CLUTTER_STATE (state), "clicked", "base");
|
||||
g_assert_cmpint (duration, ==, 150);
|
||||
|
||||
keys = clutter_state_get_keys (CLUTTER_STATE (state), "base", "clicked",
|
||||
clutter_script_get_object (script, "rect"),
|
||||
"opacity");
|
||||
|
||||
g_assert (keys != NULL);
|
||||
g_assert_cmpint (g_list_length (keys), ==, 1);
|
||||
|
||||
state_key = keys->data;
|
||||
g_assert (clutter_state_key_get_object (state_key) == clutter_script_get_object (script, "rect"));
|
||||
g_assert (clutter_state_key_get_mode (state_key) == CLUTTER_LINEAR);
|
||||
g_assert_cmpstr (clutter_state_key_get_property_name (state_key), ==, "opacity");
|
||||
|
||||
g_list_free (keys);
|
||||
keys = clutter_state_get_keys (CLUTTER_STATE (state), NULL, NULL, NULL, NULL);
|
||||
g_assert_cmpint (g_list_length (keys), ==, 2);
|
||||
g_list_free (keys);
|
||||
|
||||
|
||||
|
||||
clutter_state_set (CLUTTER_STATE (state), "base", "clicked", state, "state", CLUTTER_LINEAR, "foo", NULL);
|
||||
|
||||
keys = clutter_state_get_keys (CLUTTER_STATE (state), "base", "clicked",
|
||||
NULL, NULL);
|
||||
|
||||
g_assert (keys != NULL);
|
||||
g_assert_cmpint (g_list_length (keys), ==, 2);
|
||||
g_list_free (keys);
|
||||
|
||||
states = clutter_state_get_states (CLUTTER_STATE (state));
|
||||
g_assert_cmpint (g_list_length (states), ==, 2);
|
||||
g_list_free (states);
|
||||
|
||||
clutter_state_remove_key (CLUTTER_STATE (state), NULL, "clicked", NULL, NULL);
|
||||
states = clutter_state_get_states (CLUTTER_STATE (state));
|
||||
|
||||
/* removing the "clicked" state, will also cause the "base" state to be removed
|
||||
* since in the .json there is no default source state
|
||||
*/
|
||||
g_assert_cmpint (g_list_length (states), ==, 0);
|
||||
g_list_free (states);
|
||||
|
||||
g_object_unref (script);
|
||||
}
|
||||
BIN
src/tests/clutter/interactive/light0.png
Normal file
BIN
src/tests/clutter/interactive/light0.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
@@ -17,18 +17,14 @@ clutter_tests_interactive_link_args = [
|
||||
clutter_tests_interactive_test_sources = [
|
||||
'test-events.c',
|
||||
'test-actors.c',
|
||||
'test-shader-effects.c',
|
||||
'test-script.c',
|
||||
'test-grab.c',
|
||||
'test-cogl-shader-glsl.c',
|
||||
'test-state.c',
|
||||
'test-cogl-tex-tile.c',
|
||||
'test-cogl-tex-convert.c',
|
||||
'test-cogl-offscreen.c',
|
||||
'test-cogl-tex-polygon.c',
|
||||
'test-cogl-multitexture.c',
|
||||
'test-paint-wrapper.c',
|
||||
'test-layout.c',
|
||||
'test-animation.c',
|
||||
'test-easing.c',
|
||||
'test-binding-pool.c',
|
||||
@@ -39,12 +35,9 @@ clutter_tests_interactive_test_sources = [
|
||||
'test-stage-sizing.c',
|
||||
'test-swipe-action.c',
|
||||
'test-cogl-point-sprites.c',
|
||||
'test-path-constraint.c',
|
||||
'test-state-script.c',
|
||||
'test-devices.c',
|
||||
'test-content.c',
|
||||
'test-keyframe-transition.c',
|
||||
'test-bind-constraint.c',
|
||||
'test-touch-events.c',
|
||||
'test-rotate-zoom.c',
|
||||
'test-image.c',
|
||||
|
||||
BIN
src/tests/clutter/interactive/redhand_alpha.png
Normal file
BIN
src/tests/clutter/interactive/redhand_alpha.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
@@ -53,8 +53,6 @@ static gboolean recenter = FALSE;
|
||||
static ClutterActor *main_stage = NULL;
|
||||
static ClutterActor *easing_mode_label = NULL;
|
||||
|
||||
static ClutterAnimation *last_animation = NULL;
|
||||
|
||||
int
|
||||
test_easing_main (int argc, char *argv[]);
|
||||
|
||||
@@ -66,21 +64,23 @@ test_easing_describe (void);
|
||||
* repositions (through an animation) the bouncer at the center of the stage
|
||||
*/
|
||||
static void
|
||||
recenter_bouncer (ClutterAnimation *animation,
|
||||
ClutterActor *rectangle)
|
||||
recenter_bouncer (ClutterActor *rectangle)
|
||||
{
|
||||
gfloat base_x, base_y;
|
||||
gint cur_mode;
|
||||
|
||||
|
||||
cur_mode = easing_modes[current_mode].mode;
|
||||
base_x = clutter_actor_get_width (main_stage) / 2;
|
||||
base_y = clutter_actor_get_height (main_stage) / 2;
|
||||
|
||||
cur_mode = easing_modes[current_mode].mode;
|
||||
clutter_actor_set_easing_duration (rectangle, 250);
|
||||
clutter_actor_set_easing_mode (rectangle, cur_mode);
|
||||
clutter_actor_set_position (rectangle, base_x, base_y);
|
||||
|
||||
clutter_actor_animate (rectangle, cur_mode, 250,
|
||||
"x", base_x,
|
||||
"y", base_y,
|
||||
NULL);
|
||||
g_signal_connect_after (rectangle, "transition-completed",
|
||||
G_CALLBACK (clutter_actor_restore_easing_state),
|
||||
NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -108,28 +108,22 @@ on_button_press (ClutterActor *actor,
|
||||
}
|
||||
else if (event->button == CLUTTER_BUTTON_PRIMARY)
|
||||
{
|
||||
ClutterAnimation *animation;
|
||||
ClutterAnimationMode cur_mode;
|
||||
|
||||
cur_mode = easing_modes[current_mode].mode;
|
||||
|
||||
/* tween the actor using the current easing mode */
|
||||
animation =
|
||||
clutter_actor_animate (rectangle, cur_mode, duration * 1000,
|
||||
"x", event->x,
|
||||
"y", event->y,
|
||||
NULL);
|
||||
clutter_actor_save_easing_state (rectangle);
|
||||
clutter_actor_set_easing_duration (rectangle, duration * 1000);
|
||||
clutter_actor_set_easing_mode (rectangle, cur_mode);
|
||||
clutter_actor_set_position (rectangle, event->x, event->y);
|
||||
|
||||
/* if we were asked to, recenter the bouncer at the end of the
|
||||
* animation. we keep track of the animation to avoid connecting
|
||||
* the signal handler to the same Animation twice.
|
||||
*/
|
||||
if (recenter && last_animation != animation)
|
||||
g_signal_connect_after (animation, "completed",
|
||||
G_CALLBACK (recenter_bouncer),
|
||||
rectangle);
|
||||
|
||||
last_animation = animation;
|
||||
g_signal_connect_after (rectangle, "transition-completed",
|
||||
G_CALLBACK (recenter_bouncer),
|
||||
rectangle);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
[
|
||||
{
|
||||
"id" : "button",
|
||||
"type" : "ClutterRectangle",
|
||||
|
||||
"width" : "16 em",
|
||||
"height" : "6 em",
|
||||
|
||||
"color" : "rgb(255, 0, 0)",
|
||||
"opacity" : 128,
|
||||
|
||||
"scale-gravity" : "center",
|
||||
|
||||
"reactive" : true,
|
||||
|
||||
"signals" : [
|
||||
{
|
||||
"name" : "button-press-event",
|
||||
"handler" : "on_button_press"
|
||||
},
|
||||
{ "name" : "enter-event", "states" : "button-states", "target-state" : "hover" },
|
||||
{ "name" : "leave-event", "states" : "button-states", "target-state" : "base" },
|
||||
{ "name" : "button-press-event", "states" : "button-states", "target-state" : "active" },
|
||||
{ "name" : "button-release-event", "states" : "button-states", "target-state" : "hover" }
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"id" : "button-states",
|
||||
"type" : "ClutterState",
|
||||
|
||||
"duration" : 250,
|
||||
|
||||
"transitions" : [
|
||||
{
|
||||
"source" : null,
|
||||
"target" : "base",
|
||||
|
||||
"keys" : [
|
||||
[ "button", "opacity", "linear", 128 ],
|
||||
[ "button", "scale-x", "ease-in-cubic", 1.0 ],
|
||||
[ "button", "scale-y", "ease-in-cubic", 1.0 ],
|
||||
[ "button", "color", "linear", "rgb(255, 0, 0)" ]
|
||||
]
|
||||
},
|
||||
{
|
||||
"source" : null,
|
||||
"target" : "hover",
|
||||
|
||||
"keys" : [
|
||||
[ "button", "opacity", "linear", 255 ],
|
||||
[ "button", "scale-x", "ease-out-bounce", 1.4 ],
|
||||
[ "button", "scale-y", "ease-out-bounce", 1.4 ],
|
||||
[ "button", "color", "linear", "rgb(0, 255, 0)" ]
|
||||
]
|
||||
},
|
||||
{
|
||||
"source" : null,
|
||||
"target" : "active",
|
||||
|
||||
"keys" : [
|
||||
[ "button", "opacity", "linear", 255 ],
|
||||
[ "button", "color", "linear", "rgb(0, 0, 255)" ]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -40,13 +40,7 @@ static const gchar *test_behaviour =
|
||||
" \"type\" : \"ClutterTimeline\","
|
||||
" \"duration\" : 5000,"
|
||||
" \"loop\" : true"
|
||||
" },"
|
||||
" {"
|
||||
" \"id\" : \"sine-alpha\","
|
||||
" \"type\" : \"ClutterAlpha\","
|
||||
" \"function\" : \"sine_alpha\","
|
||||
" \"timeline\" : \"main-timeline\""
|
||||
" },"
|
||||
" }"
|
||||
"]";
|
||||
|
||||
static gboolean
|
||||
|
||||
@@ -1,213 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <gmodule.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include "test-utils.h"
|
||||
|
||||
#define STAGE_WIDTH 1024
|
||||
#define STAGE_HEIGHT 768
|
||||
|
||||
#define ACTOR_WIDTH 128
|
||||
#define ACTOR_HEIGHT 128
|
||||
|
||||
#define COLS (STAGE_WIDTH/ACTOR_WIDTH)
|
||||
#define ROWS (STAGE_HEIGHT/ACTOR_HEIGHT)
|
||||
#define TOTAL (ROWS*COLS)
|
||||
|
||||
gint
|
||||
test_state_main (gint argc,
|
||||
gchar **argv);
|
||||
|
||||
const char *
|
||||
test_state_describe (void);
|
||||
|
||||
static gboolean press_event (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
ClutterState *state = CLUTTER_STATE (user_data);
|
||||
clutter_state_set_state (state, "right");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean release_event (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
ClutterState *state = CLUTTER_STATE (user_data);
|
||||
clutter_state_set_state (state, "active");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean enter_event (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
ClutterState *state = CLUTTER_STATE (user_data);
|
||||
clutter_state_set_state (state, "hover");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean leave_event (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
ClutterState *state = CLUTTER_STATE (user_data);
|
||||
clutter_state_set_state (state, "normal");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void completed (ClutterState *state,
|
||||
gpointer data)
|
||||
{
|
||||
g_print ("Completed transitioning to state: %s\n",
|
||||
clutter_state_get_state (state));
|
||||
|
||||
if (g_str_equal (clutter_state_get_state (state), "right"))
|
||||
{
|
||||
/* skip straight to left state when reaching right */
|
||||
clutter_state_warp_to_state (state, "left");
|
||||
}
|
||||
}
|
||||
|
||||
static ClutterActor *new_rect (gint r,
|
||||
gint g,
|
||||
gint b,
|
||||
gint a)
|
||||
{
|
||||
GError *error = NULL;
|
||||
ClutterColor *color = clutter_color_new (r, g, b, a);
|
||||
ClutterActor *group = clutter_actor_new ();
|
||||
ClutterActor *rectangle = clutter_actor_new ();
|
||||
ClutterActor *hand = NULL;
|
||||
|
||||
gchar *file = g_build_filename (TESTS_DATADIR, "redhand.png", NULL);
|
||||
|
||||
hand = clutter_test_utils_create_texture_from_file (file, &error);
|
||||
if (rectangle == NULL)
|
||||
g_error ("image load failed: %s", error->message);
|
||||
g_free (file);
|
||||
clutter_actor_set_size (hand, ACTOR_WIDTH,ACTOR_HEIGHT);
|
||||
|
||||
clutter_actor_set_background_color (rectangle, color);
|
||||
clutter_actor_set_size (rectangle, ACTOR_WIDTH,ACTOR_HEIGHT);
|
||||
clutter_color_free (color);
|
||||
|
||||
clutter_actor_add_child (group, rectangle);
|
||||
clutter_actor_add_child (group, hand);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT gint
|
||||
test_state_main (gint argc,
|
||||
gchar **argv)
|
||||
{
|
||||
ClutterActor *stage;
|
||||
ClutterState *layout_state;
|
||||
gint i;
|
||||
|
||||
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
|
||||
return 1;
|
||||
|
||||
layout_state = clutter_state_new ();
|
||||
|
||||
stage = clutter_stage_new ();
|
||||
clutter_actor_set_background_color (stage, CLUTTER_COLOR_Black);
|
||||
clutter_stage_set_title (CLUTTER_STAGE (stage), "State Machine");
|
||||
clutter_actor_set_size (stage, STAGE_WIDTH, STAGE_HEIGHT);
|
||||
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
|
||||
g_signal_connect (stage, "button-press-event",
|
||||
G_CALLBACK (press_event), layout_state);
|
||||
g_signal_connect (stage, "button-release-event",
|
||||
G_CALLBACK (release_event), layout_state);
|
||||
|
||||
for (i = 0; i < TOTAL; i++)
|
||||
{
|
||||
ClutterActor *actor;
|
||||
ClutterState *a_state;
|
||||
|
||||
int row = i/COLS;
|
||||
int col = i%COLS;
|
||||
|
||||
actor = new_rect (255 * (1.0 * col / COLS), 50,
|
||||
255 * (1.0 * row / ROWS), 255);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), actor);
|
||||
clutter_actor_set_position (actor, 320.0, 240.0);
|
||||
clutter_actor_set_reactive (actor, TRUE);
|
||||
clutter_actor_add_effect_with_name (actor, "fade",
|
||||
clutter_desaturate_effect_new (0.0));
|
||||
|
||||
|
||||
clutter_state_set (layout_state, NULL, "active",
|
||||
actor, "delayed::x", CLUTTER_LINEAR,
|
||||
ACTOR_WIDTH * 1.0 * ((TOTAL-1-i) % COLS),
|
||||
((row*1.0/ROWS))/2, (1.0-(row*1.0/ROWS))/2,
|
||||
actor, "delayed::y", CLUTTER_LINEAR,
|
||||
ACTOR_HEIGHT * 1.0 * ((TOTAL-1-i) / COLS),
|
||||
((row*1.0/ROWS))/2, 0.0,
|
||||
actor, "rotation-angle-x", CLUTTER_LINEAR, 0.0,
|
||||
actor, "rotation-angle-y", CLUTTER_LINEAR, 0.0,
|
||||
NULL);
|
||||
|
||||
clutter_state_set (layout_state, NULL, "right",
|
||||
actor, "delayed::x", CLUTTER_LINEAR, STAGE_WIDTH * 1.0,
|
||||
((row*1.0/ROWS))/2,
|
||||
(1.0-(row*1.0/ROWS))/2,
|
||||
actor, "delayed::y", CLUTTER_LINEAR, STAGE_HEIGHT * 1.0,
|
||||
((row*1.0/ROWS))/2,
|
||||
0.0,
|
||||
NULL);
|
||||
|
||||
clutter_state_set (layout_state, NULL, "left",
|
||||
actor, "rotation-angle-x", CLUTTER_LINEAR, 45.0,
|
||||
actor, "rotation-angle-y", CLUTTER_LINEAR, 5.0,
|
||||
actor, "x", CLUTTER_LINEAR, 0-64.0,
|
||||
actor, "y", CLUTTER_LINEAR, 0-64.0,
|
||||
NULL);
|
||||
|
||||
a_state = clutter_state_new ();
|
||||
g_object_set_data_full (G_OBJECT (actor), "hover-state-machine",
|
||||
a_state, g_object_unref);
|
||||
g_signal_connect (actor, "enter-event",
|
||||
G_CALLBACK (enter_event), a_state);
|
||||
g_signal_connect (actor, "leave-event",
|
||||
G_CALLBACK (leave_event), a_state);
|
||||
|
||||
clutter_state_set (a_state, NULL, "normal",
|
||||
actor, "opacity", CLUTTER_LINEAR, 0x77,
|
||||
actor, "rotation-angle-z", CLUTTER_LINEAR, 0.0,
|
||||
actor, "@effects.fade.factor", CLUTTER_LINEAR, 0.0,
|
||||
NULL);
|
||||
clutter_state_set (a_state, NULL, "hover",
|
||||
actor, "opacity", CLUTTER_LINEAR, 0xff,
|
||||
actor, "rotation-angle-z", CLUTTER_LINEAR, 10.0,
|
||||
actor, "@effects.fade.factor", CLUTTER_LINEAR, 1.0,
|
||||
NULL);
|
||||
clutter_actor_set_opacity (actor, 0x77);
|
||||
|
||||
clutter_state_set_duration (a_state, NULL, NULL, 500);
|
||||
}
|
||||
|
||||
clutter_state_set_duration (layout_state, NULL, NULL, 1000);
|
||||
clutter_state_set_duration (layout_state, "active", "left", 1400);
|
||||
|
||||
g_signal_connect (layout_state, "completed", G_CALLBACK (completed), NULL);
|
||||
|
||||
clutter_actor_show (stage);
|
||||
|
||||
clutter_state_warp_to_state (layout_state, "left");
|
||||
clutter_state_set_state (layout_state, "active");
|
||||
|
||||
clutter_main ();
|
||||
|
||||
g_object_unref (layout_state);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT const char *
|
||||
test_state_describe (void)
|
||||
{
|
||||
return "Animating using the State class.";
|
||||
}
|
||||
@@ -11,11 +11,6 @@ clutter_tests_performance_c_args += clutter_debug_c_args
|
||||
clutter_tests_performance_tests = [
|
||||
'test-picking',
|
||||
'test-text-perf',
|
||||
'test-state',
|
||||
'test-state-interactive',
|
||||
'test-state-hidden',
|
||||
'test-state-mini',
|
||||
'test-state-pick',
|
||||
]
|
||||
|
||||
foreach test : clutter_tests_performance_tests
|
||||
|
||||
@@ -1,150 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <gmodule.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include "test-common.h"
|
||||
|
||||
#define STAGE_WIDTH 160
|
||||
#define STAGE_HEIGHT 120
|
||||
|
||||
#define ACTOR_WIDTH 8
|
||||
#define ACTOR_HEIGHT 8
|
||||
|
||||
#define COLS (STAGE_WIDTH/ACTOR_WIDTH)
|
||||
#define ROWS (STAGE_HEIGHT/ACTOR_HEIGHT)
|
||||
#define TOTAL (ROWS*COLS)
|
||||
|
||||
|
||||
static void completed (ClutterState *state,
|
||||
gpointer data)
|
||||
{
|
||||
if (g_str_equal (clutter_state_get_state (state), "right"))
|
||||
{
|
||||
/* skip straight to left state when reaching right */
|
||||
clutter_state_warp_to_state (state, "left");
|
||||
}
|
||||
else if (g_str_equal (clutter_state_get_state (state), "active"))
|
||||
clutter_state_set_state (state, "right");
|
||||
else
|
||||
{
|
||||
clutter_state_set_state (state, "active");
|
||||
}
|
||||
}
|
||||
|
||||
static ClutterActor *new_rect (gint r,
|
||||
gint g,
|
||||
gint b,
|
||||
gint a)
|
||||
{
|
||||
ClutterColor *color = clutter_color_new (r, g, b, a);
|
||||
ClutterActor *group = clutter_group_new ();
|
||||
ClutterActor *rectangle = clutter_rectangle_new_with_color (color);
|
||||
|
||||
gchar *file = g_build_filename (TESTS_DATA_DIR, "redhand.png", NULL);
|
||||
|
||||
g_free (file);
|
||||
clutter_actor_set_size (rectangle, ACTOR_WIDTH,ACTOR_HEIGHT);
|
||||
clutter_color_free (color);
|
||||
clutter_container_add (CLUTTER_CONTAINER (group), rectangle, NULL);
|
||||
return group;
|
||||
}
|
||||
|
||||
gint
|
||||
main (gint argc,
|
||||
gchar **argv)
|
||||
{
|
||||
ClutterActor *stage;
|
||||
ClutterActor *group;
|
||||
ClutterState *layout_state;
|
||||
gint i;
|
||||
|
||||
clutter_perf_fps_init ();
|
||||
if (CLUTTER_INIT_SUCCESS != clutter_init (&argc, &argv))
|
||||
g_error ("Failed to initialize Clutter");
|
||||
|
||||
stage = clutter_stage_new ();
|
||||
group = clutter_group_new ();
|
||||
layout_state = clutter_state_new ();
|
||||
clutter_stage_set_title (CLUTTER_STAGE (stage), "State Performance [hidden]");
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), CLUTTER_COLOR_Black);
|
||||
clutter_actor_set_size (stage, STAGE_WIDTH, STAGE_HEIGHT);
|
||||
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
|
||||
|
||||
for (i=0; i<TOTAL; i++)
|
||||
{
|
||||
ClutterActor *actor;
|
||||
ClutterState *a_state;
|
||||
|
||||
int row = i/COLS;
|
||||
int col = i%COLS;
|
||||
|
||||
actor = new_rect (255 * ( 1.0*col/COLS), 50,
|
||||
255 * ( 1.0*row/ROWS), 255);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (group), actor);
|
||||
clutter_actor_set_position (actor, 320.0, 240.0);
|
||||
clutter_actor_set_reactive (actor, TRUE);
|
||||
|
||||
|
||||
clutter_state_set (layout_state, NULL, "active",
|
||||
actor, "delayed::x", CLUTTER_LINEAR,
|
||||
ACTOR_WIDTH * 1.0 * ((TOTAL-1-i) % COLS),
|
||||
((row*1.0/ROWS))/2, (1.0-(row*1.0/ROWS))/2,
|
||||
actor, "delayed::y", CLUTTER_LINEAR,
|
||||
ACTOR_HEIGHT * 1.0 * ((TOTAL-1-i) / COLS),
|
||||
((row*1.0/ROWS))/2, 0.0,
|
||||
actor, "rotation-angle-x", CLUTTER_LINEAR, 0.0,
|
||||
actor, "rotation-angle-y", CLUTTER_LINEAR, 0.0,
|
||||
NULL);
|
||||
|
||||
clutter_state_set (layout_state, NULL, "right",
|
||||
actor, "delayed::x", CLUTTER_LINEAR, STAGE_WIDTH * 1.0,
|
||||
((row*1.0/ROWS))/2,
|
||||
(1.0-(row*1.0/ROWS))/2,
|
||||
actor, "delayed::y", CLUTTER_LINEAR, STAGE_HEIGHT * 1.0,
|
||||
((row*1.0/ROWS))/2,
|
||||
0.0,
|
||||
NULL);
|
||||
|
||||
clutter_state_set (layout_state, NULL, "left",
|
||||
actor, "rotation-angle-x", CLUTTER_LINEAR, 45.0,
|
||||
actor, "rotation-angle-y", CLUTTER_LINEAR, 5.0,
|
||||
actor, "x", CLUTTER_LINEAR, 0-64.0,
|
||||
actor, "y", CLUTTER_LINEAR, 0-64.0,
|
||||
NULL);
|
||||
|
||||
a_state = clutter_state_new ();
|
||||
g_object_set_data_full (G_OBJECT (actor), "hover-state-machine",
|
||||
a_state, g_object_unref);
|
||||
|
||||
clutter_state_set (a_state, NULL, "normal",
|
||||
actor, "opacity", CLUTTER_LINEAR, 0x77,
|
||||
actor, "rotation-angle-z", CLUTTER_LINEAR, 0.0,
|
||||
NULL);
|
||||
clutter_state_set (a_state, NULL, "hover",
|
||||
actor, "opacity", CLUTTER_LINEAR, 0xff,
|
||||
actor, "rotation-angle-z", CLUTTER_LINEAR, 10.0,
|
||||
NULL);
|
||||
clutter_actor_set_opacity (actor, 0x77);
|
||||
|
||||
clutter_state_set_duration (a_state, NULL, NULL, 500);
|
||||
}
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), group);
|
||||
clutter_actor_set_opacity (group, 0);
|
||||
|
||||
clutter_state_set_duration (layout_state, NULL, NULL, 1000);
|
||||
clutter_state_set_duration (layout_state, "active", "left", 1400);
|
||||
|
||||
g_signal_connect (layout_state, "completed", G_CALLBACK (completed), NULL);
|
||||
|
||||
clutter_actor_show (stage);
|
||||
|
||||
clutter_state_warp_to_state (layout_state, "left");
|
||||
clutter_state_set_state (layout_state, "active");
|
||||
|
||||
clutter_perf_fps_start (CLUTTER_STAGE (stage));
|
||||
clutter_main ();
|
||||
clutter_perf_fps_report ("test-state-hidden");
|
||||
g_object_unref (layout_state);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -1,195 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <gmodule.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include "test-common.h"
|
||||
#include "test-utils.h"
|
||||
|
||||
#define STAGE_WIDTH 800
|
||||
#define STAGE_HEIGHT 600
|
||||
|
||||
#define ACTOR_WIDTH 64
|
||||
#define ACTOR_HEIGHT 64
|
||||
|
||||
#define COLS (STAGE_WIDTH/ACTOR_WIDTH)
|
||||
#define ROWS (STAGE_HEIGHT/ACTOR_HEIGHT)
|
||||
#define TOTAL (ROWS*COLS)
|
||||
|
||||
|
||||
static gboolean press_event (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
ClutterState *state = CLUTTER_STATE (user_data);
|
||||
clutter_state_set_state (state, "right");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean release_event (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
ClutterState *state = CLUTTER_STATE (user_data);
|
||||
clutter_state_set_state (state, "active");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean enter_event (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
ClutterState *state = CLUTTER_STATE (user_data);
|
||||
clutter_state_set_state (state, "hover");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean leave_event (ClutterActor *actor,
|
||||
ClutterEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
ClutterState *state = CLUTTER_STATE (user_data);
|
||||
clutter_state_set_state (state, "normal");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void completed (ClutterState *state,
|
||||
gpointer data)
|
||||
{
|
||||
g_print ("Completed transitioning to state: %s\n",
|
||||
clutter_state_get_state (state));
|
||||
|
||||
if (g_str_equal (clutter_state_get_state (state), "right"))
|
||||
{
|
||||
/* skip straight to left state when reaching right */
|
||||
clutter_state_warp_to_state (state, "left");
|
||||
}
|
||||
}
|
||||
|
||||
static ClutterActor *new_rect (gint r,
|
||||
gint g,
|
||||
gint b,
|
||||
gint a)
|
||||
{
|
||||
GError *error = NULL;
|
||||
ClutterColor *color = clutter_color_new (r, g, b, a);
|
||||
ClutterActor *group = clutter_group_new ();
|
||||
ClutterActor *rectangle = clutter_rectangle_new_with_color (color);
|
||||
ClutterActor *hand = NULL;
|
||||
|
||||
gchar *file = g_build_filename (TESTS_DATA_DIR, "redhand.png", NULL);
|
||||
|
||||
hand = clutter_test_utils_create_texture_from_file (file, &error);
|
||||
if (rectangle == NULL)
|
||||
g_error ("image load failed: %s", error->message);
|
||||
g_free (file);
|
||||
clutter_actor_set_size (hand, ACTOR_WIDTH,ACTOR_HEIGHT);
|
||||
|
||||
clutter_actor_set_size (rectangle, ACTOR_WIDTH,ACTOR_HEIGHT);
|
||||
clutter_color_free (color);
|
||||
clutter_container_add (CLUTTER_CONTAINER (group), rectangle, hand, NULL);
|
||||
return group;
|
||||
}
|
||||
|
||||
gint
|
||||
main (gint argc,
|
||||
gchar **argv)
|
||||
{
|
||||
ClutterActor *stage;
|
||||
ClutterState *layout_state;
|
||||
gint i;
|
||||
clutter_perf_fps_init ();
|
||||
if (CLUTTER_INIT_SUCCESS != clutter_init (&argc, &argv))
|
||||
g_error ("Failed to initialize Clutter");
|
||||
|
||||
stage = clutter_stage_new ();
|
||||
layout_state = clutter_state_new ();
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), CLUTTER_COLOR_Black);
|
||||
clutter_stage_set_title (CLUTTER_STAGE (stage), "State Performance [interactive]");
|
||||
clutter_actor_set_size (stage, STAGE_WIDTH, STAGE_HEIGHT);
|
||||
|
||||
g_signal_connect (stage, "button-press-event",
|
||||
G_CALLBACK (press_event), layout_state);
|
||||
g_signal_connect (stage, "button-release-event",
|
||||
G_CALLBACK (release_event), layout_state);
|
||||
|
||||
for (i=0; i<TOTAL; i++)
|
||||
{
|
||||
ClutterActor *actor;
|
||||
ClutterState *a_state;
|
||||
|
||||
int row = i/COLS;
|
||||
int col = i%COLS;
|
||||
|
||||
actor = new_rect (255 * ( 1.0*col/COLS), 50,
|
||||
255 * ( 1.0*row/ROWS), 255);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), actor);
|
||||
clutter_actor_set_position (actor, 320.0, 240.0);
|
||||
clutter_actor_set_reactive (actor, TRUE);
|
||||
|
||||
|
||||
clutter_state_set (layout_state, NULL, "active",
|
||||
actor, "delayed::x", CLUTTER_LINEAR,
|
||||
ACTOR_WIDTH * 1.0 * ((TOTAL-1-i) % COLS),
|
||||
((row*1.0/ROWS))/2, (1.0-(row*1.0/ROWS))/2,
|
||||
actor, "delayed::y", CLUTTER_LINEAR,
|
||||
ACTOR_HEIGHT * 1.0 * ((TOTAL-1-i) / COLS),
|
||||
((row*1.0/ROWS))/2, 0.0,
|
||||
actor, "rotation-angle-x", CLUTTER_LINEAR, 0.0,
|
||||
actor, "rotation-angle-y", CLUTTER_LINEAR, 0.0,
|
||||
NULL);
|
||||
|
||||
clutter_state_set (layout_state, NULL, "right",
|
||||
actor, "delayed::x", CLUTTER_LINEAR, STAGE_WIDTH * 1.0,
|
||||
((row*1.0/ROWS))/2,
|
||||
(1.0-(row*1.0/ROWS))/2,
|
||||
actor, "delayed::y", CLUTTER_LINEAR, STAGE_HEIGHT * 1.0,
|
||||
((row*1.0/ROWS))/2,
|
||||
0.0,
|
||||
NULL);
|
||||
|
||||
clutter_state_set (layout_state, NULL, "left",
|
||||
actor, "rotation-angle-x", CLUTTER_LINEAR, 45.0,
|
||||
actor, "rotation-angle-y", CLUTTER_LINEAR, 5.0,
|
||||
actor, "x", CLUTTER_LINEAR, 0-64.0,
|
||||
actor, "y", CLUTTER_LINEAR, 0-64.0,
|
||||
NULL);
|
||||
|
||||
a_state = clutter_state_new ();
|
||||
g_object_set_data_full (G_OBJECT (actor), "hover-state-machine",
|
||||
a_state, g_object_unref);
|
||||
g_signal_connect (actor, "enter-event",
|
||||
G_CALLBACK (enter_event), a_state);
|
||||
g_signal_connect (actor, "leave-event",
|
||||
G_CALLBACK (leave_event), a_state);
|
||||
|
||||
clutter_state_set (a_state, NULL, "normal",
|
||||
actor, "opacity", CLUTTER_LINEAR, 0x77,
|
||||
actor, "rotation-angle-z", CLUTTER_LINEAR, 0.0,
|
||||
NULL);
|
||||
clutter_state_set (a_state, NULL, "hover",
|
||||
actor, "opacity", CLUTTER_LINEAR, 0xff,
|
||||
actor, "rotation-angle-z", CLUTTER_LINEAR, 10.0,
|
||||
NULL);
|
||||
clutter_actor_set_opacity (actor, 0x77);
|
||||
|
||||
clutter_state_set_duration (a_state, NULL, NULL, 500);
|
||||
}
|
||||
|
||||
clutter_state_set_duration (layout_state, NULL, NULL, 1000);
|
||||
clutter_state_set_duration (layout_state, "active", "left", 1400);
|
||||
|
||||
g_signal_connect (layout_state, "completed", G_CALLBACK (completed), NULL);
|
||||
|
||||
clutter_actor_show (stage);
|
||||
|
||||
clutter_state_warp_to_state (layout_state, "left");
|
||||
clutter_state_set_state (layout_state, "active");
|
||||
|
||||
clutter_perf_fake_mouse (CLUTTER_STAGE (stage));
|
||||
clutter_perf_fps_start (CLUTTER_STAGE (stage));
|
||||
clutter_main ();
|
||||
clutter_perf_fps_report ("test-state-interactive");
|
||||
g_object_unref (layout_state);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <gmodule.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include "test-common.h"
|
||||
#include "test-utils.h"
|
||||
|
||||
#define STAGE_WIDTH 160
|
||||
#define STAGE_HEIGHT 120
|
||||
|
||||
#define ACTOR_WIDTH 8
|
||||
#define ACTOR_HEIGHT 8
|
||||
|
||||
#define COLS (STAGE_WIDTH/ACTOR_WIDTH)
|
||||
#define ROWS (STAGE_HEIGHT/ACTOR_HEIGHT)
|
||||
#define TOTAL (ROWS*COLS)
|
||||
|
||||
|
||||
static void completed (ClutterState *state,
|
||||
gpointer data)
|
||||
{
|
||||
if (g_str_equal (clutter_state_get_state (state), "right"))
|
||||
{
|
||||
/* skip straight to left state when reaching right */
|
||||
clutter_state_warp_to_state (state, "left");
|
||||
}
|
||||
else if (g_str_equal (clutter_state_get_state (state), "active"))
|
||||
clutter_state_set_state (state, "right");
|
||||
else
|
||||
{
|
||||
clutter_state_set_state (state, "active");
|
||||
}
|
||||
}
|
||||
|
||||
static ClutterActor *new_rect (gint r,
|
||||
gint g,
|
||||
gint b,
|
||||
gint a)
|
||||
{
|
||||
GError *error = NULL;
|
||||
ClutterColor *color = clutter_color_new (r, g, b, a);
|
||||
ClutterActor *group = clutter_group_new ();
|
||||
ClutterActor *rectangle = clutter_rectangle_new_with_color (color);
|
||||
ClutterActor *hand = NULL;
|
||||
|
||||
gchar *file = g_build_filename (TESTS_DATA_DIR, "redhand.png", NULL);
|
||||
|
||||
hand = clutter_test_utils_create_texture_from_file (file, &error);
|
||||
if (rectangle == NULL)
|
||||
g_error ("image load failed: %s", error->message);
|
||||
g_free (file);
|
||||
clutter_actor_set_size (hand, ACTOR_WIDTH,ACTOR_HEIGHT);
|
||||
|
||||
clutter_actor_set_size (rectangle, ACTOR_WIDTH,ACTOR_HEIGHT);
|
||||
clutter_color_free (color);
|
||||
clutter_container_add (CLUTTER_CONTAINER (group), rectangle, hand, NULL);
|
||||
return group;
|
||||
}
|
||||
|
||||
gint
|
||||
main (gint argc,
|
||||
gchar **argv)
|
||||
{
|
||||
ClutterActor *stage;
|
||||
ClutterState *layout_state;
|
||||
gint i;
|
||||
|
||||
clutter_perf_fps_init ();
|
||||
if (CLUTTER_INIT_SUCCESS != clutter_init (&argc, &argv))
|
||||
g_error ("Failed to initialize Clutter");
|
||||
|
||||
stage = clutter_stage_new ();
|
||||
layout_state = clutter_state_new ();
|
||||
clutter_stage_set_title (CLUTTER_STAGE (stage), "State Performance [mini]");
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), CLUTTER_COLOR_Black);
|
||||
clutter_actor_set_size (stage, STAGE_WIDTH, STAGE_HEIGHT);
|
||||
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
|
||||
|
||||
for (i=0; i<TOTAL; i++)
|
||||
{
|
||||
ClutterActor *actor;
|
||||
ClutterState *a_state;
|
||||
|
||||
int row = i/COLS;
|
||||
int col = i%COLS;
|
||||
|
||||
actor = new_rect (255 * ( 1.0*col/COLS), 50,
|
||||
255 * ( 1.0*row/ROWS), 255);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), actor);
|
||||
clutter_actor_set_position (actor, 320.0, 240.0);
|
||||
clutter_actor_set_reactive (actor, TRUE);
|
||||
|
||||
|
||||
clutter_state_set (layout_state, NULL, "active",
|
||||
actor, "delayed::x", CLUTTER_LINEAR,
|
||||
ACTOR_WIDTH * 1.0 * ((TOTAL-1-i) % COLS),
|
||||
((row*1.0/ROWS))/2, (1.0-(row*1.0/ROWS))/2,
|
||||
actor, "delayed::y", CLUTTER_LINEAR,
|
||||
ACTOR_HEIGHT * 1.0 * ((TOTAL-1-i) / COLS),
|
||||
((row*1.0/ROWS))/2, 0.0,
|
||||
actor, "rotation-angle-x", CLUTTER_LINEAR, 0.0,
|
||||
actor, "rotation-angle-y", CLUTTER_LINEAR, 0.0,
|
||||
NULL);
|
||||
|
||||
clutter_state_set (layout_state, NULL, "right",
|
||||
actor, "delayed::x", CLUTTER_LINEAR, STAGE_WIDTH * 1.0,
|
||||
((row*1.0/ROWS))/2,
|
||||
(1.0-(row*1.0/ROWS))/2,
|
||||
actor, "delayed::y", CLUTTER_LINEAR, STAGE_HEIGHT * 1.0,
|
||||
((row*1.0/ROWS))/2,
|
||||
0.0,
|
||||
NULL);
|
||||
|
||||
clutter_state_set (layout_state, NULL, "left",
|
||||
actor, "rotation-angle-x", CLUTTER_LINEAR, 45.0,
|
||||
actor, "rotation-angle-y", CLUTTER_LINEAR, 5.0,
|
||||
actor, "x", CLUTTER_LINEAR, 0-64.0,
|
||||
actor, "y", CLUTTER_LINEAR, 0-64.0,
|
||||
NULL);
|
||||
|
||||
a_state = clutter_state_new ();
|
||||
g_object_set_data_full (G_OBJECT (actor), "hover-state-machine",
|
||||
a_state, g_object_unref);
|
||||
|
||||
clutter_state_set (a_state, NULL, "normal",
|
||||
actor, "opacity", CLUTTER_LINEAR, 0x77,
|
||||
actor, "rotation-angle-z", CLUTTER_LINEAR, 0.0,
|
||||
NULL);
|
||||
clutter_state_set (a_state, NULL, "hover",
|
||||
actor, "opacity", CLUTTER_LINEAR, 0xff,
|
||||
actor, "rotation-angle-z", CLUTTER_LINEAR, 10.0,
|
||||
NULL);
|
||||
clutter_actor_set_opacity (actor, 0x77);
|
||||
|
||||
clutter_state_set_duration (a_state, NULL, NULL, 500);
|
||||
}
|
||||
|
||||
clutter_state_set_duration (layout_state, NULL, NULL, 1000);
|
||||
clutter_state_set_duration (layout_state, "active", "left", 1400);
|
||||
|
||||
g_signal_connect (layout_state, "completed", G_CALLBACK (completed), NULL);
|
||||
|
||||
clutter_actor_show (stage);
|
||||
|
||||
clutter_state_warp_to_state (layout_state, "left");
|
||||
clutter_state_set_state (layout_state, "active");
|
||||
|
||||
clutter_perf_fps_start (CLUTTER_STAGE (stage));
|
||||
clutter_main ();
|
||||
clutter_perf_fps_report ("test-state-mini");
|
||||
g_object_unref (layout_state);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <gmodule.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include "test-common.h"
|
||||
#include "test-utils.h"
|
||||
|
||||
static gint times = 16;
|
||||
|
||||
#define STAGE_WIDTH 800
|
||||
#define STAGE_HEIGHT 600
|
||||
|
||||
#define ACTOR_WIDTH 64
|
||||
#define ACTOR_HEIGHT 64
|
||||
|
||||
#define COLS (STAGE_WIDTH/ACTOR_WIDTH)
|
||||
#define ROWS (STAGE_HEIGHT/ACTOR_HEIGHT)
|
||||
#define TOTAL (ROWS*COLS)
|
||||
|
||||
|
||||
static void completed (ClutterState *state,
|
||||
gpointer data)
|
||||
{
|
||||
if (g_str_equal (clutter_state_get_state (state), "right"))
|
||||
{
|
||||
/* skip straight to left state when reaching right */
|
||||
clutter_state_warp_to_state (state, "left");
|
||||
}
|
||||
else if (g_str_equal (clutter_state_get_state (state), "active"))
|
||||
clutter_state_set_state (state, "right");
|
||||
else
|
||||
{
|
||||
clutter_state_set_state (state, "active");
|
||||
}
|
||||
times --;
|
||||
if (times <=0)
|
||||
clutter_main_quit ();
|
||||
}
|
||||
|
||||
static ClutterActor *new_rect (gint r,
|
||||
gint g,
|
||||
gint b,
|
||||
gint a)
|
||||
{
|
||||
GError *error = NULL;
|
||||
ClutterColor *color = clutter_color_new (r, g, b, a);
|
||||
ClutterActor *group = clutter_group_new ();
|
||||
ClutterActor *rectangle = clutter_rectangle_new_with_color (color);
|
||||
ClutterActor *hand = NULL;
|
||||
|
||||
gchar *file = g_build_filename (TESTS_DATA_DIR, "redhand.png", NULL);
|
||||
|
||||
hand = clutter_test_utils_create_texture_from_file (file, &error);
|
||||
if (rectangle == NULL)
|
||||
g_error ("image load failed: %s", error->message);
|
||||
g_free (file);
|
||||
clutter_actor_set_size (hand, ACTOR_WIDTH,ACTOR_HEIGHT);
|
||||
|
||||
clutter_actor_set_size (rectangle, ACTOR_WIDTH,ACTOR_HEIGHT);
|
||||
clutter_color_free (color);
|
||||
clutter_container_add (CLUTTER_CONTAINER (group), rectangle, hand, NULL);
|
||||
return group;
|
||||
}
|
||||
|
||||
gint
|
||||
main (gint argc,
|
||||
gchar **argv)
|
||||
{
|
||||
ClutterActor *stage;
|
||||
ClutterState *layout_state;
|
||||
gint i;
|
||||
|
||||
clutter_perf_fps_init ();
|
||||
if (CLUTTER_INIT_SUCCESS != clutter_init (&argc, &argv))
|
||||
g_error ("Failed to initialize Clutter");
|
||||
|
||||
stage = clutter_stage_new ();
|
||||
layout_state = clutter_state_new ();
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), CLUTTER_COLOR_Black);
|
||||
clutter_stage_set_title (CLUTTER_STAGE (stage), "State Performance [pick]");
|
||||
clutter_actor_set_size (stage, STAGE_WIDTH, STAGE_HEIGHT);
|
||||
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
|
||||
|
||||
for (i=0; i<TOTAL; i++)
|
||||
{
|
||||
ClutterActor *actor;
|
||||
ClutterState *a_state;
|
||||
|
||||
int row = i/COLS;
|
||||
int col = i%COLS;
|
||||
|
||||
actor = new_rect (255 * ( 1.0*col/COLS), 50,
|
||||
255 * ( 1.0*row/ROWS), 255);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), actor);
|
||||
clutter_actor_set_position (actor, 320.0, 240.0);
|
||||
clutter_actor_set_reactive (actor, TRUE);
|
||||
|
||||
|
||||
clutter_state_set (layout_state, NULL, "active",
|
||||
actor, "delayed::x", CLUTTER_LINEAR,
|
||||
ACTOR_WIDTH * 1.0 * ((TOTAL-1-i) % COLS),
|
||||
((row*1.0/ROWS))/2, (1.0-(row*1.0/ROWS))/2,
|
||||
actor, "delayed::y", CLUTTER_LINEAR,
|
||||
ACTOR_HEIGHT * 1.0 * ((TOTAL-1-i) / COLS),
|
||||
((row*1.0/ROWS))/2, 0.0,
|
||||
actor, "rotation-angle-x", CLUTTER_LINEAR, 0.0,
|
||||
actor, "rotation-angle-y", CLUTTER_LINEAR, 0.0,
|
||||
NULL);
|
||||
|
||||
clutter_state_set (layout_state, NULL, "right",
|
||||
actor, "delayed::x", CLUTTER_LINEAR, STAGE_WIDTH * 1.0,
|
||||
((row*1.0/ROWS))/2,
|
||||
(1.0-(row*1.0/ROWS))/2,
|
||||
actor, "delayed::y", CLUTTER_LINEAR, STAGE_HEIGHT * 1.0,
|
||||
((row*1.0/ROWS))/2,
|
||||
0.0,
|
||||
NULL);
|
||||
|
||||
clutter_state_set (layout_state, NULL, "left",
|
||||
actor, "rotation-angle-x", CLUTTER_LINEAR, 45.0,
|
||||
actor, "rotation-angle-y", CLUTTER_LINEAR, 5.0,
|
||||
actor, "x", CLUTTER_LINEAR, 0-64.0,
|
||||
actor, "y", CLUTTER_LINEAR, 0-64.0,
|
||||
NULL);
|
||||
|
||||
a_state = clutter_state_new ();
|
||||
g_object_set_data_full (G_OBJECT (actor), "hover-state-machine",
|
||||
a_state, g_object_unref);
|
||||
|
||||
clutter_state_set (a_state, NULL, "normal",
|
||||
actor, "opacity", CLUTTER_LINEAR, 0x77,
|
||||
actor, "rotation-angle-z", CLUTTER_LINEAR, 0.0,
|
||||
NULL);
|
||||
clutter_state_set (a_state, NULL, "hover",
|
||||
actor, "opacity", CLUTTER_LINEAR, 0xff,
|
||||
actor, "rotation-angle-z", CLUTTER_LINEAR, 10.0,
|
||||
NULL);
|
||||
clutter_actor_set_opacity (actor, 0x77);
|
||||
|
||||
clutter_state_set_duration (a_state, NULL, NULL, 500);
|
||||
}
|
||||
|
||||
clutter_state_set_duration (layout_state, NULL, NULL, 1000);
|
||||
clutter_state_set_duration (layout_state, "active", "left", 1400);
|
||||
|
||||
g_signal_connect (layout_state, "completed", G_CALLBACK (completed), NULL);
|
||||
|
||||
clutter_actor_show (stage);
|
||||
|
||||
clutter_state_warp_to_state (layout_state, "left");
|
||||
clutter_state_set_state (layout_state, "active");
|
||||
|
||||
clutter_perf_fake_mouse (CLUTTER_STAGE (stage));
|
||||
clutter_perf_fps_start (CLUTTER_STAGE (stage));
|
||||
clutter_main ();
|
||||
clutter_perf_fps_report ("test-state-pick");
|
||||
g_object_unref (layout_state);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <gmodule.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include "test-common.h"
|
||||
#include "test-utils.h"
|
||||
|
||||
static gint times = 16;
|
||||
|
||||
#define STAGE_WIDTH 800
|
||||
#define STAGE_HEIGHT 600
|
||||
|
||||
#define ACTOR_WIDTH 64
|
||||
#define ACTOR_HEIGHT 64
|
||||
|
||||
#define COLS (STAGE_WIDTH/ACTOR_WIDTH)
|
||||
#define ROWS (STAGE_HEIGHT/ACTOR_HEIGHT)
|
||||
#define TOTAL (ROWS*COLS)
|
||||
|
||||
|
||||
static void completed (ClutterState *state,
|
||||
gpointer data)
|
||||
{
|
||||
if (g_str_equal (clutter_state_get_state (state), "right"))
|
||||
{
|
||||
/* skip straight to left state when reaching right */
|
||||
clutter_state_warp_to_state (state, "left");
|
||||
}
|
||||
else if (g_str_equal (clutter_state_get_state (state), "active"))
|
||||
clutter_state_set_state (state, "right");
|
||||
else
|
||||
{
|
||||
clutter_state_set_state (state, "active");
|
||||
}
|
||||
times --;
|
||||
if (times <=0)
|
||||
clutter_main_quit ();
|
||||
}
|
||||
|
||||
static ClutterActor *new_rect (gint r,
|
||||
gint g,
|
||||
gint b,
|
||||
gint a)
|
||||
{
|
||||
GError *error = NULL;
|
||||
ClutterColor *color = clutter_color_new (r, g, b, a);
|
||||
ClutterActor *group = clutter_group_new ();
|
||||
ClutterActor *rectangle = clutter_rectangle_new_with_color (color);
|
||||
ClutterActor *hand = NULL;
|
||||
|
||||
gchar *file = g_build_filename (TESTS_DATA_DIR, "redhand.png", NULL);
|
||||
|
||||
hand = clutter_test_utils_create_texture_from_file (file, &error);
|
||||
if (rectangle == NULL)
|
||||
g_error ("image load failed: %s", error->message);
|
||||
g_free (file);
|
||||
clutter_actor_set_size (hand, ACTOR_WIDTH,ACTOR_HEIGHT);
|
||||
|
||||
clutter_actor_set_size (rectangle, ACTOR_WIDTH,ACTOR_HEIGHT);
|
||||
clutter_color_free (color);
|
||||
clutter_container_add (CLUTTER_CONTAINER (group), rectangle, hand, NULL);
|
||||
return group;
|
||||
}
|
||||
|
||||
gint
|
||||
main (gint argc,
|
||||
gchar **argv)
|
||||
{
|
||||
ClutterActor *stage;
|
||||
ClutterState *layout_state;
|
||||
gint i;
|
||||
|
||||
clutter_perf_fps_init ();
|
||||
if (CLUTTER_INIT_SUCCESS != clutter_init (&argc, &argv))
|
||||
g_error ("Failed to initialize Clutter");
|
||||
|
||||
stage = clutter_stage_new ();
|
||||
layout_state = clutter_state_new ();
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), CLUTTER_COLOR_Black);
|
||||
clutter_stage_set_title (CLUTTER_STAGE (stage), "State Performance");
|
||||
clutter_actor_set_size (stage, STAGE_WIDTH, STAGE_HEIGHT);
|
||||
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
|
||||
|
||||
for (i=0; i<TOTAL; i++)
|
||||
{
|
||||
ClutterActor *actor;
|
||||
ClutterState *a_state;
|
||||
|
||||
int row = i/COLS;
|
||||
int col = i%COLS;
|
||||
|
||||
actor = new_rect (255 * ( 1.0*col/COLS), 50,
|
||||
255 * ( 1.0*row/ROWS), 255);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), actor);
|
||||
clutter_actor_set_position (actor, 320.0, 240.0);
|
||||
clutter_actor_set_reactive (actor, TRUE);
|
||||
|
||||
|
||||
clutter_state_set (layout_state, NULL, "active",
|
||||
actor, "delayed::x", CLUTTER_LINEAR,
|
||||
ACTOR_WIDTH * 1.0 * ((TOTAL-1-i) % COLS),
|
||||
((row*1.0/ROWS))/2, (1.0-(row*1.0/ROWS))/2,
|
||||
actor, "delayed::y", CLUTTER_LINEAR,
|
||||
ACTOR_HEIGHT * 1.0 * ((TOTAL-1-i) / COLS),
|
||||
((row*1.0/ROWS))/2, 0.0,
|
||||
actor, "rotation-angle-x", CLUTTER_LINEAR, 0.0,
|
||||
actor, "rotation-angle-y", CLUTTER_LINEAR, 0.0,
|
||||
NULL);
|
||||
|
||||
clutter_state_set (layout_state, NULL, "right",
|
||||
actor, "delayed::x", CLUTTER_LINEAR, STAGE_WIDTH * 1.0,
|
||||
((row*1.0/ROWS))/2,
|
||||
(1.0-(row*1.0/ROWS))/2,
|
||||
actor, "delayed::y", CLUTTER_LINEAR, STAGE_HEIGHT * 1.0,
|
||||
((row*1.0/ROWS))/2,
|
||||
0.0,
|
||||
NULL);
|
||||
|
||||
clutter_state_set (layout_state, NULL, "left",
|
||||
actor, "rotation-angle-x", CLUTTER_LINEAR, 45.0,
|
||||
actor, "rotation-angle-y", CLUTTER_LINEAR, 5.0,
|
||||
actor, "x", CLUTTER_LINEAR, 0-64.0,
|
||||
actor, "y", CLUTTER_LINEAR, 0-64.0,
|
||||
NULL);
|
||||
|
||||
a_state = clutter_state_new ();
|
||||
g_object_set_data_full (G_OBJECT (actor), "hover-state-machine",
|
||||
a_state, g_object_unref);
|
||||
|
||||
clutter_state_set (a_state, NULL, "normal",
|
||||
actor, "opacity", CLUTTER_LINEAR, 0x77,
|
||||
actor, "rotation-angle-z", CLUTTER_LINEAR, 0.0,
|
||||
NULL);
|
||||
clutter_state_set (a_state, NULL, "hover",
|
||||
actor, "opacity", CLUTTER_LINEAR, 0xff,
|
||||
actor, "rotation-angle-z", CLUTTER_LINEAR, 10.0,
|
||||
NULL);
|
||||
clutter_actor_set_opacity (actor, 0x77);
|
||||
|
||||
clutter_state_set_duration (a_state, NULL, NULL, 500);
|
||||
}
|
||||
|
||||
clutter_state_set_duration (layout_state, NULL, NULL, 1000);
|
||||
clutter_state_set_duration (layout_state, "active", "left", 1400);
|
||||
|
||||
g_signal_connect (layout_state, "completed", G_CALLBACK (completed), NULL);
|
||||
|
||||
clutter_actor_show (stage);
|
||||
|
||||
clutter_state_warp_to_state (layout_state, "left");
|
||||
clutter_state_set_state (layout_state, "active");
|
||||
|
||||
clutter_perf_fps_start (CLUTTER_STAGE (stage));
|
||||
clutter_main ();
|
||||
clutter_perf_fps_report ("test-state");
|
||||
g_object_unref (layout_state);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -141,6 +141,11 @@ stacking_tests = [
|
||||
'override-redirect',
|
||||
'set-override-redirect-parent',
|
||||
'set-parent-exported',
|
||||
'restore-size',
|
||||
'unmaximize-new-size',
|
||||
'fullscreen-maximize',
|
||||
'restore-position',
|
||||
'default-size',
|
||||
]
|
||||
|
||||
foreach stacking_test: stacking_tests
|
||||
|
||||
@@ -62,22 +62,22 @@ test_transform (void)
|
||||
},
|
||||
{
|
||||
.transform = META_MONITOR_TRANSFORM_NORMAL,
|
||||
.other = -META_MONITOR_TRANSFORM_90,
|
||||
.other = META_MONITOR_TRANSFORM_270,
|
||||
.expect = META_MONITOR_TRANSFORM_270,
|
||||
},
|
||||
{
|
||||
.transform = META_MONITOR_TRANSFORM_FLIPPED,
|
||||
.other = -META_MONITOR_TRANSFORM_90,
|
||||
.other = META_MONITOR_TRANSFORM_270,
|
||||
.expect = META_MONITOR_TRANSFORM_FLIPPED_270,
|
||||
},
|
||||
{
|
||||
.transform = META_MONITOR_TRANSFORM_FLIPPED_180,
|
||||
.other = -META_MONITOR_TRANSFORM_270,
|
||||
.other = META_MONITOR_TRANSFORM_90,
|
||||
.expect = META_MONITOR_TRANSFORM_FLIPPED_270,
|
||||
},
|
||||
{
|
||||
.transform = META_MONITOR_TRANSFORM_FLIPPED_180,
|
||||
.other = -META_MONITOR_TRANSFORM_FLIPPED_180,
|
||||
.other = META_MONITOR_TRANSFORM_FLIPPED_180,
|
||||
.expect = META_MONITOR_TRANSFORM_NORMAL,
|
||||
},
|
||||
};
|
||||
|
||||
36
src/tests/stacking/default-size.metatest
Normal file
36
src/tests/stacking/default-size.metatest
Normal file
@@ -0,0 +1,36 @@
|
||||
new_client x x11
|
||||
create x/1 csd
|
||||
|
||||
resize x/1 300 400
|
||||
show x/1
|
||||
wait
|
||||
|
||||
assert_size x/1 300 400
|
||||
|
||||
resize x/1 200 300
|
||||
wait_reconfigure
|
||||
assert_size x/1 200 300
|
||||
|
||||
hide x/1
|
||||
show x/1
|
||||
wait
|
||||
assert_size x/1 200 300
|
||||
|
||||
|
||||
new_client w wayland
|
||||
create w/1 csd
|
||||
|
||||
resize w/1 300 400
|
||||
show w/1
|
||||
wait
|
||||
|
||||
assert_size w/1 300 400
|
||||
|
||||
resize w/1 200 300
|
||||
wait_reconfigure
|
||||
assert_size w/1 200 300
|
||||
|
||||
hide w/1
|
||||
show w/1
|
||||
wait_reconfigure
|
||||
assert_size w/1 200 300
|
||||
73
src/tests/stacking/fullscreen-maximize.metatest
Normal file
73
src/tests/stacking/fullscreen-maximize.metatest
Normal file
@@ -0,0 +1,73 @@
|
||||
# Tests that the following works, both on Wayland and X11
|
||||
# 1. Create a window with a known size
|
||||
# 2. Maximize window results in maximized size
|
||||
# 3. Fullscreen window results in fullscreen size
|
||||
# 4. Unfullscreen window results in maximized size
|
||||
# 5. Unmaximize window results in original size
|
||||
# 6. Toggling fullscreen ends up with original size
|
||||
|
||||
new_client w wayland
|
||||
create w/1 csd
|
||||
|
||||
resize w/1 500 400
|
||||
show w/1
|
||||
wait
|
||||
|
||||
assert_size w/1 500 400
|
||||
|
||||
maximize w/1
|
||||
wait_reconfigure
|
||||
assert_size w/1 MONITOR_WIDTH MONITOR_HEIGHT
|
||||
|
||||
fullscreen w/1
|
||||
wait_reconfigure
|
||||
assert_size w/1 MONITOR_WIDTH MONITOR_HEIGHT
|
||||
|
||||
unfullscreen w/1
|
||||
wait_reconfigure
|
||||
assert_size w/1 MONITOR_WIDTH MONITOR_HEIGHT
|
||||
|
||||
unmaximize w/1
|
||||
wait_reconfigure
|
||||
assert_size w/1 500 400
|
||||
|
||||
fullscreen w/1
|
||||
wait_reconfigure
|
||||
assert_size w/1 MONITOR_WIDTH MONITOR_HEIGHT
|
||||
|
||||
unfullscreen w/1
|
||||
wait_reconfigure
|
||||
assert_size w/1 500 400
|
||||
|
||||
new_client x x11
|
||||
create x/1 csd
|
||||
|
||||
resize x/1 500 400
|
||||
show x/1
|
||||
wait
|
||||
|
||||
assert_size x/1 500 400
|
||||
|
||||
maximize x/1
|
||||
wait_reconfigure
|
||||
assert_size x/1 MONITOR_WIDTH MONITOR_HEIGHT
|
||||
|
||||
fullscreen x/1
|
||||
wait_reconfigure
|
||||
assert_size x/1 MONITOR_WIDTH MONITOR_HEIGHT
|
||||
|
||||
unfullscreen x/1
|
||||
wait_reconfigure
|
||||
assert_size x/1 MONITOR_WIDTH MONITOR_HEIGHT
|
||||
|
||||
unmaximize x/1
|
||||
wait_reconfigure
|
||||
assert_size x/1 500 400
|
||||
|
||||
fullscreen x/1
|
||||
wait_reconfigure
|
||||
assert_size x/1 MONITOR_WIDTH MONITOR_HEIGHT
|
||||
|
||||
unfullscreen x/1
|
||||
wait_reconfigure
|
||||
assert_size x/1 500 400
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user