Compare commits
	
		
			226 Commits
		
	
	
		
			pwood/fix-
			...
			wip/smcv/c
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					2efd0dfc06 | ||
| 
						 | 
					0b6a3166ed | ||
| 
						 | 
					066bc5986d | ||
| 
						 | 
					e8b09df8d2 | ||
| 
						 | 
					1571f8078a | ||
| 
						 | 
					510cbef15a | ||
| 
						 | 
					99c9a14bc8 | ||
| 
						 | 
					b8003807b0 | ||
| 
						 | 
					8e1bd64e05 | ||
| 
						 | 
					5aa56aa7f5 | ||
| 
						 | 
					c2c4f74923 | ||
| 
						 | 
					f8daa6bc70 | ||
| 
						 | 
					5b07ccd0a7 | ||
| 
						 | 
					ae4d299499 | ||
| 
						 | 
					8798325489 | ||
| 
						 | 
					9e34028742 | ||
| 
						 | 
					258f859e8d | ||
| 
						 | 
					9d3e4fd402 | ||
| 
						 | 
					03c65b93e6 | ||
| 
						 | 
					db975bd2a8 | ||
| 
						 | 
					4e27a4ea1d | ||
| 
						 | 
					346cadeddb | ||
| 
						 | 
					f60c485117 | ||
| 
						 | 
					19550c28f9 | ||
| 
						 | 
					c4949b553d | ||
| 
						 | 
					675a2d13b9 | ||
| 
						 | 
					f4d9953b9c | ||
| 
						 | 
					6db94a0b77 | ||
| 
						 | 
					9bf6faf639 | ||
| 
						 | 
					4434a17d08 | ||
| 
						 | 
					c65f63b647 | ||
| 
						 | 
					79d981aac9 | ||
| 
						 | 
					2791f5b466 | ||
| 
						 | 
					e68bb27df2 | ||
| 
						 | 
					e12b2c417e | ||
| 
						 | 
					0fbda366e8 | ||
| 
						 | 
					106d332c71 | ||
| 
						 | 
					c42c11583d | ||
| 
						 | 
					8c131b32b1 | ||
| 
						 | 
					c8e12ead08 | ||
| 
						 | 
					8a541c08fb | ||
| 
						 | 
					dfed5f6a11 | ||
| 
						 | 
					96dd794fd1 | ||
| 
						 | 
					73a436362a | ||
| 
						 | 
					7343b8d817 | ||
| 
						 | 
					dbf47b652e | ||
| 
						 | 
					b97a6e62a3 | ||
| 
						 | 
					4fac1a4862 | ||
| 
						 | 
					70ba844c3c | ||
| 
						 | 
					bc0b9f7628 | ||
| 
						 | 
					c971d6ea1f | ||
| 
						 | 
					dac09a8e23 | ||
| 
						 | 
					11f224f4b0 | ||
| 
						 | 
					a1be7cdbd7 | ||
| 
						 | 
					82d96aebe1 | ||
| 
						 | 
					c14ba5937f | ||
| 
						 | 
					e50e14af82 | ||
| 
						 | 
					787d9a5a15 | ||
| 
						 | 
					3c29bf7491 | ||
| 
						 | 
					dc8e5c7f8b | ||
| 
						 | 
					0a986fc885 | ||
| 
						 | 
					04e983383f | ||
| 
						 | 
					7ae6e0101c | ||
| 
						 | 
					affb3de829 | ||
| 
						 | 
					24d7a7ad0b | ||
| 
						 | 
					4729cb779e | ||
| 
						 | 
					c8837a8de5 | ||
| 
						 | 
					283cccbe9f | ||
| 
						 | 
					a7bf6322e3 | ||
| 
						 | 
					1d5f9b6917 | ||
| 
						 | 
					3c068ef135 | ||
| 
						 | 
					2becb3dd29 | ||
| 
						 | 
					55f5177fe0 | ||
| 
						 | 
					037b68ab8e | ||
| 
						 | 
					b45d5ef3f5 | ||
| 
						 | 
					7e4e371466 | ||
| 
						 | 
					fbfa136bbb | ||
| 
						 | 
					434845dbe5 | ||
| 
						 | 
					967511be61 | ||
| 
						 | 
					43c7a82461 | ||
| 
						 | 
					066e78c9b3 | ||
| 
						 | 
					08f47fee16 | ||
| 
						 | 
					afe4cd482e | ||
| 
						 | 
					3fed768db4 | ||
| 
						 | 
					8c52b431bb | ||
| 
						 | 
					d9ffbf0576 | ||
| 
						 | 
					b0953b92ba | ||
| 
						 | 
					819f9afa31 | ||
| 
						 | 
					7a0bc5af7f | ||
| 
						 | 
					c5fbab6bad | ||
| 
						 | 
					f4301b77fa | ||
| 
						 | 
					a3f27dfd89 | ||
| 
						 | 
					73ce9c2e81 | ||
| 
						 | 
					fd27c7c444 | ||
| 
						 | 
					a51807fc1e | ||
| 
						 | 
					3c35a78769 | ||
| 
						 | 
					ae7cb7a3bf | ||
| 
						 | 
					531b0ab300 | ||
| 
						 | 
					7cc604b9e5 | ||
| 
						 | 
					f3a65c9b32 | ||
| 
						 | 
					dec97a6541 | ||
| 
						 | 
					cfa2d1abf7 | ||
| 
						 | 
					d9fb6b5ca2 | ||
| 
						 | 
					696b534570 | ||
| 
						 | 
					38db4a5a65 | ||
| 
						 | 
					6f62c5b575 | ||
| 
						 | 
					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 | ||
| 
						 | 
					b7366b5b53 | ||
| 
						 | 
					5e8d8b9ade | ||
| 
						 | 
					4726f3d5d3 | ||
| 
						 | 
					91ef7515de | ||
| 
						 | 
					317f6c0910 | ||
| 
						 | 
					6a3d521466 | ||
| 
						 | 
					1363246d44 | ||
| 
						 | 
					0b6560fac4 | ||
| 
						 | 
					d4c3870286 | ||
| 
						 | 
					4bdf9a1e70 | ||
| 
						 | 
					1909977a67 | ||
| 
						 | 
					655a783891 | ||
| 
						 | 
					a4596becc4 | ||
| 
						 | 
					7015bb3efd | ||
| 
						 | 
					d2c762cc66 | ||
| 
						 | 
					04d429b743 | ||
| 
						 | 
					0b21dcfe08 | ||
| 
						 | 
					7c939d78c2 | ||
| 
						 | 
					8a2b82897d | ||
| 
						 | 
					e95c365cf0 | ||
| 
						 | 
					a32cb7133b | ||
| 
						 | 
					967966cdee | ||
| 
						 | 
					06d67b6abf | ||
| 
						 | 
					f15ce01e2b | ||
| 
						 | 
					e48516679c | ||
| 
						 | 
					65a6c4c361 | ||
| 
						 | 
					b51c468c0f | ||
| 
						 | 
					2e7d02f1ce | ||
| 
						 | 
					dc4fe780f7 | ||
| 
						 | 
					d682cdb078 | ||
| 
						 | 
					ff7a42b8bc | ||
| 
						 | 
					4b1805c306 | ||
| 
						 | 
					03c00e4944 | ||
| 
						 | 
					cb05b16414 | ||
| 
						 | 
					b9fe9c736a | ||
| 
						 | 
					3dd8861fbf | ||
| 
						 | 
					753066598f | ||
| 
						 | 
					3da8c1bfdc | ||
| 
						 | 
					f8ee974628 | ||
| 
						 | 
					f36120757f | ||
| 
						 | 
					bc178b711f | ||
| 
						 | 
					5dad87cfb9 | ||
| 
						 | 
					0f8f607e4c | ||
| 
						 | 
					282aada13a | ||
| 
						 | 
					47002bf0cd | ||
| 
						 | 
					3d47c7edc1 | ||
| 
						 | 
					bc350f37f5 | ||
| 
						 | 
					b55e2e1df9 | ||
| 
						 | 
					43baf643d4 | ||
| 
						 | 
					21b8ae10b8 | ||
| 
						 | 
					425a10de11 | ||
| 
						 | 
					d0ef660ff6 | ||
| 
						 | 
					506e06589b | ||
| 
						 | 
					1d75d5aa2f | ||
| 
						 | 
					645d596f9d | 
@@ -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]
 | 
			
		||||
 
 | 
			
		||||
@@ -33,28 +33,11 @@
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define CLUTTER_TYPE_ACTION             (clutter_action_get_type ())
 | 
			
		||||
#define CLUTTER_ACTION(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ACTION, ClutterAction))
 | 
			
		||||
#define CLUTTER_IS_ACTION(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ACTION))
 | 
			
		||||
#define CLUTTER_ACTION_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ACTION, ClutterActionClass))
 | 
			
		||||
#define CLUTTER_IS_ACTION_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ACTION))
 | 
			
		||||
#define CLUTTER_ACTION_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ACTION, ClutterActionClass))
 | 
			
		||||
#define CLUTTER_TYPE_ACTION (clutter_action_get_type ())
 | 
			
		||||
 | 
			
		||||
typedef struct _ClutterActionClass      ClutterActionClass;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ClutterAction:
 | 
			
		||||
 *
 | 
			
		||||
 * The #ClutterAction structure contains only private data and
 | 
			
		||||
 * should be accessed using the provided API.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.4
 | 
			
		||||
 */
 | 
			
		||||
struct _ClutterAction
 | 
			
		||||
{
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  ClutterActorMeta parent_instance;
 | 
			
		||||
};
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (ClutterAction, clutter_action,
 | 
			
		||||
                          CLUTTER, ACTION, ClutterActorMeta);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ClutterActionClass:
 | 
			
		||||
@@ -78,9 +61,6 @@ struct _ClutterActionClass
 | 
			
		||||
  void (* _clutter_action8) (void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
GType clutter_action_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
/* ClutterActor API */
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void           clutter_actor_add_action            (ClutterActor  *self,
 | 
			
		||||
 
 | 
			
		||||
@@ -81,38 +81,47 @@ static void
 | 
			
		||||
on_actor_destroy (ClutterActor     *actor,
 | 
			
		||||
                  ClutterActorMeta *meta)
 | 
			
		||||
{
 | 
			
		||||
  meta->priv->actor = NULL;
 | 
			
		||||
  ClutterActorMetaPrivate *priv =
 | 
			
		||||
    clutter_actor_meta_get_instance_private (meta);
 | 
			
		||||
 | 
			
		||||
  priv->actor = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_actor_meta_real_set_actor (ClutterActorMeta *meta,
 | 
			
		||||
                                   ClutterActor     *actor)
 | 
			
		||||
{
 | 
			
		||||
  g_warn_if_fail (!meta->priv->actor ||
 | 
			
		||||
                  !CLUTTER_ACTOR_IN_PAINT (meta->priv->actor));
 | 
			
		||||
  ClutterActorMetaPrivate *priv =
 | 
			
		||||
    clutter_actor_meta_get_instance_private (meta);
 | 
			
		||||
 | 
			
		||||
  g_warn_if_fail (!priv->actor ||
 | 
			
		||||
                  !CLUTTER_ACTOR_IN_PAINT (priv->actor));
 | 
			
		||||
  g_warn_if_fail (!actor || !CLUTTER_ACTOR_IN_PAINT (actor));
 | 
			
		||||
 | 
			
		||||
  if (meta->priv->actor == actor)
 | 
			
		||||
  if (priv->actor == actor)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  g_clear_signal_handler (&meta->priv->destroy_id, meta->priv->actor);
 | 
			
		||||
  g_clear_signal_handler (&priv->destroy_id, priv->actor);
 | 
			
		||||
 | 
			
		||||
  meta->priv->actor = actor;
 | 
			
		||||
  priv->actor = actor;
 | 
			
		||||
 | 
			
		||||
  if (meta->priv->actor != NULL)
 | 
			
		||||
    meta->priv->destroy_id = g_signal_connect (meta->priv->actor, "destroy",
 | 
			
		||||
                                               G_CALLBACK (on_actor_destroy),
 | 
			
		||||
                                               meta);
 | 
			
		||||
  if (priv->actor != NULL)
 | 
			
		||||
    priv->destroy_id = g_signal_connect (priv->actor, "destroy",
 | 
			
		||||
                                         G_CALLBACK (on_actor_destroy),
 | 
			
		||||
                                         meta);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_actor_meta_real_set_enabled (ClutterActorMeta *meta,
 | 
			
		||||
                                     gboolean          is_enabled)
 | 
			
		||||
{
 | 
			
		||||
  g_warn_if_fail (!meta->priv->actor ||
 | 
			
		||||
                  !CLUTTER_ACTOR_IN_PAINT (meta->priv->actor));
 | 
			
		||||
  ClutterActorMetaPrivate *priv =
 | 
			
		||||
    clutter_actor_meta_get_instance_private (meta);
 | 
			
		||||
 | 
			
		||||
  meta->priv->is_enabled = is_enabled;
 | 
			
		||||
  g_warn_if_fail (!priv->actor ||
 | 
			
		||||
                  !CLUTTER_ACTOR_IN_PAINT (priv->actor));
 | 
			
		||||
 | 
			
		||||
  priv->is_enabled = is_enabled;
 | 
			
		||||
 | 
			
		||||
  g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_ENABLED]);
 | 
			
		||||
}
 | 
			
		||||
@@ -147,20 +156,21 @@ clutter_actor_meta_get_property (GObject    *gobject,
 | 
			
		||||
                                 GValue     *value,
 | 
			
		||||
                                 GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActorMeta *meta = CLUTTER_ACTOR_META (gobject);
 | 
			
		||||
  ClutterActorMetaPrivate *priv =
 | 
			
		||||
    clutter_actor_meta_get_instance_private (CLUTTER_ACTOR_META (gobject));
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_ACTOR:
 | 
			
		||||
      g_value_set_object (value, meta->priv->actor);
 | 
			
		||||
      g_value_set_object (value, priv->actor);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_NAME:
 | 
			
		||||
      g_value_set_string (value, meta->priv->name);
 | 
			
		||||
      g_value_set_string (value, priv->name);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_ENABLED:
 | 
			
		||||
      g_value_set_boolean (value, meta->priv->is_enabled);
 | 
			
		||||
      g_value_set_boolean (value, priv->is_enabled);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
@@ -172,7 +182,8 @@ clutter_actor_meta_get_property (GObject    *gobject,
 | 
			
		||||
static void
 | 
			
		||||
clutter_actor_meta_finalize (GObject *gobject)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActorMetaPrivate *priv = CLUTTER_ACTOR_META (gobject)->priv;
 | 
			
		||||
  ClutterActorMetaPrivate *priv =
 | 
			
		||||
    clutter_actor_meta_get_instance_private (CLUTTER_ACTOR_META (gobject));
 | 
			
		||||
 | 
			
		||||
  if (priv->actor != NULL)
 | 
			
		||||
    g_clear_signal_handler (&priv->destroy_id, priv->actor);
 | 
			
		||||
@@ -243,9 +254,11 @@ clutter_actor_meta_class_init (ClutterActorMetaClass *klass)
 | 
			
		||||
void
 | 
			
		||||
clutter_actor_meta_init (ClutterActorMeta *self)
 | 
			
		||||
{
 | 
			
		||||
  self->priv = clutter_actor_meta_get_instance_private (self);
 | 
			
		||||
  self->priv->is_enabled = TRUE;
 | 
			
		||||
  self->priv->priority = CLUTTER_ACTOR_META_PRIORITY_DEFAULT;
 | 
			
		||||
  ClutterActorMetaPrivate *priv =
 | 
			
		||||
    clutter_actor_meta_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
  priv->is_enabled = TRUE;
 | 
			
		||||
  priv->priority = CLUTTER_ACTOR_META_PRIORITY_DEFAULT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -263,13 +276,17 @@ void
 | 
			
		||||
clutter_actor_meta_set_name (ClutterActorMeta *meta,
 | 
			
		||||
                             const gchar      *name)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActorMetaPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (CLUTTER_IS_ACTOR_META (meta));
 | 
			
		||||
 | 
			
		||||
  if (g_strcmp0 (meta->priv->name, name) == 0)
 | 
			
		||||
  priv = clutter_actor_meta_get_instance_private (meta);
 | 
			
		||||
 | 
			
		||||
  if (g_strcmp0 (priv->name, name) == 0)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  g_free (meta->priv->name);
 | 
			
		||||
  meta->priv->name = g_strdup (name);
 | 
			
		||||
  g_free (priv->name);
 | 
			
		||||
  priv->name = g_strdup (name);
 | 
			
		||||
 | 
			
		||||
  g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_NAME]);
 | 
			
		||||
}
 | 
			
		||||
@@ -290,9 +307,13 @@ clutter_actor_meta_set_name (ClutterActorMeta *meta,
 | 
			
		||||
const gchar *
 | 
			
		||||
clutter_actor_meta_get_name (ClutterActorMeta *meta)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActorMetaPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), NULL);
 | 
			
		||||
 | 
			
		||||
  return meta->priv->name;
 | 
			
		||||
  priv = clutter_actor_meta_get_instance_private (meta);
 | 
			
		||||
 | 
			
		||||
  return priv->name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -308,11 +329,14 @@ void
 | 
			
		||||
clutter_actor_meta_set_enabled (ClutterActorMeta *meta,
 | 
			
		||||
                                gboolean          is_enabled)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActorMetaPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (CLUTTER_IS_ACTOR_META (meta));
 | 
			
		||||
 | 
			
		||||
  priv = clutter_actor_meta_get_instance_private (meta);
 | 
			
		||||
  is_enabled = !!is_enabled;
 | 
			
		||||
 | 
			
		||||
  if (meta->priv->is_enabled == is_enabled)
 | 
			
		||||
  if (priv->is_enabled == is_enabled)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  CLUTTER_ACTOR_META_GET_CLASS (meta)->set_enabled (meta, is_enabled);
 | 
			
		||||
@@ -331,9 +355,13 @@ clutter_actor_meta_set_enabled (ClutterActorMeta *meta,
 | 
			
		||||
gboolean
 | 
			
		||||
clutter_actor_meta_get_enabled (ClutterActorMeta *meta)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActorMetaPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), FALSE);
 | 
			
		||||
 | 
			
		||||
  return meta->priv->is_enabled;
 | 
			
		||||
  priv = clutter_actor_meta_get_instance_private (meta);
 | 
			
		||||
 | 
			
		||||
  return priv->is_enabled;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@@ -369,40 +397,54 @@ _clutter_actor_meta_set_actor (ClutterActorMeta *meta,
 | 
			
		||||
ClutterActor *
 | 
			
		||||
clutter_actor_meta_get_actor (ClutterActorMeta *meta)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActorMetaPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), NULL);
 | 
			
		||||
 | 
			
		||||
  return meta->priv->actor;
 | 
			
		||||
  priv = clutter_actor_meta_get_instance_private (meta);
 | 
			
		||||
 | 
			
		||||
  return priv->actor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_clutter_actor_meta_set_priority (ClutterActorMeta *meta,
 | 
			
		||||
                                  gint priority)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActorMetaPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (CLUTTER_IS_ACTOR_META (meta));
 | 
			
		||||
 | 
			
		||||
  priv = clutter_actor_meta_get_instance_private (meta);
 | 
			
		||||
 | 
			
		||||
  /* This property shouldn't be modified after the actor meta is in
 | 
			
		||||
     use because ClutterMetaGroup doesn't resort the list when it
 | 
			
		||||
     changes. If we made the priority public then we could either make
 | 
			
		||||
     the priority a construct-only property or listen for
 | 
			
		||||
     notifications on the property from the ClutterMetaGroup and
 | 
			
		||||
     resort. */
 | 
			
		||||
  g_return_if_fail (meta->priv->actor == NULL);
 | 
			
		||||
  g_return_if_fail (priv->actor == NULL);
 | 
			
		||||
 | 
			
		||||
  meta->priv->priority = priority;
 | 
			
		||||
  priv->priority = priority;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gint
 | 
			
		||||
_clutter_actor_meta_get_priority (ClutterActorMeta *meta)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActorMetaPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), 0);
 | 
			
		||||
 | 
			
		||||
  return meta->priv->priority;
 | 
			
		||||
  priv = clutter_actor_meta_get_instance_private (meta);
 | 
			
		||||
 | 
			
		||||
  return priv->priority;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
_clutter_actor_meta_is_internal (ClutterActorMeta *meta)
 | 
			
		||||
{
 | 
			
		||||
  gint priority = meta->priv->priority;
 | 
			
		||||
  ClutterActorMetaPrivate *priv =
 | 
			
		||||
    clutter_actor_meta_get_instance_private (meta);
 | 
			
		||||
  gint priority = priv->priority;
 | 
			
		||||
 | 
			
		||||
  return (priority <= CLUTTER_ACTOR_META_PRIORITY_INTERNAL_LOW ||
 | 
			
		||||
          priority >= CLUTTER_ACTOR_META_PRIORITY_INTERNAL_HIGH);
 | 
			
		||||
@@ -449,19 +491,21 @@ void
 | 
			
		||||
_clutter_meta_group_add_meta (ClutterMetaGroup *group,
 | 
			
		||||
                              ClutterActorMeta *meta)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActorMetaPrivate *priv =
 | 
			
		||||
    clutter_actor_meta_get_instance_private (meta);
 | 
			
		||||
  GList *prev = NULL, *l;
 | 
			
		||||
 | 
			
		||||
  if (meta->priv->actor != NULL)
 | 
			
		||||
  if (priv->actor != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("The meta of type '%s' with name '%s' is "
 | 
			
		||||
                 "already attached to actor '%s'",
 | 
			
		||||
                 G_OBJECT_TYPE_NAME (meta),
 | 
			
		||||
                 meta->priv->name != NULL
 | 
			
		||||
                   ? meta->priv->name
 | 
			
		||||
                 priv->name != NULL
 | 
			
		||||
                   ? priv->name
 | 
			
		||||
                   : "<unknown>",
 | 
			
		||||
                 clutter_actor_get_name (meta->priv->actor) != NULL
 | 
			
		||||
                   ? clutter_actor_get_name (meta->priv->actor)
 | 
			
		||||
                   : G_OBJECT_TYPE_NAME (meta->priv->actor));
 | 
			
		||||
                 clutter_actor_get_name (priv->actor) != NULL
 | 
			
		||||
                   ? clutter_actor_get_name (priv->actor)
 | 
			
		||||
                   : G_OBJECT_TYPE_NAME (priv->actor));
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -497,13 +541,16 @@ void
 | 
			
		||||
_clutter_meta_group_remove_meta (ClutterMetaGroup *group,
 | 
			
		||||
                                 ClutterActorMeta *meta)
 | 
			
		||||
{
 | 
			
		||||
  if (meta->priv->actor != group->actor)
 | 
			
		||||
  ClutterActorMetaPrivate *priv =
 | 
			
		||||
    clutter_actor_meta_get_instance_private (meta);
 | 
			
		||||
 | 
			
		||||
  if (priv->actor != group->actor)
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("The meta of type '%s' with name '%s' is not "
 | 
			
		||||
                 "attached to the actor '%s'",
 | 
			
		||||
                 G_OBJECT_TYPE_NAME (meta),
 | 
			
		||||
                 meta->priv->name != NULL
 | 
			
		||||
                   ? meta->priv->name
 | 
			
		||||
                 priv->name != NULL
 | 
			
		||||
                   ? priv->name
 | 
			
		||||
                   : "<unknown>",
 | 
			
		||||
                 clutter_actor_get_name (group->actor) != NULL
 | 
			
		||||
                   ? clutter_actor_get_name (group->actor)
 | 
			
		||||
@@ -646,8 +693,10 @@ _clutter_meta_group_get_meta (ClutterMetaGroup *group,
 | 
			
		||||
  for (l = group->meta; l != NULL; l = l->next)
 | 
			
		||||
    {
 | 
			
		||||
      ClutterActorMeta *meta = l->data;
 | 
			
		||||
      ClutterActorMetaPrivate *priv =
 | 
			
		||||
        clutter_actor_meta_get_instance_private (meta);
 | 
			
		||||
 | 
			
		||||
      if (g_strcmp0 (meta->priv->name, name) == 0)
 | 
			
		||||
      if (g_strcmp0 (priv->name, name) == 0)
 | 
			
		||||
        return meta;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -667,6 +716,8 @@ _clutter_meta_group_get_meta (ClutterMetaGroup *group,
 | 
			
		||||
const gchar *
 | 
			
		||||
_clutter_actor_meta_get_debug_name (ClutterActorMeta *meta)
 | 
			
		||||
{
 | 
			
		||||
  return meta->priv->name != NULL ? meta->priv->name
 | 
			
		||||
                                  : G_OBJECT_TYPE_NAME (meta);
 | 
			
		||||
  ClutterActorMetaPrivate *priv =
 | 
			
		||||
    clutter_actor_meta_get_instance_private (meta);
 | 
			
		||||
 | 
			
		||||
  return priv->name != NULL ? priv->name : G_OBJECT_TYPE_NAME (meta);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -33,31 +33,13 @@
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define CLUTTER_TYPE_ACTOR_META                 (clutter_actor_meta_get_type ())
 | 
			
		||||
#define CLUTTER_ACTOR_META(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ACTOR_META, ClutterActorMeta))
 | 
			
		||||
#define CLUTTER_IS_ACTOR_META(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ACTOR_META))
 | 
			
		||||
#define CLUTTER_ACTOR_META_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ACTOR_META, ClutterActorMetaClass))
 | 
			
		||||
#define CLUTTER_IS_ACTOR_META_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ACTOR_META))
 | 
			
		||||
#define CLUTTER_ACTOR_META_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ACTOR_META, ClutterActorMetaClass))
 | 
			
		||||
#define CLUTTER_TYPE_ACTOR_META (clutter_actor_meta_get_type ())
 | 
			
		||||
 | 
			
		||||
typedef struct _ClutterActorMetaPrivate         ClutterActorMetaPrivate;
 | 
			
		||||
typedef struct _ClutterActorMetaClass           ClutterActorMetaClass;
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (ClutterActorMeta, clutter_actor_meta,
 | 
			
		||||
                          CLUTTER, ACTOR_META, GInitiallyUnowned);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ClutterActorMeta:
 | 
			
		||||
 *
 | 
			
		||||
 * The #ClutterActorMeta structure contains only
 | 
			
		||||
 * private data and should be accessed using the provided API
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.4
 | 
			
		||||
 */
 | 
			
		||||
struct _ClutterActorMeta
 | 
			
		||||
{
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  GInitiallyUnowned parent_instance;
 | 
			
		||||
 | 
			
		||||
  ClutterActorMetaPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
typedef struct _ClutterActorMetaPrivate ClutterActorMetaPrivate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ClutterActorMetaClass:
 | 
			
		||||
@@ -99,9 +81,6 @@ struct _ClutterActorMetaClass
 | 
			
		||||
  void (* _clutter_meta6) (void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
GType clutter_actor_meta_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void            clutter_actor_meta_set_name     (ClutterActorMeta *meta,
 | 
			
		||||
                                                 const gchar      *name);
 | 
			
		||||
 
 | 
			
		||||
@@ -698,7 +698,6 @@ struct _ClutterActorPrivate
 | 
			
		||||
   * allocation
 | 
			
		||||
   */
 | 
			
		||||
  ClutterActorBox allocation;
 | 
			
		||||
  ClutterAllocationFlags allocation_flags;
 | 
			
		||||
 | 
			
		||||
  /* clip, in actor coordinates */
 | 
			
		||||
  graphene_rect_t clip;
 | 
			
		||||
@@ -854,6 +853,7 @@ struct _ClutterActorPrivate
 | 
			
		||||
  guint needs_paint_volume_update   : 1;
 | 
			
		||||
  guint had_effects_on_last_paint_volume_update : 1;
 | 
			
		||||
  guint needs_compute_resource_scale : 1;
 | 
			
		||||
  guint absolute_origin_changed     : 1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
@@ -1013,7 +1013,6 @@ enum
 | 
			
		||||
  MOTION_EVENT,
 | 
			
		||||
  ENTER_EVENT,
 | 
			
		||||
  LEAVE_EVENT,
 | 
			
		||||
  ALLOCATION_CHANGED,
 | 
			
		||||
  TRANSITIONS_COMPLETED,
 | 
			
		||||
  TOUCH_EVENT,
 | 
			
		||||
  TRANSITION_STOPPED,
 | 
			
		||||
@@ -1198,28 +1197,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 +1220,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 +1572,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 +1586,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 */
 | 
			
		||||
@@ -2593,15 +2576,13 @@ clutter_actor_notify_if_geometry_changed (ClutterActor          *self,
 | 
			
		||||
 * Return value: %TRUE if the allocation of the #ClutterActor has been
 | 
			
		||||
 *   changed, and %FALSE otherwise
 | 
			
		||||
 */
 | 
			
		||||
static inline gboolean
 | 
			
		||||
static inline void
 | 
			
		||||
clutter_actor_set_allocation_internal (ClutterActor           *self,
 | 
			
		||||
                                       const ClutterActorBox  *box,
 | 
			
		||||
                                       ClutterAllocationFlags  flags)
 | 
			
		||||
                                       const ClutterActorBox  *box)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActorPrivate *priv = self->priv;
 | 
			
		||||
  GObject *obj;
 | 
			
		||||
  gboolean x1_changed, y1_changed, x2_changed, y2_changed;
 | 
			
		||||
  gboolean retval;
 | 
			
		||||
  ClutterActorBox old_alloc = { 0, };
 | 
			
		||||
 | 
			
		||||
  obj = G_OBJECT (self);
 | 
			
		||||
@@ -2616,7 +2597,6 @@ clutter_actor_set_allocation_internal (ClutterActor           *self,
 | 
			
		||||
  y2_changed = priv->allocation.y2 != box->y2;
 | 
			
		||||
 | 
			
		||||
  priv->allocation = *box;
 | 
			
		||||
  priv->allocation_flags = flags;
 | 
			
		||||
 | 
			
		||||
  /* allocation is authoritative */
 | 
			
		||||
  priv->needs_width_request = FALSE;
 | 
			
		||||
@@ -2641,88 +2621,37 @@ clutter_actor_set_allocation_internal (ClutterActor           *self,
 | 
			
		||||
          priv->content_box_valid = FALSE;
 | 
			
		||||
          g_object_notify_by_pspec (obj, obj_props[PROP_CONTENT_BOX]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      retval = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    retval = FALSE;
 | 
			
		||||
 | 
			
		||||
  clutter_actor_notify_if_geometry_changed (self, &old_alloc);
 | 
			
		||||
 | 
			
		||||
  g_object_thaw_notify (obj);
 | 
			
		||||
 | 
			
		||||
  return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void clutter_actor_real_allocate (ClutterActor           *self,
 | 
			
		||||
                                         const ClutterActorBox  *box,
 | 
			
		||||
                                         ClutterAllocationFlags  flags);
 | 
			
		||||
 | 
			
		||||
static inline void
 | 
			
		||||
clutter_actor_maybe_layout_children (ClutterActor           *self,
 | 
			
		||||
                                     const ClutterActorBox  *allocation,
 | 
			
		||||
                                     ClutterAllocationFlags  flags)
 | 
			
		||||
static void
 | 
			
		||||
clutter_actor_real_allocate (ClutterActor           *self,
 | 
			
		||||
                             const ClutterActorBox  *box)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActorPrivate *priv = self->priv;
 | 
			
		||||
 | 
			
		||||
  /* this is going to be a bit hard to follow, so let's put an explanation
 | 
			
		||||
   * here.
 | 
			
		||||
   *
 | 
			
		||||
   * we want ClutterActor to have a default layout manager if the actor was
 | 
			
		||||
   * created using "g_object_new (CLUTTER_TYPE_ACTOR, NULL)".
 | 
			
		||||
   *
 | 
			
		||||
   * we also want any subclass of ClutterActor that does not override the
 | 
			
		||||
   * ::allocate() virtual function to delegate to a layout manager.
 | 
			
		||||
   *
 | 
			
		||||
   * finally, we want to allow people subclassing ClutterActor and overriding
 | 
			
		||||
   * the ::allocate() vfunc to let Clutter delegate to the layout manager.
 | 
			
		||||
   *
 | 
			
		||||
   * on the other hand, we want existing actor subclasses overriding the
 | 
			
		||||
   * ::allocate() virtual function and chaining up to the parent's
 | 
			
		||||
   * implementation to continue working without allocating their children
 | 
			
		||||
   * twice, or without entering an allocation loop.
 | 
			
		||||
   *
 | 
			
		||||
   * for the first two points, we check if the class of the actor is
 | 
			
		||||
   * overridding the ::allocate() virtual function; if it isn't, then we
 | 
			
		||||
   * follow through with checking whether we have children and a layout
 | 
			
		||||
   * manager, and eventually calling clutter_layout_manager_allocate().
 | 
			
		||||
   *
 | 
			
		||||
   * for the third point, we check the CLUTTER_DELEGATE_LAYOUT flag in the
 | 
			
		||||
   * allocation flags that we got passed, and if it is present, we continue
 | 
			
		||||
   * with the check above.
 | 
			
		||||
   *
 | 
			
		||||
   * if neither of these two checks yields a positive result, we just
 | 
			
		||||
   * assume that the ::allocate() virtual function that resulted in this
 | 
			
		||||
   * function being called will also allocate the children of the actor.
 | 
			
		||||
  g_object_freeze_notify (G_OBJECT (self));
 | 
			
		||||
 | 
			
		||||
  clutter_actor_set_allocation_internal (self, box);
 | 
			
		||||
 | 
			
		||||
  /* we allocate our children before we notify changes in our geometry,
 | 
			
		||||
   * so that people connecting to properties will be able to get valid
 | 
			
		||||
   * data out of the sub-tree of the scene graph that has this actor at
 | 
			
		||||
   * the root.
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  if (CLUTTER_ACTOR_GET_CLASS (self)->allocate == clutter_actor_real_allocate)
 | 
			
		||||
    goto check_layout;
 | 
			
		||||
 | 
			
		||||
  if ((flags & CLUTTER_DELEGATE_LAYOUT) != 0)
 | 
			
		||||
    goto check_layout;
 | 
			
		||||
 | 
			
		||||
  return;
 | 
			
		||||
 | 
			
		||||
check_layout:
 | 
			
		||||
  if (priv->n_children != 0 &&
 | 
			
		||||
      priv->layout_manager != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      ClutterContainer *container = CLUTTER_CONTAINER (self);
 | 
			
		||||
      ClutterAllocationFlags children_flags;
 | 
			
		||||
      ClutterActorBox children_box;
 | 
			
		||||
 | 
			
		||||
      /* normalize the box passed to the layout manager */
 | 
			
		||||
      children_box.x1 = children_box.y1 = 0.f;
 | 
			
		||||
      children_box.x2 = (allocation->x2 - allocation->x1);
 | 
			
		||||
      children_box.y2 = (allocation->y2 - allocation->y1);
 | 
			
		||||
 | 
			
		||||
      /* remove the DELEGATE_LAYOUT flag; this won't be passed to
 | 
			
		||||
       * the actor's children, since it refers only to the current
 | 
			
		||||
       * actor's allocation.
 | 
			
		||||
       */
 | 
			
		||||
      children_flags = flags;
 | 
			
		||||
      children_flags &= ~CLUTTER_DELEGATE_LAYOUT;
 | 
			
		||||
      children_box.x2 = box->x2 - box->x1;
 | 
			
		||||
      children_box.y2 = box->y2 - box->y1;
 | 
			
		||||
 | 
			
		||||
      CLUTTER_NOTE (LAYOUT,
 | 
			
		||||
                    "Allocating %d children of %s "
 | 
			
		||||
@@ -2730,46 +2659,15 @@ check_layout:
 | 
			
		||||
                    "using %s",
 | 
			
		||||
                    priv->n_children,
 | 
			
		||||
                    _clutter_actor_get_debug_name (self),
 | 
			
		||||
                    allocation->x1,
 | 
			
		||||
                    allocation->y1,
 | 
			
		||||
                    (allocation->x2 - allocation->x1),
 | 
			
		||||
                    (allocation->y2 - allocation->y1),
 | 
			
		||||
                    box->x1,
 | 
			
		||||
                    box->y1,
 | 
			
		||||
                    (box->x2 - box->x1),
 | 
			
		||||
                    (box->y2 - box->y1),
 | 
			
		||||
                    G_OBJECT_TYPE_NAME (priv->layout_manager));
 | 
			
		||||
 | 
			
		||||
      clutter_layout_manager_allocate (priv->layout_manager,
 | 
			
		||||
                                       container,
 | 
			
		||||
                                       &children_box,
 | 
			
		||||
                                       children_flags);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_actor_real_allocate (ClutterActor           *self,
 | 
			
		||||
                             const ClutterActorBox  *box,
 | 
			
		||||
                             ClutterAllocationFlags  flags)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActorPrivate *priv = self->priv;
 | 
			
		||||
  gboolean changed;
 | 
			
		||||
 | 
			
		||||
  g_object_freeze_notify (G_OBJECT (self));
 | 
			
		||||
 | 
			
		||||
  changed = clutter_actor_set_allocation_internal (self, box, flags);
 | 
			
		||||
 | 
			
		||||
  /* we allocate our children before we notify changes in our geometry,
 | 
			
		||||
   * so that people connecting to properties will be able to get valid
 | 
			
		||||
   * data out of the sub-tree of the scene graph that has this actor at
 | 
			
		||||
   * the root.
 | 
			
		||||
   */
 | 
			
		||||
  clutter_actor_maybe_layout_children (self, box, flags);
 | 
			
		||||
 | 
			
		||||
  if (changed)
 | 
			
		||||
    {
 | 
			
		||||
      ClutterActorBox signal_box = priv->allocation;
 | 
			
		||||
      ClutterAllocationFlags signal_flags = priv->allocation_flags;
 | 
			
		||||
 | 
			
		||||
      g_signal_emit (self, actor_signals[ALLOCATION_CHANGED], 0,
 | 
			
		||||
                     &signal_box,
 | 
			
		||||
                     signal_flags);
 | 
			
		||||
                                       CLUTTER_CONTAINER (self),
 | 
			
		||||
                                       &children_box);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_object_thaw_notify (G_OBJECT (self));
 | 
			
		||||
@@ -2808,7 +2706,7 @@ _clutter_actor_propagate_queue_redraw (ClutterActor       *self,
 | 
			
		||||
      if (stop)
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      self = clutter_actor_get_parent (self);
 | 
			
		||||
      self = self->priv->parent;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -3092,96 +2990,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
 | 
			
		||||
@@ -3416,8 +3224,6 @@ _clutter_actor_apply_relative_transformation_matrix (ClutterActor *self,
 | 
			
		||||
                                                     ClutterActor *ancestor,
 | 
			
		||||
                                                     CoglMatrix *matrix)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActor *parent;
 | 
			
		||||
 | 
			
		||||
  /* Note we terminate before ever calling stage->apply_transform()
 | 
			
		||||
   * since that would conceptually be relative to the underlying
 | 
			
		||||
   * window OpenGL coordinates so we'd need a special @ancestor
 | 
			
		||||
@@ -3425,10 +3231,9 @@ _clutter_actor_apply_relative_transformation_matrix (ClutterActor *self,
 | 
			
		||||
  if (self == ancestor)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  parent = clutter_actor_get_parent (self);
 | 
			
		||||
 | 
			
		||||
  if (parent != NULL)
 | 
			
		||||
    _clutter_actor_apply_relative_transformation_matrix (parent, ancestor,
 | 
			
		||||
  if (self->priv->parent != NULL)
 | 
			
		||||
    _clutter_actor_apply_relative_transformation_matrix (self->priv->parent,
 | 
			
		||||
                                                         ancestor,
 | 
			
		||||
                                                         matrix);
 | 
			
		||||
 | 
			
		||||
  _clutter_actor_apply_modelview_transform (self, matrix);
 | 
			
		||||
@@ -4578,8 +4383,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);
 | 
			
		||||
@@ -8715,35 +8519,6 @@ clutter_actor_class_init (ClutterActorClass *klass)
 | 
			
		||||
                  G_TYPE_NONE, 1,
 | 
			
		||||
                  CLUTTER_TYPE_PICK_CONTEXT);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * ClutterActor::allocation-changed:
 | 
			
		||||
   * @actor: the #ClutterActor that emitted the signal
 | 
			
		||||
   * @box: a #ClutterActorBox with the new allocation
 | 
			
		||||
   * @flags: #ClutterAllocationFlags for the allocation
 | 
			
		||||
   *
 | 
			
		||||
   * The ::allocation-changed signal is emitted when the
 | 
			
		||||
   * #ClutterActor:allocation property changes. Usually, application
 | 
			
		||||
   * code should just use the notifications for the :allocation property
 | 
			
		||||
   * but if you want to track the allocation flags as well, for instance
 | 
			
		||||
   * to know whether the absolute origin of @actor changed, then you might
 | 
			
		||||
   * want use this signal instead.
 | 
			
		||||
   *
 | 
			
		||||
   * Since: 1.0
 | 
			
		||||
   */
 | 
			
		||||
  actor_signals[ALLOCATION_CHANGED] =
 | 
			
		||||
    g_signal_new (I_("allocation-changed"),
 | 
			
		||||
                  G_TYPE_FROM_CLASS (object_class),
 | 
			
		||||
                  G_SIGNAL_RUN_LAST,
 | 
			
		||||
                  0,
 | 
			
		||||
                  NULL, NULL,
 | 
			
		||||
                  _clutter_marshal_VOID__BOXED_FLAGS,
 | 
			
		||||
                  G_TYPE_NONE, 2,
 | 
			
		||||
                  CLUTTER_TYPE_ACTOR_BOX | G_SIGNAL_TYPE_STATIC_SCOPE,
 | 
			
		||||
                  CLUTTER_TYPE_ALLOCATION_FLAGS);
 | 
			
		||||
  g_signal_set_va_marshaller (actor_signals[ALLOCATION_CHANGED],
 | 
			
		||||
                              G_TYPE_FROM_CLASS (object_class),
 | 
			
		||||
                              _clutter_marshal_VOID__BOXED_FLAGSv);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * ClutterActor::transitions-completed:
 | 
			
		||||
   * @actor: a #ClutterActor
 | 
			
		||||
@@ -8975,26 +8750,15 @@ static void
 | 
			
		||||
_clutter_actor_get_allocation_clip (ClutterActor *self,
 | 
			
		||||
                                    ClutterActorBox *clip)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActorBox allocation;
 | 
			
		||||
 | 
			
		||||
  /* XXX: we don't care if we get an out of date allocation here
 | 
			
		||||
   * because clutter_actor_queue_redraw_with_clip knows to ignore
 | 
			
		||||
   * the clip if the actor's allocation is invalid.
 | 
			
		||||
   *
 | 
			
		||||
   * This is noted because clutter_actor_get_allocation_box does some
 | 
			
		||||
   * unnecessary work to support buggy code with a comment suggesting
 | 
			
		||||
   * that it could be changed later which would be good for this use
 | 
			
		||||
   * case!
 | 
			
		||||
   */
 | 
			
		||||
  clutter_actor_get_allocation_box (self, &allocation);
 | 
			
		||||
  ClutterActorPrivate *priv = self->priv;
 | 
			
		||||
 | 
			
		||||
  /* NB: clutter_actor_queue_redraw_with_clip expects a box in the
 | 
			
		||||
   * actor's own coordinate space but the allocation is in parent
 | 
			
		||||
   * coordinates */
 | 
			
		||||
  clip->x1 = 0;
 | 
			
		||||
  clip->y1 = 0;
 | 
			
		||||
  clip->x2 = allocation.x2 - allocation.x1;
 | 
			
		||||
  clip->y2 = allocation.y2 - allocation.y1;
 | 
			
		||||
  clip->x2 = priv->allocation.x2 - priv->allocation.x1;
 | 
			
		||||
  clip->y2 = priv->allocation.y2 - priv->allocation.y1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -9083,25 +8847,21 @@ _clutter_actor_queue_redraw_full (ClutterActor             *self,
 | 
			
		||||
  if (CLUTTER_ACTOR_IN_DESTRUCTION (self))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  /* we can ignore unmapped actors, unless they have at least one
 | 
			
		||||
   * mapped clone or they are inside a cloned branch of the scene
 | 
			
		||||
   * graph, as unmapped actors will simply be left unpainted.
 | 
			
		||||
  /* we can ignore unmapped actors, unless they are inside a cloned branch
 | 
			
		||||
   * of the scene graph, as unmapped actors will simply be left unpainted.
 | 
			
		||||
   *
 | 
			
		||||
   * this allows us to ignore redraws queued on leaf nodes when one
 | 
			
		||||
   * of their parents has been hidden
 | 
			
		||||
   */
 | 
			
		||||
  if (!CLUTTER_ACTOR_IS_MAPPED (self) &&
 | 
			
		||||
      self->priv->in_cloned_branch == 0 &&
 | 
			
		||||
      !clutter_actor_has_mapped_clones (self))
 | 
			
		||||
    {
 | 
			
		||||
      CLUTTER_NOTE (PAINT,
 | 
			
		||||
                    "Skipping queue_redraw('%s'): mapped=%s, "
 | 
			
		||||
                    "mapped_clones=%s, "
 | 
			
		||||
                    "in_cloned_branch=%s",
 | 
			
		||||
                    "has_mapped_clones=%s",
 | 
			
		||||
                    _clutter_actor_get_debug_name (self),
 | 
			
		||||
                    CLUTTER_ACTOR_IS_MAPPED (self) ? "yes" : "no",
 | 
			
		||||
                    clutter_actor_has_mapped_clones (self) ? "yes" : "no",
 | 
			
		||||
                    self->priv->in_cloned_branch != 0 ? "yes" : "no");
 | 
			
		||||
                    clutter_actor_has_mapped_clones (self) ? "yes" : "no");
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -10281,8 +10041,7 @@ clutter_actor_adjust_allocation (ClutterActor    *self,
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_actor_allocate_internal (ClutterActor           *self,
 | 
			
		||||
                                 const ClutterActorBox  *allocation,
 | 
			
		||||
                                 ClutterAllocationFlags  flags)
 | 
			
		||||
                                 const ClutterActorBox  *allocation)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActorClass *klass;
 | 
			
		||||
 | 
			
		||||
@@ -10292,7 +10051,7 @@ clutter_actor_allocate_internal (ClutterActor           *self,
 | 
			
		||||
                _clutter_actor_get_debug_name (self));
 | 
			
		||||
 | 
			
		||||
  klass = CLUTTER_ACTOR_GET_CLASS (self);
 | 
			
		||||
  klass->allocate (self, allocation, flags);
 | 
			
		||||
  klass->allocate (self, allocation);
 | 
			
		||||
 | 
			
		||||
  CLUTTER_UNSET_PRIVATE_FLAGS (self, CLUTTER_IN_RELAYOUT);
 | 
			
		||||
 | 
			
		||||
@@ -10305,7 +10064,6 @@ clutter_actor_allocate_internal (ClutterActor           *self,
 | 
			
		||||
 * clutter_actor_allocate:
 | 
			
		||||
 * @self: A #ClutterActor
 | 
			
		||||
 * @box: new allocation of the actor, in parent-relative coordinates
 | 
			
		||||
 * @flags: flags that control the allocation
 | 
			
		||||
 *
 | 
			
		||||
 * Assigns the size of a #ClutterActor from the given @box.
 | 
			
		||||
 *
 | 
			
		||||
@@ -10331,12 +10089,11 @@ clutter_actor_allocate_internal (ClutterActor           *self,
 | 
			
		||||
 * Since: 0.8
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
clutter_actor_allocate (ClutterActor           *self,
 | 
			
		||||
                        const ClutterActorBox  *box,
 | 
			
		||||
                        ClutterAllocationFlags  flags)
 | 
			
		||||
clutter_actor_allocate (ClutterActor          *self,
 | 
			
		||||
                        const ClutterActorBox *box)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActorBox old_allocation, real_allocation;
 | 
			
		||||
  gboolean origin_changed, child_moved, size_changed;
 | 
			
		||||
  gboolean origin_changed, size_changed;
 | 
			
		||||
  gboolean stage_allocation_changed;
 | 
			
		||||
  ClutterActorPrivate *priv;
 | 
			
		||||
 | 
			
		||||
@@ -10379,18 +10136,19 @@ clutter_actor_allocate (ClutterActor           *self,
 | 
			
		||||
  real_allocation.x2 = MAX (real_allocation.x2, real_allocation.x1);
 | 
			
		||||
  real_allocation.y2 = MAX (real_allocation.y2, real_allocation.y1);
 | 
			
		||||
 | 
			
		||||
  origin_changed = (flags & CLUTTER_ABSOLUTE_ORIGIN_CHANGED);
 | 
			
		||||
 | 
			
		||||
  child_moved = (real_allocation.x1 != old_allocation.x1 ||
 | 
			
		||||
                 real_allocation.y1 != old_allocation.y1);
 | 
			
		||||
  origin_changed = (real_allocation.x1 != old_allocation.x1 ||
 | 
			
		||||
                    real_allocation.y1 != old_allocation.y1);
 | 
			
		||||
 | 
			
		||||
  size_changed = (real_allocation.x2 != old_allocation.x2 ||
 | 
			
		||||
                  real_allocation.y2 != old_allocation.y2);
 | 
			
		||||
 | 
			
		||||
  if (origin_changed || child_moved || size_changed)
 | 
			
		||||
    stage_allocation_changed = TRUE;
 | 
			
		||||
  else
 | 
			
		||||
    stage_allocation_changed = FALSE;
 | 
			
		||||
  priv->absolute_origin_changed = priv->parent
 | 
			
		||||
                                ? priv->parent->priv->absolute_origin_changed
 | 
			
		||||
                                : FALSE;
 | 
			
		||||
 | 
			
		||||
  priv->absolute_origin_changed |= origin_changed;
 | 
			
		||||
 | 
			
		||||
  stage_allocation_changed = priv->absolute_origin_changed || size_changed;
 | 
			
		||||
 | 
			
		||||
  /* If we get an allocation "out of the blue"
 | 
			
		||||
   * (we did not queue relayout), then we want to
 | 
			
		||||
@@ -10420,24 +10178,10 @@ clutter_actor_allocate (ClutterActor           *self,
 | 
			
		||||
    {
 | 
			
		||||
      /* If the actor didn't move but needs_allocation is set, we just
 | 
			
		||||
       * need to allocate the children */
 | 
			
		||||
      clutter_actor_allocate_internal (self, &real_allocation, flags);
 | 
			
		||||
      clutter_actor_allocate_internal (self, &real_allocation);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* When ABSOLUTE_ORIGIN_CHANGED is passed in to
 | 
			
		||||
   * clutter_actor_allocate(), it indicates whether the parent has its
 | 
			
		||||
   * absolute origin moved; when passed in to ClutterActor::allocate()
 | 
			
		||||
   * virtual method though, it indicates whether the child has its
 | 
			
		||||
   * absolute origin moved.  So we set it when child_moved is TRUE
 | 
			
		||||
   */
 | 
			
		||||
  if (child_moved)
 | 
			
		||||
    flags |= CLUTTER_ABSOLUTE_ORIGIN_CHANGED;
 | 
			
		||||
 | 
			
		||||
  /* store the flags here, so that they can be propagated by the
 | 
			
		||||
   * transition code
 | 
			
		||||
   */
 | 
			
		||||
  self->priv->allocation_flags = flags;
 | 
			
		||||
 | 
			
		||||
  _clutter_actor_create_transition (self, obj_props[PROP_ALLOCATION],
 | 
			
		||||
                                    &priv->allocation,
 | 
			
		||||
                                    &real_allocation);
 | 
			
		||||
@@ -10447,20 +10191,14 @@ clutter_actor_allocate (ClutterActor           *self,
 | 
			
		||||
 * clutter_actor_set_allocation:
 | 
			
		||||
 * @self: a #ClutterActor
 | 
			
		||||
 * @box: a #ClutterActorBox
 | 
			
		||||
 * @flags: allocation flags
 | 
			
		||||
 *
 | 
			
		||||
 * Stores the allocation of @self as defined by @box.
 | 
			
		||||
 *
 | 
			
		||||
 * This function can only be called from within the implementation of
 | 
			
		||||
 * the #ClutterActorClass.allocate() virtual function.
 | 
			
		||||
 *
 | 
			
		||||
 * The allocation should have been adjusted to take into account constraints,
 | 
			
		||||
 * alignment, and margin properties. If you are implementing a #ClutterActor
 | 
			
		||||
 * subclass that provides its own layout management policy for its children
 | 
			
		||||
 * instead of using a #ClutterLayoutManager delegate, you should not call
 | 
			
		||||
 * this function on the children of @self; instead, you should call
 | 
			
		||||
 * clutter_actor_allocate(), which will adjust the allocation box for
 | 
			
		||||
 * you.
 | 
			
		||||
 * The allocation @box should have been adjusted to take into account
 | 
			
		||||
 * constraints, alignment, and margin properties.
 | 
			
		||||
 *
 | 
			
		||||
 * This function should only be used by subclasses of #ClutterActor
 | 
			
		||||
 * that wish to store their allocation but cannot chain up to the
 | 
			
		||||
@@ -10468,69 +10206,12 @@ clutter_actor_allocate (ClutterActor           *self,
 | 
			
		||||
 * #ClutterActorClass.allocate() virtual function will call this
 | 
			
		||||
 * function.
 | 
			
		||||
 *
 | 
			
		||||
 * It is important to note that, while chaining up was the recommended
 | 
			
		||||
 * behaviour for #ClutterActor subclasses prior to the introduction of
 | 
			
		||||
 * this function, it is recommended to call clutter_actor_set_allocation()
 | 
			
		||||
 * instead.
 | 
			
		||||
 *
 | 
			
		||||
 * If the #ClutterActor is using a #ClutterLayoutManager delegate object
 | 
			
		||||
 * to handle the allocation of its children, this function will call
 | 
			
		||||
 * the clutter_layout_manager_allocate() function only if the
 | 
			
		||||
 * %CLUTTER_DELEGATE_LAYOUT flag is set on @flags, otherwise it is
 | 
			
		||||
 * expected that the subclass will call clutter_layout_manager_allocate()
 | 
			
		||||
 * by itself. For instance, the following code:
 | 
			
		||||
 *
 | 
			
		||||
 * |[<!-- language="C" -->
 | 
			
		||||
 * static void
 | 
			
		||||
 * my_actor_allocate (ClutterActor *actor,
 | 
			
		||||
 *                    const ClutterActorBox *allocation,
 | 
			
		||||
 *                    ClutterAllocationFlags flags)
 | 
			
		||||
 * {
 | 
			
		||||
 *   ClutterActorBox new_alloc;
 | 
			
		||||
 *   ClutterAllocationFlags new_flags;
 | 
			
		||||
 *
 | 
			
		||||
 *   adjust_allocation (allocation, &new_alloc);
 | 
			
		||||
 *
 | 
			
		||||
 *   new_flags = flags | CLUTTER_DELEGATE_LAYOUT;
 | 
			
		||||
 *
 | 
			
		||||
 *   // this will use the layout manager set on the actor
 | 
			
		||||
 *   clutter_actor_set_allocation (actor, &new_alloc, new_flags);
 | 
			
		||||
 * }
 | 
			
		||||
 * ]|
 | 
			
		||||
 *
 | 
			
		||||
 * is equivalent to this:
 | 
			
		||||
 *
 | 
			
		||||
 * |[<!-- language="C" -->
 | 
			
		||||
 * static void
 | 
			
		||||
 * my_actor_allocate (ClutterActor *actor,
 | 
			
		||||
 *                    const ClutterActorBox *allocation,
 | 
			
		||||
 *                    ClutterAllocationFlags flags)
 | 
			
		||||
 * {
 | 
			
		||||
 *   ClutterLayoutManager *layout;
 | 
			
		||||
 *   ClutterActorBox new_alloc;
 | 
			
		||||
 *
 | 
			
		||||
 *   adjust_allocation (allocation, &new_alloc);
 | 
			
		||||
 *
 | 
			
		||||
 *   clutter_actor_set_allocation (actor, &new_alloc, flags);
 | 
			
		||||
 *
 | 
			
		||||
 *   layout = clutter_actor_get_layout_manager (actor);
 | 
			
		||||
 *   clutter_layout_manager_allocate (layout,
 | 
			
		||||
 *                                    CLUTTER_CONTAINER (actor),
 | 
			
		||||
 *                                    &new_alloc,
 | 
			
		||||
 *                                    flags);
 | 
			
		||||
 * }
 | 
			
		||||
 * ]|
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.10
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
clutter_actor_set_allocation (ClutterActor           *self,
 | 
			
		||||
                              const ClutterActorBox  *box,
 | 
			
		||||
                              ClutterAllocationFlags  flags)
 | 
			
		||||
                              const ClutterActorBox  *box)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActorPrivate *priv;
 | 
			
		||||
  gboolean changed;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (CLUTTER_IS_ACTOR (self));
 | 
			
		||||
  g_return_if_fail (box != NULL);
 | 
			
		||||
 | 
			
		||||
@@ -10542,28 +10223,9 @@ clutter_actor_set_allocation (ClutterActor           *self,
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  priv = self->priv;
 | 
			
		||||
 | 
			
		||||
  g_object_freeze_notify (G_OBJECT (self));
 | 
			
		||||
 | 
			
		||||
  changed = clutter_actor_set_allocation_internal (self, box, flags);
 | 
			
		||||
 | 
			
		||||
  /* we allocate our children before we notify changes in our geometry,
 | 
			
		||||
   * so that people connecting to properties will be able to get valid
 | 
			
		||||
   * data out of the sub-tree of the scene graph that has this actor at
 | 
			
		||||
   * the root.
 | 
			
		||||
   */
 | 
			
		||||
  clutter_actor_maybe_layout_children (self, box, flags);
 | 
			
		||||
 | 
			
		||||
  if (changed)
 | 
			
		||||
    {
 | 
			
		||||
      ClutterActorBox signal_box = priv->allocation;
 | 
			
		||||
      ClutterAllocationFlags signal_flags = priv->allocation_flags;
 | 
			
		||||
 | 
			
		||||
      g_signal_emit (self, actor_signals[ALLOCATION_CHANGED], 0,
 | 
			
		||||
                     &signal_box,
 | 
			
		||||
                     signal_flags);
 | 
			
		||||
    }
 | 
			
		||||
  clutter_actor_set_allocation_internal (self, box);
 | 
			
		||||
 | 
			
		||||
  g_object_thaw_notify (G_OBJECT (self));
 | 
			
		||||
}
 | 
			
		||||
@@ -13193,7 +12855,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);
 | 
			
		||||
@@ -15036,9 +14698,7 @@ clutter_actor_set_animatable_property (ClutterActor *actor,
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_ALLOCATION:
 | 
			
		||||
      clutter_actor_allocate_internal (actor,
 | 
			
		||||
                                       g_value_get_boxed (value),
 | 
			
		||||
                                       actor->priv->allocation_flags);
 | 
			
		||||
      clutter_actor_allocate_internal (actor, g_value_get_boxed (value));
 | 
			
		||||
      clutter_actor_queue_redraw (actor);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
@@ -15432,7 +15092,6 @@ clutter_actor_get_stage (ClutterActor *actor)
 | 
			
		||||
 *   actor's natural width
 | 
			
		||||
 * @available_height: the maximum available height, or -1 to use the
 | 
			
		||||
 *   actor's natural height
 | 
			
		||||
 * @flags: flags controlling the allocation
 | 
			
		||||
 *
 | 
			
		||||
 * Allocates @self taking into account the #ClutterActor's
 | 
			
		||||
 * preferred size, but limiting it to the maximum available width
 | 
			
		||||
@@ -15479,7 +15138,7 @@ clutter_actor_get_stage (ClutterActor *actor)
 | 
			
		||||
 *   box.x1 = x; box.y1 = y;
 | 
			
		||||
 *   box.x2 = box.x1 + available_width;
 | 
			
		||||
 *   box.y2 = box.y1 + available_height;
 | 
			
		||||
 *   clutter_actor_allocate (self, &box, flags);
 | 
			
		||||
 *   clutter_actor_allocate (self, &box);
 | 
			
		||||
 * ]|
 | 
			
		||||
 *
 | 
			
		||||
 * This function can be used by fluid layout managers to allocate
 | 
			
		||||
@@ -15493,8 +15152,7 @@ clutter_actor_allocate_available_size (ClutterActor           *self,
 | 
			
		||||
                                       gfloat                  x,
 | 
			
		||||
                                       gfloat                  y,
 | 
			
		||||
                                       gfloat                  available_width,
 | 
			
		||||
                                       gfloat                  available_height,
 | 
			
		||||
                                       ClutterAllocationFlags  flags)
 | 
			
		||||
                                       gfloat                  available_height)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActorPrivate *priv;
 | 
			
		||||
  gfloat width, height;
 | 
			
		||||
@@ -15550,13 +15208,12 @@ clutter_actor_allocate_available_size (ClutterActor           *self,
 | 
			
		||||
  box.y1 = y;
 | 
			
		||||
  box.x2 = box.x1 + width;
 | 
			
		||||
  box.y2 = box.y1 + height;
 | 
			
		||||
  clutter_actor_allocate (self, &box, flags);
 | 
			
		||||
  clutter_actor_allocate (self, &box);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * clutter_actor_allocate_preferred_size:
 | 
			
		||||
 * @self: a #ClutterActor
 | 
			
		||||
 * @flags: flags controlling the allocation
 | 
			
		||||
 *
 | 
			
		||||
 * Allocates the natural size of @self.
 | 
			
		||||
 *
 | 
			
		||||
@@ -15574,8 +15231,7 @@ clutter_actor_allocate_available_size (ClutterActor           *self,
 | 
			
		||||
 * Since: 0.8
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
clutter_actor_allocate_preferred_size (ClutterActor           *self,
 | 
			
		||||
                                       ClutterAllocationFlags  flags)
 | 
			
		||||
clutter_actor_allocate_preferred_size (ClutterActor *self)
 | 
			
		||||
{
 | 
			
		||||
  gfloat actor_x, actor_y;
 | 
			
		||||
  gfloat natural_width, natural_height;
 | 
			
		||||
@@ -15609,7 +15265,7 @@ clutter_actor_allocate_preferred_size (ClutterActor           *self,
 | 
			
		||||
  actor_box.x2 = actor_box.x1 + natural_width;
 | 
			
		||||
  actor_box.y2 = actor_box.y1 + natural_height;
 | 
			
		||||
 | 
			
		||||
  clutter_actor_allocate (self, &actor_box, flags);
 | 
			
		||||
  clutter_actor_allocate (self, &actor_box);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -15620,7 +15276,6 @@ clutter_actor_allocate_preferred_size (ClutterActor           *self,
 | 
			
		||||
 * @y_align: the vertical alignment, between 0 and 1
 | 
			
		||||
 * @x_fill: whether the actor should fill horizontally
 | 
			
		||||
 * @y_fill: whether the actor should fill vertically
 | 
			
		||||
 * @flags: allocation flags to be passed to clutter_actor_allocate()
 | 
			
		||||
 *
 | 
			
		||||
 * Allocates @self by taking into consideration the available allocation
 | 
			
		||||
 * area; an alignment factor on either axis; and whether the actor should
 | 
			
		||||
@@ -15647,8 +15302,7 @@ clutter_actor_allocate_align_fill (ClutterActor           *self,
 | 
			
		||||
                                   gdouble                 x_align,
 | 
			
		||||
                                   gdouble                 y_align,
 | 
			
		||||
                                   gboolean                x_fill,
 | 
			
		||||
                                   gboolean                y_fill,
 | 
			
		||||
                                   ClutterAllocationFlags  flags)
 | 
			
		||||
                                   gboolean                y_fill)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActorPrivate *priv;
 | 
			
		||||
  ClutterActorBox allocation = CLUTTER_ACTOR_BOX_INIT_ZERO;
 | 
			
		||||
@@ -15764,7 +15418,7 @@ out:
 | 
			
		||||
  allocation.x2 = ceilf (allocation.x1 + MAX (child_width, 0));
 | 
			
		||||
  allocation.y2 = ceilf (allocation.y1 + MAX (child_height, 0));
 | 
			
		||||
 | 
			
		||||
  clutter_actor_allocate (self, &allocation, flags);
 | 
			
		||||
  clutter_actor_allocate (self, &allocation);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -19426,7 +19080,6 @@ should_skip_implicit_transition (ClutterActor *self,
 | 
			
		||||
   * when those transitions happen
 | 
			
		||||
   */
 | 
			
		||||
  if (!CLUTTER_ACTOR_IS_MAPPED (self) &&
 | 
			
		||||
      priv->in_cloned_branch == 0 &&
 | 
			
		||||
      !clutter_actor_has_mapped_clones (self))
 | 
			
		||||
    return TRUE;
 | 
			
		||||
 | 
			
		||||
@@ -19960,6 +19613,23 @@ clutter_actor_get_transition (ClutterActor *self,
 | 
			
		||||
  return clos->transition;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * clutter_actor_has_transitions: (skip)
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
clutter_actor_has_transitions (ClutterActor *self)
 | 
			
		||||
{
 | 
			
		||||
  const ClutterAnimationInfo *info;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE);
 | 
			
		||||
 | 
			
		||||
  info = _clutter_actor_get_animation_info_or_defaults (self);
 | 
			
		||||
  if (info->transitions == NULL)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  return g_hash_table_size (info->transitions) > 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * clutter_actor_save_easing_state:
 | 
			
		||||
 * @self: a #ClutterActor
 | 
			
		||||
@@ -21029,31 +20699,41 @@ _clutter_actor_queue_relayout_on_clones (ClutterActor *self)
 | 
			
		||||
 * clutter_actor_has_mapped_clones:
 | 
			
		||||
 * @self: a #ClutterActor
 | 
			
		||||
 *
 | 
			
		||||
 * Returns whether a #ClutterActor has any mapped clones.
 | 
			
		||||
 * Returns whether a #ClutterActor or any parent actors have mapped clones
 | 
			
		||||
 * that are clone-painting @self.
 | 
			
		||||
 *
 | 
			
		||||
 * Return: %TRUE if the actor has mapped clones, and %FALSE otherwise
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.16
 | 
			
		||||
 * Returns: %TRUE if the actor has mapped clones, %FALSE otherwise
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
clutter_actor_has_mapped_clones (ClutterActor *self)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActorPrivate *priv;
 | 
			
		||||
  ClutterActor *actor;
 | 
			
		||||
  GHashTableIter iter;
 | 
			
		||||
  gpointer key;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE);
 | 
			
		||||
 | 
			
		||||
  priv = self->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->clones == NULL)
 | 
			
		||||
  if (self->priv->in_cloned_branch == 0)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  g_hash_table_iter_init (&iter, priv->clones);
 | 
			
		||||
  while (g_hash_table_iter_next (&iter, &key, NULL))
 | 
			
		||||
  for (actor = self; actor; actor = actor->priv->parent)
 | 
			
		||||
    {
 | 
			
		||||
      if (CLUTTER_ACTOR_IS_MAPPED (key))
 | 
			
		||||
        return TRUE;
 | 
			
		||||
      if (actor->priv->clones)
 | 
			
		||||
        {
 | 
			
		||||
          g_hash_table_iter_init (&iter, actor->priv->clones);
 | 
			
		||||
          while (g_hash_table_iter_next (&iter, &key, NULL))
 | 
			
		||||
            {
 | 
			
		||||
              if (CLUTTER_ACTOR_IS_MAPPED (key))
 | 
			
		||||
                return TRUE;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      /* Clones will force-show their own source actor but not children of
 | 
			
		||||
       * it, so if we're hidden and an actor up the hierarchy has a clone,
 | 
			
		||||
       * we won't be visisble.
 | 
			
		||||
       */
 | 
			
		||||
      if (!CLUTTER_ACTOR_IS_VISIBLE (actor))
 | 
			
		||||
        return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
 
 | 
			
		||||
@@ -175,9 +175,12 @@ struct _ClutterActor
 | 
			
		||||
 * @get_preferred_height: virtual function, used when querying the minimum
 | 
			
		||||
 *   and natural heights of an actor for a given width; it is used by
 | 
			
		||||
 *   clutter_actor_get_preferred_height()
 | 
			
		||||
 * @allocate: virtual function, used when settings the coordinates of an
 | 
			
		||||
 *   actor; it is used by clutter_actor_allocate(); it must chain up to
 | 
			
		||||
 *   the parent's implementation, or call clutter_actor_set_allocation()
 | 
			
		||||
 * @allocate: virtual function, used when setting the coordinates of an
 | 
			
		||||
 *   actor; it is used by clutter_actor_allocate(); when overriding this
 | 
			
		||||
 *   function without chaining up, clutter_actor_set_allocation() must be
 | 
			
		||||
 *   called and children must be allocated by the implementation, when
 | 
			
		||||
 *   chaining up though, those things will be done by the parent's
 | 
			
		||||
 *   implementation.
 | 
			
		||||
 * @apply_transform: virtual function, used when applying the transformations
 | 
			
		||||
 *   to an actor before painting it or when transforming coordinates or
 | 
			
		||||
 *   the allocation; it must chain up to the parent's implementation
 | 
			
		||||
@@ -253,8 +256,7 @@ struct _ClutterActorClass
 | 
			
		||||
                                 gfloat                 *min_height_p,
 | 
			
		||||
                                 gfloat                 *natural_height_p);
 | 
			
		||||
  void (* allocate)             (ClutterActor           *self,
 | 
			
		||||
                                 const ClutterActorBox  *box,
 | 
			
		||||
                                 ClutterAllocationFlags  flags);
 | 
			
		||||
                                 const ClutterActorBox  *box);
 | 
			
		||||
 | 
			
		||||
  /* transformations */
 | 
			
		||||
  void (* apply_transform)      (ClutterActor           *actor,
 | 
			
		||||
@@ -415,38 +417,29 @@ void                            clutter_actor_get_preferred_size
 | 
			
		||||
                                                                                 gfloat                      *natural_height_p);
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void                            clutter_actor_allocate                          (ClutterActor                *self,
 | 
			
		||||
                                                                                 const ClutterActorBox       *box,
 | 
			
		||||
                                                                                 ClutterAllocationFlags       flags);
 | 
			
		||||
                                                                                 const ClutterActorBox       *box);
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void                            clutter_actor_allocate_preferred_size           (ClutterActor                *self,
 | 
			
		||||
                                                                                 ClutterAllocationFlags       flags);
 | 
			
		||||
void                            clutter_actor_allocate_preferred_size           (ClutterActor                *self);
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void                            clutter_actor_allocate_available_size           (ClutterActor                *self,
 | 
			
		||||
                                                                                 gfloat                       x,
 | 
			
		||||
                                                                                 gfloat                       y,
 | 
			
		||||
                                                                                 gfloat                       available_width,
 | 
			
		||||
                                                                                 gfloat                       available_height,
 | 
			
		||||
                                                                                 ClutterAllocationFlags       flags);
 | 
			
		||||
                                                                                 gfloat                       available_height);
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void                            clutter_actor_allocate_align_fill               (ClutterActor                *self,
 | 
			
		||||
                                                                                 const ClutterActorBox       *box,
 | 
			
		||||
                                                                                 gdouble                      x_align,
 | 
			
		||||
                                                                                 gdouble                      y_align,
 | 
			
		||||
                                                                                 gboolean                     x_fill,
 | 
			
		||||
                                                                                 gboolean                     y_fill,
 | 
			
		||||
                                                                                 ClutterAllocationFlags       flags);
 | 
			
		||||
                                                                                 gboolean                     y_fill);
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void                            clutter_actor_set_allocation                    (ClutterActor                *self,
 | 
			
		||||
                                                                                 const ClutterActorBox       *box,
 | 
			
		||||
                                                                                 ClutterAllocationFlags       flags);
 | 
			
		||||
                                                                                 const ClutterActorBox       *box);
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void                            clutter_actor_get_allocation_box                (ClutterActor                *self,
 | 
			
		||||
                                                                                 ClutterActorBox             *box);
 | 
			
		||||
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,
 | 
			
		||||
 
 | 
			
		||||
@@ -85,8 +85,7 @@ G_DEFINE_TYPE (ClutterAlignConstraint,
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
source_position_changed (ClutterActor           *actor,
 | 
			
		||||
                         const ClutterActorBox  *allocation,
 | 
			
		||||
                         ClutterAllocationFlags  flags,
 | 
			
		||||
                         GParamSpec             *pspec,
 | 
			
		||||
                         ClutterAlignConstraint *align)
 | 
			
		||||
{
 | 
			
		||||
  if (align->actor != NULL)
 | 
			
		||||
@@ -410,7 +409,7 @@ clutter_align_constraint_set_source (ClutterAlignConstraint *align,
 | 
			
		||||
  align->source = source;
 | 
			
		||||
  if (align->source != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      g_signal_connect (align->source, "allocation-changed",
 | 
			
		||||
      g_signal_connect (align->source, "notify::allocation",
 | 
			
		||||
                        G_CALLBACK (source_position_changed),
 | 
			
		||||
                        align);
 | 
			
		||||
      g_signal_connect (align->source, "destroy",
 | 
			
		||||
 
 | 
			
		||||
@@ -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,
 | 
			
		||||
 
 | 
			
		||||
@@ -30,9 +30,7 @@
 | 
			
		||||
 | 
			
		||||
#ifndef __GI_SCANNER__
 | 
			
		||||
 | 
			
		||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterAction, g_object_unref)
 | 
			
		||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActor, g_object_unref)
 | 
			
		||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActorMeta, g_object_unref)
 | 
			
		||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterAlignConstraint, g_object_unref)
 | 
			
		||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBackend, g_object_unref)
 | 
			
		||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBindConstraint, g_object_unref)
 | 
			
		||||
@@ -43,7 +41,6 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBoxLayout, g_object_unref)
 | 
			
		||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBrightnessContrastEffect, g_object_unref)
 | 
			
		||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterCanvas, g_object_unref)
 | 
			
		||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterChildMeta, g_object_unref)
 | 
			
		||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterClickAction, g_object_unref)
 | 
			
		||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterClone, g_object_unref)
 | 
			
		||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterColorizeEffect, g_object_unref)
 | 
			
		||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterConstraint, g_object_unref)
 | 
			
		||||
@@ -53,7 +50,6 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDesaturateEffect, g_object_unref)
 | 
			
		||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterEffect, g_object_unref)
 | 
			
		||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterFixedLayout, g_object_unref)
 | 
			
		||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterFlowLayout, g_object_unref)
 | 
			
		||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterGestureAction, g_object_unref)
 | 
			
		||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterGridLayout, g_object_unref)
 | 
			
		||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterImage, g_object_unref)
 | 
			
		||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterInputDevice, g_object_unref)
 | 
			
		||||
 
 | 
			
		||||
@@ -406,8 +406,7 @@ get_actor_align_factor (ClutterActorAlign alignment)
 | 
			
		||||
static void
 | 
			
		||||
clutter_bin_layout_allocate (ClutterLayoutManager   *manager,
 | 
			
		||||
                             ClutterContainer       *container,
 | 
			
		||||
                             const ClutterActorBox  *allocation,
 | 
			
		||||
                             ClutterAllocationFlags  flags)
 | 
			
		||||
                             const ClutterActorBox  *allocation)
 | 
			
		||||
{
 | 
			
		||||
  gfloat allocation_x, allocation_y;
 | 
			
		||||
  gfloat available_w, available_h;
 | 
			
		||||
@@ -515,8 +514,7 @@ clutter_bin_layout_allocate (ClutterLayoutManager   *manager,
 | 
			
		||||
 | 
			
		||||
      clutter_actor_allocate_align_fill (child, &child_alloc,
 | 
			
		||||
                                         x_align, y_align,
 | 
			
		||||
                                         x_fill, y_fill,
 | 
			
		||||
                                         flags);
 | 
			
		||||
                                         x_fill, y_fill);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -105,64 +105,6 @@ void                    clutter_box_layout_set_pack_start       (ClutterBoxLayou
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
gboolean                clutter_box_layout_get_pack_start       (ClutterBoxLayout    *layout);
 | 
			
		||||
 | 
			
		||||
CLUTTER_DEPRECATED_FOR(clutter_box_layout_set_orientation)
 | 
			
		||||
void                    clutter_box_layout_set_vertical         (ClutterBoxLayout    *layout,
 | 
			
		||||
                                                                 gboolean             vertical);
 | 
			
		||||
CLUTTER_DEPRECATED_FOR(clutter_box_layout_get_orientation)
 | 
			
		||||
gboolean                clutter_box_layout_get_vertical         (ClutterBoxLayout    *layout);
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void                    clutter_box_layout_pack                 (ClutterBoxLayout    *layout,
 | 
			
		||||
                                                                 ClutterActor        *actor,
 | 
			
		||||
                                                                 gboolean             expand,
 | 
			
		||||
                                                                 gboolean             x_fill,
 | 
			
		||||
                                                                 gboolean             y_fill,
 | 
			
		||||
                                                                 ClutterBoxAlignment  x_align,
 | 
			
		||||
                                                                 ClutterBoxAlignment  y_align);
 | 
			
		||||
CLUTTER_DEPRECATED
 | 
			
		||||
void                    clutter_box_layout_set_alignment        (ClutterBoxLayout    *layout,
 | 
			
		||||
                                                                 ClutterActor        *actor,
 | 
			
		||||
                                                                 ClutterBoxAlignment  x_align,
 | 
			
		||||
                                                                 ClutterBoxAlignment  y_align);
 | 
			
		||||
CLUTTER_DEPRECATED
 | 
			
		||||
void                    clutter_box_layout_get_alignment        (ClutterBoxLayout    *layout,
 | 
			
		||||
                                                                 ClutterActor        *actor,
 | 
			
		||||
                                                                 ClutterBoxAlignment *x_align,
 | 
			
		||||
                                                                 ClutterBoxAlignment *y_align);
 | 
			
		||||
CLUTTER_DEPRECATED
 | 
			
		||||
void                    clutter_box_layout_set_fill             (ClutterBoxLayout    *layout,
 | 
			
		||||
                                                                 ClutterActor        *actor,
 | 
			
		||||
                                                                 gboolean             x_fill,
 | 
			
		||||
                                                                 gboolean             y_fill);
 | 
			
		||||
CLUTTER_DEPRECATED
 | 
			
		||||
void                    clutter_box_layout_get_fill             (ClutterBoxLayout    *layout,
 | 
			
		||||
                                                                 ClutterActor        *actor,
 | 
			
		||||
                                                                 gboolean            *x_fill,
 | 
			
		||||
                                                                 gboolean            *y_fill);
 | 
			
		||||
CLUTTER_DEPRECATED
 | 
			
		||||
void                    clutter_box_layout_set_expand           (ClutterBoxLayout    *layout,
 | 
			
		||||
                                                                 ClutterActor        *actor,
 | 
			
		||||
                                                                 gboolean             expand);
 | 
			
		||||
CLUTTER_DEPRECATED
 | 
			
		||||
gboolean                clutter_box_layout_get_expand           (ClutterBoxLayout    *layout,
 | 
			
		||||
                                                                 ClutterActor        *actor);
 | 
			
		||||
 | 
			
		||||
CLUTTER_DEPRECATED
 | 
			
		||||
void                    clutter_box_layout_set_use_animations   (ClutterBoxLayout    *layout,
 | 
			
		||||
                                                                 gboolean             animate);
 | 
			
		||||
CLUTTER_DEPRECATED
 | 
			
		||||
gboolean                clutter_box_layout_get_use_animations   (ClutterBoxLayout    *layout);
 | 
			
		||||
CLUTTER_DEPRECATED
 | 
			
		||||
void                    clutter_box_layout_set_easing_mode      (ClutterBoxLayout    *layout,
 | 
			
		||||
                                                                 gulong               mode);
 | 
			
		||||
CLUTTER_DEPRECATED
 | 
			
		||||
gulong                  clutter_box_layout_get_easing_mode      (ClutterBoxLayout    *layout);
 | 
			
		||||
CLUTTER_DEPRECATED
 | 
			
		||||
void                    clutter_box_layout_set_easing_duration  (ClutterBoxLayout    *layout,
 | 
			
		||||
                                                                 guint                msecs);
 | 
			
		||||
CLUTTER_DEPRECATED
 | 
			
		||||
guint                   clutter_box_layout_get_easing_duration  (ClutterBoxLayout    *layout);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __CLUTTER_BOX_LAYOUT_H__ */
 | 
			
		||||
 
 | 
			
		||||
@@ -159,7 +159,8 @@ static inline void
 | 
			
		||||
click_action_set_pressed (ClutterClickAction *action,
 | 
			
		||||
                          gboolean            is_pressed)
 | 
			
		||||
{
 | 
			
		||||
  ClutterClickActionPrivate *priv = action->priv;
 | 
			
		||||
  ClutterClickActionPrivate *priv =
 | 
			
		||||
    clutter_click_action_get_instance_private (action);
 | 
			
		||||
 | 
			
		||||
  is_pressed = !!is_pressed;
 | 
			
		||||
 | 
			
		||||
@@ -174,7 +175,8 @@ static inline void
 | 
			
		||||
click_action_set_held (ClutterClickAction *action,
 | 
			
		||||
                       gboolean            is_held)
 | 
			
		||||
{
 | 
			
		||||
  ClutterClickActionPrivate *priv = action->priv;
 | 
			
		||||
  ClutterClickActionPrivate *priv =
 | 
			
		||||
    clutter_click_action_get_instance_private (action);
 | 
			
		||||
 | 
			
		||||
  is_held = !!is_held;
 | 
			
		||||
 | 
			
		||||
@@ -189,7 +191,8 @@ static gboolean
 | 
			
		||||
click_action_emit_long_press (gpointer data)
 | 
			
		||||
{
 | 
			
		||||
  ClutterClickAction *action = data;
 | 
			
		||||
  ClutterClickActionPrivate *priv = action->priv;
 | 
			
		||||
  ClutterClickActionPrivate *priv =
 | 
			
		||||
    clutter_click_action_get_instance_private (action);
 | 
			
		||||
  ClutterActor *actor;
 | 
			
		||||
  gboolean result;
 | 
			
		||||
 | 
			
		||||
@@ -213,7 +216,8 @@ click_action_emit_long_press (gpointer data)
 | 
			
		||||
static inline void
 | 
			
		||||
click_action_query_long_press (ClutterClickAction *action)
 | 
			
		||||
{
 | 
			
		||||
  ClutterClickActionPrivate *priv = action->priv;
 | 
			
		||||
  ClutterClickActionPrivate *priv =
 | 
			
		||||
    clutter_click_action_get_instance_private (action);
 | 
			
		||||
  ClutterActor *actor;
 | 
			
		||||
  gboolean result = FALSE;
 | 
			
		||||
  gint timeout;
 | 
			
		||||
@@ -249,7 +253,8 @@ click_action_query_long_press (ClutterClickAction *action)
 | 
			
		||||
static inline void
 | 
			
		||||
click_action_cancel_long_press (ClutterClickAction *action)
 | 
			
		||||
{
 | 
			
		||||
  ClutterClickActionPrivate *priv = action->priv;
 | 
			
		||||
  ClutterClickActionPrivate *priv =
 | 
			
		||||
    clutter_click_action_get_instance_private (action);
 | 
			
		||||
 | 
			
		||||
  if (priv->long_press_id != 0)
 | 
			
		||||
    {
 | 
			
		||||
@@ -272,7 +277,8 @@ on_event (ClutterActor       *actor,
 | 
			
		||||
          ClutterEvent       *event,
 | 
			
		||||
          ClutterClickAction *action)
 | 
			
		||||
{
 | 
			
		||||
  ClutterClickActionPrivate *priv = action->priv;
 | 
			
		||||
  ClutterClickActionPrivate *priv =
 | 
			
		||||
    clutter_click_action_get_instance_private (action);
 | 
			
		||||
  gboolean has_button = TRUE;
 | 
			
		||||
 | 
			
		||||
  if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (action)))
 | 
			
		||||
@@ -342,7 +348,8 @@ on_captured_event (ClutterActor       *stage,
 | 
			
		||||
                   ClutterEvent       *event,
 | 
			
		||||
                   ClutterClickAction *action)
 | 
			
		||||
{
 | 
			
		||||
  ClutterClickActionPrivate *priv = action->priv;
 | 
			
		||||
  ClutterClickActionPrivate *priv =
 | 
			
		||||
    clutter_click_action_get_instance_private (action);
 | 
			
		||||
  ClutterActor *actor;
 | 
			
		||||
  ClutterModifierType modifier_state;
 | 
			
		||||
  gboolean has_button = TRUE;
 | 
			
		||||
@@ -434,7 +441,8 @@ clutter_click_action_set_actor (ClutterActorMeta *meta,
 | 
			
		||||
                                ClutterActor     *actor)
 | 
			
		||||
{
 | 
			
		||||
  ClutterClickAction *action = CLUTTER_CLICK_ACTION (meta);
 | 
			
		||||
  ClutterClickActionPrivate *priv = action->priv;
 | 
			
		||||
  ClutterClickActionPrivate *priv =
 | 
			
		||||
    clutter_click_action_get_instance_private (action);
 | 
			
		||||
 | 
			
		||||
  if (priv->event_id != 0)
 | 
			
		||||
    {
 | 
			
		||||
@@ -488,7 +496,8 @@ clutter_click_action_set_property (GObject      *gobject,
 | 
			
		||||
                                   const GValue *value,
 | 
			
		||||
                                   GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
  ClutterClickActionPrivate *priv = CLUTTER_CLICK_ACTION (gobject)->priv;
 | 
			
		||||
  ClutterClickActionPrivate *priv =
 | 
			
		||||
    clutter_click_action_get_instance_private (CLUTTER_CLICK_ACTION (gobject));
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
@@ -512,7 +521,8 @@ clutter_click_action_get_property (GObject    *gobject,
 | 
			
		||||
                                   GValue     *value,
 | 
			
		||||
                                   GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  ClutterClickActionPrivate *priv = CLUTTER_CLICK_ACTION (gobject)->priv;
 | 
			
		||||
  ClutterClickActionPrivate *priv =
 | 
			
		||||
    clutter_click_action_get_instance_private (CLUTTER_CLICK_ACTION (gobject));
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
@@ -541,7 +551,8 @@ clutter_click_action_get_property (GObject    *gobject,
 | 
			
		||||
static void
 | 
			
		||||
clutter_click_action_dispose (GObject *gobject)
 | 
			
		||||
{
 | 
			
		||||
  ClutterClickActionPrivate *priv = CLUTTER_CLICK_ACTION (gobject)->priv;
 | 
			
		||||
  ClutterClickActionPrivate *priv =
 | 
			
		||||
    clutter_click_action_get_instance_private (CLUTTER_CLICK_ACTION (gobject));
 | 
			
		||||
 | 
			
		||||
  g_clear_signal_handler (&priv->event_id,
 | 
			
		||||
                          clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (gobject)));
 | 
			
		||||
@@ -699,9 +710,11 @@ clutter_click_action_class_init (ClutterClickActionClass *klass)
 | 
			
		||||
static void
 | 
			
		||||
clutter_click_action_init (ClutterClickAction *self)
 | 
			
		||||
{
 | 
			
		||||
  self->priv = clutter_click_action_get_instance_private (self);
 | 
			
		||||
  self->priv->long_press_threshold = -1;
 | 
			
		||||
  self->priv->long_press_duration = -1;
 | 
			
		||||
  ClutterClickActionPrivate *priv =
 | 
			
		||||
    clutter_click_action_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
  priv->long_press_threshold = -1;
 | 
			
		||||
  priv->long_press_duration = -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -741,7 +754,7 @@ clutter_click_action_release (ClutterClickAction *action)
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (CLUTTER_IS_CLICK_ACTION (action));
 | 
			
		||||
 | 
			
		||||
  priv = action->priv;
 | 
			
		||||
  priv = clutter_click_action_get_instance_private (action);
 | 
			
		||||
 | 
			
		||||
  if (!priv->is_held)
 | 
			
		||||
    return;
 | 
			
		||||
@@ -767,9 +780,13 @@ clutter_click_action_release (ClutterClickAction *action)
 | 
			
		||||
guint
 | 
			
		||||
clutter_click_action_get_button (ClutterClickAction *action)
 | 
			
		||||
{
 | 
			
		||||
  ClutterClickActionPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (CLUTTER_IS_CLICK_ACTION (action), 0);
 | 
			
		||||
 | 
			
		||||
  return action->priv->press_button;
 | 
			
		||||
  priv = clutter_click_action_get_instance_private (action);
 | 
			
		||||
 | 
			
		||||
  return priv->press_button;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -785,9 +802,13 @@ clutter_click_action_get_button (ClutterClickAction *action)
 | 
			
		||||
ClutterModifierType
 | 
			
		||||
clutter_click_action_get_state (ClutterClickAction *action)
 | 
			
		||||
{
 | 
			
		||||
  ClutterClickActionPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (CLUTTER_IS_CLICK_ACTION (action), 0);
 | 
			
		||||
 | 
			
		||||
  return action->priv->modifier_state;
 | 
			
		||||
  priv = clutter_click_action_get_instance_private (action);
 | 
			
		||||
 | 
			
		||||
  return priv->modifier_state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -805,11 +826,15 @@ clutter_click_action_get_coords (ClutterClickAction *action,
 | 
			
		||||
                                 gfloat             *press_x,
 | 
			
		||||
                                 gfloat             *press_y)
 | 
			
		||||
{
 | 
			
		||||
  ClutterClickActionPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (CLUTTER_IS_ACTION (action));
 | 
			
		||||
 | 
			
		||||
  priv = clutter_click_action_get_instance_private (action);
 | 
			
		||||
 | 
			
		||||
  if (press_x != NULL)
 | 
			
		||||
    *press_x = action->priv->press_x;
 | 
			
		||||
    *press_x = priv->press_x;
 | 
			
		||||
 | 
			
		||||
  if (press_y != NULL)
 | 
			
		||||
    *press_y = action->priv->press_y;
 | 
			
		||||
    *press_y = priv->press_y;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -37,32 +37,13 @@
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define CLUTTER_TYPE_CLICK_ACTION               (clutter_click_action_get_type ())
 | 
			
		||||
#define CLUTTER_CLICK_ACTION(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_CLICK_ACTION, ClutterClickAction))
 | 
			
		||||
#define CLUTTER_IS_CLICK_ACTION(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_CLICK_ACTION))
 | 
			
		||||
#define CLUTTER_CLICK_ACTION_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_CLICK_ACTION, ClutterClickActionClass))
 | 
			
		||||
#define CLUTTER_IS_CLICK_ACTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_CLICK_ACTION))
 | 
			
		||||
#define CLUTTER_CLICK_ACTION_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_CLICK_ACTION, ClutterClickActionClass))
 | 
			
		||||
#define CLUTTER_TYPE_CLICK_ACTION (clutter_click_action_get_type ())
 | 
			
		||||
 | 
			
		||||
typedef struct _ClutterClickAction              ClutterClickAction;
 | 
			
		||||
typedef struct _ClutterClickActionPrivate       ClutterClickActionPrivate;
 | 
			
		||||
typedef struct _ClutterClickActionClass         ClutterClickActionClass;
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (ClutterClickAction, clutter_click_action,
 | 
			
		||||
                          CLUTTER, CLICK_ACTION, ClutterAction);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ClutterClickAction:
 | 
			
		||||
 *
 | 
			
		||||
 * The #ClutterClickAction structure contains
 | 
			
		||||
 * only private data and should be accessed using the provided API
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.4
 | 
			
		||||
 */
 | 
			
		||||
struct _ClutterClickAction
 | 
			
		||||
{
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  ClutterAction parent_instance;
 | 
			
		||||
 | 
			
		||||
  ClutterClickActionPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
typedef struct _ClutterClickActionPrivate ClutterClickActionPrivate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ClutterClickActionClass:
 | 
			
		||||
@@ -97,9 +78,6 @@ struct _ClutterClickActionClass
 | 
			
		||||
  void (* _clutter_click_action7) (void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
GType clutter_click_action_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
ClutterAction *        clutter_click_action_new        (void);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -240,15 +240,14 @@ clutter_clone_has_overlaps (ClutterActor *actor)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_clone_allocate (ClutterActor           *self,
 | 
			
		||||
                        const ClutterActorBox  *box,
 | 
			
		||||
                        ClutterAllocationFlags  flags)
 | 
			
		||||
                        const ClutterActorBox  *box)
 | 
			
		||||
{
 | 
			
		||||
  ClutterClonePrivate *priv = CLUTTER_CLONE (self)->priv;
 | 
			
		||||
  ClutterActorClass *parent_class;
 | 
			
		||||
 | 
			
		||||
  /* chain up */
 | 
			
		||||
  parent_class = CLUTTER_ACTOR_CLASS (clutter_clone_parent_class);
 | 
			
		||||
  parent_class->allocate (self, box, flags);
 | 
			
		||||
  parent_class->allocate (self, box);
 | 
			
		||||
 | 
			
		||||
  if (priv->clone_source == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
@@ -258,7 +257,7 @@ clutter_clone_allocate (ClutterActor           *self,
 | 
			
		||||
   */
 | 
			
		||||
  if (clutter_actor_get_parent (priv->clone_source) != NULL &&
 | 
			
		||||
      !clutter_actor_has_allocation (priv->clone_source))
 | 
			
		||||
    clutter_actor_allocate_preferred_size (priv->clone_source, flags);
 | 
			
		||||
    clutter_actor_allocate_preferred_size (priv->clone_source);
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
  /* XXX - this is wrong: ClutterClone cannot clone unparented
 | 
			
		||||
@@ -273,7 +272,7 @@ clutter_clone_allocate (ClutterActor           *self,
 | 
			
		||||
   * paint cycle, we can safely give it as much size as it requires
 | 
			
		||||
   */
 | 
			
		||||
  if (clutter_actor_get_parent (priv->clone_source) == NULL)
 | 
			
		||||
    clutter_actor_allocate_preferred_size (priv->clone_source, flags);
 | 
			
		||||
    clutter_actor_allocate_preferred_size (priv->clone_source);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,13 @@
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
@CLUTTER_CONFIG_DEFINES@
 | 
			
		||||
#mesondefine CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT
 | 
			
		||||
#mesondefine CLUTTER_WINDOWING_X11
 | 
			
		||||
#mesondefine CLUTTER_INPUT_X11
 | 
			
		||||
#mesondefine CLUTTER_WINDOWING_GLX
 | 
			
		||||
#mesondefine CLUTTER_WINDOWING_EGL
 | 
			
		||||
#mesondefine CLUTTER_INPUT_EVDEV
 | 
			
		||||
#mesondefine CLUTTER_INPUT_NULL
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										92
									
								
								clutter/clutter/clutter-damage-history.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								clutter/clutter/clutter-damage-history.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,92 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2007,2008,2009,2010,2011  Intel Corporation.
 | 
			
		||||
 * Copyright (C) 2020 Red Hat Inc
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "clutter-build-config.h"
 | 
			
		||||
 | 
			
		||||
#include "clutter-damage-history.h"
 | 
			
		||||
 | 
			
		||||
#define DAMAGE_HISTORY_LENGTH 0x10
 | 
			
		||||
 | 
			
		||||
struct _ClutterDamageHistory
 | 
			
		||||
{
 | 
			
		||||
  cairo_region_t *damages[DAMAGE_HISTORY_LENGTH];
 | 
			
		||||
  int index;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ClutterDamageHistory *
 | 
			
		||||
clutter_damage_history_new (void)
 | 
			
		||||
{
 | 
			
		||||
  ClutterDamageHistory *history;
 | 
			
		||||
 | 
			
		||||
  history = g_new0 (ClutterDamageHistory, 1);
 | 
			
		||||
 | 
			
		||||
  return history;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_damage_history_free (ClutterDamageHistory *history)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < G_N_ELEMENTS (history->damages); i++)
 | 
			
		||||
    g_clear_pointer (&history->damages[i], cairo_region_destroy);
 | 
			
		||||
 | 
			
		||||
  g_free (history);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
clutter_damage_history_is_age_valid (ClutterDamageHistory *history,
 | 
			
		||||
                                     int                   age)
 | 
			
		||||
{
 | 
			
		||||
  if (age >= DAMAGE_HISTORY_LENGTH ||
 | 
			
		||||
      age < 1)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  if (!clutter_damage_history_lookup (history, age))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_damage_history_record (ClutterDamageHistory *history,
 | 
			
		||||
                               const cairo_region_t *damage)
 | 
			
		||||
{
 | 
			
		||||
  g_clear_pointer (&history->damages[history->index], cairo_region_destroy);
 | 
			
		||||
  history->damages[history->index] = cairo_region_copy (damage);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int
 | 
			
		||||
step_damage_index (int current,
 | 
			
		||||
                   int diff)
 | 
			
		||||
{
 | 
			
		||||
  return (current + diff) & (DAMAGE_HISTORY_LENGTH - 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_damage_history_step (ClutterDamageHistory *history)
 | 
			
		||||
{
 | 
			
		||||
  history->index = step_damage_index (history->index, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const cairo_region_t *
 | 
			
		||||
clutter_damage_history_lookup (ClutterDamageHistory *history,
 | 
			
		||||
                               int                   age)
 | 
			
		||||
{
 | 
			
		||||
  return history->damages[step_damage_index (history->index, -age)];
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								clutter/clutter/clutter-damage-history.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								clutter/clutter/clutter-damage-history.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2007,2008,2009,2010,2011  Intel Corporation.
 | 
			
		||||
 * Copyright (C) 2020 Red Hat Inc
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef CLUTTER_DAMAGE_HISTORY_H
 | 
			
		||||
#define CLUTTER_DAMAGE_HISTORY_H
 | 
			
		||||
 | 
			
		||||
#include <cairo.h>
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
 | 
			
		||||
typedef struct _ClutterDamageHistory ClutterDamageHistory;
 | 
			
		||||
 | 
			
		||||
ClutterDamageHistory * clutter_damage_history_new (void);
 | 
			
		||||
 | 
			
		||||
void clutter_damage_history_free (ClutterDamageHistory *history);
 | 
			
		||||
 | 
			
		||||
gboolean clutter_damage_history_is_age_valid (ClutterDamageHistory *history,
 | 
			
		||||
                                              int                   age);
 | 
			
		||||
 | 
			
		||||
void clutter_damage_history_record (ClutterDamageHistory *history,
 | 
			
		||||
                                    const cairo_region_t *damage);
 | 
			
		||||
 | 
			
		||||
void clutter_damage_history_step (ClutterDamageHistory *history);
 | 
			
		||||
 | 
			
		||||
const cairo_region_t * clutter_damage_history_lookup (ClutterDamageHistory *history,
 | 
			
		||||
                                                      int                   age);
 | 
			
		||||
 | 
			
		||||
#endif /* CLUTTER_DAMAGE_HISTORY_H */
 | 
			
		||||
@@ -128,10 +128,9 @@ clutter_deform_effect_deform_vertex (ClutterDeformEffect *effect,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
vbo_invalidate (ClutterActor           *actor,
 | 
			
		||||
                const ClutterActorBox  *allocation,
 | 
			
		||||
                ClutterAllocationFlags  flags,
 | 
			
		||||
                ClutterDeformEffect    *effect)
 | 
			
		||||
vbo_invalidate (ClutterActor        *actor,
 | 
			
		||||
                GParamSpec          *pspec,
 | 
			
		||||
                ClutterDeformEffect *effect)
 | 
			
		||||
{
 | 
			
		||||
  effect->priv->is_dirty = TRUE;
 | 
			
		||||
}
 | 
			
		||||
@@ -156,7 +155,7 @@ clutter_deform_effect_set_actor (ClutterActorMeta *meta,
 | 
			
		||||
   * changes
 | 
			
		||||
   */
 | 
			
		||||
  if (actor != NULL)
 | 
			
		||||
    priv->allocation_id = g_signal_connect (actor, "allocation-changed",
 | 
			
		||||
    priv->allocation_id = g_signal_connect (actor, "notify::allocation",
 | 
			
		||||
                                            G_CALLBACK (vbo_invalidate),
 | 
			
		||||
                                            meta);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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">
 | 
			
		||||
@@ -554,32 +554,6 @@ typedef enum /*< prefix=CLUTTER_OFFSCREEN_REDIRECT >*/
 | 
			
		||||
  CLUTTER_OFFSCREEN_REDIRECT_ON_IDLE               = 1 << 2
 | 
			
		||||
} ClutterOffscreenRedirect;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ClutterAllocationFlags:
 | 
			
		||||
 * @CLUTTER_ALLOCATION_NONE: No flag set
 | 
			
		||||
 * @CLUTTER_ABSOLUTE_ORIGIN_CHANGED: Whether the absolute origin of the
 | 
			
		||||
 *   actor has changed; this implies that any ancestor of the actor has
 | 
			
		||||
 *   been moved.
 | 
			
		||||
 * @CLUTTER_DELEGATE_LAYOUT: Whether the allocation should be delegated
 | 
			
		||||
 *   to the #ClutterLayoutManager instance stored inside the
 | 
			
		||||
 *   #ClutterActor:layout-manager property of #ClutterActor. This flag
 | 
			
		||||
 *   should only be used if you are subclassing #ClutterActor and
 | 
			
		||||
 *   overriding the #ClutterActorClass.allocate() virtual function, but
 | 
			
		||||
 *   you wish to use the default implementation of the virtual function
 | 
			
		||||
 *   inside #ClutterActor. Added in Clutter 1.10.
 | 
			
		||||
 *
 | 
			
		||||
 * Flags passed to the #ClutterActorClass.allocate() virtual function
 | 
			
		||||
 * and to the clutter_actor_allocate() function.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.0
 | 
			
		||||
 */
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
  CLUTTER_ALLOCATION_NONE         = 0,
 | 
			
		||||
  CLUTTER_ABSOLUTE_ORIGIN_CHANGED = 1 << 1,
 | 
			
		||||
  CLUTTER_DELEGATE_LAYOUT         = 1 << 2
 | 
			
		||||
} ClutterAllocationFlags;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ClutterAlignAxis:
 | 
			
		||||
 * @CLUTTER_ALIGN_X_AXIS: Maintain the alignment on the X axis
 | 
			
		||||
 
 | 
			
		||||
@@ -131,8 +131,7 @@ clutter_fixed_layout_get_preferred_height (ClutterLayoutManager *manager,
 | 
			
		||||
static void
 | 
			
		||||
clutter_fixed_layout_allocate (ClutterLayoutManager   *manager,
 | 
			
		||||
                               ClutterContainer       *container,
 | 
			
		||||
                               const ClutterActorBox  *allocation,
 | 
			
		||||
                               ClutterAllocationFlags  flags)
 | 
			
		||||
                               const ClutterActorBox  *allocation)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActor *child;
 | 
			
		||||
 | 
			
		||||
@@ -140,7 +139,7 @@ clutter_fixed_layout_allocate (ClutterLayoutManager   *manager,
 | 
			
		||||
       child != NULL;
 | 
			
		||||
       child = clutter_actor_get_next_sibling (child))
 | 
			
		||||
    {
 | 
			
		||||
      clutter_actor_allocate_preferred_size (child, flags);
 | 
			
		||||
      clutter_actor_allocate_preferred_size (child);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -566,8 +566,7 @@ clutter_flow_layout_get_preferred_height (ClutterLayoutManager *manager,
 | 
			
		||||
static void
 | 
			
		||||
clutter_flow_layout_allocate (ClutterLayoutManager   *manager,
 | 
			
		||||
                              ClutterContainer       *container,
 | 
			
		||||
                              const ClutterActorBox  *allocation,
 | 
			
		||||
                              ClutterAllocationFlags  flags)
 | 
			
		||||
                              const ClutterActorBox  *allocation)
 | 
			
		||||
{
 | 
			
		||||
  ClutterFlowLayoutPrivate *priv = CLUTTER_FLOW_LAYOUT (manager)->priv;
 | 
			
		||||
  ClutterActor *actor, *child;
 | 
			
		||||
@@ -729,7 +728,7 @@ clutter_flow_layout_allocate (ClutterLayoutManager   *manager,
 | 
			
		||||
      child_alloc.y1 = ceil (item_y);
 | 
			
		||||
      child_alloc.x2 = ceil (child_alloc.x1 + item_width);
 | 
			
		||||
      child_alloc.y2 = ceil (child_alloc.y1 + item_height);
 | 
			
		||||
      clutter_actor_allocate (child, &child_alloc, flags);
 | 
			
		||||
      clutter_actor_allocate (child, &child_alloc);
 | 
			
		||||
 | 
			
		||||
      if (priv->orientation == CLUTTER_FLOW_HORIZONTAL)
 | 
			
		||||
        item_x = new_x;
 | 
			
		||||
 
 | 
			
		||||
@@ -157,7 +157,8 @@ G_DEFINE_TYPE_WITH_PRIVATE (ClutterGestureAction, clutter_gesture_action, CLUTTE
 | 
			
		||||
static GesturePoint *
 | 
			
		||||
gesture_register_point (ClutterGestureAction *action, ClutterEvent *event)
 | 
			
		||||
{
 | 
			
		||||
  ClutterGestureActionPrivate *priv = action->priv;
 | 
			
		||||
  ClutterGestureActionPrivate *priv =
 | 
			
		||||
    clutter_gesture_action_get_instance_private (action);
 | 
			
		||||
  GesturePoint *point = NULL;
 | 
			
		||||
 | 
			
		||||
  if (priv->points->len >= MAX_GESTURE_POINTS)
 | 
			
		||||
@@ -190,7 +191,8 @@ gesture_find_point (ClutterGestureAction *action,
 | 
			
		||||
                    ClutterEvent *event,
 | 
			
		||||
                    gint *position)
 | 
			
		||||
{
 | 
			
		||||
  ClutterGestureActionPrivate *priv = action->priv;
 | 
			
		||||
  ClutterGestureActionPrivate *priv =
 | 
			
		||||
    clutter_gesture_action_get_instance_private (action);
 | 
			
		||||
  GesturePoint *point = NULL;
 | 
			
		||||
  ClutterEventType type = clutter_event_type (event);
 | 
			
		||||
  ClutterInputDevice *device = clutter_event_get_device (event);
 | 
			
		||||
@@ -220,9 +222,10 @@ gesture_find_point (ClutterGestureAction *action,
 | 
			
		||||
static void
 | 
			
		||||
gesture_unregister_point (ClutterGestureAction *action, gint position)
 | 
			
		||||
{
 | 
			
		||||
  ClutterGestureActionPrivate *priv = action->priv;
 | 
			
		||||
  ClutterGestureActionPrivate *priv =
 | 
			
		||||
    clutter_gesture_action_get_instance_private (action);
 | 
			
		||||
 | 
			
		||||
  if (action->priv->points->len == 0)
 | 
			
		||||
  if (priv->points->len == 0)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  g_array_remove_index (priv->points, position);
 | 
			
		||||
@@ -303,7 +306,8 @@ gesture_point_unset (GesturePoint *point)
 | 
			
		||||
static void
 | 
			
		||||
cancel_gesture (ClutterGestureAction *action)
 | 
			
		||||
{
 | 
			
		||||
  ClutterGestureActionPrivate *priv = action->priv;
 | 
			
		||||
  ClutterGestureActionPrivate *priv =
 | 
			
		||||
    clutter_gesture_action_get_instance_private (action);
 | 
			
		||||
  ClutterActor *actor;
 | 
			
		||||
 | 
			
		||||
  priv->in_gesture = FALSE;
 | 
			
		||||
@@ -313,14 +317,15 @@ cancel_gesture (ClutterGestureAction *action)
 | 
			
		||||
  actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
 | 
			
		||||
  g_signal_emit (action, gesture_signals[GESTURE_CANCEL], 0, actor);
 | 
			
		||||
 | 
			
		||||
  g_array_set_size (action->priv->points, 0);
 | 
			
		||||
  g_array_set_size (priv->points, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
begin_gesture (ClutterGestureAction *action,
 | 
			
		||||
               ClutterActor         *actor)
 | 
			
		||||
{
 | 
			
		||||
  ClutterGestureActionPrivate *priv = action->priv;
 | 
			
		||||
  ClutterGestureActionPrivate *priv =
 | 
			
		||||
    clutter_gesture_action_get_instance_private (action);
 | 
			
		||||
  gboolean return_value;
 | 
			
		||||
 | 
			
		||||
  priv->in_gesture = TRUE;
 | 
			
		||||
@@ -353,7 +358,8 @@ stage_captured_event_cb (ClutterActor         *stage,
 | 
			
		||||
                         ClutterEvent         *event,
 | 
			
		||||
                         ClutterGestureAction *action)
 | 
			
		||||
{
 | 
			
		||||
  ClutterGestureActionPrivate *priv = action->priv;
 | 
			
		||||
  ClutterGestureActionPrivate *priv =
 | 
			
		||||
    clutter_gesture_action_get_instance_private (action);
 | 
			
		||||
  ClutterActor *actor;
 | 
			
		||||
  gint position;
 | 
			
		||||
  float threshold_x, threshold_y;
 | 
			
		||||
@@ -488,7 +494,8 @@ actor_captured_event_cb (ClutterActor *actor,
 | 
			
		||||
                         ClutterEvent *event,
 | 
			
		||||
                         ClutterGestureAction *action)
 | 
			
		||||
{
 | 
			
		||||
  ClutterGestureActionPrivate *priv = action->priv;
 | 
			
		||||
  ClutterGestureActionPrivate *priv =
 | 
			
		||||
    clutter_gesture_action_get_instance_private (action);
 | 
			
		||||
  GesturePoint *point G_GNUC_UNUSED;
 | 
			
		||||
 | 
			
		||||
  if ((clutter_event_type (event) != CLUTTER_BUTTON_PRESS) &&
 | 
			
		||||
@@ -522,7 +529,8 @@ static void
 | 
			
		||||
clutter_gesture_action_set_actor (ClutterActorMeta *meta,
 | 
			
		||||
                                  ClutterActor     *actor)
 | 
			
		||||
{
 | 
			
		||||
  ClutterGestureActionPrivate *priv = CLUTTER_GESTURE_ACTION (meta)->priv;
 | 
			
		||||
  ClutterGestureActionPrivate *priv =
 | 
			
		||||
    clutter_gesture_action_get_instance_private (CLUTTER_GESTURE_ACTION (meta));
 | 
			
		||||
  ClutterActorMetaClass *meta_class =
 | 
			
		||||
    CLUTTER_ACTOR_META_CLASS (clutter_gesture_action_parent_class);
 | 
			
		||||
 | 
			
		||||
@@ -563,7 +571,8 @@ clutter_gesture_action_set_enabled (ClutterActorMeta *meta,
 | 
			
		||||
  ClutterActorMetaClass *meta_class =
 | 
			
		||||
    CLUTTER_ACTOR_META_CLASS (clutter_gesture_action_parent_class);
 | 
			
		||||
  ClutterGestureAction *gesture_action = CLUTTER_GESTURE_ACTION (meta);
 | 
			
		||||
  ClutterGestureActionPrivate *priv = gesture_action->priv;
 | 
			
		||||
  ClutterGestureActionPrivate *priv =
 | 
			
		||||
    clutter_gesture_action_get_instance_private (gesture_action);
 | 
			
		||||
 | 
			
		||||
  if (!is_enabled && priv->in_gesture)
 | 
			
		||||
    cancel_gesture (gesture_action);
 | 
			
		||||
@@ -585,6 +594,8 @@ clutter_gesture_action_set_property (GObject      *gobject,
 | 
			
		||||
                                     GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
  ClutterGestureAction *self = CLUTTER_GESTURE_ACTION (gobject);
 | 
			
		||||
  ClutterGestureActionPrivate *priv =
 | 
			
		||||
    clutter_gesture_action_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
@@ -597,11 +608,15 @@ clutter_gesture_action_set_property (GObject      *gobject,
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_THRESHOLD_TRIGGER_DISTANCE_X:
 | 
			
		||||
      clutter_gesture_action_set_threshold_trigger_distance (self, g_value_get_float (value), self->priv->distance_y);
 | 
			
		||||
      clutter_gesture_action_set_threshold_trigger_distance (self,
 | 
			
		||||
                                                             g_value_get_float (value),
 | 
			
		||||
                                                             priv->distance_y);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_THRESHOLD_TRIGGER_DISTANCE_Y:
 | 
			
		||||
      clutter_gesture_action_set_threshold_trigger_distance (self, self->priv->distance_x, g_value_get_float (value));
 | 
			
		||||
      clutter_gesture_action_set_threshold_trigger_distance (self,
 | 
			
		||||
                                                             priv->distance_x,
 | 
			
		||||
                                                             g_value_get_float (value));
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
@@ -616,28 +631,29 @@ clutter_gesture_action_get_property (GObject    *gobject,
 | 
			
		||||
                                     GValue     *value,
 | 
			
		||||
                                     GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  ClutterGestureAction *self = CLUTTER_GESTURE_ACTION (gobject);
 | 
			
		||||
  ClutterGestureActionPrivate *priv =
 | 
			
		||||
    clutter_gesture_action_get_instance_private (CLUTTER_GESTURE_ACTION (gobject));
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_N_TOUCH_POINTS:
 | 
			
		||||
      g_value_set_int (value, self->priv->requested_nb_points);
 | 
			
		||||
      g_value_set_int (value, priv->requested_nb_points);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_THRESHOLD_TRIGGER_EDGE:
 | 
			
		||||
      g_value_set_enum (value, self->priv->edge);
 | 
			
		||||
      g_value_set_enum (value, priv->edge);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_THRESHOLD_TRIGGER_DISTANCE_X:
 | 
			
		||||
      if (self->priv->distance_x > 0.0)
 | 
			
		||||
        g_value_set_float (value, self->priv->distance_x);
 | 
			
		||||
      if (priv->distance_x > 0.0)
 | 
			
		||||
        g_value_set_float (value, priv->distance_x);
 | 
			
		||||
      else
 | 
			
		||||
        g_value_set_float (value, gesture_get_default_threshold ());
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_THRESHOLD_TRIGGER_DISTANCE_Y:
 | 
			
		||||
      if (self->priv->distance_y > 0.0)
 | 
			
		||||
        g_value_set_float (value, self->priv->distance_y);
 | 
			
		||||
      if (priv->distance_y > 0.0)
 | 
			
		||||
        g_value_set_float (value, priv->distance_y);
 | 
			
		||||
      else
 | 
			
		||||
        g_value_set_float (value, gesture_get_default_threshold ());
 | 
			
		||||
      break;
 | 
			
		||||
@@ -651,7 +667,8 @@ clutter_gesture_action_get_property (GObject    *gobject,
 | 
			
		||||
static void
 | 
			
		||||
clutter_gesture_action_finalize (GObject *gobject)
 | 
			
		||||
{
 | 
			
		||||
  ClutterGestureActionPrivate *priv = CLUTTER_GESTURE_ACTION (gobject)->priv;
 | 
			
		||||
  ClutterGestureActionPrivate *priv =
 | 
			
		||||
    clutter_gesture_action_get_instance_private (CLUTTER_GESTURE_ACTION (gobject));
 | 
			
		||||
 | 
			
		||||
  g_array_unref (priv->points);
 | 
			
		||||
 | 
			
		||||
@@ -843,13 +860,14 @@ clutter_gesture_action_class_init (ClutterGestureActionClass *klass)
 | 
			
		||||
static void
 | 
			
		||||
clutter_gesture_action_init (ClutterGestureAction *self)
 | 
			
		||||
{
 | 
			
		||||
  self->priv = clutter_gesture_action_get_instance_private (self);
 | 
			
		||||
  ClutterGestureActionPrivate *priv =
 | 
			
		||||
    clutter_gesture_action_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
  self->priv->points = g_array_sized_new (FALSE, TRUE, sizeof (GesturePoint), 3);
 | 
			
		||||
  g_array_set_clear_func (self->priv->points, (GDestroyNotify) gesture_point_unset);
 | 
			
		||||
  priv->points = g_array_sized_new (FALSE, TRUE, sizeof (GesturePoint), 3);
 | 
			
		||||
  g_array_set_clear_func (priv->points, (GDestroyNotify) gesture_point_unset);
 | 
			
		||||
 | 
			
		||||
  self->priv->requested_nb_points = 1;
 | 
			
		||||
  self->priv->edge = CLUTTER_GESTURE_TRIGGER_EDGE_NONE;
 | 
			
		||||
  priv->requested_nb_points = 1;
 | 
			
		||||
  priv->edge = CLUTTER_GESTURE_TRIGGER_EDGE_NONE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -888,16 +906,21 @@ clutter_gesture_action_get_press_coords (ClutterGestureAction *action,
 | 
			
		||||
                                         gfloat               *press_x,
 | 
			
		||||
                                         gfloat               *press_y)
 | 
			
		||||
{
 | 
			
		||||
  ClutterGestureActionPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action));
 | 
			
		||||
  g_return_if_fail (action->priv->points->len > point);
 | 
			
		||||
 | 
			
		||||
  priv = clutter_gesture_action_get_instance_private (action);
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (priv->points->len > point);
 | 
			
		||||
 | 
			
		||||
  if (press_x)
 | 
			
		||||
    *press_x = g_array_index (action->priv->points,
 | 
			
		||||
    *press_x = g_array_index (priv->points,
 | 
			
		||||
                              GesturePoint,
 | 
			
		||||
                              point).press_x;
 | 
			
		||||
 | 
			
		||||
  if (press_y)
 | 
			
		||||
    *press_y = g_array_index (action->priv->points,
 | 
			
		||||
    *press_y = g_array_index (priv->points,
 | 
			
		||||
                              GesturePoint,
 | 
			
		||||
                              point).press_y;
 | 
			
		||||
}
 | 
			
		||||
@@ -923,16 +946,21 @@ clutter_gesture_action_get_motion_coords (ClutterGestureAction *action,
 | 
			
		||||
                                          gfloat               *motion_x,
 | 
			
		||||
                                          gfloat               *motion_y)
 | 
			
		||||
{
 | 
			
		||||
  ClutterGestureActionPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action));
 | 
			
		||||
  g_return_if_fail (action->priv->points->len > point);
 | 
			
		||||
 | 
			
		||||
  priv = clutter_gesture_action_get_instance_private (action);
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (priv->points->len > point);
 | 
			
		||||
 | 
			
		||||
  if (motion_x)
 | 
			
		||||
    *motion_x = g_array_index (action->priv->points,
 | 
			
		||||
    *motion_x = g_array_index (priv->points,
 | 
			
		||||
                               GesturePoint,
 | 
			
		||||
                               point).last_motion_x;
 | 
			
		||||
 | 
			
		||||
  if (motion_y)
 | 
			
		||||
    *motion_y = g_array_index (action->priv->points,
 | 
			
		||||
    *motion_y = g_array_index (priv->points,
 | 
			
		||||
                               GesturePoint,
 | 
			
		||||
                               point).last_motion_y;
 | 
			
		||||
}
 | 
			
		||||
@@ -960,15 +988,19 @@ clutter_gesture_action_get_motion_delta (ClutterGestureAction *action,
 | 
			
		||||
                                         gfloat               *delta_x,
 | 
			
		||||
                                         gfloat               *delta_y)
 | 
			
		||||
{
 | 
			
		||||
  ClutterGestureActionPrivate *priv;
 | 
			
		||||
  gfloat d_x, d_y;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), 0);
 | 
			
		||||
  g_return_val_if_fail (action->priv->points->len > point, 0);
 | 
			
		||||
 | 
			
		||||
  d_x = g_array_index (action->priv->points,
 | 
			
		||||
  priv = clutter_gesture_action_get_instance_private (action);
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (priv->points->len > point, 0);
 | 
			
		||||
 | 
			
		||||
  d_x = g_array_index (priv->points,
 | 
			
		||||
                       GesturePoint,
 | 
			
		||||
                       point).last_delta_x;
 | 
			
		||||
  d_y = g_array_index (action->priv->points,
 | 
			
		||||
  d_y = g_array_index (priv->points,
 | 
			
		||||
                       GesturePoint,
 | 
			
		||||
                       point).last_delta_y;
 | 
			
		||||
 | 
			
		||||
@@ -1002,16 +1034,21 @@ clutter_gesture_action_get_release_coords (ClutterGestureAction *action,
 | 
			
		||||
                                           gfloat               *release_x,
 | 
			
		||||
                                           gfloat               *release_y)
 | 
			
		||||
{
 | 
			
		||||
  ClutterGestureActionPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action));
 | 
			
		||||
  g_return_if_fail (action->priv->points->len > point);
 | 
			
		||||
 | 
			
		||||
  priv = clutter_gesture_action_get_instance_private (action);
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (priv->points->len > point);
 | 
			
		||||
 | 
			
		||||
  if (release_x)
 | 
			
		||||
    *release_x = g_array_index (action->priv->points,
 | 
			
		||||
    *release_x = g_array_index (priv->points,
 | 
			
		||||
                                GesturePoint,
 | 
			
		||||
                                point).release_x;
 | 
			
		||||
 | 
			
		||||
  if (release_y)
 | 
			
		||||
    *release_y = g_array_index (action->priv->points,
 | 
			
		||||
    *release_y = g_array_index (priv->points,
 | 
			
		||||
                                GesturePoint,
 | 
			
		||||
                                point).release_y;
 | 
			
		||||
}
 | 
			
		||||
@@ -1037,16 +1074,20 @@ clutter_gesture_action_get_velocity (ClutterGestureAction *action,
 | 
			
		||||
                                     gfloat               *velocity_x,
 | 
			
		||||
                                     gfloat               *velocity_y)
 | 
			
		||||
{
 | 
			
		||||
  ClutterGestureActionPrivate *priv;
 | 
			
		||||
  gfloat d_x, d_y, distance, velocity;
 | 
			
		||||
  gint64 d_t;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), 0);
 | 
			
		||||
  g_return_val_if_fail (action->priv->points->len > point, 0);
 | 
			
		||||
 | 
			
		||||
  priv = clutter_gesture_action_get_instance_private (action);
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (priv->points->len > point, 0);
 | 
			
		||||
 | 
			
		||||
  distance = clutter_gesture_action_get_motion_delta (action, point,
 | 
			
		||||
                                                      &d_x, &d_y);
 | 
			
		||||
 | 
			
		||||
  d_t = g_array_index (action->priv->points,
 | 
			
		||||
  d_t = g_array_index (priv->points,
 | 
			
		||||
                       GesturePoint,
 | 
			
		||||
                       point).last_delta_time;
 | 
			
		||||
 | 
			
		||||
@@ -1073,9 +1114,13 @@ clutter_gesture_action_get_velocity (ClutterGestureAction *action,
 | 
			
		||||
gint
 | 
			
		||||
clutter_gesture_action_get_n_touch_points (ClutterGestureAction *action)
 | 
			
		||||
{
 | 
			
		||||
  ClutterGestureActionPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), 0);
 | 
			
		||||
 | 
			
		||||
  return action->priv->requested_nb_points;
 | 
			
		||||
  priv = clutter_gesture_action_get_instance_private (action);
 | 
			
		||||
 | 
			
		||||
  return priv->requested_nb_points;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -1096,7 +1141,7 @@ clutter_gesture_action_set_n_touch_points (ClutterGestureAction *action,
 | 
			
		||||
  g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action));
 | 
			
		||||
  g_return_if_fail (nb_points >= 1);
 | 
			
		||||
 | 
			
		||||
  priv = action->priv;
 | 
			
		||||
  priv = clutter_gesture_action_get_instance_private (action);
 | 
			
		||||
 | 
			
		||||
  if (priv->requested_nb_points == nb_points)
 | 
			
		||||
    return;
 | 
			
		||||
@@ -1150,9 +1195,13 @@ clutter_gesture_action_set_n_touch_points (ClutterGestureAction *action,
 | 
			
		||||
guint
 | 
			
		||||
clutter_gesture_action_get_n_current_points (ClutterGestureAction *action)
 | 
			
		||||
{
 | 
			
		||||
  ClutterGestureActionPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), 0);
 | 
			
		||||
 | 
			
		||||
  return action->priv->points->len;
 | 
			
		||||
  priv = clutter_gesture_action_get_instance_private (action);
 | 
			
		||||
 | 
			
		||||
  return priv->points->len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -1170,10 +1219,15 @@ ClutterEventSequence *
 | 
			
		||||
clutter_gesture_action_get_sequence (ClutterGestureAction *action,
 | 
			
		||||
                                     guint                 point)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), NULL);
 | 
			
		||||
  g_return_val_if_fail (action->priv->points->len > point, NULL);
 | 
			
		||||
  ClutterGestureActionPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  return g_array_index (action->priv->points, GesturePoint, point).sequence;
 | 
			
		||||
  g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), NULL);
 | 
			
		||||
 | 
			
		||||
  priv = clutter_gesture_action_get_instance_private (action);
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (priv->points->len > point, NULL);
 | 
			
		||||
 | 
			
		||||
  return g_array_index (priv->points, GesturePoint, point).sequence;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -1192,10 +1246,15 @@ ClutterInputDevice *
 | 
			
		||||
clutter_gesture_action_get_device (ClutterGestureAction *action,
 | 
			
		||||
                                   guint                 point)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), NULL);
 | 
			
		||||
  g_return_val_if_fail (action->priv->points->len > point, NULL);
 | 
			
		||||
  ClutterGestureActionPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  return g_array_index (action->priv->points, GesturePoint, point).device;
 | 
			
		||||
  g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), NULL);
 | 
			
		||||
 | 
			
		||||
  priv = clutter_gesture_action_get_instance_private (action);
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (priv->points->len > point, NULL);
 | 
			
		||||
 | 
			
		||||
  return g_array_index (priv->points, GesturePoint, point).device;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -1215,11 +1274,15 @@ clutter_gesture_action_get_last_event (ClutterGestureAction *action,
 | 
			
		||||
                                       guint                 point)
 | 
			
		||||
{
 | 
			
		||||
  GesturePoint *gesture_point;
 | 
			
		||||
  ClutterGestureActionPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), NULL);
 | 
			
		||||
  g_return_val_if_fail (action->priv->points->len > point, NULL);
 | 
			
		||||
 | 
			
		||||
  gesture_point = &g_array_index (action->priv->points, GesturePoint, point);
 | 
			
		||||
  priv = clutter_gesture_action_get_instance_private (action);
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (priv->points->len > point, NULL);
 | 
			
		||||
 | 
			
		||||
  gesture_point = &g_array_index (priv->points, GesturePoint, point);
 | 
			
		||||
 | 
			
		||||
  return gesture_point->last_event;
 | 
			
		||||
}
 | 
			
		||||
@@ -1256,12 +1319,16 @@ void
 | 
			
		||||
clutter_gesture_action_set_threshold_trigger_edge (ClutterGestureAction      *action,
 | 
			
		||||
                                                   ClutterGestureTriggerEdge  edge)
 | 
			
		||||
{
 | 
			
		||||
  ClutterGestureActionPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action));
 | 
			
		||||
 | 
			
		||||
  if (action->priv->edge == edge)
 | 
			
		||||
  priv = clutter_gesture_action_get_instance_private (action);
 | 
			
		||||
 | 
			
		||||
  if (priv->edge == edge)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  action->priv->edge = edge;
 | 
			
		||||
  priv->edge = edge;
 | 
			
		||||
 | 
			
		||||
  g_object_notify_by_pspec (G_OBJECT (action), gesture_props[PROP_THRESHOLD_TRIGGER_EDGE]);
 | 
			
		||||
}
 | 
			
		||||
@@ -1280,10 +1347,14 @@ clutter_gesture_action_set_threshold_trigger_edge (ClutterGestureAction      *ac
 | 
			
		||||
ClutterGestureTriggerEdge
 | 
			
		||||
clutter_gesture_action_get_threshold_trigger_edge (ClutterGestureAction *action)
 | 
			
		||||
{
 | 
			
		||||
  ClutterGestureActionPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action),
 | 
			
		||||
                        CLUTTER_GESTURE_TRIGGER_EDGE_NONE);
 | 
			
		||||
 | 
			
		||||
  return action->priv->edge;
 | 
			
		||||
  priv = clutter_gesture_action_get_instance_private (action);
 | 
			
		||||
 | 
			
		||||
  return priv->edge;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -1323,17 +1394,21 @@ clutter_gesture_action_set_threshold_trigger_distance (ClutterGestureAction
 | 
			
		||||
                                                       float                      x,
 | 
			
		||||
                                                       float                      y)
 | 
			
		||||
{
 | 
			
		||||
  ClutterGestureActionPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action));
 | 
			
		||||
 | 
			
		||||
  if (fabsf (x - action->priv->distance_x) > FLOAT_EPSILON)
 | 
			
		||||
  priv = clutter_gesture_action_get_instance_private (action);
 | 
			
		||||
 | 
			
		||||
  if (fabsf (x - priv->distance_x) > FLOAT_EPSILON)
 | 
			
		||||
    {
 | 
			
		||||
      action->priv->distance_x = x;
 | 
			
		||||
      priv->distance_x = x;
 | 
			
		||||
      g_object_notify_by_pspec (G_OBJECT (action), gesture_props[PROP_THRESHOLD_TRIGGER_DISTANCE_X]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (fabsf (y - action->priv->distance_y) > FLOAT_EPSILON)
 | 
			
		||||
  if (fabsf (y - priv->distance_y) > FLOAT_EPSILON)
 | 
			
		||||
    {
 | 
			
		||||
      action->priv->distance_y = y;
 | 
			
		||||
      priv->distance_y = y;
 | 
			
		||||
      g_object_notify_by_pspec (G_OBJECT (action), gesture_props[PROP_THRESHOLD_TRIGGER_DISTANCE_Y]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1354,19 +1429,23 @@ clutter_gesture_action_get_threshold_trigger_distance (ClutterGestureAction *act
 | 
			
		||||
                                                       float                *x,
 | 
			
		||||
                                                       float                *y)
 | 
			
		||||
{
 | 
			
		||||
  ClutterGestureActionPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action));
 | 
			
		||||
 | 
			
		||||
  priv = clutter_gesture_action_get_instance_private (action);
 | 
			
		||||
 | 
			
		||||
  if (x != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      if (action->priv->distance_x > 0.0)
 | 
			
		||||
        *x = action->priv->distance_x;
 | 
			
		||||
      if (priv->distance_x > 0.0)
 | 
			
		||||
        *x = priv->distance_x;
 | 
			
		||||
      else
 | 
			
		||||
        *x = gesture_get_default_threshold ();
 | 
			
		||||
    }
 | 
			
		||||
  if (y != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      if (action->priv->distance_y > 0.0)
 | 
			
		||||
        *y = action->priv->distance_y;
 | 
			
		||||
      if (priv->distance_y > 0.0)
 | 
			
		||||
        *y = priv->distance_y;
 | 
			
		||||
      else
 | 
			
		||||
        *y = gesture_get_default_threshold ();
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -34,32 +34,13 @@
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define CLUTTER_TYPE_GESTURE_ACTION               (clutter_gesture_action_get_type ())
 | 
			
		||||
#define CLUTTER_GESTURE_ACTION(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_GESTURE_ACTION, ClutterGestureAction))
 | 
			
		||||
#define CLUTTER_IS_GESTURE_ACTION(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_GESTURE_ACTION))
 | 
			
		||||
#define CLUTTER_GESTURE_ACTION_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_GESTURE_ACTION, ClutterGestureActionClass))
 | 
			
		||||
#define CLUTTER_IS_GESTURE_ACTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_GESTURE_ACTION))
 | 
			
		||||
#define CLUTTER_GESTURE_ACTION_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_GESTURE_ACTION, ClutterGestureActionClass))
 | 
			
		||||
#define CLUTTER_TYPE_GESTURE_ACTION (clutter_gesture_action_get_type ())
 | 
			
		||||
 | 
			
		||||
typedef struct _ClutterGestureAction              ClutterGestureAction;
 | 
			
		||||
typedef struct _ClutterGestureActionPrivate       ClutterGestureActionPrivate;
 | 
			
		||||
typedef struct _ClutterGestureActionClass         ClutterGestureActionClass;
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (ClutterGestureAction, clutter_gesture_action,
 | 
			
		||||
                          CLUTTER, GESTURE_ACTION, ClutterAction);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ClutterGestureAction:
 | 
			
		||||
 *
 | 
			
		||||
 * The #ClutterGestureAction structure contains
 | 
			
		||||
 * only private data and should be accessed using the provided API
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 1.8
 | 
			
		||||
 */
 | 
			
		||||
struct _ClutterGestureAction
 | 
			
		||||
{
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  ClutterAction parent_instance;
 | 
			
		||||
 | 
			
		||||
  ClutterGestureActionPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
typedef struct _ClutterGestureActionPrivate ClutterGestureActionPrivate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ClutterGestureActionClass:
 | 
			
		||||
@@ -101,9 +82,6 @@ struct _ClutterGestureActionClass
 | 
			
		||||
  void (* _clutter_gesture_action6) (void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
GType clutter_gesture_action_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
ClutterAction *        clutter_gesture_action_new                      (void);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1391,8 +1391,7 @@ allocate_child (ClutterGridRequest *request,
 | 
			
		||||
static void
 | 
			
		||||
clutter_grid_layout_allocate (ClutterLayoutManager   *layout,
 | 
			
		||||
                              ClutterContainer       *container,
 | 
			
		||||
                              const ClutterActorBox  *allocation,
 | 
			
		||||
                              ClutterAllocationFlags  flags)
 | 
			
		||||
                              const ClutterActorBox  *allocation)
 | 
			
		||||
{
 | 
			
		||||
  ClutterGridLayout *self = CLUTTER_GRID_LAYOUT (layout);
 | 
			
		||||
  ClutterOrientation orientation;
 | 
			
		||||
@@ -1453,7 +1452,7 @@ clutter_grid_layout_allocate (ClutterLayoutManager   *layout,
 | 
			
		||||
      child_allocation.x2 = child_allocation.x1 + width;
 | 
			
		||||
      child_allocation.y2 = child_allocation.y1 + height;
 | 
			
		||||
 | 
			
		||||
      clutter_actor_allocate (child, &child_allocation, flags);
 | 
			
		||||
      clutter_actor_allocate (child, &child_allocation);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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, };
 | 
			
		||||
 | 
			
		||||
@@ -255,8 +253,7 @@ layout_manager_real_get_preferred_height (ClutterLayoutManager *manager,
 | 
			
		||||
static void
 | 
			
		||||
layout_manager_real_allocate (ClutterLayoutManager   *manager,
 | 
			
		||||
                              ClutterContainer       *container,
 | 
			
		||||
                              const ClutterActorBox  *allocation,
 | 
			
		||||
                              ClutterAllocationFlags  flags)
 | 
			
		||||
                              const ClutterActorBox  *allocation)
 | 
			
		||||
{
 | 
			
		||||
  LAYOUT_MANAGER_WARN_NOT_IMPLEMENTED (manager, "allocate");
 | 
			
		||||
}
 | 
			
		||||
@@ -301,96 +298,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 +311,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;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
@@ -523,7 +433,6 @@ clutter_layout_manager_get_preferred_height (ClutterLayoutManager *manager,
 | 
			
		||||
 * @container: the #ClutterContainer using @manager
 | 
			
		||||
 * @allocation: the #ClutterActorBox containing the allocated area
 | 
			
		||||
 *   of @container
 | 
			
		||||
 * @flags: the allocation flags
 | 
			
		||||
 *
 | 
			
		||||
 * Allocates the children of @container given an area
 | 
			
		||||
 *
 | 
			
		||||
@@ -534,8 +443,7 @@ clutter_layout_manager_get_preferred_height (ClutterLayoutManager *manager,
 | 
			
		||||
void
 | 
			
		||||
clutter_layout_manager_allocate (ClutterLayoutManager   *manager,
 | 
			
		||||
                                 ClutterContainer       *container,
 | 
			
		||||
                                 const ClutterActorBox  *allocation,
 | 
			
		||||
                                 ClutterAllocationFlags  flags)
 | 
			
		||||
                                 const ClutterActorBox  *allocation)
 | 
			
		||||
{
 | 
			
		||||
  ClutterLayoutManagerClass *klass;
 | 
			
		||||
 | 
			
		||||
@@ -544,7 +452,7 @@ clutter_layout_manager_allocate (ClutterLayoutManager   *manager,
 | 
			
		||||
  g_return_if_fail (allocation != NULL);
 | 
			
		||||
 | 
			
		||||
  klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager);
 | 
			
		||||
  klass->allocate (manager, container, allocation, flags);
 | 
			
		||||
  klass->allocate (manager, container, allocation);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 
 | 
			
		||||
@@ -115,8 +115,7 @@ struct _ClutterLayoutManagerClass
 | 
			
		||||
                                                 gfloat                 *nat_height_p);
 | 
			
		||||
  void               (* allocate)               (ClutterLayoutManager   *manager,
 | 
			
		||||
                                                 ClutterContainer       *container,
 | 
			
		||||
                                                 const ClutterActorBox  *allocation,
 | 
			
		||||
                                                 ClutterAllocationFlags  flags);
 | 
			
		||||
                                                 const ClutterActorBox  *allocation);
 | 
			
		||||
 | 
			
		||||
  void               (* set_container)          (ClutterLayoutManager   *manager,
 | 
			
		||||
                                                 ClutterContainer       *container);
 | 
			
		||||
@@ -126,15 +125,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 >*/
 | 
			
		||||
@@ -167,8 +157,7 @@ void               clutter_layout_manager_get_preferred_height  (ClutterLayoutMa
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void               clutter_layout_manager_allocate              (ClutterLayoutManager   *manager,
 | 
			
		||||
                                                                 ClutterContainer       *container,
 | 
			
		||||
                                                                 const ClutterActorBox  *allocation,
 | 
			
		||||
                                                                 ClutterAllocationFlags  flags);
 | 
			
		||||
                                                                 const ClutterActorBox  *allocation);
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void               clutter_layout_manager_set_container         (ClutterLayoutManager   *manager,
 | 
			
		||||
 
 | 
			
		||||
@@ -199,7 +199,7 @@ master_clock_schedule_stage_updates (ClutterMasterClockDefault *master_clock)
 | 
			
		||||
  stages = clutter_stage_manager_peek_stages (stage_manager);
 | 
			
		||||
 | 
			
		||||
  for (l = stages; l != NULL; l = l->next)
 | 
			
		||||
    _clutter_stage_schedule_update (l->data);
 | 
			
		||||
    clutter_stage_schedule_update (l->data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GSList *
 | 
			
		||||
@@ -252,7 +252,7 @@ master_clock_reschedule_stage_updates (ClutterMasterClockDefault *master_clock,
 | 
			
		||||
      if (master_clock->timelines ||
 | 
			
		||||
          _clutter_stage_has_queued_events (l->data) ||
 | 
			
		||||
          _clutter_stage_needs_update (l->data))
 | 
			
		||||
        _clutter_stage_schedule_update (l->data);
 | 
			
		||||
        clutter_stage_schedule_update (l->data);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 | 
			
		||||
@@ -57,9 +77,16 @@ void clutter_stage_thaw_updates (ClutterStage *stage);
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void clutter_stage_update_resource_scales (ClutterStage *stage);
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void clutter_stage_view_assign_next_scanout (ClutterStageView *stage_view,
 | 
			
		||||
                                             CoglScanout      *scanout);
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
gboolean clutter_actor_has_damage (ClutterActor *actor);
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
gboolean clutter_actor_has_transitions (ClutterActor *actor);
 | 
			
		||||
 | 
			
		||||
#undef __CLUTTER_H_INSIDE__
 | 
			
		||||
 | 
			
		||||
#endif /* __CLUTTER_MUTTER_H__ */
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -74,7 +74,6 @@ void     _clutter_stage_queue_event                       (ClutterStage *stage,
 | 
			
		||||
gboolean _clutter_stage_has_queued_events                 (ClutterStage *stage);
 | 
			
		||||
void     _clutter_stage_process_queued_events             (ClutterStage *stage);
 | 
			
		||||
void     _clutter_stage_update_input_devices              (ClutterStage *stage);
 | 
			
		||||
void     _clutter_stage_schedule_update                   (ClutterStage *stage);
 | 
			
		||||
gint64    _clutter_stage_get_update_time                  (ClutterStage *stage);
 | 
			
		||||
void     _clutter_stage_clear_update_time                 (ClutterStage *stage);
 | 
			
		||||
gboolean _clutter_stage_has_full_redraw_queued            (ClutterStage *stage);
 | 
			
		||||
@@ -139,8 +138,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);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -20,17 +20,28 @@
 | 
			
		||||
 | 
			
		||||
#include "clutter/clutter-stage-view.h"
 | 
			
		||||
 | 
			
		||||
void clutter_stage_view_after_paint (ClutterStageView *view);
 | 
			
		||||
void clutter_stage_view_after_paint (ClutterStageView *view,
 | 
			
		||||
                                     cairo_region_t   *redraw_clip);
 | 
			
		||||
 | 
			
		||||
void clutter_stage_view_before_swap_buffer (ClutterStageView     *view,
 | 
			
		||||
                                            const cairo_region_t *swap_region);
 | 
			
		||||
 | 
			
		||||
gboolean clutter_stage_view_is_dirty_viewport (ClutterStageView *view);
 | 
			
		||||
 | 
			
		||||
void clutter_stage_view_set_dirty_viewport (ClutterStageView *view,
 | 
			
		||||
                                            gboolean          dirty);
 | 
			
		||||
void clutter_stage_view_invalidate_viewport (ClutterStageView *view);
 | 
			
		||||
 | 
			
		||||
void clutter_stage_view_set_viewport (ClutterStageView *view,
 | 
			
		||||
                                      float             x,
 | 
			
		||||
                                      float             y,
 | 
			
		||||
                                      float             width,
 | 
			
		||||
                                      float             height);
 | 
			
		||||
 | 
			
		||||
gboolean clutter_stage_view_is_dirty_projection (ClutterStageView *view);
 | 
			
		||||
 | 
			
		||||
void clutter_stage_view_set_dirty_projection (ClutterStageView *view,
 | 
			
		||||
                                              gboolean          dirty);
 | 
			
		||||
void clutter_stage_view_invalidate_projection (ClutterStageView *view);
 | 
			
		||||
 | 
			
		||||
void clutter_stage_view_set_projection (ClutterStageView *view,
 | 
			
		||||
                                        const CoglMatrix *matrix);
 | 
			
		||||
 | 
			
		||||
void clutter_stage_view_add_redraw_clip (ClutterStageView            *view,
 | 
			
		||||
                                         const cairo_rectangle_int_t *clip);
 | 
			
		||||
@@ -43,4 +54,12 @@ const cairo_region_t * clutter_stage_view_peek_redraw_clip (ClutterStageView *vi
 | 
			
		||||
 | 
			
		||||
cairo_region_t * clutter_stage_view_take_redraw_clip (ClutterStageView *view);
 | 
			
		||||
 | 
			
		||||
CoglScanout * clutter_stage_view_take_scanout (ClutterStageView *view);
 | 
			
		||||
 | 
			
		||||
void clutter_stage_view_transform_rect_to_onscreen (ClutterStageView            *view,
 | 
			
		||||
                                                    const cairo_rectangle_int_t *src_rect,
 | 
			
		||||
                                                    int                          dst_width,
 | 
			
		||||
                                                    int                          dst_height,
 | 
			
		||||
                                                    cairo_rectangle_int_t       *dst_rect);
 | 
			
		||||
 | 
			
		||||
#endif /* __CLUTTER_STAGE_VIEW_PRIVATE_H__ */
 | 
			
		||||
 
 | 
			
		||||
@@ -23,16 +23,20 @@
 | 
			
		||||
#include <cairo-gobject.h>
 | 
			
		||||
#include <math.h>
 | 
			
		||||
 | 
			
		||||
#include "clutter/clutter-damage-history.h"
 | 
			
		||||
#include "clutter/clutter-private.h"
 | 
			
		||||
#include "clutter/clutter-mutter.h"
 | 
			
		||||
#include "cogl/cogl.h"
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
  PROP_0,
 | 
			
		||||
 | 
			
		||||
  PROP_NAME,
 | 
			
		||||
  PROP_LAYOUT,
 | 
			
		||||
  PROP_FRAMEBUFFER,
 | 
			
		||||
  PROP_OFFSCREEN,
 | 
			
		||||
  PROP_SHADOWFB,
 | 
			
		||||
  PROP_USE_SHADOWFB,
 | 
			
		||||
  PROP_SCALE,
 | 
			
		||||
 | 
			
		||||
  PROP_LAST
 | 
			
		||||
@@ -42,6 +46,8 @@ static GParamSpec *obj_props[PROP_LAST];
 | 
			
		||||
 | 
			
		||||
typedef struct _ClutterStageViewPrivate
 | 
			
		||||
{
 | 
			
		||||
  char *name;
 | 
			
		||||
 | 
			
		||||
  cairo_rectangle_int_t layout;
 | 
			
		||||
  float scale;
 | 
			
		||||
  CoglFramebuffer *framebuffer;
 | 
			
		||||
@@ -49,8 +55,18 @@ typedef struct _ClutterStageViewPrivate
 | 
			
		||||
  CoglOffscreen *offscreen;
 | 
			
		||||
  CoglPipeline *offscreen_pipeline;
 | 
			
		||||
 | 
			
		||||
  CoglOffscreen *shadowfb;
 | 
			
		||||
  CoglPipeline *shadowfb_pipeline;
 | 
			
		||||
  gboolean use_shadowfb;
 | 
			
		||||
  struct {
 | 
			
		||||
    struct {
 | 
			
		||||
      CoglDmaBufHandle *handles[2];
 | 
			
		||||
      int current_idx;
 | 
			
		||||
      ClutterDamageHistory *damage_history;
 | 
			
		||||
    } dma_buf;
 | 
			
		||||
 | 
			
		||||
    CoglOffscreen *framebuffer;
 | 
			
		||||
  } shadow;
 | 
			
		||||
 | 
			
		||||
  CoglScanout *next_scanout;
 | 
			
		||||
 | 
			
		||||
  gboolean has_redraw_clip;
 | 
			
		||||
  cairo_region_t *redraw_clip;
 | 
			
		||||
@@ -87,8 +103,8 @@ clutter_stage_view_get_framebuffer (ClutterStageView *view)
 | 
			
		||||
 | 
			
		||||
  if (priv->offscreen)
 | 
			
		||||
    return priv->offscreen;
 | 
			
		||||
  else if (priv->shadowfb)
 | 
			
		||||
    return priv->shadowfb;
 | 
			
		||||
  else if (priv->shadow.framebuffer)
 | 
			
		||||
    return priv->shadow.framebuffer;
 | 
			
		||||
  else
 | 
			
		||||
    return priv->framebuffer;
 | 
			
		||||
}
 | 
			
		||||
@@ -148,19 +164,6 @@ clutter_stage_view_ensure_offscreen_blit_pipeline (ClutterStageView *view)
 | 
			
		||||
    view_class->setup_offscreen_blit_pipeline (view, priv->offscreen_pipeline);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_stage_view_ensure_shadowfb_blit_pipeline (ClutterStageView *view)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageViewPrivate *priv =
 | 
			
		||||
    clutter_stage_view_get_instance_private (view);
 | 
			
		||||
 | 
			
		||||
  if (priv->shadowfb_pipeline)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  priv->shadowfb_pipeline =
 | 
			
		||||
    clutter_stage_view_create_framebuffer_pipeline (priv->shadowfb);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_stage_view_invalidate_offscreen_blit_pipeline (ClutterStageView *view)
 | 
			
		||||
{
 | 
			
		||||
@@ -170,85 +173,563 @@ clutter_stage_view_invalidate_offscreen_blit_pipeline (ClutterStageView *view)
 | 
			
		||||
  g_clear_pointer (&priv->offscreen_pipeline, cogl_object_unref);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_stage_view_transform_rect_to_onscreen (ClutterStageView            *view,
 | 
			
		||||
                                               const cairo_rectangle_int_t *src_rect,
 | 
			
		||||
                                               int                          dst_width,
 | 
			
		||||
                                               int                          dst_height,
 | 
			
		||||
                                               cairo_rectangle_int_t       *dst_rect)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageViewClass *view_class = CLUTTER_STAGE_VIEW_GET_CLASS (view);
 | 
			
		||||
 | 
			
		||||
  return view_class->transform_rect_to_onscreen (view,
 | 
			
		||||
                                                 src_rect,
 | 
			
		||||
                                                 dst_width,
 | 
			
		||||
                                                 dst_height,
 | 
			
		||||
                                                 dst_rect);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_stage_view_copy_to_framebuffer (ClutterStageView *view,
 | 
			
		||||
                                        CoglPipeline     *pipeline,
 | 
			
		||||
                                        CoglFramebuffer  *src_framebuffer,
 | 
			
		||||
                                        CoglFramebuffer  *dst_framebuffer,
 | 
			
		||||
                                        gboolean          can_blit)
 | 
			
		||||
paint_transformed_framebuffer (ClutterStageView     *view,
 | 
			
		||||
                               CoglPipeline         *pipeline,
 | 
			
		||||
                               CoglFramebuffer      *src_framebuffer,
 | 
			
		||||
                               CoglFramebuffer      *dst_framebuffer,
 | 
			
		||||
                               const cairo_region_t *redraw_clip)
 | 
			
		||||
{
 | 
			
		||||
  CoglMatrix matrix;
 | 
			
		||||
  unsigned int n_rectangles, i;
 | 
			
		||||
  int dst_width, dst_height;
 | 
			
		||||
  cairo_rectangle_int_t view_layout;
 | 
			
		||||
  cairo_rectangle_int_t onscreen_layout;
 | 
			
		||||
  float view_scale;
 | 
			
		||||
  float *coordinates;
 | 
			
		||||
 | 
			
		||||
  /* First, try with blit */
 | 
			
		||||
  if (can_blit)
 | 
			
		||||
    {
 | 
			
		||||
      if (cogl_blit_framebuffer (src_framebuffer,
 | 
			
		||||
                                 dst_framebuffer,
 | 
			
		||||
                                 0, 0,
 | 
			
		||||
                                 0, 0,
 | 
			
		||||
                                 cogl_framebuffer_get_width (dst_framebuffer),
 | 
			
		||||
                                 cogl_framebuffer_get_height (dst_framebuffer),
 | 
			
		||||
                                 NULL))
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
  dst_width = cogl_framebuffer_get_width (dst_framebuffer);
 | 
			
		||||
  dst_height = cogl_framebuffer_get_height (dst_framebuffer);
 | 
			
		||||
  clutter_stage_view_get_layout (view, &view_layout);
 | 
			
		||||
  clutter_stage_view_transform_rect_to_onscreen (view,
 | 
			
		||||
                                                 &(cairo_rectangle_int_t) {
 | 
			
		||||
                                                   .width = view_layout.width,
 | 
			
		||||
                                                   .height = view_layout.height,
 | 
			
		||||
                                                 },
 | 
			
		||||
                                                 view_layout.width,
 | 
			
		||||
                                                 view_layout.height,
 | 
			
		||||
                                                 &onscreen_layout);
 | 
			
		||||
  view_scale = clutter_stage_view_get_scale (view);
 | 
			
		||||
 | 
			
		||||
  /* If blit fails, fallback to the slower painting method */
 | 
			
		||||
  cogl_framebuffer_push_matrix (dst_framebuffer);
 | 
			
		||||
 | 
			
		||||
  cogl_matrix_init_identity (&matrix);
 | 
			
		||||
  cogl_matrix_translate (&matrix, -1, 1, 0);
 | 
			
		||||
  cogl_matrix_scale (&matrix, 2, -2, 0);
 | 
			
		||||
  cogl_matrix_scale (&matrix,
 | 
			
		||||
                     1.0 / (dst_width / 2.0),
 | 
			
		||||
                     -1.0 / (dst_height / 2.0), 0);
 | 
			
		||||
  cogl_matrix_translate (&matrix,
 | 
			
		||||
                         -(dst_width / 2.0),
 | 
			
		||||
                         -(dst_height / 2.0), 0);
 | 
			
		||||
  cogl_framebuffer_set_projection_matrix (dst_framebuffer, &matrix);
 | 
			
		||||
  cogl_framebuffer_set_viewport (dst_framebuffer,
 | 
			
		||||
                                 0, 0, dst_width, dst_height);
 | 
			
		||||
 | 
			
		||||
  cogl_framebuffer_draw_rectangle (dst_framebuffer,
 | 
			
		||||
                                   pipeline,
 | 
			
		||||
                                   0, 0, 1, 1);
 | 
			
		||||
  n_rectangles = cairo_region_num_rectangles (redraw_clip);
 | 
			
		||||
  coordinates = g_newa (float, 2 * 4 * n_rectangles);
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < n_rectangles; i++)
 | 
			
		||||
    {
 | 
			
		||||
      cairo_rectangle_int_t src_rect;
 | 
			
		||||
      cairo_rectangle_int_t dst_rect;
 | 
			
		||||
 | 
			
		||||
      cairo_region_get_rectangle (redraw_clip, i, &src_rect);
 | 
			
		||||
      _clutter_util_rectangle_offset (&src_rect,
 | 
			
		||||
                                      -view_layout.x,
 | 
			
		||||
                                      -view_layout.y,
 | 
			
		||||
                                      &src_rect);
 | 
			
		||||
 | 
			
		||||
      clutter_stage_view_transform_rect_to_onscreen (view,
 | 
			
		||||
                                                     &src_rect,
 | 
			
		||||
                                                     onscreen_layout.width,
 | 
			
		||||
                                                     onscreen_layout.height,
 | 
			
		||||
                                                     &dst_rect);
 | 
			
		||||
 | 
			
		||||
      coordinates[i * 8 + 0] = (float) dst_rect.x * view_scale;
 | 
			
		||||
      coordinates[i * 8 + 1] = (float) dst_rect.y * view_scale;
 | 
			
		||||
      coordinates[i * 8 + 2] = ((float) (dst_rect.x + dst_rect.width) *
 | 
			
		||||
                                view_scale);
 | 
			
		||||
      coordinates[i * 8 + 3] = ((float) (dst_rect.y + dst_rect.height) *
 | 
			
		||||
                                view_scale);
 | 
			
		||||
 | 
			
		||||
      coordinates[i * 8 + 4] = (((float) dst_rect.x / (float) dst_width) *
 | 
			
		||||
                                view_scale);
 | 
			
		||||
      coordinates[i * 8 + 5] = (((float) dst_rect.y / (float) dst_height) *
 | 
			
		||||
                                view_scale);
 | 
			
		||||
      coordinates[i * 8 + 6] = ((float) (dst_rect.x + dst_rect.width) /
 | 
			
		||||
                                (float) dst_width) * view_scale;
 | 
			
		||||
      coordinates[i * 8 + 7] = ((float) (dst_rect.y + dst_rect.height) /
 | 
			
		||||
                                (float) dst_height) * view_scale;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  cogl_framebuffer_draw_textured_rectangles (dst_framebuffer,
 | 
			
		||||
                                             pipeline,
 | 
			
		||||
                                             coordinates,
 | 
			
		||||
                                             n_rectangles);
 | 
			
		||||
 | 
			
		||||
  cogl_framebuffer_pop_matrix (dst_framebuffer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
is_shadowfb_double_buffered (ClutterStageView *view)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageViewPrivate *priv =
 | 
			
		||||
    clutter_stage_view_get_instance_private (view);
 | 
			
		||||
 | 
			
		||||
  return priv->shadow.dma_buf.handles[0] && priv->shadow.dma_buf.handles[1];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
init_dma_buf_shadowfbs (ClutterStageView  *view,
 | 
			
		||||
                        CoglContext       *cogl_context,
 | 
			
		||||
                        int                width,
 | 
			
		||||
                        int                height,
 | 
			
		||||
                        GError           **error)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageViewPrivate *priv =
 | 
			
		||||
    clutter_stage_view_get_instance_private (view);
 | 
			
		||||
  CoglRenderer *cogl_renderer = cogl_context_get_renderer (cogl_context);
 | 
			
		||||
  CoglFramebuffer *initial_shadowfb;
 | 
			
		||||
 | 
			
		||||
  if (!cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE))
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
 | 
			
		||||
                   "Buffer age not supported");
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (!cogl_is_onscreen (priv->framebuffer))
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
 | 
			
		||||
                   "Tried to use shadow buffer without onscreen");
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  priv->shadow.dma_buf.handles[0] = cogl_renderer_create_dma_buf (cogl_renderer,
 | 
			
		||||
                                                                  width, height,
 | 
			
		||||
                                                                  error);
 | 
			
		||||
  if (!priv->shadow.dma_buf.handles[0])
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  priv->shadow.dma_buf.handles[1] = cogl_renderer_create_dma_buf (cogl_renderer,
 | 
			
		||||
                                                                  width, height,
 | 
			
		||||
                                                                  error);
 | 
			
		||||
  if (!priv->shadow.dma_buf.handles[1])
 | 
			
		||||
    {
 | 
			
		||||
      g_clear_pointer (&priv->shadow.dma_buf.handles[0],
 | 
			
		||||
                       cogl_dma_buf_handle_free);
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  priv->shadow.dma_buf.damage_history = clutter_damage_history_new ();
 | 
			
		||||
 | 
			
		||||
  initial_shadowfb =
 | 
			
		||||
    cogl_dma_buf_handle_get_framebuffer (priv->shadow.dma_buf.handles[0]);
 | 
			
		||||
  priv->shadow.framebuffer = cogl_object_ref (initial_shadowfb);
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static CoglOffscreen *
 | 
			
		||||
create_offscreen_framebuffer (CoglContext  *context,
 | 
			
		||||
                              int           width,
 | 
			
		||||
                              int           height,
 | 
			
		||||
                              GError      **error)
 | 
			
		||||
{
 | 
			
		||||
  CoglOffscreen *framebuffer;
 | 
			
		||||
  CoglTexture2D *texture;
 | 
			
		||||
 | 
			
		||||
  texture = cogl_texture_2d_new_with_size (context, width, height);
 | 
			
		||||
  cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (texture),
 | 
			
		||||
                                          FALSE);
 | 
			
		||||
 | 
			
		||||
  if (!cogl_texture_allocate (COGL_TEXTURE (texture), error))
 | 
			
		||||
    {
 | 
			
		||||
      cogl_object_unref (texture);
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  framebuffer = cogl_offscreen_new_with_texture (COGL_TEXTURE (texture));
 | 
			
		||||
  cogl_object_unref (texture);
 | 
			
		||||
  if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (framebuffer), error))
 | 
			
		||||
    {
 | 
			
		||||
      cogl_object_unref (framebuffer);
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return framebuffer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
init_fallback_shadowfb (ClutterStageView  *view,
 | 
			
		||||
                        CoglContext       *cogl_context,
 | 
			
		||||
                        int                width,
 | 
			
		||||
                        int                height,
 | 
			
		||||
                        GError           **error)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageViewPrivate *priv =
 | 
			
		||||
    clutter_stage_view_get_instance_private (view);
 | 
			
		||||
  CoglOffscreen *offscreen;
 | 
			
		||||
 | 
			
		||||
  offscreen = create_offscreen_framebuffer (cogl_context, width, height, error);
 | 
			
		||||
  if (!offscreen)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  priv->shadow.framebuffer = offscreen;
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
init_shadowfb (ClutterStageView *view)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageViewPrivate *priv =
 | 
			
		||||
    clutter_stage_view_get_instance_private (view);
 | 
			
		||||
  g_autoptr (GError) error = NULL;
 | 
			
		||||
  int width;
 | 
			
		||||
  int height;
 | 
			
		||||
  CoglContext *cogl_context;
 | 
			
		||||
 | 
			
		||||
  width = cogl_framebuffer_get_width (priv->framebuffer);
 | 
			
		||||
  height = cogl_framebuffer_get_height (priv->framebuffer);
 | 
			
		||||
  cogl_context = cogl_framebuffer_get_context (priv->framebuffer);
 | 
			
		||||
 | 
			
		||||
  if (init_dma_buf_shadowfbs (view, cogl_context, width, height, &error))
 | 
			
		||||
    {
 | 
			
		||||
      g_message ("Initialized double buffered shadow fb for %s", priv->name);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_warning ("Failed to initialize double buffered shadow fb for %s: %s",
 | 
			
		||||
             priv->name, error->message);
 | 
			
		||||
  g_clear_error (&error);
 | 
			
		||||
 | 
			
		||||
  if (!init_fallback_shadowfb (view, cogl_context, width, height, &error))
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("Failed to initialize single buffered shadow fb for %s: %s",
 | 
			
		||||
                 priv->name, error->message);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      g_message ("Initialized single buffered shadow fb for %s", priv->name);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_stage_view_after_paint (ClutterStageView *view)
 | 
			
		||||
clutter_stage_view_after_paint (ClutterStageView *view,
 | 
			
		||||
                                cairo_region_t   *redraw_clip)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageViewPrivate *priv =
 | 
			
		||||
    clutter_stage_view_get_instance_private (view);
 | 
			
		||||
 | 
			
		||||
  if (priv->offscreen)
 | 
			
		||||
    {
 | 
			
		||||
      gboolean can_blit;
 | 
			
		||||
      CoglMatrix matrix;
 | 
			
		||||
 | 
			
		||||
      clutter_stage_view_ensure_offscreen_blit_pipeline (view);
 | 
			
		||||
      clutter_stage_view_get_offscreen_transformation_matrix (view, &matrix);
 | 
			
		||||
      can_blit = cogl_matrix_is_identity (&matrix);
 | 
			
		||||
 | 
			
		||||
      if (priv->shadowfb)
 | 
			
		||||
      if (priv->shadow.framebuffer)
 | 
			
		||||
        {
 | 
			
		||||
          clutter_stage_view_copy_to_framebuffer (view,
 | 
			
		||||
                                                  priv->offscreen_pipeline,
 | 
			
		||||
                                                  priv->offscreen,
 | 
			
		||||
                                                  priv->shadowfb,
 | 
			
		||||
                                                  can_blit);
 | 
			
		||||
          paint_transformed_framebuffer (view,
 | 
			
		||||
                                         priv->offscreen_pipeline,
 | 
			
		||||
                                         priv->offscreen,
 | 
			
		||||
                                         priv->shadow.framebuffer,
 | 
			
		||||
                                         redraw_clip);
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          clutter_stage_view_copy_to_framebuffer (view,
 | 
			
		||||
                                                  priv->offscreen_pipeline,
 | 
			
		||||
                                                  priv->offscreen,
 | 
			
		||||
                                                  priv->framebuffer,
 | 
			
		||||
                                                  can_blit);
 | 
			
		||||
          paint_transformed_framebuffer (view,
 | 
			
		||||
                                         priv->offscreen_pipeline,
 | 
			
		||||
                                         priv->offscreen,
 | 
			
		||||
                                         priv->framebuffer,
 | 
			
		||||
                                         redraw_clip);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
is_tile_dirty (cairo_rectangle_int_t *tile,
 | 
			
		||||
               uint8_t               *current_data,
 | 
			
		||||
               uint8_t               *prev_data,
 | 
			
		||||
               int                    bpp,
 | 
			
		||||
               int                    stride)
 | 
			
		||||
{
 | 
			
		||||
  int y;
 | 
			
		||||
 | 
			
		||||
  for (y = tile->y; y < tile->y + tile->height; y++)
 | 
			
		||||
    {
 | 
			
		||||
      if (memcmp (prev_data + y * stride + tile->x * bpp,
 | 
			
		||||
                  current_data + y * stride + tile->x * bpp,
 | 
			
		||||
                  tile->width * bpp) != 0)
 | 
			
		||||
        return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
flip_dma_buf_idx (int idx)
 | 
			
		||||
{
 | 
			
		||||
  return (idx + 1) % 2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static cairo_region_t *
 | 
			
		||||
find_damaged_tiles (ClutterStageView      *view,
 | 
			
		||||
                    const cairo_region_t  *damage_region,
 | 
			
		||||
                    GError               **error)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageViewPrivate *priv =
 | 
			
		||||
    clutter_stage_view_get_instance_private (view);
 | 
			
		||||
  cairo_region_t *tile_damage_region;
 | 
			
		||||
  cairo_rectangle_int_t damage_extents;
 | 
			
		||||
  cairo_rectangle_int_t fb_rect;
 | 
			
		||||
  int prev_dma_buf_idx;
 | 
			
		||||
  CoglDmaBufHandle *prev_dma_buf_handle;
 | 
			
		||||
  uint8_t *prev_data;
 | 
			
		||||
  int current_dma_buf_idx;
 | 
			
		||||
  CoglDmaBufHandle *current_dma_buf_handle;
 | 
			
		||||
  uint8_t *current_data;
 | 
			
		||||
  int width, height, stride, bpp;
 | 
			
		||||
  int tile_x_min, tile_x_max;
 | 
			
		||||
  int tile_y_min, tile_y_max;
 | 
			
		||||
  int tile_x, tile_y;
 | 
			
		||||
  const int tile_size = 16;
 | 
			
		||||
 | 
			
		||||
  prev_dma_buf_idx = flip_dma_buf_idx (priv->shadow.dma_buf.current_idx);
 | 
			
		||||
  prev_dma_buf_handle = priv->shadow.dma_buf.handles[prev_dma_buf_idx];
 | 
			
		||||
 | 
			
		||||
  current_dma_buf_idx = priv->shadow.dma_buf.current_idx;
 | 
			
		||||
  current_dma_buf_handle = priv->shadow.dma_buf.handles[current_dma_buf_idx];
 | 
			
		||||
 | 
			
		||||
  width = cogl_dma_buf_handle_get_width (current_dma_buf_handle);
 | 
			
		||||
  height = cogl_dma_buf_handle_get_height (current_dma_buf_handle);
 | 
			
		||||
  stride = cogl_dma_buf_handle_get_stride (current_dma_buf_handle);
 | 
			
		||||
  bpp = cogl_dma_buf_handle_get_bpp (current_dma_buf_handle);
 | 
			
		||||
 | 
			
		||||
  cogl_framebuffer_finish (priv->shadow.framebuffer);
 | 
			
		||||
 | 
			
		||||
  if (!cogl_dma_buf_handle_sync_read_start (prev_dma_buf_handle, error))
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  if (!cogl_dma_buf_handle_sync_read_start (current_dma_buf_handle, error))
 | 
			
		||||
    goto err_sync_read_current;
 | 
			
		||||
 | 
			
		||||
  prev_data = cogl_dma_buf_handle_mmap (prev_dma_buf_handle, error);
 | 
			
		||||
  if (!prev_data)
 | 
			
		||||
    goto err_mmap_prev;
 | 
			
		||||
  current_data = cogl_dma_buf_handle_mmap (current_dma_buf_handle, error);
 | 
			
		||||
  if (!current_data)
 | 
			
		||||
    goto err_mmap_current;
 | 
			
		||||
 | 
			
		||||
  fb_rect = (cairo_rectangle_int_t) {
 | 
			
		||||
    .width = width,
 | 
			
		||||
    .height = height,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  cairo_region_get_extents (damage_region, &damage_extents);
 | 
			
		||||
 | 
			
		||||
  tile_x_min = damage_extents.x / tile_size;
 | 
			
		||||
  tile_x_max = ((damage_extents.x + damage_extents.width + tile_size - 1) /
 | 
			
		||||
                tile_size);
 | 
			
		||||
  tile_y_min = damage_extents.y / tile_size;
 | 
			
		||||
  tile_y_max = ((damage_extents.y + damage_extents.height + tile_size - 1) /
 | 
			
		||||
                tile_size);
 | 
			
		||||
 | 
			
		||||
  tile_damage_region = cairo_region_create ();
 | 
			
		||||
 | 
			
		||||
  for (tile_y = tile_y_min; tile_y <= tile_y_max; tile_y++)
 | 
			
		||||
    {
 | 
			
		||||
      for (tile_x = tile_x_min; tile_x <= tile_x_max; tile_x++)
 | 
			
		||||
        {
 | 
			
		||||
          cairo_rectangle_int_t tile = {
 | 
			
		||||
            .x = tile_x * tile_size,
 | 
			
		||||
            .y = tile_y * tile_size,
 | 
			
		||||
            .width = tile_size,
 | 
			
		||||
            .height = tile_size,
 | 
			
		||||
          };
 | 
			
		||||
 | 
			
		||||
          if (cairo_region_contains_rectangle (damage_region, &tile) ==
 | 
			
		||||
              CAIRO_REGION_OVERLAP_OUT)
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
          _clutter_util_rectangle_intersection (&tile, &fb_rect, &tile);
 | 
			
		||||
 | 
			
		||||
          if (is_tile_dirty (&tile, current_data, prev_data, bpp, stride))
 | 
			
		||||
            cairo_region_union_rectangle (tile_damage_region, &tile);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (priv->shadowfb)
 | 
			
		||||
  if (!cogl_dma_buf_handle_sync_read_end (prev_dma_buf_handle, error))
 | 
			
		||||
    {
 | 
			
		||||
      clutter_stage_view_ensure_shadowfb_blit_pipeline (view);
 | 
			
		||||
      clutter_stage_view_copy_to_framebuffer (view,
 | 
			
		||||
                                              priv->shadowfb_pipeline,
 | 
			
		||||
                                              priv->shadowfb,
 | 
			
		||||
                                              priv->framebuffer,
 | 
			
		||||
                                              TRUE);
 | 
			
		||||
      g_warning ("Failed to end DMA buffer read synchronization: %s",
 | 
			
		||||
                 (*error)->message);
 | 
			
		||||
      g_clear_error (error);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (!cogl_dma_buf_handle_sync_read_end (current_dma_buf_handle, error))
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("Failed to end DMA buffer read synchronization: %s",
 | 
			
		||||
                 (*error)->message);
 | 
			
		||||
      g_clear_error (error);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  cogl_dma_buf_handle_munmap (prev_dma_buf_handle, prev_data, NULL);
 | 
			
		||||
  cogl_dma_buf_handle_munmap (current_dma_buf_handle, current_data, NULL);
 | 
			
		||||
 | 
			
		||||
  cairo_region_intersect (tile_damage_region, damage_region);
 | 
			
		||||
 | 
			
		||||
  return tile_damage_region;
 | 
			
		||||
 | 
			
		||||
err_mmap_current:
 | 
			
		||||
  cogl_dma_buf_handle_munmap (prev_dma_buf_handle, prev_data, NULL);
 | 
			
		||||
 | 
			
		||||
err_mmap_prev:
 | 
			
		||||
  cogl_dma_buf_handle_sync_read_end (current_dma_buf_handle, NULL);
 | 
			
		||||
 | 
			
		||||
err_sync_read_current:
 | 
			
		||||
  cogl_dma_buf_handle_sync_read_end (prev_dma_buf_handle, NULL);
 | 
			
		||||
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
swap_dma_buf_framebuffer (ClutterStageView *view)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageViewPrivate *priv =
 | 
			
		||||
    clutter_stage_view_get_instance_private (view);
 | 
			
		||||
  int next_idx;
 | 
			
		||||
  CoglDmaBufHandle *next_dma_buf_handle;
 | 
			
		||||
  CoglOffscreen *next_framebuffer;
 | 
			
		||||
 | 
			
		||||
  next_idx = ((priv->shadow.dma_buf.current_idx + 1) %
 | 
			
		||||
              G_N_ELEMENTS (priv->shadow.dma_buf.handles));
 | 
			
		||||
  priv->shadow.dma_buf.current_idx = next_idx;
 | 
			
		||||
 | 
			
		||||
  next_dma_buf_handle = priv->shadow.dma_buf.handles[next_idx];
 | 
			
		||||
  next_framebuffer =
 | 
			
		||||
    cogl_dma_buf_handle_get_framebuffer (next_dma_buf_handle);
 | 
			
		||||
  cogl_clear_object (&priv->shadow.framebuffer);
 | 
			
		||||
  priv->shadow.framebuffer = cogl_object_ref (next_framebuffer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
copy_shadowfb_to_onscreen (ClutterStageView     *view,
 | 
			
		||||
                           const cairo_region_t *swap_region)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageViewPrivate *priv =
 | 
			
		||||
    clutter_stage_view_get_instance_private (view);
 | 
			
		||||
  ClutterDamageHistory *damage_history = priv->shadow.dma_buf.damage_history;
 | 
			
		||||
  cairo_region_t *damage_region;
 | 
			
		||||
  int age;
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  if (cairo_region_is_empty (swap_region))
 | 
			
		||||
    {
 | 
			
		||||
      cairo_rectangle_int_t full_damage = {
 | 
			
		||||
        .width = cogl_framebuffer_get_width (priv->framebuffer),
 | 
			
		||||
        .height = cogl_framebuffer_get_height (priv->framebuffer),
 | 
			
		||||
      };
 | 
			
		||||
      damage_region = cairo_region_create_rectangle (&full_damage);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      damage_region = cairo_region_copy (swap_region);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (is_shadowfb_double_buffered (view))
 | 
			
		||||
    {
 | 
			
		||||
      CoglOnscreen *onscreen = COGL_ONSCREEN (priv->framebuffer);
 | 
			
		||||
      cairo_region_t *changed_region;
 | 
			
		||||
 | 
			
		||||
      if (cogl_onscreen_get_frame_counter (onscreen) >= 1)
 | 
			
		||||
        {
 | 
			
		||||
          g_autoptr (GError) error = NULL;
 | 
			
		||||
 | 
			
		||||
          changed_region = find_damaged_tiles (view, damage_region, &error);
 | 
			
		||||
          if (!changed_region)
 | 
			
		||||
            {
 | 
			
		||||
              int other_dma_buf_idx;
 | 
			
		||||
 | 
			
		||||
              g_warning ("Disabling actual damage detection: %s",
 | 
			
		||||
                         error->message);
 | 
			
		||||
 | 
			
		||||
              other_dma_buf_idx =
 | 
			
		||||
                flip_dma_buf_idx (priv->shadow.dma_buf.current_idx);
 | 
			
		||||
              g_clear_pointer (&priv->shadow.dma_buf.handles[other_dma_buf_idx],
 | 
			
		||||
                               cogl_dma_buf_handle_free);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          changed_region = cairo_region_copy (damage_region);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      if (changed_region)
 | 
			
		||||
        {
 | 
			
		||||
          int buffer_age;
 | 
			
		||||
 | 
			
		||||
          clutter_damage_history_record (damage_history, changed_region);
 | 
			
		||||
 | 
			
		||||
          buffer_age = cogl_onscreen_get_buffer_age (onscreen);
 | 
			
		||||
          if (clutter_damage_history_is_age_valid (damage_history, buffer_age))
 | 
			
		||||
            {
 | 
			
		||||
              for (age = 1; age <= buffer_age; age++)
 | 
			
		||||
                {
 | 
			
		||||
                  const cairo_region_t *old_damage;
 | 
			
		||||
 | 
			
		||||
                  old_damage = clutter_damage_history_lookup (damage_history, age);
 | 
			
		||||
                  cairo_region_union (changed_region, old_damage);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
              cairo_region_destroy (damage_region);
 | 
			
		||||
              damage_region = g_steal_pointer (&changed_region);
 | 
			
		||||
            }
 | 
			
		||||
          else
 | 
			
		||||
            {
 | 
			
		||||
              cairo_region_destroy (changed_region);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          clutter_damage_history_step (damage_history);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < cairo_region_num_rectangles (damage_region); i++)
 | 
			
		||||
    {
 | 
			
		||||
      g_autoptr (GError) error = NULL;
 | 
			
		||||
      cairo_rectangle_int_t rect;
 | 
			
		||||
 | 
			
		||||
      cairo_region_get_rectangle (damage_region, i, &rect);
 | 
			
		||||
 | 
			
		||||
      if (!cogl_blit_framebuffer (priv->shadow.framebuffer,
 | 
			
		||||
                                  priv->framebuffer,
 | 
			
		||||
                                  rect.x, rect.y,
 | 
			
		||||
                                  rect.x, rect.y,
 | 
			
		||||
                                  rect.width, rect.height,
 | 
			
		||||
                                  &error))
 | 
			
		||||
        {
 | 
			
		||||
          g_warning ("Failed to blit shadow buffer: %s", error->message);
 | 
			
		||||
          cairo_region_destroy (damage_region);
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  cairo_region_destroy (damage_region);
 | 
			
		||||
 | 
			
		||||
  if (is_shadowfb_double_buffered (view))
 | 
			
		||||
    swap_dma_buf_framebuffer (view);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_stage_view_before_swap_buffer (ClutterStageView     *view,
 | 
			
		||||
                                       const cairo_region_t *swap_region)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageViewPrivate *priv =
 | 
			
		||||
    clutter_stage_view_get_instance_private (view);
 | 
			
		||||
 | 
			
		||||
  if (priv->shadow.framebuffer)
 | 
			
		||||
    copy_shadowfb_to_onscreen (view, swap_region);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float
 | 
			
		||||
@@ -260,6 +741,47 @@ clutter_stage_view_get_scale (ClutterStageView *view)
 | 
			
		||||
  return priv->scale;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef void (*FrontBufferCallback) (CoglFramebuffer *framebuffer,
 | 
			
		||||
                                     gconstpointer    user_data);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_stage_view_foreach_front_buffer (ClutterStageView    *view,
 | 
			
		||||
                                         FrontBufferCallback  callback,
 | 
			
		||||
                                         gconstpointer        user_data)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageViewPrivate *priv =
 | 
			
		||||
    clutter_stage_view_get_instance_private (view);
 | 
			
		||||
 | 
			
		||||
  if (priv->offscreen)
 | 
			
		||||
    {
 | 
			
		||||
      callback (priv->offscreen, user_data);
 | 
			
		||||
    }
 | 
			
		||||
  else if (priv->shadow.framebuffer)
 | 
			
		||||
    {
 | 
			
		||||
      if (is_shadowfb_double_buffered (view))
 | 
			
		||||
        {
 | 
			
		||||
          int i;
 | 
			
		||||
 | 
			
		||||
          for (i = 0; i < G_N_ELEMENTS (priv->shadow.dma_buf.handles); i++)
 | 
			
		||||
            {
 | 
			
		||||
              CoglDmaBufHandle *handle = priv->shadow.dma_buf.handles[i];
 | 
			
		||||
              CoglFramebuffer *framebuffer =
 | 
			
		||||
                cogl_dma_buf_handle_get_framebuffer (handle);
 | 
			
		||||
 | 
			
		||||
              callback (framebuffer, user_data);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          callback (priv->shadow.framebuffer, user_data);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      callback (priv->framebuffer, user_data);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
clutter_stage_view_is_dirty_viewport (ClutterStageView *view)
 | 
			
		||||
{
 | 
			
		||||
@@ -270,13 +792,47 @@ clutter_stage_view_is_dirty_viewport (ClutterStageView *view)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_stage_view_set_dirty_viewport (ClutterStageView *view,
 | 
			
		||||
                                       gboolean          dirty)
 | 
			
		||||
clutter_stage_view_invalidate_viewport (ClutterStageView *view)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageViewPrivate *priv =
 | 
			
		||||
    clutter_stage_view_get_instance_private (view);
 | 
			
		||||
 | 
			
		||||
  priv->dirty_viewport = dirty;
 | 
			
		||||
  priv->dirty_viewport = TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
set_framebuffer_viewport (CoglFramebuffer *framebuffer,
 | 
			
		||||
                          gconstpointer    user_data)
 | 
			
		||||
{
 | 
			
		||||
  const graphene_rect_t *rect = user_data;
 | 
			
		||||
 | 
			
		||||
  cogl_framebuffer_set_viewport (framebuffer,
 | 
			
		||||
                                 rect->origin.x,
 | 
			
		||||
                                 rect->origin.y,
 | 
			
		||||
                                 rect->size.width,
 | 
			
		||||
                                 rect->size.height);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_stage_view_set_viewport (ClutterStageView *view,
 | 
			
		||||
                                 float             x,
 | 
			
		||||
                                 float             y,
 | 
			
		||||
                                 float             width,
 | 
			
		||||
                                 float             height)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageViewPrivate *priv =
 | 
			
		||||
    clutter_stage_view_get_instance_private (view);
 | 
			
		||||
  graphene_rect_t rect;
 | 
			
		||||
 | 
			
		||||
  priv->dirty_viewport = FALSE;
 | 
			
		||||
 | 
			
		||||
  rect = (graphene_rect_t) {
 | 
			
		||||
    .origin = { .x = x, .y = y },
 | 
			
		||||
    .size = { .width = width, .height = height },
 | 
			
		||||
  };
 | 
			
		||||
  clutter_stage_view_foreach_front_buffer (view,
 | 
			
		||||
                                           set_framebuffer_viewport,
 | 
			
		||||
                                           &rect);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
@@ -288,14 +844,33 @@ clutter_stage_view_is_dirty_projection (ClutterStageView *view)
 | 
			
		||||
  return priv->dirty_projection;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
set_framebuffer_projection_matrix (CoglFramebuffer *framebuffer,
 | 
			
		||||
                                   gconstpointer    user_data)
 | 
			
		||||
{
 | 
			
		||||
  cogl_framebuffer_set_projection_matrix (framebuffer, user_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_stage_view_set_dirty_projection (ClutterStageView *view,
 | 
			
		||||
                                         gboolean          dirty)
 | 
			
		||||
clutter_stage_view_invalidate_projection (ClutterStageView *view)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageViewPrivate *priv =
 | 
			
		||||
    clutter_stage_view_get_instance_private (view);
 | 
			
		||||
 | 
			
		||||
  priv->dirty_projection = dirty;
 | 
			
		||||
  priv->dirty_projection = TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_stage_view_set_projection (ClutterStageView *view,
 | 
			
		||||
                                   const CoglMatrix *matrix)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageViewPrivate *priv =
 | 
			
		||||
    clutter_stage_view_get_instance_private (view);
 | 
			
		||||
 | 
			
		||||
  priv->dirty_projection = FALSE;
 | 
			
		||||
  clutter_stage_view_foreach_front_buffer (view,
 | 
			
		||||
                                           set_framebuffer_projection_matrix,
 | 
			
		||||
                                           matrix);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -387,19 +962,6 @@ clutter_stage_view_take_redraw_clip (ClutterStageView *view)
 | 
			
		||||
  return g_steal_pointer (&priv->redraw_clip);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_stage_view_transform_to_onscreen (ClutterStageView *view,
 | 
			
		||||
                                          gfloat           *x,
 | 
			
		||||
                                          gfloat           *y)
 | 
			
		||||
{
 | 
			
		||||
  gfloat z = 0, w = 1;
 | 
			
		||||
  CoglMatrix matrix;
 | 
			
		||||
 | 
			
		||||
  clutter_stage_view_get_offscreen_transformation_matrix (view, &matrix);
 | 
			
		||||
  cogl_matrix_get_inverse (&matrix, &matrix);
 | 
			
		||||
  cogl_matrix_transform_point (&matrix, x, y, &z, &w);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_stage_default_get_offscreen_transformation_matrix (ClutterStageView *view,
 | 
			
		||||
                                                           CoglMatrix       *matrix)
 | 
			
		||||
@@ -407,6 +969,25 @@ clutter_stage_default_get_offscreen_transformation_matrix (ClutterStageView *vie
 | 
			
		||||
  cogl_matrix_init_identity (matrix);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clutter_stage_view_assign_next_scanout (ClutterStageView *view,
 | 
			
		||||
                                        CoglScanout      *scanout)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageViewPrivate *priv =
 | 
			
		||||
    clutter_stage_view_get_instance_private (view);
 | 
			
		||||
 | 
			
		||||
  g_set_object (&priv->next_scanout, scanout);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CoglScanout *
 | 
			
		||||
clutter_stage_view_take_scanout (ClutterStageView *view)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageViewPrivate *priv =
 | 
			
		||||
    clutter_stage_view_get_instance_private (view);
 | 
			
		||||
 | 
			
		||||
  return g_steal_pointer (&priv->next_scanout);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_stage_view_get_property (GObject    *object,
 | 
			
		||||
                                 guint       prop_id,
 | 
			
		||||
@@ -419,6 +1000,9 @@ clutter_stage_view_get_property (GObject    *object,
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_NAME:
 | 
			
		||||
      g_value_set_string (value, priv->name);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_LAYOUT:
 | 
			
		||||
      g_value_set_boxed (value, &priv->layout);
 | 
			
		||||
      break;
 | 
			
		||||
@@ -428,8 +1012,8 @@ clutter_stage_view_get_property (GObject    *object,
 | 
			
		||||
    case PROP_OFFSCREEN:
 | 
			
		||||
      g_value_set_boxed (value, priv->offscreen);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_SHADOWFB:
 | 
			
		||||
      g_value_set_boxed (value, priv->shadowfb);
 | 
			
		||||
    case PROP_USE_SHADOWFB:
 | 
			
		||||
      g_value_set_boolean (value, priv->use_shadowfb);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_SCALE:
 | 
			
		||||
      g_value_set_float (value, priv->scale);
 | 
			
		||||
@@ -452,6 +1036,9 @@ clutter_stage_view_set_property (GObject      *object,
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_NAME:
 | 
			
		||||
      priv->name = g_value_dup_string (value);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_LAYOUT:
 | 
			
		||||
      layout = g_value_get_boxed (value);
 | 
			
		||||
      priv->layout = *layout;
 | 
			
		||||
@@ -476,8 +1063,8 @@ clutter_stage_view_set_property (GObject      *object,
 | 
			
		||||
    case PROP_OFFSCREEN:
 | 
			
		||||
      priv->offscreen = g_value_dup_boxed (value);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_SHADOWFB:
 | 
			
		||||
      priv->shadowfb = g_value_dup_boxed (value);
 | 
			
		||||
    case PROP_USE_SHADOWFB:
 | 
			
		||||
      priv->use_shadowfb = g_value_get_boolean (value);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_SCALE:
 | 
			
		||||
      priv->scale = g_value_get_float (value);
 | 
			
		||||
@@ -488,17 +1075,40 @@ clutter_stage_view_set_property (GObject      *object,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_stage_view_dispose (GObject *object)
 | 
			
		||||
clutter_stage_view_constructed (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageView *view = CLUTTER_STAGE_VIEW (object);
 | 
			
		||||
  ClutterStageViewPrivate *priv =
 | 
			
		||||
    clutter_stage_view_get_instance_private (view);
 | 
			
		||||
 | 
			
		||||
  if (priv->use_shadowfb)
 | 
			
		||||
    init_shadowfb (view);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (clutter_stage_view_parent_class)->constructed (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_stage_view_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageView *view = CLUTTER_STAGE_VIEW (object);
 | 
			
		||||
  ClutterStageViewPrivate *priv =
 | 
			
		||||
    clutter_stage_view_get_instance_private (view);
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  g_clear_pointer (&priv->name, g_free);
 | 
			
		||||
  g_clear_pointer (&priv->framebuffer, cogl_object_unref);
 | 
			
		||||
  g_clear_pointer (&priv->shadowfb, cogl_object_unref);
 | 
			
		||||
 | 
			
		||||
  g_clear_pointer (&priv->shadow.framebuffer, cogl_object_unref);
 | 
			
		||||
  for (i = 0; i < G_N_ELEMENTS (priv->shadow.dma_buf.handles); i++)
 | 
			
		||||
    {
 | 
			
		||||
      g_clear_pointer (&priv->shadow.dma_buf.handles[i],
 | 
			
		||||
                       cogl_dma_buf_handle_free);
 | 
			
		||||
    }
 | 
			
		||||
  g_clear_pointer (&priv->shadow.dma_buf.damage_history,
 | 
			
		||||
                   clutter_damage_history_free);
 | 
			
		||||
 | 
			
		||||
  g_clear_pointer (&priv->offscreen, cogl_object_unref);
 | 
			
		||||
  g_clear_pointer (&priv->offscreen_pipeline, cogl_object_unref);
 | 
			
		||||
  g_clear_pointer (&priv->shadowfb_pipeline, cogl_object_unref);
 | 
			
		||||
  g_clear_pointer (&priv->redraw_clip, cairo_region_destroy);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (clutter_stage_view_parent_class)->dispose (object);
 | 
			
		||||
@@ -525,8 +1135,17 @@ clutter_stage_view_class_init (ClutterStageViewClass *klass)
 | 
			
		||||
 | 
			
		||||
  object_class->get_property = clutter_stage_view_get_property;
 | 
			
		||||
  object_class->set_property = clutter_stage_view_set_property;
 | 
			
		||||
  object_class->constructed = clutter_stage_view_constructed;
 | 
			
		||||
  object_class->dispose = clutter_stage_view_dispose;
 | 
			
		||||
 | 
			
		||||
  obj_props[PROP_NAME] =
 | 
			
		||||
    g_param_spec_string ("name",
 | 
			
		||||
                         "Name",
 | 
			
		||||
                         "Name of view",
 | 
			
		||||
                         NULL,
 | 
			
		||||
                         G_PARAM_READWRITE |
 | 
			
		||||
                         G_PARAM_CONSTRUCT_ONLY |
 | 
			
		||||
                         G_PARAM_STATIC_STRINGS);
 | 
			
		||||
  obj_props[PROP_LAYOUT] =
 | 
			
		||||
    g_param_spec_boxed ("layout",
 | 
			
		||||
                        "View layout",
 | 
			
		||||
@@ -554,14 +1173,14 @@ clutter_stage_view_class_init (ClutterStageViewClass *klass)
 | 
			
		||||
                        G_PARAM_CONSTRUCT_ONLY |
 | 
			
		||||
                        G_PARAM_STATIC_STRINGS);
 | 
			
		||||
 | 
			
		||||
  obj_props[PROP_SHADOWFB] =
 | 
			
		||||
    g_param_spec_boxed ("shadowfb",
 | 
			
		||||
                        "Shadow framebuffer",
 | 
			
		||||
                        "Framebuffer used as intermediate shadow buffer",
 | 
			
		||||
                        COGL_TYPE_HANDLE,
 | 
			
		||||
                        G_PARAM_READWRITE |
 | 
			
		||||
                        G_PARAM_CONSTRUCT_ONLY |
 | 
			
		||||
                        G_PARAM_STATIC_STRINGS);
 | 
			
		||||
  obj_props[PROP_USE_SHADOWFB] =
 | 
			
		||||
    g_param_spec_boolean ("use-shadowfb",
 | 
			
		||||
                          "Use shadowfb",
 | 
			
		||||
                          "Whether to use one or more shadow framebuffers",
 | 
			
		||||
                          FALSE,
 | 
			
		||||
                          G_PARAM_READWRITE |
 | 
			
		||||
                          G_PARAM_CONSTRUCT_ONLY |
 | 
			
		||||
                          G_PARAM_STATIC_STRINGS);
 | 
			
		||||
 | 
			
		||||
  obj_props[PROP_SCALE] =
 | 
			
		||||
    g_param_spec_float ("scale",
 | 
			
		||||
 
 | 
			
		||||
@@ -43,6 +43,12 @@ struct _ClutterStageViewClass
 | 
			
		||||
 | 
			
		||||
  void (* get_offscreen_transformation_matrix) (ClutterStageView *view,
 | 
			
		||||
                                                CoglMatrix       *matrix);
 | 
			
		||||
 | 
			
		||||
  void (* transform_rect_to_onscreen) (ClutterStageView            *view,
 | 
			
		||||
                                       const cairo_rectangle_int_t *src_rect,
 | 
			
		||||
                                       int                          dst_width,
 | 
			
		||||
                                       int                          dst_height,
 | 
			
		||||
                                       cairo_rectangle_int_t       *dst_rect);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
@@ -56,11 +62,6 @@ CoglFramebuffer *clutter_stage_view_get_onscreen (ClutterStageView *view);
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void             clutter_stage_view_invalidate_offscreen_blit_pipeline (ClutterStageView *view);
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void             clutter_stage_view_transform_to_onscreen (ClutterStageView *view,
 | 
			
		||||
                                                           gfloat           *x,
 | 
			
		||||
                                                           gfloat           *y);
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
float clutter_stage_view_get_scale (ClutterStageView *view);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -142,6 +142,8 @@ struct _ClutterStagePrivate
 | 
			
		||||
 | 
			
		||||
  int update_freeze_count;
 | 
			
		||||
 | 
			
		||||
  gboolean needs_update;
 | 
			
		||||
 | 
			
		||||
  guint redraw_pending         : 1;
 | 
			
		||||
  guint throttle_motion_events : 1;
 | 
			
		||||
  guint min_size_changed       : 1;
 | 
			
		||||
@@ -552,7 +554,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;
 | 
			
		||||
 | 
			
		||||
@@ -613,8 +615,7 @@ stage_is_default (ClutterStage *stage)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_stage_allocate (ClutterActor           *self,
 | 
			
		||||
                        const ClutterActorBox  *box,
 | 
			
		||||
                        ClutterAllocationFlags  flags)
 | 
			
		||||
                        const ClutterActorBox  *box)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv;
 | 
			
		||||
  ClutterActorBox alloc = CLUTTER_ACTOR_BOX_INIT_ZERO;
 | 
			
		||||
@@ -622,6 +623,7 @@ clutter_stage_allocate (ClutterActor           *self,
 | 
			
		||||
  float new_width, new_height;
 | 
			
		||||
  float width, height;
 | 
			
		||||
  cairo_rectangle_int_t window_size;
 | 
			
		||||
  ClutterLayoutManager *layout_manager = clutter_actor_get_layout_manager (self);
 | 
			
		||||
 | 
			
		||||
  if (priv->impl == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
@@ -643,15 +645,21 @@ clutter_stage_allocate (ClutterActor           *self,
 | 
			
		||||
   */
 | 
			
		||||
  if (!clutter_feature_available (CLUTTER_FEATURE_STAGE_STATIC))
 | 
			
		||||
    {
 | 
			
		||||
      CLUTTER_NOTE (LAYOUT,
 | 
			
		||||
                    "Following allocation to %.2fx%.2f (absolute origin %s)",
 | 
			
		||||
                    width, height,
 | 
			
		||||
                    (flags & CLUTTER_ABSOLUTE_ORIGIN_CHANGED)
 | 
			
		||||
                      ? "changed"
 | 
			
		||||
                      : "not changed");
 | 
			
		||||
      ClutterActorBox children_box;
 | 
			
		||||
 | 
			
		||||
      clutter_actor_set_allocation (self, box,
 | 
			
		||||
                                    flags | CLUTTER_DELEGATE_LAYOUT);
 | 
			
		||||
      children_box.x1 = children_box.y1 = 0.f;
 | 
			
		||||
      children_box.x2 = box->x2 - box->x1;
 | 
			
		||||
      children_box.y2 = box->y2 - box->y1;
 | 
			
		||||
 | 
			
		||||
      CLUTTER_NOTE (LAYOUT,
 | 
			
		||||
                    "Following allocation to %.2fx%.2f",
 | 
			
		||||
                    width, height);
 | 
			
		||||
 | 
			
		||||
      clutter_actor_set_allocation (self, box);
 | 
			
		||||
 | 
			
		||||
      clutter_layout_manager_allocate (layout_manager,
 | 
			
		||||
                                       CLUTTER_CONTAINER (self),
 | 
			
		||||
                                       &children_box);
 | 
			
		||||
 | 
			
		||||
      /* Ensure the window is sized correctly */
 | 
			
		||||
      if (priv->min_size_changed)
 | 
			
		||||
@@ -699,16 +707,16 @@ clutter_stage_allocate (ClutterActor           *self,
 | 
			
		||||
 | 
			
		||||
      CLUTTER_NOTE (LAYOUT,
 | 
			
		||||
                    "Overriding original allocation of %.2fx%.2f "
 | 
			
		||||
                    "with %.2fx%.2f (absolute origin %s)",
 | 
			
		||||
                    "with %.2fx%.2f",
 | 
			
		||||
                    width, height,
 | 
			
		||||
                    override.x2, override.y2,
 | 
			
		||||
                    (flags & CLUTTER_ABSOLUTE_ORIGIN_CHANGED)
 | 
			
		||||
                      ? "changed"
 | 
			
		||||
                      : "not changed");
 | 
			
		||||
                    override.x2, override.y2);
 | 
			
		||||
 | 
			
		||||
      /* and store the overridden allocation */
 | 
			
		||||
      clutter_actor_set_allocation (self, &override,
 | 
			
		||||
                                    flags | CLUTTER_DELEGATE_LAYOUT);
 | 
			
		||||
      clutter_actor_set_allocation (self, &override);
 | 
			
		||||
 | 
			
		||||
      clutter_layout_manager_allocate (layout_manager,
 | 
			
		||||
                                       CLUTTER_CONTAINER (self),
 | 
			
		||||
                                       &override);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* reset the viewport if the allocation effectively changed */
 | 
			
		||||
@@ -924,7 +932,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);
 | 
			
		||||
@@ -1169,7 +1178,7 @@ _clutter_stage_queue_event (ClutterStage *stage,
 | 
			
		||||
    {
 | 
			
		||||
      ClutterMasterClock *master_clock = _clutter_master_clock_get_default ();
 | 
			
		||||
      _clutter_master_clock_start_running (master_clock);
 | 
			
		||||
      _clutter_stage_schedule_update (stage);
 | 
			
		||||
      clutter_stage_schedule_update (stage);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1301,7 +1310,9 @@ _clutter_stage_needs_update (ClutterStage *stage)
 | 
			
		||||
 | 
			
		||||
  priv = stage->priv;
 | 
			
		||||
 | 
			
		||||
  return priv->redraw_pending || g_hash_table_size (priv->pending_relayouts) > 0;
 | 
			
		||||
  return (priv->redraw_pending ||
 | 
			
		||||
          priv->needs_update ||
 | 
			
		||||
          g_hash_table_size (priv->pending_relayouts) > 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -1311,7 +1322,7 @@ clutter_stage_queue_actor_relayout (ClutterStage *stage,
 | 
			
		||||
  ClutterStagePrivate *priv = stage->priv;
 | 
			
		||||
 | 
			
		||||
  if (g_hash_table_size (priv->pending_relayouts) == 0)
 | 
			
		||||
    _clutter_stage_schedule_update (stage);
 | 
			
		||||
    clutter_stage_schedule_update (stage);
 | 
			
		||||
 | 
			
		||||
  g_hash_table_add (priv->pending_relayouts, g_object_ref (actor));
 | 
			
		||||
  priv->pending_relayouts_version++;
 | 
			
		||||
@@ -1358,8 +1369,7 @@ _clutter_stage_maybe_relayout (ClutterActor *actor)
 | 
			
		||||
      CLUTTER_SET_PRIVATE_FLAGS (queued_actor, CLUTTER_IN_RELAYOUT);
 | 
			
		||||
 | 
			
		||||
      old_version = priv->pending_relayouts_version;
 | 
			
		||||
      clutter_actor_allocate_preferred_size (queued_actor,
 | 
			
		||||
                                             CLUTTER_ALLOCATION_NONE);
 | 
			
		||||
      clutter_actor_allocate_preferred_size (queued_actor);
 | 
			
		||||
 | 
			
		||||
      CLUTTER_UNSET_PRIVATE_FLAGS (queued_actor, CLUTTER_IN_RELAYOUT);
 | 
			
		||||
 | 
			
		||||
@@ -1493,6 +1503,8 @@ _clutter_stage_do_update (ClutterStage *stage)
 | 
			
		||||
 | 
			
		||||
  priv->stage_was_relayout = FALSE;
 | 
			
		||||
 | 
			
		||||
  priv->needs_update = FALSE;
 | 
			
		||||
 | 
			
		||||
  /* if the stage is being destroyed, or if the destruction already
 | 
			
		||||
   * happened and we don't have an StageWindow any more, then we
 | 
			
		||||
   * should bail out
 | 
			
		||||
@@ -1572,7 +1584,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;
 | 
			
		||||
 | 
			
		||||
@@ -2428,7 +2440,7 @@ _clutter_stage_dirty_projection (ClutterStage *stage)
 | 
			
		||||
    {
 | 
			
		||||
      ClutterStageView *view = l->data;
 | 
			
		||||
 | 
			
		||||
      clutter_stage_view_set_dirty_projection (view, TRUE);
 | 
			
		||||
      clutter_stage_view_invalidate_projection (view);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -2518,7 +2530,7 @@ _clutter_stage_dirty_viewport (ClutterStage *stage)
 | 
			
		||||
    {
 | 
			
		||||
      ClutterStageView *view = l->data;
 | 
			
		||||
 | 
			
		||||
      clutter_stage_view_set_dirty_viewport (view, TRUE);
 | 
			
		||||
      clutter_stage_view_invalidate_viewport (view);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -3141,7 +3153,6 @@ _clutter_stage_maybe_setup_viewport (ClutterStage     *stage,
 | 
			
		||||
                                     ClutterStageView *view)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStagePrivate *priv = stage->priv;
 | 
			
		||||
  CoglFramebuffer *fb = clutter_stage_view_get_framebuffer (view);
 | 
			
		||||
 | 
			
		||||
  if (clutter_stage_view_is_dirty_viewport (view))
 | 
			
		||||
    {
 | 
			
		||||
@@ -3168,19 +3179,14 @@ _clutter_stage_maybe_setup_viewport (ClutterStage     *stage,
 | 
			
		||||
      viewport_y = roundf (priv->viewport[1] * fb_scale - viewport_offset_y);
 | 
			
		||||
      viewport_width = roundf (priv->viewport[2] * fb_scale);
 | 
			
		||||
      viewport_height = roundf (priv->viewport[3] * fb_scale);
 | 
			
		||||
      cogl_framebuffer_set_viewport (fb,
 | 
			
		||||
                                     viewport_x, viewport_y,
 | 
			
		||||
                                     viewport_width, viewport_height);
 | 
			
		||||
 | 
			
		||||
      clutter_stage_view_set_dirty_viewport (view, FALSE);
 | 
			
		||||
      clutter_stage_view_set_viewport (view,
 | 
			
		||||
                                       viewport_x, viewport_y,
 | 
			
		||||
                                       viewport_width, viewport_height);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (clutter_stage_view_is_dirty_projection (view))
 | 
			
		||||
    {
 | 
			
		||||
      cogl_framebuffer_set_projection_matrix (fb, &priv->projection);
 | 
			
		||||
 | 
			
		||||
      clutter_stage_view_set_dirty_projection (view, FALSE);
 | 
			
		||||
    }
 | 
			
		||||
    clutter_stage_view_set_projection (view, &priv->projection);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#undef _DEG_TO_RAD
 | 
			
		||||
@@ -3208,7 +3214,7 @@ clutter_stage_ensure_redraw (ClutterStage *stage)
 | 
			
		||||
  priv = stage->priv;
 | 
			
		||||
 | 
			
		||||
  if (!_clutter_stage_needs_update (stage))
 | 
			
		||||
    _clutter_stage_schedule_update (stage);
 | 
			
		||||
    clutter_stage_schedule_update (stage);
 | 
			
		||||
 | 
			
		||||
  priv->redraw_pending = TRUE;
 | 
			
		||||
 | 
			
		||||
@@ -3436,13 +3442,13 @@ clutter_stage_get_minimum_size (ClutterStage *stage,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * _clutter_stage_schedule_update:
 | 
			
		||||
 * @window: a #ClutterStage actor
 | 
			
		||||
 * clutter_stage_schedule_update:
 | 
			
		||||
 * @stage: a #ClutterStage actor
 | 
			
		||||
 *
 | 
			
		||||
 * Schedules a redraw of the #ClutterStage at the next optimal timestamp.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
_clutter_stage_schedule_update (ClutterStage *stage)
 | 
			
		||||
clutter_stage_schedule_update (ClutterStage *stage)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageWindow *stage_window;
 | 
			
		||||
 | 
			
		||||
@@ -3453,6 +3459,8 @@ _clutter_stage_schedule_update (ClutterStage *stage)
 | 
			
		||||
  if (stage_window == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  stage->priv->needs_update = TRUE;
 | 
			
		||||
 | 
			
		||||
  return _clutter_stage_window_schedule_update (stage_window,
 | 
			
		||||
                                                stage->priv->sync_delay);
 | 
			
		||||
}
 | 
			
		||||
@@ -3462,7 +3470,7 @@ _clutter_stage_schedule_update (ClutterStage *stage)
 | 
			
		||||
 * @stage: a #ClutterStage actor
 | 
			
		||||
 *
 | 
			
		||||
 * Returns the earliest time in which the stage is ready to update. The update
 | 
			
		||||
 * time is set when _clutter_stage_schedule_update() is called. This can then
 | 
			
		||||
 * time is set when clutter_stage_schedule_update() is called. This can then
 | 
			
		||||
 * be used by e.g. the #ClutterMasterClock to know when the stage needs to be
 | 
			
		||||
 * redrawn.
 | 
			
		||||
 *
 | 
			
		||||
@@ -3572,7 +3580,7 @@ _clutter_stage_queue_actor_redraw (ClutterStage                 *stage,
 | 
			
		||||
 | 
			
		||||
      CLUTTER_NOTE (PAINT, "First redraw request");
 | 
			
		||||
 | 
			
		||||
      _clutter_stage_schedule_update (stage);
 | 
			
		||||
      clutter_stage_schedule_update (stage);
 | 
			
		||||
      priv->redraw_pending = TRUE;
 | 
			
		||||
 | 
			
		||||
      master_clock = _clutter_master_clock_get_default ();
 | 
			
		||||
@@ -4163,6 +4171,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 +4409,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;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -209,6 +209,9 @@ CLUTTER_EXPORT
 | 
			
		||||
void            clutter_stage_skip_sync_delay                   (ClutterStage          *stage);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
void clutter_stage_schedule_update (ClutterStage *stage);
 | 
			
		||||
 | 
			
		||||
CLUTTER_EXPORT
 | 
			
		||||
gboolean clutter_stage_get_capture_final_size (ClutterStage          *stage,
 | 
			
		||||
                                               cairo_rectangle_int_t *rect,
 | 
			
		||||
 
 | 
			
		||||
@@ -3037,8 +3037,7 @@ clutter_text_get_preferred_height (ClutterActor *self,
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_text_allocate (ClutterActor           *self,
 | 
			
		||||
                       const ClutterActorBox  *box,
 | 
			
		||||
                       ClutterAllocationFlags  flags)
 | 
			
		||||
                       const ClutterActorBox  *box)
 | 
			
		||||
{
 | 
			
		||||
  ClutterText *text = CLUTTER_TEXT (self);
 | 
			
		||||
  ClutterActorClass *parent_class;
 | 
			
		||||
@@ -3058,7 +3057,7 @@ clutter_text_allocate (ClutterActor           *self,
 | 
			
		||||
                                                  box->y2 - box->y1);
 | 
			
		||||
 | 
			
		||||
  parent_class = CLUTTER_ACTOR_CLASS (clutter_text_parent_class);
 | 
			
		||||
  parent_class->allocate (self, box, flags);
 | 
			
		||||
  parent_class->allocate (self, box);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
@@ -4787,11 +4786,11 @@ clutter_text_queue_redraw_or_relayout (ClutterText *self)
 | 
			
		||||
  clutter_text_get_preferred_height (actor, preferred_width, NULL, &preferred_height);
 | 
			
		||||
 | 
			
		||||
  if (clutter_actor_has_allocation (actor) &&
 | 
			
		||||
      (fabsf (preferred_width - clutter_actor_get_width (actor)) > 0.001 ||
 | 
			
		||||
       fabsf (preferred_height - clutter_actor_get_height (actor)) > 0.001))
 | 
			
		||||
    clutter_actor_queue_relayout (actor);
 | 
			
		||||
  else
 | 
			
		||||
      fabsf (preferred_width - clutter_actor_get_width (actor)) <= 0.001 &&
 | 
			
		||||
      fabsf (preferred_height - clutter_actor_get_height (actor)) <= 0.001)
 | 
			
		||||
    clutter_text_queue_redraw (actor);
 | 
			
		||||
  else
 | 
			
		||||
    clutter_actor_queue_relayout (actor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -38,6 +38,7 @@
 | 
			
		||||
 | 
			
		||||
#include "clutter-actor-private.h"
 | 
			
		||||
#include "clutter-backend-private.h"
 | 
			
		||||
#include "clutter-damage-history.h"
 | 
			
		||||
#include "clutter-debug.h"
 | 
			
		||||
#include "clutter-event.h"
 | 
			
		||||
#include "clutter-enum-types.h"
 | 
			
		||||
@@ -51,13 +52,9 @@
 | 
			
		||||
 | 
			
		||||
typedef struct _ClutterStageViewCoglPrivate
 | 
			
		||||
{
 | 
			
		||||
  /*
 | 
			
		||||
   * List of previous damaged areas in stage view framebuffer coordinate space.
 | 
			
		||||
  /* Damage history, in stage view render target framebuffer coordinate space.
 | 
			
		||||
   */
 | 
			
		||||
#define DAMAGE_HISTORY_MAX 16
 | 
			
		||||
#define DAMAGE_HISTORY(x) ((x) & (DAMAGE_HISTORY_MAX - 1))
 | 
			
		||||
  cairo_region_t * damage_history[DAMAGE_HISTORY_MAX];
 | 
			
		||||
  unsigned int damage_index;
 | 
			
		||||
  ClutterDamageHistory *damage_history;
 | 
			
		||||
} ClutterStageViewCoglPrivate;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (ClutterStageViewCogl, clutter_stage_view_cogl,
 | 
			
		||||
@@ -288,26 +285,13 @@ clutter_stage_cogl_resize (ClutterStageWindow *stage_window,
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline gboolean
 | 
			
		||||
valid_buffer_age (ClutterStageViewCogl *view_cogl,
 | 
			
		||||
                  int                   age)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageViewCoglPrivate *view_priv =
 | 
			
		||||
    clutter_stage_view_cogl_get_instance_private (view_cogl);
 | 
			
		||||
 | 
			
		||||
  if (age <= 0)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  return age < MIN (view_priv->damage_index, DAMAGE_HISTORY_MAX);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
paint_damage_region (ClutterStageWindow *stage_window,
 | 
			
		||||
                     ClutterStageView   *view,
 | 
			
		||||
                     cairo_region_t     *swap_region,
 | 
			
		||||
                     cairo_region_t     *queued_redraw_clip)
 | 
			
		||||
{
 | 
			
		||||
  CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (view);
 | 
			
		||||
  CoglFramebuffer *framebuffer = clutter_stage_view_get_framebuffer (view);
 | 
			
		||||
  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
 | 
			
		||||
  static CoglPipeline *overlay_blue = NULL;
 | 
			
		||||
  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
 | 
			
		||||
@@ -375,31 +359,29 @@ 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++)
 | 
			
		||||
    {
 | 
			
		||||
      cairo_rectangle_int_t rect;
 | 
			
		||||
 | 
			
		||||
      cairo_region_get_rectangle (swap_region, i, &rect);
 | 
			
		||||
      damage[i * 4] = rect.x;
 | 
			
		||||
      damage[i * 4 + 1] = rect.y;
 | 
			
		||||
      damage[i * 4 + 2] = rect.width;
 | 
			
		||||
      damage[i * 4 + 3] = rect.height;
 | 
			
		||||
    }
 | 
			
		||||
  clutter_stage_view_before_swap_buffer (view, swap_region);
 | 
			
		||||
 | 
			
		||||
  if (cogl_is_onscreen (framebuffer))
 | 
			
		||||
    {
 | 
			
		||||
      CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
 | 
			
		||||
      int *damage, n_rects, i;
 | 
			
		||||
 | 
			
		||||
      n_rects = cairo_region_num_rectangles (swap_region);
 | 
			
		||||
      damage = g_newa (int, n_rects * 4);
 | 
			
		||||
      for (i = 0; i < n_rects; i++)
 | 
			
		||||
        {
 | 
			
		||||
          cairo_rectangle_int_t rect;
 | 
			
		||||
 | 
			
		||||
          cairo_region_get_rectangle (swap_region, i, &rect);
 | 
			
		||||
          damage[i * 4] = rect.x;
 | 
			
		||||
          damage[i * 4 + 1] = rect.y;
 | 
			
		||||
          damage[i * 4 + 2] = rect.width;
 | 
			
		||||
          damage[i * 4 + 3] = rect.height;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      /* push on the screen */
 | 
			
		||||
      if (n_rects > 0 && !swap_with_damage)
 | 
			
		||||
@@ -434,18 +416,6 @@ swap_framebuffer (ClutterStageWindow *stage_window,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
scale_and_clamp_rect (const graphene_rect_t *rect,
 | 
			
		||||
                      float                  scale,
 | 
			
		||||
                      cairo_rectangle_int_t *dest)
 | 
			
		||||
 | 
			
		||||
{
 | 
			
		||||
  graphene_rect_t tmp = *rect;
 | 
			
		||||
 | 
			
		||||
  graphene_rect_scale (&tmp, scale, scale, &tmp);
 | 
			
		||||
  _clutter_util_rectangle_int_extents (&tmp, dest);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static cairo_region_t *
 | 
			
		||||
offset_scale_and_clamp_region (const cairo_region_t *region,
 | 
			
		||||
                               int                   offset_x,
 | 
			
		||||
@@ -467,15 +437,52 @@ offset_scale_and_clamp_region (const cairo_region_t *region,
 | 
			
		||||
    rects = freeme = g_new (cairo_rectangle_int_t, n_rects);
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < n_rects; i++)
 | 
			
		||||
    cairo_region_get_rectangle (region, i, &rects[i]);
 | 
			
		||||
    {
 | 
			
		||||
      cairo_rectangle_int_t *rect = &rects[i];
 | 
			
		||||
      graphene_rect_t tmp;
 | 
			
		||||
 | 
			
		||||
      cairo_region_get_rectangle (region, i, rect);
 | 
			
		||||
 | 
			
		||||
      _clutter_util_rect_from_rectangle (rect, &tmp);
 | 
			
		||||
      graphene_rect_offset (&tmp, offset_x, offset_y);
 | 
			
		||||
      graphene_rect_scale (&tmp, scale, scale, &tmp);
 | 
			
		||||
      _clutter_util_rectangle_int_extents (&tmp, rect);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return cairo_region_create_rectangles (rects, n_rects);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static cairo_region_t *
 | 
			
		||||
scale_offset_and_clamp_region (const cairo_region_t *region,
 | 
			
		||||
                               float                 scale,
 | 
			
		||||
                               int                   offset_x,
 | 
			
		||||
                               int                   offset_y)
 | 
			
		||||
{
 | 
			
		||||
  int n_rects, i;
 | 
			
		||||
  cairo_rectangle_int_t *rects;
 | 
			
		||||
  g_autofree cairo_rectangle_int_t *freeme = NULL;
 | 
			
		||||
 | 
			
		||||
  n_rects = cairo_region_num_rectangles (region);
 | 
			
		||||
 | 
			
		||||
  if (n_rects == 0)
 | 
			
		||||
    return cairo_region_create ();
 | 
			
		||||
 | 
			
		||||
  if (n_rects < MAX_STACK_RECTS)
 | 
			
		||||
    rects = g_newa (cairo_rectangle_int_t, n_rects);
 | 
			
		||||
  else
 | 
			
		||||
    rects = freeme = g_new (cairo_rectangle_int_t, n_rects);
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < n_rects; i++)
 | 
			
		||||
    {
 | 
			
		||||
      cairo_rectangle_int_t *rect = &rects[i];
 | 
			
		||||
      graphene_rect_t tmp;
 | 
			
		||||
 | 
			
		||||
      _clutter_util_rect_from_rectangle (&rects[i], &tmp);
 | 
			
		||||
      cairo_region_get_rectangle (region, i, rect);
 | 
			
		||||
 | 
			
		||||
      _clutter_util_rect_from_rectangle (rect, &tmp);
 | 
			
		||||
      graphene_rect_scale (&tmp, scale, scale, &tmp);
 | 
			
		||||
      graphene_rect_offset (&tmp, offset_x, offset_y);
 | 
			
		||||
      scale_and_clamp_rect (&tmp, scale, &rects[i]);
 | 
			
		||||
      _clutter_util_rectangle_int_extents (&tmp, rect);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return cairo_region_create_rectangles (rects, n_rects);
 | 
			
		||||
@@ -491,107 +498,38 @@ paint_stage (ClutterStageCogl *stage_cogl,
 | 
			
		||||
  _clutter_stage_maybe_setup_viewport (stage, view);
 | 
			
		||||
  clutter_stage_paint_view (stage, view, redraw_clip);
 | 
			
		||||
 | 
			
		||||
  clutter_stage_view_after_paint (view);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
fill_current_damage_history (ClutterStageView *view,
 | 
			
		||||
                             cairo_region_t   *damage)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageViewCogl *view_cogl = CLUTTER_STAGE_VIEW_COGL (view);
 | 
			
		||||
  ClutterStageViewCoglPrivate *view_priv =
 | 
			
		||||
    clutter_stage_view_cogl_get_instance_private (view_cogl);
 | 
			
		||||
  cairo_region_t **current_fb_damage;
 | 
			
		||||
 | 
			
		||||
  current_fb_damage =
 | 
			
		||||
    &view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index)];
 | 
			
		||||
 | 
			
		||||
  g_clear_pointer (current_fb_damage, cairo_region_destroy);
 | 
			
		||||
  *current_fb_damage = cairo_region_copy (damage);
 | 
			
		||||
  view_priv->damage_index++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
fill_current_damage_history_rectangle (ClutterStageView            *view,
 | 
			
		||||
                                       const cairo_rectangle_int_t *rect)
 | 
			
		||||
{
 | 
			
		||||
  cairo_region_t *damage;
 | 
			
		||||
 | 
			
		||||
  damage = cairo_region_create_rectangle (rect);
 | 
			
		||||
  fill_current_damage_history (view, damage);
 | 
			
		||||
  cairo_region_destroy (damage);
 | 
			
		||||
  clutter_stage_view_after_paint (view, redraw_clip);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static cairo_region_t *
 | 
			
		||||
transform_swap_region_to_onscreen (ClutterStageView *view,
 | 
			
		||||
                                   cairo_region_t   *swap_region)
 | 
			
		||||
{
 | 
			
		||||
  CoglFramebuffer *framebuffer;
 | 
			
		||||
  cairo_rectangle_int_t layout;
 | 
			
		||||
  gint width, height;
 | 
			
		||||
  CoglFramebuffer *onscreen = clutter_stage_view_get_onscreen (view);
 | 
			
		||||
  int n_rects, i;
 | 
			
		||||
  cairo_rectangle_int_t *rects;
 | 
			
		||||
  cairo_region_t *transformed_region;
 | 
			
		||||
  int width, height;
 | 
			
		||||
 | 
			
		||||
  framebuffer = clutter_stage_view_get_onscreen (view);
 | 
			
		||||
  clutter_stage_view_get_layout (view, &layout);
 | 
			
		||||
 | 
			
		||||
  width = cogl_framebuffer_get_width (framebuffer);
 | 
			
		||||
  height = cogl_framebuffer_get_height (framebuffer);
 | 
			
		||||
  width = cogl_framebuffer_get_width (onscreen);
 | 
			
		||||
  height = cogl_framebuffer_get_height (onscreen);
 | 
			
		||||
 | 
			
		||||
  n_rects = cairo_region_num_rectangles (swap_region);
 | 
			
		||||
  rects = g_newa (cairo_rectangle_int_t, n_rects);
 | 
			
		||||
  for (i = 0; i < n_rects; i++)
 | 
			
		||||
    {
 | 
			
		||||
      gfloat x1, y1, x2, y2;
 | 
			
		||||
 | 
			
		||||
      cairo_region_get_rectangle (swap_region, i, &rects[i]);
 | 
			
		||||
 | 
			
		||||
      x1 = (float) rects[i].x / layout.width;
 | 
			
		||||
      y1 = (float) rects[i].y / layout.height;
 | 
			
		||||
      x2 = (float) (rects[i].x + rects[i].width) / layout.width;
 | 
			
		||||
      y2 = (float) (rects[i].y + rects[i].height) / layout.height;
 | 
			
		||||
 | 
			
		||||
      clutter_stage_view_transform_to_onscreen (view, &x1, &y1);
 | 
			
		||||
      clutter_stage_view_transform_to_onscreen (view, &x2, &y2);
 | 
			
		||||
 | 
			
		||||
      x1 = floor (x1 * width);
 | 
			
		||||
      y1 = floor (height - (y1 * height));
 | 
			
		||||
      x2 = ceil (x2 * width);
 | 
			
		||||
      y2 = ceil (height - (y2 * height));
 | 
			
		||||
 | 
			
		||||
      rects[i].x = x1;
 | 
			
		||||
      rects[i].y = y1;
 | 
			
		||||
      rects[i].width = x2 - x1;
 | 
			
		||||
      rects[i].height = y2 - y1;
 | 
			
		||||
      clutter_stage_view_transform_rect_to_onscreen (view,
 | 
			
		||||
                                                     &rects[i],
 | 
			
		||||
                                                     width,
 | 
			
		||||
                                                     height,
 | 
			
		||||
                                                     &rects[i]);
 | 
			
		||||
    }
 | 
			
		||||
  transformed_region = cairo_region_create_rectangles (rects, n_rects);
 | 
			
		||||
 | 
			
		||||
  return transformed_region;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
calculate_scissor_region (cairo_rectangle_int_t *fb_clip_region,
 | 
			
		||||
                          int                    subpixel_compensation,
 | 
			
		||||
                          int                    fb_width,
 | 
			
		||||
                          int                    fb_height,
 | 
			
		||||
                          cairo_rectangle_int_t *out_scissor_rect)
 | 
			
		||||
{
 | 
			
		||||
  *out_scissor_rect = *fb_clip_region;
 | 
			
		||||
 | 
			
		||||
  if (subpixel_compensation == 0)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (fb_clip_region->x > 0)
 | 
			
		||||
    out_scissor_rect->x += subpixel_compensation;
 | 
			
		||||
  if (fb_clip_region->y > 0)
 | 
			
		||||
    out_scissor_rect->y += subpixel_compensation;
 | 
			
		||||
  if (fb_clip_region->x + fb_clip_region->width < fb_width)
 | 
			
		||||
    out_scissor_rect->width -= 2 * subpixel_compensation;
 | 
			
		||||
  if (fb_clip_region->y + fb_clip_region->height < fb_height)
 | 
			
		||||
    out_scissor_rect->height -= 2 * subpixel_compensation;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline gboolean
 | 
			
		||||
is_buffer_age_enabled (void)
 | 
			
		||||
{
 | 
			
		||||
@@ -610,27 +548,21 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
 | 
			
		||||
  ClutterStageViewCoglPrivate *view_priv =
 | 
			
		||||
    clutter_stage_view_cogl_get_instance_private (view_cogl);
 | 
			
		||||
  CoglFramebuffer *fb = clutter_stage_view_get_framebuffer (view);
 | 
			
		||||
  CoglFramebuffer *onscreen = clutter_stage_view_get_onscreen (view);
 | 
			
		||||
  cairo_rectangle_int_t view_rect;
 | 
			
		||||
  gboolean is_full_redraw;
 | 
			
		||||
  gboolean may_use_clipped_redraw;
 | 
			
		||||
  gboolean use_clipped_redraw;
 | 
			
		||||
  gboolean can_blit_sub_buffer;
 | 
			
		||||
  gboolean has_buffer_age;
 | 
			
		||||
  gboolean do_swap_buffer;
 | 
			
		||||
  gboolean swap_with_damage;
 | 
			
		||||
  ClutterActor *wrapper;
 | 
			
		||||
  cairo_region_t *redraw_clip;
 | 
			
		||||
  cairo_region_t *queued_redraw_clip;
 | 
			
		||||
  cairo_region_t *queued_redraw_clip = NULL;
 | 
			
		||||
  cairo_region_t *fb_clip_region;
 | 
			
		||||
  cairo_region_t *swap_region;
 | 
			
		||||
  cairo_rectangle_int_t redraw_rect;
 | 
			
		||||
  gboolean clip_region_empty;
 | 
			
		||||
  float fb_scale;
 | 
			
		||||
  int subpixel_compensation = 0;
 | 
			
		||||
  int fb_width, fb_height;
 | 
			
		||||
  int buffer_age;
 | 
			
		||||
 | 
			
		||||
  wrapper = CLUTTER_ACTOR (stage_cogl->wrapper);
 | 
			
		||||
  gboolean res;
 | 
			
		||||
 | 
			
		||||
  clutter_stage_view_get_layout (view, &view_rect);
 | 
			
		||||
  fb_scale = clutter_stage_view_get_scale (view);
 | 
			
		||||
@@ -638,12 +570,14 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
 | 
			
		||||
  fb_height = cogl_framebuffer_get_height (fb);
 | 
			
		||||
 | 
			
		||||
  can_blit_sub_buffer =
 | 
			
		||||
    cogl_is_onscreen (fb) &&
 | 
			
		||||
    cogl_is_onscreen (onscreen) &&
 | 
			
		||||
    cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_REGION);
 | 
			
		||||
 | 
			
		||||
  has_buffer_age = cogl_is_onscreen (fb) && is_buffer_age_enabled ();
 | 
			
		||||
  has_buffer_age = cogl_is_onscreen (onscreen) && is_buffer_age_enabled ();
 | 
			
		||||
 | 
			
		||||
  redraw_clip = clutter_stage_view_take_redraw_clip (view);
 | 
			
		||||
  if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION))
 | 
			
		||||
    queued_redraw_clip = cairo_region_copy (redraw_clip);
 | 
			
		||||
 | 
			
		||||
  /* NB: a NULL redraw clip == full stage redraw */
 | 
			
		||||
  if (!redraw_clip)
 | 
			
		||||
@@ -651,51 +585,35 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
 | 
			
		||||
  else
 | 
			
		||||
    is_full_redraw = FALSE;
 | 
			
		||||
 | 
			
		||||
  may_use_clipped_redraw =
 | 
			
		||||
  if (has_buffer_age)
 | 
			
		||||
    {
 | 
			
		||||
      buffer_age = cogl_onscreen_get_buffer_age (COGL_ONSCREEN (onscreen));
 | 
			
		||||
      if (!clutter_damage_history_is_age_valid (view_priv->damage_history,
 | 
			
		||||
                                                buffer_age))
 | 
			
		||||
        {
 | 
			
		||||
          CLUTTER_NOTE (CLIPPING,
 | 
			
		||||
                        "Invalid back buffer(age=%d): forcing full redraw\n",
 | 
			
		||||
                        buffer_age);
 | 
			
		||||
          use_clipped_redraw = FALSE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  use_clipped_redraw =
 | 
			
		||||
    use_clipped_redraw &&
 | 
			
		||||
    !(clutter_paint_debug_flags & CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS) &&
 | 
			
		||||
    _clutter_stage_window_can_clip_redraws (stage_window) &&
 | 
			
		||||
    (can_blit_sub_buffer || has_buffer_age) &&
 | 
			
		||||
    !is_full_redraw &&
 | 
			
		||||
    /* some drivers struggle to get going and produce some junk
 | 
			
		||||
     * frames when starting up... */
 | 
			
		||||
    cogl_onscreen_get_frame_counter (COGL_ONSCREEN (fb)) > 3;
 | 
			
		||||
    cogl_onscreen_get_frame_counter (COGL_ONSCREEN (onscreen)) > 3;
 | 
			
		||||
 | 
			
		||||
  if (has_buffer_age)
 | 
			
		||||
    {
 | 
			
		||||
      buffer_age = cogl_onscreen_get_buffer_age (COGL_ONSCREEN (fb));
 | 
			
		||||
      if (!valid_buffer_age (view_cogl, buffer_age))
 | 
			
		||||
        {
 | 
			
		||||
          CLUTTER_NOTE (CLIPPING, "Invalid back buffer(age=%d): forcing full redraw\n", buffer_age);
 | 
			
		||||
          may_use_clipped_redraw = FALSE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (may_use_clipped_redraw)
 | 
			
		||||
  if (use_clipped_redraw)
 | 
			
		||||
    {
 | 
			
		||||
      fb_clip_region = offset_scale_and_clamp_region (redraw_clip,
 | 
			
		||||
                                                      -view_rect.x,
 | 
			
		||||
                                                      -view_rect.y,
 | 
			
		||||
                                                      fb_scale);
 | 
			
		||||
 | 
			
		||||
      if (fb_scale != floorf (fb_scale))
 | 
			
		||||
        {
 | 
			
		||||
          int n_rects, i;
 | 
			
		||||
          cairo_rectangle_int_t *rects;
 | 
			
		||||
 | 
			
		||||
          subpixel_compensation = ceilf (fb_scale);
 | 
			
		||||
 | 
			
		||||
          n_rects = cairo_region_num_rectangles (fb_clip_region);
 | 
			
		||||
          rects = g_newa (cairo_rectangle_int_t, n_rects);
 | 
			
		||||
          for (i = 0; i < n_rects; i++)
 | 
			
		||||
            {
 | 
			
		||||
              cairo_region_get_rectangle (fb_clip_region, i, &rects[i]);
 | 
			
		||||
              rects[i].x -= subpixel_compensation;
 | 
			
		||||
              rects[i].y -= subpixel_compensation;
 | 
			
		||||
              rects[i].width += 2 * subpixel_compensation;
 | 
			
		||||
              rects[i].height += 2 * subpixel_compensation;
 | 
			
		||||
            }
 | 
			
		||||
          cairo_region_destroy (fb_clip_region);
 | 
			
		||||
          fb_clip_region = cairo_region_create_rectangles (rects, n_rects);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
@@ -711,48 +629,40 @@ 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;
 | 
			
		||||
  else
 | 
			
		||||
    use_clipped_redraw = FALSE;
 | 
			
		||||
 | 
			
		||||
  clip_region_empty = may_use_clipped_redraw && cairo_region_is_empty (fb_clip_region);
 | 
			
		||||
  g_return_val_if_fail (!cairo_region_is_empty (fb_clip_region), FALSE);
 | 
			
		||||
 | 
			
		||||
  swap_with_damage = FALSE;
 | 
			
		||||
  if (has_buffer_age)
 | 
			
		||||
    {
 | 
			
		||||
      if (use_clipped_redraw && !clip_region_empty)
 | 
			
		||||
      clutter_damage_history_record (view_priv->damage_history,
 | 
			
		||||
                                     fb_clip_region);
 | 
			
		||||
 | 
			
		||||
      if (use_clipped_redraw)
 | 
			
		||||
        {
 | 
			
		||||
          cairo_region_t *fb_damage;
 | 
			
		||||
          cairo_region_t *view_damage;
 | 
			
		||||
          int i;
 | 
			
		||||
 | 
			
		||||
          fill_current_damage_history (view, fb_clip_region);
 | 
			
		||||
          int age;
 | 
			
		||||
 | 
			
		||||
          fb_damage = cairo_region_create ();
 | 
			
		||||
 | 
			
		||||
          for (i = 1; i <= buffer_age; i++)
 | 
			
		||||
          for (age = 1; age <= buffer_age; age++)
 | 
			
		||||
            {
 | 
			
		||||
              int damage_index;
 | 
			
		||||
              const cairo_region_t *old_damage;
 | 
			
		||||
 | 
			
		||||
              damage_index = DAMAGE_HISTORY (view_priv->damage_index - i - 1);
 | 
			
		||||
              cairo_region_union (fb_damage,
 | 
			
		||||
                                  view_priv->damage_history[damage_index]);
 | 
			
		||||
              old_damage =
 | 
			
		||||
                clutter_damage_history_lookup (view_priv->damage_history, age);
 | 
			
		||||
              cairo_region_union (fb_damage, old_damage);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          /* Update the fb clip region with the extra damage. */
 | 
			
		||||
          cairo_region_union (fb_clip_region, fb_damage);
 | 
			
		||||
 | 
			
		||||
          view_damage = offset_scale_and_clamp_region (fb_damage,
 | 
			
		||||
                                                       0, 0,
 | 
			
		||||
                                                       1.0f / fb_scale);
 | 
			
		||||
          cairo_region_translate (view_damage, view_rect.x, view_rect.y);
 | 
			
		||||
          cairo_region_intersect_rectangle (view_damage, &view_rect);
 | 
			
		||||
          /* Update the redraw clip with the extra damage done to the view */
 | 
			
		||||
          view_damage = scale_offset_and_clamp_region (fb_damage,
 | 
			
		||||
                                                       1.0f / fb_scale,
 | 
			
		||||
                                                       view_rect.x,
 | 
			
		||||
                                                       view_rect.y);
 | 
			
		||||
 | 
			
		||||
          /* Update the redraw clip region with the extra damage. */
 | 
			
		||||
          cairo_region_union (redraw_clip, view_damage);
 | 
			
		||||
 | 
			
		||||
          cairo_region_destroy (view_damage);
 | 
			
		||||
@@ -764,55 +674,13 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
 | 
			
		||||
 | 
			
		||||
          swap_with_damage = TRUE;
 | 
			
		||||
        }
 | 
			
		||||
      else if (!use_clipped_redraw)
 | 
			
		||||
        {
 | 
			
		||||
          cairo_rectangle_int_t fb_damage;
 | 
			
		||||
 | 
			
		||||
          fb_damage = (cairo_rectangle_int_t) {
 | 
			
		||||
            .x = 0,
 | 
			
		||||
            .y = 0,
 | 
			
		||||
            .width = ceilf (view_rect.width * fb_scale),
 | 
			
		||||
            .height = ceilf (view_rect.height * fb_scale)
 | 
			
		||||
          };
 | 
			
		||||
          fill_current_damage_history_rectangle (view, &fb_damage);
 | 
			
		||||
        }
 | 
			
		||||
      clutter_damage_history_step (view_priv->damage_history);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (use_clipped_redraw && clip_region_empty)
 | 
			
		||||
  if (use_clipped_redraw)
 | 
			
		||||
    {
 | 
			
		||||
      CLUTTER_NOTE (CLIPPING, "Empty stage output paint\n");
 | 
			
		||||
    }
 | 
			
		||||
  else if (use_clipped_redraw)
 | 
			
		||||
    {
 | 
			
		||||
      cairo_rectangle_int_t clip_rect;
 | 
			
		||||
      cairo_rectangle_int_t scissor_rect;
 | 
			
		||||
 | 
			
		||||
      if (cairo_region_num_rectangles (fb_clip_region) == 1)
 | 
			
		||||
        {
 | 
			
		||||
          cairo_region_get_extents (fb_clip_region, &clip_rect);
 | 
			
		||||
 | 
			
		||||
          calculate_scissor_region (&clip_rect,
 | 
			
		||||
                                    subpixel_compensation,
 | 
			
		||||
                                    fb_width, fb_height,
 | 
			
		||||
                                    &scissor_rect);
 | 
			
		||||
 | 
			
		||||
          CLUTTER_NOTE (CLIPPING,
 | 
			
		||||
                        "Stage clip pushed: x=%d, y=%d, width=%d, height=%d\n",
 | 
			
		||||
                        scissor_rect.x,
 | 
			
		||||
                        scissor_rect.y,
 | 
			
		||||
                        scissor_rect.width,
 | 
			
		||||
                        scissor_rect.height);
 | 
			
		||||
 | 
			
		||||
          cogl_framebuffer_push_scissor_clip (fb,
 | 
			
		||||
                                              scissor_rect.x,
 | 
			
		||||
                                              scissor_rect.y,
 | 
			
		||||
                                              scissor_rect.width,
 | 
			
		||||
                                              scissor_rect.height);
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          cogl_framebuffer_push_region_clip (fb, fb_clip_region);
 | 
			
		||||
        }
 | 
			
		||||
      cogl_framebuffer_push_region_clip (fb, fb_clip_region);
 | 
			
		||||
 | 
			
		||||
      paint_stage (stage_cogl, view, redraw_clip);
 | 
			
		||||
 | 
			
		||||
@@ -822,77 +690,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
 | 
			
		||||
    {
 | 
			
		||||
      CLUTTER_NOTE (CLIPPING, "Unclipped stage paint\n");
 | 
			
		||||
 | 
			
		||||
      /* If we are trying to debug redraw issues then we want to pass
 | 
			
		||||
       * the redraw_clip so it can be visualized */
 | 
			
		||||
      if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS) &&
 | 
			
		||||
          may_use_clipped_redraw &&
 | 
			
		||||
          !clip_region_empty)
 | 
			
		||||
        {
 | 
			
		||||
          cairo_rectangle_int_t clip_rect;
 | 
			
		||||
          cairo_rectangle_int_t scissor_rect;
 | 
			
		||||
 | 
			
		||||
          cairo_region_get_extents (fb_clip_region, &clip_rect);
 | 
			
		||||
 | 
			
		||||
          calculate_scissor_region (&clip_rect,
 | 
			
		||||
                                    subpixel_compensation,
 | 
			
		||||
                                    fb_width, fb_height,
 | 
			
		||||
                                    &scissor_rect);
 | 
			
		||||
 | 
			
		||||
          cogl_framebuffer_push_scissor_clip (fb,
 | 
			
		||||
                                              scissor_rect.x,
 | 
			
		||||
                                              scissor_rect.y,
 | 
			
		||||
                                              scissor_rect.width,
 | 
			
		||||
                                              scissor_rect.height);
 | 
			
		||||
 | 
			
		||||
          paint_stage (stage_cogl, view, redraw_clip);
 | 
			
		||||
 | 
			
		||||
          cogl_framebuffer_pop_clip (fb);
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          paint_stage (stage_cogl, view, redraw_clip);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  cairo_region_get_extents (redraw_clip, &redraw_rect);
 | 
			
		||||
 | 
			
		||||
  if (may_use_clipped_redraw &&
 | 
			
		||||
      G_UNLIKELY ((clutter_paint_debug_flags & CLUTTER_DEBUG_REDRAWS)))
 | 
			
		||||
    {
 | 
			
		||||
      CoglContext *ctx = cogl_framebuffer_get_context (fb);
 | 
			
		||||
      static CoglPipeline *outline = NULL;
 | 
			
		||||
      ClutterActor *actor = CLUTTER_ACTOR (wrapper);
 | 
			
		||||
      float x_1 = redraw_rect.x;
 | 
			
		||||
      float x_2 = redraw_rect.x + redraw_rect.width;
 | 
			
		||||
      float y_1 = redraw_rect.y;
 | 
			
		||||
      float y_2 = redraw_rect.y + redraw_rect.height;
 | 
			
		||||
      CoglVertexP2 quad[4] = {
 | 
			
		||||
        { x_1, y_1 },
 | 
			
		||||
        { x_2, y_1 },
 | 
			
		||||
        { x_2, y_2 },
 | 
			
		||||
        { x_1, y_2 }
 | 
			
		||||
      };
 | 
			
		||||
      CoglPrimitive *prim;
 | 
			
		||||
      CoglMatrix modelview;
 | 
			
		||||
 | 
			
		||||
      if (outline == NULL)
 | 
			
		||||
        {
 | 
			
		||||
          outline = cogl_pipeline_new (ctx);
 | 
			
		||||
          cogl_pipeline_set_color4ub (outline, 0xff, 0x00, 0x00, 0xff);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      prim = cogl_primitive_new_p2 (ctx,
 | 
			
		||||
                                    COGL_VERTICES_MODE_LINE_LOOP,
 | 
			
		||||
                                    4, /* n_vertices */
 | 
			
		||||
                                    quad);
 | 
			
		||||
 | 
			
		||||
      cogl_framebuffer_push_matrix (fb);
 | 
			
		||||
      cogl_matrix_init_identity (&modelview);
 | 
			
		||||
      _clutter_actor_apply_modelview_transform (actor, &modelview);
 | 
			
		||||
      cogl_framebuffer_set_modelview_matrix (fb, &modelview);
 | 
			
		||||
      cogl_framebuffer_draw_primitive (fb, outline, prim);
 | 
			
		||||
      cogl_framebuffer_pop_matrix (fb);
 | 
			
		||||
      cogl_object_unref (prim);
 | 
			
		||||
      paint_stage (stage_cogl, view, redraw_clip);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* XXX: It seems there will be a race here in that the stage
 | 
			
		||||
@@ -904,59 +702,56 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
 | 
			
		||||
   * artefacts.
 | 
			
		||||
   */
 | 
			
		||||
  if (use_clipped_redraw)
 | 
			
		||||
    {
 | 
			
		||||
      if (clip_region_empty)
 | 
			
		||||
        {
 | 
			
		||||
          do_swap_buffer = FALSE;
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          swap_region = cairo_region_copy (fb_clip_region);
 | 
			
		||||
          do_swap_buffer = TRUE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    swap_region = cairo_region_copy (fb_clip_region);
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      swap_region = cairo_region_create ();
 | 
			
		||||
      do_swap_buffer = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
    swap_region = cairo_region_create ();
 | 
			
		||||
 | 
			
		||||
  g_clear_pointer (&redraw_clip, cairo_region_destroy);
 | 
			
		||||
  g_clear_pointer (&queued_redraw_clip, cairo_region_destroy);
 | 
			
		||||
  g_clear_pointer (&fb_clip_region, cairo_region_destroy);
 | 
			
		||||
 | 
			
		||||
  if (do_swap_buffer)
 | 
			
		||||
  COGL_TRACE_BEGIN_SCOPED (ClutterStageCoglRedrawViewSwapFramebuffer,
 | 
			
		||||
                           "Paint (swap framebuffer)");
 | 
			
		||||
 | 
			
		||||
  if (clutter_stage_view_get_onscreen (view) !=
 | 
			
		||||
      clutter_stage_view_get_framebuffer (view))
 | 
			
		||||
    {
 | 
			
		||||
      gboolean res;
 | 
			
		||||
 | 
			
		||||
      COGL_TRACE_BEGIN_SCOPED (ClutterStageCoglRedrawViewSwapFramebuffer,
 | 
			
		||||
                               "Paint (swap framebuffer)");
 | 
			
		||||
 | 
			
		||||
      if (clutter_stage_view_get_onscreen (view) !=
 | 
			
		||||
          clutter_stage_view_get_framebuffer (view))
 | 
			
		||||
        {
 | 
			
		||||
          cairo_region_t *transformed_swap_region;
 | 
			
		||||
 | 
			
		||||
          transformed_swap_region =
 | 
			
		||||
            transform_swap_region_to_onscreen (view, swap_region);
 | 
			
		||||
          cairo_region_destroy (swap_region);
 | 
			
		||||
          swap_region = transformed_swap_region;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      res = swap_framebuffer (stage_window,
 | 
			
		||||
                              view,
 | 
			
		||||
                              swap_region,
 | 
			
		||||
                              swap_with_damage,
 | 
			
		||||
                              queued_redraw_clip);
 | 
			
		||||
      cairo_region_t *transformed_swap_region;
 | 
			
		||||
 | 
			
		||||
      transformed_swap_region =
 | 
			
		||||
        transform_swap_region_to_onscreen (view, swap_region);
 | 
			
		||||
      cairo_region_destroy (swap_region);
 | 
			
		||||
      swap_region = transformed_swap_region;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
      return res;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
  if (queued_redraw_clip)
 | 
			
		||||
    {
 | 
			
		||||
      return FALSE;
 | 
			
		||||
      paint_damage_region (stage_window, view,
 | 
			
		||||
                           swap_region, queued_redraw_clip);
 | 
			
		||||
      cairo_region_destroy (queued_redraw_clip);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  res = swap_framebuffer (stage_window,
 | 
			
		||||
                          view,
 | 
			
		||||
                          swap_region,
 | 
			
		||||
                          swap_with_damage);
 | 
			
		||||
 | 
			
		||||
  cairo_region_destroy (swap_region);
 | 
			
		||||
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_stage_cogl_scanout_view (ClutterStageCogl *stage_cogl,
 | 
			
		||||
                                 ClutterStageView *view,
 | 
			
		||||
                                 CoglScanout      *scanout)
 | 
			
		||||
{
 | 
			
		||||
  CoglFramebuffer *framebuffer = clutter_stage_view_get_framebuffer (view);
 | 
			
		||||
  CoglOnscreen *onscreen;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (cogl_is_onscreen (framebuffer));
 | 
			
		||||
 | 
			
		||||
  onscreen = COGL_ONSCREEN (framebuffer);
 | 
			
		||||
  cogl_onscreen_direct_scanout (onscreen, scanout);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -971,11 +766,23 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
 | 
			
		||||
  for (l = _clutter_stage_window_get_views (stage_window); l; l = l->next)
 | 
			
		||||
    {
 | 
			
		||||
      ClutterStageView *view = l->data;
 | 
			
		||||
      g_autoptr (CoglScanout) scanout = NULL;
 | 
			
		||||
 | 
			
		||||
      if (!clutter_stage_view_has_redraw_clip (view))
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      swap_event |= clutter_stage_cogl_redraw_view (stage_window, view);
 | 
			
		||||
      scanout = clutter_stage_view_take_scanout (view);
 | 
			
		||||
      if (scanout)
 | 
			
		||||
        {
 | 
			
		||||
          clutter_stage_cogl_scanout_view (stage_cogl,
 | 
			
		||||
                                           view,
 | 
			
		||||
                                           scanout);
 | 
			
		||||
          swap_event = TRUE;
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          swap_event |= clutter_stage_cogl_redraw_view (stage_window, view);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  _clutter_stage_emit_after_paint (stage_cogl->wrapper);
 | 
			
		||||
@@ -1055,12 +862,31 @@ _clutter_stage_cogl_init (ClutterStageCogl *stage)
 | 
			
		||||
  stage->update_time = -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_stage_view_cogl_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageViewCogl *view_cogl = CLUTTER_STAGE_VIEW_COGL (object);
 | 
			
		||||
  ClutterStageViewCoglPrivate *view_priv =
 | 
			
		||||
    clutter_stage_view_cogl_get_instance_private (view_cogl);
 | 
			
		||||
 | 
			
		||||
  clutter_damage_history_free (view_priv->damage_history);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (clutter_stage_view_cogl_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_stage_view_cogl_init (ClutterStageViewCogl *view_cogl)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageViewCoglPrivate *view_priv =
 | 
			
		||||
    clutter_stage_view_cogl_get_instance_private (view_cogl);
 | 
			
		||||
 | 
			
		||||
  view_priv->damage_history = clutter_damage_history_new ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_stage_view_cogl_class_init (ClutterStageViewCoglClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  object_class->finalize = clutter_stage_view_cogl_finalize;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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__ */
 | 
			
		||||
@@ -333,21 +333,20 @@ clutter_group_real_get_preferred_height (ClutterActor *actor,
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clutter_group_real_allocate (ClutterActor           *actor,
 | 
			
		||||
                             const ClutterActorBox  *allocation,
 | 
			
		||||
                             ClutterAllocationFlags  flags)
 | 
			
		||||
                             const ClutterActorBox  *allocation)
 | 
			
		||||
{
 | 
			
		||||
  ClutterGroupPrivate *priv = CLUTTER_GROUP (actor)->priv;
 | 
			
		||||
  ClutterActorClass *klass;
 | 
			
		||||
 | 
			
		||||
  klass = CLUTTER_ACTOR_CLASS (clutter_group_parent_class);
 | 
			
		||||
  klass->allocate (actor, allocation, flags);
 | 
			
		||||
  klass->allocate (actor, allocation);
 | 
			
		||||
 | 
			
		||||
  if (priv->children == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  clutter_layout_manager_allocate (priv->layout,
 | 
			
		||||
                                   CLUTTER_CONTAINER (actor),
 | 
			
		||||
                                   allocation, flags);
 | 
			
		||||
                                   allocation);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
 
 | 
			
		||||
										
											
												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__ */
 | 
			
		||||
@@ -114,6 +114,7 @@ clutter_sources = [
 | 
			
		||||
  'clutter-constraint.c',
 | 
			
		||||
  'clutter-container.c',
 | 
			
		||||
  'clutter-content.c',
 | 
			
		||||
  'clutter-damage-history.c',
 | 
			
		||||
  'clutter-deform-effect.c',
 | 
			
		||||
  'clutter-desaturate-effect.c',
 | 
			
		||||
  'clutter-effect.c',
 | 
			
		||||
@@ -185,6 +186,7 @@ clutter_private_headers = [
 | 
			
		||||
  'clutter-bezier.h',
 | 
			
		||||
  'clutter-constraint-private.h',
 | 
			
		||||
  'clutter-content-private.h',
 | 
			
		||||
  'clutter-damage-history.h',
 | 
			
		||||
  'clutter-debug.h',
 | 
			
		||||
  'clutter-easing.h',
 | 
			
		||||
  'clutter-effect-private.h',
 | 
			
		||||
@@ -219,24 +221,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 = []
 | 
			
		||||
@@ -337,35 +333,20 @@ clutter_build_config_h = configure_file(
 | 
			
		||||
)
 | 
			
		||||
clutter_built_private_headers += clutter_build_config_h
 | 
			
		||||
 | 
			
		||||
clutter_config_defines = []
 | 
			
		||||
cdata = configuration_data()
 | 
			
		||||
if have_wayland
 | 
			
		||||
  clutter_config_defines += [
 | 
			
		||||
    '#define CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT 1',
 | 
			
		||||
  ]
 | 
			
		||||
  cdata.set10('CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT', true)
 | 
			
		||||
endif
 | 
			
		||||
if have_x11
 | 
			
		||||
  clutter_config_defines += [
 | 
			
		||||
    '#define CLUTTER_WINDOWING_X11 "x11"',
 | 
			
		||||
    '#define CLUTTER_INPUT_X11 "x11"',
 | 
			
		||||
    '#define CLUTTER_WINDOWING_GLX "glx"',
 | 
			
		||||
  ]
 | 
			
		||||
  cdata.set_quoted('CLUTTER_WINDOWING_X11', 'x11')
 | 
			
		||||
  cdata.set_quoted('CLUTTER_INPUT_X11', 'x11')
 | 
			
		||||
  cdata.set_quoted('CLUTTER_WINDOWING_GLX', 'glx')
 | 
			
		||||
endif
 | 
			
		||||
if have_native_backend
 | 
			
		||||
  clutter_config_defines += [
 | 
			
		||||
    '#define CLUTTER_WINDOWING_EGL "eglnative"',
 | 
			
		||||
    '#define CLUTTER_INPUT_EVDEV "evdev"',
 | 
			
		||||
  ]
 | 
			
		||||
  cdata.set_quoted('CLUTTER_WINDOWING_EGL', 'eglnative')
 | 
			
		||||
  cdata.set_quoted('CLUTTER_INPUT_EVDEV', 'evdev')
 | 
			
		||||
endif
 | 
			
		||||
clutter_config_defines += [
 | 
			
		||||
  '#define CLUTTER_INPUT_NULL "null"',
 | 
			
		||||
]
 | 
			
		||||
clutter_config_defines_string = ''
 | 
			
		||||
foreach clutter_config_define : clutter_config_defines
 | 
			
		||||
  clutter_config_defines_string += clutter_config_define + '\n'
 | 
			
		||||
endforeach
 | 
			
		||||
 | 
			
		||||
cdata = configuration_data()
 | 
			
		||||
cdata.set('CLUTTER_CONFIG_DEFINES', clutter_config_defines_string)
 | 
			
		||||
cdata.set_quoted('CLUTTER_INPUT_NULL', 'null')
 | 
			
		||||
 | 
			
		||||
clutter_config_h = configure_file(
 | 
			
		||||
  input: 'clutter-config.h.in',
 | 
			
		||||
 
 | 
			
		||||
@@ -74,7 +74,7 @@ PangoFontMap *
 | 
			
		||||
cogl_pango_font_map_new (void)
 | 
			
		||||
{
 | 
			
		||||
  PangoFontMap *fm = pango_cairo_font_map_new ();
 | 
			
		||||
  CoglPangoFontMapPriv *priv = g_new0 (CoglPangoFontMapPriv, 1);
 | 
			
		||||
  g_autofree CoglPangoFontMapPriv *priv = g_new0 (CoglPangoFontMapPriv, 1);
 | 
			
		||||
 | 
			
		||||
  _COGL_GET_CONTEXT (context, NULL);
 | 
			
		||||
 | 
			
		||||
@@ -85,7 +85,7 @@ cogl_pango_font_map_new (void)
 | 
			
		||||
   * for now. */
 | 
			
		||||
  g_object_set_qdata_full (G_OBJECT (fm),
 | 
			
		||||
                           cogl_pango_font_map_get_priv_key (),
 | 
			
		||||
                           priv,
 | 
			
		||||
                           g_steal_pointer (&priv),
 | 
			
		||||
                           free_priv);
 | 
			
		||||
 | 
			
		||||
  return fm;
 | 
			
		||||
 
 | 
			
		||||
@@ -158,7 +158,7 @@ _cogl_blit_framebuffer_begin (CoglBlitData *data)
 | 
			
		||||
     supported. */
 | 
			
		||||
  if ((_cogl_texture_get_format (data->src_tex) & COGL_PREMULT_BIT) !=
 | 
			
		||||
      (_cogl_texture_get_format (data->dst_tex) & COGL_PREMULT_BIT) ||
 | 
			
		||||
      !_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER))
 | 
			
		||||
      !cogl_has_feature (ctx, COGL_FEATURE_ID_BLIT_FRAMEBUFFER))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  dst_offscreen = _cogl_offscreen_new_with_texture_full
 | 
			
		||||
 
 | 
			
		||||
@@ -193,6 +193,8 @@ cogl_is_context (void *object);
 | 
			
		||||
 *    expected to return age values other than 0.
 | 
			
		||||
 * @COGL_FEATURE_ID_PRESENTATION_TIME: Whether frame presentation
 | 
			
		||||
 *    time stamps will be recorded in #CoglFrameInfo objects.
 | 
			
		||||
 * @COGL_FEATURE_ID_BLIT_FRAMEBUFFER: Whether blitting using
 | 
			
		||||
 *    cogl_blit_framebuffer() is supported.
 | 
			
		||||
 *
 | 
			
		||||
 * All the capabilities that can vary between different GPUs supported
 | 
			
		||||
 * by Cogl. Applications that depend on any of these features should explicitly
 | 
			
		||||
@@ -211,6 +213,7 @@ typedef enum _CoglFeatureID
 | 
			
		||||
  COGL_FEATURE_ID_TEXTURE_RG,
 | 
			
		||||
  COGL_FEATURE_ID_BUFFER_AGE,
 | 
			
		||||
  COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL,
 | 
			
		||||
  COGL_FEATURE_ID_BLIT_FRAMEBUFFER,
 | 
			
		||||
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  _COGL_N_FEATURE_IDS   /*< skip >*/
 | 
			
		||||
 
 | 
			
		||||
@@ -34,12 +34,22 @@
 | 
			
		||||
#include "cogl-dma-buf-handle.h"
 | 
			
		||||
#include "cogl-object.h"
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
#include <linux/dma-buf.h>
 | 
			
		||||
#include <sys/ioctl.h>
 | 
			
		||||
#include <sys/mman.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
struct _CoglDmaBufHandle
 | 
			
		||||
{
 | 
			
		||||
  CoglFramebuffer *framebuffer;
 | 
			
		||||
  int dmabuf_fd;
 | 
			
		||||
  int width;
 | 
			
		||||
  int height;
 | 
			
		||||
  int stride;
 | 
			
		||||
  int offset;
 | 
			
		||||
  int bpp;
 | 
			
		||||
  gpointer user_data;
 | 
			
		||||
  GDestroyNotify destroy_func;
 | 
			
		||||
};
 | 
			
		||||
@@ -47,6 +57,11 @@ struct _CoglDmaBufHandle
 | 
			
		||||
CoglDmaBufHandle *
 | 
			
		||||
cogl_dma_buf_handle_new (CoglFramebuffer *framebuffer,
 | 
			
		||||
                         int              dmabuf_fd,
 | 
			
		||||
                         int              width,
 | 
			
		||||
                         int              height,
 | 
			
		||||
                         int              stride,
 | 
			
		||||
                         int              offset,
 | 
			
		||||
                         int              bpp,
 | 
			
		||||
                         gpointer         user_data,
 | 
			
		||||
                         GDestroyNotify   destroy_func)
 | 
			
		||||
{
 | 
			
		||||
@@ -61,6 +76,12 @@ cogl_dma_buf_handle_new (CoglFramebuffer *framebuffer,
 | 
			
		||||
  dmabuf_handle->user_data = user_data;
 | 
			
		||||
  dmabuf_handle->destroy_func = destroy_func;
 | 
			
		||||
 | 
			
		||||
  dmabuf_handle->width = width;
 | 
			
		||||
  dmabuf_handle->height = height;
 | 
			
		||||
  dmabuf_handle->stride = stride;
 | 
			
		||||
  dmabuf_handle->offset = offset;
 | 
			
		||||
  dmabuf_handle->bpp = bpp;
 | 
			
		||||
 | 
			
		||||
  return dmabuf_handle;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -80,6 +101,93 @@ cogl_dma_buf_handle_free (CoglDmaBufHandle *dmabuf_handle)
 | 
			
		||||
  g_free (dmabuf_handle);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
sync_read (CoglDmaBufHandle  *dmabuf_handle,
 | 
			
		||||
           uint64_t           start_or_end,
 | 
			
		||||
           GError           **error)
 | 
			
		||||
{
 | 
			
		||||
  struct dma_buf_sync sync = { 0 };
 | 
			
		||||
 | 
			
		||||
  sync.flags = start_or_end | DMA_BUF_SYNC_READ;
 | 
			
		||||
 | 
			
		||||
  while (TRUE)
 | 
			
		||||
    {
 | 
			
		||||
      int ret;
 | 
			
		||||
 | 
			
		||||
      ret = ioctl (dmabuf_handle->dmabuf_fd, DMA_BUF_IOCTL_SYNC, &sync);
 | 
			
		||||
      if (ret == -1 && errno == EINTR)
 | 
			
		||||
        {
 | 
			
		||||
          continue;
 | 
			
		||||
        }
 | 
			
		||||
      else if (ret == -1)
 | 
			
		||||
        {
 | 
			
		||||
          g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
 | 
			
		||||
                       "ioctl: %s", g_strerror (errno));
 | 
			
		||||
          return FALSE;
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
cogl_dma_buf_handle_sync_read_start (CoglDmaBufHandle  *dmabuf_handle,
 | 
			
		||||
                                     GError           **error)
 | 
			
		||||
{
 | 
			
		||||
  return sync_read (dmabuf_handle, DMA_BUF_SYNC_START, error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
cogl_dma_buf_handle_sync_read_end (CoglDmaBufHandle  *dmabuf_handle,
 | 
			
		||||
                                   GError           **error)
 | 
			
		||||
{
 | 
			
		||||
  return sync_read (dmabuf_handle, DMA_BUF_SYNC_END, error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gpointer
 | 
			
		||||
cogl_dma_buf_handle_mmap (CoglDmaBufHandle  *dmabuf_handle,
 | 
			
		||||
                          GError           **error)
 | 
			
		||||
{
 | 
			
		||||
  size_t size;
 | 
			
		||||
  gpointer data;
 | 
			
		||||
 | 
			
		||||
  size = dmabuf_handle->height * dmabuf_handle->stride;
 | 
			
		||||
 | 
			
		||||
  data = mmap (NULL, size, PROT_READ, MAP_PRIVATE,
 | 
			
		||||
               dmabuf_handle->dmabuf_fd,
 | 
			
		||||
               dmabuf_handle->offset);
 | 
			
		||||
  if (data == MAP_FAILED)
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
 | 
			
		||||
                   "mmap failed: %s", g_strerror (errno));
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
cogl_dma_buf_handle_munmap (CoglDmaBufHandle  *dmabuf_handle,
 | 
			
		||||
                            gpointer           data,
 | 
			
		||||
                            GError           **error)
 | 
			
		||||
{
 | 
			
		||||
  size_t size;
 | 
			
		||||
 | 
			
		||||
  size = dmabuf_handle->height * dmabuf_handle->stride;
 | 
			
		||||
  if (munmap (data, size) != 0)
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
 | 
			
		||||
                   "munmap failed: %s", g_strerror (errno));
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CoglFramebuffer *
 | 
			
		||||
cogl_dma_buf_handle_get_framebuffer (CoglDmaBufHandle *dmabuf_handle)
 | 
			
		||||
{
 | 
			
		||||
@@ -92,3 +200,32 @@ cogl_dma_buf_handle_get_fd (CoglDmaBufHandle *dmabuf_handle)
 | 
			
		||||
  return dmabuf_handle->dmabuf_fd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
cogl_dma_buf_handle_get_width (CoglDmaBufHandle *dmabuf_handle)
 | 
			
		||||
{
 | 
			
		||||
  return dmabuf_handle->width;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
cogl_dma_buf_handle_get_height (CoglDmaBufHandle *dmabuf_handle)
 | 
			
		||||
{
 | 
			
		||||
  return dmabuf_handle->height;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
cogl_dma_buf_handle_get_stride (CoglDmaBufHandle *dmabuf_handle)
 | 
			
		||||
{
 | 
			
		||||
  return dmabuf_handle->stride;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
cogl_dma_buf_handle_get_offset (CoglDmaBufHandle *dmabuf_handle)
 | 
			
		||||
{
 | 
			
		||||
  return dmabuf_handle->offset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
cogl_dma_buf_handle_get_bpp (CoglDmaBufHandle *dmabuf_handle)
 | 
			
		||||
{
 | 
			
		||||
  return dmabuf_handle->bpp;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -46,7 +46,12 @@
 | 
			
		||||
COGL_EXPORT CoglDmaBufHandle *
 | 
			
		||||
cogl_dma_buf_handle_new (CoglFramebuffer *framebuffer,
 | 
			
		||||
                         int              dmabuf_fd,
 | 
			
		||||
                         gpointer         data,
 | 
			
		||||
                         int              width,
 | 
			
		||||
                         int              height,
 | 
			
		||||
                         int              stride,
 | 
			
		||||
                         int              offset,
 | 
			
		||||
                         int              bpp,
 | 
			
		||||
                         gpointer         user_data,
 | 
			
		||||
                         GDestroyNotify   destroy_func);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -58,6 +63,23 @@ cogl_dma_buf_handle_new (CoglFramebuffer *framebuffer,
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_dma_buf_handle_free (CoglDmaBufHandle *dmabuf_handle);
 | 
			
		||||
 | 
			
		||||
COGL_EXPORT gboolean
 | 
			
		||||
cogl_dma_buf_handle_sync_read_start (CoglDmaBufHandle  *dmabuf_handle,
 | 
			
		||||
                                     GError           **error);
 | 
			
		||||
 | 
			
		||||
COGL_EXPORT gboolean
 | 
			
		||||
cogl_dma_buf_handle_sync_read_end (CoglDmaBufHandle  *dmabuf_handle,
 | 
			
		||||
                                   GError           **error);
 | 
			
		||||
 | 
			
		||||
COGL_EXPORT gpointer
 | 
			
		||||
cogl_dma_buf_handle_mmap (CoglDmaBufHandle  *dmabuf_handle,
 | 
			
		||||
                          GError           **error);
 | 
			
		||||
 | 
			
		||||
COGL_EXPORT gboolean
 | 
			
		||||
cogl_dma_buf_handle_munmap (CoglDmaBufHandle  *dmabuf_handle,
 | 
			
		||||
                            gpointer           data,
 | 
			
		||||
                            GError           **error);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_dma_buf_handle_get_framebuffer: (skip)
 | 
			
		||||
 *
 | 
			
		||||
@@ -79,5 +101,44 @@ cogl_dma_buf_handle_get_framebuffer (CoglDmaBufHandle *dmabuf_handle);
 | 
			
		||||
COGL_EXPORT int
 | 
			
		||||
cogl_dma_buf_handle_get_fd (CoglDmaBufHandle *dmabuf_handle);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_dmabuf_handle_get_width: (skip)
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: the buffer width
 | 
			
		||||
 */
 | 
			
		||||
COGL_EXPORT int
 | 
			
		||||
cogl_dma_buf_handle_get_width (CoglDmaBufHandle *dmabuf_handle);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_dmabuf_handle_get_height: (skip)
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: the buffer height
 | 
			
		||||
 */
 | 
			
		||||
COGL_EXPORT int
 | 
			
		||||
cogl_dma_buf_handle_get_height (CoglDmaBufHandle *dmabuf_handle);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_dmabuf_handle_get_stride: (skip)
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: the buffer stride
 | 
			
		||||
 */
 | 
			
		||||
COGL_EXPORT int
 | 
			
		||||
cogl_dma_buf_handle_get_stride (CoglDmaBufHandle *dmabuf_handle);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_dmabuf_handle_get_offset: (skip)
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: the buffer offset
 | 
			
		||||
 */
 | 
			
		||||
COGL_EXPORT int
 | 
			
		||||
cogl_dma_buf_handle_get_offset (CoglDmaBufHandle *dmabuf_handle);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_dmabuf_handle_get_bpp: (skip)
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: the number of bytes per pixel
 | 
			
		||||
 */
 | 
			
		||||
COGL_EXPORT int
 | 
			
		||||
cogl_dma_buf_handle_get_bpp (CoglDmaBufHandle *dmabuf_handle);
 | 
			
		||||
 | 
			
		||||
#endif /* __COGL_DMA_BUF_HANDLE_H__ */
 | 
			
		||||
 
 | 
			
		||||
@@ -1292,7 +1292,7 @@ cogl_blit_framebuffer (CoglFramebuffer *src,
 | 
			
		||||
  int src_x1, src_y1, src_x2, src_y2;
 | 
			
		||||
  int dst_x1, dst_y1, dst_x2, dst_y2;
 | 
			
		||||
 | 
			
		||||
  if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER))
 | 
			
		||||
  if (!cogl_has_feature (ctx, COGL_FEATURE_ID_BLIT_FRAMEBUFFER))
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error_literal (error, COGL_SYSTEM_ERROR,
 | 
			
		||||
                           COGL_SYSTEM_ERROR_UNSUPPORTED,
 | 
			
		||||
 
 | 
			
		||||
@@ -1509,7 +1509,7 @@ cogl_is_framebuffer (void *object);
 | 
			
		||||
 *
 | 
			
		||||
 * This blits a region of the color buffer of the source buffer
 | 
			
		||||
 * to the destination buffer. This function should only be
 | 
			
		||||
 * called if the COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER feature is
 | 
			
		||||
 * called if the COGL_FEATURE_ID_BLIT_FRAMEBUFFER feature is
 | 
			
		||||
 * advertised.
 | 
			
		||||
 *
 | 
			
		||||
 * The source and destination rectangles are defined in offscreen
 | 
			
		||||
 
 | 
			
		||||
@@ -93,10 +93,12 @@ _cogl_onscreen_init_from_template (CoglOnscreen *onscreen,
 | 
			
		||||
CoglOnscreen *
 | 
			
		||||
_cogl_onscreen_new (void)
 | 
			
		||||
{
 | 
			
		||||
  CoglOnscreen *onscreen = g_new0 (CoglOnscreen, 1);
 | 
			
		||||
  g_autofree CoglOnscreen *onscreen_ptr = g_new0 (CoglOnscreen, 1);
 | 
			
		||||
  CoglOnscreen *onscreen;
 | 
			
		||||
 | 
			
		||||
  _COGL_GET_CONTEXT (ctx, NULL);
 | 
			
		||||
 | 
			
		||||
  onscreen = g_steal_pointer (&onscreen_ptr);
 | 
			
		||||
  _cogl_framebuffer_init (COGL_FRAMEBUFFER (onscreen),
 | 
			
		||||
                          ctx,
 | 
			
		||||
                          COGL_FRAMEBUFFER_TYPE_ONSCREEN,
 | 
			
		||||
@@ -403,6 +405,27 @@ cogl_onscreen_get_buffer_age (CoglOnscreen *onscreen)
 | 
			
		||||
  return winsys->onscreen_get_buffer_age (onscreen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
cogl_onscreen_direct_scanout (CoglOnscreen *onscreen,
 | 
			
		||||
                              CoglScanout  *scanout)
 | 
			
		||||
{
 | 
			
		||||
  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
 | 
			
		||||
  const CoglWinsysVtable *winsys;
 | 
			
		||||
  CoglFrameInfo *info;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN);
 | 
			
		||||
  g_return_if_fail (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT));
 | 
			
		||||
 | 
			
		||||
  info = _cogl_frame_info_new ();
 | 
			
		||||
  info->frame_counter = onscreen->frame_counter;
 | 
			
		||||
  g_queue_push_tail (&onscreen->pending_frame_infos, info);
 | 
			
		||||
 | 
			
		||||
  winsys = _cogl_framebuffer_get_winsys (framebuffer);
 | 
			
		||||
  winsys->onscreen_direct_scanout (onscreen, scanout);
 | 
			
		||||
 | 
			
		||||
  onscreen->frame_counter++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef COGL_HAS_X11_SUPPORT
 | 
			
		||||
uint32_t
 | 
			
		||||
cogl_x11_onscreen_get_window_xid (CoglOnscreen *onscreen)
 | 
			
		||||
 
 | 
			
		||||
@@ -50,6 +50,8 @@ G_BEGIN_DECLS
 | 
			
		||||
typedef struct _CoglOnscreen CoglOnscreen;
 | 
			
		||||
#define COGL_ONSCREEN(X) ((CoglOnscreen *)(X))
 | 
			
		||||
 | 
			
		||||
typedef struct _CoglScanout CoglScanout;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_onscreen_get_gtype:
 | 
			
		||||
 *
 | 
			
		||||
@@ -284,6 +286,13 @@ cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
 | 
			
		||||
                                        const int *rectangles,
 | 
			
		||||
                                        int n_rectangles);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_onscreen_direct_scanout: (skip)
 | 
			
		||||
 */
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_onscreen_direct_scanout (CoglOnscreen *onscreen,
 | 
			
		||||
                              CoglScanout  *scanout);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * cogl_onscreen_swap_region:
 | 
			
		||||
 * @onscreen: A #CoglOnscreen framebuffer
 | 
			
		||||
 
 | 
			
		||||
@@ -50,7 +50,7 @@ struct _CoglPipelineCache
 | 
			
		||||
CoglPipelineCache *
 | 
			
		||||
_cogl_pipeline_cache_new (void)
 | 
			
		||||
{
 | 
			
		||||
  CoglPipelineCache *cache = g_new (CoglPipelineCache, 1);
 | 
			
		||||
  g_autofree CoglPipelineCache *cache = g_new (CoglPipelineCache, 1);
 | 
			
		||||
  unsigned long vertex_state;
 | 
			
		||||
  unsigned long layer_vertex_state;
 | 
			
		||||
  unsigned int fragment_state;
 | 
			
		||||
@@ -80,7 +80,7 @@ _cogl_pipeline_cache_new (void)
 | 
			
		||||
                                  layer_vertex_state | layer_fragment_state,
 | 
			
		||||
                                  "programs");
 | 
			
		||||
 | 
			
		||||
  return cache;
 | 
			
		||||
  return g_steal_pointer (&cache);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
 
 | 
			
		||||
@@ -1361,6 +1361,17 @@ cogl_pipeline_set_layer_filters (CoglPipeline      *pipeline,
 | 
			
		||||
                                          sampler_state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
cogl_pipeline_set_layer_max_mipmap_level (CoglPipeline *pipeline,
 | 
			
		||||
                                          int           layer,
 | 
			
		||||
                                          int           max_level)
 | 
			
		||||
{
 | 
			
		||||
  CoglTexture *texture = cogl_pipeline_get_layer_texture (pipeline, layer);
 | 
			
		||||
 | 
			
		||||
  if (texture != NULL)
 | 
			
		||||
    cogl_texture_set_max_level (texture, max_level);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const CoglSamplerCacheEntry *
 | 
			
		||||
_cogl_pipeline_layer_get_sampler_state (CoglPipelineLayer *layer)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -568,6 +568,11 @@ cogl_pipeline_add_layer_snippet (CoglPipeline *pipeline,
 | 
			
		||||
                                 int layer,
 | 
			
		||||
                                 CoglSnippet *snippet);
 | 
			
		||||
 | 
			
		||||
COGL_EXPORT void
 | 
			
		||||
cogl_pipeline_set_layer_max_mipmap_level (CoglPipeline *pipeline,
 | 
			
		||||
                                          int           layer,
 | 
			
		||||
                                          int           max_level);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __COGL_PIPELINE_LAYER_STATE_H__ */
 | 
			
		||||
 
 | 
			
		||||
@@ -42,7 +42,6 @@ typedef enum
 | 
			
		||||
{
 | 
			
		||||
  COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE,
 | 
			
		||||
  COGL_PRIVATE_FEATURE_MESA_PACK_INVERT,
 | 
			
		||||
  COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER,
 | 
			
		||||
  COGL_PRIVATE_FEATURE_PBOS,
 | 
			
		||||
  COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL,
 | 
			
		||||
  COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										27
									
								
								cogl/cogl/cogl-scanout.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								cogl/cogl/cogl-scanout.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2019 Red Hat Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "cogl-config.h"
 | 
			
		||||
 | 
			
		||||
#include "cogl-scanout.h"
 | 
			
		||||
 | 
			
		||||
G_DEFINE_INTERFACE (CoglScanout, cogl_scanout, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
cogl_scanout_default_init (CoglScanoutInterface *iface)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										35
									
								
								cogl/cogl/cogl-scanout.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								cogl/cogl/cogl-scanout.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2019 Red Hat Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef COGL_SCANOUT_H
 | 
			
		||||
#define COGL_SCANOUT_H
 | 
			
		||||
 | 
			
		||||
#include "cogl/cogl-types.h"
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
#define COGL_TYPE_SCANOUT (cogl_scanout_get_type ())
 | 
			
		||||
COGL_EXPORT
 | 
			
		||||
G_DECLARE_INTERFACE (CoglScanout, cogl_scanout,
 | 
			
		||||
                     COGL, SCANOUT, GObject)
 | 
			
		||||
 | 
			
		||||
struct _CoglScanoutInterface
 | 
			
		||||
{
 | 
			
		||||
  GTypeInterface parent_iface;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* COGL_SCANOUT_H */
 | 
			
		||||
@@ -204,7 +204,8 @@ struct _CoglTexture
 | 
			
		||||
  CoglContext *context;
 | 
			
		||||
  CoglTextureLoader *loader;
 | 
			
		||||
  GList *framebuffers;
 | 
			
		||||
  int max_level;
 | 
			
		||||
  int max_level_set;
 | 
			
		||||
  int max_level_requested;
 | 
			
		||||
  int width;
 | 
			
		||||
  int height;
 | 
			
		||||
  gboolean allocated;
 | 
			
		||||
@@ -377,6 +378,10 @@ _cogl_texture_needs_premult_conversion (CoglPixelFormat src_format,
 | 
			
		||||
int
 | 
			
		||||
_cogl_texture_get_n_levels (CoglTexture *texture);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
cogl_texture_set_max_level (CoglTexture *texture,
 | 
			
		||||
                            int          max_level);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_cogl_texture_get_level_size (CoglTexture *texture,
 | 
			
		||||
                              int level,
 | 
			
		||||
 
 | 
			
		||||
@@ -115,7 +115,8 @@ _cogl_texture_init (CoglTexture *texture,
 | 
			
		||||
                    const CoglTextureVtable *vtable)
 | 
			
		||||
{
 | 
			
		||||
  texture->context = context;
 | 
			
		||||
  texture->max_level = 0;
 | 
			
		||||
  texture->max_level_set = 0;
 | 
			
		||||
  texture->max_level_requested = 1000; /* OpenGL default GL_TEXTURE_MAX_LEVEL */
 | 
			
		||||
  texture->width = width;
 | 
			
		||||
  texture->height = height;
 | 
			
		||||
  texture->allocated = FALSE;
 | 
			
		||||
@@ -229,8 +230,16 @@ _cogl_texture_get_n_levels (CoglTexture *texture)
 | 
			
		||||
  int width = cogl_texture_get_width (texture);
 | 
			
		||||
  int height = cogl_texture_get_height (texture);
 | 
			
		||||
  int max_dimension = MAX (width, height);
 | 
			
		||||
  int n_levels = _cogl_util_fls (max_dimension);
 | 
			
		||||
 | 
			
		||||
  return _cogl_util_fls (max_dimension);
 | 
			
		||||
  return MIN (n_levels, texture->max_level_requested + 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
cogl_texture_set_max_level (CoglTexture *texture,
 | 
			
		||||
                            int          max_level)
 | 
			
		||||
{
 | 
			
		||||
  texture->max_level_requested = max_level;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
 
 | 
			
		||||
@@ -122,6 +122,7 @@
 | 
			
		||||
#include <cogl/cogl-fence.h>
 | 
			
		||||
#include <cogl/cogl-glib-source.h>
 | 
			
		||||
#include <cogl/cogl-trace.h>
 | 
			
		||||
#include <cogl/cogl-scanout.h>
 | 
			
		||||
/* XXX: This will definitly go away once all the Clutter winsys
 | 
			
		||||
 * code has been migrated down into Cogl! */
 | 
			
		||||
#include <cogl/deprecated/cogl-clutter.h>
 | 
			
		||||
 
 | 
			
		||||
@@ -388,8 +388,8 @@ _cogl_framebuffer_gl_flush_state (CoglFramebuffer *draw_buffer,
 | 
			
		||||
        {
 | 
			
		||||
          /* NB: Currently we only take advantage of binding separate
 | 
			
		||||
           * read/write buffers for framebuffer blit purposes. */
 | 
			
		||||
          g_return_if_fail (_cogl_has_private_feature
 | 
			
		||||
                            (ctx, COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER));
 | 
			
		||||
          g_return_if_fail (cogl_has_feature
 | 
			
		||||
                            (ctx, COGL_FEATURE_ID_BLIT_FRAMEBUFFER));
 | 
			
		||||
 | 
			
		||||
          _cogl_framebuffer_gl_bind (draw_buffer, GL_DRAW_FRAMEBUFFER);
 | 
			
		||||
          _cogl_framebuffer_gl_bind (read_buffer, GL_READ_FRAMEBUFFER);
 | 
			
		||||
 
 | 
			
		||||
@@ -567,6 +567,9 @@ _cogl_texture_2d_gl_copy_from_bitmap (CoglTexture2D *tex_2d,
 | 
			
		||||
                                          &gl_format,
 | 
			
		||||
                                          &gl_type);
 | 
			
		||||
 | 
			
		||||
  if (tex->max_level_set < level)
 | 
			
		||||
    cogl_texture_gl_set_max_level (tex, level);
 | 
			
		||||
 | 
			
		||||
  status = ctx->texture_driver->upload_subregion_to_gl (ctx,
 | 
			
		||||
                                                        tex,
 | 
			
		||||
                                                        src_x, src_y,
 | 
			
		||||
@@ -580,8 +583,6 @@ _cogl_texture_2d_gl_copy_from_bitmap (CoglTexture2D *tex_2d,
 | 
			
		||||
 | 
			
		||||
  cogl_object_unref (upload_bmp);
 | 
			
		||||
 | 
			
		||||
  _cogl_texture_gl_maybe_update_max_level (tex, level);
 | 
			
		||||
 | 
			
		||||
  return status;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -53,8 +53,8 @@ _cogl_texture_gl_flush_legacy_texobj_filters (CoglTexture *texture,
 | 
			
		||||
                                              unsigned int mag_filter);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_cogl_texture_gl_maybe_update_max_level (CoglTexture *texture,
 | 
			
		||||
                                         int max_level);
 | 
			
		||||
cogl_texture_gl_set_max_level (CoglTexture *texture,
 | 
			
		||||
                               int max_level);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_cogl_texture_gl_generate_mipmaps (CoglTexture *texture);
 | 
			
		||||
 
 | 
			
		||||
@@ -97,32 +97,36 @@ _cogl_texture_gl_flush_legacy_texobj_filters (CoglTexture *texture,
 | 
			
		||||
                                                   min_filter, mag_filter);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* GL and GLES3 have this by default, but GLES2 does not except via extension.
 | 
			
		||||
 * So really it's probably always available. Even if we used it and it wasn't
 | 
			
		||||
 * available in some driver then there are no adverse consequences to the
 | 
			
		||||
 * command simply being ignored...
 | 
			
		||||
 */
 | 
			
		||||
#ifndef GL_TEXTURE_MAX_LEVEL
 | 
			
		||||
#define GL_TEXTURE_MAX_LEVEL 0x813D
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_cogl_texture_gl_maybe_update_max_level (CoglTexture *texture,
 | 
			
		||||
                                         int max_level)
 | 
			
		||||
cogl_texture_gl_set_max_level (CoglTexture *texture,
 | 
			
		||||
                               int max_level)
 | 
			
		||||
{
 | 
			
		||||
  /* This isn't supported on GLES */
 | 
			
		||||
#ifdef HAVE_COGL_GL
 | 
			
		||||
  CoglContext *ctx = texture->context;
 | 
			
		||||
 | 
			
		||||
  if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL) &&
 | 
			
		||||
      texture->max_level < max_level)
 | 
			
		||||
  if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL))
 | 
			
		||||
    {
 | 
			
		||||
      CoglContext *ctx = texture->context;
 | 
			
		||||
      GLuint gl_handle;
 | 
			
		||||
      GLenum gl_target;
 | 
			
		||||
 | 
			
		||||
      cogl_texture_get_gl_texture (texture, &gl_handle, &gl_target);
 | 
			
		||||
 | 
			
		||||
      texture->max_level = max_level;
 | 
			
		||||
      texture->max_level_set = max_level;
 | 
			
		||||
 | 
			
		||||
      _cogl_bind_gl_texture_transient (gl_target,
 | 
			
		||||
                                       gl_handle);
 | 
			
		||||
 | 
			
		||||
      GE( ctx, glTexParameteri (gl_target,
 | 
			
		||||
                                GL_TEXTURE_MAX_LEVEL, texture->max_level));
 | 
			
		||||
                                GL_TEXTURE_MAX_LEVEL, texture->max_level_set));
 | 
			
		||||
    }
 | 
			
		||||
#endif /* HAVE_COGL_GL */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -133,7 +137,8 @@ _cogl_texture_gl_generate_mipmaps (CoglTexture *texture)
 | 
			
		||||
  GLuint gl_handle;
 | 
			
		||||
  GLenum gl_target;
 | 
			
		||||
 | 
			
		||||
  _cogl_texture_gl_maybe_update_max_level (texture, n_levels - 1);
 | 
			
		||||
  if (texture->max_level_set != n_levels - 1)
 | 
			
		||||
    cogl_texture_gl_set_max_level (texture, n_levels - 1);
 | 
			
		||||
 | 
			
		||||
  cogl_texture_get_gl_texture (texture, &gl_handle, &gl_target);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -455,8 +455,8 @@ _cogl_driver_update_features (CoglContext *ctx,
 | 
			
		||||
                  TRUE);
 | 
			
		||||
 | 
			
		||||
  if (ctx->glBlitFramebuffer)
 | 
			
		||||
    COGL_FLAGS_SET (private_features,
 | 
			
		||||
                    COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER, TRUE);
 | 
			
		||||
    COGL_FLAGS_SET (ctx->features,
 | 
			
		||||
                    COGL_FEATURE_ID_BLIT_FRAMEBUFFER, TRUE);
 | 
			
		||||
 | 
			
		||||
  COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_PBOS, TRUE);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -255,7 +255,7 @@ _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx,
 | 
			
		||||
       * glTexImage2D first to assert that the storage for this
 | 
			
		||||
       * level exists.
 | 
			
		||||
       */
 | 
			
		||||
      if (texture->max_level < level)
 | 
			
		||||
      if (texture->max_level_set < level)
 | 
			
		||||
        {
 | 
			
		||||
          ctx->glTexImage2D (gl_target,
 | 
			
		||||
                             level,
 | 
			
		||||
 
 | 
			
		||||
@@ -318,8 +318,8 @@ _cogl_driver_update_features (CoglContext *context,
 | 
			
		||||
    COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS, TRUE);
 | 
			
		||||
 | 
			
		||||
  if (context->glBlitFramebuffer)
 | 
			
		||||
    COGL_FLAGS_SET (private_features,
 | 
			
		||||
                    COGL_PRIVATE_FEATURE_BLIT_FRAMEBUFFER, TRUE);
 | 
			
		||||
    COGL_FLAGS_SET (context->features,
 | 
			
		||||
                    COGL_FEATURE_ID_BLIT_FRAMEBUFFER, TRUE);
 | 
			
		||||
 | 
			
		||||
  if (_cogl_check_extension ("GL_OES_element_index_uint", gl_extensions))
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -303,7 +303,7 @@ _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx,
 | 
			
		||||
       * glTexImage2D first to assert that the storage for this
 | 
			
		||||
       * level exists.
 | 
			
		||||
       */
 | 
			
		||||
      if (texture->max_level < level)
 | 
			
		||||
      if (texture->max_level_set < level)
 | 
			
		||||
        {
 | 
			
		||||
          ctx->glTexImage2D (gl_target,
 | 
			
		||||
                             level,
 | 
			
		||||
 
 | 
			
		||||
@@ -122,6 +122,7 @@ cogl_nonintrospected_headers = [
 | 
			
		||||
  'cogl-version.h',
 | 
			
		||||
  'cogl-gtype-private.h',
 | 
			
		||||
  'cogl-glib-source.h',
 | 
			
		||||
  'cogl-scanout.h',
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
cogl_nodist_headers = [
 | 
			
		||||
@@ -347,6 +348,7 @@ cogl_sources = [
 | 
			
		||||
  'cogl-closure-list.c',
 | 
			
		||||
  'cogl-fence.c',
 | 
			
		||||
  'cogl-fence-private.h',
 | 
			
		||||
  'cogl-scanout.c',
 | 
			
		||||
  'deprecated/cogl-material-compat.c',
 | 
			
		||||
  'deprecated/cogl-program.c',
 | 
			
		||||
  'deprecated/cogl-program-private.h',
 | 
			
		||||
 
 | 
			
		||||
@@ -33,6 +33,7 @@
 | 
			
		||||
 | 
			
		||||
#include "cogl-renderer.h"
 | 
			
		||||
#include "cogl-onscreen.h"
 | 
			
		||||
#include "cogl-scanout.h"
 | 
			
		||||
 | 
			
		||||
#ifdef COGL_HAS_XLIB_SUPPORT
 | 
			
		||||
#include "cogl-texture-pixmap-x11-private.h"
 | 
			
		||||
@@ -117,6 +118,10 @@ typedef struct _CoglWinsysVtable
 | 
			
		||||
                                        const int *rectangles,
 | 
			
		||||
                                        int n_rectangles);
 | 
			
		||||
 | 
			
		||||
  void
 | 
			
		||||
  (*onscreen_direct_scanout) (CoglOnscreen *onscreen,
 | 
			
		||||
                              CoglScanout  *scanout);
 | 
			
		||||
 | 
			
		||||
  void
 | 
			
		||||
  (*onscreen_set_visibility) (CoglOnscreen *onscreen,
 | 
			
		||||
                              gboolean visibility);
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,7 @@ cogl_config_h = configure_file(
 | 
			
		||||
 | 
			
		||||
cogl_pkg_deps = [
 | 
			
		||||
  glib_dep,
 | 
			
		||||
  gio_dep,
 | 
			
		||||
  gobject_dep,
 | 
			
		||||
  graphene_dep,
 | 
			
		||||
]
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,7 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
 | 
			
		||||
set -o pipefail
 | 
			
		||||
 | 
			
		||||
if test -z "$G_DEBUG"; then
 | 
			
		||||
    G_DEBUG=fatal-warnings
 | 
			
		||||
else
 | 
			
		||||
@@ -69,7 +71,12 @@ get_status()
 | 
			
		||||
 | 
			
		||||
run_test()
 | 
			
		||||
{
 | 
			
		||||
  $("$TEST_BINARY" "$1" &> "$LOG")
 | 
			
		||||
  if [ -n "${VERBOSE-}" ]; then
 | 
			
		||||
    echo "running $TEST_BINARY $1:"
 | 
			
		||||
    $TEST_BINARY $1 2>&1 | tee "$LOG"
 | 
			
		||||
  else
 | 
			
		||||
    $($TEST_BINARY $1 &> "$LOG")
 | 
			
		||||
  fi
 | 
			
		||||
  TMP=$?
 | 
			
		||||
  var_name=$2_result
 | 
			
		||||
  eval "$var_name=$TMP"
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
 
 | 
			
		||||
@@ -108,6 +108,14 @@ struct _MetaBackendClass
 | 
			
		||||
 | 
			
		||||
void meta_init_backend (GType backend_gtype);
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_WAYLAND
 | 
			
		||||
MetaWaylandCompositor * meta_backend_get_wayland_compositor (MetaBackend *backend);
 | 
			
		||||
 | 
			
		||||
void meta_backend_init_wayland_display (MetaBackend *backend);
 | 
			
		||||
 | 
			
		||||
void meta_backend_init_wayland (MetaBackend *backend);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
ClutterBackend * meta_backend_get_clutter_backend (MetaBackend *backend);
 | 
			
		||||
 | 
			
		||||
MetaIdleMonitor * meta_backend_get_idle_monitor (MetaBackend        *backend,
 | 
			
		||||
 
 | 
			
		||||
@@ -49,8 +49,11 @@ 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;
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaWaylandCompositor MetaWaylandCompositor;
 | 
			
		||||
 | 
			
		||||
#endif /* META_BACKEND_TYPE_H */
 | 
			
		||||
 
 | 
			
		||||
@@ -81,6 +81,10 @@
 | 
			
		||||
#include "backends/native/meta-backend-native.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_WAYLAND
 | 
			
		||||
#include "wayland/meta-wayland.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
  KEYMAP_CHANGED,
 | 
			
		||||
@@ -130,6 +134,10 @@ struct _MetaBackendPrivate
 | 
			
		||||
  MetaRemoteDesktop *remote_desktop;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_WAYLAND
 | 
			
		||||
  MetaWaylandCompositor *wayland_compositor;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_PROFILER
 | 
			
		||||
  MetaProfiler *profiler;
 | 
			
		||||
#endif
 | 
			
		||||
@@ -552,12 +560,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 +817,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);
 | 
			
		||||
}
 | 
			
		||||
@@ -867,6 +872,120 @@ system_bus_gotten_cb (GObject      *object,
 | 
			
		||||
                                        NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_WAYLAND
 | 
			
		||||
MetaWaylandCompositor *
 | 
			
		||||
meta_backend_get_wayland_compositor (MetaBackend *backend)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
 | 
			
		||||
 | 
			
		||||
  return priv->wayland_compositor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_backend_init_wayland_display (MetaBackend *backend)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
 | 
			
		||||
 | 
			
		||||
  priv->wayland_compositor = meta_wayland_compositor_new (backend);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_backend_init_wayland (MetaBackend *backend)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
 | 
			
		||||
 | 
			
		||||
  meta_wayland_compositor_setup (priv->wayland_compositor);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Mutter is responsible for pulling events off the X queue, so Clutter
 | 
			
		||||
 * doesn't need (and shouldn't) run its normal event source which polls
 | 
			
		||||
 * the X fd, but we do have to deal with dispatching events that accumulate
 | 
			
		||||
 * in the clutter queue. This happens, for example, when clutter generate
 | 
			
		||||
 * enter/leave events on mouse motion - several events are queued in the
 | 
			
		||||
 * clutter queue but only one dispatched. It could also happen because of
 | 
			
		||||
 * explicit calls to clutter_event_put(). We add a very simple custom
 | 
			
		||||
 * event loop source which is simply responsible for pulling events off
 | 
			
		||||
 * of the queue and dispatching them before we block for new events.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
clutter_source_prepare (GSource *source,
 | 
			
		||||
                        int     *timeout)
 | 
			
		||||
{
 | 
			
		||||
  *timeout = -1;
 | 
			
		||||
 | 
			
		||||
  return clutter_events_pending ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
clutter_source_check (GSource *source)
 | 
			
		||||
{
 | 
			
		||||
  return clutter_events_pending ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
clutter_source_dispatch (GSource     *source,
 | 
			
		||||
                         GSourceFunc  callback,
 | 
			
		||||
                         gpointer     user_data)
 | 
			
		||||
{
 | 
			
		||||
  ClutterEvent *event = clutter_event_get ();
 | 
			
		||||
 | 
			
		||||
  if (event)
 | 
			
		||||
    {
 | 
			
		||||
      clutter_do_event (event);
 | 
			
		||||
      clutter_event_free (event);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GSourceFuncs clutter_source_funcs = {
 | 
			
		||||
  clutter_source_prepare,
 | 
			
		||||
  clutter_source_check,
 | 
			
		||||
  clutter_source_dispatch
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static ClutterBackend *
 | 
			
		||||
meta_get_clutter_backend (void)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackend *backend = meta_get_backend ();
 | 
			
		||||
 | 
			
		||||
  return meta_backend_get_clutter_backend (backend);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
init_clutter (MetaBackend  *backend,
 | 
			
		||||
              GError      **error)
 | 
			
		||||
{
 | 
			
		||||
  GSource *source;
 | 
			
		||||
 | 
			
		||||
  clutter_set_custom_backend_func (meta_get_clutter_backend);
 | 
			
		||||
 | 
			
		||||
  if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS)
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
 | 
			
		||||
                   "Unable to initialize Clutter");
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  source = g_source_new (&clutter_source_funcs, sizeof (GSource));
 | 
			
		||||
  g_source_attach (source, NULL);
 | 
			
		||||
  g_source_unref (source);
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_backend_post_init (MetaBackend *backend)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
 | 
			
		||||
 | 
			
		||||
  META_BACKEND_GET_CLASS (backend)->post_init (backend);
 | 
			
		||||
 | 
			
		||||
  meta_settings_post_init (priv->settings);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
meta_backend_initable_init (GInitable     *initable,
 | 
			
		||||
                            GCancellable  *cancellable,
 | 
			
		||||
@@ -905,6 +1024,11 @@ meta_backend_initable_init (GInitable     *initable,
 | 
			
		||||
  priv->profiler = meta_profiler_new ();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  if (!init_clutter (backend, error))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  meta_backend_post_init (backend);
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -920,16 +1044,6 @@ meta_backend_init (MetaBackend *backend)
 | 
			
		||||
  _backend = backend;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_backend_post_init (MetaBackend *backend)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
 | 
			
		||||
 | 
			
		||||
  META_BACKEND_GET_CLASS (backend)->post_init (backend);
 | 
			
		||||
 | 
			
		||||
  meta_settings_post_init (priv->settings);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_backend_get_idle_monitor: (skip)
 | 
			
		||||
 */
 | 
			
		||||
@@ -1261,54 +1375,6 @@ meta_backend_set_client_pointer_constraint (MetaBackend           *backend,
 | 
			
		||||
    priv->client_pointer_constraint = g_object_ref (constraint);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Mutter is responsible for pulling events off the X queue, so Clutter
 | 
			
		||||
 * doesn't need (and shouldn't) run its normal event source which polls
 | 
			
		||||
 * the X fd, but we do have to deal with dispatching events that accumulate
 | 
			
		||||
 * in the clutter queue. This happens, for example, when clutter generate
 | 
			
		||||
 * enter/leave events on mouse motion - several events are queued in the
 | 
			
		||||
 * clutter queue but only one dispatched. It could also happen because of
 | 
			
		||||
 * explicit calls to clutter_event_put(). We add a very simple custom
 | 
			
		||||
 * event loop source which is simply responsible for pulling events off
 | 
			
		||||
 * of the queue and dispatching them before we block for new events.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
event_prepare (GSource    *source,
 | 
			
		||||
               gint       *timeout_)
 | 
			
		||||
{
 | 
			
		||||
  *timeout_ = -1;
 | 
			
		||||
 | 
			
		||||
  return clutter_events_pending ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
event_check (GSource *source)
 | 
			
		||||
{
 | 
			
		||||
  return clutter_events_pending ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
event_dispatch (GSource    *source,
 | 
			
		||||
                GSourceFunc callback,
 | 
			
		||||
                gpointer    user_data)
 | 
			
		||||
{
 | 
			
		||||
  ClutterEvent *event = clutter_event_get ();
 | 
			
		||||
 | 
			
		||||
  if (event)
 | 
			
		||||
    {
 | 
			
		||||
      clutter_do_event (event);
 | 
			
		||||
      clutter_event_free (event);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GSourceFuncs event_funcs = {
 | 
			
		||||
  event_prepare,
 | 
			
		||||
  event_check,
 | 
			
		||||
  event_dispatch
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ClutterBackend *
 | 
			
		||||
meta_backend_get_clutter_backend (MetaBackend *backend)
 | 
			
		||||
{
 | 
			
		||||
@@ -1323,14 +1389,6 @@ meta_backend_get_clutter_backend (MetaBackend *backend)
 | 
			
		||||
  return priv->clutter_backend;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ClutterBackend *
 | 
			
		||||
meta_get_clutter_backend (void)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackend *backend = meta_get_backend ();
 | 
			
		||||
 | 
			
		||||
  return meta_backend_get_clutter_backend (backend);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_init_backend (GType backend_gtype)
 | 
			
		||||
{
 | 
			
		||||
@@ -1347,29 +1405,6 @@ meta_init_backend (GType backend_gtype)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_clutter_init: (skip)
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
meta_clutter_init (void)
 | 
			
		||||
{
 | 
			
		||||
  GSource *source;
 | 
			
		||||
 | 
			
		||||
  clutter_set_custom_backend_func (meta_get_clutter_backend);
 | 
			
		||||
 | 
			
		||||
  if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS)
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("Unable to initialize Clutter.\n");
 | 
			
		||||
      exit (1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  source = g_source_new (&event_funcs, sizeof (GSource));
 | 
			
		||||
  g_source_attach (source, NULL);
 | 
			
		||||
  g_source_unref (source);
 | 
			
		||||
 | 
			
		||||
  meta_backend_post_init (_backend);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_is_stage_views_enabled:
 | 
			
		||||
 *
 | 
			
		||||
 
 | 
			
		||||
@@ -84,6 +84,7 @@ translate_meta_cursor (MetaCursor cursor)
 | 
			
		||||
      return "crosshair";
 | 
			
		||||
    case META_CURSOR_IBEAM:
 | 
			
		||||
      return "xterm";
 | 
			
		||||
    case META_CURSOR_BLANK:
 | 
			
		||||
    case META_CURSOR_NONE:
 | 
			
		||||
    case META_CURSOR_LAST:
 | 
			
		||||
      break;
 | 
			
		||||
@@ -93,6 +94,48 @@ translate_meta_cursor (MetaCursor cursor)
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Cursor
 | 
			
		||||
create_blank_cursor (Display *xdisplay)
 | 
			
		||||
{
 | 
			
		||||
  Pixmap pixmap;
 | 
			
		||||
  XColor color;
 | 
			
		||||
  Cursor cursor;
 | 
			
		||||
  XGCValues gc_values;
 | 
			
		||||
  GC gc;
 | 
			
		||||
 | 
			
		||||
  pixmap = XCreatePixmap (xdisplay, DefaultRootWindow (xdisplay), 1, 1, 1);
 | 
			
		||||
 | 
			
		||||
  gc_values.foreground = BlackPixel (xdisplay, DefaultScreen (xdisplay));
 | 
			
		||||
  gc = XCreateGC (xdisplay, pixmap, GCForeground, &gc_values);
 | 
			
		||||
 | 
			
		||||
  XFillRectangle (xdisplay, pixmap, gc, 0, 0, 1, 1);
 | 
			
		||||
 | 
			
		||||
  color.pixel = 0;
 | 
			
		||||
  color.red = color.blue = color.green = 0;
 | 
			
		||||
 | 
			
		||||
  cursor = XCreatePixmapCursor (xdisplay, pixmap, pixmap, &color, &color, 1, 1);
 | 
			
		||||
 | 
			
		||||
  XFreeGC (xdisplay, gc);
 | 
			
		||||
  XFreePixmap (xdisplay, pixmap);
 | 
			
		||||
 | 
			
		||||
  return cursor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static XcursorImages *
 | 
			
		||||
create_blank_cursor_images (void)
 | 
			
		||||
{
 | 
			
		||||
  XcursorImages *images;
 | 
			
		||||
 | 
			
		||||
  images = XcursorImagesCreate (1);
 | 
			
		||||
  images->images[0] = XcursorImageCreate (1, 1);
 | 
			
		||||
 | 
			
		||||
  images->images[0]->xhot = 0;
 | 
			
		||||
  images->images[0]->yhot = 0;
 | 
			
		||||
  memset (images->images[0]->pixels, 0, sizeof(int32_t));
 | 
			
		||||
 | 
			
		||||
  return images;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaCursor
 | 
			
		||||
meta_cursor_sprite_xcursor_get_cursor (MetaCursorSpriteXcursor *sprite_xcursor)
 | 
			
		||||
{
 | 
			
		||||
@@ -103,12 +146,18 @@ Cursor
 | 
			
		||||
meta_create_x_cursor (Display    *xdisplay,
 | 
			
		||||
                      MetaCursor  cursor)
 | 
			
		||||
{
 | 
			
		||||
  if (cursor == META_CURSOR_BLANK)
 | 
			
		||||
    return create_blank_cursor (xdisplay);
 | 
			
		||||
 | 
			
		||||
  return XcursorLibraryLoadCursor (xdisplay, translate_meta_cursor (cursor));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static XcursorImages *
 | 
			
		||||
load_cursor_on_client (MetaCursor cursor, int scale)
 | 
			
		||||
{
 | 
			
		||||
  if (cursor == META_CURSOR_BLANK)
 | 
			
		||||
    return create_blank_cursor_images ();
 | 
			
		||||
 | 
			
		||||
  return XcursorLibraryLoadImages (translate_meta_cursor (cursor),
 | 
			
		||||
                                   meta_prefs_get_cursor_theme (),
 | 
			
		||||
                                   meta_prefs_get_cursor_size () * scale);
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -172,6 +172,7 @@ assign_monitor_crtc (MetaMonitor         *monitor,
 | 
			
		||||
  MetaCrtc *crtc;
 | 
			
		||||
  MetaMonitorTransform transform;
 | 
			
		||||
  MetaMonitorTransform crtc_transform;
 | 
			
		||||
  MetaMonitorTransform crtc_hw_transform;
 | 
			
		||||
  int crtc_x, crtc_y;
 | 
			
		||||
  float x_offset, y_offset;
 | 
			
		||||
  float scale = 0.0;
 | 
			
		||||
@@ -200,10 +201,12 @@ assign_monitor_crtc (MetaMonitor         *monitor,
 | 
			
		||||
 | 
			
		||||
  transform = data->logical_monitor_config->transform;
 | 
			
		||||
  crtc_transform = meta_monitor_logical_to_crtc_transform (monitor, transform);
 | 
			
		||||
  if (!meta_monitor_manager_is_transform_handled (data->monitor_manager,
 | 
			
		||||
                                                  crtc,
 | 
			
		||||
                                                  crtc_transform))
 | 
			
		||||
    crtc_transform = META_MONITOR_TRANSFORM_NORMAL;
 | 
			
		||||
  if (meta_monitor_manager_is_transform_handled (data->monitor_manager,
 | 
			
		||||
                                                 crtc,
 | 
			
		||||
                                                 crtc_transform))
 | 
			
		||||
    crtc_hw_transform = crtc_transform;
 | 
			
		||||
  else
 | 
			
		||||
    crtc_hw_transform = META_MONITOR_TRANSFORM_NORMAL;
 | 
			
		||||
 | 
			
		||||
  meta_monitor_calculate_crtc_pos (monitor, mode, output, crtc_transform,
 | 
			
		||||
                                   &crtc_x, &crtc_y);
 | 
			
		||||
@@ -244,7 +247,7 @@ assign_monitor_crtc (MetaMonitor         *monitor,
 | 
			
		||||
    .crtc = crtc,
 | 
			
		||||
    .mode = crtc_mode,
 | 
			
		||||
    .layout = crtc_layout,
 | 
			
		||||
    .transform = crtc_transform,
 | 
			
		||||
    .transform = crtc_hw_transform,
 | 
			
		||||
    .outputs = g_ptr_array_new ()
 | 
			
		||||
  };
 | 
			
		||||
  g_ptr_array_add (crtc_info->outputs, output);
 | 
			
		||||
@@ -443,23 +446,35 @@ MetaMonitorsConfigKey *
 | 
			
		||||
meta_create_monitors_config_key_for_current_state (MetaMonitorManager *monitor_manager)
 | 
			
		||||
{
 | 
			
		||||
  MetaMonitorsConfigKey *config_key;
 | 
			
		||||
  MetaMonitorSpec *laptop_monitor_spec;
 | 
			
		||||
  GList *l;
 | 
			
		||||
  GList *monitor_specs;
 | 
			
		||||
 | 
			
		||||
  laptop_monitor_spec = NULL;
 | 
			
		||||
  monitor_specs = NULL;
 | 
			
		||||
  for (l = monitor_manager->monitors; l; l = l->next)
 | 
			
		||||
    {
 | 
			
		||||
      MetaMonitor *monitor = l->data;
 | 
			
		||||
      MetaMonitorSpec *monitor_spec;
 | 
			
		||||
 | 
			
		||||
      if (meta_monitor_is_laptop_panel (monitor) &&
 | 
			
		||||
          is_lid_closed (monitor_manager))
 | 
			
		||||
        continue;
 | 
			
		||||
      if (meta_monitor_is_laptop_panel (monitor))
 | 
			
		||||
        {
 | 
			
		||||
          laptop_monitor_spec = meta_monitor_get_spec (monitor);
 | 
			
		||||
 | 
			
		||||
          if (is_lid_closed (monitor_manager))
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      monitor_spec = meta_monitor_spec_clone (meta_monitor_get_spec (monitor));
 | 
			
		||||
      monitor_specs = g_list_prepend (monitor_specs, monitor_spec);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (!monitor_specs && laptop_monitor_spec)
 | 
			
		||||
    {
 | 
			
		||||
      monitor_specs =
 | 
			
		||||
        g_list_prepend (NULL, meta_monitor_spec_clone (laptop_monitor_spec));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (!monitor_specs)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user