Compare commits
	
		
			4 Commits
		
	
	
		
			citadel-46
			...
			wip/is-swi
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 2467439d94 | ||
|   | 0e83b748d5 | ||
|   | bda4af5504 | ||
|   | f97d8dfb6c | 
							
								
								
									
										35
									
								
								.cvsignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								.cvsignore
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| Makefile | ||||
| Makefile.in | ||||
| aclocal.m4 | ||||
| confdefs.h | ||||
| config.cache | ||||
| config.guess | ||||
| config.h | ||||
| config.log | ||||
| config.status | ||||
| config.sub | ||||
| configure | ||||
| configure.scan | ||||
| libtool | ||||
| ltconfig | ||||
| ltmain.sh | ||||
| stamp-h | ||||
| stamp-h.in | ||||
| stamp-h1 | ||||
| stamp.h | ||||
| version.h | ||||
| config.h.in | ||||
| install-sh | ||||
| missing | ||||
| mkinstalldirs | ||||
| INSTALL | ||||
| intl | ||||
| ABOUT-NLS | ||||
| COPYING | ||||
| intltool-* | ||||
| metacity.spec | ||||
| autom4te.cache | ||||
| compile | ||||
| depcomp | ||||
| omf.make | ||||
| xmldocs.make | ||||
							
								
								
									
										101
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										101
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,11 +1,94 @@ | ||||
| Makefile | ||||
| Makefile.in | ||||
| Makefile.in.in | ||||
| aclocal.m4 | ||||
| autom4te.cache | ||||
| compile | ||||
| config.guess | ||||
| config.h | ||||
| config.h.in | ||||
| config.log | ||||
| config.status | ||||
| config.sub | ||||
| configure | ||||
| depcomp | ||||
| install-sh | ||||
| intltool-extract.in | ||||
| intltool-merge.in | ||||
| libtool | ||||
| ltmain.sh | ||||
| missing | ||||
| .deps | ||||
| src/50-mutter-navigation.xml | ||||
| src/50-mutter-system.xml | ||||
| src/50-mutter-windows.xml | ||||
| src/mutter-wm.desktop | ||||
| src/mutter.desktop | ||||
| *.o | ||||
| *.a | ||||
| *.lo | ||||
| *.la | ||||
| .libs | ||||
| *.swp | ||||
| *.gir | ||||
| *.typelib | ||||
| tidy-enum-types.[ch] | ||||
| tidy-marshal.[ch] | ||||
| stamp-tidy-enum-types.h | ||||
| stamp-tidy-marshal.h | ||||
| stamp-h1 | ||||
| *.gmo | ||||
| *.make | ||||
| *~ | ||||
| **/tags.* | ||||
| subprojects/sysprof/ | ||||
| __pycache__/ | ||||
| .buildconfig | ||||
| .vscode | ||||
| runtime-dir | ||||
| build | ||||
| _build | ||||
| builddir | ||||
| stamp-it | ||||
| .intltool-merge-cache | ||||
| POTFILES | ||||
| po/*.pot | ||||
| 50-metacity-desktop-key.xml | ||||
| 50-metacity-key.xml | ||||
| inlinepixbufs.h | ||||
| libmutter.pc | ||||
| mutter | ||||
| mutter-theme-viewer | ||||
| mutter.desktop | ||||
| org.gnome.mutter.gschema.valid | ||||
| org.gnome.mutter.gschema.xml | ||||
| testasyncgetprop | ||||
| testboxes | ||||
| testgradient | ||||
| mutter-grayscale | ||||
| mutter-mag | ||||
| mutter-message | ||||
| mutter-window-demo | ||||
| focus-window | ||||
| test-attached | ||||
| test-gravity | ||||
| test-resizing | ||||
| test-size-hints | ||||
| # We can't say just "wm-tester" here or it will ignore the directory | ||||
| # rather than the binary | ||||
| src/wm-tester/wm-tester | ||||
| INSTALL | ||||
| mkinstalldirs | ||||
| src/mutter-enum-types.[ch] | ||||
| src/stamp-mutter-enum-types.h | ||||
| src/mutter-marshal.[ch] | ||||
| src/stamp-mutter-marshal.h | ||||
| src/mutter-plugins.pc | ||||
| doc/reference/*.args | ||||
| doc/reference/*.bak | ||||
| doc/reference/*.hierarchy | ||||
| doc/reference/*.interfaces | ||||
| doc/reference/*.prerequisites | ||||
| doc/reference/*.signals | ||||
| doc/reference/*.stamp | ||||
| doc/reference/html/ | ||||
| doc/reference/xml/ | ||||
| doc/reference/meta-decl-list.txt | ||||
| doc/reference/meta-decl.txt | ||||
| doc/reference/meta-overrides.txt | ||||
| doc/reference/meta-undeclared.txt | ||||
| doc/reference/meta-undocumented.txt | ||||
| doc/reference/meta-unused.txt | ||||
| doc/reference/meta-docs.sgml | ||||
| doc/reference/meta.types | ||||
|   | ||||
							
								
								
									
										675
									
								
								.gitlab-ci.yml
									
									
									
									
									
								
							
							
						
						
									
										675
									
								
								.gitlab-ci.yml
									
									
									
									
									
								
							| @@ -1,675 +0,0 @@ | ||||
| include: | ||||
|   - remote: 'https://gitlab.freedesktop.org/freedesktop/ci-templates/-/raw/145b1bc7ef1702d2bd71584010d7113c6786a506/templates/fedora.yml' | ||||
|   - remote: 'https://gitlab.freedesktop.org/freedesktop/ci-templates/-/raw/34f4ade99434043f88e164933f570301fd18b125/templates/ci-fairy.yml' | ||||
|  | ||||
| stages: | ||||
|  - review | ||||
|  - prepare | ||||
|  - code-review | ||||
|  - build | ||||
|  - test | ||||
|  - analyze | ||||
|  - docs | ||||
|  - deploy | ||||
|  | ||||
| variables: | ||||
|   FDO_UPSTREAM_REPO: GNOME/mutter | ||||
|  | ||||
| .skip-git-clone: | ||||
|   variables: | ||||
|     GIT_STRATEGY: none | ||||
|  | ||||
| .mutter.git-clone: | ||||
|   extends: | ||||
|     - .skip-git-clone | ||||
|   variables: | ||||
|     MUTTER_CLONE_PATH: $CI_BUILDS_DIR/$CI_PROJECT_PATH | ||||
|     MUTTER_CLONE_DEPTH: 1 | ||||
|   before_script: | | ||||
|     if [ -n "$MUTTER_CLONE_PATH" ]; then | ||||
|       set -x | ||||
|       uri="$CI_REPOSITORY_URL" | ||||
|       if [ -n "$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME" ]; then | ||||
|         uri="$CI_MERGE_REQUEST_SOURCE_PROJECT_URL.git" | ||||
|         branch="$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME" | ||||
|       elif [ -n "$CI_COMMIT_TAG" ]; then | ||||
|         branch="$CI_COMMIT_TAG" | ||||
|       elif [ -n "$CI_COMMIT_BRANCH" ]; then | ||||
|         branch="$CI_COMMIT_BRANCH" | ||||
|       else | ||||
|         branch="$CI_DEFAULT_BRANCH" | ||||
|       fi | ||||
|       if [ ! -d "$MUTTER_CLONE_PATH" ] || [ -z "$(ls -A "$MUTTER_CLONE_PATH")" ]; then | ||||
|         git clone --depth $MUTTER_CLONE_DEPTH "$uri" "$MUTTER_CLONE_PATH" -b "$branch" | ||||
|       elif [ ! -d "$MUTTER_CLONE_PATH/.git" ]; then | ||||
|         git clone --bare --depth $MUTTER_CLONE_DEPTH "$uri" "$MUTTER_CLONE_PATH/.git" -b "$branch" | ||||
|         if git -C "$MUTTER_CLONE_PATH" config --unset core.bare; then | ||||
|           git -C "$MUTTER_CLONE_PATH" checkout | ||||
|         else | ||||
|           # For some weird reasons sometimes the fast-path could fail with | ||||
|           # "fatal: not in a git directory" error, so handle it manually | ||||
|           tmpdir=$(mktemp --directory --tmpdir mutter-XXXXXX) | ||||
|           mkdir "$tmpdir/repo" | ||||
|           mv "$MUTTER_CLONE_PATH/.git" "$tmpdir/repo/" | ||||
|           git clone "$tmpdir/repo" "$tmpdir/src" | ||||
|           mv "$tmpdir"/src/* "$tmpdir"/src/.* "$MUTTER_CLONE_PATH" | ||||
|           rm -r "$tmpdir/repo" | ||||
|           rm -rv "$tmpdir" | ||||
|         fi | ||||
|       fi | ||||
|       set +x | ||||
|     fi | ||||
|  | ||||
| .mutter.skip-git-clone: | ||||
|   extends: | ||||
|     - .skip-git-clone | ||||
|   variables: | ||||
|     MUTTER_CLONE_PATH: '' | ||||
|  | ||||
| .mutter.run-as-user: | ||||
|   image: | ||||
|     name: ${FDO_DISTRIBUTION_IMAGE} | ||||
|     entrypoint: | ||||
|       - 'runuser' | ||||
|       - '-u' | ||||
|       - !reference [.mutter.fedora@common, variables, MUTTER_USER] | ||||
|       - '--' | ||||
|  | ||||
| .mutter.distribution-image: | ||||
|   extends: | ||||
|     - .fdo.distribution-image@fedora | ||||
|     - .mutter.run-as-user | ||||
|  | ||||
| .mutter.fedora@common: | ||||
|   extends: | ||||
|     - .skip-git-clone | ||||
|   variables: | ||||
|     FDO_DISTRIBUTION_VERSION: 40 | ||||
|     BASE_TAG: '2024-02-23.0' | ||||
|     MUTTER_USER: 'meta-user' | ||||
|     FDO_DISTRIBUTION_PACKAGES: | ||||
|       asciidoc | ||||
|       clang | ||||
|       gcovr | ||||
|       gdm | ||||
|       gnome-shell | ||||
|       sassc | ||||
|       uncrustify | ||||
|       xorg-x11-server-Xvfb | ||||
|       mesa-dri-drivers | ||||
|       xorg-x11-proto-devel | ||||
|       qemu-system-x86-core | ||||
|       busybox | ||||
|       zenity | ||||
|       python3-dbusmock | ||||
|       "pkgconfig(libgcrypt)" | ||||
|       "pkgconfig(libdisplay-info)" | ||||
|  | ||||
|     FDO_DISTRIBUTION_EXEC: | | ||||
|       set -e | ||||
|  | ||||
|       # Create $MUTTER_USER | ||||
|       useradd -u 9999 -b /opt/mutter -ms /bin/bash $MUTTER_USER | ||||
|  | ||||
|       # Enable sudo for $MUTTER_USER | ||||
|       echo "%$MUTTER_USER ALL = (ALL) NOPASSWD: ALL" > /etc/sudoers.d/99_mutter-user | ||||
|  | ||||
|       dnf install -y 'dnf-command(builddep)' | ||||
|  | ||||
|       dnf builddep -y mutter --setopt=install_weak_deps=False | ||||
|       dnf builddep -y gnome-shell --setopt=install_weak_deps=False | ||||
|       dnf builddep -y kernel --setopt=install_weak_deps=False | ||||
|       dnf builddep -y gi-docgen --setopt=install_weak_deps=False | ||||
|  | ||||
|       ./.gitlab-ci/install-meson-project.sh \ | ||||
|         https://gitlab.gnome.org/jadahl/catch.git \ | ||||
|         main | ||||
|  | ||||
|       ./.gitlab-ci/install-meson-project.sh \ | ||||
|         https://gitlab.gnome.org/GNOME/gi-docgen.git \ | ||||
|         main | ||||
|  | ||||
|       rpm -e --nodeps gnome-bluetooth-libs-devel \ | ||||
|                       mutter mutter-devel \ | ||||
|                       gnome-shell | ||||
|  | ||||
|       # Work-around for podman-push aborting on permission issue | ||||
|       # https://gitlab.gnome.org/Infrastructure/Infrastructure/-/issues/1247 | ||||
|       rm -rf /etc/pki/pesign/ | ||||
|       chmod -R a+rX /opt/mutter/$MUTTER_USER | ||||
|       chmod -R a+rX /var/lib/gdm | ||||
|  | ||||
|       # Ensure that we mark the project clone dir as safe directory | ||||
|       git config --system --add safe.directory "$CI_PROJECT_DIR" | ||||
|  | ||||
|       if [[ x"$(uname -m )" = "xx86_64" ]] ; then | ||||
|         if [ -n "$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME" ]; then | ||||
|           git clone --depth $MUTTER_CLONE_DEPTH \ | ||||
|             $CI_MERGE_REQUEST_SOURCE_PROJECT_URL.git mutter-src \ | ||||
|             -b "$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME" | ||||
|         elif [ -n "$CI_COMMIT_BRANCH" ]; then | ||||
|           git clone --depth $MUTTER_CLONE_DEPTH \ | ||||
|             $CI_REPOSITORY_URL mutter-src -b "$CI_COMMIT_BRANCH" | ||||
|         else | ||||
|           git clone --depth $MUTTER_CLONE_DEPTH $CI_REPOSITORY_URL mutter-src | ||||
|         fi | ||||
|         meson setup build mutter-src -Dkvm_tests=true | ||||
|         ninja -C build src/tests/kvm/bzImage | ||||
|         mkdir -p /opt/mutter | ||||
|         cp build/src/tests/kvm/bzImage /opt/mutter/bzImage | ||||
|  | ||||
|         dnf install -y python3-argcomplete | ||||
|  | ||||
|         git clone https://github.com/arighi/virtme-ng.git | ||||
|         cd virtme-ng | ||||
|         git fetch --tags | ||||
|         git checkout v1.8 | ||||
|         ./setup.py install --prefix=/usr | ||||
|         cd .. | ||||
|         rm -rf virtme-ng | ||||
|         rm -rf build mutter-src | ||||
|       fi | ||||
|   retry: | ||||
|     max: 2 | ||||
|     when: | ||||
|       - 'always' | ||||
|  | ||||
| default: | ||||
|   # Cancel jobs if newer commits are pushed to the branch | ||||
|   interruptible: true | ||||
|   # Auto-retry jobs in case of infra failures | ||||
|   retry: | ||||
|     max: 1 | ||||
|     when: | ||||
|       - 'runner_system_failure' | ||||
|       - 'stuck_or_timeout_failure' | ||||
|       - 'scheduler_failure' | ||||
|       - 'api_failure' | ||||
|  | ||||
| .mutter.fedora@x86_64: | ||||
|   extends: | ||||
|     - .mutter.fedora@common | ||||
|     - .mutter.git-clone | ||||
|   variables: | ||||
|     FDO_DISTRIBUTION_TAG: "x86_64-${BASE_TAG}" | ||||
|  | ||||
| .mutter.fedora@aarch64: | ||||
|   extends: | ||||
|     - .mutter.fedora@common | ||||
|     - .mutter.git-clone | ||||
|   variables: | ||||
|     FDO_DISTRIBUTION_TAG: "aarch64-${BASE_TAG}" | ||||
|   tags: | ||||
|     - aarch64 | ||||
|  | ||||
| workflow: | ||||
|   rules: | ||||
|     # Allow to switch from branch pipelines to MR pipelines seamlessly | ||||
|     # https://docs.gitlab.com/ee/ci/jobs/job_control.html#avoid-duplicate-pipelines | ||||
|     - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push" | ||||
|       when: never | ||||
|     - if: $CI_PIPELINE_SOURCE == "merge_request_event" | ||||
|     # Don't trigger a branch pipeline if there is an open MR | ||||
|     - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS | ||||
|       when: never | ||||
|     - if: '$CI_COMMIT_BRANCH' | ||||
|     - if: '$CI_COMMIT_TAG' | ||||
|  | ||||
| .pipeline-guard: | ||||
|   rules: | ||||
|     - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' | ||||
|     - if: '$CI_COMMIT_TAG' | ||||
|     - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' | ||||
|     - if: '$CI_COMMIT_BRANCH =~ /^gnome-[0-9-]+$/' | ||||
|     # Avoid catchall `when: manual` rule which might | ||||
|     # cause duplicate pipelines to be triggered. | ||||
|     # https://docs.gitlab.com/ee/ci/jobs/job_control.html#avoid-duplicate-pipelines | ||||
|     # | ||||
|     # Also make it so pipelines without MR need to be started | ||||
|     # manually, since their state will most likely be WIP | ||||
|     - if: '$CI_COMMIT_BRANCH' | ||||
|       when: 'manual' | ||||
|  | ||||
| .only-merge-requests: | ||||
|   rules: | ||||
|     - if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /^$/' | ||||
|       when: never | ||||
|     - if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME | ||||
|       when: on_success | ||||
|  | ||||
| check-commit-log: | ||||
|   extends: | ||||
|     - .fdo.ci-fairy | ||||
|   stage: review | ||||
|   variables: | ||||
|     GIT_DEPTH: "100" | ||||
|   script: | ||||
|     ci-fairy check-commits --junit-xml=commit-message-junit-report.xml | ||||
|   artifacts: | ||||
|     expire_in: 1 week | ||||
|     paths: | ||||
|       - commit-message-junit-report.xml | ||||
|     reports: | ||||
|       junit: commit-message-junit-report.xml | ||||
|   rules: | ||||
|     - !reference [.only-merge-requests, rules] | ||||
|  | ||||
| check-merge-request: | ||||
|   extends: | ||||
|     - .fdo.ci-fairy | ||||
|     - .skip-git-clone | ||||
|   stage: review | ||||
|   script: | ||||
|     ci-fairy check-merge-request --require-allow-collaboration --junit-xml=check-merge-request-report.xml | ||||
|   artifacts: | ||||
|     expire_in: 1 week | ||||
|     paths: | ||||
|       - check-merge-request-report.xml | ||||
|     reports: | ||||
|       junit: check-merge-request-report.xml | ||||
|   rules: | ||||
|     - !reference [.only-merge-requests, rules] | ||||
|  | ||||
| build-fedora-container@x86_64: | ||||
|   extends: | ||||
|     - .fdo.container-build@fedora@x86_64 | ||||
|     - .mutter.fedora@x86_64 | ||||
|     - .mutter.skip-git-clone | ||||
|   stage: prepare | ||||
|   rules: | ||||
|     - !reference [.pipeline-guard, rules] | ||||
|  | ||||
| build-fedora-container@aarch64: | ||||
|   extends: | ||||
|     - .fdo.container-build@fedora@aarch64 | ||||
|     - .mutter.fedora@aarch64 | ||||
|     - .mutter.skip-git-clone | ||||
|   stage: prepare | ||||
|   rules: | ||||
|     - !reference [.pipeline-guard, rules] | ||||
|   when: manual | ||||
|  | ||||
| check-code-style: | ||||
|   extends: | ||||
|     - .mutter.distribution-image | ||||
|     - .mutter.fedora@x86_64 | ||||
|   variables: | ||||
|     MUTTER_CLONE_DEPTH: 200 | ||||
|   stage: code-review | ||||
|   needs: | ||||
|     - job: build-fedora-container@x86_64 | ||||
|       artifacts: false | ||||
|   script: | ||||
|       git config --global --add safe.directory $CI_PROJECT_DIR ; | ||||
|       git remote add target $CI_MERGE_REQUEST_PROJECT_URL.git ; | ||||
|       git fetch target $CI_MERGE_REQUEST_TARGET_BRANCH_NAME ; | ||||
|       export common_parent_sha=$(diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "target/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME") <(git rev-list --first-parent HEAD) | head -1) ; | ||||
|       python3 -u ./check-style.py --dry-run --sha $common_parent_sha ; | ||||
|   allow_failure: true | ||||
|   rules: | ||||
|     - !reference [.only-merge-requests, rules] | ||||
|  | ||||
| .build-mutter-base: | ||||
|   variables: | ||||
|     BASE_MESON_OPTIONS: | ||||
|       -Degl_device=true | ||||
|       -Dwayland_eglstream=true | ||||
|       -Dcatch=true | ||||
|       -Dlibdisplay_info=enabled | ||||
|  | ||||
| .build-mutter: | ||||
|   extends: | ||||
|     - .mutter.distribution-image | ||||
|     - .build-mutter-base | ||||
|   stage: build | ||||
|   script: | ||||
|     - meson setup . build | ||||
|         --prefix /usr | ||||
|         --werror | ||||
|         --fatal-meson-warnings | ||||
|         --warnlevel 2 | ||||
|         -Dbuildtype=debugoptimized | ||||
|         -Db_coverage=true | ||||
|         $BASE_MESON_OPTIONS | ||||
|         $EXTRA_MESON_OPTIONS | ||||
|     - meson compile -C build | ||||
|     - sudo meson install --dry-run -C build | ||||
|   artifacts: | ||||
|     expire_in: 1 day | ||||
|     paths: | ||||
|       - build | ||||
|  | ||||
| build-mutter@x86_64: | ||||
|   variables: | ||||
|     EXTRA_MESON_OPTIONS: | ||||
|       -Dkvm_tests=true | ||||
|       -Dkvm_kernel_image=/opt/mutter/bzImage | ||||
|   extends: | ||||
|     - .build-mutter | ||||
|     - .mutter.fedora@x86_64 | ||||
|   needs: | ||||
|     - job: build-fedora-container@x86_64 | ||||
|       artifacts: false | ||||
|  | ||||
| build-mutter@aarch64: | ||||
|   extends: | ||||
|     - .build-mutter | ||||
|     - .mutter.fedora@aarch64 | ||||
|   needs: | ||||
|     - job: build-fedora-container@aarch64 | ||||
|       artifacts: false | ||||
|   when: manual | ||||
|  | ||||
| build-without-opengl-and-glx@x86_64: | ||||
|   extends: | ||||
|     - .mutter.distribution-image | ||||
|     - .mutter.fedora@x86_64 | ||||
|   stage: build | ||||
|   needs: | ||||
|     - job: build-fedora-container@x86_64 | ||||
|       artifacts: false | ||||
|   script: | ||||
|     - meson setup . build --werror --prefix /usr | ||||
|         -Dbuildtype=debugoptimized | ||||
|         -Dopengl=false | ||||
|         -Dglx=false | ||||
|         -Degl_device=true | ||||
|         -Dwayland_eglstream=true | ||||
|         -Dintrospection=false | ||||
|     - meson compile -C build | ||||
|     - sudo meson install --no-rebuild -C build | ||||
|   artifacts: | ||||
|     paths: | ||||
|       - build/meson-logs | ||||
|  | ||||
| build-without-native-backend-and-wayland@x86_64: | ||||
|   extends: | ||||
|     - .mutter.distribution-image | ||||
|     - .mutter.fedora@x86_64 | ||||
|   stage: build | ||||
|   needs: | ||||
|     - job: build-fedora-container@x86_64 | ||||
|       artifacts: false | ||||
|   script: | ||||
|     - meson setup . build --werror --prefix /usr | ||||
|         -Dbuildtype=debugoptimized | ||||
|         -Dnative_backend=false | ||||
|         -Dudev=false | ||||
|         -Dwayland=false | ||||
|         -Dxwayland=false | ||||
|         -Dcore_tests=false | ||||
|         -Dnative_tests=false | ||||
|         -Dintrospection=false | ||||
|     - meson compile -C build | ||||
|     - sudo meson install --no-rebuild -C build | ||||
|   artifacts: | ||||
|     paths: | ||||
|       - build/meson-logs | ||||
|  | ||||
| build-wayland-only@x86_64: | ||||
|   extends: | ||||
|     - .mutter.distribution-image | ||||
|     - .mutter.fedora@x86_64 | ||||
|   stage: build | ||||
|   needs: | ||||
|     - job: build-fedora-container@x86_64 | ||||
|       artifacts: false | ||||
|   script: | ||||
|     - meson setup . build --werror --prefix /usr | ||||
|         -Dbuildtype=debugoptimized | ||||
|         -Dwayland=true | ||||
|         -Dxwayland=false | ||||
|         -Dcore_tests=false | ||||
|         -Dnative_tests=false | ||||
|         -Dintrospection=false | ||||
|     - meson compile -C build | ||||
|     - sudo meson install --no-rebuild -C build | ||||
|   artifacts: | ||||
|     paths: | ||||
|       - build/meson-logs | ||||
|  | ||||
| .test-setup: | ||||
|   variables: | ||||
|     XDG_RUNTIME_DIR: "$CI_PROJECT_DIR/runtime-dir" | ||||
|     GSETTINGS_SCHEMA_DIR: "$CI_PROJECT_DIR/build/data" | ||||
|     MUTTER_DEBUG_DUMMY_MODE_SPECS: "800x600@10.0" | ||||
|     PIPEWIRE_DEBUG: 2 | ||||
|     PIPEWIRE_LOG: "$CI_PROJECT_DIR/build/meson-logs/pipewire.log" | ||||
|     XVFB_SERVER_ARGS: "+iglx -noreset" | ||||
|     G_SLICE: "always-malloc" | ||||
|     MALLOC_CHECK_: "3" | ||||
|     NO_AT_BRIDGE: "1" | ||||
|     GTK_A11Y: "none" | ||||
|   before_script: | ||||
|     - !reference [.mutter.git-clone, before_script] | ||||
|     # Disable e.g. audio support to not dead lock screen cast tests | ||||
|     - mkdir -m 700 $XDG_RUNTIME_DIR | ||||
|     - pipewire & sleep 2 | ||||
|  | ||||
| .test-mutter-base: | ||||
|   extends: | ||||
|     - .mutter.distribution-image | ||||
|     - .test-setup | ||||
|   stage: test | ||||
|   after_script: | ||||
|     - pushd build | ||||
|     - gcovr --root=.. | ||||
|         --filter='\.\./src/' | ||||
|         --filter='\.\./clutter/' | ||||
|         --filter='\.\./cogl/' | ||||
|         --filter='\.\./mtk/' | ||||
|         --exclude='\.\./build/.*\.[ch]$' --exclude='.*/tests/.*\.[ch]$' | ||||
|         --json --output=../coverage-${CI_JOB_NAME}.json | ||||
|     - popd | ||||
|   artifacts: | ||||
|     expire_in: 1 day | ||||
|     name: "mutter-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}" | ||||
|     when: always | ||||
|     paths: | ||||
|       - build | ||||
|       - coverage-*.json | ||||
|  | ||||
| .test-mutter: | ||||
|   extends: | ||||
|     - .mutter.distribution-image | ||||
|     - .test-mutter-base | ||||
|   script: | ||||
|     - glib-compile-schemas $GSETTINGS_SCHEMA_DIR | ||||
|     - xvfb-run -a -s "$XVFB_SERVER_ARGS" | ||||
|         ./src/tests/meta-dbus-runner.py | ||||
|           --launch=wireplumber | ||||
|           meson test | ||||
|             -C build | ||||
|             --setup plain | ||||
|             --no-suite 'mutter/kvm' | ||||
|             --no-rebuild | ||||
|             --timeout-multiplier 10 | ||||
|             --print-errorlogs | ||||
|   artifacts: | ||||
|     reports: | ||||
|       junit: "build/meson-logs/testlog-plain.junit.xml" | ||||
|  | ||||
| test-mutter@x86_64: | ||||
|   extends: | ||||
|     - .mutter.fedora@x86_64 | ||||
|     - .test-mutter | ||||
|   tags: | ||||
|     - asan | ||||
|   needs: | ||||
|     - build-mutter@x86_64 | ||||
|  | ||||
| test-mutter-kvm@x86_64: | ||||
|   extends: | ||||
|     - .mutter.fedora@x86_64 | ||||
|     - .test-mutter-base | ||||
|   tags: | ||||
|     - kvm | ||||
|   script: | ||||
|     - meson test -C build | ||||
|         --no-rebuild | ||||
|         --timeout-multiplier 10 | ||||
|         --setup plain | ||||
|         --suite 'mutter/kvm' | ||||
|         --print-errorlogs | ||||
|   needs: | ||||
|     - build-mutter@x86_64 | ||||
|   artifacts: | ||||
|     reports: | ||||
|       junit: "build/meson-logs/testlog-plain.junit.xml" | ||||
|  | ||||
| test-mutter@aarch64: | ||||
|   extends: | ||||
|     - .mutter.fedora@aarch64 | ||||
|     - .test-mutter | ||||
|   tags: | ||||
|     - asan-aarch64 | ||||
|   needs: | ||||
|     - build-mutter@aarch64 | ||||
|   when: manual | ||||
|  | ||||
| coverage: | ||||
|   extends: | ||||
|     - .mutter.distribution-image | ||||
|     - .mutter.fedora@x86_64 | ||||
|   stage: analyze | ||||
|   script: | ||||
|     - mkdir coveragereport | ||||
|     - gcovr --add-tracefile 'coverage-*.json' | ||||
|         --html-details --print-summary --output coveragereport/index.html | ||||
|     - gcovr --add-tracefile 'coverage-*.json' | ||||
|         --xml --output coveragereport/coverage.xml | ||||
|   artifacts: | ||||
|     expose_as: 'Coverage Report' | ||||
|     paths: | ||||
|       - coveragereport | ||||
|       - coveragereport/index.html | ||||
|     reports: | ||||
|       coverage_report: | ||||
|         coverage_format: cobertura | ||||
|         # TODO: we may need to split this file once it will reach the | ||||
|         # gitlab limit size of 10M, or it will stop working: | ||||
|         #  https://gitlab.com/gitlab-org/gitlab/-/issues/328772 | ||||
|         path: coveragereport/coverage.xml | ||||
|   coverage: '/^lines: (\d+\.\d+\%)/' | ||||
|   needs: | ||||
|     - test-mutter@x86_64 | ||||
| #    - test-mutter@aarch64 | ||||
|     - test-mutter-kvm@x86_64 | ||||
|  | ||||
| can-run-gnome-shell@x86_64: | ||||
|   extends: | ||||
|     - .mutter.distribution-image | ||||
|     - .mutter.fedora@x86_64 | ||||
|     - .test-setup | ||||
|   stage: test | ||||
|   needs: | ||||
|     - build-mutter@x86_64 | ||||
|   before_script: | ||||
|     - !reference [.mutter.fedora@x86_64, before_script] | ||||
|     - sudo meson install --no-rebuild -C build | ||||
|   script: | ||||
|     - .gitlab-ci/checkout-gnome-shell.sh | ||||
|     - meson setup gnome-shell gnome-shell/build --prefix /usr -Dbuildtype=debugoptimized -Dman=false --werror --fatal-meson-warnings | ||||
|     - sudo meson install -C gnome-shell/build | ||||
|     - dbus-run-session -- xvfb-run meson test -C gnome-shell/build --no-rebuild | ||||
|  | ||||
| test-mutter-coverity: | ||||
|   rules: | ||||
|     - if: '$CI_PIPELINE_SOURCE == "schedule" && $MUTTER_SCHEDULED_JOB == "coverity"' | ||||
|       when: on_success | ||||
|     - if: '$CI_COMMIT_BRANCH' | ||||
|       when: 'manual' | ||||
|   extends: | ||||
|     - .mutter.distribution-image | ||||
|     - .mutter.fedora@x86_64 | ||||
|   needs: | ||||
|     - job: build-fedora-container@x86_64 | ||||
|       artifacts: false | ||||
|   stage: analyze | ||||
|   allow_failure: true | ||||
|   script: | ||||
|     - .gitlab-ci/download-coverity-tarball.sh | ||||
|     - CC=clang meson setup coverity-build -Dprofiler=false | ||||
|     - ./coverity/cov-analysis-linux64-*/bin/cov-build --dir cov-int meson compile -C coverity-build | ||||
|     - tar czf cov-int.tar.gz cov-int | ||||
|     - curl https://scan.coverity.com/builds?project=mutter | ||||
|       --form token=$COVERITY_TOKEN --form email=carlosg@gnome.org | ||||
|       --form file=@cov-int.tar.gz --form version="`git describe --tags`" | ||||
|       --form description="GitLab CI build" | ||||
|   cache: | ||||
|     key: coverity-tarball | ||||
|     paths: | ||||
|       - coverity | ||||
|  | ||||
| dist-mutter: | ||||
|   extends: | ||||
|     - .fdo.distribution-image@fedora | ||||
|     - .mutter.fedora@x86_64 | ||||
|     - .build-mutter-base | ||||
|     - .test-setup | ||||
|   stage: deploy | ||||
|   needs: | ||||
|     - job: build-fedora-container@x86_64 | ||||
|       artifacts: false | ||||
|   script: | ||||
|     - meson setup . build --werror --prefix /usr | ||||
|         -Dbuildtype=debugoptimized | ||||
|     - glib-compile-schemas $GSETTINGS_SCHEMA_DIR | ||||
|     - xvfb-run -a -s "$XVFB_SERVER_ARGS" | ||||
|         ./src/tests/meta-dbus-runner.py | ||||
|           --launch=wireplumber | ||||
|           meson dist -C build | ||||
|   rules: | ||||
|     - if: '$CI_PIPELINE_SOURCE != "merge_request_event"' | ||||
|       when: manual | ||||
|     - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' | ||||
|       changes: | ||||
|         - "**/meson.build" | ||||
|         - meson/* | ||||
|       when: on_success | ||||
|     - if: '$GITLAB_USER_LOGIN == "marge-bot"' | ||||
|       when: on_success | ||||
|     - if: '$CI_MERGE_REQUEST_ASSIGNEES == "marge-bot"' | ||||
|       when: on_success | ||||
|  | ||||
| dist-mutter-tarball: | ||||
|   extends: dist-mutter | ||||
|   artifacts: | ||||
|     expose_as: 'Get tarball here' | ||||
|     paths: | ||||
|       - build/meson-dist/$CI_PROJECT_NAME-$CI_COMMIT_TAG.tar.xz | ||||
|   rules: | ||||
|     - if: '$CI_COMMIT_TAG' | ||||
|  | ||||
| reference: | ||||
|   extends: | ||||
|     - .mutter.distribution-image | ||||
|     - .mutter.fedora@x86_64 | ||||
|   stage: docs | ||||
|   needs: | ||||
|     - job: build-fedora-container@x86_64 | ||||
|       artifacts: false | ||||
|   script: | ||||
|     - meson setup . build --werror -Ddocs=true -Dtests=false | ||||
|     - ninja -C build | ||||
|     - mkdir references | ||||
|     - cp -r doc/website/* ./references | ||||
|     - mv build/doc/reference/{cally/cally,clutter/clutter,cogl/cogl,cogl-pango/cogl-pango,meta/meta,mtk/mtk} references/ | ||||
|   artifacts: | ||||
|     expire_in: 1 week | ||||
|     expose_as: 'Documentation' | ||||
|     paths: | ||||
|       - references/ | ||||
|  | ||||
| pages: | ||||
|   stage: deploy | ||||
|   needs: ['reference'] | ||||
|   extends: | ||||
|     - .skip-git-clone | ||||
|   script: | ||||
|     - mv references public/ | ||||
|   artifacts: | ||||
|     paths: | ||||
|       - public | ||||
|   rules: | ||||
|     - if: ($CI_DEFAULT_BRANCH == $CI_COMMIT_BRANCH && $CI_PROJECT_NAMESPACE == "GNOME") | ||||
| @@ -1,56 +0,0 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| fetch() { | ||||
|   local remote=$1 | ||||
|   local ref=$2 | ||||
|  | ||||
|   git fetch --quiet --depth=1 $remote $ref 2>/dev/null | ||||
| } | ||||
|  | ||||
| gnome_shell_target= | ||||
|  | ||||
| echo -n Cloning into gnome-shell ... | ||||
| if git clone --quiet --depth=1 https://gitlab.gnome.org/GNOME/gnome-shell.git; then | ||||
|   echo \ done | ||||
| else | ||||
|   echo \ failed | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| cd gnome-shell | ||||
|  | ||||
| if [ "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then | ||||
|   merge_request_remote=${CI_MERGE_REQUEST_SOURCE_PROJECT_URL//mutter/gnome-shell} | ||||
|   merge_request_branch=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME | ||||
|  | ||||
|   echo -n Looking for $merge_request_branch on remote ... | ||||
|   if fetch $merge_request_remote $merge_request_branch; then | ||||
|     echo \ found | ||||
|     gnome_shell_target=FETCH_HEAD | ||||
|   else | ||||
|     echo \ not found | ||||
|  | ||||
|     echo -n Looking for $CI_MERGE_REQUEST_TARGET_BRANCH_NAME instead ... | ||||
|     if fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME; then | ||||
|       echo \ found | ||||
|       gnome_shell_target=FETCH_HEAD | ||||
|     else | ||||
|       echo \ not found | ||||
|     fi | ||||
|   fi | ||||
| fi | ||||
|  | ||||
| if [ -z "$gnome_shell_target" ]; then | ||||
|   ref_remote=${CI_PROJECT_URL//mutter/gnome-shell} | ||||
|   echo -n Looking for $CI_COMMIT_REF_NAME on remote ... | ||||
|   if fetch $ref_remote $CI_COMMIT_REF_NAME; then | ||||
|     echo \ found | ||||
|     gnome_shell_target=FETCH_HEAD | ||||
|   else | ||||
|     echo \ not found | ||||
|     gnome_shell_target=HEAD | ||||
|     echo Using $gnome_shell_target instead | ||||
|   fi | ||||
| fi | ||||
|  | ||||
| git checkout -q $gnome_shell_target | ||||
| @@ -1,19 +0,0 @@ | ||||
| patterns: | ||||
|   deny: | ||||
|     - regex: '^$CI_MERGE_REQUEST_PROJECT_URL/(-/)?merge_requests/$CI_MERGE_REQUEST_IID$' | ||||
|       message: Commit message must not contain a link to its own merge request | ||||
|     - regex: '^(meta-|Meta)' | ||||
|       message: Commit message subject should not be prefixed with 'meta-' or 'Meta' | ||||
|       where: subject | ||||
|     - regex: '^(clutter-|Clutter)' | ||||
|       message: Commit message subject should not be prefixed with 'clutter-' or 'Clutter', use 'clutter/' instead | ||||
|       where: subject | ||||
|     - regex: '^(cogl-|Cogl)' | ||||
|       message: Commit message subject should not be prefixed with 'cogl-' or 'Cogl', use 'cogl/' instead | ||||
|       where: subject | ||||
|     - regex: '^[^:]+: [a-z]' | ||||
|       message: "Commit message subject should be properly Capitalized. E.g.  'window: Marginalize extradicity'" | ||||
|       where: subject | ||||
|     - regex: '^\S*\.[ch]:' | ||||
|       message: Commit message subject prefix should not include .c, .h, etc. | ||||
|       where: subject | ||||
| @@ -1,38 +0,0 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| # We need a coverity token to fetch the tarball | ||||
| if [ -x $COVERITY_TOKEN ] | ||||
| then | ||||
|   echo "No coverity token. Run this job from a protected branch." | ||||
|   exit -1 | ||||
| fi | ||||
|  | ||||
| mkdir -p coverity | ||||
|  | ||||
| # Download and check MD5 first | ||||
| curl https://scan.coverity.com/download/linux64 \ | ||||
|   --data "token=$COVERITY_TOKEN&project=mutter&md5=1" \ | ||||
|   --output /tmp/coverity_tool.md5 | ||||
|  | ||||
| diff /tmp/coverity_tool.md5 coverity/coverity_tool.md5 >/dev/null 2>&1 | ||||
|  | ||||
| if [ $? -eq 0 -a -d coverity/cov-analysis* ] | ||||
| then | ||||
|   echo "Coverity tarball is up-to-date" | ||||
|   exit 0 | ||||
| fi | ||||
|  | ||||
| # Download and extract coverity tarball | ||||
| curl https://scan.coverity.com/download/linux64 \ | ||||
|   --data "token=$COVERITY_TOKEN&project=mutter" \ | ||||
|   --output /tmp/coverity_tool.tgz | ||||
|  | ||||
| rm -rf ./coverity/cov-analysis* | ||||
|  | ||||
| tar zxf /tmp/coverity_tool.tgz -C coverity/ | ||||
| if [ $? -eq 0 ] | ||||
| then | ||||
|   mv /tmp/coverity_tool.md5 coverity/ | ||||
| fi | ||||
|  | ||||
| rm /tmp/coverity_tool.tgz | ||||
| @@ -1,82 +0,0 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| set -e | ||||
|  | ||||
| usage() { | ||||
|   cat <<-EOF | ||||
| 	Usage: $(basename $0) [OPTION…] REPO_URL COMMIT | ||||
|  | ||||
| 	Check out and install a meson project | ||||
|  | ||||
| 	Options: | ||||
| 	  -Dkey=val      Option to pass on to meson | ||||
| 	  --subdir       Build subdirectory instead of whole project | ||||
| 	  --prepare      Script to run before build | ||||
|  | ||||
| 	  -h, --help     Display this help | ||||
|  | ||||
| 	EOF | ||||
| } | ||||
|  | ||||
| TEMP=$(getopt \ | ||||
|   --name=$(basename $0) \ | ||||
|   --options='D:h' \ | ||||
|   --longoptions='subdir:' \ | ||||
|   --longoptions='prepare:' \ | ||||
|   --longoptions='help' \ | ||||
|   -- "$@") | ||||
|  | ||||
| eval set -- "$TEMP" | ||||
| unset TEMP | ||||
|  | ||||
| MESON_OPTIONS=() | ||||
| SUBDIR=. | ||||
| PREPARE=: | ||||
|  | ||||
| while true; do | ||||
|   case "$1" in | ||||
|     -D) | ||||
|       MESON_OPTIONS+=( -D$2 ) | ||||
|       shift 2 | ||||
|     ;; | ||||
|  | ||||
|     --subdir) | ||||
|       SUBDIR=$2 | ||||
|       shift 2 | ||||
|     ;; | ||||
|  | ||||
|     --prepare) | ||||
|       PREPARE=$2 | ||||
|       shift 2 | ||||
|     ;; | ||||
|  | ||||
|     -h|--help) | ||||
|       usage | ||||
|       exit 0 | ||||
|     ;; | ||||
|  | ||||
|     --) | ||||
|       shift | ||||
|       break | ||||
|     ;; | ||||
|   esac | ||||
| done | ||||
|  | ||||
| if [[ $# -lt 2 ]]; then | ||||
|   usage | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| REPO_URL="$1" | ||||
| COMMIT="$2" | ||||
|  | ||||
| CHECKOUT_DIR=$(mktemp --directory) | ||||
| trap "rm -rf $CHECKOUT_DIR" EXIT | ||||
|  | ||||
| git clone --depth 1 "$REPO_URL" -b "$COMMIT" "$CHECKOUT_DIR" | ||||
|  | ||||
| pushd "$CHECKOUT_DIR/$SUBDIR" | ||||
| sh -c "$PREPARE" | ||||
| meson setup --prefix=/usr _build "${MESON_OPTIONS[@]}" | ||||
| meson install -C _build | ||||
| popd | ||||
| @@ -1,55 +0,0 @@ | ||||
| <!--  | ||||
| Please read https://wiki.gnome.org/Community/GettingInTouch/BugReportingGuidelines | ||||
| first to ensure that you create a clear and specific issue. | ||||
| --> | ||||
|  | ||||
| ### Affected version | ||||
|  | ||||
| <!-- | ||||
| Provide at least the following information: | ||||
| * Your OS and version | ||||
| * Affected Mutter version | ||||
| * Does this issue appear in XOrg and/or Wayland | ||||
| --> | ||||
|  | ||||
| ### Bug summary | ||||
|  | ||||
| <!--  | ||||
| Provide a short summary of the bug you encountered. | ||||
| --> | ||||
|  | ||||
| ### Steps to reproduce | ||||
|  | ||||
| <!--  | ||||
| 1. Step one | ||||
| 2. Step two | ||||
| 3. ... | ||||
| --> | ||||
|  | ||||
| ### What happened | ||||
|  | ||||
| <!--  | ||||
| What did Mutter do that was unexpected? | ||||
| --> | ||||
|  | ||||
| ### What did you expect to happen | ||||
|  | ||||
| <!--  | ||||
| What did you expect Mutter to do? | ||||
| --> | ||||
|  | ||||
| ### Relevant logs, screenshots, screencasts etc. | ||||
|  | ||||
| <!--  | ||||
| If you have further information, such as technical documentation, logs, | ||||
| screenshots or screencasts related, please provide them here. | ||||
|  | ||||
| If the bug is a crash, please obtain a stack trace with installed debug | ||||
| symbols (at least for GNOME Shell and Mutter) and attach it to | ||||
| this issue following the instructions on | ||||
| https://wiki.gnome.org/Community/GettingInTouch/Bugzilla/GettingTraces. | ||||
| --> | ||||
|  | ||||
|  | ||||
| <!-- Do not remove the following line. --> | ||||
| /label ~"1. Bug" | ||||
| @@ -1,30 +0,0 @@ | ||||
| <!--  | ||||
| Please read https://wiki.gnome.org/Community/GettingInTouch/BugReportingGuidelines | ||||
| first to ensure that you create a clear and specific issue. | ||||
| --> | ||||
|  | ||||
| ### Feature summary | ||||
|  | ||||
| <!--  | ||||
| Describe what you would like to be able to do with Mutter | ||||
| that you currently cannot do. | ||||
| --> | ||||
|  | ||||
| ### How would you like it to work | ||||
|  | ||||
| <!--  | ||||
| If you can think of a way Mutter might be able to do this, | ||||
| let us know here. | ||||
| --> | ||||
|  | ||||
| ### Relevant links, screenshots, screencasts etc. | ||||
|  | ||||
| <!--  | ||||
| If you have further information, such as technical documentation, | ||||
| code, mockups or a similar feature in another window managers, | ||||
| please provide them here. | ||||
| --> | ||||
|  | ||||
|  | ||||
| <!-- Do not remove the following line. --> | ||||
| /label ~"1. Feature" | ||||
							
								
								
									
										159
									
								
								COMPLIANCE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								COMPLIANCE
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,159 @@ | ||||
| Metacity Standards Compliance | ||||
| ============================= | ||||
| $Id$ | ||||
|  | ||||
| 1) Introduction | ||||
| 2) EWMH Compliance | ||||
|   a. Root Window Properties | ||||
|   b. Root Window Messages | ||||
|   c. Application Window Properties | ||||
|   d. Window Manager Protocols | ||||
| 3) ICCCM Compliance | ||||
|  | ||||
| 1) Introduction | ||||
| --------------- | ||||
|  | ||||
| This document details metacity compliance with the relevent standards. | ||||
| The format of this document is as follows: | ||||
|  | ||||
| [-/+?] Hint Name/Feature Name (Version number) | ||||
|        Errata/Comments | ||||
|  | ||||
| The first character indicates the level of compliance as follows: | ||||
|     -   none | ||||
|     /   partial | ||||
|     +   complete | ||||
|     ?   unknown | ||||
|  | ||||
| The title indicates a feature or a hint in the specification, and the | ||||
| version number indicates the minimum version of the specification | ||||
| supported by metacity.  Later versions may be supported if no | ||||
| incompatible changes have been made in the specification. | ||||
|  | ||||
| 2) EWMH Compliance | ||||
| ------------------ | ||||
|  | ||||
| The EWMH, or Extended Window Manager Hints is a freedesktop.org- | ||||
| developed standard to support a number of conventions for | ||||
| communication between the window manager and clients.  It builds on | ||||
| and extends the ICCCM (See Section 3).  A copy of the current EWMH | ||||
| standard is available at http://freedesktop.org/Standards/wm-spec/ | ||||
|  | ||||
|   a. Root Window Properties | ||||
|   ------------------------- | ||||
|  | ||||
| + _NET_SUPPORTED (1.3) | ||||
|  | ||||
| + _NET_CLIENT_LIST (1.3) | ||||
|  | ||||
| + _NET_NUMBER_OF_DESKTOPS (1.3) | ||||
|  | ||||
| + _NET_DESKTOP_GEOMETRY (1.3) | ||||
|   Metacity does not implement large desktops, so this is kept set to | ||||
|   the screen size. | ||||
|  | ||||
| + _NET_DESKTOP_VIEWPORT (1.3) | ||||
|   Metacity does not implement viewports, so this is a constant (0,0). | ||||
|  | ||||
| + _NET_CURRENT_DESKTOP (1.3) | ||||
|  | ||||
| + _NET_DESKTOP_NAMES (1.3) | ||||
|  | ||||
| + _NET_ACTIVE_WINDOW (1.3) | ||||
|  | ||||
| + _NET_WORKAREA (1.3) | ||||
|  | ||||
| + _NET_SUPPORTING_WM_CHECK (1.3) | ||||
|  | ||||
| + _NET_VIRTUAL_ROOTS (1.3) | ||||
|   Metacity does not read or set this property, but it does not use | ||||
|   virtual roots to implement virtual desktops, so it complies with the | ||||
|   specification. | ||||
|  | ||||
| + _NET_DESKTOP_LAYOUT (1.3) | ||||
|  | ||||
| + _NET_SHOWING_DESKTOP (1.3) | ||||
|  | ||||
|   b. Root Window Messages | ||||
|   ----------------------- | ||||
|  | ||||
| + _NET_CLOSE_WINDOW (1.3) | ||||
|  | ||||
| - _NET_MOVERESIZE_WINDOW (1.3) | ||||
|   Metacity supports this message, but the specification is unclear on | ||||
|   the layout of the detail value, and as such it is #if 0'd in the code | ||||
|  | ||||
| + _NET_WM_MOVERESIZE (1.3) | ||||
|  | ||||
| - _NET_RESTACK_WINDOW (1.3) | ||||
|   Metacity will raise or lower windows in response to this message, | ||||
|   but the sibling restack modes are not supported, and it is currently | ||||
|   #if 0'd in the code. | ||||
|  | ||||
| + _NET_REQUEST_FRAME_EXTENTS (1.3)   | ||||
|  | ||||
|   c. Application Window Properties | ||||
|   -------------------------------- | ||||
|  | ||||
| + _NET_WM_NAME (1.3) | ||||
|  | ||||
| + _NET_WM_VISIBLE_NAME (1.3) | ||||
|   Metacity does not set this property, but metacity will never display | ||||
|   a name different from _NET_WM_NAME | ||||
|  | ||||
| + _NET_WM_ICON_NAME (1.3) | ||||
|  | ||||
| + _NET_WM_VISIBLE_ICON_NAME (1.3) | ||||
|   Metacity does not set this property, but metacity will never display | ||||
|   a name different from _NET_WM_NAME | ||||
|  | ||||
| + _NET_WM_DESKTOP (1.3) | ||||
|  | ||||
| + _NET_WM_WINDOW_TYPE (1.3) | ||||
|  | ||||
| / _NET_WM_STATE (1.3) | ||||
|   This property is read and updated according to the specification, | ||||
|   but see caveat below. | ||||
|   Metacity does not recognize separate vertical and horizontal | ||||
|   maximization states.  Currently metacity will do a two-dimensional | ||||
|   maximization if either property is set. | ||||
|   See: http://bugzilla.gnome.org/show_bug.cgi?id=113601 | ||||
|   Metacity doesn't implement viewports so _NET_WM_STATE_STICKY is | ||||
|   unimplemented. | ||||
|  | ||||
| + _NET_WM_ALLOWED_ACTIONS (1.3) | ||||
|   Metacity keeps this hint up to date.  The code is somewhat crufty | ||||
|   and should be rewritten, though it is functional. | ||||
|   See: http://bugzilla.gnome.org/show_bug.cgi?id=90420 | ||||
|  | ||||
| + _NET_WM_STRUT (1.3) | ||||
|  | ||||
| + _NET_WM_STRUT_PARTIAL (1.3) | ||||
|  | ||||
| + _NET_WM_ICON_GEOMETRY (1.3) | ||||
|   Metacity uses this property to draw minimize/restore animations | ||||
|  | ||||
| + _NET_WM_ICON (1.3) | ||||
|  | ||||
| + _NET_WM_PID (1.3) | ||||
|  | ||||
| + _NET_WM_HANDLED_ICONS (1.3) | ||||
|   Metacity does not read or set this property.  However, metacity | ||||
|   never manages iconified windows, and so has no need to do so. | ||||
|  | ||||
| + _NET_WM_USER_TIME (1.3) | ||||
|   Metacity uses this property to prevent applications from stealing | ||||
|   focus if supported by the toolkit. | ||||
|  | ||||
| + _NET_FRAME_EXTENTS (1.3) | ||||
|   If set in response to a _NET_REQUEST_FRAME_EXTENTS message received | ||||
|   prior to the window being mapped, this may be an estimate.  This is, | ||||
|   however, expressly allowed by the specification. | ||||
|  | ||||
|   d. Window Manager Protocols | ||||
|   --------------------------- | ||||
| + _NET_WM_PING (1.3) | ||||
|  | ||||
| 3) ICCCM Compliance | ||||
| ------------------- | ||||
| TODO | ||||
							
								
								
									
										41
									
								
								COPYING
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								COPYING
									
									
									
									
									
								
							| @@ -1,12 +1,12 @@ | ||||
|                     GNU GENERAL PUBLIC LICENSE | ||||
|                        Version 2, June 1991 | ||||
| 		    GNU GENERAL PUBLIC LICENSE | ||||
| 		       Version 2, June 1991 | ||||
|  | ||||
|  Copyright (C) 1989, 1991 Free Software Foundation, Inc., | ||||
|  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||||
|  Copyright (C) 1989, 1991 Free Software Foundation, Inc. | ||||
|      59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | ||||
|  Everyone is permitted to copy and distribute verbatim copies | ||||
|  of this license document, but changing it is not allowed. | ||||
|  | ||||
|                             Preamble | ||||
| 			    Preamble | ||||
|  | ||||
|   The licenses for most software are designed to take away your | ||||
| freedom to share and change it.  By contrast, the GNU General Public | ||||
| @@ -15,7 +15,7 @@ software--to make sure the software is free for all its users.  This | ||||
| General Public License applies to most of the Free Software | ||||
| Foundation's software and to any other program whose authors commit to | ||||
| using it.  (Some other Free Software Foundation software is covered by | ||||
| the GNU Lesser General Public License instead.)  You can apply it to | ||||
| the GNU Library General Public License instead.)  You can apply it to | ||||
| your programs, too. | ||||
|  | ||||
|   When we speak of free software, we are referring to freedom, not | ||||
| @@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all. | ||||
|  | ||||
|   The precise terms and conditions for copying, distribution and | ||||
| modification follow. | ||||
|  | ||||
|                     GNU GENERAL PUBLIC LICENSE | ||||
|  | ||||
| 		    GNU GENERAL PUBLIC LICENSE | ||||
|    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | ||||
|  | ||||
|   0. This License applies to any program or other work which contains | ||||
| @@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions: | ||||
|     License.  (Exception: if the Program itself is interactive but | ||||
|     does not normally print such an announcement, your work based on | ||||
|     the Program is not required to print an announcement.) | ||||
|  | ||||
|  | ||||
| These requirements apply to the modified work as a whole.  If | ||||
| identifiable sections of that work are not derived from the Program, | ||||
| and can be reasonably considered independent and separate works in | ||||
| @@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent | ||||
| access to copy the source code from the same place counts as | ||||
| distribution of the source code, even though third parties are not | ||||
| compelled to copy the source along with the object code. | ||||
|  | ||||
|  | ||||
|   4. You may not copy, modify, sublicense, or distribute the Program | ||||
| except as expressly provided under this License.  Any attempt | ||||
| otherwise to copy, modify, sublicense or distribute the Program is | ||||
| @@ -225,7 +225,7 @@ impose that choice. | ||||
|  | ||||
| This section is intended to make thoroughly clear what is believed to | ||||
| be a consequence of the rest of this License. | ||||
|  | ||||
|  | ||||
|   8. If the distribution and/or use of the Program is restricted in | ||||
| certain countries either by patents or by copyrighted interfaces, the | ||||
| original copyright holder who places the Program under this License | ||||
| @@ -255,7 +255,7 @@ make exceptions for this.  Our decision will be guided by the two goals | ||||
| of preserving the free status of all derivatives of our free software and | ||||
| of promoting the sharing and reuse of software generally. | ||||
|  | ||||
|                             NO WARRANTY | ||||
| 			    NO WARRANTY | ||||
|  | ||||
|   11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY | ||||
| FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN | ||||
| @@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER | ||||
| PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE | ||||
| POSSIBILITY OF SUCH DAMAGES. | ||||
|  | ||||
|                      END OF TERMS AND CONDITIONS | ||||
|  | ||||
|             How to Apply These Terms to Your New Programs | ||||
| 		     END OF TERMS AND CONDITIONS | ||||
|  | ||||
| 	    How to Apply These Terms to Your New Programs | ||||
|  | ||||
|   If you develop a new program, and you want it to be of the greatest | ||||
| possible use to the public, the best way to achieve this is to make it | ||||
| @@ -303,16 +303,17 @@ the "copyright" line and a pointer to where the full notice is found. | ||||
|     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|     GNU General Public License for more details. | ||||
|  | ||||
|     You should have received a copy of the GNU General Public License along | ||||
|     with this program; if not, write to the Free Software Foundation, Inc., | ||||
|     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|     You should have received a copy of the GNU General Public License | ||||
|     along with this program; if not, write to the Free Software | ||||
|     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | ||||
|  | ||||
|  | ||||
| Also add information on how to contact you by electronic and paper mail. | ||||
|  | ||||
| If the program is interactive, make it output a short notice like this | ||||
| when it starts in an interactive mode: | ||||
|  | ||||
|     Gnomovision version 69, Copyright (C) year name of author | ||||
|     Gnomovision version 69, Copyright (C) year  name of author | ||||
|     Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. | ||||
|     This is free software, and you are welcome to redistribute it | ||||
|     under certain conditions; type `show c' for details. | ||||
| @@ -335,5 +336,5 @@ necessary.  Here is a sample; alter the names: | ||||
| This General Public License does not permit incorporating your program into | ||||
| proprietary programs.  If your program is a subroutine library, you may | ||||
| consider it more useful to permit linking proprietary applications with the | ||||
| library.  If this is what you want to do, use the GNU Lesser General | ||||
| library.  If this is what you want to do, use the GNU Library General | ||||
| Public License instead of this License. | ||||
|   | ||||
							
								
								
									
										298
									
								
								HACKING
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										298
									
								
								HACKING
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,298 @@ | ||||
| Intro... | ||||
|  | ||||
| Window managers have a few ways in which they are significantly different | ||||
| from other applications.  This file, combined with the code overview in | ||||
| doc/code-overview.txt, should hopefully provide a series of relatively | ||||
| quick pointers (hopefully only a few minutes each) to some of the places | ||||
| one can look to orient themselves and get started.  Some of this will be | ||||
| general to window managers on X, much will be specific to Metacity, and | ||||
| there's probably some information that's common to programs in general but | ||||
| is nonetheless useful. | ||||
|  | ||||
| Overview | ||||
|   Administrative issues | ||||
|   Minimal Building/Testing Environment | ||||
|   Relevant standards and X properties | ||||
|   Debugging and testing | ||||
|     Debugging logs | ||||
|     Adding information to the log | ||||
|     Valgrind | ||||
|     Testing Utilities | ||||
|   Technical gotchas to keep in mind | ||||
|   Other important reading | ||||
|     Extra reading | ||||
|     Ideas for tasks to work on | ||||
|  | ||||
|  | ||||
| Administrative issues | ||||
|   Don't commit substantive code in here without asking hp@redhat.com. | ||||
|   Adding translations, no-brainer typo fixes, etc. is fine. | ||||
|  | ||||
|   The code could use cleanup in a lot of places, feel free to do so. | ||||
|  | ||||
|   See http://developer.gnome.org/dotplan/for_maintainers.html for | ||||
|   information on how to make a release.  The only difference from those | ||||
|   instructions is that the minor version number of a Metacity release | ||||
|   should always be a number from the Fibonacci sequence. | ||||
|  | ||||
| Minimal Building/Testing Environment | ||||
|   You do not need to _install_ a development version of Metacity to | ||||
|   build, run and test it; you can run it from some temporary | ||||
|   directory.  Also, you do not need to build all of Gnome in order to | ||||
|   build a development version of Metacity -- odds are, you may be able | ||||
|   to build metacity from CVS without building any other modules. | ||||
|  | ||||
|   As long as you have gtk+ >= 3.0 and GIO >= 2.25.10 with your distro | ||||
|   (gtk+ >= 2.6 if you manually revert the change from bug 348633), you | ||||
|   should be able to install your distro's development packages | ||||
|   (e.g. gtk2-devel, glib-devel, startup-notification-devel on | ||||
|   Fedora; also, remember to install the gnome-common package which is | ||||
|   needed for building cvs versions of Gnome modules like Metacity) as | ||||
|   well as the standard development tools (gcc, autoconf, automake, | ||||
|   pkg-config, intltool, and libtool) and be ready to build and test | ||||
|   Metacity.  Steps to do so: | ||||
|  | ||||
|   $ svn checkout http://svn.gnome.org/svn/metacity/trunk metacity | ||||
|   $ cd metacity | ||||
|   $ ./autogen.sh --prefix /usr | ||||
|   $ make | ||||
|   $ ./src/metacity --replace | ||||
|  | ||||
|   Again, note that you do not need to run 'make install'. | ||||
|  | ||||
| Relevant standards and X properties | ||||
|   There are two documents that describe some basics about how window | ||||
|   managers should behave: the ICCCM (Inter-Client Communication Conventions | ||||
|   Manual) and EWMH (Extended Window Manager Hints).  You can find these at | ||||
|   the following locations: | ||||
|     ICCCM - http://tronche.com/gui/x/icccm/ | ||||
|     EWMH  - :pserver:anoncvs@pdx.freedesktop.org:/cvs | ||||
|   The ICCCM is usually available in RPM or DEB format as well.  There is | ||||
|   actually an online version of the EWMH, but it is almost always woefully | ||||
|   out of date.  Just get it from cvs with these commands (the backslash | ||||
|   means include the stuff from the next line): | ||||
|     cvs -d :pserver:anoncvs@cvs.freedesktop.org:/cvs/icccm-extensions login | ||||
|     cvs -d :pserver:anoncvs@cvs.freedesktop.org:/cvs/icccm-extensions \ | ||||
|       checkout wm-spec | ||||
|  | ||||
|   DO NOT GO AND READ THOSE THINGS.  THEY ARE REALLY, REALLY BORING. | ||||
|  | ||||
|   If you do, you'll probably end up catching up on your sleep instead of | ||||
|   hacking on Metacity. ;-)  Instead, just look at the table of contents and | ||||
|   glance at a page or two to get an idea of what's in there.  Then only | ||||
|   refer to it if you see something weird in the code and you don't know | ||||
|   what it is but has some funny looking name like you see in one of those | ||||
|   two documents. | ||||
|  | ||||
|   You can refer to the COMPLIANCE file for additional information on these | ||||
|   specifications and Metacity's compliance therewith. | ||||
|  | ||||
|   One of the major things those documents cover that are useful to learn | ||||
|   about immediately are X properties.  The right way to learn about those, | ||||
|   though, is through hand on experimentation with the xprop command (and | ||||
|   then look up things you find from xprop in those two manuals if you're | ||||
|   curious enough).  First, try running | ||||
|     xprop | ||||
|   in a terminal and click on one of the windows on your screen.  That gives | ||||
|   you the x properties for that window.  Look through them and get a basic | ||||
|   idea of what's there for kicks.  Note that you can get rid of some of the | ||||
|   verboseness by grepping out the _NET_WM_ICON stuff, i.e. | ||||
|     xprop | grep -v _NET_WM_ICON | ||||
|   Next, try running | ||||
|     xprop -root | ||||
|   in a terminal.  There's all the properties of the root window (which you | ||||
|   can think of as the "main" Xserver window).  You can also manually | ||||
|   specify individual windows that you want the properties of with | ||||
|     xprop -id <id> | ||||
|   if you know the id of the window in question.  You can get the id of a | ||||
|   given window by either running xwininfo, e.g. | ||||
|     xwininfo | grep "Window id" | cut -f 4 -d ' ' | ||||
|   or by looking at the _NET_CLIENT_STACKING property of the root | ||||
|   window.  Finally, it can also be useful to add "-spy" (without the | ||||
|   quotes) to the xprop command to get it to continually monitor that | ||||
|   window and report any changes to you. | ||||
|  | ||||
| Debugging information | ||||
|   Trying to run a window manager under a typical debugger, such as gdb, | ||||
|   unfortunately just doesn't work very well.  So, we have to resort to | ||||
|   other methods. | ||||
|  | ||||
|   Debugging logs | ||||
|  | ||||
|   First, note that you can start a new version of metacity to replace the | ||||
|   existing one by running | ||||
|     metacity --replace | ||||
|   (which also comes in handy in the form "./src/metacity --replace" when | ||||
|   trying to quickly test a small change while hacking on metacity without | ||||
|   doing a full "make install", though I'm going off topic...)  This will | ||||
|   allow you to see any warnings printed at the terminal.  Sometimes it's | ||||
|   useful to have these directed to a logfile instead, which you can do by | ||||
|   running | ||||
|     METACITY_USE_LOGFILE=1 metacity --replace | ||||
|   The logfile it uses will be printed in the terminal.  Sometimes, it's | ||||
|   useful to get more information than just warnings.  You can set | ||||
|   METACITY_VERBOSE to do that, like so: | ||||
|     METACITY_VERBOSE=1 METACITY_USE_LOGFILE=1 metacity --replace | ||||
|   (note that METACITY_VERBOSE=1 can be problematic without | ||||
|   METACITY_USE_LOGFILE=1; avoid it unless running in from something that | ||||
|   won't be managed by the new Metacity--see bug 305091 for more details). | ||||
|   There are also other flags, such as METACITY_DEBUG, most of which I | ||||
|   haven't tried and don't know what they do.  Go to the source code | ||||
|   directory and run | ||||
|     grep "METACITY_" * | grep getenv | ||||
|   to find out what the other ones are. | ||||
|  | ||||
|   Adding information to the log | ||||
|  | ||||
|   Since we can't single step with a debugger, we often have to fall back to | ||||
|   the primitive method of getting information we want to know: adding | ||||
|   "print" statements.  Metacity has a fairly structured way to do this, | ||||
|   using the functions meta_warning, meta_topic, and meta_verbose.  All | ||||
|   three have the same basic format as printf, except that meta_topic also | ||||
|   takes a leading enumeration parameter to specify the type of message | ||||
|   being shown (makes it easier for grepping in a verbose log).  You'll find | ||||
|   tons of examples in the source code if you need them; just do a quick | ||||
|   grep or look in most any file.  Note that meta_topic and meta_verbose | ||||
|   messages only appear if verbosity is turned on.  I tend to frequently add | ||||
|   temporary meta_warning statements (or switch meta_topic or meta_verbose | ||||
|   ones to meta_warning ones) and then undo the changes once I've learned | ||||
|   the info that I needed. | ||||
|  | ||||
|   There is also a meta_print_backtrace (which again is only active if | ||||
|   verbosity is turned on) that can also be useful if you want to learn how | ||||
|   a particular line of code gets called.  And, of course, there's always | ||||
|   g_assert if you want to make sure some section isn't executed (or isn't | ||||
|   executed under certain conditions). | ||||
|  | ||||
|   Valgrind | ||||
|  | ||||
|   Valgrind is awesome for finding memory leaks or corruption and | ||||
|   uninitialized variables.  But I also tend to use it in a non-traditional | ||||
|   way as a partial substitute for a normal debugger: it can provide me with | ||||
|   a stack trace of where metacity is crashing if I made a change that | ||||
|   caused it to do so, which is one of the major uses of debuggers.  (And, | ||||
|   what makes it cooler than a debugger is that there will also often be | ||||
|   warnings pinpointing the cause of the crash from either some kind of | ||||
|   simple memory corruption or an uninitialized variable).  Sometimes, when | ||||
|   I merely want to know what is calling a particular function I'll just | ||||
|   throw in an "int i; printf("%d\n", i);" just because valgrind will give | ||||
|   me a full stacktrace whenever it sees that uninitialized variable being | ||||
|   used (yes, I could use meta_print_backtrace, but that means I have to | ||||
|   turn verbosity on). | ||||
|  | ||||
|   To run metacity under valgrind, use options typical for any Gnome | ||||
|   program, such as | ||||
|     valgrind --log-file=metacity.log --tool=memcheck --num-callers=48 \ | ||||
|     --leak-check=yes --leak-resolution=high --show-reachable=yes     \ | ||||
|     ./src/metacity --replace | ||||
|   where, again, the backslashes mean to join all the stuff on the following | ||||
|   line with the previous one. | ||||
|  | ||||
|   However, there is a downside.  Things run a little bit slowly, and it | ||||
|   appears that you'll need about 1.5GB of ram, which unfortunately prevents | ||||
|   most people from trying this. | ||||
|  | ||||
|   Testing Utilities | ||||
|  | ||||
|   src/run-metacity.sh | ||||
|     The script src/run-metacity.sh is useful to hack on the window manager.  | ||||
|     It runs metacity in an Xnest. e.g.: | ||||
|       CLIENTS=3 ./run-metacity.sh | ||||
|     or  | ||||
|       DEBUG=memprof ./run-metacity.sh | ||||
|     or | ||||
|       DEBUG_TEST=1 ./run-metacity-sh | ||||
|     or whatever. | ||||
|  | ||||
|   metacity-message | ||||
|     The tool metacity-message can be used as follows: | ||||
|       metacity-message reload-theme | ||||
|       metacity-message restart | ||||
|       metacity-message enable-keybindings | ||||
|       metacity-message disable-keybindings | ||||
|     The first of these is useful for testing themes, the second is just | ||||
|     another way (besides the --restart flag to metacity itself) of | ||||
|     restarting metacity, and the third is useful for testing Metacity when | ||||
|     running it under an Xnest (typically, the Metacity under the Xnest | ||||
|     wouldn't get keybinding notifications--making keyboard navigation not | ||||
|     work--but if you disable the keybindings for the global Metacity then | ||||
|     the Metacity under the Xnest can then get those keybinding notifications). | ||||
|  | ||||
|   metacity-window-demo | ||||
|     metacity-window-demo is good for trying behavior of various kinds | ||||
|     of window without launching a full desktop. | ||||
|  | ||||
| Technical gotchas to keep in mind | ||||
|   Files that include gdk.h or gtk.h are not supposed to include | ||||
|   display.h or window.h or other core files.  Files in the core | ||||
|   (display.[hc], window.[hc]) are not supposed to include gdk.h or | ||||
|   gtk.h.  Reasons: | ||||
|  | ||||
|     "Basically you don't want GDK most of the time. It adds | ||||
|     abstractions that cause problems, because they aren't designed to | ||||
|     be used in a WM where we do weird stuff (display grabs, and just | ||||
|     being the WM). At best GDK adds inefficiency, at worst it breaks | ||||
|     things in weird ways where you have to be a GDK guru to figure | ||||
|     them out. Owen also told me that they didn't want to start adding | ||||
|     a lot of hacks to GDK to let a WM use it; we both agreed back in | ||||
|     the mists of time that metacity would only use it for the "UI" | ||||
|     bits as it does. | ||||
|  | ||||
|     Having the split in the source code contains and makes very clear | ||||
|     the interface between the WM and GDK/GTK. This keeps people from | ||||
|     introducing extra GDK/GTK usage when it isn't needed or | ||||
|     appropriate. Also, it speeds up the compilation a bit, though this | ||||
|     was perhaps more relevant 5 years ago than it is now. | ||||
|  | ||||
|     There was also a very old worry that the GDK stuff might have to | ||||
|     be in a separate process to work right; that turned out to be | ||||
|     untrue. Though who knows what issues the CM will introduce." | ||||
|  | ||||
|   Remember that strings stored in X properties are not in UTF-8, and they | ||||
|   have to end up in UTF-8 before we try putting them through Pango. | ||||
|  | ||||
|   If you make any X request involving a client window, you have to | ||||
|   meta_error_trap_push() around the call; this is not necessary for X | ||||
|   requests on the frame windows. | ||||
|  | ||||
|   Remember that not all windows have frames, and window->frame can be NULL. | ||||
|  | ||||
| Other important reading & where to get started | ||||
|   Extra reading | ||||
|  | ||||
|   There are some other important things to read to get oriented as well. | ||||
|   These are: | ||||
|     http://pobox.com/~hp/features.html | ||||
|     rationales.txt | ||||
|     doc/code-overview.txt | ||||
|  | ||||
|   It pays to read http://pobox.com/~hp/features.html in order | ||||
|   to understand the philosophy of Metacity. | ||||
|  | ||||
|   The rationales.txt file has two things: (1) a list of design choices with | ||||
|   links in the form of bugzilla bugs that discuss the issue, and (2) a list | ||||
|   outstanding bug categories, each of which is tracked by a particular | ||||
|   tracker bug in bugzilla from which you can find several closely related | ||||
|   bug reports. | ||||
|  | ||||
|   doc/code-overview.txt provides a fairly good overview of the code, | ||||
|   including coverage of the function of the various files, the main | ||||
|   structures and their relationships, and places to start looking in the | ||||
|   code tailored to general categories of tasks. | ||||
|  | ||||
|   Ideas for tasks to work on | ||||
|  | ||||
|   There are a variety of things you could work on in the code.  You may | ||||
|   have ideas of your own, but in case you don't, let me provide a list of | ||||
|   ideas you could choose from: | ||||
|  | ||||
|   If you're ambitious, there's a list of things Havoc made that he'd really | ||||
|   like to see tackled, which you can find at | ||||
|   http://log.ometer.com/2004-05.html.  Be sure to double check with someone | ||||
|   to make sure the item is still relevant if you're interested in one of | ||||
|   these.  Another place to look for ideas, of course, is bugzilla.  One can | ||||
|   just do queries and look for things that look fixable. | ||||
|  | ||||
|   However, perhaps the best way of getting ideas of related tasks to work | ||||
|   on, is to look at the second half of the rationales.txt file, which tries | ||||
|   to group bugs by type. | ||||
							
								
								
									
										8
									
								
								MAINTAINERS
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								MAINTAINERS
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| Tomas Frydrych | ||||
| Email: tf linux intel com | ||||
| Userid: tomasf | ||||
|  | ||||
| Owen Taylor | ||||
| Email: otaylor redhat com | ||||
| Userid: otaylor | ||||
|  | ||||
							
								
								
									
										43
									
								
								METACITY_MAINTAINERS
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								METACITY_MAINTAINERS
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| Currently active maintainers | ||||
| -------------------------------- | ||||
|  | ||||
| Elijah Newren | ||||
| Email: newren gmail com | ||||
| Userid: newren | ||||
|  | ||||
|   - Usually won't touch the theme bugs (isn't interested) or the | ||||
|     compositor (until open source nvidia drivers are up to snuff). | ||||
|     Tends to be most interested in libwnck/gtk interactions, focus | ||||
|     issues, constraints problems, and raising/stacking, but works on | ||||
|     just about anything other than themes and the compositor. | ||||
|  | ||||
| Thomas Thurman | ||||
| Email: thomas thurman org uk | ||||
| Userid: tthurman | ||||
|  | ||||
|   - Responsible for all theme bugs and the compositor (thank goodness | ||||
|     Thomas got involved, eh?).  I'm sure he'll replace this sentence | ||||
|     with his interests when he reads it.  ;-) | ||||
|  | ||||
|  | ||||
| Semi-active maintainers | ||||
| -------------------------------- | ||||
|  | ||||
| Havoc Pennington | ||||
| Email: hp  redhat com | ||||
| Userid: hp | ||||
|   - Original author.  Doesn't patch metacity anymore, but is active in | ||||
|     answering questions, responding to bugs, providing very helpful | ||||
|     suggestions and insight, and even assisting with debugging. | ||||
|  | ||||
|  | ||||
| Important historical figureheads | ||||
| -------------------------------- | ||||
|  | ||||
| Rob Adams (readams  readams net) | ||||
|   - Was the main maintainer of metacity for a while; particular areas | ||||
|     of focus included xinerama, placement, and an older version of the | ||||
|     constraints code.  Still responds to bugs every once in a while. | ||||
|  | ||||
| Søren Sandmann (sandmann  redhat com) | ||||
|   - Wrote most of the current compositing manager code + libcm | ||||
							
								
								
									
										8
									
								
								Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
|  | ||||
| SUBDIRS=src po doc | ||||
|  | ||||
| EXTRA_DIST = HACKING MAINTAINERS rationales.txt | ||||
|  | ||||
| DISTCLEANFILES = intltool-extract intltool-merge intltool-update po/stamp-it po/.intltool-merge-cache | ||||
|  | ||||
| DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc | ||||
							
								
								
									
										416
									
								
								README
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										416
									
								
								README
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,416 @@ | ||||
| The original codebase named "Metacity" is not a meta-City as in an | ||||
| urban center, but rather Meta-ness as in the state of being | ||||
| meta. i.e. metacity : meta as opacity : opaque. Also it may have | ||||
| something to do with the Meta key on UNIX keyboards. | ||||
|  | ||||
| Since then, it has been renamed mutter after a rebase on top of | ||||
| clutter as a compositing manager. | ||||
|  | ||||
| COMPILING MUTTER | ||||
| === | ||||
|  | ||||
| You need GTK+ 2.2.  For startup notification to work you need | ||||
| libstartup-notification at | ||||
| http://www.freedesktop.org/software/startup-notification/ or on the | ||||
| GNOME ftp site. | ||||
| You need Clutter 1.0. You need gobject-introspection 0.6.3. | ||||
|  | ||||
| REPORTING BUGS AND SUBMITTING PATCHES | ||||
| === | ||||
|  | ||||
| Report new bugs on http://bugzilla.gnome.org. Please check for | ||||
| duplicates, *especially* if you are reporting a feature request.  | ||||
|  | ||||
| Please do *not* add "me too!" or "yes I really want this!" comments to | ||||
| feature requests in bugzilla. Please read | ||||
| http://pobox.com/~hp/features.html prior to adding any kind of flame | ||||
| about missing features or misfeatures. | ||||
|  | ||||
| Feel free to send patches too; Metacity is relatively small and | ||||
| simple, so if you find a bug or want to add a feature it should be | ||||
| pretty easy.  Send me mail, or put the patch in bugzilla. | ||||
|  | ||||
| See the HACKING file for some notes on hacking Mutter. | ||||
|  | ||||
| MUTTER FEATURES | ||||
| === | ||||
|  | ||||
|  - Uses GTK+ 2.0 for drawing window frames. This means colors, fonts,  | ||||
|    etc. come from GTK+ theme. | ||||
|  | ||||
|  - Does not expose the concept of "window manager" to the user.  Some | ||||
|    of the features in the GNOME control panel and other parts of the | ||||
|    desktop happen to be implemented in metacity, such as changing your | ||||
|    window border theme, or changing your window navigation shortcuts, | ||||
|    but the user doesn't need to know this. | ||||
|  | ||||
|  - Includes only the window manager; does not try to be a desktop | ||||
|    environment. The pager, configuration, etc. are all separate and | ||||
|    modular. The "libwnck" library (which I also wrote) is available | ||||
|    for writing metacity extensions, pagers, and so on. (But libwnck | ||||
|    isn't metacity specific, or GNOME-dependent; it requires only GTK, | ||||
|    and should work with KWin, fvwm2, and other EWMH-compliant WMs.) | ||||
|  | ||||
|  - Has a simple theme system and a couple of extra themes come with it. | ||||
|    Change themes via gsettings: | ||||
|      gsettings set org.gnome.desktop.wm.preferences theme Crux | ||||
|      gsettings set org.gnome.desktop.wm.preferences theme Gorilla | ||||
|      gsettings set org.gnome.desktop.wm.preferences theme Atlanta | ||||
|      gsettings set org.gnome.desktop.wm.preferences theme Bright | ||||
|  | ||||
|    See theme-format.txt for docs on the theme format. Use  | ||||
|    metacity-theme-viewer to preview themes. | ||||
|  | ||||
|  - Change number of workspaces via gsettings: | ||||
|      gsettings set org.gnome.desktop.wm.preferences num-workspaces 5 | ||||
|  | ||||
|    Can also change workspaces from GNOME 2 pager. | ||||
|  | ||||
|  - Change focus mode: | ||||
|      gsettings set org.gnome.desktop.wm.preferences focus-mode mouse | ||||
|      gsettings set org.gnome.desktop.wm.preferences focus-mode sloppy | ||||
|      gsettings set org.gnome.desktop.wm.preferences focus-mode click | ||||
|  | ||||
|  - Global keybinding defaults include:    | ||||
|  | ||||
|     Alt-Tab                forward cycle window focus | ||||
|     Alt-Shift-Tab          backward cycle focus | ||||
|     Alt-Ctrl-Tab           forward cycle focus among panels | ||||
|     Alt-Ctrl-Shift-Tab     backward cycle focus among panels | ||||
|     Alt-Escape             cycle window focus without a popup thingy | ||||
|     Ctrl-Alt-Left Arrow    previous workspace | ||||
|     Ctrl-Alt-Right Arrow   next workspace | ||||
|     Ctrl-Alt-D             minimize/unminimize all, to show desktop | ||||
|  | ||||
|    Change keybindings for example: | ||||
|  | ||||
|      gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-1 '[<Alt>F1]' | ||||
|     | ||||
|    Also try the GNOME keyboard shortcuts control panel. | ||||
|  | ||||
|  - Window keybindings: | ||||
|  | ||||
|     Alt-space         window menu | ||||
|  | ||||
|     Mnemonics work in the menu. That is, Alt-space then underlined | ||||
|     letter in the menu item works. | ||||
|  | ||||
|     Choose Move from menu, and arrow keys to move the window. | ||||
|  | ||||
|     While moving, hold down Control to move slower, and  | ||||
|       Shift to snap to edges. | ||||
|  | ||||
|     Choose Resize from menu, and nothing happens yet, but  | ||||
|       eventually I might implement something. | ||||
|  | ||||
|     Keybindings for things like maximize window, vertical maximize, | ||||
|     etc. can be bound, but may not all exist by default. See | ||||
|     metacity.schemas. | ||||
|  | ||||
|  - Window mouse bindings: | ||||
|  | ||||
|     Clicking anywhere on frame with button 1 will raise/focus window | ||||
|      | ||||
|     If you click a window control, such as the close button, then the  | ||||
|      control will activate on button release if you are still over it | ||||
|      on release (as with most GUI toolkits) | ||||
|  | ||||
|     If you click and drag borders with button 1 it resizes the window | ||||
|      | ||||
|     If you click and drag the titlebar with button 1 it moves the  | ||||
|      window. | ||||
|  | ||||
|     If you click anywhere on the frame with button 2 it lowers the  | ||||
|      window. | ||||
|  | ||||
|     If you click anywhere on the frame with button 3 it shows the  | ||||
|      window menu. | ||||
|  | ||||
|     If you hold down Super (windows key) and click inside a window, it | ||||
|      will move the window (buttons 1 and 2) or show menu (button 3). | ||||
|      Or you can configure a different modifier for this. | ||||
|  | ||||
|     If you pick up a window with button 1 and then switch workspaces | ||||
|      the window will come with you to the new workspace, this is  | ||||
|      a feature copied from Enlightenment. | ||||
|  | ||||
|     If you hold down Shift while moving a window, the window snaps | ||||
|      to edges of other windows and the screen. | ||||
|  | ||||
|  - Session management: | ||||
|  | ||||
|     Mutter connects to the session manager and will set itself up to | ||||
|      be respawned. It theoretically restores sizes/positions/workspace | ||||
|      for session-aware applications. | ||||
|  | ||||
|  - Mutter implements much of the EWMH window manager specification | ||||
|    from freedesktop.org, as well as the older ICCCM.  Please refer to | ||||
|    the COMPLIANCE file for information on mutter compliance with | ||||
|    these standards. | ||||
|  | ||||
|  - Uses Pango to render text, so has cool i18n capabilities.  | ||||
|    Supports UTF-8 window titles and such. | ||||
|  | ||||
|  - There are simple animations for actions such as minimization,  | ||||
|    to help users see what is happening. Should probably  | ||||
|    have a few more of these and make them nicer. | ||||
|  | ||||
|  - if you have the proper X setup, set the GDK_USE_XFT=1  | ||||
|    environment variable to get antialiased window titles. | ||||
|  | ||||
|  - considers the panel when placing windows and maximizing | ||||
|    them. | ||||
|  | ||||
|  - handles the window manager selection from the ICCCM. Will exit if | ||||
|    another WM claims it, and can claim it from another WM if you pass | ||||
|    the --replace argument. So if you're running another | ||||
|    ICCCM-compliant WM, you can run "mutter --replace" to replace it | ||||
|    with Metacity. | ||||
|  | ||||
|  - does basic colormap handling | ||||
|  | ||||
|  - and much more! well, maybe not a lot more. | ||||
|  | ||||
| HOW TO ADD EXTERNAL FEATURES | ||||
| === | ||||
|  | ||||
| You can write a mutter "plugin" such as a pager, window list, icon | ||||
| box, task menu, or even things like "window matching" using the | ||||
| Extended Window Manager Hints. See http://www.freedesktop.org for the | ||||
| EWMH specification. An easy-to-use library called "libwnck" is | ||||
| available that uses the EWMH and is specifically designed for writing | ||||
| WM accessories. | ||||
|  | ||||
| You might be interested in existing accessories such as "Devil's Pie" | ||||
| by Ross Burton, which add features to Mutter (or other | ||||
| EWMH-compliant WMs). | ||||
|  | ||||
| MUTTER BUGS, NON-FEATURES, AND CAVEATS | ||||
| === | ||||
|  | ||||
| See bugzilla: http://bugzilla.gnome.org/query.cgi | ||||
|  | ||||
| FAQ | ||||
| === | ||||
|  | ||||
| Q: Will you add my feature? | ||||
|  | ||||
| A: If it makes sense to turn on unconditionally, or is genuinely a | ||||
|    harmless preference that I would not be embarrassed to put in a | ||||
|    simple, uncluttered, user-friendly configuration dialog. | ||||
|  | ||||
|    If the only rationale for your feature is that other window | ||||
|    managers have it, or that you are personally used to it, or | ||||
|    something like that, then I will not be impressed. Metacity is | ||||
|    firmly in the "choose good defaults" camp rather than the "offer 6 | ||||
|    equally broken ways to do it, and let the user pick one" camp. | ||||
|  | ||||
|    This is part of a "no crackrock" policy, despite some exceptions | ||||
|    I'm mildly embarrassed about. For example, multiple workspaces | ||||
|    probably constitute crackrock, they confuse most users and really | ||||
|    are not that useful if you have a decent tasklist and so on. But I | ||||
|    am too used to them to turn them off.  Or alternatively | ||||
|    iconification/tasklist is crack, and workspaces/pager are good. But | ||||
|    having both is certainly a bit wrong.  Sloppy focus is probably | ||||
|    crackrock too. | ||||
|  | ||||
|    But don't think unlimited crack is OK just because I slipped up a | ||||
|    little. No slippery slope here. | ||||
|  | ||||
|    Don't let this discourage patches and fixes - I love those. ;-) | ||||
|    Just be prepared to hear the above objections if your patch adds | ||||
|    some crack-ridden configuration option. | ||||
|  | ||||
|    http://pobox.com/~hp/free-software-ui.html | ||||
|    http://pobox.com/~hp/features.html    | ||||
|  | ||||
| Q: Will Mutter be part of GNOME? | ||||
|  | ||||
| A: It is not officially part of GNOME as of GNOME 2.27. We are | ||||
|    hoping to have mutter officially included as of GNOME 2.28.  | ||||
|  | ||||
| Q: Why does Mutter remember the workspace/position of some apps  | ||||
|    but not others across logout/login? | ||||
|  | ||||
| A: Mutter only stores sizes/positions for apps that are session | ||||
|    managed. As far as I can determine, there is no way to attempt to | ||||
|    remember workspace/position for non-session-aware apps without | ||||
|    causing a lot of weird effects. | ||||
|  | ||||
|    The reason is that you don't know which non-SM-aware apps were | ||||
|    launched by the session. When you initially log in, Metacity sees a | ||||
|    bunch of new windows appear. But it can't distinguish between | ||||
|    windows that were stored in your session, or windows you just | ||||
|    launched after logging in. If Metacity tried to guess that a window | ||||
|    was from the session, it could e.g. end up maximizing a dialog, or | ||||
|    put a window you just launched on another desktop or in a weird | ||||
|    place. And in fact I see a lot of bugs like this in window managers | ||||
|    that try to handle non-session-aware apps. | ||||
|  | ||||
|    However, for session-aware apps, Mutter can tell that the | ||||
|    application instance is from the session and thus restore it | ||||
|    reliably, assuming the app properly restores the windows it had  | ||||
|    open on session save. | ||||
|     | ||||
|    So the correct way to fix the situation is to make apps | ||||
|    session-aware. libSM has come with X for years, it's very | ||||
|    standardized, it's shared by GNOME and KDE - even twm is | ||||
|    session-aware. So anyone who won't take a patch to add SM is more | ||||
|    archaic than twm - and you should flame them. ;-) | ||||
|  | ||||
|    Docs on session management: | ||||
|     http://www.fifi.org/doc/xspecs/xsmp.txt.gz | ||||
|     http://www.fifi.org/doc/xspecs/SMlib.txt.gz | ||||
|  | ||||
|    See also the ICCCM section on SM. For GNOME apps, use the | ||||
|    GnomeClient object. For a simple example of using libSM directly, | ||||
|    twm/session.c in the twm source code is pretty easy to understand. | ||||
|  | ||||
| Q: How about adding viewports in addition to workspaces? | ||||
|  | ||||
| A: I could conceivably be convinced to use viewports _instead_ of | ||||
|    workspaces, though currently I'm not thinking that. But I don't | ||||
|    think it makes any sense to have both; it's just confusing. They | ||||
|    are functionally equivalent. | ||||
|  | ||||
|    You may think this means that you won't have certain keybindings,  | ||||
|    or something like that. This is a misconception. The only  | ||||
|    _fundamental_ difference between viewports and workspaces is that  | ||||
|    with viewports, windows can "overlap" and appear partially on  | ||||
|    one and partially on another. All other differences that | ||||
|    traditionally exist in other window managers are accidental -  | ||||
|    the features commonly associated with viewports can be implemented | ||||
|    for workspaces, and vice versa. | ||||
|  | ||||
|    So I don't want to have two kinds of | ||||
|    workspace/desktop/viewport/whatever, but I'm willing to add | ||||
|    features traditionally associated with either kind if those | ||||
|    features make sense. | ||||
|  | ||||
| Q: Why is the panel always on top? | ||||
|  | ||||
| A: Because it's a better user interface, and until we made this not | ||||
|    configurable a bunch of apps were not getting fixed (the app | ||||
|    authors were just saying "put your panel on the bottom" instead of | ||||
|    properly supporting fullscreen mode, and such). | ||||
|  | ||||
|    rationales.txt has the bugzilla URL for some flamefesting on this, | ||||
|    if you want to go back and relive the glory. | ||||
|    Read these and the bugzilla stuff before asking/commenting: | ||||
|      http://pobox.com/~hp/free-software-ui.html | ||||
|      http://pobox.com/~hp/features.html    | ||||
|  | ||||
| Q: Why is there no edge flipping? | ||||
|  | ||||
| A: This one is also in rationales.txt. Because "ouija board" UI, where | ||||
|    you just move the mouse around and the computer guesses what you | ||||
|    mean, has a lot of issues. This includes mouse focus, shade-hover | ||||
|    mode, edge flipping, autoraise, etc. Metacity has mouse focus and | ||||
|    autoraise as a compromise, but these features are all confusing for | ||||
|    many users, and cause problems with accessibility, fitt's law, and | ||||
|    so on. | ||||
|  | ||||
|    Read these and the bugzilla stuff before asking/commenting: | ||||
|      http://pobox.com/~hp/free-software-ui.html | ||||
|      http://pobox.com/~hp/features.html    | ||||
|  | ||||
| Q: Why does wireframe move/resize suck? | ||||
|  | ||||
| A: You can turn it on with the reduced_resources setting. | ||||
|  | ||||
|    But: it has low usability, and is a pain | ||||
|    to implement, and there's no reason opaque move/resize should be a | ||||
|    problem on any setup that can run a modern desktop worth a darn to | ||||
|    begin with. | ||||
|  | ||||
|    Read these and the bugzilla stuff before asking/commenting: | ||||
|      http://pobox.com/~hp/free-software-ui.html | ||||
|      http://pobox.com/~hp/features.html    | ||||
|  | ||||
|    The reason we had to add wireframe anyway was broken  | ||||
|    proprietary apps that can't handle lots of resize events. | ||||
|  | ||||
| Q: Why no XYZ? | ||||
|  | ||||
| A: You are probably getting the idea by now - check rationales.txt, | ||||
|    query/search bugzilla, and read http://pobox.com/~hp/features.html | ||||
|    and http://pobox.com/~hp/free-software-ui.html | ||||
|  | ||||
|    Then sit down and answer the question for yourself.  Is the feature | ||||
|    good? What's the rationale for it? Answer "why" not just "why not." | ||||
|    Justify in terms of users as a whole, not just users like | ||||
|    yourself. How else can you solve the same problem? etc. If that | ||||
|    leads you to a strong opinion, then please, post the rationale for | ||||
|    discussion to an appropriate bugzilla bug, or to | ||||
|    usability@gnome.org. | ||||
|  | ||||
|    Please don't just "me too!" on bugzilla bugs, please don't think | ||||
|    flames will get you anywhere, and please don't repeat rationale | ||||
|    that's already been offered. | ||||
|  | ||||
| Q: Your dumb web pages you made me read talk about solving problems in | ||||
|    fundamental ways instead of adding preferences or workarounds. | ||||
|    What are some examples where metacity has done this? | ||||
|  | ||||
| A: There are quite a few, though many opportunities remain.  Sometimes | ||||
|    the real fix involves application changes. The metacity approach is | ||||
|    that it's OK to require apps to change, though there are also | ||||
|    plenty of workarounds in metacity for battles considered too hard | ||||
|    to fight. | ||||
|  | ||||
|    Here are some examples: | ||||
|  | ||||
|    - fullscreen mode was introduced to allow position constraints, | ||||
|      panel-on-top, and other such things to apply to normal windows | ||||
|      while still allowing video players etc. to "just work" | ||||
|  | ||||
|    - "whether to include minimized windows in Alt+Tab" was solved  | ||||
|      by putting minimized windows at the *end* of the tab order.  | ||||
|  | ||||
|    - Whether to pop up a feedback display during Alt+Tab was solved by | ||||
|      having both Alt+Tab and Alt+Esc | ||||
|  | ||||
|    - Whether to have a "kill" feature was solved by automatically | ||||
|      detecting and offering to kill stuck apps. Better, metacity | ||||
|      actually does "kill -9" on the process, it doesn't just | ||||
|      disconnect the process from the X server. You'll appreciate this | ||||
|      if you ever did a "kill" on Netscape 4, and watched it keep | ||||
|      eating 100% CPU even though the X server had booted it. | ||||
|  | ||||
|    - The workspaces vs. viewports mess was avoided by adding | ||||
|      directional navigation and such to workspaces, see discussion | ||||
|      earlier in this file. | ||||
|  | ||||
|    - Instead of configurable placement algorithms, there's just one  | ||||
|      that works fairly well most of the time. | ||||
|  | ||||
|    - To avoid excess CPU use during opaque move/resize, we rate limit | ||||
|      the updates to the application window's size. | ||||
|  | ||||
|    - Instead of configurable "show size of window while resizing," | ||||
|      it's only shown for windows where it matters, such as terminals. | ||||
|      (Only use-case given for all windows is for web designers | ||||
|      choosing their web browser size, but there are web sites and | ||||
|      desktop backgrounds that do this for you.) | ||||
|  | ||||
|    - Using startup notification, applications open on the workspace | ||||
|      where you launched them, not the active workspace when their | ||||
|      window is opened. | ||||
|  | ||||
|    - and much more. | ||||
|  | ||||
| Q: I think mutter sucks. | ||||
|  | ||||
| A: Feel free to use any WM you like. The reason metacity follows the | ||||
|    ICCCM and EWMH specifications is that it makes metacity a modular, | ||||
|    interchangeable part in the desktop. libwnck-based apps such as the | ||||
|    GNOME window list will work just fine with any EWMH-compliant WM. | ||||
|  | ||||
| Q: Did you spend a lot of time on this? | ||||
|  | ||||
| A: Originally the answer was no. Sadly the answer is now yes. | ||||
|  | ||||
| Q: How can you claim that you are anti-crack, while still  | ||||
|    writing a window manager? | ||||
|  | ||||
| A: I have no comment on that. | ||||
							
								
								
									
										57
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										57
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,57 +0,0 @@ | ||||
| # Mutter | ||||
|  | ||||
| Mutter is a Wayland display server and X11 window manager and compositor library. | ||||
|  | ||||
| When used as a Wayland display server, it runs on top of KMS and libinput. It | ||||
| implements the compositor side of the Wayland core protocol as well as various | ||||
| protocol extensions. It also has functionality related to running X11 | ||||
| applications using Xwayland. | ||||
|  | ||||
| When used on top of Xorg it acts as a X11 window manager and compositing manager. | ||||
|  | ||||
| It contains functionality related to, among other things, window management, | ||||
| window compositing, focus tracking, workspace management, keybindings and | ||||
| monitor configuration. | ||||
|  | ||||
| Internally it uses a fork of Cogl, a hardware acceleration abstraction library | ||||
| used to simplify usage of OpenGL pipelines, as well as a fork of Clutter, a | ||||
| scene graph and user interface toolkit. | ||||
|  | ||||
| Mutter is used by, for example, GNOME Shell, the GNOME core user interface, and | ||||
| by  Gala, elementary OS's window manager. It can also be run standalone, using | ||||
| the  command "mutter", but just running plain mutter is only intended for | ||||
| debugging purposes. | ||||
|  | ||||
| ## Contributing | ||||
|  | ||||
| To contribute, open merge requests at https://gitlab.gnome.org/GNOME/mutter. | ||||
|  | ||||
| It can be useful to first look at the | ||||
| [GNOME Handbook](https://handbook.gnome.org/development.html) and the | ||||
| documentation and API references below first. | ||||
|  | ||||
| ## Documentation | ||||
|  | ||||
| - [Coding style and conventions](doc/coding-style.md) | ||||
| - [Git conventions](doc/git-conventions.md) | ||||
| - [Code overview](doc/code-overview.md) | ||||
| - [Building and Running](doc/building-and-running.md) | ||||
| - [Debugging](doc/debugging.md) | ||||
| - [Monitor configuration](doc/monitor-configuration.md) | ||||
|  | ||||
| ## API Reference | ||||
|  | ||||
| - Meta: <https://mutter.gnome.org/meta/> | ||||
| - Clutter: <https://mutter.gnome.org/clutter/> | ||||
| - Cally: <https://mutter.gnome.org/cally/> | ||||
| - Cogl: <https://mutter.gnome.org/cogl/> | ||||
| - CoglPango: <https://mutter.gnome.org/cogl-pango/> | ||||
| - Mtk: <https://mutter.gnome.org/mtk/> | ||||
|  | ||||
| ## License | ||||
|  | ||||
| Mutter is distributed under the terms of the GNU General Public License, | ||||
| version 2 or later. See the [COPYING][license] file for detalis. | ||||
|  | ||||
| [bug-tracker]: https://gitlab.gnome.org/GNOME/mutter/issues | ||||
| [license]: COPYING | ||||
							
								
								
									
										22
									
								
								autogen.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										22
									
								
								autogen.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| #!/bin/bash | ||||
| # Run this to generate all the initial makefiles, etc. | ||||
|  | ||||
| srcdir=`dirname $0` | ||||
| test -z "$srcdir" && srcdir=. | ||||
|  | ||||
| PKG_NAME="mutter" | ||||
| REQUIRED_AUTOMAKE_VERSION=1.10 | ||||
|  | ||||
| (test -f $srcdir/configure.ac \ | ||||
|   && test -d $srcdir/src) || { | ||||
|     echo -n "**Error**: Directory "\`$srcdir\'" does not look like the" | ||||
|     echo " top-level metacity directory" | ||||
|     exit 1 | ||||
| } | ||||
|  | ||||
| which gnome-autogen.sh || { | ||||
|     echo "You need to install gnome-common from GNOME Subversion (or from" | ||||
|     echo "your distribution's package manager)." | ||||
|     exit 1 | ||||
| } | ||||
| USE_GNOME2_MACROS=1 USE_COMMON_DOC_BUILD=yes . gnome-autogen.sh | ||||
							
								
								
									
										164
									
								
								check-style.py
									
									
									
									
									
								
							
							
						
						
									
										164
									
								
								check-style.py
									
									
									
									
									
								
							| @@ -1,164 +0,0 @@ | ||||
| #!/bin/env python3 | ||||
|  | ||||
| import argparse | ||||
| import os | ||||
| import re | ||||
| import subprocess | ||||
| import sys | ||||
| import tempfile | ||||
|  | ||||
| # Path relative to this script | ||||
| uncrustify_cfg = 'tools/uncrustify.cfg' | ||||
|  | ||||
| def run_diff(sha): | ||||
|     proc = subprocess.run( | ||||
|         ["git", "diff", "-U0", "--function-context", "--default-prefix", sha, "HEAD"], | ||||
|         stdout=subprocess.PIPE, | ||||
|         stderr=subprocess.STDOUT, | ||||
|         encoding="utf-8", | ||||
|     ) | ||||
|     return proc.stdout.strip().splitlines() | ||||
|  | ||||
| def find_chunks(diff): | ||||
|     file_entry_re = re.compile(r'^\+\+\+ b/(.*)$') | ||||
|     diff_chunk_re = re.compile(r'^@@ -\d+,\d+ \+(\d+),(\d+)') | ||||
|     file = None | ||||
|     chunks = [] | ||||
|  | ||||
|     for line in diff: | ||||
|         match = file_entry_re.match(line) | ||||
|         if match: | ||||
|             file = match.group(1) | ||||
|  | ||||
|         match = diff_chunk_re.match(line) | ||||
|         if match: | ||||
|             start = int(match.group(1)) | ||||
|             len = int(match.group(2)) | ||||
|             end = start + len | ||||
|  | ||||
|             if len > 0 and (file.endswith('.c') or file.endswith('.h') or file.endswith('.vala')): | ||||
|                 chunks.append({ 'file': file, 'start': start, 'end': end }) | ||||
|  | ||||
|     return chunks | ||||
|  | ||||
| def reformat_chunks(chunks, rewrite): | ||||
|     # Creates temp file with INDENT-ON/OFF comments | ||||
|     def create_temp_file(file, start, end): | ||||
|         with open(file) as f: | ||||
|             tmp = tempfile.NamedTemporaryFile() | ||||
|             if start > 1: | ||||
|                 tmp.write(b'/** *INDENT-OFF* **/\n') | ||||
|             for i, line in enumerate(f, start=1): | ||||
|                 if i == start - 1: | ||||
|                     tmp.write(b'/** *INDENT-ON* **/\n') | ||||
|  | ||||
|                 tmp.write(bytes(line, 'utf-8')) | ||||
|  | ||||
|                 if i == end - 1: | ||||
|                     tmp.write(b'/** *INDENT-OFF* **/\n') | ||||
|  | ||||
|             tmp.seek(0) | ||||
|  | ||||
|         return tmp | ||||
|  | ||||
|     # Removes uncrustify INDENT-ON/OFF helper comments | ||||
|     def remove_indent_comments(output): | ||||
|         tmp = tempfile.NamedTemporaryFile() | ||||
|  | ||||
|         for line in output: | ||||
|             if line != b'/** *INDENT-OFF* **/\n' and line != b'/** *INDENT-ON* **/\n': | ||||
|                 tmp.write(line) | ||||
|  | ||||
|         tmp.seek(0) | ||||
|  | ||||
|         return tmp | ||||
|  | ||||
|     changed = None | ||||
|  | ||||
|     for chunk in chunks: | ||||
|         # Add INDENT-ON/OFF comments | ||||
|         tmp = create_temp_file(chunk['file'], chunk['start'], chunk['end']) | ||||
|  | ||||
|         # uncrustify chunk | ||||
|         proc = subprocess.run( | ||||
|             ["uncrustify", "-c", uncrustify_cfg, "-f", tmp.name], | ||||
|             stdout=subprocess.PIPE, | ||||
|         ) | ||||
|         reindented = proc.stdout.splitlines(keepends=True) | ||||
|         if proc.returncode != 0: | ||||
|             continue | ||||
|  | ||||
|         tmp.close() | ||||
|  | ||||
|         # Remove INDENT-ON/OFF comments | ||||
|         formatted = remove_indent_comments(reindented) | ||||
|  | ||||
|         if dry_run is True: | ||||
|             # Show changes | ||||
|             proc = subprocess.run( | ||||
|                 ["diff", "-up", "--color=always", chunk['file'], formatted.name], | ||||
|                 stdout=subprocess.PIPE, | ||||
|                 stderr=subprocess.STDOUT, | ||||
|                 encoding="utf-8", | ||||
|             ) | ||||
|             diff = proc.stdout | ||||
|             if diff != '': | ||||
|                 output = re.sub('\t', '↦\t', diff) | ||||
|                 print(output) | ||||
|                 changed = True | ||||
|         else: | ||||
|             # Apply changes | ||||
|             diff = subprocess.run( | ||||
|                 ["diff", "-up", chunk['file'], formatted.name], | ||||
|                 stdout=subprocess.PIPE, | ||||
|                 stderr=subprocess.STDOUT, | ||||
|             ) | ||||
|             patch = subprocess.run(["patch", chunk['file']], input=diff.stdout) | ||||
|  | ||||
|         formatted.close() | ||||
|  | ||||
|     return changed | ||||
|  | ||||
|  | ||||
| parser = argparse.ArgumentParser(description='Check code style. Needs uncrustify installed.') | ||||
| parser.add_argument('--sha', metavar='SHA', type=str, | ||||
|                     help='SHA for the commit to compare HEAD with') | ||||
| parser.add_argument('--dry-run', '-d', type=bool, | ||||
|                     action=argparse.BooleanOptionalAction, | ||||
|                     help='Only print changes to stdout, do not change code') | ||||
| parser.add_argument('--rewrite', '-r', type=bool, | ||||
|                     action=argparse.BooleanOptionalAction, | ||||
|                     help='Whether to amend the result to the last commit (e.g. \'git rebase --exec "%(prog)s -r"\')') | ||||
|  | ||||
| # Change CWD to script location, necessary for always locating the configuration file | ||||
| os.chdir(os.path.dirname(os.path.abspath(sys.argv[0]))) | ||||
|  | ||||
| args = parser.parse_args() | ||||
| sha = args.sha or 'HEAD^' | ||||
| rewrite = args.rewrite | ||||
| dry_run = args.dry_run | ||||
|  | ||||
| diff = run_diff(sha) | ||||
| chunks = find_chunks(diff) | ||||
| changed = reformat_chunks(chunks, rewrite) | ||||
|  | ||||
| if dry_run is not True and rewrite is True: | ||||
|     proc = subprocess.run(["git", "add", "-p"]) | ||||
|     if proc.returncode == 0: | ||||
|         # Commit the added changes as a squash commit | ||||
|         subprocess.run( | ||||
|             ["git", "commit", "--squash", "HEAD", "-C", "HEAD"], | ||||
|             stdout=subprocess.DEVNULL) | ||||
|         # Delete the unapplied changes | ||||
|         subprocess.run(["git", "reset", "--hard"], stdout=subprocess.DEVNULL) | ||||
|     os._exit(0) | ||||
| elif dry_run is True and changed is True: | ||||
|     print(f""" | ||||
| Issue the following commands in your local tree to apply the suggested changes: | ||||
|  | ||||
|     $ git rebase {sha} --exec "./check-style.py -r" | ||||
|     $ git rebase --autosquash {sha} | ||||
| """) | ||||
|     os._exit(-1) | ||||
|  | ||||
| os._exit(0) | ||||
| @@ -1,986 +0,0 @@ | ||||
| # DO NOT MODIFY THIS FILE | ||||
| # | ||||
| # Clutter uses the Git commit log to generate the ChangeLog files when | ||||
| # creating the tarball for releases and snapshots. This file is maintained | ||||
| # only for historical reasons. | ||||
|  | ||||
| 2010-07-05 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Cleaning ClutterText | ||||
|  | ||||
|   * Removing superfluous g_return_if_fail | ||||
|   * Removing unused ClutterText::text-changed callback | ||||
|  | ||||
| 2010-07-05 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Refactoring "window:create" and "window:destroy" emission code | ||||
|  | ||||
| Previously "window:create" and "window:destroy" were emitted on | ||||
| CallyUtil. Although it works, and CallyUtil already have callbacks to | ||||
| stage_added/removed signals, I think that it is more tidy/clear to do | ||||
| that on CallyRoot: | ||||
|  | ||||
|   * CallyRoot already has code to manage ClutterStage addition/removal | ||||
|  | ||||
|   * In fact, we can see CallyRoot as the object exposing the a11y | ||||
|     information from ClutterStageManager, so it fits better here. | ||||
|  | ||||
|   * CallyUtil callbacks these signals are related to key event | ||||
|     listeners (key snooper simulation). One of the main CallyUtil | ||||
|     responsibilities is managing event (connecting, emitting), so I | ||||
|     would prefer to not start to add/mix more functionalities here. | ||||
|  | ||||
| Ideally it would be better to emit all CallyStage methods from | ||||
| CallyStage, but it is clear that "create" and "destroy" are more easy | ||||
| to emit from a external object. | ||||
|  | ||||
| 2010-06-25 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Cleaning clutter-actor | ||||
|  | ||||
| Some cleaning changes: | ||||
|   * Using CallyActionFunc instead of ACTION_FUNC | ||||
|   * Removing a extra * on cally-actor-private macro documentation, to | ||||
|     avoid gtk-doc warnings | ||||
|   * Using g_strcmp0 instead of strcmp | ||||
|  | ||||
| Changes to be applied on clutter (see CB#2097 and CB#2098), applied | ||||
| also here to maintain the sync. My intention is keep this developing line | ||||
| until the real integration, in order to make a final independent cally | ||||
| release. | ||||
|  | ||||
| 2010-06-14 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Adding -Wshadow option and solving warnings related | ||||
|  | ||||
|  | ||||
| 2010-06-14 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Added dummy padding for future vt expansion | ||||
|  | ||||
| Added dummy padding on the different classes structures, to allow | ||||
| future expansion of virtual methods. | ||||
|  | ||||
| I decided to add this on all the classes, although it would be | ||||
| really unlikely in some cases (ie, CallyGroup) | ||||
|  | ||||
| 2010-06-10 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Adding and emitting "window:xxx" methods on CallyStage | ||||
|  | ||||
| Added some window related signals on CallyStage: | ||||
|  | ||||
|   * window:activate and window:deactivate emitted from CallyStage | ||||
|   * window:create and window:destroy emitted from CallyUtil | ||||
|  | ||||
| ClutterStage doesn't fulfill 100% the window concept, but some of | ||||
| these signals are important in order to identify the object which | ||||
| could emit global/key events. | ||||
|  | ||||
| The current implementation is equivalent to GailWindow one, supposing | ||||
| CallyStage as the only window related window. This likely would change | ||||
| in any clutter-based toolkit implement a real Window object, so a more | ||||
| flexible procedure would be required. But we would solve problems step | ||||
| by step. | ||||
|  | ||||
| BTW: as I explain here [1] I really think that the current way to | ||||
| implement "window:xxx" signals (not defined in ATK but expected from | ||||
| the a11y implementation toolkit) somewhat hacky and undocumented (you | ||||
| need to check at-spi2 idls to know that you require to emit this | ||||
| events) | ||||
|  | ||||
| Related to bug CB#2147 (Orca doesn't speech out properly non | ||||
| printable chars on some environments), as solves this problem | ||||
| in a specific case. | ||||
|  | ||||
| [1] https://bugzilla.gnome.org/show_bug.cgi?id=620977#c1 | ||||
|  | ||||
| 2010-06-04 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Avoiding clutter_stage_get_key_focus warning | ||||
|  | ||||
| For any reason, in some cases, a clutter actor doesn't have a stage | ||||
| associated. We use the default one as fallback. | ||||
|  | ||||
| 2010-06-02 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Added a defunct check on cally_group_get_n_children | ||||
|  | ||||
| Some warnings appeared when we tried to get the number | ||||
| of children of a defunct object. | ||||
|  | ||||
| 2010-06-02 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Update TODO file | ||||
|  | ||||
| Use Bugzilla to setting missing features. | ||||
|  | ||||
| 2010-06-01 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Removing heuristics to decide CallyRectable/CallyTexture role | ||||
|  | ||||
| Previously CallyRectangle and CallyTexture used some heuristics in | ||||
| order to decide the default role: ATK_ROLE_IMAGE or | ||||
| ATK_PUSH_BUTTON, as in practice most applications using these | ||||
| objects as buttons were not applying the proper role. | ||||
|  | ||||
| As this is a hack, and a application responsibility, finally we | ||||
| have decided to remove this, so the default role is ATK_ROLE_IMAGE. | ||||
|  | ||||
| Fixes CB#1732 (CallyTexture and CallyRectangle uses some heuristics to | ||||
| decide the role) | ||||
|  | ||||
| 2010-05-28 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Post-release version bump, after release 1.2.0 | ||||
|  | ||||
| I wrongly added the last commit on the 1.1 branch, when in fact it | ||||
| requires clutter 1.3.3, and on the README it is explained that | ||||
| cally versioning is tied to clutter versioning. In order to solve | ||||
| that a clutter-1.2 release branch is created, and bumped the version. | ||||
|  | ||||
| This versioning tyding will be obsolete when the integration with | ||||
| clutter become a reality, but in the same way, this is the way to | ||||
| tidy this thinking in this integration. | ||||
|  | ||||
| 2010-04-13 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Use clutter_actor_get_accessible | ||||
|  | ||||
| The method clutter_actor_get_accessible was added due work on | ||||
| bug 2070, and should be used to get the accessibility object, | ||||
| instead of atk_gobject_accessible_for_object | ||||
|  | ||||
| This would allow to implement a11y support directly on | ||||
| any clutter based toolkit object (ie StLabel). | ||||
|  | ||||
| 2010-05-13 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Added CallyClone example | ||||
|  | ||||
|  | ||||
| 2010-05-13 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Added a11y support for ClutterClone | ||||
|  | ||||
| Resolved in the most simplified way, just as a image and a | ||||
| default description to identify cloned objects. | ||||
|  | ||||
| More information: | ||||
| http://lists.o-hand.com/clutter/3797.html | ||||
|  | ||||
| 2010-04-14 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Remove gail dependency | ||||
|  | ||||
| Removed to avoid gdk/gtk dependency on cally. | ||||
|  | ||||
| Part of bug CB#2072 solution | ||||
|  | ||||
| 2010-04-14 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Avoid gdk functions filling AtkKeyEventStruct | ||||
|  | ||||
| Now when AtkKeyEventStruct is filled in order to emit any key event | ||||
| signal, it is not used any gdk function on the keyval or the | ||||
| string fields. | ||||
|  | ||||
| event_string is filled with the printable character if possible, if | ||||
| not (Ctrl, Alt, etc) it is set as NULL. | ||||
|  | ||||
| Now the AT should take care of that, at least until we define atk key | ||||
| event struct in a more agnostic way (not tied to gdk/gtk). See orca | ||||
| bug bgo#616206 as a example. | ||||
|  | ||||
| Part of bug CB#2072 solution. | ||||
|  | ||||
| 2010-04-15 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Added gail_misc_layout_get_run_attributes implementation | ||||
|  | ||||
| Part of bug CB#2072 solution | ||||
|  | ||||
| 2010-04-14 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Remove gailutil/gailmisc functions calls | ||||
|  | ||||
| This is because gailutil/gailmisc added a gdk/gtk dependency, and | ||||
| this dependency is being removed. New cally-specific implementation | ||||
| are required. | ||||
|  | ||||
| Related to bug CB#1733 | ||||
|  | ||||
| Part of bug CB#2072 solution | ||||
|  | ||||
| 2010-04-13 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Fixing the libdir directory in some examples | ||||
|  | ||||
|  | ||||
| 2010-03-26 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Previous cally.pc.in update was incomplete | ||||
|  | ||||
| The previous commit was not tested properly, and it was missing one | ||||
| detail. Sorry for the noise. | ||||
|  | ||||
| 2010-03-26 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Update cally.pc.in after module relocation | ||||
|  | ||||
| Previous commit places cally module in a different directory. | ||||
| It also corrects where the include directory is placed. | ||||
|  | ||||
| 2010-03-15 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Use a proper clutter module directory | ||||
|  | ||||
| Use a proper clutter module directory, instead of keep being | ||||
| installed on a gtk directory. | ||||
|  | ||||
| Improve the cally-examples-util, in order to keep using | ||||
| hardcoded values. | ||||
|  | ||||
| Fixes CB#1737 (Wrong cally module directory) | ||||
|  | ||||
| 2010-03-15 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Proper UTF-8 headers | ||||
|  | ||||
|  | ||||
| 2010-02-25 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Change "--with-dbus" option for "atk-bridge-dir" on examples | ||||
|  | ||||
| The atk-adaptor in the dbus at-spi was renamed to atk-bridge due | ||||
| some apps hardcoding the name. So right now the only difference | ||||
| is the final directory. | ||||
|  | ||||
| So the option was removed, and atk-bridge-dir added. This also allows | ||||
| to use the system atk-bridge or the compiled in any developing environment, | ||||
| so it is really more flexible. | ||||
|  | ||||
| See the README (updated with this commit) for more information. | ||||
|  | ||||
| 2010-02-19 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Added .gitignore file | ||||
|  | ||||
|  | ||||
| 2010-02-19 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Release 1.1.1 | ||||
|  | ||||
|  | ||||
| 2010-02-19 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Using clutter_threads_idle_add instead of the gdk one | ||||
|  | ||||
| The idea is being as less gdk dependent as possible. Right now | ||||
| it is inviable to remove the dependency (gailutil and so on) but | ||||
| hypothetically, the ideal is remove this dependency in the future, | ||||
| and being "clutter pure". | ||||
|  | ||||
| 2010-02-15 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Check if the state is defunct on cally_text_get_name | ||||
|  | ||||
| Check if the state is defunct on cally_text_get_name, in order | ||||
| to avoid warnings cally clutter_text_get_text when the clutter | ||||
| object is NULL | ||||
|  | ||||
| 2010-01-26 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Update on configure.ac after autoupdate call | ||||
|  | ||||
|  | ||||
| 2010-02-02 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Try to apply the key modifiers to event->keyval like GDK does | ||||
|  | ||||
| ClutterKeyEvent defines the keyval without taking into account the | ||||
| modifiers. GDK defines this keyval taking into account the modifiers. | ||||
|  | ||||
| AtkKeyEventStruct expects the keyval in a GDK fashion, so a | ||||
| translation is required. | ||||
|  | ||||
| This patch tries to do that using using | ||||
| gdk_keymap_translate_keyboard_state. | ||||
|  | ||||
| This functions only works correctly if gtk has been initialized, so | ||||
| the fallback is create the AtkKeyEventStruct with the keyval | ||||
| provided by Clutter. | ||||
|  | ||||
| More information: | ||||
| http://library.gnome.org/devel/atk/stable/AtkUtil.html#AtkKeyEventStruct | ||||
| http://bugzilla.openedhand.com/show_bug.cgi?id=1961 | ||||
|  | ||||
| 2010-02-02 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Filling AtkKeyEventStruct->string used on the atk key event listeners | ||||
|  | ||||
| Finally we use directly gdk_keyval_name. Not the ideal solution, but works, | ||||
| and more important, it avoids to reimplement this issue on clutter or cally. | ||||
|  | ||||
| More information on Bug 1952 | ||||
|  | ||||
| Fixes http://bugzilla.openedhand.com/show_bug.cgi?id=1952 | ||||
|  | ||||
| 2010-01-22 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Added AM_PROG_CC_C_O option to avoid a warning running configure | ||||
|  | ||||
|  | ||||
| 2010-01-22 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Fix clutter version required on the pc files | ||||
|  | ||||
|  | ||||
| 2010-01-22 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Check on configure time if any x11 clutter backend is in use | ||||
|  | ||||
| It uses AC_CHECK_LIB in order to check if x11 backend is in use. | ||||
| It also modifies cally-actor in order to use the information | ||||
| retrieved. | ||||
|  | ||||
| So now cally has a minimum multi-backend support. It only manages | ||||
| a x11 (glx or eglx) backend, but at least, it checks it, so you | ||||
| can compile cally without this backend. It probably will not work | ||||
| properly, but at least you can compile and execute it. | ||||
|  | ||||
| Solves http://bugzilla.openedhand.com/show_bug.cgi?id=1736 | ||||
|  | ||||
| 2010-01-21 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Fix the perspective problems computing the on-screen extensions | ||||
|  | ||||
| Use clutter_actor_get_abs_allocation_vertices and | ||||
| clutter_actor_get_transformed_size to get the real on-screen | ||||
| position and size, instead of compute that using the geometry | ||||
| and the anchor point. | ||||
|  | ||||
| It also update cally-atkcomponent-example, adding a actor inside | ||||
| a nested ClutterGroup hierarchy. | ||||
|  | ||||
| Fixes: http://bugzilla.openedhand.com/show_bug.cgi?id=1731 | ||||
|  | ||||
| 2010-01-13 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Added extra button on cally-atkeditabletext-example | ||||
|  | ||||
| Added a button to print the current cursor position, and also | ||||
| extend the size of the buttons | ||||
|  | ||||
| 2010-01-12 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Remove superfluous g_print on CallyStage | ||||
|  | ||||
|  | ||||
| 2009-12-03 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Use clutter_stage_manager_peek_stages to avoid a leak | ||||
|  | ||||
|  | ||||
| 2009-12-03 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Added ATK_STATE_SELECTABLE_TEXT management | ||||
|  | ||||
|  | ||||
| 2009-11-26 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Manage properly ATK_STATE_ACTIVE on CallyStage | ||||
|  | ||||
| * cally/cally-stage.c | ||||
| Added private struct | ||||
| (cally_stage_class_init),(cally_stage_init),(cally_stage_real_initialize): | ||||
| Initialization stuff | ||||
| (cally_stage_activate_cb) | ||||
| (cally_stage_deactivate_cb): new ClutterStage signal callbacks, change | ||||
| the internal value of active, and notify the atk state change | ||||
| (cally_stage_ref_state_set): manage ATK_STATE_ACTIVATE | ||||
| * examples/cally-atktext-example2.c | ||||
| If possible, creates two stage, in order to test ATK_STATE_ACTIVATE | ||||
|  | ||||
| 2009-11-24 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Focused state change and focused object notification | ||||
|  | ||||
| * cally/cally-actor.h | ||||
| (focus_clutter): added virtual method for the focus management | ||||
| * cally/cally-actor.c | ||||
| (cally_actor_component_interface_init) | ||||
| (cally_actor_add_focus_handler) | ||||
| (cally_actor_remove_focus_handler): | ||||
| Implementation of the AtkComponent methods add_focus_handler and | ||||
| remove_focus_handler | ||||
| (cally_actor_focus_event): CallyActor specific focus handler, notify | ||||
| the state focused change | ||||
| (cally_actor_focus_clutter) | ||||
| (cally_actor_real_focus_clutter): | ||||
| Handlers for the ClutterActor "key-focus-in" and "key-focus-out" | ||||
| signals. Emit the signal AtkObject "focus_event" and set the focus | ||||
| object with atk_focus_tracker_notify. | ||||
| (cally_actor_initialize): | ||||
| Connect to the signals "key-focus-in" and "key-focus-out", use | ||||
| atk_component_add_focus_handler to add cally_actor_focus_event | ||||
|  | ||||
| Note: The focus management is more simplified that the gail one. The | ||||
| main reason is that the focus management in GTK is really more complex | ||||
| that the Clutter one. | ||||
|  | ||||
| 2009-11-24 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Modify cally-atkeditabletext-example.c to manage "activatable" status | ||||
|  | ||||
|  | ||||
| 2009-11-24 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Added "activate" action in ClutterText | ||||
|  | ||||
| * cally/cally-actor.h | ||||
| * cally/cally-actor.c | ||||
| cally_actor_add_action now returns the action id added. Documentation | ||||
| added in order to explain the return values and others. | ||||
|  | ||||
| * cally/cally-text.c | ||||
| Added action "activate". This action is only available if the ClutterText is | ||||
| activatable, so the "activatable" property is tracked in the notify | ||||
|  | ||||
| 2009-11-20 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Signal event emission | ||||
|  | ||||
| Emits the signals "text_selection_changed", "text_caret_moved", | ||||
| "text_changed::insert", "text_changed::delete", and notify the | ||||
| ATK_STATE_EDITABLE state change. | ||||
|  | ||||
| It also adds the ATK_STATE_EDITABLE in the ref_state_set, includes a | ||||
| finalize to clean the new private data used, and move part of the | ||||
| initialization from the _init to the _real_initialization. | ||||
|  | ||||
| 2009-12-03 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Remove the ATK_STATE_DEFUNCT emission | ||||
|  | ||||
| Remove the ATK_STATE_DEFUNCT emission, as this is already made by | ||||
| AtkGObjectAccessible. | ||||
|  | ||||
| It also removes the clutter actor from the private structure, as we | ||||
| can use the AtkGObjectAccessible API to obtain it. This makes the code | ||||
| more coherent, with respect of the rest of the Cally classes | ||||
| implementation. | ||||
|  | ||||
| 2009-11-26 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Remove ; from the CALLY_GET_CLUTTER_ACTOR macro | ||||
|  | ||||
|  | ||||
| 2009-11-25 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| TODO cleanup and more implementation notes | ||||
|  | ||||
| * TODO: removed the data that we have in the bugzilla or in the implementation | ||||
|   notes on the cally source | ||||
| * cally/cally-actor.c: complete implementations notes | ||||
| * cally/Makefile.am: add a comment related to the public headers, and include | ||||
|   Makefile.in in the MAINTAINERCLEANFILES | ||||
|  | ||||
| 2009-11-13 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Adding new tips on CODING_STYLE | ||||
|  | ||||
|  | ||||
| 2009-11-09 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| AtkEditableText implementation on CallyText | ||||
|  | ||||
| * examples/Makefile.am | ||||
| * examples/cally-atkeditabletext-example.c: New example added | ||||
| * cally/cally-text.c | ||||
|  | ||||
| Interface AtkEditableText implemented, except some methods: | ||||
|   * Missing ClipBoard feature on Clutter: | ||||
|       paste_text | ||||
|       copy_text | ||||
|       cut_text | ||||
|   * Missing a equivalent GtkTextTag on Clutter (so the possibility to | ||||
|     set run attributes in a range): | ||||
|        set_run_attributes | ||||
|  | ||||
| Fixes bug CB#1734 | ||||
|  | ||||
| 2009-11-03 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Removed DG_DISABLE_CHECKS and DG_DISABLE_CAST_CHECKS from CFLAGS | ||||
|  | ||||
| * configure.ac: Removed DG_DISABLE_CHECKS and DG_DISABLE_CAST_CHECKS | ||||
|   from the common CFLAGS options | ||||
| * cally/cally-actor.c: fixed cast errors on some return values, not | ||||
|   detected previously because of the use of relaxed compilation | ||||
|   options | ||||
|  | ||||
| Problem detected by Mario Sánchez Prada <msanchez@igalia.com> | ||||
|  | ||||
| 2009-10-28 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Support for multiple stages | ||||
|  | ||||
| * cally-root.c | ||||
| * cally-stage.c | ||||
| * cally-util.c | ||||
| Implemented the support for multiple stages, by tracking the signals | ||||
| stage-added and stage-removed of the ClutterStageManager. | ||||
|  | ||||
| In the same way CallyRoot has implement properly the atk_object_initialize, | ||||
| and in general now is more tied to ClutterStageManager (CallyRoot is now | ||||
| the a11y object of ClutterStageManager), but factory not required anyway, | ||||
| as it is instanced on the CallyUtil atk_get_root | ||||
|  | ||||
| Fixes: CB#1754 (Missing multi-stage support) | ||||
|  | ||||
| 2009-10-27 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Implemented atk_[add/remove]_key_event_listener on CallyUtil | ||||
|  | ||||
| * cally/cally-util.c: | ||||
|   Implemented atk_[add/remove]_key_event_listener | ||||
| * examples/cally-atktext-example2.c: | ||||
|   Modified in order to install and remove key event listeners, | ||||
|   for testing purposes | ||||
|  | ||||
| Fixes CB#1852 (AtkUtil implementation misses | ||||
| atk_[add/remove]_key_event_listener) | ||||
|  | ||||
| 2009-10-21 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Implemented atk-[add/remove]-global-event-listener on CallyUtil | ||||
|  | ||||
|  * cally/cally-util.c: | ||||
|    Implemented atk-[add/remove]-global-event-listener on CallyUtil | ||||
|  * examples/Makefile.am | ||||
|  * examples/cally-atktext-example2.c | ||||
|    New example in order to test easier the event emission on focus | ||||
|    change (not working right now) | ||||
|  | ||||
| 2009-10-12 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Add --with-dbus option executing the examples | ||||
|  | ||||
| The replacement for atk-bridge on at-spi-dbus has a different name | ||||
| (atk-adaptor), and it has not defined the method gnome_accessibility_init. | ||||
| The --with-dbus option allow to load the correct library and use the | ||||
| correct hook method if you are using at-spi-dbus. | ||||
|  | ||||
| Anyway, take into account that this is just an example, and in a final | ||||
| environment, this should be made in a more general way. | ||||
|  | ||||
| More information: CB#1738, CB#1737 | ||||
|  | ||||
| 2009-09-25 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Symplifying shave support. | ||||
|  | ||||
|  | ||||
| 2009-09-25 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Cleanup on the compilation and installation process | ||||
|  | ||||
| * cally/Makefile.am: | ||||
|   Added libcallydir and libcally_HEADERS in order to publish all cally | ||||
|   headers, as the current policy is use the cally headers as public. | ||||
| * configure.ac: | ||||
|   Change API_VERSION_MAJOR for CALLY_API_VERSION, as was the real | ||||
|   meaning, and define CALLY_VERSION. | ||||
|   Change CALLY_OBJ_CFLAGS and CALLY_OBJ_LIBS, used to compile the | ||||
|   tests, as was not required to compile against the cally module (the | ||||
|   example only required to compile against Clutter, as the cally | ||||
|   module was just a module loaded by GModule). | ||||
|   Support for Shave. | ||||
|  | ||||
| 2009-07-31 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Be able to run the examples without installing Cally | ||||
|  | ||||
| Before that, the examples searched the cally module from the final installed | ||||
| directory. This means that you should install the library to use the examples. | ||||
| On development this is not desirable. Now it is loaded from ../cally/.libs | ||||
|  | ||||
| This is a little hackish, but more useful, and in the end, it is just a example. | ||||
| Probably a best option could be configure that on the command line. | ||||
|    $ ./example --cally-dir="mydir" | ||||
|  | ||||
| But just a nitpick. | ||||
|  | ||||
| 2009-07-29 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Upgrade to cally-1.0, using clutter-1.0 | ||||
|  | ||||
| * NEWS | ||||
| * TODO: removed several items, waiting to be moved to the bugzilla | ||||
| * configure.ac | ||||
| * examples/cally-examples-util.c | ||||
|  | ||||
| 2009-07-27 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Fixed return value of cally_actor_get_index_in_parent | ||||
|  | ||||
| Bug and solutiond pointed by Gerd Kohlberger | ||||
|  | ||||
| 2009-06-30 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Added the implementation of most AtkText methods for CluttetText (CallyText) | ||||
|  | ||||
| It remains some methods: | ||||
|   get_default_attributes | ||||
|   get_character_extents | ||||
|   get_offset_at_point | ||||
|  | ||||
| The current gail implementation delegate on gailmisc, but this is tied to | ||||
| GtkWidget so an equivalent functionality would be implemented (something like | ||||
| callymisc), and in the case of get_character_extents, not sure about the layout | ||||
| position (see gtk_entry_get_layout_offsets). | ||||
|  | ||||
| I think that worth manage this in a different commit. | ||||
|  | ||||
| In the same way is still missing AtkEditableText support. | ||||
|  | ||||
| 2009-07-07 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Added CALLY_GET_CLUTTER_ACTOR macro | ||||
|  | ||||
| This macro was created to simplify how do you get the clutter actor object | ||||
| related to the cally object. On CallyActor a private attributte maintains it | ||||
| (for convenience, as it is heavily used) but outside, atkgobject methods can | ||||
| be used. Note that there is a possibility on the future to change it. Two | ||||
| options: | ||||
|   * Add a public method to get the clutter object | ||||
|   * Use this method on CallyActor too | ||||
|  | ||||
| This macro simplifies this: | ||||
|  | ||||
| CLUTTER_ACTOR (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (cally_object))) | ||||
|  | ||||
| 2009-06-24 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Renamed examples/cally-util.[ch] to examples/cally-examples-util.[ch] | ||||
|  | ||||
| Renamed examples/cally-util.[ch] to examples/cally-examples-util.[ch] to avoid | ||||
| confusion with cally/cally-util.[ch], implementation of the AtkUtil interface | ||||
|  | ||||
| 2009-06-23 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Adding examples directory | ||||
|  | ||||
| * NEWS: Updates | ||||
| * configure.ac | ||||
| * Makefile.am | ||||
| * cally/Makefile.am | ||||
| * examples/Makefile.am: New | ||||
| * examples/cally-util.[ch]: New | ||||
| * examples/example1.c: New | ||||
| Added a directory in order to put examples. In this way we don't require any | ||||
| external clutter app to make the basic a11y functionality checks. At this | ||||
| moment only an example was added, but all the compiling structure is working. | ||||
| By default the examples are not compiled, use "--enable-examples" on configure | ||||
| time in order to enable their compilation. | ||||
|  | ||||
| This basic example basically shows several objects, with different depth, in | ||||
| order to check that AtkComponent returns the correct screen position. | ||||
|  | ||||
| Other minor changes done on the building infrastructure. | ||||
|  | ||||
| 2009-06-23 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Fix clutter version required | ||||
|  | ||||
|  | ||||
| 2009-06-23 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Solve a problem calling clutter_actor_get_anchor_point | ||||
|  | ||||
| * cally/cally-actor.c: | ||||
| (_get_actor_extents): use gfloat instead of gint, as now this clutter_actor_get_anchor_point | ||||
| use floats | ||||
|  | ||||
| 2009-06-11 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Minor fixes | ||||
|  | ||||
|   * Update TODO | ||||
|   * Fix .pc files, to use clutter-0.9 version | ||||
|  | ||||
| 2009-05-20 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Library renamed from cail to cally | ||||
|  | ||||
|  | ||||
| 2009-05-08 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Removed cail-clone-texture.h from cail.h | ||||
|  | ||||
| * cail/cail.h: Removed reference to cail-clone-texture.h | ||||
|  | ||||
| 2009-05-08 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Upgrade to cail-0.9, using clutter-0.9, first compilable version | ||||
|  | ||||
| * NEWS: new file with the information of the releases | ||||
| * TODO: updated | ||||
| * configure.ac: updated clutter version to compile against | ||||
| * cail/cail-clone-texture.[ch]: Removed as ClutterCloneTexture was removed on Clutter 0.9.0 | ||||
| * cail/cail-label.[ch]: Removed as ClutterLabel was removed on Clutter 0.9.0 | ||||
| * cail/Makefile.am: updated due the source files removed | ||||
| * cail/cail-actor.c: removed include to <clutter/clutter-actor.h> | ||||
| * cail/cail.c: removed the factories for CailLabel and CailCloneTexture | ||||
|  | ||||
| 2009-05-07 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Reflect change on the version number policy | ||||
|  | ||||
| * README: correct some typos and explain that the cail version number | ||||
| is tied to the clutter version number and how | ||||
| * configure.ac | ||||
| Set the version number to 0.8.0 | ||||
|  | ||||
| 2009-05-07 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Edit the ChangeLog file, to show that now we are using git | ||||
|  | ||||
| * ChangeLog.SVN: new file, with the ChangeLog used while cail was | ||||
| using a Subversion repository | ||||
| * ChangeLog: now is empty, and only maintains a reference to use git log | ||||
|  | ||||
| 2009-04-29 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Coding style review | ||||
|  | ||||
| * CODING_STYLE | ||||
| * cail/Makefile.am | ||||
| * cail/cail-actor-private.[ch] | ||||
| * cail/cail-actor.h | ||||
| * cail/cail-clone-texture.[ch] | ||||
| * cail/cail-group.[ch] | ||||
| * cail/cail-label.[ch] | ||||
| * cail/cail-rectangle.[ch] | ||||
| * cail/cail-root.[ch] | ||||
| * cail/cail-stage.[ch] | ||||
| * cail/cail-texture.[ch] | ||||
| * cail/cail-util.[ch] | ||||
| * cail/cail.c | ||||
|  | ||||
| 2009-04-28 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Coding style review: cail-actor.c | ||||
|  | ||||
|  | ||||
| 2009-04-21 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| 2009-04-21 Alejandro Pinheiro <apinheiro@igalia.com> | ||||
|  | ||||
| 	* TODO: updated TODO file | ||||
|  | ||||
| 2009-04-21 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| 2009-03-06 Alejandro Pinheiro <apinheiro@igalia.com> | ||||
|  | ||||
| 	* AUTHORS: update authors file to public release | ||||
|  | ||||
| 2009-03-06 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| 2009-03-06 Alejandro Pinheiro <apinheiro@igalia.com> | ||||
|  | ||||
| 	* debian/control | ||||
| 	Added cdbs dependency, renamed debugging package | ||||
| 	* debian/libcail-common-dbg.dirs: new file | ||||
| 	* debian/libcail-common.dirs | ||||
| 	* debian/libcail-common.install | ||||
| 	Minor changes | ||||
|  | ||||
| 2009-03-05 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| 2009-03-05 Alejandro Pinheiro <apinheiro@igalia.com> | ||||
|  | ||||
| 	* TODO | ||||
| 	Added TODO file, in order to list the remaining tasks. | ||||
|  | ||||
| 2009-03-05 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| 2009-03-05 Alejandro Pinheiro <apinheiro@igalia.com> | ||||
|  | ||||
| 	* configure.ac | ||||
| 	* cail/cail.c | ||||
| 	* cail/cail-util.c | ||||
| 	* Makefile.am | ||||
| 	Removed all the missing gtk related stuff | ||||
|  | ||||
| 2009-03-05 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| 2009-03-05 Alejandro Pinheiro <apinheiro@igalia.com> | ||||
|  | ||||
| 	* cail/cail-actor.c | ||||
| 	(_get_actor_extents): managing too the anchor point to compute the position | ||||
| 	(_get_top_level_origin): reimplemented using x11 functions, removed | ||||
| 	gtk/gdk related functions, and taking into account the relative position | ||||
| 	inside the parent (previous position calculation was wrong if a child | ||||
| 	was not a direct stage child) | ||||
| 	* cail/clutter-gtk/cail-clutter-embed.[ch] | ||||
| 	* cail/clutter-gtk/cail-gtk-factory.h | ||||
| 	Removed, in order to remove any gtk dependency | ||||
| 	* cail/debian/control: removed gtk dependency | ||||
|  | ||||
| 2009-03-03 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| 2009-03-03 Alejandro Pinheiro <apinheiro@igalia.com> | ||||
|  | ||||
| 	* cail/cail-actor-private.[ch]: new files to private utility functions | ||||
| 	(_cail_actor_pushable): new function, that checks if a cail actor is | ||||
| 	pushable by checking if the clutter actor related has a handler for | ||||
| 	a release event | ||||
| 	* cail/cail-texture.c | ||||
| 	* cail/cail-clone-texture.c | ||||
| 	* cail/cail-rectangle.c | ||||
| 	Use of new function _cail_actor_pushable | ||||
| 	* cail-actor.c: Added some documentation related to current implementation | ||||
| 	* cail-util.c: Code style review | ||||
|  | ||||
| 2009-03-02 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| 2009-03-02 Alejandro Pinheiro <apinheiro@igalia.com> | ||||
|  | ||||
| 	* cail/cail-label.[ch]: new | ||||
| 	* cail/cail.[ch] | ||||
| 	(cail_accessibility_module_init) | ||||
| 	* cail/Makefile.am | ||||
| 	Added CailLabel, a11y object for ClutterLabel | ||||
|  | ||||
| 2009-02-27 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| 2009-02-27 Alejandro Pinheiro <apinheiro@igalia.com> | ||||
|  | ||||
| 	* cail/cail-actor.c | ||||
| 	(cail_actor_real_remove_actor) | ||||
| 	Fixed a typo that causes a crash while removing the actor from a | ||||
| 	container | ||||
|  | ||||
| 2009-02-26 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| 2009-02-26 Alejandro Pinheiro <apinheiro@igalia.com> | ||||
|  | ||||
| 	* cail/cail-actor.c | ||||
| 	(cail_actor_remove_actor) | ||||
| 	(cail_actor_add_actor) | ||||
| 	Fixed a typo calling klass->add_actor and klass->remove_actor that causes | ||||
| 	a crash in some (container,actor) combinations | ||||
|  | ||||
| 	(cail_actor_real_add_actor) | ||||
| 	Additional parameter check | ||||
|  | ||||
| 2009-02-25 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| Missing cail-rectangle.[ch] files, according 2009-02-23 entry at Changelog | ||||
|  | ||||
|  | ||||
| 2009-02-23 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| 2009-02-23 Alejandro Pinheiro <apinheiro@igalia.com> | ||||
|  | ||||
| 	* cail/cail-rectangle.[ch] | ||||
| 	* cail/cail.[ch] | ||||
| 	* cail/Makefile.am | ||||
|  | ||||
| 	Added CailRectangle, a11y object for ClutterRectangle | ||||
|  | ||||
| 	* cail/cail-group.c | ||||
| 	* cail/cail-texture.c | ||||
| 	* cail/cail-stage.c | ||||
|  | ||||
| 	Avoid to add a empty private structure, to avoid the glib warning. Anyway | ||||
| 	the pointer to the private structure is still on the .h, to allow future | ||||
| 	add-on. | ||||
|  | ||||
| 2009-02-20 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| 2009-02-20 Alejandro Pinheiro <apinheiro@igalia.com> | ||||
|  | ||||
| 	* cail-actor.[ch] | ||||
| 	* cail-group.[ch] | ||||
|  | ||||
| 	Moved most of the ClutterContainer a11y support from cail-group to | ||||
| 	cail-actor, in order to generalize this support. | ||||
|  | ||||
| 	* cail-stage.[ch] | ||||
| 	* cail-util.[ch] | ||||
| 	Normalize the private structure to avoid future problems with missing | ||||
| 	gaps | ||||
|  | ||||
| 2009-02-20 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| 2009-02-20 Alejandro Pinheiro <apinheiro@igalia.com> | ||||
|  | ||||
| 	* cail/cail-actor.c | ||||
| 	(cail_actor_connect_actor_destroyed): connects to the clutter actor | ||||
| 	destroy signal | ||||
| 	(cail_actor_clutter_actor_destroyed): handler to the clutter actor | ||||
| 	destroy signal, update the priv->actor pointer and notify a state change | ||||
|  | ||||
| 	This change allows to be sure about the priv->actor correct value, so we | ||||
| 	can use directly priv->actor instead of atk_gobject_accessible_get_object | ||||
| 	in the next functions: | ||||
| 	(cail_actor_get_parent) | ||||
| 	(cail_actor_get_index_in_parent) | ||||
| 	(cail_actor_ref_state_set) | ||||
| 	(cail_actor_get_extents) | ||||
|  | ||||
| 2009-02-19 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| 2009-02-19 Alejandro Pinheiro <apinheiro@igalia.com> | ||||
|  | ||||
| 	* cail/cail-texture.[ch] | ||||
| 	* cail/cail-clone-texture.[ch] | ||||
| 	* cail/cail.[ch] | ||||
| 	* cail/Makefile.am | ||||
|  | ||||
| 	Added CailTexture and CailCloneTexture a11y objects for ClutterTexture | ||||
| 	and ClutterCloneTexture | ||||
|  | ||||
| 	* cail/cail-util.c | ||||
|  | ||||
| 	Added private structure | ||||
|  | ||||
| 2009-02-18 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| 2009-02-18 Alejandro Pinheiro <apinheiro@igalia.com> | ||||
|  | ||||
| 	* cail/cail-actor.c: | ||||
| 	(cail_actor_get_parent) | ||||
| 	Return the accessible object of the clutter actor if accessible_parent | ||||
| 	is not available. Previously it only took into account the these object | ||||
| 	as a possible parent to return (you can set it with atk_object_set_parent) | ||||
|  | ||||
| 2009-02-18 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| 2009-02-18 Alejandro Pinheiro <apinheiro@igalia.com> | ||||
|  | ||||
| 	* cail/cail-group.[ch]: code style review | ||||
| 	* cail/cail-actor.[ch]: implemented basic support for ClutterContainer | ||||
|  | ||||
| 2009-02-18 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| 2009-02-18 Alejandro Pinheiro <apinheiro@igalia.com> | ||||
|  | ||||
| 	* debian/control: updating dependencies | ||||
|  | ||||
| 2009-02-18 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| 2009-02-18 Alejandro Pinheiro <apinheiro@igalia.com> | ||||
|  | ||||
| 	* configure.ac: added additional compile flags | ||||
| 	* cail/cail-actor.[ch]: Reimplemented support for AtkAction interface | ||||
| 	* cail/cail-root.[ch]: code style review | ||||
|  | ||||
| 2009-02-16 Alejandro Pi<50>eiro <apinheiro@igalia.com> | ||||
|  | ||||
| 2009-02-16 Alejandro Pinheiro <apinheiro@igalia.com> | ||||
|  | ||||
| 	* First release. | ||||
| @@ -1,35 +0,0 @@ | ||||
| /* CALLY - The Clutter Accessibility Implementation Library | ||||
|  * | ||||
|  * Copyright (C) 2008 Igalia, S.L. | ||||
|  * | ||||
|  * Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com> | ||||
|  * | ||||
|  * Some parts are based on GailWidget from GAIL | ||||
|  * GAIL - The GNOME Accessibility Implementation Library | ||||
|  * Copyright 2001, 2002, 2003 Sun Microsystems 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/>. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "cally/cally-actor.h" | ||||
|  | ||||
| /* | ||||
|  * Auxiliary define, in order to get the clutter actor from the AtkObject using | ||||
|  * AtkGObject methods | ||||
|  * | ||||
|  */ | ||||
| #define CALLY_GET_CLUTTER_ACTOR(cally_object) \ | ||||
|   (CLUTTER_ACTOR (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (cally_object)))) | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,123 +0,0 @@ | ||||
| /* CALLY - The Clutter Accessibility Implementation Library | ||||
|  * | ||||
|  * Copyright (C) 2008 Igalia, S.L. | ||||
|  * | ||||
|  * Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com> | ||||
|  * | ||||
|  * Some parts are based on GailWidget from GAIL | ||||
|  * GAIL - The GNOME Accessibility Implementation Library | ||||
|  * Copyright 2001, 2002, 2003 Sun Microsystems 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/>. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <cally/cally.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include <atk/atk.h> | ||||
|  | ||||
| #include "clutter/clutter.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CALLY_TYPE_ACTOR            (cally_actor_get_type ()) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_DERIVABLE_TYPE (CallyActor, | ||||
|                           cally_actor, | ||||
|                           CALLY, | ||||
|                           ACTOR, | ||||
|                           AtkGObjectAccessible) | ||||
|  | ||||
| typedef struct _CallyActor           CallyActor; | ||||
| typedef struct _CallyActorClass      CallyActorClass; | ||||
| typedef struct _CallyActorPrivate    CallyActorPrivate; | ||||
|  | ||||
| /** | ||||
|  * CallyActionFunc: | ||||
|  * @cally_actor: a #CallyActor | ||||
|  * | ||||
|  * Action function, to be used on #AtkAction implementations as a individual | ||||
|  * action | ||||
|  */ | ||||
| typedef void (* CallyActionFunc) (CallyActor *cally_actor); | ||||
|  | ||||
| /** | ||||
|  * CallyActionCallback: | ||||
|  * @cally_actor: a #CallyActor | ||||
|  * @user_data: user data passed to the function | ||||
|  * | ||||
|  * Action function, to be used on #AtkAction implementations as | ||||
|  * an individual action. | ||||
|  * | ||||
|  * Unlike #CallyActionFunc, this function uses the @user_data | ||||
|  * argument passed to [method@Actor.add_action_full]. | ||||
|  */ | ||||
| typedef void (* CallyActionCallback) (CallyActor *cally_actor, | ||||
|                                       gpointer    user_data); | ||||
|  | ||||
| /** | ||||
|  * CallyActorClass: | ||||
|  * @notify_clutter: Signal handler for notify signal on Clutter actor | ||||
|  * @add_actor: Signal handler for child-added signal on Clutter actor | ||||
|  * @remove_actor: Signal handler for child-removed signal on Clutter actor | ||||
|  */ | ||||
| struct _CallyActorClass | ||||
| { | ||||
|   /*< private >*/ | ||||
|   AtkGObjectAccessibleClass parent_class; | ||||
|  | ||||
|   /*< public >*/ | ||||
|   void     (*notify_clutter) (GObject    *object, | ||||
|                               GParamSpec *pspec); | ||||
|  | ||||
|   gint     (*add_actor)      (ClutterActor *container, | ||||
|                               ClutterActor *actor, | ||||
|                               gpointer      data); | ||||
|  | ||||
|   gint     (*remove_actor)   (ClutterActor *container, | ||||
|                               ClutterActor *actor, | ||||
|                               gpointer      data); | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| AtkObject* cally_actor_new                   (ClutterActor        *actor); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| guint      cally_actor_add_action            (CallyActor          *cally_actor, | ||||
|                                               const gchar         *action_name, | ||||
|                                               const gchar         *action_description, | ||||
|                                               const gchar         *action_keybinding, | ||||
|                                               CallyActionFunc      action_func); | ||||
| CLUTTER_EXPORT | ||||
| guint      cally_actor_add_action_full       (CallyActor          *cally_actor, | ||||
|                                               const gchar         *action_name, | ||||
|                                               const gchar         *action_description, | ||||
|                                               const gchar         *action_keybinding, | ||||
|                                               CallyActionCallback  callback, | ||||
|                                               gpointer             user_data, | ||||
|                                               GDestroyNotify       notify); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| gboolean   cally_actor_remove_action         (CallyActor          *cally_actor, | ||||
|                                               gint                 action_id); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| gboolean   cally_actor_remove_action_by_name (CallyActor          *cally_actor, | ||||
|                                               const gchar         *action_name); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,127 +0,0 @@ | ||||
| /* CALLY - The Clutter Accessibility Implementation Library | ||||
|  * | ||||
|  * Copyright (C) 2010 Igalia, S.L. | ||||
|  * | ||||
|  * Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com> | ||||
|  * | ||||
|  * 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/>. | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * CallyClone: | ||||
|  *  | ||||
|  * Implementation of the ATK interfaces for a #ClutterClone | ||||
|  * | ||||
|  * #CallyClone implements the required ATK interfaces of [class@Clutter.Clone] | ||||
|  * | ||||
|  * In particular it sets a proper role for the clone, as just a image, | ||||
|  * as it is the sanest and simplest approach. | ||||
|  */ | ||||
|  | ||||
| /* Design rationale for CallyClone: | ||||
|  * | ||||
|  * In the old times, it was just ClutterCloneTexture. So, from a a11y POV | ||||
|  * CallyCloneTexture was just another image, like ClutterTexture, and if | ||||
|  * it was a clone was irrelevant. So on cally-0.8, CallyCloneTexture | ||||
|  * expose a object with role ATK_ROLE_IMAGE. But now, ClutterClone is more | ||||
|  * general. You can clone any object, including groups, and made things | ||||
|  * like have one text entry, and a clone with different properties in the | ||||
|  * same window, updated both at once. | ||||
|  * | ||||
|  * The question is if the idea is have a ClutterClone as a "first-class" | ||||
|  * citizen inside the stage hierarchy (full clone), or it is just supposed | ||||
|  * to be a mirror image of the original object. | ||||
|  * | ||||
|  * In the case of the a11y POV this would mean that if the text changes on | ||||
|  * the source, the clone should emit as well the text-changing signals. | ||||
|  * | ||||
|  * As ClutterClone smartly just paint the same object with different | ||||
|  * parameters, this would mean that it should be the cally object the one | ||||
|  * that should replicate the source clutter hierarchy to do that, | ||||
|  * something that just sound crazy. | ||||
|  * | ||||
|  * Taking into account that: | ||||
|  * | ||||
|  * - ClutterClone doesn't re-emit mirrored signals from the source  | ||||
|  *   I think that likely the answer would be "yes, it is just a | ||||
|  *   mirrored image, not a real full clone". | ||||
|  * | ||||
|  * - You can't interact directly with the clone (ie: focus, and so on). | ||||
|  *   Its basic usage (right now) is clone textures. | ||||
|  * | ||||
|  * Any other solution could be overwhelming. | ||||
|  * | ||||
|  * I think that the final solution would be that ClutterClone from the | ||||
|  * a11y POV should still be managed as a image (with the proper properties, | ||||
|  * position, size, etc.). | ||||
|  */ | ||||
| #include "config.h" | ||||
|  | ||||
| #include "cally/cally-clone.h" | ||||
| #include "cally/cally-actor-private.h" | ||||
|  | ||||
| /* AtkObject */ | ||||
| static void                  cally_clone_real_initialize (AtkObject *obj, | ||||
|                                                           gpointer   data); | ||||
|  | ||||
| G_DEFINE_TYPE (CallyClone, cally_clone, CALLY_TYPE_ACTOR) | ||||
|  | ||||
| static void | ||||
| cally_clone_class_init (CallyCloneClass *klass) | ||||
| { | ||||
| /*   GObjectClass   *gobject_class = G_OBJECT_CLASS (klass); */ | ||||
|   AtkObjectClass *class         = ATK_OBJECT_CLASS (klass); | ||||
|  | ||||
|   class->initialize      = cally_clone_real_initialize; | ||||
| } | ||||
|  | ||||
| static void | ||||
| cally_clone_init (CallyClone *clone) | ||||
| { | ||||
|   /* nothing to do yet */ | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * cally_clone_new: | ||||
|  * @actor: a #ClutterActor | ||||
|  * | ||||
|  * Creates a new #CallyClone for the given @actor. @actor must be a | ||||
|  * [class@Clutter.Clone]. | ||||
|  * | ||||
|  * Return value: the newly created #AtkObject | ||||
|  */ | ||||
| AtkObject* | ||||
| cally_clone_new (ClutterActor *actor) | ||||
| { | ||||
|   GObject   *object     = NULL; | ||||
|   AtkObject *accessible = NULL; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_CLONE (actor), NULL); | ||||
|  | ||||
|   object = g_object_new (CALLY_TYPE_CLONE, NULL); | ||||
|  | ||||
|   accessible = ATK_OBJECT (object); | ||||
|   atk_object_initialize (accessible, actor); | ||||
|  | ||||
|   return accessible; | ||||
| } | ||||
|  | ||||
| static void | ||||
| cally_clone_real_initialize (AtkObject *obj, | ||||
|                               gpointer   data) | ||||
| { | ||||
|   ATK_OBJECT_CLASS (cally_clone_parent_class)->initialize (obj, data); | ||||
|  | ||||
|   obj->role = ATK_ROLE_IMAGE; | ||||
| } | ||||
| @@ -1,53 +0,0 @@ | ||||
| /* CALLY - The Clutter Accessibility Implementation Library | ||||
|  * | ||||
|  * Copyright (C) 2010 Igalia, S.L. | ||||
|  * | ||||
|  * Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com> | ||||
|  * | ||||
|  * 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/>. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <cally/cally.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include "clutter/clutter.h" | ||||
| #include "cally/cally-actor.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CALLY_TYPE_CLONE            (cally_clone_get_type ()) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_DERIVABLE_TYPE (CallyClone, | ||||
|                           cally_clone, | ||||
|                           CALLY, | ||||
|                           CLONE, | ||||
|                           CallyActor) | ||||
|  | ||||
| typedef struct _CallyClone CallyClone; | ||||
| typedef struct _CallyCloneClass CallyCloneClass; | ||||
|  | ||||
| struct _CallyCloneClass | ||||
| { | ||||
|   /*< private >*/ | ||||
|   CallyActorClass parent_class; | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| AtkObject *cally_clone_new      (ClutterActor *actor); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,108 +0,0 @@ | ||||
| /* CALLY - The Clutter Accessibility Implementation Library | ||||
|  * | ||||
|  * Copyright (C) 2008 Igalia, S.L. | ||||
|  * | ||||
|  * Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com> | ||||
|  * | ||||
|  * Based on gailfactory.h from GAIL | ||||
|  * Copyright 2001, 2002, 2003 Sun Microsystems 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/>. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <glib-object.h> | ||||
| #include <atk/atkobject.h> | ||||
|  | ||||
| /** | ||||
|  * CALLY_ACCESSIBLE_FACTORY: | ||||
|  * @type: GType of the accessible which is created by the factory | ||||
|  * @type_as_function: prefix of the accessible object methods | ||||
|  * @opt_create_accessible: method to instantiate the accessibility object | ||||
|  * | ||||
|  * Defines a new #AtkObjectFactory factory to create accessible | ||||
|  * objects of a specific GType. It defines the factory GType and also | ||||
|  * overrides the proper #AtkObjectFactory methods. | ||||
|  * | ||||
|  * It assumes that the accessibility object provides a | ||||
|  * @opt_create_accessible method in order to create the accessibility | ||||
|  * object. It returns a @type GType object. | ||||
|  */ | ||||
| #define CALLY_ACCESSIBLE_FACTORY(type, type_as_function, opt_create_accessible)	\ | ||||
| 										\ | ||||
| static GType									\ | ||||
| type_as_function ## _factory_get_accessible_type (void)				\ | ||||
| {										\ | ||||
|   return type;									\ | ||||
| }										\ | ||||
| 										\ | ||||
| static AtkObject*								\ | ||||
| type_as_function ## _factory_create_accessible (GObject *obj)			\ | ||||
| {										\ | ||||
|   ClutterActor *actor;								\ | ||||
|   AtkObject *accessible;							\ | ||||
| 										\ | ||||
|   g_return_val_if_fail (CLUTTER_ACTOR (obj), NULL);				\ | ||||
| 										\ | ||||
|   actor = CLUTTER_ACTOR (obj);                                                  \ | ||||
| 										\ | ||||
|   accessible = opt_create_accessible (actor);					\ | ||||
| 										\ | ||||
|   return accessible;								\ | ||||
| }										\ | ||||
| 										\ | ||||
| static void									\ | ||||
| type_as_function ## _factory_class_init (AtkObjectFactoryClass *klass)		\ | ||||
| {										\ | ||||
|   klass->create_accessible   = type_as_function ## _factory_create_accessible;	\ | ||||
|   klass->get_accessible_type = type_as_function ## _factory_get_accessible_type;\ | ||||
| }										\ | ||||
| 										\ | ||||
| static GType									\ | ||||
| type_as_function ## _factory_get_type (void)					\ | ||||
| {										\ | ||||
|   static GType t = 0;								\ | ||||
| 										\ | ||||
|   if (!t)									\ | ||||
|   {										\ | ||||
|     char *name;									\ | ||||
|     static const GTypeInfo tinfo =						\ | ||||
|     {										\ | ||||
|       sizeof (AtkObjectFactoryClass),					\ | ||||
|       NULL, NULL, (GClassInitFunc) type_as_function ## _factory_class_init,			\ | ||||
|       NULL, NULL, sizeof (AtkObjectFactory), 0, NULL, NULL			\ | ||||
|     };										\ | ||||
| 										\ | ||||
|     name = g_strconcat (g_type_name (type), "Factory", NULL);			\ | ||||
|     t = g_type_register_static (						\ | ||||
| 	    ATK_TYPE_OBJECT_FACTORY, name, &tinfo, 0);				\ | ||||
|     g_free (name);								\ | ||||
|   }										\ | ||||
| 										\ | ||||
|   return t;									\ | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * CALLY_ACTOR_SET_FACTORY: | ||||
|  * @widget_type: GType of the clutter actor | ||||
|  * @type_as_function: prefix of the accessible object methods | ||||
|  * | ||||
|  * Sets the #AtkObjectFactory to be used in order to instantiate | ||||
|  * accessibility objects for the actor which GType is @widget_type. | ||||
|  */ | ||||
| #define CALLY_ACTOR_SET_FACTORY(widget_type, type_as_function)			\ | ||||
| 	atk_registry_set_factory_type (atk_get_default_registry (),		\ | ||||
| 				       widget_type,				\ | ||||
| 				       type_as_function ## _factory_get_type ()) | ||||
| @@ -1,41 +0,0 @@ | ||||
| /* CALLY - The Clutter Accessibility Implementation Library | ||||
|  * | ||||
|  * Copyright (C) 2008 Igalia, S.L. | ||||
|  * | ||||
|  * Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com> | ||||
|  * | ||||
|  * Some parts are based on GailWidget from GAIL | ||||
|  * GAIL - The GNOME Accessibility Implementation Library | ||||
|  * Copyright 2001, 2002, 2003 Sun Microsystems 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/>. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <cally/cally.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include <glib.h> | ||||
| #include <atk/atk.h> | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| gboolean cally_get_cally_initialized (void); | ||||
| CLUTTER_EXPORT | ||||
| gboolean cally_accessibility_init    (void); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,294 +0,0 @@ | ||||
| /* CALLY - The Clutter Accessibility Implementation Library | ||||
|  * | ||||
|  * Copyright (C) 2008 Igalia, S.L. | ||||
|  * | ||||
|  * Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com> | ||||
|  * | ||||
|  * 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/>. | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * CallyRoot: | ||||
|  *  | ||||
|  * Root object for the Cally toolkit | ||||
|  * | ||||
|  * #CallyRoot is the root object of the accessibility tree-like | ||||
|  * hierarchy, exposing the application level. | ||||
|  * | ||||
|  * Somewhat equivalent to #GailTopLevel. We consider that this class | ||||
|  * expose the a11y information of the [class@Clutter.StageManager], as the | ||||
|  * children of this object are the different [class@Clutter.Stage] managed (so | ||||
|  * the [class@GObject.Object] used in the [method@Atk.Object.initialize] is the | ||||
|  * [class@Clutter.StageManager]). | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "cally/cally-root.h" | ||||
|  | ||||
| #include "clutter/clutter-actor.h" | ||||
| #include "clutter/clutter-stage-private.h" | ||||
| #include "clutter/clutter-stage-manager.h" | ||||
|  | ||||
|  | ||||
| /* GObject */ | ||||
| static void cally_root_finalize   (GObject *object); | ||||
|  | ||||
| /* AtkObject.h */ | ||||
| static void             cally_root_initialize           (AtkObject *accessible, | ||||
|                                                          gpointer   data); | ||||
| static gint             cally_root_get_n_children       (AtkObject *obj); | ||||
| static AtkObject *      cally_root_ref_child            (AtkObject *obj, | ||||
|                                                          gint i); | ||||
| static AtkObject *      cally_root_get_parent           (AtkObject *obj); | ||||
| static const char *     cally_root_get_name             (AtkObject *obj); | ||||
|  | ||||
| /* Private */ | ||||
| static void             cally_util_stage_added_cb       (ClutterStageManager *stage_manager, | ||||
|                                                          ClutterStage *stage, | ||||
|                                                          gpointer data); | ||||
| static void             cally_util_stage_removed_cb     (ClutterStageManager *stage_manager, | ||||
|                                                          ClutterStage *stage, | ||||
|                                                          gpointer data); | ||||
|  | ||||
| typedef struct _CallyRootPrivate | ||||
| { | ||||
| /* We save the CallyStage objects. Other option could save the stage | ||||
|  * list, and then just get the a11y object on the ref_child, etc. But | ||||
|  * the ref_child is more common that the init and the stage-add, | ||||
|  * stage-remove, so we avoid getting the accessible object | ||||
|  * constantly | ||||
|  */ | ||||
|   GSList *stage_list; | ||||
|  | ||||
|   /* signals id */ | ||||
|   gulong stage_added_id; | ||||
|   gulong stage_removed_id; | ||||
| } CallyRootPrivate; | ||||
|  | ||||
| G_DEFINE_TYPE_WITH_PRIVATE (CallyRoot, cally_root,  ATK_TYPE_GOBJECT_ACCESSIBLE) | ||||
|  | ||||
| static void | ||||
| cally_root_class_init (CallyRootClass *klass) | ||||
| { | ||||
|   GObjectClass *gobject_class = G_OBJECT_CLASS (klass); | ||||
|   AtkObjectClass *class = ATK_OBJECT_CLASS (klass); | ||||
|  | ||||
|   gobject_class->finalize = cally_root_finalize; | ||||
|  | ||||
|   /* AtkObject */ | ||||
|   class->get_n_children = cally_root_get_n_children; | ||||
|   class->ref_child = cally_root_ref_child; | ||||
|   class->get_parent = cally_root_get_parent; | ||||
|   class->initialize = cally_root_initialize; | ||||
|   class->get_name = cally_root_get_name; | ||||
| } | ||||
|  | ||||
| static void | ||||
| cally_root_init (CallyRoot *root) | ||||
| { | ||||
|   CallyRootPrivate *priv = cally_root_get_instance_private (root); | ||||
|  | ||||
|   priv->stage_list = NULL; | ||||
|   priv->stage_added_id = 0; | ||||
|   priv->stage_removed_id = 0; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * cally_root_new: | ||||
|  * | ||||
|  * Creates a new #CallyRoot object. | ||||
|  * | ||||
|  * Return value: the newly created #AtkObject | ||||
|  */ | ||||
| AtkObject* | ||||
| cally_root_new (void) | ||||
| { | ||||
|   GObject *object = NULL; | ||||
|   AtkObject *accessible = NULL; | ||||
|   ClutterStageManager *stage_manager = NULL; | ||||
|  | ||||
|   object = g_object_new (CALLY_TYPE_ROOT, NULL); | ||||
|  | ||||
|   accessible = ATK_OBJECT (object); | ||||
|   stage_manager = clutter_stage_manager_get_default (); | ||||
|  | ||||
|   atk_object_initialize (accessible, stage_manager); | ||||
|  | ||||
|   return accessible; | ||||
| } | ||||
|  | ||||
| static void | ||||
| cally_root_finalize (GObject *object) | ||||
| { | ||||
|   CallyRoot *root = CALLY_ROOT (object); | ||||
|   GObject *stage_manager = NULL; | ||||
|   CallyRootPrivate *priv; | ||||
|  | ||||
|   g_return_if_fail (CALLY_IS_ROOT (object)); | ||||
|  | ||||
|   priv = cally_root_get_instance_private (root); | ||||
|   if (priv->stage_list) | ||||
|     { | ||||
|       g_slist_free (priv->stage_list); | ||||
|       priv->stage_list = NULL; | ||||
|     } | ||||
|  | ||||
|   stage_manager = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (root)); | ||||
|  | ||||
|   g_clear_signal_handler (&priv->stage_added_id, stage_manager); | ||||
|  | ||||
|   g_clear_signal_handler (&priv->stage_removed_id, stage_manager); | ||||
|  | ||||
|   G_OBJECT_CLASS (cally_root_parent_class)->finalize (object); | ||||
| } | ||||
|  | ||||
| /* AtkObject.h */ | ||||
| static void | ||||
| cally_root_initialize (AtkObject              *accessible, | ||||
|                        gpointer                data) | ||||
| { | ||||
|   ClutterStageManager *stage_manager = NULL; | ||||
|   const GSList        *iter          = NULL; | ||||
|   const GSList        *stage_list    = NULL; | ||||
|   ClutterStage        *clutter_stage = NULL; | ||||
|   AtkObject           *cally_stage   = NULL; | ||||
|   CallyRoot *root = CALLY_ROOT (accessible); | ||||
|   CallyRootPrivate *priv = cally_root_get_instance_private (root); | ||||
|  | ||||
|  | ||||
|   accessible->role = ATK_ROLE_APPLICATION; | ||||
|   accessible->accessible_parent = NULL; | ||||
|  | ||||
|   /* children initialization */ | ||||
|   stage_manager = CLUTTER_STAGE_MANAGER (data); | ||||
|   stage_list = clutter_stage_manager_peek_stages (stage_manager); | ||||
|  | ||||
|   for (iter = stage_list; iter != NULL; iter = g_slist_next (iter)) | ||||
|     { | ||||
|       clutter_stage = CLUTTER_STAGE (iter->data); | ||||
|       cally_stage = clutter_actor_get_accessible (CLUTTER_ACTOR (clutter_stage)); | ||||
|  | ||||
|       atk_object_set_parent (cally_stage, ATK_OBJECT (root)); | ||||
|  | ||||
|       priv->stage_list = g_slist_append (priv->stage_list, cally_stage); | ||||
|     } | ||||
|  | ||||
|   priv->stage_added_id = | ||||
|     g_signal_connect (G_OBJECT (stage_manager), "stage-added", | ||||
|                       G_CALLBACK (cally_util_stage_added_cb), root); | ||||
|  | ||||
|   priv->stage_removed_id = | ||||
|     g_signal_connect (G_OBJECT (stage_manager), "stage-removed", | ||||
|                       G_CALLBACK (cally_util_stage_removed_cb), root); | ||||
|  | ||||
|   ATK_OBJECT_CLASS (cally_root_parent_class)->initialize (accessible, data); | ||||
| } | ||||
|  | ||||
|  | ||||
| static gint | ||||
| cally_root_get_n_children (AtkObject *obj) | ||||
| { | ||||
|   CallyRoot *root = CALLY_ROOT (obj); | ||||
|   CallyRootPrivate *priv = cally_root_get_instance_private (root); | ||||
|  | ||||
|   return g_slist_length (priv->stage_list); | ||||
| } | ||||
|  | ||||
| static AtkObject* | ||||
| cally_root_ref_child (AtkObject *obj, | ||||
|                       gint       i) | ||||
| { | ||||
|   CallyRoot *cally_root = CALLY_ROOT (obj); | ||||
|   CallyRootPrivate *priv = cally_root_get_instance_private (cally_root); | ||||
|   GSList *stage_list = NULL; | ||||
|   gint num = 0; | ||||
|   AtkObject *item = NULL; | ||||
|  | ||||
|   stage_list = priv->stage_list; | ||||
|   num = g_slist_length (stage_list); | ||||
|  | ||||
|   g_return_val_if_fail ((i < num)&&(i >= 0), NULL); | ||||
|  | ||||
|   item = g_slist_nth_data (stage_list, i); | ||||
|   if (!item) | ||||
|     { | ||||
|       return NULL; | ||||
|     } | ||||
|  | ||||
|   g_object_ref (item); | ||||
|  | ||||
|   return item; | ||||
| } | ||||
|  | ||||
| static AtkObject* | ||||
| cally_root_get_parent (AtkObject *obj) | ||||
| { | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| static const char * | ||||
| cally_root_get_name (AtkObject *obj) | ||||
| { | ||||
|   return g_get_prgname (); | ||||
| } | ||||
|  | ||||
| /* -------------------------------- PRIVATE --------------------------------- */ | ||||
|  | ||||
| static void | ||||
| cally_util_stage_added_cb (ClutterStageManager *stage_manager, | ||||
|                            ClutterStage        *stage, | ||||
|                            gpointer             data) | ||||
| { | ||||
|   CallyRoot *root = CALLY_ROOT (data); | ||||
|   AtkObject *cally_stage = NULL; | ||||
|   CallyRootPrivate *priv = cally_root_get_instance_private (root); | ||||
|  | ||||
|   gint index = -1; | ||||
|  | ||||
|   cally_stage = clutter_actor_get_accessible (CLUTTER_ACTOR (stage)); | ||||
|  | ||||
|   atk_object_set_parent (cally_stage, ATK_OBJECT (root)); | ||||
|  | ||||
|   priv->stage_list = g_slist_append (priv->stage_list, cally_stage); | ||||
|  | ||||
|   index = g_slist_index (priv->stage_list, cally_stage); | ||||
|   g_signal_emit_by_name (root, "children_changed::add", | ||||
|                          index, cally_stage, NULL); | ||||
|   g_signal_emit_by_name (cally_stage, "create", 0); | ||||
| } | ||||
|  | ||||
| static void | ||||
| cally_util_stage_removed_cb (ClutterStageManager *stage_manager, | ||||
|                              ClutterStage        *stage, | ||||
|                              gpointer             data) | ||||
| { | ||||
|   CallyRoot *root = CALLY_ROOT (data); | ||||
|   AtkObject *cally_stage = NULL; | ||||
|   CallyRootPrivate *priv | ||||
|     = cally_root_get_instance_private (root); | ||||
|   gint index = -1; | ||||
|  | ||||
|   cally_stage = clutter_actor_get_accessible (CLUTTER_ACTOR (stage)); | ||||
|  | ||||
|   index = g_slist_index (priv->stage_list, cally_stage); | ||||
|  | ||||
|   priv->stage_list = g_slist_remove (priv->stage_list, | ||||
|                                      cally_stage); | ||||
|  | ||||
|   index = g_slist_index (priv->stage_list, cally_stage); | ||||
|   g_signal_emit_by_name (root, "children_changed::remove", | ||||
|                          index, cally_stage, NULL); | ||||
|   g_signal_emit_by_name (cally_stage, "destroy", 0); | ||||
| } | ||||
| @@ -1,54 +0,0 @@ | ||||
| /* CALLY - The Clutter Accessibility Implementation Library | ||||
|  * | ||||
|  * Copyright (C) 2009 Igalia, S.L. | ||||
|  * | ||||
|  * Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com> | ||||
|  * | ||||
|  * 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/>. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <cally/cally.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include <atk/atk.h> | ||||
|  | ||||
| #include "clutter/clutter.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CALLY_TYPE_ROOT            (cally_root_get_type ()) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_DERIVABLE_TYPE (CallyRoot, | ||||
|                           cally_root, | ||||
|                           CALLY, | ||||
|                           ROOT, | ||||
|                           AtkGObjectAccessible) | ||||
|  | ||||
| typedef struct _CallyRoot CallyRoot; | ||||
| typedef struct _CallyRootClass CallyRootClass; | ||||
|  | ||||
| struct _CallyRootClass | ||||
| { | ||||
|   /*< private >*/ | ||||
|   AtkGObjectAccessibleClass parent_class; | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| AtkObject *cally_root_new      (void); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,266 +0,0 @@ | ||||
| /* CALLY - The Clutter Accessibility Implementation Library | ||||
|  * | ||||
|  * Copyright (C) 2008 Igalia, S.L. | ||||
|  * | ||||
|  * Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com> | ||||
|  * | ||||
|  * 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/>. | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * CallyStage: | ||||
|  *  | ||||
|  * Implementation of the ATK interfaces for a #ClutterStage | ||||
|  * | ||||
|  * #CallyStage implements the required ATK interfaces for [class@Clutter.Stage] | ||||
|  * | ||||
|  * Some implementation details: at this moment #CallyStage is used as | ||||
|  * the most similar Window object in this toolkit (ie: emitting window | ||||
|  * related signals), although the real purpose of [class@Clutter.Stage] is | ||||
|  * being a canvas. Anyway, this is required for applications using | ||||
|  * just clutter, or directly [class@Clutter.Stage] | ||||
|  */ | ||||
| #include "config.h" | ||||
|  | ||||
| #include "cally/cally-stage.h" | ||||
| #include "cally/cally-actor-private.h" | ||||
|  | ||||
| /* AtkObject.h */ | ||||
| static void                  cally_stage_real_initialize (AtkObject *obj, | ||||
|                                                           gpointer   data); | ||||
| static AtkStateSet*          cally_stage_ref_state_set   (AtkObject *obj); | ||||
|  | ||||
| /* AtkWindow */ | ||||
| static void                  cally_stage_window_interface_init (AtkWindowIface *iface); | ||||
|  | ||||
| /* Auxiliary */ | ||||
| static void                  cally_stage_activate_cb     (ClutterStage *stage, | ||||
|                                                           gpointer      data); | ||||
| static void                  cally_stage_deactivate_cb   (ClutterStage *stage, | ||||
|                                                           gpointer      data); | ||||
|  | ||||
| typedef struct _CallyStagePrivate | ||||
| { | ||||
|   /* NULL means that the stage will receive the focus */ | ||||
|   ClutterActor *key_focus; | ||||
|  | ||||
|   gboolean active; | ||||
| } CallyStagePrivate; | ||||
|  | ||||
| G_DEFINE_TYPE_WITH_CODE (CallyStage, | ||||
|                          cally_stage, | ||||
|                          CALLY_TYPE_ACTOR, | ||||
|                          G_ADD_PRIVATE (CallyStage) | ||||
|                          G_IMPLEMENT_INTERFACE (ATK_TYPE_WINDOW, | ||||
|                                                 cally_stage_window_interface_init)); | ||||
|  | ||||
| static void | ||||
| cally_stage_class_init (CallyStageClass *klass) | ||||
| { | ||||
|   AtkObjectClass *class = ATK_OBJECT_CLASS (klass); | ||||
|  | ||||
|   /* AtkObject */ | ||||
|   class->initialize = cally_stage_real_initialize; | ||||
|   class->ref_state_set = cally_stage_ref_state_set; | ||||
| } | ||||
|  | ||||
| static void | ||||
| cally_stage_init (CallyStage *cally_stage) | ||||
| { | ||||
|   CallyStagePrivate *priv = cally_stage_get_instance_private (cally_stage); | ||||
|  | ||||
|   priv->active = FALSE; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * cally_stage_new: | ||||
|  * @actor: a #ClutterActor | ||||
|  * | ||||
|  * Creates a new #CallyStage for the given @actor. @actor should be a | ||||
|  * [class@Clutter.Stage]. | ||||
|  * | ||||
|  * Return value: the newly created #AtkObject | ||||
|  */ | ||||
| AtkObject* | ||||
| cally_stage_new (ClutterActor *actor) | ||||
| { | ||||
|   GObject   *object     = NULL; | ||||
|   AtkObject *accessible = NULL; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_STAGE (actor), NULL); | ||||
|  | ||||
|   object = g_object_new (CALLY_TYPE_STAGE, NULL); | ||||
|  | ||||
|   accessible = ATK_OBJECT (object); | ||||
|   atk_object_initialize (accessible, actor); | ||||
|  | ||||
|   return accessible; | ||||
| } | ||||
|  | ||||
| static void | ||||
| cally_stage_notify_key_focus_cb (ClutterStage *stage, | ||||
|                                  GParamSpec   *pspec, | ||||
|                                  CallyStage   *self) | ||||
| { | ||||
|   ClutterActor *key_focus = NULL; | ||||
|   AtkObject *new = NULL; | ||||
|   CallyStagePrivate *priv = cally_stage_get_instance_private (self); | ||||
|  | ||||
|   if (priv->active == FALSE) | ||||
|     return; | ||||
|  | ||||
|   key_focus = clutter_stage_get_key_focus (stage); | ||||
|  | ||||
|   if (key_focus != priv->key_focus) | ||||
|     { | ||||
|       AtkObject *old = NULL; | ||||
|  | ||||
|       if (priv->key_focus != NULL) | ||||
|         { | ||||
|           if (priv->key_focus != CLUTTER_ACTOR (stage)) | ||||
|             { | ||||
|               g_object_remove_weak_pointer (G_OBJECT (priv->key_focus), | ||||
|                                             (gpointer *) &priv->key_focus); | ||||
|             } | ||||
|           old = clutter_actor_get_accessible (priv->key_focus); | ||||
|         } | ||||
|       else | ||||
|         old = clutter_actor_get_accessible (CLUTTER_ACTOR (stage)); | ||||
|  | ||||
|       atk_object_notify_state_change (old, | ||||
|                                       ATK_STATE_FOCUSED, | ||||
|                                       FALSE); | ||||
|     } | ||||
|  | ||||
|   /* we keep notifying the focus gain without checking previous | ||||
|    * key-focus to avoid some missing events due timing | ||||
|    */ | ||||
|   priv->key_focus = key_focus; | ||||
|  | ||||
|   if (key_focus != NULL) | ||||
|     { | ||||
|       /* ensure that if the key focus goes away, the field inside | ||||
|        * CallyStage is reset. see bug: | ||||
|        * | ||||
|        * https://bugzilla.gnome.org/show_bug.cgi?id=692706 | ||||
|        * | ||||
|        * we remove the weak pointer above. | ||||
|        */ | ||||
|       if (key_focus != CLUTTER_ACTOR (stage)) | ||||
|         { | ||||
|           g_object_add_weak_pointer (G_OBJECT (priv->key_focus), | ||||
|                                      (gpointer *) &priv->key_focus); | ||||
|         } | ||||
|  | ||||
|       new = clutter_actor_get_accessible (key_focus); | ||||
|     } | ||||
|   else | ||||
|     new = clutter_actor_get_accessible (CLUTTER_ACTOR (stage)); | ||||
|  | ||||
|   atk_object_notify_state_change (new, | ||||
|                                   ATK_STATE_FOCUSED, | ||||
|                                   TRUE); | ||||
| } | ||||
|  | ||||
| static void | ||||
| cally_stage_real_initialize (AtkObject *obj, | ||||
|                              gpointer  data) | ||||
| { | ||||
|   ClutterStage *stage = NULL; | ||||
|  | ||||
|   g_return_if_fail (CALLY_IS_STAGE (obj)); | ||||
|  | ||||
|   ATK_OBJECT_CLASS (cally_stage_parent_class)->initialize (obj, data); | ||||
|  | ||||
|   stage = CLUTTER_STAGE (CALLY_GET_CLUTTER_ACTOR (obj)); | ||||
|  | ||||
|   g_signal_connect (stage, "activate", G_CALLBACK (cally_stage_activate_cb), obj); | ||||
|   g_signal_connect (stage, "deactivate", G_CALLBACK (cally_stage_deactivate_cb), obj); | ||||
|   g_signal_connect (stage, "notify::key-focus", | ||||
|                     G_CALLBACK (cally_stage_notify_key_focus_cb), obj); | ||||
|  | ||||
|   atk_object_set_role (obj, ATK_ROLE_WINDOW); | ||||
| } | ||||
|  | ||||
| static AtkStateSet* | ||||
| cally_stage_ref_state_set   (AtkObject *obj) | ||||
| { | ||||
|   CallyStage   *cally_stage = NULL; | ||||
|   AtkStateSet  *state_set   = NULL; | ||||
|   ClutterStage *stage       = NULL; | ||||
|   CallyStagePrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (CALLY_IS_STAGE (obj), NULL); | ||||
|   cally_stage = CALLY_STAGE (obj); | ||||
|   priv = cally_stage_get_instance_private (cally_stage); | ||||
|  | ||||
|   state_set = ATK_OBJECT_CLASS (cally_stage_parent_class)->ref_state_set (obj); | ||||
|   stage = CLUTTER_STAGE (CALLY_GET_CLUTTER_ACTOR (cally_stage)); | ||||
|  | ||||
|   if (stage == NULL) | ||||
|     return state_set; | ||||
|  | ||||
|   if (priv->active) | ||||
|     atk_state_set_add_state (state_set, ATK_STATE_ACTIVE); | ||||
|  | ||||
|   return state_set; | ||||
| } | ||||
|  | ||||
| /* AtkWindow */ | ||||
| static void | ||||
| cally_stage_window_interface_init (AtkWindowIface *iface) | ||||
| { | ||||
|   /* At this moment AtkWindow is just about signals */ | ||||
| } | ||||
|  | ||||
| /* Auxiliary */ | ||||
| static void | ||||
| cally_stage_activate_cb     (ClutterStage *stage, | ||||
|                              gpointer      data) | ||||
| { | ||||
|   CallyStage *cally_stage = NULL; | ||||
|   CallyStagePrivate *priv; | ||||
|  | ||||
|   g_return_if_fail (CALLY_IS_STAGE (data)); | ||||
|  | ||||
|   cally_stage = CALLY_STAGE (data); | ||||
|   priv = cally_stage_get_instance_private (cally_stage); | ||||
|  | ||||
|   priv->active = TRUE; | ||||
|  | ||||
|   atk_object_notify_state_change (ATK_OBJECT (cally_stage), | ||||
|                                   ATK_STATE_ACTIVE, TRUE); | ||||
|  | ||||
|   g_signal_emit_by_name (cally_stage, "activate", 0); | ||||
| } | ||||
|  | ||||
| static void | ||||
| cally_stage_deactivate_cb   (ClutterStage *stage, | ||||
|                              gpointer      data) | ||||
| { | ||||
|   CallyStage *cally_stage = NULL; | ||||
|   CallyStagePrivate *priv; | ||||
|  | ||||
|   g_return_if_fail (CALLY_IS_STAGE (data)); | ||||
|  | ||||
|   cally_stage = CALLY_STAGE (data); | ||||
|   priv = cally_stage_get_instance_private (cally_stage); | ||||
|  | ||||
|   priv->active = FALSE; | ||||
|  | ||||
|   atk_object_notify_state_change (ATK_OBJECT (cally_stage), | ||||
|                                   ATK_STATE_ACTIVE, FALSE); | ||||
|  | ||||
|   g_signal_emit_by_name (cally_stage, "deactivate", 0); | ||||
| } | ||||
| @@ -1,53 +0,0 @@ | ||||
| /* CALLY - The Clutter Accessibility Implementation Library | ||||
|  * | ||||
|  * Copyright (C) 2008 Igalia, S.L. | ||||
|  * | ||||
|  * Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com> | ||||
|  * | ||||
|  * 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/>. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <cally/cally.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include "cally/cally-actor.h" | ||||
| #include "clutter/clutter.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CALLY_TYPE_STAGE            (cally_stage_get_type ()) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_DERIVABLE_TYPE (CallyStage, | ||||
|                           cally_stage, | ||||
|                           CALLY, | ||||
|                           STAGE, | ||||
|                           CallyActor) | ||||
|  | ||||
| typedef struct _CallyStage CallyStage; | ||||
| typedef struct _CallyStageClass CallyStageClass; | ||||
|  | ||||
| struct _CallyStageClass | ||||
| { | ||||
|   /*< private >*/ | ||||
|   CallyActorClass parent_class; | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| AtkObject *cally_stage_new      (ClutterActor *actor); | ||||
|  | ||||
| G_END_DECLS | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,53 +0,0 @@ | ||||
| /* CALLY - The Clutter Accessibility Implementation Library | ||||
|  * | ||||
|  * Copyright (C) 2009 Igalia, S.L. | ||||
|  * | ||||
|  * Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com> | ||||
|  * | ||||
|  * 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/>. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <cally/cally.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include "clutter/clutter.h" | ||||
| #include "cally/cally-actor.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CALLY_TYPE_TEXT                 (cally_text_get_type ()) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_DERIVABLE_TYPE (CallyText, | ||||
|                           cally_text, | ||||
|                           CALLY, | ||||
|                           TEXT, | ||||
|                           CallyActor) | ||||
|  | ||||
| typedef struct _CallyText CallyText; | ||||
| typedef struct _CallyTextClass CallyTextClass; | ||||
|  | ||||
| struct _CallyTextClass | ||||
| { | ||||
|   /*< private >*/ | ||||
|   CallyActorClass parent_class; | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| AtkObject* cally_text_new      (ClutterActor *actor); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,351 +0,0 @@ | ||||
| /* CALLY - The Clutter Accessibility Implementation Library | ||||
|  * | ||||
|  * Copyright (C) 2008 Igalia, S.L. | ||||
|  * | ||||
|  * Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com> | ||||
|  * | ||||
|  * Based on GailUtil from GAIL | ||||
|  * Copyright 2001, 2002, 2003 Sun Microsystems 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/>. | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * CallyUtil: | ||||
|  *  | ||||
|  * #AtkUtil implementation | ||||
|  * | ||||
|  * #CallyUtil implements #AtkUtil abstract methods. Although it | ||||
|  * includes the name "Util" it is in fact one of the most important | ||||
|  * interfaces to be implemented in any ATK toolkit implementation. | ||||
|  | ||||
|  * For instance, it defines [func@Atk.get_root], the method that returns | ||||
|  * the root object in the hierarchy. Without it, you don't have | ||||
|  * available any accessible object. | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #include "cally/cally-util.h" | ||||
| #include "cally/cally-root.h" | ||||
| #include "cally/cally-stage.h" | ||||
| #include "clutter/clutter.h" | ||||
|  | ||||
| #define DEFAULT_PASSWORD_CHAR '*' | ||||
|  | ||||
| /* atkutil.h */ | ||||
|  | ||||
| static guint                 cally_util_add_key_event_listener	    (AtkKeySnoopFunc listener, | ||||
|                                                                      gpointer        data); | ||||
| static void                  cally_util_remove_key_event_listener    (guint remove_listener); | ||||
| static AtkObject*            cally_util_get_root			    (void); | ||||
| static const gchar *         cally_util_get_toolkit_name		    (void); | ||||
| static const gchar *         cally_util_get_toolkit_version          (void); | ||||
|  | ||||
| /* private */ | ||||
| static gboolean              notify_hf                               (gpointer key, | ||||
|                                                                       gpointer value, | ||||
|                                                                       gpointer data); | ||||
| static void                  insert_hf                               (gpointer key, | ||||
|                                                                       gpointer value, | ||||
|                                                                       gpointer data); | ||||
|  | ||||
| /* This is just a copy of the Gail one, a shared library or place to | ||||
|    define it could be a good idea. */ | ||||
| typedef struct _CallyKeyEventInfo CallyKeyEventInfo; | ||||
|  | ||||
| struct _CallyKeyEventInfo | ||||
| { | ||||
|   AtkKeySnoopFunc listener; | ||||
|   gpointer func_data; | ||||
| }; | ||||
|  | ||||
| static AtkObject* root = NULL; | ||||
| static GHashTable *key_listener_list = NULL; | ||||
|  | ||||
|  | ||||
| G_DEFINE_TYPE (CallyUtil, cally_util, ATK_TYPE_UTIL); | ||||
|  | ||||
| static void | ||||
| cally_util_class_init (CallyUtilClass *klass) | ||||
| { | ||||
|   AtkUtilClass *atk_class; | ||||
|   gpointer data; | ||||
|  | ||||
|   data = g_type_class_peek (ATK_TYPE_UTIL); | ||||
|   atk_class = ATK_UTIL_CLASS (data); | ||||
|  | ||||
|   atk_class->add_key_event_listener       = cally_util_add_key_event_listener; | ||||
|   atk_class->remove_key_event_listener    = cally_util_remove_key_event_listener; | ||||
|   atk_class->get_root                     = cally_util_get_root; | ||||
|   atk_class->get_toolkit_name             = cally_util_get_toolkit_name; | ||||
|   atk_class->get_toolkit_version          = cally_util_get_toolkit_version; | ||||
|  | ||||
|   /* FIXME: Instead of create this on the class, I think that would | ||||
|      worth to implement CallyUtil as a singleton instance, so the | ||||
|      class methods will access this instance. This will be a good | ||||
|      future enhancement, meanwhile, just using the same *working* | ||||
|      implementation used on GailUtil */ | ||||
| } | ||||
|  | ||||
| static void | ||||
| cally_util_init (CallyUtil *cally_util) | ||||
| { | ||||
|   /* instance init: usually not required */ | ||||
| } | ||||
|  | ||||
| /* ------------------------------ ATK UTIL METHODS -------------------------- */ | ||||
|  | ||||
| static AtkObject* | ||||
| cally_util_get_root (void) | ||||
| { | ||||
|   if (!root) | ||||
|     root = cally_root_new (); | ||||
|  | ||||
|   return root; | ||||
| } | ||||
|  | ||||
| static const gchar * | ||||
| cally_util_get_toolkit_name (void) | ||||
| { | ||||
|   return "clutter"; | ||||
| } | ||||
|  | ||||
| static const gchar * | ||||
| cally_util_get_toolkit_version (void) | ||||
| { | ||||
|   return VERSION; | ||||
| } | ||||
|  | ||||
| static guint | ||||
| cally_util_add_key_event_listener (AtkKeySnoopFunc  listener, | ||||
|                                    gpointer         data) | ||||
| { | ||||
|   static guint key = 1; | ||||
|   CallyKeyEventInfo *event_info = NULL; | ||||
|  | ||||
|   if (!key_listener_list) | ||||
|     key_listener_list = g_hash_table_new_full (NULL, NULL, NULL, g_free); | ||||
|  | ||||
|   event_info = g_new (CallyKeyEventInfo, 1); | ||||
|   event_info->listener = listener; | ||||
|   event_info->func_data = data; | ||||
|  | ||||
|   g_hash_table_insert (key_listener_list, GUINT_TO_POINTER (key++), event_info); | ||||
|   /* XXX: we don't check to see if n_listeners > MAXUINT */ | ||||
|   return key - 1; | ||||
| } | ||||
|  | ||||
| static void | ||||
| cally_util_remove_key_event_listener (guint remove_listener) | ||||
| { | ||||
|   if (!g_hash_table_remove (key_listener_list, GUINT_TO_POINTER (remove_listener))) { | ||||
|     g_warning ("Not able to remove listener with id %i", remove_listener); | ||||
|   } | ||||
|  | ||||
|   if (g_hash_table_size (key_listener_list) == 0) | ||||
|     { | ||||
|       g_hash_table_destroy (key_listener_list); | ||||
|       key_listener_list = NULL; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /* ------------------------------ PRIVATE FUNCTIONS ------------------------- */ | ||||
|  | ||||
| static AtkKeyEventStruct * | ||||
| atk_key_event_from_clutter_event_key (ClutterKeyEvent *clutter_event, | ||||
|                                       gunichar         password_char) | ||||
| { | ||||
|   AtkKeyEventStruct *atk_event = g_new0 (AtkKeyEventStruct, 1); | ||||
|   gunichar key_unichar; | ||||
|  | ||||
|   switch (clutter_event_type ((ClutterEvent *) clutter_event)) | ||||
|     { | ||||
|     case CLUTTER_KEY_PRESS: | ||||
|       atk_event->type = ATK_KEY_EVENT_PRESS; | ||||
|       break; | ||||
|     case CLUTTER_KEY_RELEASE: | ||||
|       atk_event->type = ATK_KEY_EVENT_RELEASE; | ||||
|       break; | ||||
|     default: | ||||
|       g_assert_not_reached (); | ||||
|       return NULL; | ||||
|     } | ||||
|  | ||||
|   if (password_char) | ||||
|     atk_event->state = 0; | ||||
|   else | ||||
|     atk_event->state = clutter_event_get_state ((ClutterEvent *) clutter_event); | ||||
|  | ||||
|   /* We emit the clutter keyval. This is not exactly the one expected | ||||
|      by AtkKeyEventStruct, as it expects a Gdk-like event, with the | ||||
|      modifiers applied. But to avoid a dependency to gdk, we delegate | ||||
|      that on the AT application. | ||||
|      More information: Bug 1952 and bug 2072 | ||||
|   */ | ||||
|   if (password_char) | ||||
|     atk_event->keyval = clutter_unicode_to_keysym (password_char); | ||||
|   else | ||||
|     atk_event->keyval = clutter_event_get_key_symbol ((ClutterEvent *) clutter_event); | ||||
|  | ||||
|   /* It is expected to store a key defining string here (ie "Space" in | ||||
|      case you press a space). Anyway, there are no function on clutter | ||||
|      to obtain that, and we want to avoid a gdk dependency here, so we | ||||
|      delegate on the AT application to obtain that string using the | ||||
|      rest of the data on the ATK event struct. | ||||
|  | ||||
|      More information: Bug 1952 and 2072 | ||||
|   */ | ||||
|  | ||||
|   if (password_char) | ||||
|     key_unichar = password_char; | ||||
|   else | ||||
|     key_unichar = clutter_event_get_key_unicode ((ClutterEvent *) clutter_event); | ||||
|  | ||||
|   if (g_unichar_validate (key_unichar) && !g_unichar_iscntrl (key_unichar)) | ||||
|     { | ||||
|       GString *new = NULL; | ||||
|  | ||||
|       new = g_string_new (""); | ||||
|       new = g_string_insert_unichar (new, 0, key_unichar); | ||||
|       atk_event->string = g_string_free (new, FALSE); | ||||
|     } | ||||
|   else | ||||
|     atk_event->string = NULL; | ||||
|  | ||||
|   atk_event->length = 0; | ||||
|  | ||||
|   /* Computing the hardware keycode from the password-char is | ||||
|      difficult. But we are in a password situation. We are already a | ||||
|      unichar that it is not the original one. Providing a "almost | ||||
|      real" keycode is irrelevant */ | ||||
|   if (password_char) | ||||
|     atk_event->keycode = 0; | ||||
|   else | ||||
|     atk_event->keycode = clutter_event_get_key_code ((ClutterEvent *) clutter_event); | ||||
|  | ||||
|   atk_event->timestamp = clutter_event_get_time ((ClutterEvent *) clutter_event); | ||||
|  | ||||
| #ifdef CALLY_DEBUG | ||||
|  | ||||
|   g_debug ("CallyKeyEvent:\tsym 0x%x\n\t\tmods %x\n\t\tcode %u\n\t\ttime %lx \n\t\tstring %s\n", | ||||
| 	   (unsigned int) atk_event->keyval, | ||||
| 	   (unsigned int) atk_event->state, | ||||
| 	   (unsigned int) atk_event->keycode, | ||||
| 	   (unsigned long int) atk_event->timestamp, | ||||
|            atk_event->string); | ||||
| #endif | ||||
|  | ||||
|   return atk_event; | ||||
| } | ||||
|  | ||||
|  | ||||
| static gboolean | ||||
| notify_hf (gpointer key, gpointer value, gpointer data) | ||||
| { | ||||
|   CallyKeyEventInfo *info = (CallyKeyEventInfo *) value; | ||||
|   AtkKeyEventStruct *key_event = (AtkKeyEventStruct *)data; | ||||
|  | ||||
|   return (*(AtkKeySnoopFunc) info->listener) (key_event, info->func_data) ? TRUE : FALSE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| insert_hf (gpointer key, gpointer value, gpointer data) | ||||
| { | ||||
|   GHashTable *new_table = (GHashTable *) data; | ||||
|   g_hash_table_insert (new_table, key, value); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * 0 if the key of that event is visible, in other case the password | ||||
|  * char | ||||
|  */ | ||||
| static gunichar | ||||
| check_key_visibility (ClutterStage *stage) | ||||
| { | ||||
|   AtkObject *accessible; | ||||
|   ClutterActor *focus; | ||||
|  | ||||
|   focus = clutter_stage_get_key_focus (stage); | ||||
|   accessible = clutter_actor_get_accessible (focus); | ||||
|  | ||||
|   g_return_val_if_fail (accessible != NULL, 0); | ||||
|  | ||||
|   if (atk_object_get_role (accessible) != ATK_ROLE_PASSWORD_TEXT) | ||||
|     return 0; | ||||
|  | ||||
|   /* If it is a clutter text, we use his password char.  Note that | ||||
|      although at Clutter toolkit itself, only ClutterText exposes a | ||||
|      password role, nothing prevents on any derived toolkit (like st) | ||||
|      to create a new actor that can behave like a password entry. And | ||||
|      the key event will still be emitted here. Although in that case | ||||
|      we would lose any password char from the derived toolkit, it is | ||||
|      still better fill this with a default unichar that the original | ||||
|      one */ | ||||
|  | ||||
|   if (CLUTTER_IS_TEXT (focus)) | ||||
|     return clutter_text_get_password_char (CLUTTER_TEXT (focus)); | ||||
|   else | ||||
|     return DEFAULT_PASSWORD_CHAR; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| cally_snoop_key_event (ClutterStage    *stage, | ||||
|                        ClutterKeyEvent *key) | ||||
| { | ||||
|   ClutterEvent *event = (ClutterEvent *) key; | ||||
|   AtkKeyEventStruct *key_event = NULL; | ||||
|   ClutterEventType event_type; | ||||
|   gboolean consumed = FALSE; | ||||
|   gunichar password_char = 0; | ||||
|  | ||||
|   event_type = clutter_event_type (event); | ||||
|  | ||||
|   /* filter key events */ | ||||
|   if ((event_type != CLUTTER_KEY_PRESS) && (event_type != CLUTTER_KEY_RELEASE)) | ||||
|     return FALSE; | ||||
|  | ||||
|   if (key_listener_list) | ||||
|     { | ||||
|       GHashTable *new_hash = g_hash_table_new (NULL, NULL); | ||||
|  | ||||
|       g_hash_table_foreach (key_listener_list, insert_hf, new_hash); | ||||
|       password_char = check_key_visibility (stage); | ||||
|       key_event = atk_key_event_from_clutter_event_key (key, password_char); | ||||
|       /* func data is inside the hash table */ | ||||
|       consumed = g_hash_table_foreach_steal (new_hash, notify_hf, key_event) > 0; | ||||
|       g_hash_table_destroy (new_hash); | ||||
|  | ||||
|       g_free (key_event->string); | ||||
|       g_free (key_event); | ||||
|     } | ||||
|  | ||||
|   return consumed; | ||||
| } | ||||
|  | ||||
| void | ||||
| _cally_util_override_atk_util (void) | ||||
| { | ||||
|   AtkUtilClass *atk_class = ATK_UTIL_CLASS (g_type_class_ref (ATK_TYPE_UTIL)); | ||||
|  | ||||
|   atk_class->add_key_event_listener = cally_util_add_key_event_listener; | ||||
|   atk_class->remove_key_event_listener = cally_util_remove_key_event_listener; | ||||
|   atk_class->get_root = cally_util_get_root; | ||||
|   atk_class->get_toolkit_name = cally_util_get_toolkit_name; | ||||
|   atk_class->get_toolkit_version = cally_util_get_toolkit_version; | ||||
| } | ||||
| @@ -1,55 +0,0 @@ | ||||
| /* CALLY - The Clutter Accessibility Implementation Library | ||||
|  * | ||||
|  * Copyright (C) 2008 Igalia, S.L. | ||||
|  * | ||||
|  * Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com> | ||||
|  * | ||||
|  * 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/>. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <cally/cally.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include "clutter/clutter.h" | ||||
| #include <atk/atk.h> | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CALLY_TYPE_UTIL            (cally_util_get_type ()) | ||||
|  | ||||
| typedef struct _CallyUtil        CallyUtil; | ||||
| typedef struct _CallyUtilClass   CallyUtilClass; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_DERIVABLE_TYPE (CallyUtil, | ||||
|                           cally_util, | ||||
|                           CALLY, | ||||
|                           UTIL, | ||||
|                           AtkUtil) | ||||
|  | ||||
| struct _CallyUtilClass | ||||
| { | ||||
|   /*< private >*/ | ||||
|   AtkUtilClass parent_class; | ||||
| }; | ||||
|  | ||||
| void _cally_util_override_atk_util (void); | ||||
|  | ||||
| gboolean cally_snoop_key_event (ClutterStage    *stage, | ||||
|                                 ClutterKeyEvent *key); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,79 +0,0 @@ | ||||
| /* CALLY - The Clutter Accessibility Implementation Library | ||||
|  * | ||||
|  * Copyright (C) 2008 Igalia, S.L. | ||||
|  * | ||||
|  * Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com> | ||||
|  * | ||||
|  * 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 "config.h" | ||||
|  | ||||
| #include "cally/cally.h" | ||||
|  | ||||
| #include "cally/cally-actor.h" | ||||
| #include "cally/cally-stage.h" | ||||
| #include "cally/cally-text.h" | ||||
| #include "cally/cally-clone.h" | ||||
|  | ||||
| #include "cally/cally-factory.h" | ||||
| #include "cally/cally-util.h" | ||||
|  | ||||
| #include "clutter/clutter.h" | ||||
|  | ||||
| #include "clutter/clutter-debug.h" | ||||
| #include "clutter/clutter-private.h" | ||||
|  | ||||
| /* factories initialization*/ | ||||
| CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_ACTOR, cally_actor, cally_actor_new) | ||||
| CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_STAGE, cally_stage, cally_stage_new) | ||||
| CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_TEXT, cally_text, cally_text_new) | ||||
| CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_CLONE, cally_clone, cally_clone_new) | ||||
|  | ||||
| /** | ||||
|  * cally_accessibility_init: | ||||
|  * | ||||
|  * Initializes the accessibility support. | ||||
|  * | ||||
|  * Return value: %TRUE if accessibility support has been correctly | ||||
|  * initialized. | ||||
|  */ | ||||
| gboolean | ||||
| cally_accessibility_init (void) | ||||
| { | ||||
|   /* setting the factories */ | ||||
|   CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_ACTOR, cally_actor); | ||||
|   CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_STAGE, cally_stage); | ||||
|   CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_TEXT, cally_text); | ||||
|   CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_CLONE, cally_clone); | ||||
|  | ||||
|   /* Initialize the CallyUtility class */ | ||||
|   _cally_util_override_atk_util (); | ||||
|  | ||||
|   CLUTTER_NOTE (MISC, "Clutter Accessibility initialized"); | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * cally_get_cally_initialized: | ||||
|  * | ||||
|  * Returns if the accessibility support using cally is enabled. | ||||
|  * | ||||
|  * Return value: %TRUE if accessibility support has been correctly | ||||
|  * initialized. | ||||
|  */ | ||||
| gboolean cally_get_cally_initialized (void) | ||||
| { | ||||
|   return !g_strcmp0 (atk_get_toolkit_name (), "clutter"); | ||||
| } | ||||
| @@ -1,34 +0,0 @@ | ||||
| /* CALLY - The Clutter Accessibility Implementation Library | ||||
|  * | ||||
|  * Copyright (C) 2008 Igalia, S.L. | ||||
|  * | ||||
|  * Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com> | ||||
|  * | ||||
|  * 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/>. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #define __CALLY_H_INSIDE__ | ||||
|  | ||||
| #include "cally/cally-actor.h" | ||||
| #include "cally/cally-clone.h" | ||||
| #include "cally/cally-factory.h" | ||||
| #include "cally/cally-main.h" | ||||
| #include "cally/cally-root.h" | ||||
| #include "cally/cally-stage.h" | ||||
| #include "cally/cally-text.h" | ||||
| #include "cally/cally-util.h" | ||||
|  | ||||
| #undef __CALLY_H_INSIDE__ | ||||
| @@ -1,53 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2021 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/>. | ||||
|  * | ||||
|  * Author: | ||||
|  *   Carlos Garnacho <carlosg@gnome.org> | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <clutter/clutter.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include "clutter/clutter-action.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| void clutter_action_set_phase (ClutterAction     *action, | ||||
|                                ClutterEventPhase  phase); | ||||
|  | ||||
| gboolean clutter_action_handle_event (ClutterAction      *action, | ||||
|                                       const ClutterEvent *event); | ||||
|  | ||||
| void clutter_action_sequence_cancelled (ClutterAction        *action, | ||||
|                                         ClutterInputDevice   *device, | ||||
|                                         ClutterEventSequence *sequence); | ||||
|  | ||||
| gboolean clutter_action_register_sequence (ClutterAction      *self, | ||||
|                                            const ClutterEvent *event); | ||||
|  | ||||
| int clutter_action_setup_sequence_relationship (ClutterAction        *action_1, | ||||
|                                                 ClutterAction        *action_2, | ||||
|                                                 ClutterInputDevice   *device, | ||||
|                                                 ClutterEventSequence *sequence); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,146 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2010  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> | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * ClutterAction: | ||||
|  *  | ||||
|  * Abstract class for event-related logic | ||||
|  * | ||||
|  * #ClutterAction is an abstract base class for event-related actions that | ||||
|  * modify the user interaction of a [class@Actor], just like | ||||
|  * [class@Constraint] is an abstract class for modifiers of an actor's | ||||
|  * position or size. | ||||
|  * | ||||
|  * Implementations of #ClutterAction are associated to an actor and can | ||||
|  * provide behavioral changes when dealing with user input - for instance | ||||
|  * drag and drop capabilities, or scrolling, or panning - by using the | ||||
|  * various event-related signals provided by [class@Actor] itself. | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "clutter/clutter-action.h" | ||||
| #include "clutter/clutter-action-private.h" | ||||
| #include "clutter/clutter-debug.h" | ||||
| #include "clutter/clutter-private.h" | ||||
|  | ||||
| typedef struct _ClutterActionPrivate ClutterActionPrivate; | ||||
|  | ||||
| struct _ClutterActionPrivate | ||||
| { | ||||
|   ClutterEventPhase phase; | ||||
| }; | ||||
|  | ||||
| G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterAction, clutter_action, | ||||
|                                      CLUTTER_TYPE_ACTOR_META) | ||||
|  | ||||
| static gboolean | ||||
| clutter_action_handle_event_default (ClutterAction      *action, | ||||
|                                      const ClutterEvent *event) | ||||
| { | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_action_class_init (ClutterActionClass *klass) | ||||
| { | ||||
|   klass->handle_event = clutter_action_handle_event_default; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_action_init (ClutterAction *self) | ||||
| { | ||||
| } | ||||
|  | ||||
| void | ||||
| clutter_action_set_phase (ClutterAction     *action, | ||||
|                           ClutterEventPhase  phase) | ||||
| { | ||||
|   ClutterActionPrivate *priv; | ||||
|  | ||||
|   priv = clutter_action_get_instance_private (action); | ||||
|   priv->phase = phase; | ||||
| } | ||||
|  | ||||
| ClutterEventPhase | ||||
| clutter_action_get_phase (ClutterAction *action) | ||||
| { | ||||
|   ClutterActionPrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_ACTION (action), CLUTTER_PHASE_CAPTURE); | ||||
|  | ||||
|   priv = clutter_action_get_instance_private (action); | ||||
|  | ||||
|   return priv->phase; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| clutter_action_handle_event (ClutterAction      *action, | ||||
|                              const ClutterEvent *event) | ||||
| { | ||||
|   gboolean retval; | ||||
|  | ||||
|   g_object_ref (action); | ||||
|   retval = CLUTTER_ACTION_GET_CLASS (action)->handle_event (action, event); | ||||
|   g_object_unref (action); | ||||
|  | ||||
|   return retval; | ||||
| } | ||||
|  | ||||
| void | ||||
| clutter_action_sequence_cancelled (ClutterAction        *action, | ||||
|                                    ClutterInputDevice   *device, | ||||
|                                    ClutterEventSequence *sequence) | ||||
| { | ||||
|   ClutterActionClass *action_class = CLUTTER_ACTION_GET_CLASS (action); | ||||
|  | ||||
|   if (action_class->sequence_cancelled) | ||||
|     action_class->sequence_cancelled (action, device, sequence); | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| clutter_action_register_sequence (ClutterAction      *self, | ||||
|                                   const ClutterEvent *event) | ||||
| { | ||||
|   ClutterActionClass *action_class = CLUTTER_ACTION_GET_CLASS (self); | ||||
|  | ||||
|   if (action_class->register_sequence) | ||||
|     return action_class->register_sequence (self, event); | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| int | ||||
| clutter_action_setup_sequence_relationship (ClutterAction        *action_1, | ||||
|                                             ClutterAction        *action_2, | ||||
|                                             ClutterInputDevice   *device, | ||||
|                                             ClutterEventSequence *sequence) | ||||
| { | ||||
|   ClutterActionClass *action_class = CLUTTER_ACTION_GET_CLASS (action_1); | ||||
|  | ||||
|   if (action_class->setup_sequence_relationship) | ||||
|     return action_class->setup_sequence_relationship (action_1, action_2, device, sequence); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
| @@ -1,99 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2010  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> | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <clutter/clutter.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include "clutter/clutter-actor-meta.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CLUTTER_TYPE_ACTION (clutter_action_get_type ()) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_DERIVABLE_TYPE (ClutterAction, clutter_action, | ||||
|                           CLUTTER, ACTION, ClutterActorMeta); | ||||
|  | ||||
| /** | ||||
|  * ClutterActionClass: | ||||
|  * | ||||
|  * The ClutterActionClass structure contains only private data | ||||
|  */ | ||||
| struct _ClutterActionClass | ||||
| { | ||||
|   /*< private >*/ | ||||
|   ClutterActorMetaClass parent_class; | ||||
|  | ||||
|   gboolean (* handle_event) (ClutterAction      *action, | ||||
|                              const ClutterEvent *event); | ||||
|  | ||||
|   void (* sequence_cancelled) (ClutterAction        *action, | ||||
|                                ClutterInputDevice   *device, | ||||
|                                ClutterEventSequence *sequence); | ||||
|  | ||||
|   gboolean (* register_sequence) (ClutterAction      *self, | ||||
|                                   const ClutterEvent *event); | ||||
|  | ||||
|   int (* setup_sequence_relationship) (ClutterAction        *action_1, | ||||
|                                        ClutterAction        *action_2, | ||||
|                                        ClutterInputDevice   *device, | ||||
|                                        ClutterEventSequence *sequence); | ||||
| }; | ||||
|  | ||||
| /* ClutterActor API */ | ||||
| CLUTTER_EXPORT | ||||
| void           clutter_actor_add_action            (ClutterActor  *self, | ||||
|                                                     ClutterAction *action); | ||||
| CLUTTER_EXPORT | ||||
| void           clutter_actor_add_action_with_name  (ClutterActor  *self, | ||||
|                                                     const gchar   *name, | ||||
|                                                     ClutterAction *action); | ||||
| CLUTTER_EXPORT | ||||
| void           clutter_actor_add_action_full       (ClutterActor      *self, | ||||
|                                                     const char        *name, | ||||
|                                                     ClutterEventPhase  phase, | ||||
|                                                     ClutterAction     *action); | ||||
| CLUTTER_EXPORT | ||||
| void           clutter_actor_remove_action         (ClutterActor  *self, | ||||
|                                                     ClutterAction *action); | ||||
| CLUTTER_EXPORT | ||||
| void           clutter_actor_remove_action_by_name (ClutterActor  *self, | ||||
|                                                     const gchar   *name); | ||||
| CLUTTER_EXPORT | ||||
| ClutterAction *clutter_actor_get_action            (ClutterActor  *self, | ||||
|                                                     const gchar   *name); | ||||
| CLUTTER_EXPORT | ||||
| GList *        clutter_actor_get_actions           (ClutterActor  *self); | ||||
| CLUTTER_EXPORT | ||||
| void           clutter_actor_clear_actions         (ClutterActor  *self); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| gboolean       clutter_actor_has_actions           (ClutterActor  *self); | ||||
|  | ||||
| ClutterEventPhase clutter_action_get_phase (ClutterAction *action); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,9 +0,0 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "clutter/clutter-types.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| void _clutter_actor_box_enlarge_for_effects (ClutterActorBox *box); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,606 +0,0 @@ | ||||
| #include "config.h" | ||||
|  | ||||
| #include <math.h> | ||||
|  | ||||
| #include "clutter/clutter-types.h" | ||||
| #include "clutter/clutter-interval.h" | ||||
| #include "clutter/clutter-private.h" | ||||
| #include "clutter/clutter-actor-box-private.h" | ||||
|  | ||||
| /** | ||||
|  * clutter_actor_box_new: | ||||
|  * @x_1: X coordinate of the top left point | ||||
|  * @y_1: Y coordinate of the top left point | ||||
|  * @x_2: X coordinate of the bottom right point | ||||
|  * @y_2: Y coordinate of the bottom right point | ||||
|  * | ||||
|  * Allocates a new [struct@ActorBox] using the passed coordinates | ||||
|  * for the top left and bottom right points. | ||||
|  * | ||||
|  * This function is the logical equivalent of: | ||||
|  * | ||||
|  * ```c | ||||
|  *   clutter_actor_box_init (clutter_actor_box_alloc (), | ||||
|  *                           x_1, y_1, | ||||
|  *                           x_2, y_2); | ||||
|  * ``` | ||||
|  * | ||||
|  * Return value: (transfer full): the newly allocated #ClutterActorBox. | ||||
|  *   Use [method@ActorBox.free] to free the resources | ||||
|  */ | ||||
| ClutterActorBox * | ||||
| clutter_actor_box_new (gfloat x_1, | ||||
|                        gfloat y_1, | ||||
|                        gfloat x_2, | ||||
|                        gfloat y_2) | ||||
| { | ||||
|   return clutter_actor_box_init (clutter_actor_box_alloc (), | ||||
|                                  x_1, y_1, | ||||
|                                  x_2, y_2); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_actor_box_alloc: | ||||
|  * | ||||
|  * Allocates a new [struct@ActorBox]. | ||||
|  * | ||||
|  * Return value: (transfer full): the newly allocated #ClutterActorBox. | ||||
|  *   Use [method@ActorBox.free] to free its resources | ||||
|  */ | ||||
| ClutterActorBox * | ||||
| clutter_actor_box_alloc (void) | ||||
| { | ||||
|   return g_new0 (ClutterActorBox, 1); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_actor_box_init: | ||||
|  * @box: a #ClutterActorBox | ||||
|  * @x_1: X coordinate of the top left point | ||||
|  * @y_1: Y coordinate of the top left point | ||||
|  * @x_2: X coordinate of the bottom right point | ||||
|  * @y_2: Y coordinate of the bottom right point | ||||
|  * | ||||
|  * Initializes @box with the given coordinates. | ||||
|  * | ||||
|  * Return value: (transfer none): the initialized #ClutterActorBox | ||||
|  */ | ||||
| ClutterActorBox * | ||||
| clutter_actor_box_init (ClutterActorBox *box, | ||||
|                         gfloat           x_1, | ||||
|                         gfloat           y_1, | ||||
|                         gfloat           x_2, | ||||
|                         gfloat           y_2) | ||||
| { | ||||
|   g_return_val_if_fail (box != NULL, NULL); | ||||
|  | ||||
|   box->x1 = x_1; | ||||
|   box->y1 = y_1; | ||||
|   box->x2 = x_2; | ||||
|   box->y2 = y_2; | ||||
|  | ||||
|   return box; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_actor_box_init_rect: | ||||
|  * @box: a #ClutterActorBox | ||||
|  * @x: X coordinate of the origin | ||||
|  * @y: Y coordinate of the origin | ||||
|  * @width: width of the box | ||||
|  * @height: height of the box | ||||
|  * | ||||
|  * Initializes @box with the given origin and size. | ||||
|  */ | ||||
| void | ||||
| clutter_actor_box_init_rect (ClutterActorBox *box, | ||||
|                              gfloat           x, | ||||
|                              gfloat           y, | ||||
|                              gfloat           width, | ||||
|                              gfloat           height) | ||||
| { | ||||
|   g_return_if_fail (box != NULL); | ||||
|  | ||||
|   box->x1 = x; | ||||
|   box->y1 = y; | ||||
|   box->x2 = box->x1 + width; | ||||
|   box->y2 = box->y1 + height; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_actor_box_copy: | ||||
|  * @box: a #ClutterActorBox | ||||
|  * | ||||
|  * Copies @box | ||||
|  * | ||||
|  * Return value: a newly allocated copy of #ClutterActorBox. Use | ||||
|  *   [method@ActorBox.free] to free the allocated resources | ||||
|  */ | ||||
| ClutterActorBox * | ||||
| clutter_actor_box_copy (const ClutterActorBox *box) | ||||
| { | ||||
|   if (G_LIKELY (box != NULL)) | ||||
|     return g_memdup2 (box, sizeof (ClutterActorBox)); | ||||
|  | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_actor_box_free: | ||||
|  * @box: a #ClutterActorBox | ||||
|  * | ||||
|  * Frees a #ClutterActorBox allocated using [ctor@ActorBox.new] | ||||
|  * or [method@ActorBox.copy]. | ||||
|  */ | ||||
| void | ||||
| clutter_actor_box_free (ClutterActorBox *box) | ||||
| { | ||||
|   if (G_LIKELY (box != NULL)) | ||||
|     g_free (box); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_actor_box_equal: | ||||
|  * @box_a: a #ClutterActorBox | ||||
|  * @box_b: a #ClutterActorBox | ||||
|  * | ||||
|  * Checks @box_a and @box_b for equality | ||||
|  * | ||||
|  * Return value: %TRUE if the passed #ClutterActorBox are equal | ||||
|  */ | ||||
| gboolean | ||||
| clutter_actor_box_equal (const ClutterActorBox *box_a, | ||||
|                          const ClutterActorBox *box_b) | ||||
| { | ||||
|   g_return_val_if_fail (box_a != NULL && box_b != NULL, FALSE); | ||||
|  | ||||
|   if (box_a == box_b) | ||||
|     return TRUE; | ||||
|  | ||||
|   return box_a->x1 == box_b->x1 && box_a->y1 == box_b->y1 && | ||||
|          box_a->x2 == box_b->x2 && box_a->y2 == box_b->y2; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_actor_box_get_x: | ||||
|  * @box: a #ClutterActorBox | ||||
|  * | ||||
|  * Retrieves the X coordinate of the origin of @box | ||||
|  * | ||||
|  * Return value: the X coordinate of the origin | ||||
|  */ | ||||
| gfloat | ||||
| clutter_actor_box_get_x (const ClutterActorBox *box) | ||||
| { | ||||
|   g_return_val_if_fail (box != NULL, 0.); | ||||
|  | ||||
|   return box->x1; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_actor_box_get_y: | ||||
|  * @box: a #ClutterActorBox | ||||
|  * | ||||
|  * Retrieves the Y coordinate of the origin of @box | ||||
|  * | ||||
|  * Return value: the Y coordinate of the origin | ||||
|  */ | ||||
| gfloat | ||||
| clutter_actor_box_get_y (const ClutterActorBox *box) | ||||
| { | ||||
|   g_return_val_if_fail (box != NULL, 0.); | ||||
|  | ||||
|   return box->y1; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_actor_box_get_width: | ||||
|  * @box: a #ClutterActorBox | ||||
|  * | ||||
|  * Retrieves the width of the @box | ||||
|  * | ||||
|  * Return value: the width of the box | ||||
|  */ | ||||
| gfloat | ||||
| clutter_actor_box_get_width (const ClutterActorBox *box) | ||||
| { | ||||
|   g_return_val_if_fail (box != NULL, 0.); | ||||
|  | ||||
|   return box->x2 - box->x1; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_actor_box_get_height: | ||||
|  * @box: a #ClutterActorBox | ||||
|  * | ||||
|  * Retrieves the height of the @box | ||||
|  * | ||||
|  * Return value: the height of the box | ||||
|  */ | ||||
| gfloat | ||||
| clutter_actor_box_get_height (const ClutterActorBox *box) | ||||
| { | ||||
|   g_return_val_if_fail (box != NULL, 0.); | ||||
|  | ||||
|   return box->y2 - box->y1; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_actor_box_get_origin: | ||||
|  * @box: a #ClutterActorBox | ||||
|  * @x: (out) (allow-none): return location for the X coordinate, or %NULL | ||||
|  * @y: (out) (allow-none): return location for the Y coordinate, or %NULL | ||||
|  * | ||||
|  * Retrieves the origin of @box | ||||
|  */ | ||||
| void | ||||
| clutter_actor_box_get_origin (const ClutterActorBox *box, | ||||
|                               gfloat                *x, | ||||
|                               gfloat                *y) | ||||
| { | ||||
|   g_return_if_fail (box != NULL); | ||||
|  | ||||
|   if (x) | ||||
|     *x = box->x1; | ||||
|  | ||||
|   if (y) | ||||
|     *y = box->y1; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_actor_box_get_size: | ||||
|  * @box: a #ClutterActorBox | ||||
|  * @width: (out) (allow-none): return location for the width, or %NULL | ||||
|  * @height: (out) (allow-none): return location for the height, or %NULL | ||||
|  * | ||||
|  * Retrieves the size of @box | ||||
|  */ | ||||
| void | ||||
| clutter_actor_box_get_size (const ClutterActorBox *box, | ||||
|                             gfloat                *width, | ||||
|                             gfloat                *height) | ||||
| { | ||||
|   g_return_if_fail (box != NULL); | ||||
|  | ||||
|   if (width) | ||||
|     *width = box->x2 - box->x1; | ||||
|  | ||||
|   if (height) | ||||
|     *height = box->y2 - box->y1; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_actor_box_get_area: | ||||
|  * @box: a #ClutterActorBox | ||||
|  * | ||||
|  * Retrieves the area of @box | ||||
|  * | ||||
|  * Return value: the area of a #ClutterActorBox, in pixels | ||||
|  */ | ||||
| gfloat | ||||
| clutter_actor_box_get_area (const ClutterActorBox *box) | ||||
| { | ||||
|   g_return_val_if_fail (box != NULL, 0.); | ||||
|  | ||||
|   return (box->x2 - box->x1) * (box->y2 - box->y1); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_actor_box_contains: | ||||
|  * @box: a #ClutterActorBox | ||||
|  * @x: X coordinate of the point | ||||
|  * @y: Y coordinate of the point | ||||
|  * | ||||
|  * Checks whether a point with @x, @y coordinates is contained | ||||
|  * within @box | ||||
|  * | ||||
|  * Return value: %TRUE if the point is contained by the #ClutterActorBox | ||||
|  */ | ||||
| gboolean | ||||
| clutter_actor_box_contains (const ClutterActorBox *box, | ||||
|                             gfloat                 x, | ||||
|                             gfloat                 y) | ||||
| { | ||||
|   g_return_val_if_fail (box != NULL, FALSE); | ||||
|  | ||||
|   return (x > box->x1 && x < box->x2) && | ||||
|          (y > box->y1 && y < box->y2); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_actor_box_from_vertices: | ||||
|  * @box: a #ClutterActorBox | ||||
|  * @verts: (array fixed-size=4): array of four #graphene_point3d_t | ||||
|  * | ||||
|  * Calculates the bounding box represented by the four vertices; for details | ||||
|  * of the vertex array see [method@Actor.get_abs_allocation_vertices]. | ||||
|  */ | ||||
| void | ||||
| clutter_actor_box_from_vertices (ClutterActorBox          *box, | ||||
|                                  const graphene_point3d_t  verts[]) | ||||
| { | ||||
|   gfloat x_1, x_2, y_1, y_2; | ||||
|  | ||||
|   g_return_if_fail (box != NULL); | ||||
|   g_return_if_fail (verts != NULL); | ||||
|  | ||||
|   /* 4-way min/max */ | ||||
|   x_1 = verts[0].x; | ||||
|   y_1 = verts[0].y; | ||||
|  | ||||
|   if (verts[1].x < x_1) | ||||
|     x_1 = verts[1].x; | ||||
|  | ||||
|   if (verts[2].x < x_1) | ||||
|     x_1 = verts[2].x; | ||||
|  | ||||
|   if (verts[3].x < x_1) | ||||
|     x_1 = verts[3].x; | ||||
|  | ||||
|   if (verts[1].y < y_1) | ||||
|     y_1 = verts[1].y; | ||||
|  | ||||
|   if (verts[2].y < y_1) | ||||
|     y_1 = verts[2].y; | ||||
|  | ||||
|   if (verts[3].y < y_1) | ||||
|     y_1 = verts[3].y; | ||||
|  | ||||
|   x_2 = verts[0].x; | ||||
|   y_2 = verts[0].y; | ||||
|  | ||||
|   if (verts[1].x > x_2) | ||||
|     x_2 = verts[1].x; | ||||
|  | ||||
|   if (verts[2].x > x_2) | ||||
|     x_2 = verts[2].x; | ||||
|  | ||||
|   if (verts[3].x > x_2) | ||||
|     x_2 = verts[3].x; | ||||
|  | ||||
|   if (verts[1].y > y_2) | ||||
|     y_2 = verts[1].y; | ||||
|  | ||||
|   if (verts[2].y > y_2) | ||||
|     y_2 = verts[2].y; | ||||
|  | ||||
|   if (verts[3].y > y_2) | ||||
|     y_2 = verts[3].y; | ||||
|  | ||||
|   box->x1 = x_1; | ||||
|   box->x2 = x_2; | ||||
|   box->y1 = y_1; | ||||
|   box->y2 = y_2; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_actor_box_interpolate: | ||||
|  * @initial: the initial #ClutterActorBox | ||||
|  * @final: the final #ClutterActorBox | ||||
|  * @progress: the interpolation progress | ||||
|  * @result: (out): return location for the interpolation | ||||
|  * | ||||
|  * Interpolates between @initial and @final `ClutterActorBox`es | ||||
|  * using @progress | ||||
|  */ | ||||
| void | ||||
| clutter_actor_box_interpolate (const ClutterActorBox *initial, | ||||
|                                const ClutterActorBox *final, | ||||
|                                gdouble                progress, | ||||
|                                ClutterActorBox       *result) | ||||
| { | ||||
|   g_return_if_fail (initial != NULL); | ||||
|   g_return_if_fail (final != NULL); | ||||
|   g_return_if_fail (result != NULL); | ||||
|  | ||||
|   result->x1 = initial->x1 + (final->x1 - initial->x1) * progress; | ||||
|   result->y1 = initial->y1 + (final->y1 - initial->y1) * progress; | ||||
|   result->x2 = initial->x2 + (final->x2 - initial->x2) * progress; | ||||
|   result->y2 = initial->y2 + (final->y2 - initial->y2) * progress; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_actor_box_clamp_to_pixel: | ||||
|  * @box: (inout): the #ClutterActorBox to clamp | ||||
|  * | ||||
|  * Clamps the components of @box to the nearest integer | ||||
|  */ | ||||
| void | ||||
| clutter_actor_box_clamp_to_pixel (ClutterActorBox *box) | ||||
| { | ||||
|   g_return_if_fail (box != NULL); | ||||
|  | ||||
|   box->x1 = floorf (box->x1); | ||||
|   box->y1 = floorf (box->y1); | ||||
|   box->x2 = ceilf (box->x2); | ||||
|   box->y2 = ceilf (box->y2); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_actor_box_union: | ||||
|  * @a: (in): the first #ClutterActorBox | ||||
|  * @b: (in): the second #ClutterActorBox | ||||
|  * @result: (out): the #ClutterActorBox representing a union | ||||
|  *   of @a and @b | ||||
|  * | ||||
|  * Unions the two boxes @a and @b and stores the result in @result. | ||||
|  */ | ||||
| void | ||||
| clutter_actor_box_union (const ClutterActorBox *a, | ||||
|                          const ClutterActorBox *b, | ||||
|                          ClutterActorBox       *result) | ||||
| { | ||||
|   g_return_if_fail (a != NULL); | ||||
|   g_return_if_fail (b != NULL); | ||||
|   g_return_if_fail (result != NULL); | ||||
|  | ||||
|   result->x1 = MIN (a->x1, b->x1); | ||||
|   result->y1 = MIN (a->y1, b->y1); | ||||
|  | ||||
|   result->x2 = MAX (a->x2, b->x2); | ||||
|   result->y2 = MAX (a->y2, b->y2); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| clutter_actor_box_progress (const GValue *a, | ||||
|                             const GValue *b, | ||||
|                             gdouble       factor, | ||||
|                             GValue       *retval) | ||||
| { | ||||
|   ClutterActorBox res = { 0, }; | ||||
|  | ||||
|   clutter_actor_box_interpolate (g_value_get_boxed (a), | ||||
|                                  g_value_get_boxed (b), | ||||
|                                  factor, | ||||
|                                  &res); | ||||
|  | ||||
|   g_value_set_boxed (retval, &res); | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_actor_box_set_origin: | ||||
|  * @box: a #ClutterActorBox | ||||
|  * @x: the X coordinate of the new origin | ||||
|  * @y: the Y coordinate of the new origin | ||||
|  * | ||||
|  * Changes the origin of @box, maintaining the size of the #ClutterActorBox. | ||||
|  */ | ||||
| void | ||||
| clutter_actor_box_set_origin (ClutterActorBox *box, | ||||
|                               gfloat           x, | ||||
|                               gfloat           y) | ||||
| { | ||||
|   gfloat width, height; | ||||
|  | ||||
|   g_return_if_fail (box != NULL); | ||||
|  | ||||
|   width = box->x2 - box->x1; | ||||
|   height = box->y2 - box->y1; | ||||
|  | ||||
|   clutter_actor_box_init_rect (box, x, y, width, height); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_actor_box_set_size: | ||||
|  * @box: a #ClutterActorBox | ||||
|  * @width: the new width | ||||
|  * @height: the new height | ||||
|  * | ||||
|  * Sets the size of @box, maintaining the origin of the #ClutterActorBox. | ||||
|  */ | ||||
| void | ||||
| clutter_actor_box_set_size (ClutterActorBox *box, | ||||
|                             gfloat           width, | ||||
|                             gfloat           height) | ||||
| { | ||||
|   g_return_if_fail (box != NULL); | ||||
|  | ||||
|   box->x2 = box->x1 + width; | ||||
|   box->y2 = box->y1 + height; | ||||
| } | ||||
|  | ||||
| void | ||||
| _clutter_actor_box_enlarge_for_effects (ClutterActorBox *box) | ||||
| { | ||||
|   float width, height; | ||||
|  | ||||
|   if (clutter_actor_box_get_area (box) == 0.0) | ||||
|     return; | ||||
|  | ||||
|   /* The aim here is that for a given rectangle defined with floating point | ||||
|    * coordinates we want to determine a stable quantized size in pixels | ||||
|    * that doesn't vary due to the original box's sub-pixel position. | ||||
|    * | ||||
|    * The reason this is important is because effects will use this | ||||
|    * API to determine the size of offscreen framebuffers and so for | ||||
|    * a fixed-size object that may be animated across the screen we | ||||
|    * want to make sure that the stage paint-box has an equally stable | ||||
|    * size so that effects aren't made to continuously re-allocate | ||||
|    * a corresponding fbo. | ||||
|    * | ||||
|    * The other thing we consider is that the calculation of this box is | ||||
|    * subject to floating point precision issues that might be slightly | ||||
|    * different to the precision issues involved with actually painting the | ||||
|    * actor, which might result in painting slightly leaking outside the | ||||
|    * user's calculated paint-volume. For this we simply aim to pad out the | ||||
|    * paint-volume by at least half a pixel all the way around. | ||||
|    */ | ||||
|   width = box->x2 - box->x1; | ||||
|   height = box->y2 - box->y1; | ||||
|   width = CLUTTER_NEARBYINT (width); | ||||
|   height = CLUTTER_NEARBYINT (height); | ||||
|   /* XXX: NB the width/height may now be up to 0.5px too small so we | ||||
|    * must also pad by 0.25px all around to account for this. In total we | ||||
|    * must padd by at least 0.75px around all sides. */ | ||||
|  | ||||
|   /* XXX: The furthest that we can overshoot the bottom right corner by | ||||
|    * here is 1.75px in total if you consider that the 0.75 padding could | ||||
|    * just cross an integer boundary and so ceil will effectively add 1. | ||||
|    */ | ||||
|   box->x2 = ceilf (box->x2 + 0.75); | ||||
|   box->y2 = ceilf (box->y2 + 0.75); | ||||
|  | ||||
|   /* Now we redefine the top-left relative to the bottom right based on the | ||||
|    * rounded width/height determined above + a constant so that the overall | ||||
|    * size of the box will be stable and not dependent on the box's | ||||
|    * position. | ||||
|    * | ||||
|    * Adding 3px to the width/height will ensure we cover the maximum of | ||||
|    * 1.75px padding on the bottom/right and still ensure we have > 0.75px | ||||
|    * padding on the top/left. | ||||
|    */ | ||||
|   box->x1 = box->x2 - width - 3; | ||||
|   box->y1 = box->y2 - height - 3; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_actor_box_scale: | ||||
|  * @box: a #ClutterActorBox | ||||
|  * @scale: scale factor for resizing this box | ||||
|  * | ||||
|  * Rescale the @box by provided @scale factor. | ||||
|  */ | ||||
| void | ||||
| clutter_actor_box_scale (ClutterActorBox *box, | ||||
|                          gfloat           scale) | ||||
| { | ||||
|   g_return_if_fail (box != NULL); | ||||
|  | ||||
|   box->x1 *= scale; | ||||
|   box->x2 *= scale; | ||||
|   box->y1 *= scale; | ||||
|   box->y2 *= scale; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_actor_box_is_initialized: | ||||
|  * @box: a #ClutterActorBox | ||||
|  * | ||||
|  * Checks if @box has been initialized, a #ClutterActorBox is uninitialized | ||||
|  * if it has a size of -1 at an origin of 0, 0. | ||||
|  * | ||||
|  * Returns: %TRUE if the box is uninitialized, %FALSE if it isn't | ||||
|  */ | ||||
| gboolean | ||||
| clutter_actor_box_is_initialized (ClutterActorBox *box) | ||||
| { | ||||
|   gboolean x1_uninitialized, x2_uninitialized; | ||||
|   gboolean y1_uninitialized, y2_uninitialized; | ||||
|  | ||||
|   g_return_val_if_fail (box != NULL, TRUE); | ||||
|  | ||||
|   x1_uninitialized = isinf (box->x1); | ||||
|   x2_uninitialized = isinf (box->x2) && signbit (box->x2); | ||||
|   y1_uninitialized = isinf (box->y1); | ||||
|   y2_uninitialized = isinf (box->y2) && signbit (box->y2); | ||||
|  | ||||
|   return !x1_uninitialized || !x2_uninitialized || | ||||
|          !y1_uninitialized || !y2_uninitialized; | ||||
| } | ||||
|  | ||||
| G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterActorBox, clutter_actor_box, | ||||
|                                clutter_actor_box_copy, | ||||
|                                clutter_actor_box_free, | ||||
|                                CLUTTER_REGISTER_INTERVAL_PROGRESS (clutter_actor_box_progress)); | ||||
| @@ -1,82 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2010  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> | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "clutter/clutter-actor-meta.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CLUTTER_TYPE_META_GROUP         (_clutter_meta_group_get_type ()) | ||||
|  | ||||
|  | ||||
| struct _ClutterMetaGroup | ||||
| { | ||||
|   GObject parent_instance; | ||||
|  | ||||
|   ClutterActor *actor; | ||||
|  | ||||
|   GList *meta; | ||||
| }; | ||||
|  | ||||
| G_DECLARE_FINAL_TYPE (ClutterMetaGroup, | ||||
|                       _clutter_meta_group, | ||||
|                       CLUTTER, META_GROUP, | ||||
|                       GObject) | ||||
|  | ||||
| /* Each actor meta has a priority with zero as a default. A higher | ||||
|    number means higher priority. Higher priority metas stay at the | ||||
|    beginning of the list. The priority can be negative to give lower | ||||
|    priority than the default. */ | ||||
|  | ||||
| #define CLUTTER_ACTOR_META_PRIORITY_DEFAULT 0 | ||||
|  | ||||
| /* Any value greater than this is considered an 'internal' priority | ||||
|    and if we expose the priority property publicly then an application | ||||
|    would not be able to use these values. */ | ||||
|  | ||||
| #define CLUTTER_ACTOR_META_PRIORITY_INTERNAL_HIGH (G_MAXINT / 2) | ||||
| #define CLUTTER_ACTOR_META_PRIORITY_INTERNAL_LOW (G_MININT / 2) | ||||
|  | ||||
| void                    _clutter_meta_group_add_meta    (ClutterMetaGroup *group, | ||||
|                                                          ClutterActorMeta *meta); | ||||
| void                    _clutter_meta_group_remove_meta (ClutterMetaGroup *group, | ||||
|                                                          ClutterActorMeta *meta); | ||||
| const GList *           _clutter_meta_group_peek_metas  (ClutterMetaGroup *group); | ||||
| void                    _clutter_meta_group_clear_metas (ClutterMetaGroup *group); | ||||
| ClutterActorMeta *      _clutter_meta_group_get_meta    (ClutterMetaGroup *group, | ||||
|                                                          const gchar      *name); | ||||
|  | ||||
| gboolean                _clutter_meta_group_has_metas_no_internal (ClutterMetaGroup *group); | ||||
|  | ||||
| GList *                 _clutter_meta_group_get_metas_no_internal   (ClutterMetaGroup *group); | ||||
| void                    _clutter_meta_group_clear_metas_no_internal (ClutterMetaGroup *group); | ||||
|  | ||||
| /* ActorMeta */ | ||||
| const gchar *           _clutter_actor_meta_get_debug_name      (ClutterActorMeta *meta); | ||||
|  | ||||
| void                    _clutter_actor_meta_set_priority        (ClutterActorMeta *meta, | ||||
|                                                                  gint priority); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,702 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2010  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> | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * ClutterActorMeta: | ||||
|  *  | ||||
|  * Base class of actor modifiers | ||||
|  * | ||||
|  * #ClutterActorMeta is an abstract class providing a common API for | ||||
|  * modifiers of [class@Actor] behaviour, appearance or layout. | ||||
|  * | ||||
|  * A #ClutterActorMeta can only be owned by a single [class@Actor] at | ||||
|  * any time. | ||||
|  * | ||||
|  * Every sub-class of #ClutterActorMeta should check if the | ||||
|  * [property@ActorMeta:enabled] property is set to %TRUE before applying | ||||
|  * any kind of modification. | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "clutter/clutter-actor-meta-private.h" | ||||
|  | ||||
| #include "clutter/clutter-debug.h" | ||||
| #include "clutter/clutter-private.h" | ||||
|  | ||||
| struct _ClutterActorMetaPrivate | ||||
| { | ||||
|   ClutterActor *actor; | ||||
|   gulong destroy_id; | ||||
|  | ||||
|   gchar *name; | ||||
|  | ||||
|   guint is_enabled : 1; | ||||
|  | ||||
|   gint priority; | ||||
| }; | ||||
|  | ||||
| enum | ||||
| { | ||||
|   PROP_0, | ||||
|  | ||||
|   PROP_ACTOR, | ||||
|   PROP_NAME, | ||||
|   PROP_ENABLED, | ||||
|  | ||||
|   PROP_LAST | ||||
| }; | ||||
|  | ||||
| static GParamSpec *obj_props[PROP_LAST]; | ||||
|  | ||||
| G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterActorMeta, | ||||
|                                      clutter_actor_meta, | ||||
|                                      G_TYPE_INITIALLY_UNOWNED) | ||||
|  | ||||
| static void | ||||
| on_actor_destroy (ClutterActor     *actor, | ||||
|                   ClutterActorMeta *meta) | ||||
| { | ||||
|   ClutterActorMetaPrivate *priv = | ||||
|     clutter_actor_meta_get_instance_private (meta); | ||||
|  | ||||
|   priv->actor = NULL; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_actor_meta_real_set_actor (ClutterActorMeta *meta, | ||||
|                                    ClutterActor     *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 (priv->actor == actor) | ||||
|     return; | ||||
|  | ||||
|   g_clear_signal_handler (&priv->destroy_id, priv->actor); | ||||
|  | ||||
|   priv->actor = actor; | ||||
|  | ||||
|   if (priv->actor != NULL) | ||||
|     priv->destroy_id = g_signal_connect (priv->actor, "destroy", | ||||
|                                          G_CALLBACK (on_actor_destroy), | ||||
|                                          meta); | ||||
|  | ||||
|   g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_ACTOR]); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_actor_meta_real_set_enabled (ClutterActorMeta *meta, | ||||
|                                      gboolean          is_enabled) | ||||
| { | ||||
|   ClutterActorMetaPrivate *priv = | ||||
|     clutter_actor_meta_get_instance_private (meta); | ||||
|  | ||||
|   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]); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_actor_meta_set_property (GObject      *gobject, | ||||
|                                  guint         prop_id, | ||||
|                                  const GValue *value, | ||||
|                                  GParamSpec   *pspec) | ||||
| { | ||||
|   ClutterActorMeta *meta = CLUTTER_ACTOR_META (gobject); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_NAME: | ||||
|       clutter_actor_meta_set_name (meta, g_value_get_string (value)); | ||||
|       break; | ||||
|  | ||||
|     case PROP_ENABLED: | ||||
|       clutter_actor_meta_set_enabled (meta, g_value_get_boolean (value)); | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_actor_meta_get_property (GObject    *gobject, | ||||
|                                  guint       prop_id, | ||||
|                                  GValue     *value, | ||||
|                                  GParamSpec *pspec) | ||||
| { | ||||
|   ClutterActorMetaPrivate *priv = | ||||
|     clutter_actor_meta_get_instance_private (CLUTTER_ACTOR_META (gobject)); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_ACTOR: | ||||
|       g_value_set_object (value, priv->actor); | ||||
|       break; | ||||
|  | ||||
|     case PROP_NAME: | ||||
|       g_value_set_string (value, priv->name); | ||||
|       break; | ||||
|  | ||||
|     case PROP_ENABLED: | ||||
|       g_value_set_boolean (value, priv->is_enabled); | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_actor_meta_finalize (GObject *gobject) | ||||
| { | ||||
|   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); | ||||
|  | ||||
|   g_free (priv->name); | ||||
|  | ||||
|   G_OBJECT_CLASS (clutter_actor_meta_parent_class)->finalize (gobject); | ||||
| } | ||||
|  | ||||
| void | ||||
| clutter_actor_meta_class_init (ClutterActorMetaClass *klass) | ||||
| { | ||||
|   GObjectClass *gobject_class = G_OBJECT_CLASS (klass); | ||||
|  | ||||
|   klass->set_actor = clutter_actor_meta_real_set_actor; | ||||
|   klass->set_enabled = clutter_actor_meta_real_set_enabled; | ||||
|  | ||||
|   /** | ||||
|    * ClutterActorMeta:actor: | ||||
|    * | ||||
|    * The #ClutterActor attached to the #ClutterActorMeta instance | ||||
|    */ | ||||
|   obj_props[PROP_ACTOR] = | ||||
|     g_param_spec_object ("actor", NULL, NULL, | ||||
|                          CLUTTER_TYPE_ACTOR, | ||||
|                          G_PARAM_READABLE | | ||||
|                          G_PARAM_STATIC_STRINGS | | ||||
|                          G_PARAM_EXPLICIT_NOTIFY); | ||||
|  | ||||
|   /** | ||||
|    * ClutterActorMeta:name: | ||||
|    * | ||||
|    * The unique name to access the #ClutterActorMeta | ||||
|    */ | ||||
|   obj_props[PROP_NAME] = | ||||
|     g_param_spec_string ("name", NULL, NULL, | ||||
|                          NULL, | ||||
|                          G_PARAM_READWRITE | | ||||
|                          G_PARAM_STATIC_STRINGS); | ||||
|  | ||||
|   /** | ||||
|    * ClutterActorMeta:enabled: | ||||
|    * | ||||
|    * Whether or not the #ClutterActorMeta is enabled | ||||
|    */ | ||||
|   obj_props[PROP_ENABLED] = | ||||
|     g_param_spec_boolean ("enabled", NULL, NULL, | ||||
|                           TRUE, | ||||
|                           G_PARAM_READWRITE | | ||||
|                           G_PARAM_STATIC_STRINGS); | ||||
|  | ||||
|   gobject_class->finalize = clutter_actor_meta_finalize; | ||||
|   gobject_class->set_property = clutter_actor_meta_set_property; | ||||
|   gobject_class->get_property = clutter_actor_meta_get_property; | ||||
|   g_object_class_install_properties (gobject_class, | ||||
|                                      PROP_LAST, | ||||
|                                      obj_props); | ||||
| } | ||||
|  | ||||
| void | ||||
| clutter_actor_meta_init (ClutterActorMeta *self) | ||||
| { | ||||
|   ClutterActorMetaPrivate *priv = | ||||
|     clutter_actor_meta_get_instance_private (self); | ||||
|  | ||||
|   priv->is_enabled = TRUE; | ||||
|   priv->priority = CLUTTER_ACTOR_META_PRIORITY_DEFAULT; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_actor_meta_set_name: | ||||
|  * @meta: a #ClutterActorMeta | ||||
|  * @name: the name of @meta | ||||
|  * | ||||
|  * Sets the name of @meta | ||||
|  * | ||||
|  * The name can be used to identify the #ClutterActorMeta instance | ||||
|  */ | ||||
| void | ||||
| clutter_actor_meta_set_name (ClutterActorMeta *meta, | ||||
|                              const gchar      *name) | ||||
| { | ||||
|   ClutterActorMetaPrivate *priv; | ||||
|  | ||||
|   g_return_if_fail (CLUTTER_IS_ACTOR_META (meta)); | ||||
|  | ||||
|   priv = clutter_actor_meta_get_instance_private (meta); | ||||
|  | ||||
|   if (g_strcmp0 (priv->name, name) == 0) | ||||
|     return; | ||||
|  | ||||
|   g_free (priv->name); | ||||
|   priv->name = g_strdup (name); | ||||
|  | ||||
|   g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_NAME]); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_actor_meta_get_name: | ||||
|  * @meta: a #ClutterActorMeta | ||||
|  * | ||||
|  * Retrieves the name set using [method@ActorMeta.set_name] | ||||
|  * | ||||
|  * Return value: (transfer none): the name of the #ClutterActorMeta | ||||
|  *   instance, or %NULL if none was set. The returned string is owned | ||||
|  *   by the #ClutterActorMeta instance and it should not be modified | ||||
|  *   or freed | ||||
|  */ | ||||
| const gchar * | ||||
| clutter_actor_meta_get_name (ClutterActorMeta *meta) | ||||
| { | ||||
|   ClutterActorMetaPrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), NULL); | ||||
|  | ||||
|   priv = clutter_actor_meta_get_instance_private (meta); | ||||
|  | ||||
|   return priv->name; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_actor_meta_set_enabled: | ||||
|  * @meta: a #ClutterActorMeta | ||||
|  * @is_enabled: whether @meta is enabled | ||||
|  * | ||||
|  * Sets whether @meta should be enabled or not | ||||
|  */ | ||||
| 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 (priv->is_enabled == is_enabled) | ||||
|     return; | ||||
|  | ||||
|   CLUTTER_ACTOR_META_GET_CLASS (meta)->set_enabled (meta, is_enabled); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_actor_meta_get_enabled: | ||||
|  * @meta: a #ClutterActorMeta | ||||
|  * | ||||
|  * Retrieves whether @meta is enabled | ||||
|  * | ||||
|  * Return value: %TRUE if the #ClutterActorMeta instance is enabled | ||||
|  */ | ||||
| gboolean | ||||
| clutter_actor_meta_get_enabled (ClutterActorMeta *meta) | ||||
| { | ||||
|   ClutterActorMetaPrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), FALSE); | ||||
|  | ||||
|   priv = clutter_actor_meta_get_instance_private (meta); | ||||
|  | ||||
|   return priv->is_enabled; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * _clutter_actor_meta_set_actor | ||||
|  * @meta: a #ClutterActorMeta | ||||
|  * @actor: a #ClutterActor or %NULL | ||||
|  * | ||||
|  * Sets or unsets a back pointer to the #ClutterActor that owns | ||||
|  * the @meta | ||||
|  */ | ||||
| static void | ||||
| _clutter_actor_meta_set_actor (ClutterActorMeta *meta, | ||||
|                                ClutterActor     *actor) | ||||
| { | ||||
|   g_return_if_fail (CLUTTER_IS_ACTOR_META (meta)); | ||||
|   g_return_if_fail (actor == NULL || CLUTTER_IS_ACTOR (actor)); | ||||
|  | ||||
|   CLUTTER_ACTOR_META_GET_CLASS (meta)->set_actor (meta, actor); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_actor_meta_get_actor: | ||||
|  * @meta: a #ClutterActorMeta | ||||
|  * | ||||
|  * Retrieves a pointer to the [class@Actor] that owns @meta | ||||
|  * | ||||
|  * Return value: (transfer none): a pointer to a #ClutterActor or %NULL | ||||
|  */ | ||||
| ClutterActor * | ||||
| clutter_actor_meta_get_actor (ClutterActorMeta *meta) | ||||
| { | ||||
|   ClutterActorMetaPrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), NULL); | ||||
|  | ||||
|   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 (priv->actor == NULL); | ||||
|  | ||||
|   priv->priority = priority; | ||||
| } | ||||
|  | ||||
| static gint | ||||
| _clutter_actor_meta_get_priority (ClutterActorMeta *meta) | ||||
| { | ||||
|   ClutterActorMetaPrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), 0); | ||||
|  | ||||
|   priv = clutter_actor_meta_get_instance_private (meta); | ||||
|  | ||||
|   return priv->priority; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| _clutter_actor_meta_is_internal (ClutterActorMeta *meta) | ||||
| { | ||||
|   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); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * ClutterMetaGroup: a collection of ClutterActorMeta instances | ||||
|  */ | ||||
|  | ||||
| G_DEFINE_FINAL_TYPE (ClutterMetaGroup, _clutter_meta_group, G_TYPE_OBJECT); | ||||
|  | ||||
| static void | ||||
| _clutter_meta_group_dispose (GObject *gobject) | ||||
| { | ||||
|   _clutter_meta_group_clear_metas (CLUTTER_META_GROUP (gobject)); | ||||
|  | ||||
|   G_OBJECT_CLASS (_clutter_meta_group_parent_class)->dispose (gobject); | ||||
| } | ||||
|  | ||||
| static void | ||||
| _clutter_meta_group_class_init (ClutterMetaGroupClass *klass) | ||||
| { | ||||
|   GObjectClass *gobject_class = G_OBJECT_CLASS (klass); | ||||
|  | ||||
|   gobject_class->dispose = _clutter_meta_group_dispose; | ||||
| } | ||||
|  | ||||
| static void | ||||
| _clutter_meta_group_init (ClutterMetaGroup *self) | ||||
| { | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * _clutter_meta_group_add_meta: | ||||
|  * @group: a #ClutterMetaGroup | ||||
|  * @meta: a #ClutterActorMeta to add | ||||
|  * | ||||
|  * Adds @meta to @group | ||||
|  * | ||||
|  * This function will remove the floating reference of @meta or, if the | ||||
|  * floating reference has already been sunk, add a reference to it | ||||
|  */ | ||||
| void | ||||
| _clutter_meta_group_add_meta (ClutterMetaGroup *group, | ||||
|                               ClutterActorMeta *meta) | ||||
| { | ||||
|   ClutterActorMetaPrivate *priv = | ||||
|     clutter_actor_meta_get_instance_private (meta); | ||||
|   GList *prev = NULL, *l; | ||||
|  | ||||
|   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), | ||||
|                  priv->name != NULL | ||||
|                    ? priv->name | ||||
|                    : "<unknown>", | ||||
|                  clutter_actor_get_name (priv->actor) != NULL | ||||
|                    ? clutter_actor_get_name (priv->actor) | ||||
|                    : G_OBJECT_TYPE_NAME (priv->actor)); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   /* Find a meta that has lower priority and insert before that */ | ||||
|   for (l = group->meta; l; l = l->next) | ||||
|     if (_clutter_actor_meta_get_priority (l->data) < | ||||
|         _clutter_actor_meta_get_priority (meta)) | ||||
|       break; | ||||
|     else | ||||
|       prev = l; | ||||
|  | ||||
|   if (prev == NULL) | ||||
|     group->meta = g_list_prepend (group->meta, meta); | ||||
|   else | ||||
|     { | ||||
|       prev->next = g_list_prepend (prev->next, meta); | ||||
|       prev->next->prev = prev; | ||||
|     } | ||||
|  | ||||
|   g_object_ref_sink (meta); | ||||
|  | ||||
|   _clutter_actor_meta_set_actor (meta, group->actor); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * _clutter_meta_group_remove_meta: | ||||
|  * @group: a #ClutterMetaGroup | ||||
|  * @meta: a #ClutterActorMeta to remove | ||||
|  * | ||||
|  * Removes @meta from @group and releases the reference being held on it | ||||
|  */ | ||||
| void | ||||
| _clutter_meta_group_remove_meta (ClutterMetaGroup *group, | ||||
|                                  ClutterActorMeta *meta) | ||||
| { | ||||
|   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), | ||||
|                  priv->name != NULL | ||||
|                    ? priv->name | ||||
|                    : "<unknown>", | ||||
|                  clutter_actor_get_name (group->actor) != NULL | ||||
|                    ? clutter_actor_get_name (group->actor) | ||||
|                    : G_OBJECT_TYPE_NAME (group->actor)); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   _clutter_actor_meta_set_actor (meta, NULL); | ||||
|  | ||||
|   group->meta = g_list_remove (group->meta, meta); | ||||
|   g_object_unref (meta); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * _clutter_meta_group_peek_metas: | ||||
|  * @group: a #ClutterMetaGroup | ||||
|  * | ||||
|  * Returns a pointer to the #ClutterActorMeta list | ||||
|  * | ||||
|  * Return value: a const pointer to the #GList of #ClutterActorMeta | ||||
|  */ | ||||
| const GList * | ||||
| _clutter_meta_group_peek_metas (ClutterMetaGroup *group) | ||||
| { | ||||
|   return group->meta; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * _clutter_meta_group_get_metas_no_internal: | ||||
|  * @group: a #ClutterMetaGroup | ||||
|  * | ||||
|  * Returns a new allocated list containing all of the metas that don't | ||||
|  * have an internal priority. | ||||
|  * | ||||
|  * Return value: A GList containing non-internal metas. Free with | ||||
|  * g_list_free. | ||||
|  */ | ||||
| GList * | ||||
| _clutter_meta_group_get_metas_no_internal (ClutterMetaGroup *group) | ||||
| { | ||||
|   GList *ret = NULL; | ||||
|   GList *l; | ||||
|  | ||||
|   /* Build a new list filtering out the internal metas */ | ||||
|   for (l = group->meta; l; l = l->next) | ||||
|     if (!_clutter_actor_meta_is_internal (l->data)) | ||||
|       ret = g_list_prepend (ret, l->data); | ||||
|  | ||||
|   return g_list_reverse (ret); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * _clutter_meta_group_has_metas_no_internal: | ||||
|  * @group: a #ClutterMetaGroup | ||||
|  * | ||||
|  * Returns whether the group has any metas that don't have an internal priority. | ||||
|  * | ||||
|  * Return value: %TRUE if metas without internal priority exist | ||||
|  *   %FALSE otherwise | ||||
|  */ | ||||
| gboolean | ||||
| _clutter_meta_group_has_metas_no_internal (ClutterMetaGroup *group) | ||||
| { | ||||
|   GList *l; | ||||
|  | ||||
|   for (l = group->meta; l; l = l->next) | ||||
|     if (!_clutter_actor_meta_is_internal (l->data)) | ||||
|       return TRUE; | ||||
|  | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * _clutter_meta_group_clear_metas: | ||||
|  * @group: a #ClutterMetaGroup | ||||
|  * | ||||
|  * Clears @group of all #ClutterActorMeta instances and releases | ||||
|  * the reference on them | ||||
|  */ | ||||
| void | ||||
| _clutter_meta_group_clear_metas (ClutterMetaGroup *group) | ||||
| { | ||||
|   g_list_foreach (group->meta, (GFunc) _clutter_actor_meta_set_actor, NULL); | ||||
|  | ||||
|   g_list_free_full (group->meta, g_object_unref); | ||||
|   group->meta = NULL; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * _clutter_meta_group_clear_metas_no_internal: | ||||
|  * @group: a #ClutterMetaGroup | ||||
|  * | ||||
|  * Clears @group of all #ClutterActorMeta instances that don't have an | ||||
|  * internal priority and releases the reference on them | ||||
|  */ | ||||
| void | ||||
| _clutter_meta_group_clear_metas_no_internal (ClutterMetaGroup *group) | ||||
| { | ||||
|   GList *internal_list = NULL; | ||||
|   GList *l, *next; | ||||
|  | ||||
|   for (l = group->meta; l; l = next) | ||||
|     { | ||||
|       next = l->next; | ||||
|  | ||||
|       if (_clutter_actor_meta_is_internal (l->data)) | ||||
|         { | ||||
|           if (internal_list) | ||||
|             internal_list->prev = l; | ||||
|           l->next = internal_list; | ||||
|           l->prev = NULL; | ||||
|           internal_list = l; | ||||
|         } | ||||
|       else | ||||
|         { | ||||
|           _clutter_actor_meta_set_actor (l->data, NULL); | ||||
|           g_object_unref (l->data); | ||||
|           g_list_free_1 (l); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   group->meta = g_list_reverse (internal_list); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * _clutter_meta_group_get_meta: | ||||
|  * @group: a #ClutterMetaGroup | ||||
|  * @name: the name of the #ClutterActorMeta to retrieve | ||||
|  * | ||||
|  * Retrieves a named #ClutterActorMeta from @group | ||||
|  * | ||||
|  * Return value: a #ClutterActorMeta for the given name, or %NULL | ||||
|  */ | ||||
| ClutterActorMeta * | ||||
| _clutter_meta_group_get_meta (ClutterMetaGroup *group, | ||||
|                               const gchar      *name) | ||||
| { | ||||
|   GList *l; | ||||
|  | ||||
|   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 (priv->name, name) == 0) | ||||
|         return meta; | ||||
|     } | ||||
|  | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| /*< private > | ||||
|  * clutter_actor_meta_get_debug_name: | ||||
|  * @meta: a #ClutterActorMeta | ||||
|  * | ||||
|  * Retrieves the name of the @meta for debugging purposes. | ||||
|  * | ||||
|  * Return value: (transfer none): the name of the @meta. The returned | ||||
|  *   string is owned by the @meta instance and it should not be | ||||
|  *   modified or freed | ||||
|  */ | ||||
| const gchar * | ||||
| _clutter_actor_meta_get_debug_name (ClutterActorMeta *meta) | ||||
| { | ||||
|   ClutterActorMetaPrivate *priv = | ||||
|     clutter_actor_meta_get_instance_private (meta); | ||||
|  | ||||
|   return priv->name != NULL ? priv->name : G_OBJECT_TYPE_NAME (meta); | ||||
| } | ||||
| @@ -1,87 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2010  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> | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <clutter/clutter.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include "clutter/clutter-types.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CLUTTER_TYPE_ACTOR_META (clutter_actor_meta_get_type ()) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_DERIVABLE_TYPE (ClutterActorMeta, clutter_actor_meta, | ||||
|                           CLUTTER, ACTOR_META, GInitiallyUnowned); | ||||
|  | ||||
| typedef struct _ClutterActorMetaPrivate ClutterActorMetaPrivate; | ||||
|  | ||||
| /** | ||||
|  * ClutterActorMetaClass: | ||||
|  * @set_actor: virtual function, invoked when attaching and detaching | ||||
|  *   a #ClutterActorMeta instance to a #ClutterActor | ||||
|  * | ||||
|  * The #ClutterActorMetaClass structure contains | ||||
|  * only private data | ||||
|  */ | ||||
| struct _ClutterActorMetaClass | ||||
| { | ||||
|   /*< private >*/ | ||||
|   GInitiallyUnownedClass parent_class; | ||||
|  | ||||
|   /*< public >*/ | ||||
|  | ||||
|   /** | ||||
|    * ClutterActorMetaClass::set_actor: | ||||
|    * @meta: a #ClutterActorMeta | ||||
|    * @actor: (allow-none): the actor attached to @meta, or %NULL | ||||
|    * | ||||
|    * Virtual function, called when @meta is attached or detached | ||||
|    * from a #ClutterActor. | ||||
|    */ | ||||
|   void (* set_actor) (ClutterActorMeta *meta, | ||||
|                       ClutterActor     *actor); | ||||
|  | ||||
|   void (* set_enabled) (ClutterActorMeta *meta, | ||||
|                         gboolean          is_enabled); | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void            clutter_actor_meta_set_name     (ClutterActorMeta *meta, | ||||
|                                                  const gchar      *name); | ||||
| CLUTTER_EXPORT | ||||
| const gchar *   clutter_actor_meta_get_name     (ClutterActorMeta *meta); | ||||
| CLUTTER_EXPORT | ||||
| void            clutter_actor_meta_set_enabled  (ClutterActorMeta *meta, | ||||
|                                                  gboolean          is_enabled); | ||||
| CLUTTER_EXPORT | ||||
| gboolean        clutter_actor_meta_get_enabled  (ClutterActorMeta *meta); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterActor *  clutter_actor_meta_get_actor    (ClutterActorMeta *meta); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,271 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2010  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/>. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "clutter/clutter-actor.h" | ||||
| #include "clutter/clutter-grab.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| /*< private > | ||||
|  * ClutterActorTraverseFlags: | ||||
|  * CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST: Traverse the graph in | ||||
|  *   a depth first order. | ||||
|  * CLUTTER_ACTOR_TRAVERSE_BREADTH_FIRST: Traverse the graph in a | ||||
|  *   breadth first order. | ||||
|  * | ||||
|  * Controls some options for how clutter_actor_traverse() iterates | ||||
|  * through the graph. | ||||
|  */ | ||||
| typedef enum | ||||
| { | ||||
|   CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST   = 1L<<0, | ||||
|   CLUTTER_ACTOR_TRAVERSE_BREADTH_FIRST = 1L<<1 | ||||
| } ClutterActorTraverseFlags; | ||||
|  | ||||
| /*< private > | ||||
|  * ClutterActorTraverseVisitFlags: | ||||
|  * CLUTTER_ACTOR_TRAVERSE_VISIT_CONTINUE: Continue traversing as | ||||
|  *   normal | ||||
|  * CLUTTER_ACTOR_TRAVERSE_VISIT_SKIP_CHILDREN: Don't traverse the | ||||
|  *   children of the last visited actor. (Not applicable when using | ||||
|  *   %CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST_POST_ORDER since the children | ||||
|  *   are visited before having an opportunity to bail out) | ||||
|  * CLUTTER_ACTOR_TRAVERSE_VISIT_BREAK: Immediately bail out without | ||||
|  *   visiting any more actors. | ||||
|  * | ||||
|  * Each time an actor is visited during a scenegraph traversal the | ||||
|  * ClutterTraverseCallback can return a set of flags that may affect | ||||
|  * the continuing traversal. It may stop traversal completely, just | ||||
|  * skip over children for the current actor or continue as normal. | ||||
|  */ | ||||
| typedef enum | ||||
| { | ||||
|   CLUTTER_ACTOR_TRAVERSE_VISIT_CONTINUE       = 1L<<0, | ||||
|   CLUTTER_ACTOR_TRAVERSE_VISIT_SKIP_CHILDREN  = 1L<<1, | ||||
|   CLUTTER_ACTOR_TRAVERSE_VISIT_BREAK          = 1L<<2 | ||||
| } ClutterActorTraverseVisitFlags; | ||||
|  | ||||
| /*< private > | ||||
|  * ClutterTraverseCallback: | ||||
|  * | ||||
|  * The callback prototype used with clutter_actor_traverse. The | ||||
|  * returned flags can be used to affect the continuing traversal | ||||
|  * either by continuing as normal, skipping over children of an | ||||
|  * actor or bailing out completely. | ||||
|  */ | ||||
| typedef ClutterActorTraverseVisitFlags (*ClutterTraverseCallback) (ClutterActor *actor, | ||||
|                                                                    gint          depth, | ||||
|                                                                    gpointer      user_data); | ||||
|  | ||||
| /*< private > | ||||
|  * ClutterForeachCallback: | ||||
|  * @actor: The actor being iterated | ||||
|  * @user_data: The private data specified when starting the iteration | ||||
|  * | ||||
|  * A generic callback for iterating over actor, such as with | ||||
|  * _clutter_actor_foreach_child. | ||||
|  * | ||||
|  * Return value: %TRUE to continue iterating or %FALSE to break iteration | ||||
|  * early. | ||||
|  */ | ||||
| typedef gboolean (*ClutterForeachCallback) (ClutterActor *actor, | ||||
|                                             gpointer      user_data); | ||||
|  | ||||
| typedef struct _SizeRequest             SizeRequest; | ||||
|  | ||||
| typedef struct _ClutterLayoutInfo       ClutterLayoutInfo; | ||||
| typedef struct _ClutterTransformInfo    ClutterTransformInfo; | ||||
| typedef struct _ClutterAnimationInfo    ClutterAnimationInfo; | ||||
|  | ||||
| struct _SizeRequest | ||||
| { | ||||
|   guint  age; | ||||
|   gfloat for_size; | ||||
|   gfloat min_size; | ||||
|   gfloat natural_size; | ||||
| }; | ||||
|  | ||||
| /*< private > | ||||
|  * ClutterLayoutInfo: | ||||
|  * @fixed_pos: the fixed position of the actor | ||||
|  * @margin: the composed margin of the actor | ||||
|  * @x_align: the horizontal alignment, if the actor expands horizontally | ||||
|  * @y_align: the vertical alignment, if the actor expands vertically | ||||
|  * @x_expand: whether the actor should expand horizontally | ||||
|  * @y_expand: whether the actor should expand vertically | ||||
|  * @minimum: the fixed minimum size | ||||
|  * @natural: the fixed natural size | ||||
|  * | ||||
|  * Ancillary layout information for an actor. | ||||
|  */ | ||||
| struct _ClutterLayoutInfo | ||||
| { | ||||
|   /* fixed position coordinates */ | ||||
|   graphene_point_t fixed_pos; | ||||
|  | ||||
|   ClutterMargin margin; | ||||
|  | ||||
|   guint x_align : 4; | ||||
|   guint y_align : 4; | ||||
|  | ||||
|   guint x_expand : 1; | ||||
|   guint y_expand : 1; | ||||
|  | ||||
|   graphene_size_t minimum; | ||||
|   graphene_size_t natural; | ||||
| }; | ||||
|  | ||||
| const ClutterLayoutInfo *       _clutter_actor_get_layout_info_or_defaults      (ClutterActor *self); | ||||
| ClutterLayoutInfo *             _clutter_actor_get_layout_info                  (ClutterActor *self); | ||||
| ClutterLayoutInfo *             _clutter_actor_peek_layout_info                 (ClutterActor *self); | ||||
|  | ||||
| struct _ClutterTransformInfo | ||||
| { | ||||
|   /* rotation */ | ||||
|   gdouble rx_angle; | ||||
|   gdouble ry_angle; | ||||
|   gdouble rz_angle; | ||||
|  | ||||
|   /* scaling */ | ||||
|   gdouble scale_x; | ||||
|   gdouble scale_y; | ||||
|   gdouble scale_z; | ||||
|  | ||||
|   /* translation */ | ||||
|   graphene_point3d_t translation; | ||||
|  | ||||
|   /* z_position */ | ||||
|   gfloat z_position; | ||||
|  | ||||
|   /* transformation center */ | ||||
|   graphene_point_t pivot; | ||||
|   gfloat pivot_z; | ||||
|  | ||||
|   graphene_matrix_t transform; | ||||
|   guint transform_set : 1; | ||||
|  | ||||
|   graphene_matrix_t child_transform; | ||||
|   guint child_transform_set : 1; | ||||
| }; | ||||
|  | ||||
| const ClutterTransformInfo *    _clutter_actor_get_transform_info_or_defaults   (ClutterActor *self); | ||||
| ClutterTransformInfo *          _clutter_actor_get_transform_info               (ClutterActor *self); | ||||
|  | ||||
| typedef struct _AState { | ||||
|   guint easing_duration; | ||||
|   guint easing_delay; | ||||
|   ClutterAnimationMode easing_mode; | ||||
| } AState; | ||||
|  | ||||
| struct _ClutterAnimationInfo | ||||
| { | ||||
|   GArray *states; | ||||
|   AState *cur_state; | ||||
|  | ||||
|   GHashTable *transitions; | ||||
| }; | ||||
|  | ||||
| const ClutterAnimationInfo *    _clutter_actor_get_animation_info_or_defaults           (ClutterActor *self); | ||||
| ClutterAnimationInfo *          _clutter_actor_get_animation_info                       (ClutterActor *self); | ||||
|  | ||||
| ClutterTransition *             _clutter_actor_create_transition                        (ClutterActor *self, | ||||
|                                                                                          GParamSpec   *pspec, | ||||
|                                                                                          ...); | ||||
| gboolean                        _clutter_actor_foreach_child                            (ClutterActor *self, | ||||
|                                                                                          ClutterForeachCallback callback, | ||||
|                                                                                          gpointer user_data); | ||||
| void                            _clutter_actor_traverse                                 (ClutterActor *actor, | ||||
|                                                                                          ClutterActorTraverseFlags flags, | ||||
|                                                                                          ClutterTraverseCallback before_children_callback, | ||||
|                                                                                          ClutterTraverseCallback after_children_callback, | ||||
|                                                                                          gpointer user_data); | ||||
| ClutterActor *                  _clutter_actor_get_stage_internal                       (ClutterActor *actor); | ||||
|  | ||||
| void                            _clutter_actor_apply_modelview_transform                (ClutterActor      *self, | ||||
|                                                                                          graphene_matrix_t *matrix); | ||||
| void                            _clutter_actor_apply_relative_transformation_matrix     (ClutterActor      *self, | ||||
|                                                                                          ClutterActor      *ancestor, | ||||
|                                                                                          graphene_matrix_t *matrix); | ||||
|  | ||||
| void                            _clutter_actor_set_in_clone_paint                       (ClutterActor *self, | ||||
|                                                                                          gboolean      is_in_clone_paint); | ||||
|  | ||||
| void                            _clutter_actor_set_enable_model_view_transform          (ClutterActor *self, | ||||
|                                                                                          gboolean      enable); | ||||
|  | ||||
| void                            _clutter_actor_set_enable_paint_unmapped                (ClutterActor *self, | ||||
|                                                                                          gboolean      enable); | ||||
|  | ||||
| void                            _clutter_actor_set_has_pointer                          (ClutterActor *self, | ||||
|                                                                                          gboolean      has_pointer); | ||||
|  | ||||
| void                            _clutter_actor_set_has_key_focus                        (ClutterActor *self, | ||||
|                                                                                          gboolean      has_key_focus); | ||||
|  | ||||
| void                            _clutter_actor_queue_redraw_full                        (ClutterActor             *self, | ||||
|                                                                                          const ClutterPaintVolume *volume, | ||||
|                                                                                          ClutterEffect            *effect); | ||||
|  | ||||
| gboolean                        _clutter_actor_set_default_paint_volume                 (ClutterActor       *self, | ||||
|                                                                                          GType               check_gtype, | ||||
|                                                                                          ClutterPaintVolume *volume); | ||||
|  | ||||
| const char *                    _clutter_actor_get_debug_name                           (ClutterActor *self); | ||||
|  | ||||
| void                            _clutter_actor_push_clone_paint                         (void); | ||||
| void                            _clutter_actor_pop_clone_paint                          (void); | ||||
|  | ||||
| ClutterActorAlign               _clutter_actor_get_effective_x_align                    (ClutterActor *self); | ||||
|  | ||||
| void                            _clutter_actor_attach_clone                             (ClutterActor *actor, | ||||
|                                                                                          ClutterActor *clone); | ||||
| void                            _clutter_actor_detach_clone                             (ClutterActor *actor, | ||||
|                                                                                          ClutterActor *clone); | ||||
| void                            _clutter_actor_queue_only_relayout                      (ClutterActor *actor); | ||||
| void                            clutter_actor_clear_stage_views_recursive               (ClutterActor *actor, | ||||
|                                                                                          gboolean      stop_transitions); | ||||
|  | ||||
| float                           clutter_actor_get_real_resource_scale                   (ClutterActor *actor); | ||||
|  | ||||
| void clutter_actor_finish_layout (ClutterActor *self, | ||||
|                                   int           phase); | ||||
|  | ||||
| void clutter_actor_queue_immediate_relayout (ClutterActor *self); | ||||
|  | ||||
| gboolean clutter_actor_is_painting_unmapped (ClutterActor *self); | ||||
|  | ||||
| void clutter_actor_attach_grab (ClutterActor *actor, | ||||
|                                 ClutterGrab  *grab); | ||||
| void clutter_actor_detach_grab (ClutterActor *actor, | ||||
|                                 ClutterGrab  *grab); | ||||
|  | ||||
| void clutter_actor_collect_event_actors (ClutterActor *self, | ||||
|                                          ClutterActor *deepmost, | ||||
|                                          GPtrArray    *actors); | ||||
|  | ||||
| const GList * clutter_actor_peek_actions (ClutterActor *self); | ||||
|  | ||||
| void clutter_actor_set_implicitly_grabbed (ClutterActor *actor, | ||||
|                                            gboolean      is_implicitly_grabbed); | ||||
|  | ||||
| G_END_DECLS | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,882 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Authored By Matthew Allum  <mallum@openedhand.com> | ||||
|  * | ||||
|  * Copyright (C) 2006, 2007, 2008 OpenedHand Ltd | ||||
|  * 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/>. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <clutter/clutter.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| /* clutter-actor.h */ | ||||
|  | ||||
| #include <gio/gio.h> | ||||
| #include <pango/pango.h> | ||||
| #include <atk/atk.h> | ||||
|  | ||||
| #include "cogl/cogl.h" | ||||
|  | ||||
| #include "clutter/clutter-types.h" | ||||
| #include "clutter/clutter-event.h" | ||||
| #include "clutter/clutter-paint-context.h" | ||||
| #include "clutter/clutter-pick-context.h" | ||||
| #include "mtk/mtk.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CLUTTER_TYPE_ACTOR              (clutter_actor_get_type ()) | ||||
| #define CLUTTER_ACTOR(obj)              (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ACTOR, ClutterActor)) | ||||
| #define CLUTTER_ACTOR_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ACTOR, ClutterActorClass)) | ||||
| #define CLUTTER_IS_ACTOR(obj)           (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ACTOR)) | ||||
| #define CLUTTER_IS_ACTOR_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ACTOR)) | ||||
| #define CLUTTER_ACTOR_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ACTOR, ClutterActorClass)) | ||||
|  | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActor, g_object_unref) | ||||
|  | ||||
| typedef struct _ClutterActorClass    ClutterActorClass; | ||||
| typedef struct _ClutterActorPrivate  ClutterActorPrivate; | ||||
|  | ||||
|  | ||||
| struct _ClutterActor | ||||
| { | ||||
|   /*< private >*/ | ||||
|   GInitiallyUnowned parent_instance; | ||||
|  | ||||
|   /*< public >*/ | ||||
|   guint32 flags; | ||||
|  | ||||
|   /*< private >*/ | ||||
|   guint32 private_flags; | ||||
|  | ||||
|   ClutterActorPrivate *priv; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * ClutterActorClass: | ||||
|  * @show: signal class handler for [signal@Clutter.Actor::show]; it must chain | ||||
|  *   up to the parent's implementation | ||||
|  * @hide: signal class handler for [signal@Clutter.Actor::hide]; it must chain | ||||
|  *   up to the parent's implementation | ||||
|  * @hide_all: virtual function for containers and composite actors, to | ||||
|  *   determine which children should be shown when calling | ||||
|  *   clutter_actor_hide_all() on the actor. Defaults to calling | ||||
|  *   clutter_actor_hide(). This virtual function is deprecated and it | ||||
|  *   should not be overridden. | ||||
|  * @realize: virtual function, used to allocate resources for the actor; | ||||
|  *   it should chain up to the parent's implementation. This virtual | ||||
|  *   function is deprecated and should not be overridden in newly | ||||
|  *   written code. | ||||
|  * @unrealize: virtual function, used to deallocate resources allocated | ||||
|  *   in ::realize; it should chain up to the parent's implementation. This | ||||
|  *   function is deprecated and should not be overridden in newly | ||||
|  *   written code. | ||||
|  * @map: virtual function for containers and composite actors, to | ||||
|  *   map their children; it must chain up to the parent's implementation. | ||||
|  *   Overriding this function is optional. | ||||
|  * @unmap: virtual function for containers and composite actors, to | ||||
|  *   unmap their children; it must chain up to the parent's implementation. | ||||
|  *   Overriding this function is optional. | ||||
|  * @paint: virtual function, used to paint the actor | ||||
|  * @get_preferred_width: virtual function, used when querying the minimum | ||||
|  *   and natural widths of an actor for a given height; it is used by | ||||
|  *   clutter_actor_get_preferred_width() | ||||
|  * @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 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; if the transformation calculated by this function may | ||||
|  *   have changed, the cached transformation must be invalidated by calling | ||||
|  *   clutter_actor_invalidate_transform(); it must chain up to the parent's | ||||
|  *   implementation | ||||
|  * @parent_set: signal class handler for the [signal@Clutter.Actor::parent-set] | ||||
|  * @destroy: signal class handler for [signal@Clutter.Actor::destroy]. It must | ||||
|  *   chain up to the parent's implementation | ||||
|  * @pick: virtual function, used to draw an outline of the actor with | ||||
|  *   the given color | ||||
|  * @event: class handler for [signal@Clutter.Actor::event] | ||||
|  * @button_press_event: class handler for [signal@Clutter.Actor::button-press-event] | ||||
|  * @button_release_event: class handler for | ||||
|  *   [signal@Clutter.Actor::button-release-event] | ||||
|  * @scroll_event: signal class closure for [signal@Clutter.Actor::scroll-event] | ||||
|  * @key_press_event: signal class closure for [signal@Clutter.Actor::key-press-event] | ||||
|  * @key_release_event: signal class closure for | ||||
|  *   [signal@Clutter.Actor::key-release-event] | ||||
|  * @motion_event: signal class closure for [signal@Clutter.Actor::motion-event] | ||||
|  * @enter_event: signal class closure for [signal@Clutter.Actor::enter-event] | ||||
|  * @leave_event: signal class closure for [signal@Clutter.Actor::leave-event] | ||||
|  * @captured_event: signal class closure for [signal@Clutter.Actor::captured-event] | ||||
|  * @key_focus_in: signal class closure for [signal@Clutter.Actor::key-focus-in] | ||||
|  * @key_focus_out: signal class closure for [signal@Clutter.Actor::key-focus-out] | ||||
|  * @queue_relayout: class handler for [signal@Clutter.Actor::queue-relayout] | ||||
|  * @get_accessible: virtual function, returns the accessible object that | ||||
|  *   describes the actor to an assistive technology. | ||||
|  * @get_paint_volume: virtual function, for sub-classes to define their | ||||
|  *   #ClutterPaintVolume | ||||
|  * @has_overlaps: virtual function for | ||||
|  *   sub-classes to advertise whether they need an offscreen redirect | ||||
|  *   to get the correct opacity. See | ||||
|  *   clutter_actor_set_offscreen_redirect() for details. | ||||
|  * @paint_node: virtual function for creating paint nodes and attaching | ||||
|  *   them to the render tree | ||||
|  * @touch_event: signal class closure for [signal@Clutter.Actor::touch-event] | ||||
|  * | ||||
|  * Base class for actors. | ||||
|  */ | ||||
| struct _ClutterActorClass | ||||
| { | ||||
|   /*< private >*/ | ||||
|   GInitiallyUnownedClass parent_class; | ||||
|  | ||||
|   /*< public >*/ | ||||
|   void (* show)                 (ClutterActor          *self); | ||||
|   void (* hide)                 (ClutterActor          *self); | ||||
|   void (* hide_all)             (ClutterActor          *self); | ||||
|   void (* realize)              (ClutterActor          *self); | ||||
|   void (* unrealize)            (ClutterActor          *self); | ||||
|   void (* map)                  (ClutterActor          *self); | ||||
|   void (* unmap)                (ClutterActor          *self); | ||||
|   void (* paint)                (ClutterActor          *self, | ||||
|                                  ClutterPaintContext   *paint_context); | ||||
|   void (* parent_set)           (ClutterActor          *actor, | ||||
|                                  ClutterActor          *old_parent); | ||||
|  | ||||
|   void (* destroy)              (ClutterActor          *self); | ||||
|   void (* pick)                 (ClutterActor          *actor, | ||||
|                                  ClutterPickContext    *pick_context); | ||||
|  | ||||
|   /* size negotiation */ | ||||
|   void (* get_preferred_width)  (ClutterActor           *self, | ||||
|                                  gfloat                  for_height, | ||||
|                                  gfloat                 *min_width_p, | ||||
|                                  gfloat                 *natural_width_p); | ||||
|   void (* get_preferred_height) (ClutterActor           *self, | ||||
|                                  gfloat                  for_width, | ||||
|                                  gfloat                 *min_height_p, | ||||
|                                  gfloat                 *natural_height_p); | ||||
|   void (* allocate)             (ClutterActor           *self, | ||||
|                                  const ClutterActorBox  *box); | ||||
|  | ||||
|   /* transformations */ | ||||
|   void (* apply_transform)      (ClutterActor           *actor, | ||||
|                                  graphene_matrix_t      *matrix); | ||||
|  | ||||
|   /* event signals */ | ||||
|   gboolean (* event)                (ClutterActor         *actor, | ||||
|                                      ClutterEvent         *event); | ||||
|   gboolean (* button_press_event)   (ClutterActor         *actor, | ||||
|                                      ClutterEvent         *event); | ||||
|   gboolean (* button_release_event) (ClutterActor         *actor, | ||||
|                                      ClutterEvent         *event); | ||||
|   gboolean (* scroll_event)         (ClutterActor         *actor, | ||||
|                                      ClutterEvent         *event); | ||||
|   gboolean (* key_press_event)      (ClutterActor         *actor, | ||||
|                                      ClutterEvent         *event); | ||||
|   gboolean (* key_release_event)    (ClutterActor         *actor, | ||||
|                                      ClutterEvent         *event); | ||||
|   gboolean (* motion_event)         (ClutterActor         *actor, | ||||
|                                      ClutterEvent         *event); | ||||
|   gboolean (* enter_event)          (ClutterActor         *actor, | ||||
|                                      ClutterEvent         *event); | ||||
|   gboolean (* leave_event)          (ClutterActor         *actor, | ||||
|                                      ClutterEvent         *event); | ||||
|   gboolean (* captured_event)       (ClutterActor         *actor, | ||||
|                                      ClutterEvent         *event); | ||||
|   void     (* key_focus_in)         (ClutterActor         *actor); | ||||
|   void     (* key_focus_out)        (ClutterActor         *actor); | ||||
|  | ||||
|   void     (* queue_relayout)       (ClutterActor         *self); | ||||
|  | ||||
|   /* accessibility support */ | ||||
|   AtkObject * (* get_accessible)    (ClutterActor         *self); | ||||
|  | ||||
|   gboolean (* get_paint_volume)     (ClutterActor         *actor, | ||||
|                                      ClutterPaintVolume   *volume); | ||||
|  | ||||
|   gboolean (* has_overlaps)         (ClutterActor         *self); | ||||
|  | ||||
|   void     (* paint_node)           (ClutterActor         *self, | ||||
|                                      ClutterPaintNode     *root); | ||||
|  | ||||
|   gboolean (* touch_event)          (ClutterActor         *self, | ||||
|                                      ClutterEvent         *event); | ||||
|   gboolean (* has_accessible)       (ClutterActor         *self); | ||||
|   void     (* resource_scale_changed) (ClutterActor *self); | ||||
|   float    (* calculate_resource_scale) (ClutterActor *self, | ||||
|                                          int           phase); | ||||
|  | ||||
|   void     (* child_added)          (ClutterActor         *self, | ||||
|                                      ClutterActor         *child); | ||||
|   void     (* child_removed)        (ClutterActor         *self, | ||||
|                                      ClutterActor         *child); | ||||
|  | ||||
|   /* private */ | ||||
|   GType layout_manager_type; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * ClutterActorIter: | ||||
|  * | ||||
|  * An iterator structure that allows to efficiently iterate over a | ||||
|  * section of the scene graph. | ||||
|  * | ||||
|  * The contents of the #ClutterActorIter structure | ||||
|  * are private and should only be accessed using the provided API. | ||||
|  */ | ||||
| struct _ClutterActorIter | ||||
| { | ||||
|   /*< private >*/ | ||||
|   gpointer CLUTTER_PRIVATE_FIELD (dummy1); | ||||
|   gpointer CLUTTER_PRIVATE_FIELD (dummy2); | ||||
|   gint     CLUTTER_PRIVATE_FIELD (dummy3); | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| GType clutter_actor_get_type (void) G_GNUC_CONST; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterActor *                  clutter_actor_new                               (void); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_flags                         (ClutterActor                *self, | ||||
|                                                                                  ClutterActorFlags            flags); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_unset_flags                       (ClutterActor                *self, | ||||
|                                                                                  ClutterActorFlags            flags); | ||||
| CLUTTER_EXPORT | ||||
| ClutterActorFlags               clutter_actor_get_flags                         (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_show                              (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_hide                              (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_realize                           (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_unrealize                         (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_map                               (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_unmap                             (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_paint                             (ClutterActor                *self, | ||||
|                                                                                  ClutterPaintContext         *paint_context); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_continue_paint                    (ClutterActor                *self, | ||||
|                                                                                  ClutterPaintContext         *paint_context); | ||||
| CLUTTER_EXPORT | ||||
| ClutterPaintNode *              clutter_actor_create_texture_paint_node         (ClutterActor                *self, | ||||
|                                                                                  CoglTexture                 *texture); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_pick                              (ClutterActor                *actor, | ||||
|                                                                                  ClutterPickContext          *pick_context); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_continue_pick                     (ClutterActor                *actor, | ||||
|                                                                                  ClutterPickContext          *pick_context); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_queue_redraw                      (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_queue_redraw_with_clip            (ClutterActor       *self, | ||||
|                                                                                  const MtkRectangle *clip); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_queue_relayout                    (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_destroy                           (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_name                          (ClutterActor                *self, | ||||
|                                                                                  const gchar                 *name); | ||||
| CLUTTER_EXPORT | ||||
| const gchar *                   clutter_actor_get_name                          (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| AtkObject *                     clutter_actor_get_accessible                    (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_has_accessible                    (ClutterActor                *self); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_is_visible                        (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_is_mapped                         (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_is_realized                       (ClutterActor                *self); | ||||
|  | ||||
| /* Size negotiation */ | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_request_mode                  (ClutterActor                *self, | ||||
|                                                                                  ClutterRequestMode           mode); | ||||
| CLUTTER_EXPORT | ||||
| ClutterRequestMode              clutter_actor_get_request_mode                  (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_get_preferred_width               (ClutterActor                *self, | ||||
|                                                                                  gfloat                       for_height, | ||||
|                                                                                  gfloat                      *min_width_p, | ||||
|                                                                                  gfloat                      *natural_width_p); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_get_preferred_height              (ClutterActor                *self, | ||||
|                                                                                  gfloat                       for_width, | ||||
|                                                                                  gfloat                      *min_height_p, | ||||
|                                                                                  gfloat                      *natural_height_p); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_get_preferred_size                (ClutterActor                *self, | ||||
|                                                                                  gfloat                      *min_width_p, | ||||
|                                                                                  gfloat                      *min_height_p, | ||||
|                                                                                  gfloat                      *natural_width_p, | ||||
|                                                                                  gfloat                      *natural_height_p); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_allocate                          (ClutterActor                *self, | ||||
|                                                                                  const ClutterActorBox       *box); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_allocate_preferred_size           (ClutterActor                *self, | ||||
|                                                                                  float                        x, | ||||
|                                                                                  float                        y); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_allocate_available_size           (ClutterActor                *self, | ||||
|                                                                                  gfloat                       x, | ||||
|                                                                                  gfloat                       y, | ||||
|                                                                                  gfloat                       available_width, | ||||
|                                                                                  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); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_allocation                    (ClutterActor                *self, | ||||
|                                                                                  const ClutterActorBox       *box); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_get_allocation_box                (ClutterActor                *self, | ||||
|                                                                                  ClutterActorBox             *box); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_has_allocation                    (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_size                          (ClutterActor                *self, | ||||
|                                                                                  gfloat                       width, | ||||
|                                                                                  gfloat                       height); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_get_size                          (ClutterActor                *self, | ||||
|                                                                                  gfloat                      *width, | ||||
|                                                                                  gfloat                      *height); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_position                      (ClutterActor                *self, | ||||
|                                                                                  gfloat                       x, | ||||
|                                                                                  gfloat                       y); | ||||
| CLUTTER_EXPORT | ||||
| gboolean clutter_actor_get_fixed_position (ClutterActor *self, | ||||
|                                            float        *x, | ||||
|                                            float        *y); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_get_position                      (ClutterActor                *self, | ||||
|                                                                                  gfloat                      *x, | ||||
|                                                                                  gfloat                      *y); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_get_fixed_position_set            (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_fixed_position_set            (ClutterActor                *self, | ||||
|                                                                                  gboolean                     is_set); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_move_by                           (ClutterActor                *self, | ||||
|                                                                                  gfloat                       dx, | ||||
|                                                                                  gfloat                       dy); | ||||
|  | ||||
| /* Actor geometry */ | ||||
| CLUTTER_EXPORT | ||||
| gfloat                          clutter_actor_get_width                         (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| gfloat                          clutter_actor_get_height                        (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_width                         (ClutterActor                *self, | ||||
|                                                                                  gfloat                       width); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_height                        (ClutterActor                *self, | ||||
|                                                                                  gfloat                       height); | ||||
| CLUTTER_EXPORT | ||||
| gfloat                          clutter_actor_get_x                             (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| gfloat                          clutter_actor_get_y                             (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_x                             (ClutterActor                *self, | ||||
|                                                                                  gfloat                       x); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_y                             (ClutterActor                *self, | ||||
|                                                                                  gfloat                       y); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_z_position                    (ClutterActor                *self, | ||||
|                                                                                  gfloat                       z_position); | ||||
| CLUTTER_EXPORT | ||||
| gfloat                          clutter_actor_get_z_position                    (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_layout_manager                (ClutterActor                *self, | ||||
|                                                                                  ClutterLayoutManager        *manager); | ||||
| CLUTTER_EXPORT | ||||
| ClutterLayoutManager *          clutter_actor_get_layout_manager                (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_x_align                       (ClutterActor                *self, | ||||
|                                                                                  ClutterActorAlign            x_align); | ||||
| CLUTTER_EXPORT | ||||
| ClutterActorAlign               clutter_actor_get_x_align                       (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_y_align                       (ClutterActor                *self, | ||||
|                                                                                  ClutterActorAlign            y_align); | ||||
| CLUTTER_EXPORT | ||||
| ClutterActorAlign               clutter_actor_get_y_align                       (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_margin_top                    (ClutterActor                *self, | ||||
|                                                                                  gfloat                       margin); | ||||
| CLUTTER_EXPORT | ||||
| gfloat                          clutter_actor_get_margin_top                    (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_margin_bottom                 (ClutterActor                *self, | ||||
|                                                                                  gfloat                       margin); | ||||
| CLUTTER_EXPORT | ||||
| gfloat                          clutter_actor_get_margin_bottom                 (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_margin_left                   (ClutterActor                *self, | ||||
|                                                                                  gfloat                       margin); | ||||
| CLUTTER_EXPORT | ||||
| gfloat                          clutter_actor_get_margin_left                   (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_margin_right                  (ClutterActor                *self, | ||||
|                                                                                  gfloat                       margin); | ||||
| CLUTTER_EXPORT | ||||
| gfloat                          clutter_actor_get_margin_right                  (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_margin                        (ClutterActor                *self, | ||||
|                                                                                  const ClutterMargin         *margin); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_get_margin                        (ClutterActor                *self, | ||||
|                                                                                  ClutterMargin               *margin); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_x_expand                      (ClutterActor                *self, | ||||
|                                                                                  gboolean                     expand); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_get_x_expand                      (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_y_expand                      (ClutterActor                *self, | ||||
|                                                                                  gboolean                     expand); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_get_y_expand                      (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_needs_expand                      (ClutterActor                *self, | ||||
|                                                                                  ClutterOrientation           orientation); | ||||
|  | ||||
| /* Paint */ | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_clip                          (ClutterActor                *self, | ||||
|                                                                                  gfloat                       xoff, | ||||
|                                                                                  gfloat                       yoff, | ||||
|                                                                                  gfloat                       width, | ||||
|                                                                                  gfloat                       height); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_remove_clip                       (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_has_clip                          (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_get_clip                          (ClutterActor               *self, | ||||
|                                                                                  gfloat                     *xoff, | ||||
|                                                                                  gfloat                     *yoff, | ||||
|                                                                                  gfloat                     *width, | ||||
|                                                                                  gfloat                     *height); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_clip_to_allocation            (ClutterActor               *self, | ||||
|                                                                                  gboolean                    clip_set); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_get_clip_to_allocation            (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_opacity                       (ClutterActor               *self, | ||||
|                                                                                  guint8                      opacity); | ||||
| CLUTTER_EXPORT | ||||
| guint8                          clutter_actor_get_opacity                       (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| guint8                          clutter_actor_get_paint_opacity                 (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_get_paint_visibility              (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_offscreen_redirect            (ClutterActor               *self, | ||||
|                                                                                  ClutterOffscreenRedirect    redirect); | ||||
| CLUTTER_EXPORT | ||||
| ClutterOffscreenRedirect        clutter_actor_get_offscreen_redirect            (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_should_pick                       (ClutterActor               *self, | ||||
|                                                                                  ClutterPickContext         *pick_context); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_is_in_clone_paint                 (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_get_paint_box                     (ClutterActor               *self, | ||||
|                                                                                  ClutterActorBox            *box); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| float                           clutter_actor_get_resource_scale                (ClutterActor *self); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_has_overlaps                      (ClutterActor               *self); | ||||
|  | ||||
| /* Content */ | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_content                       (ClutterActor               *self, | ||||
|                                                                                  ClutterContent             *content); | ||||
| CLUTTER_EXPORT | ||||
| ClutterContent *                clutter_actor_get_content                       (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_content_gravity               (ClutterActor               *self, | ||||
|                                                                                  ClutterContentGravity       gravity); | ||||
| CLUTTER_EXPORT | ||||
| ClutterContentGravity           clutter_actor_get_content_gravity               (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_content_scaling_filters       (ClutterActor               *self, | ||||
|                                                                                  ClutterScalingFilter        min_filter, | ||||
|                                                                                  ClutterScalingFilter        mag_filter); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_get_content_scaling_filters       (ClutterActor               *self, | ||||
|                                                                                  ClutterScalingFilter       *min_filter, | ||||
|                                                                                  ClutterScalingFilter       *mag_filter); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_content_repeat                (ClutterActor               *self, | ||||
|                                                                                  ClutterContentRepeat        repeat); | ||||
| CLUTTER_EXPORT | ||||
| ClutterContentRepeat            clutter_actor_get_content_repeat                (ClutterActor               *self); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void clutter_actor_set_color_state (ClutterActor      *self, | ||||
|                                     ClutterColorState *color_state); | ||||
| CLUTTER_EXPORT | ||||
| ClutterColorState *clutter_actor_get_color_state (ClutterActor *self); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_get_content_box                   (ClutterActor               *self, | ||||
|                                                                                  ClutterActorBox            *box); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_background_color              (ClutterActor               *self, | ||||
|                                                                                  const ClutterColor         *color); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_get_background_color              (ClutterActor               *self, | ||||
|                                                                                  ClutterColor               *color); | ||||
| CLUTTER_EXPORT | ||||
| const ClutterPaintVolume *      clutter_actor_get_paint_volume                  (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| ClutterPaintVolume *            clutter_actor_get_transformed_paint_volume      (ClutterActor               *self, | ||||
|                                                                                  ClutterActor               *relative_to_ancestor); | ||||
|  | ||||
| /* Events */ | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_reactive                      (ClutterActor               *actor, | ||||
|                                                                                  gboolean                    reactive); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_get_reactive                      (ClutterActor               *actor); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_has_key_focus                     (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_grab_key_focus                    (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_event                             (ClutterActor               *actor, | ||||
|                                                                                  const ClutterEvent         *event, | ||||
|                                                                                  gboolean                    capture); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_has_pointer                       (ClutterActor               *self); | ||||
|  | ||||
| /* Text */ | ||||
| CLUTTER_EXPORT | ||||
| PangoContext *                  clutter_actor_get_pango_context                 (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| PangoContext *                  clutter_actor_create_pango_context              (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| PangoLayout *                   clutter_actor_create_pango_layout               (ClutterActor               *self, | ||||
|                                                                                  const gchar                *text); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_text_direction                (ClutterActor               *self, | ||||
|                                                                                  ClutterTextDirection        text_dir); | ||||
| CLUTTER_EXPORT | ||||
| ClutterTextDirection            clutter_actor_get_text_direction                (ClutterActor               *self); | ||||
|  | ||||
| /* Actor hierarchy */ | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_add_child                         (ClutterActor               *self, | ||||
|                                                                                  ClutterActor               *child); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_insert_child_at_index             (ClutterActor               *self, | ||||
|                                                                                  ClutterActor               *child, | ||||
|                                                                                  gint                        index_); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_insert_child_above                (ClutterActor               *self, | ||||
|                                                                                  ClutterActor               *child, | ||||
|                                                                                  ClutterActor               *sibling); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_insert_child_below                (ClutterActor               *self, | ||||
|                                                                                  ClutterActor               *child, | ||||
|                                                                                  ClutterActor               *sibling); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_replace_child                     (ClutterActor               *self, | ||||
|                                                                                  ClutterActor               *old_child, | ||||
|                                                                                  ClutterActor               *new_child); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_remove_child                      (ClutterActor               *self, | ||||
|                                                                                  ClutterActor               *child); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_remove_all_children               (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_destroy_all_children              (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| GList *                         clutter_actor_get_children                      (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| gint                            clutter_actor_get_n_children                    (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| ClutterActor *                  clutter_actor_get_child_at_index                (ClutterActor               *self, | ||||
|                                                                                  gint                        index_); | ||||
| CLUTTER_EXPORT | ||||
| ClutterActor *                  clutter_actor_get_previous_sibling              (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| ClutterActor *                  clutter_actor_get_next_sibling                  (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| ClutterActor *                  clutter_actor_get_first_child                   (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| ClutterActor *                  clutter_actor_get_last_child                    (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| ClutterActor *                  clutter_actor_get_parent                        (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_contains                          (ClutterActor               *self, | ||||
|                                                                                  ClutterActor               *descendant); | ||||
| CLUTTER_EXPORT | ||||
| ClutterActor*                   clutter_actor_get_stage                         (ClutterActor               *actor); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_child_below_sibling           (ClutterActor               *self, | ||||
|                                                                                  ClutterActor               *child, | ||||
|                                                                                  ClutterActor               *sibling); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_child_above_sibling           (ClutterActor               *self, | ||||
|                                                                                  ClutterActor               *child, | ||||
|                                                                                  ClutterActor               *sibling); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_child_at_index                (ClutterActor               *self, | ||||
|                                                                                  ClutterActor               *child, | ||||
|                                                                                  gint                        index_); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_iter_init                         (ClutterActorIter           *iter, | ||||
|                                                                                  ClutterActor               *root); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_iter_next                         (ClutterActorIter           *iter, | ||||
|                                                                                  ClutterActor              **child); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_iter_prev                         (ClutterActorIter           *iter, | ||||
|                                                                                  ClutterActor              **child); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_iter_remove                       (ClutterActorIter           *iter); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_iter_destroy                      (ClutterActorIter           *iter); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_iter_is_valid                     (const ClutterActorIter     *iter); | ||||
|  | ||||
| /* Transformations */ | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_is_rotated                        (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_is_scaled                         (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_pivot_point                   (ClutterActor               *self, | ||||
|                                                                                  gfloat                      pivot_x, | ||||
|                                                                                  gfloat                      pivot_y); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_get_pivot_point                   (ClutterActor               *self, | ||||
|                                                                                  gfloat                     *pivot_x, | ||||
|                                                                                  gfloat                     *pivot_y); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_pivot_point_z                 (ClutterActor               *self, | ||||
|                                                                                  gfloat                      pivot_z); | ||||
| CLUTTER_EXPORT | ||||
| gfloat                          clutter_actor_get_pivot_point_z                 (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_rotation_angle                (ClutterActor               *self, | ||||
|                                                                                  ClutterRotateAxis           axis, | ||||
|                                                                                  gdouble                     angle); | ||||
| CLUTTER_EXPORT | ||||
| gdouble                         clutter_actor_get_rotation_angle                (ClutterActor               *self, | ||||
|                                                                                  ClutterRotateAxis           axis); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_scale                         (ClutterActor               *self, | ||||
|                                                                                  gdouble                     scale_x, | ||||
|                                                                                  gdouble                     scale_y); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_get_scale                         (ClutterActor               *self, | ||||
|                                                                                  gdouble                    *scale_x, | ||||
|                                                                                  gdouble                    *scale_y); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_scale_z                       (ClutterActor               *self, | ||||
|                                                                                  gdouble                     scale_z); | ||||
| CLUTTER_EXPORT | ||||
| gdouble                         clutter_actor_get_scale_z                       (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_translation                   (ClutterActor               *self, | ||||
|                                                                                  gfloat                      translate_x, | ||||
|                                                                                  gfloat                      translate_y, | ||||
|                                                                                  gfloat                      translate_z); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_get_translation                   (ClutterActor               *self, | ||||
|                                                                                  gfloat                     *translate_x, | ||||
|                                                                                  gfloat                     *translate_y, | ||||
|                                                                                  gfloat                     *translate_z); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_transform                     (ClutterActor               *self, | ||||
|                                                                                  const graphene_matrix_t    *transform); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_get_transform                     (ClutterActor               *self, | ||||
|                                                                                  graphene_matrix_t          *transform); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_child_transform               (ClutterActor               *self, | ||||
|                                                                                  const graphene_matrix_t    *transform); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_get_child_transform               (ClutterActor               *self, | ||||
|                                                                                  graphene_matrix_t          *transform); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_get_transformed_extents          (ClutterActor               *self, | ||||
|                                                                                 graphene_rect_t            *rect); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_get_transformed_position          (ClutterActor               *self, | ||||
|                                                                                  gfloat                     *x, | ||||
|                                                                                  gfloat                     *y); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_get_transformed_size              (ClutterActor               *self, | ||||
|                                                                                  gfloat                     *width, | ||||
|                                                                                  gfloat                     *height); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_transform_stage_point             (ClutterActor               *self, | ||||
|                                                                                  gfloat                      x, | ||||
|                                                                                  gfloat                      y, | ||||
|                                                                                  gfloat                     *x_out, | ||||
|                                                                                  gfloat                     *y_out); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_get_abs_allocation_vertices       (ClutterActor               *self, | ||||
|                                                                                  graphene_point3d_t         *verts); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_apply_transform_to_point          (ClutterActor               *self, | ||||
|                                                                                  const graphene_point3d_t   *point, | ||||
|                                                                                  graphene_point3d_t         *vertex); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_apply_relative_transform_to_point (ClutterActor               *self, | ||||
|                                                                                  ClutterActor               *ancestor, | ||||
|                                                                                  const graphene_point3d_t   *point, | ||||
|                                                                                  graphene_point3d_t         *vertex); | ||||
|  | ||||
| /* Implicit animations */ | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_save_easing_state                 (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_restore_easing_state              (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_easing_mode                   (ClutterActor               *self, | ||||
|                                                                                  ClutterAnimationMode        mode); | ||||
| CLUTTER_EXPORT | ||||
| ClutterAnimationMode            clutter_actor_get_easing_mode                   (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_easing_duration               (ClutterActor               *self, | ||||
|                                                                                  guint                       msecs); | ||||
| CLUTTER_EXPORT | ||||
| guint                           clutter_actor_get_easing_duration               (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_easing_delay                  (ClutterActor               *self, | ||||
|                                                                                  guint                       msecs); | ||||
| CLUTTER_EXPORT | ||||
| guint                           clutter_actor_get_easing_delay                  (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| ClutterTransition *             clutter_actor_get_transition                    (ClutterActor               *self, | ||||
|                                                                                  const char                 *name); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_add_transition                    (ClutterActor               *self, | ||||
|                                                                                  const char                 *name, | ||||
|                                                                                  ClutterTransition          *transition); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_remove_transition                 (ClutterActor               *self, | ||||
|                                                                                  const char                 *name); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_remove_all_transitions            (ClutterActor               *self); | ||||
|  | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_has_mapped_clones                 (ClutterActor *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_opacity_override              (ClutterActor               *self, | ||||
|                                                                                  gint                        opacity); | ||||
| CLUTTER_EXPORT | ||||
| gint                            clutter_actor_get_opacity_override              (ClutterActor               *self); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_inhibit_culling                   (ClutterActor               *actor); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_uninhibit_culling                 (ClutterActor               *actor); | ||||
|  | ||||
| /** | ||||
|  * ClutterActorCreateChildFunc: | ||||
|  * @item: (type GObject): the item in the model | ||||
|  * @user_data: Data passed to clutter_actor_bind_model() | ||||
|  * | ||||
|  * Creates a #ClutterActor using the @item in the model. | ||||
|  * | ||||
|  * The usual way to implement this function is to create a #ClutterActor | ||||
|  * instance and then bind the #GObject properties to the actor properties | ||||
|  * of interest, using g_object_bind_property(). This way, when the @item | ||||
|  * in the #GListModel changes, the #ClutterActor changes as well. | ||||
|  * | ||||
|  * Returns: (transfer full): The newly created child #ClutterActor4 | ||||
|  */ | ||||
| typedef ClutterActor * (* ClutterActorCreateChildFunc) (gpointer item, | ||||
|                                                         gpointer user_data); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_bind_model                        (ClutterActor               *self, | ||||
|                                                                                  GListModel                 *model, | ||||
|                                                                                  ClutterActorCreateChildFunc create_child_func, | ||||
|                                                                                  gpointer                    user_data, | ||||
|                                                                                  GDestroyNotify              notify); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_bind_model_with_properties        (ClutterActor               *self, | ||||
|                                                                                  GListModel                 *model, | ||||
|                                                                                  GType                       child_type, | ||||
|                                                                                  const char                 *first_model_property, | ||||
|                                                                                  ...); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void clutter_actor_pick_box (ClutterActor          *self, | ||||
|                              ClutterPickContext    *pick_context, | ||||
|                              const ClutterActorBox *box); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| GList * clutter_actor_peek_stage_views (ClutterActor *self); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void clutter_actor_invalidate_transform (ClutterActor *self); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void clutter_actor_invalidate_paint_volume (ClutterActor *self); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void clutter_actor_class_set_layout_manager_type (ClutterActorClass *actor_class, | ||||
|                                                   GType              type); | ||||
| CLUTTER_EXPORT | ||||
| GType clutter_actor_class_get_layout_manager_type (ClutterActorClass *actor_class); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,607 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2010  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> | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * ClutterAlignConstraint: | ||||
|  * | ||||
|  * A constraint aligning the position of an actor | ||||
|  * | ||||
|  * #ClutterAlignConstraint is a [class@Constraint] that aligns the position | ||||
|  * of the [class@Actor] to which it is applied to the size of another | ||||
|  * [class@Actor] using an alignment factor | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "clutter/clutter-align-constraint.h" | ||||
|  | ||||
| #include "clutter/clutter-actor-meta-private.h" | ||||
| #include "clutter/clutter-actor-private.h" | ||||
| #include "clutter/clutter-constraint.h" | ||||
| #include "clutter/clutter-debug.h" | ||||
| #include "clutter/clutter-enum-types.h" | ||||
| #include "clutter/clutter-private.h" | ||||
|  | ||||
| #include <math.h> | ||||
|  | ||||
| struct _ClutterAlignConstraint | ||||
| { | ||||
|   ClutterConstraint parent_instance; | ||||
|  | ||||
|   ClutterActor *actor; | ||||
|   ClutterActor *source; | ||||
|   ClutterAlignAxis align_axis; | ||||
|   graphene_point_t pivot; | ||||
|   gfloat factor; | ||||
| }; | ||||
|  | ||||
| enum | ||||
| { | ||||
|   PROP_0, | ||||
|  | ||||
|   PROP_SOURCE, | ||||
|   PROP_ALIGN_AXIS, | ||||
|   PROP_PIVOT_POINT, | ||||
|   PROP_FACTOR, | ||||
|  | ||||
|   PROP_LAST | ||||
| }; | ||||
|  | ||||
| static GParamSpec *obj_props[PROP_LAST]; | ||||
|  | ||||
| G_DEFINE_FINAL_TYPE (ClutterAlignConstraint, | ||||
|                      clutter_align_constraint, | ||||
|                      CLUTTER_TYPE_CONSTRAINT); | ||||
|  | ||||
| static void | ||||
| source_queue_relayout (ClutterActor           *actor, | ||||
|                        ClutterAlignConstraint *align) | ||||
| { | ||||
|   if (align->actor != NULL) | ||||
|     _clutter_actor_queue_only_relayout (align->actor); | ||||
| } | ||||
|  | ||||
| static void | ||||
| source_destroyed (ClutterActor           *actor, | ||||
|                   ClutterAlignConstraint *align) | ||||
| { | ||||
|   align->source = NULL; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_align_constraint_set_actor (ClutterActorMeta *meta, | ||||
|                                     ClutterActor     *new_actor) | ||||
| { | ||||
|   ClutterAlignConstraint *align = CLUTTER_ALIGN_CONSTRAINT (meta); | ||||
|   ClutterActorMetaClass *parent; | ||||
|  | ||||
|   if (new_actor != NULL && | ||||
|       align->source != NULL && | ||||
|       clutter_actor_contains (new_actor, align->source)) | ||||
|     { | ||||
|       g_warning (G_STRLOC ": The source actor '%s' is contained " | ||||
|                  "by the actor '%s' associated to the constraint " | ||||
|                  "'%s'", | ||||
|                  _clutter_actor_get_debug_name (align->source), | ||||
|                  _clutter_actor_get_debug_name (new_actor), | ||||
|                  _clutter_actor_meta_get_debug_name (meta)); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   /* store the pointer to the actor, for later use */ | ||||
|   align->actor = new_actor; | ||||
|  | ||||
|   parent = CLUTTER_ACTOR_META_CLASS (clutter_align_constraint_parent_class); | ||||
|   parent->set_actor (meta, new_actor); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_align_constraint_update_allocation (ClutterConstraint *constraint, | ||||
|                                             ClutterActor      *actor, | ||||
|                                             ClutterActorBox   *allocation) | ||||
| { | ||||
|   ClutterAlignConstraint *align = CLUTTER_ALIGN_CONSTRAINT (constraint); | ||||
|   gfloat source_width, source_height; | ||||
|   gfloat actor_width, actor_height; | ||||
|   gfloat offset_x_start, offset_y_start; | ||||
|   gfloat pivot_x, pivot_y; | ||||
|  | ||||
|   if (align->source == NULL) | ||||
|     return; | ||||
|  | ||||
|   clutter_actor_box_get_size (allocation, &actor_width, &actor_height); | ||||
|  | ||||
|   clutter_actor_get_size (align->source, &source_width, &source_height); | ||||
|  | ||||
|   pivot_x = align->pivot.x == -1.f | ||||
|     ? align->factor | ||||
|     : align->pivot.x; | ||||
|   pivot_y = align->pivot.y == -1.f | ||||
|     ? align->factor | ||||
|     : align->pivot.y; | ||||
|  | ||||
|   offset_x_start = pivot_x * -actor_width; | ||||
|   offset_y_start = pivot_y * -actor_height; | ||||
|  | ||||
|   switch (align->align_axis) | ||||
|     { | ||||
|     case CLUTTER_ALIGN_X_AXIS: | ||||
|       allocation->x1 += offset_x_start + (source_width * align->factor); | ||||
|       allocation->x2 = allocation->x1 + actor_width; | ||||
|       break; | ||||
|  | ||||
|     case CLUTTER_ALIGN_Y_AXIS: | ||||
|       allocation->y1 += offset_y_start + (source_height * align->factor); | ||||
|       allocation->y2 = allocation->y1 + actor_height; | ||||
|       break; | ||||
|  | ||||
|     case CLUTTER_ALIGN_BOTH: | ||||
|       allocation->x1 += offset_x_start + (source_width * align->factor); | ||||
|       allocation->y1 += offset_y_start + (source_height * align->factor); | ||||
|       allocation->x2 = allocation->x1 + actor_width; | ||||
|       allocation->y2 = allocation->y1 + actor_height; | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       g_assert_not_reached (); | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|   clutter_actor_box_clamp_to_pixel (allocation); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_align_constraint_dispose (GObject *gobject) | ||||
| { | ||||
|   ClutterAlignConstraint *align = CLUTTER_ALIGN_CONSTRAINT (gobject); | ||||
|  | ||||
|   if (align->source != NULL) | ||||
|     { | ||||
|       g_signal_handlers_disconnect_by_func (align->source, | ||||
|                                             G_CALLBACK (source_destroyed), | ||||
|                                             align); | ||||
|       g_signal_handlers_disconnect_by_func (align->source, | ||||
|                                             G_CALLBACK (source_queue_relayout), | ||||
|                                             align); | ||||
|       align->source = NULL; | ||||
|     } | ||||
|  | ||||
|   G_OBJECT_CLASS (clutter_align_constraint_parent_class)->dispose (gobject); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_align_constraint_set_property (GObject      *gobject, | ||||
|                                        guint         prop_id, | ||||
|                                        const GValue *value, | ||||
|                                        GParamSpec   *pspec) | ||||
| { | ||||
|   ClutterAlignConstraint *align = CLUTTER_ALIGN_CONSTRAINT (gobject); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_SOURCE: | ||||
|       clutter_align_constraint_set_source (align, g_value_get_object (value)); | ||||
|       break; | ||||
|  | ||||
|     case PROP_ALIGN_AXIS: | ||||
|       clutter_align_constraint_set_align_axis (align, g_value_get_enum (value)); | ||||
|       break; | ||||
|  | ||||
|     case PROP_PIVOT_POINT: | ||||
|       clutter_align_constraint_set_pivot_point (align, g_value_get_boxed (value)); | ||||
|       break; | ||||
|  | ||||
|     case PROP_FACTOR: | ||||
|       clutter_align_constraint_set_factor (align, g_value_get_float (value)); | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_align_constraint_get_property (GObject    *gobject, | ||||
|                                        guint       prop_id, | ||||
|                                        GValue     *value, | ||||
|                                        GParamSpec *pspec) | ||||
| { | ||||
|   ClutterAlignConstraint *align = CLUTTER_ALIGN_CONSTRAINT (gobject); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_SOURCE: | ||||
|       g_value_set_object (value, align->source); | ||||
|       break; | ||||
|  | ||||
|     case PROP_ALIGN_AXIS: | ||||
|       g_value_set_enum (value, align->align_axis); | ||||
|       break; | ||||
|  | ||||
|     case PROP_PIVOT_POINT: | ||||
|       { | ||||
|         graphene_point_t point; | ||||
|  | ||||
|         clutter_align_constraint_get_pivot_point (align, &point); | ||||
|  | ||||
|         g_value_set_boxed (value, &point); | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|     case PROP_FACTOR: | ||||
|       g_value_set_float (value, align->factor); | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_align_constraint_class_init (ClutterAlignConstraintClass *klass) | ||||
| { | ||||
|   GObjectClass *gobject_class = G_OBJECT_CLASS (klass); | ||||
|   ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass); | ||||
|   ClutterConstraintClass *constraint_class = CLUTTER_CONSTRAINT_CLASS (klass); | ||||
|  | ||||
|   meta_class->set_actor = clutter_align_constraint_set_actor; | ||||
|  | ||||
|   constraint_class->update_allocation = clutter_align_constraint_update_allocation; | ||||
|  | ||||
|   /** | ||||
|    * ClutterAlignConstraint:source: | ||||
|    * | ||||
|    * The #ClutterActor used as the source for the alignment. | ||||
|    * | ||||
|    * The #ClutterActor must not be a child or a grandchild of the actor | ||||
|    * using the constraint. | ||||
|    */ | ||||
|   obj_props[PROP_SOURCE] = | ||||
|     g_param_spec_object ("source", NULL, NULL, | ||||
|                            CLUTTER_TYPE_ACTOR, | ||||
|                            G_PARAM_READWRITE | | ||||
|                            G_PARAM_STATIC_STRINGS | | ||||
|                            G_PARAM_CONSTRUCT); | ||||
|  | ||||
|   /** | ||||
|    * ClutterAlignConstraint:align-axis: | ||||
|    * | ||||
|    * The axis to be used to compute the alignment | ||||
|    */ | ||||
|   obj_props[PROP_ALIGN_AXIS] = | ||||
|     g_param_spec_enum ("align-axis", NULL, NULL, | ||||
|                        CLUTTER_TYPE_ALIGN_AXIS, | ||||
|                        CLUTTER_ALIGN_X_AXIS, | ||||
|                        G_PARAM_READWRITE | | ||||
|                        G_PARAM_STATIC_STRINGS | | ||||
|                        G_PARAM_CONSTRUCT); | ||||
|  | ||||
|   /** | ||||
|    * ClutterAlignConstraint:pivot-point: | ||||
|    * | ||||
|    * The pivot point used by the constraint. The pivot point is the | ||||
|    * point in the constraint actor around which the aligning is applied, | ||||
|    * with (0, 0) being the top left corner of the actor and (1, 1) the | ||||
|    * bottom right corner of the actor. | ||||
|    * | ||||
|    * For example, setting the pivot point to (0.5, 0.5) and using a factor | ||||
|    * of 1 for both axes will align the actors horizontal and vertical | ||||
|    * center point with the bottom right corner of the source actor. | ||||
|    * | ||||
|    * By default, the pivot point is set to (-1, -1), which means it's not | ||||
|    * used and the constrained actor will be aligned to always stay inside | ||||
|    * the source actor. | ||||
|    */ | ||||
|   obj_props[PROP_PIVOT_POINT] = | ||||
|     g_param_spec_boxed ("pivot-point", NULL, NULL, | ||||
|                        GRAPHENE_TYPE_POINT, | ||||
|                        G_PARAM_READWRITE | | ||||
|                        G_PARAM_STATIC_STRINGS); | ||||
|  | ||||
|   /** | ||||
|    * ClutterAlignConstraint:factor: | ||||
|    * | ||||
|    * The alignment factor, as a normalized value between 0.0 and 1.0 | ||||
|    * | ||||
|    * The factor depends on the #ClutterAlignConstraint:align-axis property: | ||||
|    * with an align-axis value of %CLUTTER_ALIGN_X_AXIS, 0.0 means left and | ||||
|    * 1.0 means right; with a value of %CLUTTER_ALIGN_Y_AXIS, 0.0 means top | ||||
|    * and 1.0 means bottom. | ||||
|    */ | ||||
|   obj_props[PROP_FACTOR] = | ||||
|     g_param_spec_float ("factor", NULL, NULL, | ||||
|                         0.0, 1.0, | ||||
|                         0.0, | ||||
|                         G_PARAM_READWRITE | | ||||
|                         G_PARAM_STATIC_STRINGS | | ||||
|                         G_PARAM_CONSTRUCT); | ||||
|  | ||||
|   gobject_class->dispose = clutter_align_constraint_dispose; | ||||
|   gobject_class->set_property = clutter_align_constraint_set_property; | ||||
|   gobject_class->get_property = clutter_align_constraint_get_property; | ||||
|   g_object_class_install_properties (gobject_class, PROP_LAST, obj_props); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_align_constraint_init (ClutterAlignConstraint *self) | ||||
| { | ||||
|   self->actor = NULL; | ||||
|   self->source = NULL; | ||||
|   self->align_axis = CLUTTER_ALIGN_X_AXIS; | ||||
|   self->pivot.x = -1.f; | ||||
|   self->pivot.y = -1.f; | ||||
|   self->factor = 0.0f; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_align_constraint_new: | ||||
|  * @source: (allow-none): the #ClutterActor to use as the source of the | ||||
|  *   alignment, or %NULL | ||||
|  * @axis: the axis to be used to compute the alignment | ||||
|  * @factor: the alignment factor, between 0.0 and 1.0 | ||||
|  * | ||||
|  * Creates a new constraint, aligning a #ClutterActor's position with | ||||
|  * regards of the size of the actor to @source, with the given | ||||
|  * alignment @factor | ||||
|  * | ||||
|  * Return value: the newly created #ClutterAlignConstraint | ||||
|  */ | ||||
| ClutterConstraint * | ||||
| clutter_align_constraint_new (ClutterActor     *source, | ||||
|                               ClutterAlignAxis  axis, | ||||
|                               gfloat            factor) | ||||
| { | ||||
|   g_return_val_if_fail (source == NULL || CLUTTER_IS_ACTOR (source), NULL); | ||||
|  | ||||
|   return g_object_new (CLUTTER_TYPE_ALIGN_CONSTRAINT, | ||||
|                        "source", source, | ||||
|                        "align-axis", axis, | ||||
|                        "factor", factor, | ||||
|                        NULL); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_align_constraint_set_source: | ||||
|  * @align: a #ClutterAlignConstraint | ||||
|  * @source: (allow-none): a #ClutterActor, or %NULL to unset the source | ||||
|  * | ||||
|  * Sets the source of the alignment constraint | ||||
|  */ | ||||
| void | ||||
| clutter_align_constraint_set_source (ClutterAlignConstraint *align, | ||||
|                                      ClutterActor           *source) | ||||
| { | ||||
|   ClutterActor *old_source, *actor; | ||||
|   ClutterActorMeta *meta; | ||||
|  | ||||
|   g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align)); | ||||
|   g_return_if_fail (source == NULL || CLUTTER_IS_ACTOR (source)); | ||||
|  | ||||
|   if (align->source == source) | ||||
|     return; | ||||
|  | ||||
|   meta = CLUTTER_ACTOR_META (align); | ||||
|   actor = clutter_actor_meta_get_actor (meta); | ||||
|   if (actor != NULL && source != NULL) | ||||
|     { | ||||
|       if (clutter_actor_contains (actor, source)) | ||||
|         { | ||||
|           g_warning (G_STRLOC ": The source actor '%s' is contained " | ||||
|                      "by the actor '%s' associated to the constraint " | ||||
|                      "'%s'", | ||||
|                      _clutter_actor_get_debug_name (source), | ||||
|                      _clutter_actor_get_debug_name (actor), | ||||
|                      _clutter_actor_meta_get_debug_name (meta)); | ||||
|           return; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   old_source = align->source; | ||||
|   if (old_source != NULL) | ||||
|     { | ||||
|       g_signal_handlers_disconnect_by_func (old_source, | ||||
|                                             G_CALLBACK (source_destroyed), | ||||
|                                             align); | ||||
|       g_signal_handlers_disconnect_by_func (old_source, | ||||
|                                             G_CALLBACK (source_queue_relayout), | ||||
|                                             align); | ||||
|     } | ||||
|  | ||||
|   align->source = source; | ||||
|   if (align->source != NULL) | ||||
|     { | ||||
|       g_signal_connect (align->source, "queue-relayout", | ||||
|                         G_CALLBACK (source_queue_relayout), | ||||
|                         align); | ||||
|       g_signal_connect (align->source, "destroy", | ||||
|                         G_CALLBACK (source_destroyed), | ||||
|                         align); | ||||
|  | ||||
|       if (align->actor != NULL) | ||||
|         clutter_actor_queue_relayout (align->actor); | ||||
|     } | ||||
|  | ||||
|   g_object_notify_by_pspec (G_OBJECT (align), obj_props[PROP_SOURCE]); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_align_constraint_get_source: | ||||
|  * @align: a #ClutterAlignConstraint | ||||
|  * | ||||
|  * Retrieves the source of the alignment | ||||
|  * | ||||
|  * Return value: (transfer none): the #ClutterActor used as the source | ||||
|  *   of the alignment | ||||
|  */ | ||||
| ClutterActor * | ||||
| clutter_align_constraint_get_source (ClutterAlignConstraint *align) | ||||
| { | ||||
|   g_return_val_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align), NULL); | ||||
|  | ||||
|   return align->source; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_align_constraint_set_align_axis: | ||||
|  * @align: a #ClutterAlignConstraint | ||||
|  * @axis: the axis to which the alignment refers to | ||||
|  * | ||||
|  * Sets the axis to which the alignment refers to | ||||
|  */ | ||||
| void | ||||
| clutter_align_constraint_set_align_axis (ClutterAlignConstraint *align, | ||||
|                                          ClutterAlignAxis        axis) | ||||
| { | ||||
|   g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align)); | ||||
|  | ||||
|   if (align->align_axis == axis) | ||||
|     return; | ||||
|  | ||||
|   align->align_axis = axis; | ||||
|  | ||||
|   if (align->actor != NULL) | ||||
|     clutter_actor_queue_relayout (align->actor); | ||||
|  | ||||
|   g_object_notify_by_pspec (G_OBJECT (align), obj_props[PROP_ALIGN_AXIS]); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_align_constraint_get_align_axis: | ||||
|  * @align: a #ClutterAlignConstraint | ||||
|  * | ||||
|  * Retrieves the value set using [method@Clutter.AlignConstraint.set_align_axis] | ||||
|  * | ||||
|  * Return value: the alignment axis | ||||
|  */ | ||||
| ClutterAlignAxis | ||||
| clutter_align_constraint_get_align_axis (ClutterAlignConstraint *align) | ||||
| { | ||||
|   g_return_val_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align), | ||||
|                         CLUTTER_ALIGN_X_AXIS); | ||||
|  | ||||
|   return align->align_axis; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_align_constraint_set_pivot_point: | ||||
|  * @align: a #ClutterAlignConstraint | ||||
|  * @pivot_point: A #GraphenePoint | ||||
|  * | ||||
|  * Sets the pivot point used by the constraint, the pivot point is the | ||||
|  * point in the constraint actor around which the aligning is applied, | ||||
|  * with (0, 0) being the top left corner of the actor and (1, 1) the | ||||
|  * bottom right corner of the actor. | ||||
|  * | ||||
|  * If -1 is used, the pivot point is unset and the constrained actor | ||||
|  * will be aligned to always stay inside the source actor. | ||||
|  */ | ||||
| void | ||||
| clutter_align_constraint_set_pivot_point (ClutterAlignConstraint *align, | ||||
|                                           const graphene_point_t *pivot_point) | ||||
| { | ||||
|   g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align)); | ||||
|   g_return_if_fail (pivot_point != NULL); | ||||
|   g_return_if_fail (pivot_point->x == -1.f || | ||||
|                     (pivot_point->x >= 0.f && pivot_point->x <= 1.f)); | ||||
|   g_return_if_fail (pivot_point->y == -1.f || | ||||
|                     (pivot_point->y >= 0.f && pivot_point->y <= 1.f)); | ||||
|  | ||||
|   if (graphene_point_equal (&align->pivot, pivot_point)) | ||||
|     return; | ||||
|  | ||||
|   align->pivot = *pivot_point; | ||||
|  | ||||
|   if (align->actor != NULL) | ||||
|     clutter_actor_queue_relayout (align->actor); | ||||
|  | ||||
|   g_object_notify_by_pspec (G_OBJECT (align), obj_props[PROP_PIVOT_POINT]); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_align_constraint_get_pivot_point | ||||
|  * @align: a #ClutterAlignConstraint | ||||
|  * @pivot_point: (out caller-allocates): return location for a #GraphenePoint | ||||
|  * | ||||
|  * Gets the pivot point used by the constraint set with | ||||
|  * [method@Clutter.AlignConstraint.set_pivot_point]. If no custom pivot | ||||
|  * point is set, -1 is set. | ||||
|  */ | ||||
| void | ||||
| clutter_align_constraint_get_pivot_point (ClutterAlignConstraint *align, | ||||
|                                           graphene_point_t       *pivot_point) | ||||
| { | ||||
|   g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align)); | ||||
|   g_return_if_fail (pivot_point != NULL); | ||||
|  | ||||
|   *pivot_point = align->pivot; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_align_constraint_set_factor: | ||||
|  * @align: a #ClutterAlignConstraint | ||||
|  * @factor: the alignment factor, between 0.0 and 1.0 | ||||
|  * | ||||
|  * Sets the alignment factor of the constraint | ||||
|  * | ||||
|  * The factor depends on the #ClutterAlignConstraint:align-axis property | ||||
|  * and it is a value between 0.0 (meaning left, when | ||||
|  * #ClutterAlignConstraint:align-axis is set to %CLUTTER_ALIGN_X_AXIS; or | ||||
|  * meaning top, when #ClutterAlignConstraint:align-axis is set to | ||||
|  * %CLUTTER_ALIGN_Y_AXIS) and 1.0 (meaning right, when | ||||
|  * #ClutterAlignConstraint:align-axis is set to %CLUTTER_ALIGN_X_AXIS; or | ||||
|  * meaning bottom, when #ClutterAlignConstraint:align-axis is set to | ||||
|  * %CLUTTER_ALIGN_Y_AXIS). A value of 0.5 aligns in the middle in either | ||||
|  * cases | ||||
|  */ | ||||
| void | ||||
| clutter_align_constraint_set_factor (ClutterAlignConstraint *align, | ||||
|                                      gfloat                  factor) | ||||
| { | ||||
|   g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align)); | ||||
|  | ||||
|   align->factor = CLAMP (factor, 0.0, 1.0); | ||||
|  | ||||
|   if (align->actor != NULL) | ||||
|     clutter_actor_queue_relayout (align->actor); | ||||
|  | ||||
|   g_object_notify_by_pspec (G_OBJECT (align), obj_props[PROP_FACTOR]); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_align_constraint_get_factor: | ||||
|  * @align: a #ClutterAlignConstraint | ||||
|  * | ||||
|  * Retrieves the factor set using [method@Clutter.AlignConstraint.set_factor] | ||||
|  * | ||||
|  * Return value: the alignment factor | ||||
|  */ | ||||
| gfloat | ||||
| clutter_align_constraint_get_factor (ClutterAlignConstraint *align) | ||||
| { | ||||
|   g_return_val_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align), 0.0); | ||||
|  | ||||
|   return align->factor; | ||||
| } | ||||
| @@ -1,68 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2010  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> | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <clutter/clutter.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include "clutter/clutter-constraint.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CLUTTER_TYPE_ALIGN_CONSTRAINT           (clutter_align_constraint_get_type ()) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_FINAL_TYPE (ClutterAlignConstraint, clutter_align_constraint, | ||||
|                       CLUTTER, ALIGN_CONSTRAINT, ClutterConstraint) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterConstraint *clutter_align_constraint_new            (ClutterActor           *source, | ||||
|                                                             ClutterAlignAxis        axis, | ||||
|                                                             gfloat                  factor); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void               clutter_align_constraint_set_source     (ClutterAlignConstraint *align, | ||||
|                                                             ClutterActor           *source); | ||||
| CLUTTER_EXPORT | ||||
| ClutterActor *     clutter_align_constraint_get_source     (ClutterAlignConstraint *align); | ||||
| CLUTTER_EXPORT | ||||
| void               clutter_align_constraint_set_align_axis (ClutterAlignConstraint *align, | ||||
|                                                             ClutterAlignAxis        axis); | ||||
| CLUTTER_EXPORT | ||||
| ClutterAlignAxis   clutter_align_constraint_get_align_axis (ClutterAlignConstraint *align); | ||||
| CLUTTER_EXPORT | ||||
| void               clutter_align_constraint_set_pivot_point (ClutterAlignConstraint *align, | ||||
|                                                              const graphene_point_t *pivot_point); | ||||
| CLUTTER_EXPORT | ||||
| void               clutter_align_constraint_get_pivot_point (ClutterAlignConstraint *align, | ||||
|                                                              graphene_point_t       *pivot_point); | ||||
| CLUTTER_EXPORT | ||||
| void               clutter_align_constraint_set_factor     (ClutterAlignConstraint *align, | ||||
|                                                             gfloat                  factor); | ||||
| CLUTTER_EXPORT | ||||
| gfloat             clutter_align_constraint_get_factor     (ClutterAlignConstraint *align); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,207 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * 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/>. | ||||
|  * | ||||
|  * Author: | ||||
|  *   Emmanuele Bassi <ebassi@linux.intel.com> | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * ClutterAnimatable: | ||||
|  *  | ||||
|  * Interface for animatable classes | ||||
|  * | ||||
|  * #ClutterAnimatable is an interface that allows a [class@GObject.Object] class | ||||
|  * to control how an actor will animate a property. | ||||
|  * | ||||
|  * Each #ClutterAnimatable should implement the | ||||
|  * [vfunc@Animatable.interpolate_value] 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. | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "clutter/clutter-animatable.h" | ||||
| #include "clutter/clutter-interval.h" | ||||
| #include "clutter/clutter-debug.h" | ||||
| #include "clutter/clutter-private.h" | ||||
|  | ||||
| G_DEFINE_INTERFACE (ClutterAnimatable, clutter_animatable, G_TYPE_OBJECT); | ||||
|  | ||||
| static void | ||||
| clutter_animatable_default_init (ClutterAnimatableInterface *iface) | ||||
| { | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_animatable_find_property: | ||||
|  * @animatable: a #ClutterAnimatable | ||||
|  * @property_name: the name of the animatable property to find | ||||
|  * | ||||
|  * Finds the [class@GObject.ParamSpec] for @property_name | ||||
|  * | ||||
|  * Return value: (transfer none): The #GParamSpec for the given property | ||||
|  *   or %NULL | ||||
|  */ | ||||
| GParamSpec * | ||||
| clutter_animatable_find_property (ClutterAnimatable *animatable, | ||||
|                                   const gchar       *property_name) | ||||
| { | ||||
|   ClutterAnimatableInterface *iface; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_ANIMATABLE (animatable), NULL); | ||||
|   g_return_val_if_fail (property_name != NULL, NULL); | ||||
|  | ||||
|   CLUTTER_NOTE (ANIMATION, "Looking for property '%s'", property_name); | ||||
|  | ||||
|   iface = CLUTTER_ANIMATABLE_GET_IFACE (animatable); | ||||
|   if (iface->find_property != NULL) | ||||
|     return iface->find_property (animatable, property_name); | ||||
|  | ||||
|   return g_object_class_find_property (G_OBJECT_GET_CLASS (animatable), | ||||
|                                        property_name); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_animatable_get_initial_state: | ||||
|  * @animatable: a #ClutterAnimatable | ||||
|  * @property_name: the name of the animatable property to retrieve | ||||
|  * @value: a #GValue initialized to the type of the property to retrieve | ||||
|  * | ||||
|  * Retrieves the current state of @property_name and sets @value with it | ||||
|  */ | ||||
| void | ||||
| clutter_animatable_get_initial_state (ClutterAnimatable *animatable, | ||||
|                                       const gchar       *property_name, | ||||
|                                       GValue            *value) | ||||
| { | ||||
|   ClutterAnimatableInterface *iface; | ||||
|  | ||||
|   g_return_if_fail (CLUTTER_IS_ANIMATABLE (animatable)); | ||||
|   g_return_if_fail (property_name != NULL); | ||||
|  | ||||
|   CLUTTER_NOTE (ANIMATION, "Getting initial state of '%s'", property_name); | ||||
|  | ||||
|   iface = CLUTTER_ANIMATABLE_GET_IFACE (animatable); | ||||
|   if (iface->get_initial_state != NULL) | ||||
|     iface->get_initial_state (animatable, property_name, value); | ||||
|   else | ||||
|     g_object_get_property (G_OBJECT (animatable), property_name, value); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_animatable_set_final_state: | ||||
|  * @animatable: a #ClutterAnimatable | ||||
|  * @property_name: the name of the animatable property to set | ||||
|  * @value: the value of the animatable property to set | ||||
|  * | ||||
|  * Sets the current state of @property_name to @value | ||||
|  */ | ||||
| void | ||||
| clutter_animatable_set_final_state (ClutterAnimatable *animatable, | ||||
|                                     const gchar       *property_name, | ||||
|                                     const GValue      *value) | ||||
| { | ||||
|   ClutterAnimatableInterface *iface; | ||||
|  | ||||
|   g_return_if_fail (CLUTTER_IS_ANIMATABLE (animatable)); | ||||
|   g_return_if_fail (property_name != NULL); | ||||
|  | ||||
|   CLUTTER_NOTE (ANIMATION, "Setting state of property '%s'", property_name); | ||||
|  | ||||
|   iface = CLUTTER_ANIMATABLE_GET_IFACE (animatable); | ||||
|   if (iface->set_final_state != NULL) | ||||
|     iface->set_final_state (animatable, property_name, value); | ||||
|   else | ||||
|     g_object_set_property (G_OBJECT (animatable), property_name, value); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_animatable_interpolate_value: | ||||
|  * @animatable: a #ClutterAnimatable | ||||
|  * @property_name: the name of the property to interpolate | ||||
|  * @interval: a #ClutterInterval with the animation range | ||||
|  * @progress: the progress to use to interpolate between the | ||||
|  *   initial and final values of the @interval | ||||
|  * @value: (out): return location for an initialized #GValue | ||||
|  *   using the same type of the @interval | ||||
|  * | ||||
|  * Asks a #ClutterAnimatable implementation to interpolate a | ||||
|  * a named property between the initial and final values of | ||||
|  * a #ClutterInterval, using @progress as the interpolation | ||||
|  * value, and store the result inside @value. | ||||
|  * | ||||
|  * This function should be used for every property animation | ||||
|  * involving `ClutterAnimatable`s. | ||||
|  * | ||||
|  * Return value: %TRUE if the interpolation was successful, | ||||
|  *   and %FALSE otherwise | ||||
|  */ | ||||
| gboolean | ||||
| clutter_animatable_interpolate_value (ClutterAnimatable *animatable, | ||||
|                                       const gchar       *property_name, | ||||
|                                       ClutterInterval   *interval, | ||||
|                                       gdouble            progress, | ||||
|                                       GValue            *value) | ||||
| { | ||||
|   ClutterAnimatableInterface *iface; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_ANIMATABLE (animatable), FALSE); | ||||
|   g_return_val_if_fail (property_name != NULL, FALSE); | ||||
|   g_return_val_if_fail (CLUTTER_IS_INTERVAL (interval), FALSE); | ||||
|   g_return_val_if_fail (value != NULL, FALSE); | ||||
|  | ||||
|   CLUTTER_NOTE (ANIMATION, "Interpolating '%s' (progress: %.3f)", | ||||
|                 property_name, | ||||
|                 progress); | ||||
|  | ||||
|   iface = CLUTTER_ANIMATABLE_GET_IFACE (animatable); | ||||
|   if (iface->interpolate_value != NULL) | ||||
|     { | ||||
|       return iface->interpolate_value (animatable, property_name, | ||||
|                                        interval, | ||||
|                                        progress, | ||||
|                                        value); | ||||
|     } | ||||
|   else | ||||
|     return clutter_interval_compute_value (interval, progress, value); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_animatable_get_actor: | ||||
|  * @animatable: a #ClutterAnimatable | ||||
|  * | ||||
|  * Get animated actor. | ||||
|  * | ||||
|  * Return value: (transfer none): a #ClutterActor | ||||
|  */ | ||||
| ClutterActor * | ||||
| clutter_animatable_get_actor (ClutterAnimatable *animatable) | ||||
| { | ||||
|   ClutterAnimatableInterface *iface; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_ANIMATABLE (animatable), NULL); | ||||
|  | ||||
|   iface = CLUTTER_ANIMATABLE_GET_IFACE (animatable); | ||||
|  | ||||
|   g_return_val_if_fail (iface->get_actor, NULL); | ||||
|  | ||||
|   return iface->get_actor (animatable); | ||||
| } | ||||
| @@ -1,97 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * 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/>. | ||||
|  * | ||||
|  * Author: | ||||
|  *   Emmanuele Bassi <ebassi@linux.intel.com> | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <clutter/clutter.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include "clutter/clutter-types.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CLUTTER_TYPE_ANIMATABLE (clutter_animatable_get_type ()) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_INTERFACE (ClutterAnimatable, clutter_animatable, | ||||
|                      CLUTTER, ANIMATABLE, | ||||
|                      GObject) | ||||
|  | ||||
| /** | ||||
|  * ClutterAnimatableInterface: | ||||
|  * @find_property: virtual function for retrieving the #GParamSpec of | ||||
|  *   an animatable property | ||||
|  * @get_initial_state: virtual function for retrieving the initial | ||||
|  *   state of an animatable property | ||||
|  * @set_final_state: virtual function for setting the state of an | ||||
|  *   animatable property | ||||
|  * @interpolate_value: virtual function for interpolating the progress | ||||
|  *   of a property | ||||
|  * @get_actor: virtual function for getting associated actor | ||||
|  */ | ||||
| struct _ClutterAnimatableInterface | ||||
| { | ||||
|   /*< private >*/ | ||||
|   GTypeInterface parent_iface; | ||||
|  | ||||
|   /*< public >*/ | ||||
|   GParamSpec *(* find_property)     (ClutterAnimatable *animatable, | ||||
|                                      const gchar       *property_name); | ||||
|   void        (* get_initial_state) (ClutterAnimatable *animatable, | ||||
|                                      const gchar       *property_name, | ||||
|                                      GValue            *value); | ||||
|   void        (* set_final_state)   (ClutterAnimatable *animatable, | ||||
|                                      const gchar       *property_name, | ||||
|                                      const GValue      *value); | ||||
|   gboolean    (* interpolate_value) (ClutterAnimatable *animatable, | ||||
|                                      const gchar       *property_name, | ||||
|                                      ClutterInterval   *interval, | ||||
|                                      gdouble            progress, | ||||
|                                      GValue            *value); | ||||
|   ClutterActor * (* get_actor)      (ClutterAnimatable *animatable); | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| GParamSpec *clutter_animatable_find_property     (ClutterAnimatable *animatable, | ||||
|                                                   const gchar       *property_name); | ||||
| CLUTTER_EXPORT | ||||
| void        clutter_animatable_get_initial_state (ClutterAnimatable *animatable, | ||||
|                                                   const gchar       *property_name, | ||||
|                                                   GValue            *value); | ||||
| CLUTTER_EXPORT | ||||
| void        clutter_animatable_set_final_state   (ClutterAnimatable *animatable, | ||||
|                                                   const gchar       *property_name, | ||||
|                                                   const GValue      *value); | ||||
| CLUTTER_EXPORT | ||||
| gboolean    clutter_animatable_interpolate_value (ClutterAnimatable *animatable, | ||||
|                                                   const gchar       *property_name, | ||||
|                                                   ClutterInterval   *interval, | ||||
|                                                   gdouble            progress, | ||||
|                                                   GValue            *value); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterActor * clutter_animatable_get_actor      (ClutterAnimatable *animatable); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,107 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2010  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/>. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "clutter/clutter-backend.h" | ||||
| #include "clutter/clutter-seat.h" | ||||
| #include "clutter/clutter-stage-window.h" | ||||
|  | ||||
| #define CLUTTER_BACKEND_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_BACKEND, ClutterBackendClass)) | ||||
| #define CLUTTER_IS_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_BACKEND)) | ||||
| #define CLUTTER_BACKEND_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_BACKEND, ClutterBackendClass)) | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| typedef struct _ClutterBackendPrivate   ClutterBackendPrivate; | ||||
|  | ||||
| struct _ClutterBackend | ||||
| { | ||||
|   /*< private >*/ | ||||
|   GObject parent_instance; | ||||
|  | ||||
|   CoglRenderer *cogl_renderer; | ||||
|   CoglDisplay *cogl_display; | ||||
|   CoglContext *cogl_context; | ||||
|   GSource *cogl_source; | ||||
|  | ||||
|   CoglOnscreen *dummy_onscreen; | ||||
|  | ||||
|   cairo_font_options_t *font_options; | ||||
|  | ||||
|   gchar *font_name; | ||||
|  | ||||
|   float fallback_resource_scale; | ||||
|  | ||||
|   ClutterStageWindow *stage_window; | ||||
|  | ||||
|   ClutterInputMethod *input_method; | ||||
| }; | ||||
|  | ||||
| struct _ClutterBackendClass | ||||
| { | ||||
|   /*< private >*/ | ||||
|   GObjectClass parent_class; | ||||
|  | ||||
|   /* vfuncs */ | ||||
|   ClutterStageWindow *  (* create_stage)       (ClutterBackend  *backend, | ||||
|                                                 ClutterStage    *wrapper, | ||||
|                                                 GError         **error); | ||||
|   CoglRenderer *        (* get_renderer)       (ClutterBackend  *backend, | ||||
|                                                 GError         **error); | ||||
|   CoglDisplay *         (* get_display)        (ClutterBackend  *backend, | ||||
|                                                 CoglRenderer    *renderer, | ||||
|                                                 CoglSwapChain   *swap_chain, | ||||
|                                                 GError         **error); | ||||
|   gboolean              (* create_context)     (ClutterBackend  *backend, | ||||
|                                                 GError         **error); | ||||
|  | ||||
|   ClutterSeat *         (* get_default_seat)   (ClutterBackend *backend); | ||||
|  | ||||
|   gboolean              (* is_display_server)  (ClutterBackend *backend); | ||||
|  | ||||
|   /* signals */ | ||||
|   void (* resolution_changed) (ClutterBackend *backend); | ||||
|   void (* font_changed)       (ClutterBackend *backend); | ||||
|   void (* settings_changed)   (ClutterBackend *backend); | ||||
| }; | ||||
|  | ||||
| ClutterStageWindow *    _clutter_backend_create_stage                   (ClutterBackend         *backend, | ||||
|                                                                          ClutterStage           *wrapper, | ||||
|                                                                          GError                **error); | ||||
| gboolean                _clutter_backend_create_context                 (ClutterBackend         *backend, | ||||
|                                                                          GError                **error); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterStageWindow *    clutter_backend_get_stage_window                (ClutterBackend         *backend); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void clutter_backend_set_fallback_resource_scale (ClutterBackend *backend, | ||||
|                                                   float           fallback_resource_scale); | ||||
|  | ||||
| float clutter_backend_get_fallback_resource_scale (ClutterBackend *backend); | ||||
|  | ||||
| gboolean clutter_backend_is_display_server (ClutterBackend *backend); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void clutter_backend_destroy (ClutterBackend *backend); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,603 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Authored By: | ||||
|  *      Matthew Allum <mallum@openedhand.com> | ||||
|  *      Emmanuele Bassi <ebassi@linux.intel.com> | ||||
|  * | ||||
|  * Copyright (C) 2006, 2007, 2008 OpenedHand Ltd | ||||
|  * 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/>. | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * ClutterBackend: | ||||
|  *  | ||||
|  * Backend abstraction | ||||
|  * | ||||
|  * Clutter can be compiled against different backends. Each backend | ||||
|  * has to implement a set of functions, in order to be used by Clutter. | ||||
|  * | ||||
|  * #ClutterBackend is the base class abstracting the various implementation; | ||||
|  * it provides a basic API to query the backend for generic information | ||||
|  * and settings. | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "clutter/clutter-backend-private.h" | ||||
| #include "clutter/clutter-context-private.h" | ||||
| #include "clutter/clutter-debug.h" | ||||
| #include "clutter/clutter-event-private.h" | ||||
| #include "clutter/clutter-marshal.h" | ||||
| #include "clutter/clutter-mutter.h" | ||||
| #include "clutter/clutter-private.h" | ||||
| #include "clutter/clutter-stage-manager-private.h" | ||||
| #include "clutter/clutter-stage-private.h" | ||||
| #include "clutter/clutter-stage-window.h" | ||||
|  | ||||
| #include "cogl/cogl.h" | ||||
|  | ||||
| #define DEFAULT_FONT_NAME       "Sans 10" | ||||
|  | ||||
| enum | ||||
| { | ||||
|   RESOLUTION_CHANGED, | ||||
|   FONT_CHANGED, | ||||
|   SETTINGS_CHANGED, | ||||
|  | ||||
|   LAST_SIGNAL | ||||
| }; | ||||
|  | ||||
| G_DEFINE_ABSTRACT_TYPE (ClutterBackend, clutter_backend, G_TYPE_OBJECT) | ||||
|  | ||||
| static guint backend_signals[LAST_SIGNAL] = { 0, }; | ||||
|  | ||||
| static void | ||||
| clutter_backend_dispose (GObject *gobject) | ||||
| { | ||||
|   ClutterBackend *backend = CLUTTER_BACKEND (gobject); | ||||
|  | ||||
|   /* clear the events still in the queue of the main context */ | ||||
|   _clutter_clear_events_queue (); | ||||
|  | ||||
|   g_clear_object (&backend->dummy_onscreen); | ||||
|   if (backend->stage_window) | ||||
|     { | ||||
|       g_object_remove_weak_pointer (G_OBJECT (backend->stage_window), | ||||
|                                     (gpointer *) &backend->stage_window); | ||||
|       backend->stage_window = NULL; | ||||
|     } | ||||
|  | ||||
|   g_clear_pointer (&backend->cogl_source, g_source_destroy); | ||||
|   g_clear_pointer (&backend->font_name, g_free); | ||||
|   g_clear_pointer (&backend->font_options, cairo_font_options_destroy); | ||||
|   g_clear_object (&backend->input_method); | ||||
|  | ||||
|   G_OBJECT_CLASS (clutter_backend_parent_class)->dispose (gobject); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_backend_real_resolution_changed (ClutterBackend *backend) | ||||
| { | ||||
|   ClutterContext *context; | ||||
|   ClutterSettings *settings; | ||||
|   gdouble resolution; | ||||
|   gint dpi; | ||||
|  | ||||
|   settings = clutter_settings_get_default (); | ||||
|   g_object_get (settings, "font-dpi", &dpi, NULL); | ||||
|  | ||||
|   if (dpi < 0) | ||||
|     resolution = 96.0; | ||||
|   else | ||||
|     resolution = dpi / 1024.0; | ||||
|  | ||||
|   context = _clutter_context_get_default (); | ||||
|   if (context->font_map != NULL) | ||||
|     cogl_pango_font_map_set_resolution (context->font_map, resolution); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| clutter_backend_do_real_create_context (ClutterBackend  *backend, | ||||
|                                         CoglDriver       driver_id, | ||||
|                                         GError         **error) | ||||
| { | ||||
|   ClutterBackendClass *klass; | ||||
|   CoglSwapChain *swap_chain; | ||||
|  | ||||
|   klass = CLUTTER_BACKEND_GET_CLASS (backend); | ||||
|  | ||||
|   swap_chain = NULL; | ||||
|  | ||||
|   CLUTTER_NOTE (BACKEND, "Creating Cogl renderer"); | ||||
|   backend->cogl_renderer = klass->get_renderer (backend, error); | ||||
|  | ||||
|   if (backend->cogl_renderer == NULL) | ||||
|     goto error; | ||||
|  | ||||
|   CLUTTER_NOTE (BACKEND, "Connecting the renderer"); | ||||
|   cogl_renderer_set_driver (backend->cogl_renderer, driver_id); | ||||
|   if (!cogl_renderer_connect (backend->cogl_renderer, error)) | ||||
|     goto error; | ||||
|  | ||||
|   CLUTTER_NOTE (BACKEND, "Creating Cogl swap chain"); | ||||
|   swap_chain = cogl_swap_chain_new (); | ||||
|  | ||||
|   CLUTTER_NOTE (BACKEND, "Creating Cogl display"); | ||||
|   if (klass->get_display != NULL) | ||||
|     { | ||||
|       backend->cogl_display = klass->get_display (backend, | ||||
|                                                   backend->cogl_renderer, | ||||
|                                                   swap_chain, | ||||
|                                                   error); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       CoglOnscreenTemplate *tmpl; | ||||
|       gboolean res; | ||||
|  | ||||
|       tmpl = cogl_onscreen_template_new (swap_chain); | ||||
|  | ||||
|       /* XXX: I have some doubts that this is a good design. | ||||
|        * | ||||
|        * Conceptually should we be able to check an onscreen_template | ||||
|        * without more details about the CoglDisplay configuration? | ||||
|        */ | ||||
|       res = cogl_renderer_check_onscreen_template (backend->cogl_renderer, | ||||
|                                                    tmpl, | ||||
|                                                    error); | ||||
|  | ||||
|       if (!res) | ||||
|         goto error; | ||||
|  | ||||
|       backend->cogl_display = cogl_display_new (backend->cogl_renderer, tmpl); | ||||
|  | ||||
|       /* the display owns the template */ | ||||
|       g_object_unref (tmpl); | ||||
|     } | ||||
|  | ||||
|   if (backend->cogl_display == NULL) | ||||
|     goto error; | ||||
|  | ||||
|   CLUTTER_NOTE (BACKEND, "Setting up the display"); | ||||
|   if (!cogl_display_setup (backend->cogl_display, error)) | ||||
|     goto error; | ||||
|  | ||||
|   CLUTTER_NOTE (BACKEND, "Creating the Cogl context"); | ||||
|   backend->cogl_context = cogl_context_new (backend->cogl_display, error); | ||||
|   if (backend->cogl_context == NULL) | ||||
|     goto error; | ||||
|  | ||||
|   /* the display owns the renderer and the swap chain */ | ||||
|   g_object_unref (backend->cogl_renderer); | ||||
|   g_object_unref (swap_chain); | ||||
|  | ||||
|   return TRUE; | ||||
|  | ||||
| error: | ||||
|   g_clear_object (&backend->cogl_display); | ||||
|   g_clear_object (&backend->cogl_renderer); | ||||
|  | ||||
|   if (swap_chain != NULL) | ||||
|     g_object_unref (swap_chain); | ||||
|  | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| static const struct { | ||||
|   const char *driver_name; | ||||
|   const char *driver_desc; | ||||
|   CoglDriver driver_id; | ||||
| } all_known_drivers[] = { | ||||
|   { "gl3", "OpenGL 3.1 core profile", COGL_DRIVER_GL3 }, | ||||
|   { "gles2", "OpenGL ES 2.0", COGL_DRIVER_GLES2 }, | ||||
|   { "any", "Default Cogl driver", COGL_DRIVER_ANY }, | ||||
| }; | ||||
|  | ||||
| static gboolean | ||||
| clutter_backend_real_create_context (ClutterBackend  *backend, | ||||
|                                      GError         **error) | ||||
| { | ||||
|   GError *internal_error = NULL; | ||||
|   const char *drivers_list; | ||||
|   char **known_drivers; | ||||
|   int i; | ||||
|  | ||||
|   if (backend->cogl_context != NULL) | ||||
|     return TRUE; | ||||
|  | ||||
|   drivers_list = g_getenv ("CLUTTER_DRIVER"); | ||||
|   if (drivers_list == NULL) | ||||
|     drivers_list = "*"; | ||||
|  | ||||
|   known_drivers = g_strsplit (drivers_list, ",", 0); | ||||
|  | ||||
|   for (i = 0; backend->cogl_context == NULL && known_drivers[i] != NULL; i++) | ||||
|     { | ||||
|       const char *driver_name = known_drivers[i]; | ||||
|       gboolean is_any = g_str_equal (driver_name, "*"); | ||||
|       int j; | ||||
|  | ||||
|       for (j = 0; j < G_N_ELEMENTS (all_known_drivers); j++) | ||||
|         { | ||||
|           if (is_any || | ||||
|               g_str_equal (all_known_drivers[j].driver_name, driver_name)) | ||||
|             { | ||||
|               CLUTTER_NOTE (BACKEND, "Checking for the %s driver", all_known_drivers[j].driver_desc); | ||||
|  | ||||
|               if (clutter_backend_do_real_create_context (backend, all_known_drivers[j].driver_id, &internal_error)) | ||||
|                 break; | ||||
|  | ||||
|               if (internal_error) | ||||
|                 { | ||||
|                   CLUTTER_NOTE (BACKEND, "Unable to use the %s driver: %s", | ||||
|                                 all_known_drivers[j].driver_desc, | ||||
|                                 internal_error->message); | ||||
|                   g_clear_error (&internal_error); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   g_strfreev (known_drivers); | ||||
|  | ||||
|   if (backend->cogl_context == NULL) | ||||
|     { | ||||
|       if (internal_error != NULL) | ||||
|         g_propagate_error (error, internal_error); | ||||
|       else | ||||
|         g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, | ||||
|                              "Unable to initialize the Clutter backend: no available drivers found."); | ||||
|  | ||||
|       return FALSE; | ||||
|     } | ||||
|  | ||||
|   backend->cogl_source = cogl_glib_source_new (backend->cogl_context, G_PRIORITY_DEFAULT); | ||||
|   g_source_attach (backend->cogl_source, NULL); | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_backend_class_init (ClutterBackendClass *klass) | ||||
| { | ||||
|   GObjectClass *gobject_class = G_OBJECT_CLASS (klass); | ||||
|  | ||||
|   gobject_class->dispose = clutter_backend_dispose; | ||||
|  | ||||
|   /** | ||||
|    * ClutterBackend::resolution-changed: | ||||
|    * @backend: the #ClutterBackend that emitted the signal | ||||
|    * | ||||
|    * The signal is emitted each time the font | ||||
|    * resolutions has been changed through #ClutterSettings. | ||||
|    */ | ||||
|   backend_signals[RESOLUTION_CHANGED] = | ||||
|     g_signal_new (I_("resolution-changed"), | ||||
|                   G_TYPE_FROM_CLASS (klass), | ||||
|                   G_SIGNAL_RUN_FIRST, | ||||
|                   G_STRUCT_OFFSET (ClutterBackendClass, resolution_changed), | ||||
|                   NULL, NULL, NULL, | ||||
|                   G_TYPE_NONE, 0); | ||||
|  | ||||
|   /** | ||||
|    * ClutterBackend::font-changed: | ||||
|    * @backend: the #ClutterBackend that emitted the signal | ||||
|    * | ||||
|    * The signal is emitted each time the font options | ||||
|    * have been changed through #ClutterSettings. | ||||
|    */ | ||||
|   backend_signals[FONT_CHANGED] = | ||||
|     g_signal_new (I_("font-changed"), | ||||
|                   G_TYPE_FROM_CLASS (klass), | ||||
|                   G_SIGNAL_RUN_FIRST, | ||||
|                   G_STRUCT_OFFSET (ClutterBackendClass, font_changed), | ||||
|                   NULL, NULL, NULL, | ||||
|                   G_TYPE_NONE, 0); | ||||
|  | ||||
|   /** | ||||
|    * ClutterBackend::settings-changed: | ||||
|    * @backend: the #ClutterBackend that emitted the signal | ||||
|    * | ||||
|    * The signal is emitted each time the #ClutterSettings | ||||
|    * properties have been changed. | ||||
|    */ | ||||
|   backend_signals[SETTINGS_CHANGED] = | ||||
|     g_signal_new (I_("settings-changed"), | ||||
|                   G_TYPE_FROM_CLASS (klass), | ||||
|                   G_SIGNAL_RUN_FIRST, | ||||
|                   G_STRUCT_OFFSET (ClutterBackendClass, settings_changed), | ||||
|                   NULL, NULL, NULL, | ||||
|                   G_TYPE_NONE, 0); | ||||
|  | ||||
|   klass->resolution_changed = clutter_backend_real_resolution_changed; | ||||
|  | ||||
|   klass->create_context = clutter_backend_real_create_context; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_backend_init (ClutterBackend *self) | ||||
| { | ||||
|   self->dummy_onscreen = NULL; | ||||
|  | ||||
|   self->fallback_resource_scale = 1.f; | ||||
| } | ||||
|  | ||||
| ClutterStageWindow * | ||||
| _clutter_backend_create_stage (ClutterBackend  *backend, | ||||
|                                ClutterStage    *wrapper, | ||||
|                                GError         **error) | ||||
| { | ||||
|   ClutterBackendClass *klass; | ||||
|   ClutterStageWindow *stage_window; | ||||
|  | ||||
|   g_assert (CLUTTER_IS_BACKEND (backend)); | ||||
|   g_assert (CLUTTER_IS_STAGE (wrapper)); | ||||
|  | ||||
|   klass = CLUTTER_BACKEND_GET_CLASS (backend); | ||||
|   if (klass->create_stage != NULL) | ||||
|     stage_window = klass->create_stage (backend, wrapper, error); | ||||
|   else | ||||
|     stage_window = NULL; | ||||
|  | ||||
|   if (stage_window == NULL) | ||||
|     return NULL; | ||||
|  | ||||
|   g_assert (CLUTTER_IS_STAGE_WINDOW (stage_window)); | ||||
|  | ||||
|   backend->stage_window = stage_window; | ||||
|   g_object_add_weak_pointer (G_OBJECT (backend->stage_window), | ||||
|                              (gpointer *) &backend->stage_window); | ||||
|  | ||||
|   return stage_window; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| _clutter_backend_create_context (ClutterBackend  *backend, | ||||
|                                  GError         **error) | ||||
| { | ||||
|   ClutterBackendClass *klass; | ||||
|  | ||||
|   klass = CLUTTER_BACKEND_GET_CLASS (backend); | ||||
|  | ||||
|   return klass->create_context (backend, error); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_get_default_backend: | ||||
|  * | ||||
|  * Retrieves the default #ClutterBackend used by Clutter. The | ||||
|  * #ClutterBackend holds backend-specific configuration options. | ||||
|  * | ||||
|  * Return value: (transfer none): the default backend. You should | ||||
|  *   not ref or unref the returned object. Applications should rarely | ||||
|  *   need to use this. | ||||
|  */ | ||||
| ClutterBackend * | ||||
| clutter_get_default_backend (void) | ||||
| { | ||||
|   ClutterContext *clutter_context; | ||||
|  | ||||
|   clutter_context = _clutter_context_get_default (); | ||||
|  | ||||
|   return clutter_context->backend; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_backend_get_resolution: | ||||
|  * @backend: a #ClutterBackend | ||||
|  * | ||||
|  * Gets the resolution for font handling on the screen. | ||||
|  * | ||||
|  * The resolution is a scale factor between points specified in a | ||||
|  * #PangoFontDescription and cairo units. The default value is 96.0, | ||||
|  * meaning that a 10 point font will be 13 units | ||||
|  * high (10 * 96. / 72. = 13.3). | ||||
|  * | ||||
|  * Clutter will set the resolution using the current backend when | ||||
|  * initializing; the resolution is also stored in the | ||||
|  * #ClutterSettings:font-dpi property. | ||||
|  * | ||||
|  * Return value: the current resolution, or -1 if no resolution | ||||
|  *   has been set. | ||||
|  */ | ||||
| gdouble | ||||
| clutter_backend_get_resolution (ClutterBackend *backend) | ||||
| { | ||||
|   ClutterSettings *settings; | ||||
|   gint resolution; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), -1.0); | ||||
|  | ||||
|   settings = clutter_settings_get_default (); | ||||
|   g_object_get (settings, "font-dpi", &resolution, NULL); | ||||
|  | ||||
|   if (resolution < 0) | ||||
|     return 96.0; | ||||
|  | ||||
|   return resolution / 1024.0; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_backend_set_font_options: | ||||
|  * @backend: a #ClutterBackend | ||||
|  * @options: Cairo font options for the backend, or %NULL | ||||
|  * | ||||
|  * Sets the new font options for @backend. The #ClutterBackend will | ||||
|  * copy the #cairo_font_options_t. | ||||
|  * | ||||
|  * If @options is %NULL, the first following call to | ||||
|  * [method@Clutter.Backend.get_font_options] will return the default font | ||||
|  * options for @backend. | ||||
|  * | ||||
|  * This function is intended for actors creating a Pango layout | ||||
|  * using the PangoCairo API. | ||||
|  */ | ||||
| void | ||||
| clutter_backend_set_font_options (ClutterBackend             *backend, | ||||
|                                   const cairo_font_options_t *options) | ||||
| { | ||||
|   g_return_if_fail (CLUTTER_IS_BACKEND (backend)); | ||||
|  | ||||
|   if (backend->font_options != options) | ||||
|     { | ||||
|       if (backend->font_options) | ||||
|         cairo_font_options_destroy (backend->font_options); | ||||
|  | ||||
|       if (options) | ||||
|         backend->font_options = cairo_font_options_copy (options); | ||||
|       else | ||||
|         backend->font_options = NULL; | ||||
|  | ||||
|       g_signal_emit (backend, backend_signals[FONT_CHANGED], 0); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_backend_get_font_options: | ||||
|  * @backend: a #ClutterBackend | ||||
|  * | ||||
|  * Retrieves the font options for @backend. | ||||
|  * | ||||
|  * Return value: (transfer none): the font options of the #ClutterBackend. | ||||
|  *   The returned #cairo_font_options_t is owned by the backend and should | ||||
|  *   not be modified or freed | ||||
|  */ | ||||
| const cairo_font_options_t * | ||||
| clutter_backend_get_font_options (ClutterBackend *backend) | ||||
| { | ||||
|   g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), NULL); | ||||
|  | ||||
|   if (G_LIKELY (backend->font_options)) | ||||
|     return backend->font_options; | ||||
|  | ||||
|   backend->font_options = cairo_font_options_create (); | ||||
|  | ||||
|   cairo_font_options_set_hint_style (backend->font_options, CAIRO_HINT_STYLE_NONE); | ||||
|   cairo_font_options_set_subpixel_order (backend->font_options, CAIRO_SUBPIXEL_ORDER_DEFAULT); | ||||
|   cairo_font_options_set_antialias (backend->font_options, CAIRO_ANTIALIAS_DEFAULT); | ||||
|  | ||||
|   g_signal_emit (backend, backend_signals[FONT_CHANGED], 0); | ||||
|  | ||||
|   return backend->font_options; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_backend_get_cogl_context: | ||||
|  * @backend: a #ClutterBackend | ||||
|  * | ||||
|  * Retrieves the #CoglContext associated with the given clutter | ||||
|  * @backend. A #CoglContext is required when using some of the | ||||
|  * experimental 2.0 Cogl API. | ||||
|  * | ||||
|  * Since CoglContext is itself experimental API this API should | ||||
|  * be considered experimental too. | ||||
|  * | ||||
|  * This API is not yet supported on OSX because OSX still | ||||
|  * uses the stub Cogl winsys and the Clutter backend doesn't | ||||
|  * explicitly create a CoglContext. | ||||
|  * | ||||
|  * Return value: (transfer none): The #CoglContext associated with @backend. | ||||
|  */ | ||||
| CoglContext * | ||||
| clutter_backend_get_cogl_context (ClutterBackend *backend) | ||||
| { | ||||
|   return backend->cogl_context; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_backend_get_input_method: | ||||
|  * @backend: the #CLutterBackend | ||||
|  * | ||||
|  * Returns the input method used by Clutter | ||||
|  * | ||||
|  * Returns: (transfer none): the input method | ||||
|  **/ | ||||
| ClutterInputMethod * | ||||
| clutter_backend_get_input_method (ClutterBackend *backend) | ||||
| { | ||||
|   return backend->input_method; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_backend_set_input_method: | ||||
|  * @backend: the #ClutterBackend | ||||
|  * @method: (nullable): the input method | ||||
|  * | ||||
|  * Sets the input method to be used by Clutter | ||||
|  **/ | ||||
| void | ||||
| clutter_backend_set_input_method (ClutterBackend     *backend, | ||||
|                                   ClutterInputMethod *method) | ||||
| { | ||||
|   if (backend->input_method == method) | ||||
|     return; | ||||
|  | ||||
|   if (backend->input_method) | ||||
|     clutter_input_method_focus_out (backend->input_method); | ||||
|  | ||||
|   g_set_object (&backend->input_method, method); | ||||
| } | ||||
|  | ||||
| ClutterStageWindow * | ||||
| clutter_backend_get_stage_window (ClutterBackend *backend) | ||||
| { | ||||
|   return backend->stage_window; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_backend_get_default_seat: | ||||
|  * @backend: the #ClutterBackend | ||||
|  * | ||||
|  * Returns the default seat | ||||
|  * | ||||
|  * Returns: (transfer none): the default seat | ||||
|  **/ | ||||
| ClutterSeat * | ||||
| clutter_backend_get_default_seat (ClutterBackend *backend) | ||||
| { | ||||
|   g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), NULL); | ||||
|  | ||||
|   return CLUTTER_BACKEND_GET_CLASS (backend)->get_default_seat (backend); | ||||
| } | ||||
|  | ||||
| void | ||||
| clutter_backend_set_fallback_resource_scale (ClutterBackend *backend, | ||||
|                                              float           fallback_resource_scale) | ||||
| { | ||||
|   backend->fallback_resource_scale = fallback_resource_scale; | ||||
| } | ||||
|  | ||||
| float | ||||
| clutter_backend_get_fallback_resource_scale (ClutterBackend *backend) | ||||
| { | ||||
|   return backend->fallback_resource_scale; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| clutter_backend_is_display_server (ClutterBackend *backend) | ||||
| { | ||||
|   return CLUTTER_BACKEND_GET_CLASS (backend)->is_display_server (backend); | ||||
| } | ||||
|  | ||||
| void | ||||
| clutter_backend_destroy (ClutterBackend *backend) | ||||
| { | ||||
|   g_object_run_dispose (G_OBJECT (backend)); | ||||
|   g_object_unref (backend); | ||||
| } | ||||
| @@ -1,76 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Authored By Matthew Allum  <mallum@openedhand.com> | ||||
|  * | ||||
|  * Copyright (C) 2006 OpenedHand | ||||
|  * | ||||
|  * 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/>. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <clutter/clutter.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include <cairo.h> | ||||
|  | ||||
| #include "cogl/cogl.h" | ||||
|  | ||||
| #include "clutter/clutter-keymap.h" | ||||
| #include "clutter/clutter-types.h" | ||||
| #include "clutter/clutter-seat.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CLUTTER_TYPE_BACKEND            (clutter_backend_get_type ()) | ||||
| #define CLUTTER_BACKEND(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BACKEND, ClutterBackend)) | ||||
| #define CLUTTER_IS_BACKEND(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BACKEND)) | ||||
|  | ||||
| typedef struct _ClutterBackend          ClutterBackend; | ||||
| typedef struct _ClutterBackendClass     ClutterBackendClass; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| GType clutter_backend_get_type (void) G_GNUC_CONST; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterBackend *                clutter_get_default_backend             (void); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| gdouble                         clutter_backend_get_resolution          (ClutterBackend             *backend); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_backend_set_font_options        (ClutterBackend             *backend, | ||||
|                                                                          const cairo_font_options_t *options); | ||||
| CLUTTER_EXPORT | ||||
| const cairo_font_options_t *    clutter_backend_get_font_options        (ClutterBackend             *backend); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| CoglContext *                   clutter_backend_get_cogl_context        (ClutterBackend             *backend); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterInputMethod *            clutter_backend_get_input_method        (ClutterBackend             *backend); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_backend_set_input_method        (ClutterBackend             *backend, | ||||
|                                                                          ClutterInputMethod         *method); | ||||
| CLUTTER_EXPORT | ||||
| ClutterSeat *                   clutter_backend_get_default_seat        (ClutterBackend             *backend); | ||||
|  | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBackend, g_object_unref) | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,85 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Authored By Matthew Allum  <mallum@openedhand.com> | ||||
|  * | ||||
|  * Copyright (C) 2006 OpenedHand | ||||
|  * | ||||
|  * 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 "config.h" | ||||
|  | ||||
| #include "clutter/clutter-types.h" | ||||
| #include "clutter/clutter-private.h" | ||||
|  | ||||
| #include <math.h> | ||||
|  | ||||
| #define FLOAT_EPSILON   (1e-15) | ||||
|  | ||||
| /* | ||||
|  * ClutterMargin | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * clutter_margin_new: | ||||
|  * | ||||
|  * Creates a new #ClutterMargin. | ||||
|  * | ||||
|  * Return value: (transfer full): a newly allocated #ClutterMargin. Use | ||||
|  *   [method@Clutter.Margin.free] to free the resources associated with it when | ||||
|  *   done. | ||||
|  */ | ||||
| ClutterMargin * | ||||
| clutter_margin_new (void) | ||||
| { | ||||
|   return g_new0 (ClutterMargin, 1); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_margin_copy: | ||||
|  * @margin_: a #ClutterMargin | ||||
|  * | ||||
|  * Creates a new #ClutterMargin and copies the contents of @margin_ into | ||||
|  * the newly created structure. | ||||
|  * | ||||
|  * Return value: (transfer full): a copy of the #ClutterMargin. | ||||
|  */ | ||||
| ClutterMargin * | ||||
| clutter_margin_copy (const ClutterMargin *margin_) | ||||
| { | ||||
|   if (G_LIKELY (margin_ != NULL)) | ||||
|     return g_memdup2 (margin_, sizeof (ClutterMargin)); | ||||
|  | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_margin_free: | ||||
|  * @margin_: a #ClutterMargin | ||||
|  * | ||||
|  * Frees the resources allocated by [ctor@Clutter.Margin.new] and | ||||
|  * [method@Clutter.Margin.copy]. | ||||
|  */ | ||||
| void | ||||
| clutter_margin_free (ClutterMargin *margin_) | ||||
| { | ||||
|   if (G_LIKELY (margin_ != NULL)) | ||||
|     g_free (margin_); | ||||
| } | ||||
|  | ||||
| G_DEFINE_BOXED_TYPE (ClutterMargin, clutter_margin, | ||||
|                      clutter_margin_copy, | ||||
|                      clutter_margin_free) | ||||
| @@ -1,279 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * 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/>. | ||||
|  * | ||||
|  * Author: | ||||
|  *   Emmanuele Bassi <ebassi@linux.intel.com> | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * ClutterBinLayout: | ||||
|  * | ||||
|  * A simple layout manager | ||||
|  * | ||||
|  * #ClutterBinLayout is a layout manager which implements the following | ||||
|  * policy: | ||||
|  * | ||||
|  *   - the preferred size is the maximum preferred size | ||||
|  *   between all the children of the container using the | ||||
|  *   layout; | ||||
|  *   - each child is allocated in "layers", on on top | ||||
|  *   of the other; | ||||
|  *   - for each layer there are horizontal and vertical | ||||
|  *   alignment policies. | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include <math.h> | ||||
|  | ||||
| #include "clutter/clutter-actor-private.h" | ||||
| #include "clutter/clutter-animatable.h" | ||||
| #include "clutter/clutter-bin-layout.h" | ||||
| #include "clutter/clutter-debug.h" | ||||
| #include "clutter/clutter-enum-types.h" | ||||
| #include "clutter/clutter-layout-meta.h" | ||||
| #include "clutter/clutter-private.h" | ||||
|  | ||||
| G_DEFINE_TYPE (ClutterBinLayout, | ||||
|                clutter_bin_layout, | ||||
|                CLUTTER_TYPE_LAYOUT_MANAGER) | ||||
|  | ||||
| static void | ||||
| clutter_bin_layout_get_preferred_width (ClutterLayoutManager *manager, | ||||
|                                         ClutterActor         *container, | ||||
|                                         gfloat                for_height, | ||||
|                                         gfloat               *min_width_p, | ||||
|                                         gfloat               *nat_width_p) | ||||
| { | ||||
|   ClutterActor *actor = CLUTTER_ACTOR (container); | ||||
|   ClutterActorIter iter; | ||||
|   ClutterActor *child; | ||||
|   gfloat min_width, nat_width; | ||||
|  | ||||
|   min_width = nat_width = 0.0; | ||||
|  | ||||
|   clutter_actor_iter_init (&iter, actor); | ||||
|   while (clutter_actor_iter_next (&iter, &child)) | ||||
|     { | ||||
|       gfloat minimum, natural; | ||||
|  | ||||
|       if (!clutter_actor_is_visible (child)) | ||||
|         continue; | ||||
|  | ||||
|       clutter_actor_get_preferred_width (child, for_height, | ||||
|                                          &minimum, | ||||
|                                          &natural); | ||||
|  | ||||
|       min_width = MAX (min_width, minimum); | ||||
|       nat_width = MAX (nat_width, natural); | ||||
|     } | ||||
|  | ||||
|   if (min_width_p) | ||||
|     *min_width_p = min_width; | ||||
|  | ||||
|   if (nat_width_p) | ||||
|     *nat_width_p = nat_width; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_bin_layout_get_preferred_height (ClutterLayoutManager *manager, | ||||
|                                          ClutterActor         *container, | ||||
|                                          gfloat                for_width, | ||||
|                                          gfloat               *min_height_p, | ||||
|                                          gfloat               *nat_height_p) | ||||
| { | ||||
|   ClutterActor *actor = CLUTTER_ACTOR (container); | ||||
|   ClutterActorIter iter; | ||||
|   ClutterActor *child; | ||||
|   gfloat min_height, nat_height; | ||||
|  | ||||
|   min_height = nat_height = 0.0; | ||||
|  | ||||
|   clutter_actor_iter_init (&iter, actor); | ||||
|   while (clutter_actor_iter_next (&iter, &child)) | ||||
|     { | ||||
|       gfloat minimum, natural; | ||||
|  | ||||
|       if (!clutter_actor_is_visible (child)) | ||||
|         continue; | ||||
|  | ||||
|       clutter_actor_get_preferred_height (child, for_width, | ||||
|                                           &minimum, | ||||
|                                           &natural); | ||||
|  | ||||
|       min_height = MAX (min_height, minimum); | ||||
|       nat_height = MAX (nat_height, natural); | ||||
|     } | ||||
|  | ||||
|   if (min_height_p) | ||||
|     *min_height_p = min_height; | ||||
|  | ||||
|   if (nat_height_p) | ||||
|     *nat_height_p = nat_height; | ||||
| } | ||||
|  | ||||
| static gdouble | ||||
| get_actor_align_factor (ClutterActorAlign alignment) | ||||
| { | ||||
|   switch (alignment) | ||||
|     { | ||||
|     case CLUTTER_ACTOR_ALIGN_CENTER: | ||||
|       return 0.5; | ||||
|  | ||||
|     case CLUTTER_ACTOR_ALIGN_START: | ||||
|       return 0.0; | ||||
|  | ||||
|     case CLUTTER_ACTOR_ALIGN_END: | ||||
|       return 1.0; | ||||
|  | ||||
|     case CLUTTER_ACTOR_ALIGN_FILL: | ||||
|       return 0.0; | ||||
|     } | ||||
|  | ||||
|   return 0.0; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_bin_layout_allocate (ClutterLayoutManager   *manager, | ||||
|                              ClutterActor           *container, | ||||
|                              const ClutterActorBox  *allocation) | ||||
| { | ||||
|   gfloat allocation_x, allocation_y; | ||||
|   gfloat available_w, available_h; | ||||
|   ClutterActor *actor, *child; | ||||
|   ClutterActorIter iter; | ||||
|  | ||||
|   clutter_actor_box_get_origin (allocation, &allocation_x, &allocation_y); | ||||
|   clutter_actor_box_get_size (allocation, &available_w, &available_h); | ||||
|  | ||||
|   actor = CLUTTER_ACTOR (container); | ||||
|  | ||||
|   clutter_actor_iter_init (&iter, actor); | ||||
|   while (clutter_actor_iter_next (&iter, &child)) | ||||
|     { | ||||
|       ClutterActorBox child_alloc = { 0, }; | ||||
|       gdouble x_align, y_align; | ||||
|       gboolean x_fill, y_fill, is_fixed_position_set; | ||||
|       float fixed_x, fixed_y; | ||||
|  | ||||
|       if (!clutter_actor_is_visible (child)) | ||||
|         continue; | ||||
|  | ||||
|       fixed_x = fixed_y = 0.f; | ||||
|       g_object_get (child, | ||||
|                     "fixed-position-set", &is_fixed_position_set, | ||||
|                     "fixed-x", &fixed_x, | ||||
|                     "fixed-y", &fixed_y, | ||||
|                     NULL); | ||||
|  | ||||
|       if (is_fixed_position_set) | ||||
| 	{ | ||||
|           if (is_fixed_position_set) | ||||
|             child_alloc.x1 = fixed_x; | ||||
|           else | ||||
|             child_alloc.x1 = clutter_actor_get_x (child); | ||||
| 	} | ||||
|       else | ||||
|         child_alloc.x1 = allocation_x; | ||||
|  | ||||
|       if (is_fixed_position_set) | ||||
| 	{ | ||||
| 	  if (is_fixed_position_set) | ||||
|             child_alloc.y1 = fixed_y; | ||||
|           else | ||||
| 	    child_alloc.y1 = clutter_actor_get_y (child); | ||||
| 	} | ||||
|       else | ||||
|         child_alloc.y1 = allocation_y; | ||||
|  | ||||
|       child_alloc.x2 = allocation_x + available_w; | ||||
|       child_alloc.y2 = allocation_y + available_h; | ||||
|  | ||||
|       if (clutter_actor_needs_expand (child, CLUTTER_ORIENTATION_HORIZONTAL)) | ||||
|         { | ||||
|           ClutterActorAlign align; | ||||
|  | ||||
|           align = clutter_actor_get_x_align (child); | ||||
|           x_fill = align == CLUTTER_ACTOR_ALIGN_FILL; | ||||
|           x_align = get_actor_align_factor (align); | ||||
|         } | ||||
|       else | ||||
|         { | ||||
|           x_fill = FALSE; | ||||
|  | ||||
|           if (!is_fixed_position_set) | ||||
|             x_align = 0.5; | ||||
|           else | ||||
|             x_align = 0.0; | ||||
|         } | ||||
|  | ||||
|       if (clutter_actor_needs_expand (child, CLUTTER_ORIENTATION_VERTICAL)) | ||||
|         { | ||||
|           ClutterActorAlign align; | ||||
|  | ||||
|           align = clutter_actor_get_y_align (child); | ||||
|           y_fill = align == CLUTTER_ACTOR_ALIGN_FILL; | ||||
|           y_align = get_actor_align_factor (align); | ||||
|         } | ||||
|       else | ||||
|         { | ||||
|           y_fill = FALSE; | ||||
|  | ||||
|           if (!is_fixed_position_set) | ||||
|             y_align = 0.5; | ||||
|           else | ||||
|             y_align = 0.0; | ||||
|         } | ||||
|  | ||||
|       clutter_actor_allocate_align_fill (child, &child_alloc, | ||||
|                                          x_align, y_align, | ||||
|                                          x_fill, y_fill); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_bin_layout_class_init (ClutterBinLayoutClass *klass) | ||||
| { | ||||
|   ClutterLayoutManagerClass *layout_class = | ||||
|     CLUTTER_LAYOUT_MANAGER_CLASS (klass); | ||||
|  | ||||
|   layout_class->get_preferred_width = clutter_bin_layout_get_preferred_width; | ||||
|   layout_class->get_preferred_height = clutter_bin_layout_get_preferred_height; | ||||
|   layout_class->allocate = clutter_bin_layout_allocate; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_bin_layout_init (ClutterBinLayout *self) | ||||
| { | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_bin_layout_new: | ||||
|  * | ||||
|  * Creates a new #ClutterBinLayout layout manager | ||||
|  * | ||||
|  * Return value: the newly created layout manager | ||||
|  */ | ||||
| ClutterLayoutManager * | ||||
| clutter_bin_layout_new (void) | ||||
| { | ||||
|   return g_object_new (CLUTTER_TYPE_BIN_LAYOUT, | ||||
|                        NULL); | ||||
| } | ||||
| @@ -1,59 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * 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/>. | ||||
|  * | ||||
|  * Author: | ||||
|  *   Emmanuele Bassi <ebassi@linux.intel.com> | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <clutter/clutter.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include "clutter/clutter-layout-manager.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CLUTTER_TYPE_BIN_LAYOUT (clutter_bin_layout_get_type ()) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_DERIVABLE_TYPE (ClutterBinLayout, | ||||
|                           clutter_bin_layout, | ||||
|                           CLUTTER, | ||||
|                           BIN_LAYOUT, | ||||
|                           ClutterLayoutManager) | ||||
|  | ||||
| /** | ||||
|  * ClutterBinLayoutClass: | ||||
|  * | ||||
|  * The #ClutterBinLayoutClass structure contains only private | ||||
|  * data and should be accessed using the provided API | ||||
|  */ | ||||
| struct _ClutterBinLayoutClass | ||||
| { | ||||
|   /*< private >*/ | ||||
|   ClutterLayoutManagerClass parent_class; | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterLayoutManager *  clutter_bin_layout_new  (void); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,617 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2010  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> | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * ClutterBindConstraint: | ||||
|  * | ||||
|  * A constraint binding the position or size of an actor | ||||
|  * | ||||
|  * #ClutterBindConstraint is a [class@Constraint] that binds the | ||||
|  * position or the size of the [class@Actor] to which it is applied | ||||
|  * to the the position or the size of another [class@Actor], or | ||||
|  * "source". | ||||
|  * | ||||
|  * An offset can be applied to the constraint, to avoid overlapping. The offset | ||||
|  * can also be animated. For instance, the following code will set up three | ||||
|  * actors to be bound to the same origin: | ||||
|  * | ||||
|  * ```c | ||||
|  * // source | ||||
|  * rect[0] = clutter_actor_new (); | ||||
|  * clutter_actor_set_background_color (rect[0], &red_color); | ||||
|  * clutter_actor_set_position (rect[0], x_pos, y_pos); | ||||
|  * clutter_actor_set_size (rect[0], 100, 100); | ||||
|  * | ||||
|  * // second rectangle | ||||
|  * rect[1] = clutter_actor_new (); | ||||
|  * clutter_actor_set_background_color (rect[1], &green_color); | ||||
|  * clutter_actor_set_size (rect[1], 100, 100); | ||||
|  * clutter_actor_set_opacity (rect[1], 0); | ||||
|  * | ||||
|  * constraint = clutter_bind_constraint_new (rect[0], CLUTTER_BIND_X, 0.0); | ||||
|  * clutter_actor_add_constraint_with_name (rect[1], "green-x", constraint); | ||||
|  * constraint = clutter_bind_constraint_new (rect[0], CLUTTER_BIND_Y, 0.0); | ||||
|  * clutter_actor_add_constraint_with_name (rect[1], "green-y", constraint); | ||||
|  * | ||||
|  * // third rectangle | ||||
|  * rect[2] = clutter_actor_new (); | ||||
|  * clutter_actor_set_background_color (rect[2], &blue_color); | ||||
|  * clutter_actor_set_size (rect[2], 100, 100); | ||||
|  * clutter_actor_set_opacity (rect[2], 0); | ||||
|  * | ||||
|  * constraint = clutter_bind_constraint_new (rect[0], CLUTTER_BIND_X, 0.0); | ||||
|  * clutter_actor_add_constraint_with_name (rect[2], "blue-x", constraint); | ||||
|  * constraint = clutter_bind_constraint_new (rect[0], CLUTTER_BIND_Y, 0.0); | ||||
|  * clutter_actor_add_constraint_with_name (rect[2], "blue-y", constraint); | ||||
|  * ``` | ||||
|  * | ||||
|  * The following code animates the second and third rectangles to "expand" | ||||
|  * them horizontally from underneath the first rectangle: | ||||
|  * | ||||
|  * ```c | ||||
|  * clutter_actor_animate (rect[1], CLUTTER_EASE_OUT_CUBIC, 250, | ||||
|  *                        "@constraints.green-x.offset", 100.0, | ||||
|  *                        "opacity", 255, | ||||
|  *                        NULL); | ||||
|  * clutter_actor_animate (rect[2], CLUTTER_EASE_OUT_CUBIC, 250, | ||||
|  *                        "@constraints.blue-x.offset", 200.0, | ||||
|  *                        "opacity", 255, | ||||
|  *                        NULL); | ||||
|  * ``` | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include <math.h> | ||||
|  | ||||
| #include "clutter/clutter-bind-constraint.h" | ||||
|  | ||||
| #include "clutter/clutter-actor-meta-private.h" | ||||
| #include "clutter/clutter-actor-private.h" | ||||
| #include "clutter/clutter-constraint.h" | ||||
| #include "clutter/clutter-debug.h" | ||||
| #include "clutter/clutter-enum-types.h" | ||||
| #include "clutter/clutter-private.h" | ||||
|  | ||||
| struct _ClutterBindConstraint | ||||
| { | ||||
|   ClutterConstraint parent_instance; | ||||
|  | ||||
|   ClutterActor *actor; | ||||
|   ClutterActor *source; | ||||
|   ClutterBindCoordinate coordinate; | ||||
|   gfloat offset; | ||||
| }; | ||||
|  | ||||
| enum | ||||
| { | ||||
|   PROP_0, | ||||
|  | ||||
|   PROP_SOURCE, | ||||
|   PROP_COORDINATE, | ||||
|   PROP_OFFSET, | ||||
|  | ||||
|   PROP_LAST | ||||
| }; | ||||
|  | ||||
| static GParamSpec *obj_props[PROP_LAST]; | ||||
|  | ||||
| G_DEFINE_FINAL_TYPE (ClutterBindConstraint, | ||||
|                      clutter_bind_constraint, | ||||
|                      CLUTTER_TYPE_CONSTRAINT); | ||||
|  | ||||
| static void | ||||
| source_queue_relayout (ClutterActor          *source, | ||||
|                        ClutterBindConstraint *bind) | ||||
| { | ||||
|   if (bind->actor != NULL) | ||||
|     _clutter_actor_queue_only_relayout (bind->actor); | ||||
| } | ||||
|  | ||||
| static void | ||||
| source_destroyed (ClutterActor          *actor, | ||||
|                   ClutterBindConstraint *bind) | ||||
| { | ||||
|   bind->source = NULL; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_bind_constraint_update_preferred_size (ClutterConstraint  *constraint, | ||||
|                                                ClutterActor       *actor, | ||||
|                                                ClutterOrientation  direction, | ||||
|                                                float               for_size, | ||||
|                                                float              *minimum_size, | ||||
|                                                float              *natural_size) | ||||
| { | ||||
|   ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (constraint); | ||||
|   float source_min, source_nat; | ||||
|  | ||||
|   if (bind->source == NULL) | ||||
|     return; | ||||
|  | ||||
|   /* only these bindings affect the preferred size */ | ||||
|   if (!(bind->coordinate == CLUTTER_BIND_WIDTH || | ||||
|         bind->coordinate == CLUTTER_BIND_HEIGHT || | ||||
|         bind->coordinate == CLUTTER_BIND_SIZE || | ||||
|         bind->coordinate == CLUTTER_BIND_ALL)) | ||||
|     return; | ||||
|  | ||||
|   if (clutter_actor_contains (bind->source, actor)) | ||||
|     return; | ||||
|  | ||||
|   switch (direction) | ||||
|     { | ||||
|     case CLUTTER_ORIENTATION_HORIZONTAL: | ||||
|       if (bind->coordinate != CLUTTER_BIND_HEIGHT) | ||||
|         { | ||||
|           clutter_actor_get_preferred_width (bind->source, for_size, | ||||
|                                              &source_min, | ||||
|                                              &source_nat); | ||||
|  | ||||
|           *minimum_size = source_min; | ||||
|           *natural_size = source_nat; | ||||
|         } | ||||
|       break; | ||||
|  | ||||
|     case CLUTTER_ORIENTATION_VERTICAL: | ||||
|       if (bind->coordinate != CLUTTER_BIND_WIDTH) | ||||
|         { | ||||
|           clutter_actor_get_preferred_height (bind->source, for_size, | ||||
|                                               &source_min, | ||||
|                                               &source_nat); | ||||
|  | ||||
|           *minimum_size = source_min; | ||||
|           *natural_size = source_nat; | ||||
|         } | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_bind_constraint_update_allocation (ClutterConstraint *constraint, | ||||
|                                            ClutterActor      *actor, | ||||
|                                            ClutterActorBox   *allocation) | ||||
| { | ||||
|   ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (constraint); | ||||
|   gfloat source_width, source_height; | ||||
|   gfloat actor_width, actor_height; | ||||
|   graphene_point3d_t source_position; | ||||
|  | ||||
|   source_position = GRAPHENE_POINT3D_INIT (0.f, 0.f, 0.f); | ||||
|  | ||||
|   if (bind->source == NULL) | ||||
|     return; | ||||
|  | ||||
|   source_position.x = clutter_actor_get_x (bind->source); | ||||
|   source_position.y = clutter_actor_get_y (bind->source); | ||||
|   clutter_actor_get_size (bind->source, &source_width, &source_height); | ||||
|  | ||||
|   clutter_actor_box_get_size (allocation, &actor_width, &actor_height); | ||||
|  | ||||
|   switch (bind->coordinate) | ||||
|     { | ||||
|     case CLUTTER_BIND_X: | ||||
|       allocation->x1 = source_position.x + bind->offset; | ||||
|       allocation->x2 = allocation->x1 + actor_width; | ||||
|       break; | ||||
|  | ||||
|     case CLUTTER_BIND_Y: | ||||
|       allocation->y1 = source_position.y + bind->offset; | ||||
|       allocation->y2 = allocation->y1 + actor_height; | ||||
|       break; | ||||
|  | ||||
|     case CLUTTER_BIND_POSITION: | ||||
|       allocation->x1 = source_position.x + bind->offset; | ||||
|       allocation->y1 = source_position.y + bind->offset; | ||||
|       allocation->x2 = allocation->x1 + actor_width; | ||||
|       allocation->y2 = allocation->y1 + actor_height; | ||||
|       break; | ||||
|  | ||||
|     case CLUTTER_BIND_WIDTH: | ||||
|       allocation->x2 = allocation->x1 + source_width + bind->offset; | ||||
|       break; | ||||
|  | ||||
|     case CLUTTER_BIND_HEIGHT: | ||||
|       allocation->y2 = allocation->y1 + source_height + bind->offset; | ||||
|       break; | ||||
|  | ||||
|     case CLUTTER_BIND_SIZE: | ||||
|       allocation->x2 = allocation->x1 + source_width + bind->offset; | ||||
|       allocation->y2 = allocation->y1 + source_height + bind->offset; | ||||
|       break; | ||||
|  | ||||
|     case CLUTTER_BIND_ALL: | ||||
|       allocation->x1 = source_position.x + bind->offset; | ||||
|       allocation->y1 = source_position.y + bind->offset; | ||||
|       allocation->x2 = allocation->x1 + source_width + bind->offset; | ||||
|       allocation->y2 = allocation->y1 + source_height + bind->offset; | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       g_assert_not_reached (); | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|   clutter_actor_box_clamp_to_pixel (allocation); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_bind_constraint_set_actor (ClutterActorMeta *meta, | ||||
|                                    ClutterActor     *new_actor) | ||||
| { | ||||
|   ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (meta); | ||||
|   ClutterActorMetaClass *parent; | ||||
|  | ||||
|   if (new_actor != NULL && | ||||
|       bind->source != NULL && | ||||
|       clutter_actor_contains (new_actor, bind->source)) | ||||
|     { | ||||
|       g_warning (G_STRLOC ": The source actor '%s' is contained " | ||||
|                  "by the actor '%s' associated to the constraint " | ||||
|                  "'%s'", | ||||
|                  _clutter_actor_get_debug_name (bind->source), | ||||
|                  _clutter_actor_get_debug_name (new_actor), | ||||
|                  _clutter_actor_meta_get_debug_name (meta)); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   /* store the pointer to the actor, for later use */ | ||||
|   bind->actor = new_actor; | ||||
|  | ||||
|   parent = CLUTTER_ACTOR_META_CLASS (clutter_bind_constraint_parent_class); | ||||
|   parent->set_actor (meta, new_actor); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_bind_constraint_dispose (GObject *gobject) | ||||
| { | ||||
|   ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (gobject); | ||||
|  | ||||
|   if (bind->source != NULL) | ||||
|     { | ||||
|       g_signal_handlers_disconnect_by_func (bind->source, | ||||
|                                             G_CALLBACK (source_destroyed), | ||||
|                                             bind); | ||||
|       g_signal_handlers_disconnect_by_func (bind->source, | ||||
|                                             G_CALLBACK (source_queue_relayout), | ||||
|                                             bind); | ||||
|       bind->source = NULL; | ||||
|     } | ||||
|  | ||||
|   G_OBJECT_CLASS (clutter_bind_constraint_parent_class)->dispose (gobject); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_bind_constraint_set_property (GObject      *gobject, | ||||
|                                       guint         prop_id, | ||||
|                                       const GValue *value, | ||||
|                                       GParamSpec   *pspec) | ||||
| { | ||||
|   ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (gobject); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_SOURCE: | ||||
|       clutter_bind_constraint_set_source (bind, g_value_get_object (value)); | ||||
|       break; | ||||
|  | ||||
|     case PROP_COORDINATE: | ||||
|       clutter_bind_constraint_set_coordinate (bind, g_value_get_enum (value)); | ||||
|       break; | ||||
|  | ||||
|     case PROP_OFFSET: | ||||
|       clutter_bind_constraint_set_offset (bind, g_value_get_float (value)); | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_bind_constraint_get_property (GObject    *gobject, | ||||
|                                       guint       prop_id, | ||||
|                                       GValue     *value, | ||||
|                                       GParamSpec *pspec) | ||||
| { | ||||
|   ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (gobject); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_SOURCE: | ||||
|       g_value_set_object (value, bind->source); | ||||
|       break; | ||||
|  | ||||
|     case PROP_COORDINATE: | ||||
|       g_value_set_enum (value, bind->coordinate); | ||||
|       break; | ||||
|  | ||||
|     case PROP_OFFSET: | ||||
|       g_value_set_float (value, bind->offset); | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_bind_constraint_class_init (ClutterBindConstraintClass *klass) | ||||
| { | ||||
|   ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass); | ||||
|   ClutterConstraintClass *constraint_class = CLUTTER_CONSTRAINT_CLASS (klass); | ||||
|   GObjectClass *gobject_class = G_OBJECT_CLASS (klass); | ||||
|  | ||||
|   gobject_class->set_property = clutter_bind_constraint_set_property; | ||||
|   gobject_class->get_property = clutter_bind_constraint_get_property; | ||||
|   gobject_class->dispose = clutter_bind_constraint_dispose; | ||||
|  | ||||
|   meta_class->set_actor = clutter_bind_constraint_set_actor; | ||||
|  | ||||
|   constraint_class->update_allocation = clutter_bind_constraint_update_allocation; | ||||
|   constraint_class->update_preferred_size = clutter_bind_constraint_update_preferred_size; | ||||
|  | ||||
|   /** | ||||
|    * ClutterBindConstraint:source: | ||||
|    * | ||||
|    * The #ClutterActor used as the source for the binding. | ||||
|    * | ||||
|    * The #ClutterActor must not be contained inside the actor associated | ||||
|    * to the constraint. | ||||
|    */ | ||||
|   obj_props[PROP_SOURCE] = | ||||
|     g_param_spec_object ("source", NULL, NULL, | ||||
|                          CLUTTER_TYPE_ACTOR, | ||||
|                          G_PARAM_READWRITE | | ||||
|                          G_PARAM_STATIC_STRINGS | | ||||
|                          G_PARAM_CONSTRUCT); | ||||
|  | ||||
|   /** | ||||
|    * ClutterBindConstraint:coordinate: | ||||
|    * | ||||
|    * The coordinate to be bound | ||||
|    */ | ||||
|   obj_props[PROP_COORDINATE] = | ||||
|     g_param_spec_enum ("coordinate", NULL, NULL, | ||||
|                        CLUTTER_TYPE_BIND_COORDINATE, | ||||
|                        CLUTTER_BIND_X, | ||||
|                        G_PARAM_READWRITE | | ||||
|                        G_PARAM_STATIC_STRINGS | | ||||
|                        G_PARAM_CONSTRUCT); | ||||
|  | ||||
|   /** | ||||
|    * ClutterBindConstraint:offset: | ||||
|    * | ||||
|    * The offset, in pixels, to be applied to the binding | ||||
|    */ | ||||
|   obj_props[PROP_OFFSET] = | ||||
|     g_param_spec_float ("offset", NULL, NULL, | ||||
|                         -G_MAXFLOAT, G_MAXFLOAT, | ||||
|                         0.0f, | ||||
|                         G_PARAM_READWRITE | | ||||
|                         G_PARAM_STATIC_STRINGS | | ||||
|                         G_PARAM_CONSTRUCT); | ||||
|  | ||||
|   g_object_class_install_properties (gobject_class, | ||||
|                                      PROP_LAST, | ||||
|                                      obj_props); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_bind_constraint_init (ClutterBindConstraint *self) | ||||
| { | ||||
|   self->actor = NULL; | ||||
|   self->source = NULL; | ||||
|   self->coordinate = CLUTTER_BIND_X; | ||||
|   self->offset = 0.0f; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_bind_constraint_new: | ||||
|  * @source: (allow-none): the #ClutterActor to use as the source of | ||||
|  *   the binding, or %NULL | ||||
|  * @coordinate: the coordinate to bind | ||||
|  * @offset: the offset to apply to the binding, in pixels | ||||
|  * | ||||
|  * Creates a new constraint, binding a #ClutterActor's position to | ||||
|  * the given @coordinate of the position of @source | ||||
|  * | ||||
|  * Return value: the newly created #ClutterBindConstraint | ||||
|  */ | ||||
| ClutterConstraint * | ||||
| clutter_bind_constraint_new (ClutterActor          *source, | ||||
|                              ClutterBindCoordinate  coordinate, | ||||
|                              gfloat                 offset) | ||||
| { | ||||
|   g_return_val_if_fail (source == NULL || CLUTTER_IS_ACTOR (source), NULL); | ||||
|  | ||||
|   return g_object_new (CLUTTER_TYPE_BIND_CONSTRAINT, | ||||
|                        "source", source, | ||||
|                        "coordinate", coordinate, | ||||
|                        "offset", offset, | ||||
|                        NULL); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_bind_constraint_set_source: | ||||
|  * @constraint: a #ClutterBindConstraint | ||||
|  * @source: (allow-none): a #ClutterActor, or %NULL to unset the source | ||||
|  * | ||||
|  * Sets the source #ClutterActor for the constraint | ||||
|  */ | ||||
| void | ||||
| clutter_bind_constraint_set_source (ClutterBindConstraint *constraint, | ||||
|                                     ClutterActor          *source) | ||||
| { | ||||
|   ClutterActor *old_source, *actor; | ||||
|   ClutterActorMeta *meta; | ||||
|  | ||||
|   g_return_if_fail (CLUTTER_IS_BIND_CONSTRAINT (constraint)); | ||||
|   g_return_if_fail (source == NULL || CLUTTER_IS_ACTOR (source)); | ||||
|  | ||||
|   if (constraint->source == source) | ||||
|     return; | ||||
|  | ||||
|   meta = CLUTTER_ACTOR_META (constraint); | ||||
|   actor = clutter_actor_meta_get_actor (meta); | ||||
|   if (source != NULL && actor != NULL) | ||||
|     { | ||||
|       if (clutter_actor_contains (actor, source)) | ||||
|         { | ||||
|           g_warning (G_STRLOC ": The source actor '%s' is contained " | ||||
|                      "by the actor '%s' associated to the constraint " | ||||
|                      "'%s'", | ||||
|                      _clutter_actor_get_debug_name (source), | ||||
|                      _clutter_actor_get_debug_name (actor), | ||||
|                      _clutter_actor_meta_get_debug_name (meta)); | ||||
|           return; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   old_source = constraint->source; | ||||
|   if (old_source != NULL) | ||||
|     { | ||||
|       g_signal_handlers_disconnect_by_func (old_source, | ||||
|                                             G_CALLBACK (source_destroyed), | ||||
|                                             constraint); | ||||
|       g_signal_handlers_disconnect_by_func (old_source, | ||||
|                                             G_CALLBACK (source_queue_relayout), | ||||
|                                             constraint); | ||||
|     } | ||||
|  | ||||
|   constraint->source = source; | ||||
|   if (constraint->source != NULL) | ||||
|     { | ||||
|       g_signal_connect (constraint->source, "queue-relayout", | ||||
|                         G_CALLBACK (source_queue_relayout), | ||||
|                         constraint); | ||||
|       g_signal_connect (constraint->source, "destroy", | ||||
|                         G_CALLBACK (source_destroyed), | ||||
|                         constraint); | ||||
|  | ||||
|       if (constraint->actor != NULL) | ||||
|         clutter_actor_queue_relayout (constraint->actor); | ||||
|     } | ||||
|  | ||||
|   g_object_notify_by_pspec (G_OBJECT (constraint), obj_props[PROP_SOURCE]); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_bind_constraint_get_source: | ||||
|  * @constraint: a #ClutterBindConstraint | ||||
|  * | ||||
|  * Retrieves the #ClutterActor set using [method@Clutter.BindConstraint.set_source] | ||||
|  * | ||||
|  * Return value: (transfer none): a pointer to the source actor | ||||
|  */ | ||||
| ClutterActor * | ||||
| clutter_bind_constraint_get_source (ClutterBindConstraint *constraint) | ||||
| { | ||||
|   g_return_val_if_fail (CLUTTER_IS_BIND_CONSTRAINT (constraint), NULL); | ||||
|  | ||||
|   return constraint->source; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_bind_constraint_set_coordinate: | ||||
|  * @constraint: a #ClutterBindConstraint | ||||
|  * @coordinate: the coordinate to bind | ||||
|  * | ||||
|  * Sets the coordinate to bind in the constraint | ||||
|  */ | ||||
| void | ||||
| clutter_bind_constraint_set_coordinate (ClutterBindConstraint *constraint, | ||||
|                                         ClutterBindCoordinate  coordinate) | ||||
| { | ||||
|   g_return_if_fail (CLUTTER_IS_BIND_CONSTRAINT (constraint)); | ||||
|  | ||||
|   if (constraint->coordinate == coordinate) | ||||
|     return; | ||||
|  | ||||
|   constraint->coordinate = coordinate; | ||||
|  | ||||
|   if (constraint->actor != NULL) | ||||
|     clutter_actor_queue_relayout (constraint->actor); | ||||
|  | ||||
|   g_object_notify_by_pspec (G_OBJECT (constraint), obj_props[PROP_COORDINATE]); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_bind_constraint_get_coordinate: | ||||
|  * @constraint: a #ClutterBindConstraint | ||||
|  * | ||||
|  * Retrieves the bound coordinate of the constraint | ||||
|  * | ||||
|  * Return value: the bound coordinate | ||||
|  */ | ||||
| ClutterBindCoordinate | ||||
| clutter_bind_constraint_get_coordinate (ClutterBindConstraint *constraint) | ||||
| { | ||||
|   g_return_val_if_fail (CLUTTER_IS_BIND_CONSTRAINT (constraint), | ||||
|                         CLUTTER_BIND_X); | ||||
|  | ||||
|   return constraint->coordinate; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_bind_constraint_set_offset: | ||||
|  * @constraint: a #ClutterBindConstraint | ||||
|  * @offset: the offset to apply, in pixels | ||||
|  * | ||||
|  * Sets the offset to be applied to the constraint | ||||
|  */ | ||||
| void | ||||
| clutter_bind_constraint_set_offset (ClutterBindConstraint *constraint, | ||||
|                                     gfloat                 offset) | ||||
| { | ||||
|   g_return_if_fail (CLUTTER_IS_BIND_CONSTRAINT (constraint)); | ||||
|  | ||||
|   if (fabs (constraint->offset - offset) < 0.00001f) | ||||
|     return; | ||||
|  | ||||
|   constraint->offset = offset; | ||||
|  | ||||
|   if (constraint->actor != NULL) | ||||
|     clutter_actor_queue_relayout (constraint->actor); | ||||
|  | ||||
|   g_object_notify_by_pspec (G_OBJECT (constraint), obj_props[PROP_OFFSET]); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_bind_constraint_get_offset: | ||||
|  * @constraint: a #ClutterBindConstraint | ||||
|  * | ||||
|  * Retrieves the offset set using [method@Clutter.BindConstraint.set_offset] | ||||
|  * | ||||
|  * Return value: the offset, in pixels | ||||
|  */ | ||||
| gfloat | ||||
| clutter_bind_constraint_get_offset (ClutterBindConstraint *bind) | ||||
| { | ||||
|   g_return_val_if_fail (CLUTTER_IS_BIND_CONSTRAINT (bind), 0.0); | ||||
|  | ||||
|   return bind->offset; | ||||
| } | ||||
| @@ -1,62 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2010  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> | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <clutter/clutter.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include "clutter/clutter-constraint.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CLUTTER_TYPE_BIND_CONSTRAINT    (clutter_bind_constraint_get_type ()) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_FINAL_TYPE (ClutterBindConstraint, clutter_bind_constraint, | ||||
|                       CLUTTER, BIND_CONSTRAINT, ClutterConstraint) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterConstraint *   clutter_bind_constraint_new            (ClutterActor          *source, | ||||
|                                                               ClutterBindCoordinate  coordinate, | ||||
|                                                               gfloat                 offset); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void                  clutter_bind_constraint_set_source     (ClutterBindConstraint *constraint, | ||||
|                                                               ClutterActor          *source); | ||||
| CLUTTER_EXPORT | ||||
| ClutterActor *        clutter_bind_constraint_get_source     (ClutterBindConstraint *constraint); | ||||
| CLUTTER_EXPORT | ||||
| void                  clutter_bind_constraint_set_coordinate (ClutterBindConstraint *constraint, | ||||
|                                                               ClutterBindCoordinate  coordinate); | ||||
| CLUTTER_EXPORT | ||||
| ClutterBindCoordinate clutter_bind_constraint_get_coordinate (ClutterBindConstraint *constraint); | ||||
| CLUTTER_EXPORT | ||||
| void                  clutter_bind_constraint_set_offset     (ClutterBindConstraint *constraint, | ||||
|                                                               gfloat                 offset); | ||||
| CLUTTER_EXPORT | ||||
| gfloat                clutter_bind_constraint_get_offset     (ClutterBindConstraint *constraint); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,898 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2008  Intel Corporation. | ||||
|  * | ||||
|  * Authored By: Emmanuele Bassi <ebassi@linux.intel.com> | ||||
|  * | ||||
|  * 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/>. | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * ClutterBindingPool | ||||
|  * | ||||
|  * Pool for key bindings | ||||
|  * | ||||
|  * #ClutterBindingPool is a data structure holding a set of key bindings. | ||||
|  * Each key binding associates a key symbol (eventually with modifiers) | ||||
|  * to an action. A callback function is associated to each action. | ||||
|  * | ||||
|  * For a given key symbol and modifier mask combination there can be only one | ||||
|  * action; for each action there can be only one callback. There can be | ||||
|  * multiple actions with the same name, and the same callback can be used | ||||
|  * to handle multiple key bindings. | ||||
|  * | ||||
|  * Actors requiring key bindings should create a new #ClutterBindingPool | ||||
|  * inside their class initialization function and then install actions | ||||
|  * like this: | ||||
|  * | ||||
|  * ```c | ||||
|  * static void | ||||
|  * foo_class_init (FooClass *klass) | ||||
|  * { | ||||
|  *   ClutterBindingPool *binding_pool; | ||||
|  * | ||||
|  *   binding_pool = clutter_binding_pool_get_for_class (klass); | ||||
|  * | ||||
|  *   clutter_binding_pool_install_action (binding_pool, "move-up", | ||||
|  *                                        CLUTTER_Up, 0, | ||||
|  *                                        G_CALLBACK (foo_action_move_up), | ||||
|  *                                        NULL, NULL); | ||||
|  *   clutter_binding_pool_install_action (binding_pool, "move-up", | ||||
|  *                                        CLUTTER_KP_Up, 0, | ||||
|  *                                        G_CALLBACK (foo_action_move_up), | ||||
|  *                                        NULL, NULL); | ||||
|  * } | ||||
|  * ``` | ||||
|  * | ||||
|  * The callback has a signature of: | ||||
|  * | ||||
|  * ```c | ||||
|  *    gboolean (* callback) (GObject             *instance, | ||||
|  *                           const gchar         *action_name, | ||||
|  *                           guint                key_val, | ||||
|  *                           ClutterModifierType  modifiers, | ||||
|  *                           gpointer             user_data); | ||||
|  * ``` | ||||
|  * | ||||
|  * The actor should then override the [signal@Actor::key-press-event] and | ||||
|  * use [method@BindingPool.activate] to match a [struct@Event] key event | ||||
|  * structure to one of the actions: | ||||
|  * | ||||
|  * ```c | ||||
|  *   ClutterBindingPool *pool; | ||||
|  * | ||||
|  *   // retrieve the binding pool for the type of the actor | ||||
|  *   pool = clutter_binding_pool_find (G_OBJECT_TYPE_NAME (actor)); | ||||
|  * | ||||
|  *   // activate any callback matching the key symbol and modifiers | ||||
|  *   // mask of the key event. the returned value can be directly | ||||
|  *   // used to signal that the actor has handled the event. | ||||
|  *   return clutter_binding_pool_activate (pool, | ||||
|  *                                         key_event->keyval, | ||||
|  *                                         key_event->modifier_state, | ||||
|  *                                         G_OBJECT (actor)); | ||||
|  * ``` | ||||
|  * | ||||
|  * The [method@BindingPool.activate] function will return %FALSE if | ||||
|  * no action for the given key binding was found, if the action was | ||||
|  * blocked (using [method@BindingPool.block_action]) or if the | ||||
|  * key binding handler returned %FALSE. | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "clutter/clutter-binding-pool.h" | ||||
| #include "clutter/clutter-debug.h" | ||||
| #include "clutter/clutter-enum-types.h" | ||||
| #include "clutter/clutter-marshal.h" | ||||
| #include "clutter/clutter-private.h" | ||||
|  | ||||
| #define BINDING_MOD_MASK        ((CLUTTER_SHIFT_MASK | \ | ||||
|                                   CLUTTER_CONTROL_MASK | \ | ||||
|                                   CLUTTER_MOD1_MASK | \ | ||||
|                                   CLUTTER_SUPER_MASK | \ | ||||
|                                   CLUTTER_HYPER_MASK | \ | ||||
|                                   CLUTTER_META_MASK) | CLUTTER_RELEASE_MASK) | ||||
|  | ||||
| typedef struct _ClutterBindingEntry     ClutterBindingEntry; | ||||
|  | ||||
| static GSList *clutter_binding_pools = NULL; | ||||
| static GQuark  key_class_bindings = 0; | ||||
|  | ||||
| struct _ClutterBindingPool | ||||
| { | ||||
|   GObject parent_instance; | ||||
|  | ||||
|   gchar *name; /* interned string, do not free */ | ||||
|  | ||||
|   GSList *entries; | ||||
|   GHashTable *entries_hash; | ||||
| }; | ||||
|  | ||||
| struct _ClutterBindingEntry | ||||
| { | ||||
|   gchar *name; /* interned string, do not free */ | ||||
|  | ||||
|   guint key_val; | ||||
|   ClutterModifierType modifiers; | ||||
|  | ||||
|   GClosure *closure; | ||||
|  | ||||
|   guint is_blocked  : 1; | ||||
| }; | ||||
|  | ||||
| enum | ||||
| { | ||||
|   PROP_0, | ||||
|  | ||||
|   PROP_NAME, | ||||
|  | ||||
|   PROP_LAST | ||||
| }; | ||||
|  | ||||
| static GParamSpec *obj_props[PROP_LAST]; | ||||
|  | ||||
| G_DEFINE_FINAL_TYPE (ClutterBindingPool, clutter_binding_pool, G_TYPE_OBJECT); | ||||
|  | ||||
| static guint | ||||
| binding_entry_hash (gconstpointer v) | ||||
| { | ||||
|   const ClutterBindingEntry *e = v; | ||||
|   guint h; | ||||
|  | ||||
|   h = e->key_val; | ||||
|   h ^= e->modifiers; | ||||
|  | ||||
|   return h; | ||||
| } | ||||
|  | ||||
| static gint | ||||
| binding_entry_compare (gconstpointer v1, | ||||
|                        gconstpointer v2) | ||||
| { | ||||
|   const ClutterBindingEntry *e1 = v1; | ||||
|   const ClutterBindingEntry *e2 = v2; | ||||
|  | ||||
|   return (e1->key_val == e2->key_val && e1->modifiers == e2->modifiers); | ||||
| } | ||||
|  | ||||
| static ClutterBindingEntry * | ||||
| binding_entry_new (const gchar         *name, | ||||
|                    guint                key_val, | ||||
|                    ClutterModifierType  modifiers) | ||||
| { | ||||
|   ClutterBindingEntry *entry; | ||||
|  | ||||
|   modifiers = modifiers & BINDING_MOD_MASK; | ||||
|  | ||||
|   entry = g_new0 (ClutterBindingEntry, 1); | ||||
|   entry->key_val = key_val; | ||||
|   entry->modifiers = modifiers; | ||||
|   entry->name = (gchar *) g_intern_string (name); | ||||
|   entry->closure = NULL; | ||||
|   entry->is_blocked = FALSE; | ||||
|  | ||||
|   return entry; | ||||
| } | ||||
|  | ||||
| static ClutterBindingEntry * | ||||
| binding_pool_lookup_entry (ClutterBindingPool  *pool, | ||||
|                            guint                key_val, | ||||
|                            ClutterModifierType  modifiers) | ||||
| { | ||||
|   ClutterBindingEntry lookup_entry = { 0, }; | ||||
|  | ||||
|   lookup_entry.key_val = key_val; | ||||
|   lookup_entry.modifiers = modifiers; | ||||
|  | ||||
|   return g_hash_table_lookup (pool->entries_hash, &lookup_entry); | ||||
| } | ||||
|  | ||||
| static void | ||||
| binding_entry_free (gpointer data) | ||||
| { | ||||
|   if (G_LIKELY (data)) | ||||
|     { | ||||
|       ClutterBindingEntry *entry = data; | ||||
|  | ||||
|       g_closure_unref (entry->closure); | ||||
|  | ||||
|       g_free (entry); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_binding_pool_finalize (GObject *gobject) | ||||
| { | ||||
|   ClutterBindingPool *pool = CLUTTER_BINDING_POOL (gobject); | ||||
|  | ||||
|   /* remove from the pools */ | ||||
|   clutter_binding_pools = g_slist_remove (clutter_binding_pools, pool); | ||||
|  | ||||
|   g_hash_table_destroy (pool->entries_hash); | ||||
|  | ||||
|   g_slist_free_full (pool->entries, (GDestroyNotify) binding_entry_free); | ||||
|  | ||||
|   G_OBJECT_CLASS (clutter_binding_pool_parent_class)->finalize (gobject); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_binding_pool_set_property (GObject      *gobject, | ||||
|                                    guint         prop_id, | ||||
|                                    const GValue *value, | ||||
|                                    GParamSpec   *pspec) | ||||
| { | ||||
|   ClutterBindingPool *pool = CLUTTER_BINDING_POOL (gobject); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_NAME: | ||||
|       pool->name = (gchar *) g_intern_string (g_value_get_string (value)); | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_binding_pool_get_property (GObject    *gobject, | ||||
|                                    guint       prop_id, | ||||
|                                    GValue     *value, | ||||
|                                    GParamSpec *pspec) | ||||
| { | ||||
|   ClutterBindingPool *pool = CLUTTER_BINDING_POOL (gobject); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_NAME: | ||||
|       g_value_set_string (value, pool->name); | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_binding_pool_constructed (GObject *gobject) | ||||
| { | ||||
|   ClutterBindingPool *pool = CLUTTER_BINDING_POOL (gobject); | ||||
|  | ||||
|   /* bad monkey! bad, bad monkey! */ | ||||
|   if (G_UNLIKELY (pool->name == NULL)) | ||||
|     g_critical ("No name set for ClutterBindingPool %p", pool); | ||||
|  | ||||
|   if (G_OBJECT_CLASS (clutter_binding_pool_parent_class)->constructed) | ||||
|     G_OBJECT_CLASS (clutter_binding_pool_parent_class)->constructed (gobject); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_binding_pool_class_init (ClutterBindingPoolClass *klass) | ||||
| { | ||||
|   GObjectClass *gobject_class = G_OBJECT_CLASS (klass); | ||||
|  | ||||
|   gobject_class->constructed = clutter_binding_pool_constructed; | ||||
|   gobject_class->set_property = clutter_binding_pool_set_property; | ||||
|   gobject_class->get_property = clutter_binding_pool_get_property; | ||||
|   gobject_class->finalize = clutter_binding_pool_finalize; | ||||
|  | ||||
|   /** | ||||
|    * ClutterBindingPool:name: | ||||
|    * | ||||
|    * The unique name of the #ClutterBindingPool. | ||||
|    */ | ||||
|   obj_props[PROP_NAME] = | ||||
|     g_param_spec_string ("name", NULL, NULL, | ||||
|                          NULL, | ||||
|                          G_PARAM_READWRITE | | ||||
|                          G_PARAM_STATIC_STRINGS | | ||||
|                          G_PARAM_CONSTRUCT_ONLY); | ||||
|  | ||||
|   g_object_class_install_properties (gobject_class, | ||||
|                                      PROP_LAST, | ||||
|                                      obj_props); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_binding_pool_init (ClutterBindingPool *pool) | ||||
| { | ||||
|   pool->name = NULL; | ||||
|   pool->entries = NULL; | ||||
|   pool->entries_hash = g_hash_table_new (binding_entry_hash, | ||||
|                                          binding_entry_compare); | ||||
|  | ||||
|   clutter_binding_pools = g_slist_prepend (clutter_binding_pools, pool); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_binding_pool_new: | ||||
|  * @name: the name of the binding pool | ||||
|  * | ||||
|  * Creates a new #ClutterBindingPool that can be used to store | ||||
|  * key bindings for an actor. The @name must be a unique identifier | ||||
|  * for the binding pool, so that [func@Clutter.BindingPool.find] will | ||||
|  * be able to return the correct binding pool. | ||||
|  * | ||||
|  * Return value: the newly created binding pool with the given | ||||
|  *   name. Use g_object_unref() when done. | ||||
|  */ | ||||
| ClutterBindingPool * | ||||
| clutter_binding_pool_new (const gchar *name) | ||||
| { | ||||
|   ClutterBindingPool *pool; | ||||
|  | ||||
|   g_return_val_if_fail (name != NULL, NULL); | ||||
|  | ||||
|   pool = clutter_binding_pool_find (name); | ||||
|   if (G_UNLIKELY (pool)) | ||||
|     { | ||||
|       g_warning ("A binding pool named '%s' is already present " | ||||
|                  "in the binding pools list", | ||||
|                  pool->name); | ||||
|       return NULL; | ||||
|     } | ||||
|  | ||||
|   return g_object_new (CLUTTER_TYPE_BINDING_POOL, "name", name, NULL); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_binding_pool_get_for_class: | ||||
|  * @klass: a #GObjectClass pointer | ||||
|  * | ||||
|  * Retrieves the #ClutterBindingPool for the given #GObject class | ||||
|  * and, eventually, creates it. This function is a wrapper around | ||||
|  * [ctor@Clutter.BindingPool.new] and uses the class type name as the | ||||
|  * unique name for the binding pool. | ||||
|  * | ||||
|  * Calling this function multiple times will return the same | ||||
|  * #ClutterBindingPool. | ||||
|  * | ||||
|  * A binding pool for a class can also be retrieved using | ||||
|  * [func@Clutter.BindingPool.find] with the class type name: | ||||
|  * | ||||
|  * ``` | ||||
|  *   pool = clutter_binding_pool_find (G_OBJECT_TYPE_NAME (instance)); | ||||
|  * ``` | ||||
|  * | ||||
|  * Return value: (transfer none): the binding pool for the given class. | ||||
|  *   The returned #ClutterBindingPool is owned by Clutter and should not | ||||
|  *   be freed directly | ||||
|  */ | ||||
| ClutterBindingPool * | ||||
| clutter_binding_pool_get_for_class (gpointer klass) | ||||
| { | ||||
|   ClutterBindingPool *pool; | ||||
|  | ||||
|   g_return_val_if_fail (G_IS_OBJECT_CLASS (klass), NULL); | ||||
|  | ||||
|   if (G_UNLIKELY (key_class_bindings == 0)) | ||||
|     key_class_bindings = g_quark_from_static_string ("clutter-bindings-set"); | ||||
|  | ||||
|   pool = g_dataset_id_get_data (klass, key_class_bindings); | ||||
|   if (pool) | ||||
|     return pool; | ||||
|  | ||||
|   pool = clutter_binding_pool_new (G_OBJECT_CLASS_NAME (klass)); | ||||
|   g_dataset_id_set_data_full (klass, key_class_bindings, | ||||
|                               pool, | ||||
|                               g_object_unref); | ||||
|  | ||||
|   return pool; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_binding_pool_find: | ||||
|  * @name: the name of the binding pool to find | ||||
|  * | ||||
|  * Finds the #ClutterBindingPool with @name. | ||||
|  * | ||||
|  * Return value: (transfer none): a pointer to the #ClutterBindingPool, or %NULL | ||||
|  */ | ||||
| ClutterBindingPool * | ||||
| clutter_binding_pool_find (const gchar *name) | ||||
| { | ||||
|   GSList *l; | ||||
|  | ||||
|   g_return_val_if_fail (name != NULL, NULL); | ||||
|  | ||||
|   for (l = clutter_binding_pools; l != NULL; l = l->next) | ||||
|     { | ||||
|       ClutterBindingPool *pool = l->data; | ||||
|  | ||||
|       if (g_str_equal (pool->name, (gpointer) name)) | ||||
|         return pool; | ||||
|     } | ||||
|  | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_binding_pool_install_action: | ||||
|  * @pool: a #ClutterBindingPool | ||||
|  * @action_name: the name of the action | ||||
|  * @key_val: key symbol | ||||
|  * @modifiers: bitmask of modifiers | ||||
|  * @callback: function to be called | ||||
|  *   when the action is activated | ||||
|  * @data: data to be passed to @callback | ||||
|  * @notify: function to be called when the action is removed | ||||
|  *   from the pool | ||||
|  * | ||||
|  * Installs a new action inside a #ClutterBindingPool. The action | ||||
|  * is bound to @key_val and @modifiers. | ||||
|  * | ||||
|  * The same action name can be used for multiple @key_val, @modifiers | ||||
|  * pairs. | ||||
|  * | ||||
|  * When an action has been activated using [method@Clutter.BindingPool.activate] | ||||
|  * the passed @callback will be invoked (with @data). | ||||
|  * | ||||
|  * Actions can be blocked with [method@Clutter.BindingPool.block_action] | ||||
|  * and then unblocked using [method@Clutter.BindingPool.unblock_action]. | ||||
|  */ | ||||
| void | ||||
| clutter_binding_pool_install_action (ClutterBindingPool  *pool, | ||||
|                                      const gchar         *action_name, | ||||
|                                      guint                key_val, | ||||
|                                      ClutterModifierType  modifiers, | ||||
|                                      GCallback            callback, | ||||
|                                      gpointer             data, | ||||
|                                      GDestroyNotify       notify) | ||||
| { | ||||
|   ClutterBindingEntry *entry; | ||||
|   GClosure *closure; | ||||
|  | ||||
|   g_return_if_fail (pool != NULL); | ||||
|   g_return_if_fail (action_name != NULL); | ||||
|   g_return_if_fail (key_val != 0); | ||||
|   g_return_if_fail (callback != NULL); | ||||
|  | ||||
|   entry = binding_pool_lookup_entry (pool, key_val, modifiers); | ||||
|   if (G_UNLIKELY (entry)) | ||||
|     { | ||||
|       g_warning ("There already is an action '%s' for the given " | ||||
|                  "key symbol of %d (modifiers: %d) installed inside " | ||||
|                  "the binding pool.", | ||||
|                  entry->name, | ||||
|                  entry->key_val, entry->modifiers); | ||||
|       return; | ||||
|     } | ||||
|   else | ||||
|     entry = binding_entry_new (action_name, key_val, modifiers); | ||||
|  | ||||
|   closure = g_cclosure_new (callback, data, (GClosureNotify) notify); | ||||
|   entry->closure = g_closure_ref (closure); | ||||
|   g_closure_sink (closure); | ||||
|  | ||||
|   if (G_CLOSURE_NEEDS_MARSHAL (closure)) | ||||
|     { | ||||
|       GClosureMarshal marshal; | ||||
|  | ||||
|       marshal = _clutter_marshal_BOOLEAN__STRING_UINT_FLAGS; | ||||
|       g_closure_set_marshal (closure, marshal); | ||||
|     } | ||||
|  | ||||
|   pool->entries = g_slist_prepend (pool->entries, entry); | ||||
|   g_hash_table_insert (pool->entries_hash, entry, entry); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_binding_pool_install_closure: | ||||
|  * @pool: a #ClutterBindingPool | ||||
|  * @action_name: the name of the action | ||||
|  * @key_val: key symbol | ||||
|  * @modifiers: bitmask of modifiers | ||||
|  * @closure: a #GClosure | ||||
|  * | ||||
|  * A #GClosure variant of [method@Clutter.BindingPool.install_action]. | ||||
|  * | ||||
|  * Installs a new action inside a #ClutterBindingPool. The action | ||||
|  * is bound to @key_val and @modifiers. | ||||
|  * | ||||
|  * The same action name can be used for multiple @key_val, @modifiers | ||||
|  * pairs. | ||||
|  * | ||||
|  * When an action has been activated using [method@Clutter.BindingPool.activate] | ||||
|  * the passed @closure will be invoked. | ||||
|  * | ||||
|  * Actions can be blocked with [method@Clutter.BindingPool.block_action] | ||||
|  * and then unblocked using [method@Clutter.BindingPool.unblock_action]. | ||||
|  */ | ||||
| void | ||||
| clutter_binding_pool_install_closure (ClutterBindingPool  *pool, | ||||
|                                       const gchar         *action_name, | ||||
|                                       guint                key_val, | ||||
|                                       ClutterModifierType  modifiers, | ||||
|                                       GClosure            *closure) | ||||
| { | ||||
|   ClutterBindingEntry *entry; | ||||
|  | ||||
|   g_return_if_fail (pool != NULL); | ||||
|   g_return_if_fail (action_name != NULL); | ||||
|   g_return_if_fail (key_val != 0); | ||||
|   g_return_if_fail (closure != NULL); | ||||
|  | ||||
|   entry = binding_pool_lookup_entry (pool, key_val, modifiers); | ||||
|   if (G_UNLIKELY (entry)) | ||||
|     { | ||||
|       g_warning ("There already is an action '%s' for the given " | ||||
|                  "key symbol of %d (modifiers: %d) installed inside " | ||||
|                  "the binding pool.", | ||||
|                  entry->name, | ||||
|                  entry->key_val, entry->modifiers); | ||||
|       return; | ||||
|     } | ||||
|   else | ||||
|     entry = binding_entry_new (action_name, key_val, modifiers); | ||||
|  | ||||
|   entry->closure = g_closure_ref (closure); | ||||
|   g_closure_sink (closure); | ||||
|  | ||||
|   if (G_CLOSURE_NEEDS_MARSHAL (closure)) | ||||
|     { | ||||
|       GClosureMarshal marshal; | ||||
|  | ||||
|       marshal = _clutter_marshal_BOOLEAN__STRING_UINT_FLAGS; | ||||
|       g_closure_set_marshal (closure, marshal); | ||||
|     } | ||||
|  | ||||
|   pool->entries = g_slist_prepend (pool->entries, entry); | ||||
|   g_hash_table_insert (pool->entries_hash, entry, entry); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_binding_pool_override_action: | ||||
|  * @pool: a #ClutterBindingPool | ||||
|  * @key_val: key symbol | ||||
|  * @modifiers: bitmask of modifiers | ||||
|  * @callback: function to be called when the action is activated | ||||
|  * @data: data to be passed to @callback | ||||
|  * @notify: function to be called when the action is removed | ||||
|  *   from the pool | ||||
|  * | ||||
|  * Allows overriding the action for @key_val and @modifiers inside a | ||||
|  * #ClutterBindingPool. See [method@Clutter.BindingPool.install_action]. | ||||
|  * | ||||
|  * When an action has been activated using [method@Clutter.BindingPool.activate] | ||||
|  * the passed @callback will be invoked (with @data). | ||||
|  * | ||||
|  * Actions can be blocked with [method@Clutter.BindingPool.block_action] | ||||
|  * and then unblocked using [method@Clutter.BindingPool.unblock_action]. | ||||
|  */ | ||||
| void | ||||
| clutter_binding_pool_override_action (ClutterBindingPool  *pool, | ||||
|                                       guint                key_val, | ||||
|                                       ClutterModifierType  modifiers, | ||||
|                                       GCallback            callback, | ||||
|                                       gpointer             data, | ||||
|                                       GDestroyNotify       notify) | ||||
| { | ||||
|   ClutterBindingEntry *entry; | ||||
|   GClosure *closure; | ||||
|  | ||||
|   g_return_if_fail (pool != NULL); | ||||
|   g_return_if_fail (key_val != 0); | ||||
|   g_return_if_fail (callback != NULL); | ||||
|  | ||||
|   entry = binding_pool_lookup_entry (pool, key_val, modifiers); | ||||
|   if (G_UNLIKELY (entry == NULL)) | ||||
|     { | ||||
|       g_warning ("There is no action for the given key symbol " | ||||
|                  "of %d (modifiers: %d) installed inside the " | ||||
|                  "binding pool.", | ||||
|                  key_val, modifiers); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   if (entry->closure) | ||||
|     { | ||||
|       g_closure_unref (entry->closure); | ||||
|       entry->closure = NULL; | ||||
|     } | ||||
|  | ||||
|   closure = g_cclosure_new (callback, data, (GClosureNotify) notify); | ||||
|   entry->closure = g_closure_ref (closure); | ||||
|   g_closure_sink (closure); | ||||
|  | ||||
|   if (G_CLOSURE_NEEDS_MARSHAL (closure)) | ||||
|     { | ||||
|       GClosureMarshal marshal; | ||||
|  | ||||
|       marshal = _clutter_marshal_BOOLEAN__STRING_UINT_FLAGS; | ||||
|       g_closure_set_marshal (closure, marshal); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_binding_pool_override_closure: | ||||
|  * @pool: a #ClutterBindingPool | ||||
|  * @key_val: key symbol | ||||
|  * @modifiers: bitmask of modifiers | ||||
|  * @closure: a #GClosure | ||||
|  * | ||||
|  * A #GClosure variant of [method@Clutter.BindingPool.override_action]. | ||||
|  * | ||||
|  * Allows overriding the action for @key_val and @modifiers inside a | ||||
|  * #ClutterBindingPool. See [method@Clutter.BindingPool.install_closure]. | ||||
|  * | ||||
|  * When an action has been activated using [method@Clutter.BindingPool.activate] | ||||
|  * the passed @callback will be invoked (with @data). | ||||
|  * | ||||
|  * Actions can be blocked with [method@Clutter.BindingPool.block_action] | ||||
|  * and then unblocked using [method@Clutter.BindingPool.unblock_action]. | ||||
|  */ | ||||
| void | ||||
| clutter_binding_pool_override_closure (ClutterBindingPool  *pool, | ||||
|                                        guint                key_val, | ||||
|                                        ClutterModifierType  modifiers, | ||||
|                                        GClosure            *closure) | ||||
| { | ||||
|   ClutterBindingEntry *entry; | ||||
|  | ||||
|   g_return_if_fail (pool != NULL); | ||||
|   g_return_if_fail (key_val != 0); | ||||
|   g_return_if_fail (closure != NULL); | ||||
|  | ||||
|   entry = binding_pool_lookup_entry (pool, key_val, modifiers); | ||||
|   if (G_UNLIKELY (entry == NULL)) | ||||
|     { | ||||
|       g_warning ("There is no action for the given key symbol " | ||||
|                  "of %d (modifiers: %d) installed inside the " | ||||
|                  "binding pool.", | ||||
|                  key_val, modifiers); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   if (entry->closure) | ||||
|     { | ||||
|       g_closure_unref (entry->closure); | ||||
|       entry->closure = NULL; | ||||
|     } | ||||
|  | ||||
|   entry->closure = g_closure_ref (closure); | ||||
|   g_closure_sink (closure); | ||||
|  | ||||
|   if (G_CLOSURE_NEEDS_MARSHAL (closure)) | ||||
|     { | ||||
|       GClosureMarshal marshal; | ||||
|  | ||||
|       marshal = _clutter_marshal_BOOLEAN__STRING_UINT_FLAGS; | ||||
|       g_closure_set_marshal (closure, marshal); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_binding_pool_find_action: | ||||
|  * @pool: a #ClutterBindingPool | ||||
|  * @key_val: a key symbol | ||||
|  * @modifiers: a bitmask for the modifiers | ||||
|  * | ||||
|  * Retrieves the name of the action matching the given key symbol | ||||
|  * and modifiers bitmask. | ||||
|  * | ||||
|  * Return value: the name of the action, if found, or %NULL. The | ||||
|  *   returned string is owned by the binding pool and should never | ||||
|  *   be modified or freed | ||||
|  */ | ||||
| const gchar * | ||||
| clutter_binding_pool_find_action (ClutterBindingPool  *pool, | ||||
|                                   guint                key_val, | ||||
|                                   ClutterModifierType  modifiers) | ||||
| { | ||||
|   ClutterBindingEntry *entry; | ||||
|  | ||||
|   g_return_val_if_fail (pool != NULL, NULL); | ||||
|   g_return_val_if_fail (key_val != 0, NULL); | ||||
|  | ||||
|   entry = binding_pool_lookup_entry (pool, key_val, modifiers); | ||||
|   if (!entry) | ||||
|     return NULL; | ||||
|  | ||||
|   return entry->name; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_binding_pool_remove_action: | ||||
|  * @pool: a #ClutterBindingPool | ||||
|  * @key_val: a key symbol | ||||
|  * @modifiers: a bitmask for the modifiers | ||||
|  * | ||||
|  * Removes the action matching the given @key_val, @modifiers pair, | ||||
|  * if any exists. | ||||
|  */ | ||||
| void | ||||
| clutter_binding_pool_remove_action (ClutterBindingPool  *pool, | ||||
|                                     guint                key_val, | ||||
|                                     ClutterModifierType  modifiers) | ||||
| { | ||||
|   ClutterBindingEntry remove_entry = { 0, }; | ||||
|   GSList *l; | ||||
|  | ||||
|   g_return_if_fail (pool != NULL); | ||||
|   g_return_if_fail (key_val != 0); | ||||
|  | ||||
|   modifiers = modifiers & BINDING_MOD_MASK; | ||||
|  | ||||
|   remove_entry.key_val = key_val; | ||||
|   remove_entry.modifiers = modifiers; | ||||
|  | ||||
|   for (l = pool->entries; l != NULL; l = l->data) | ||||
|     { | ||||
|       ClutterBindingEntry *e = l->data; | ||||
|  | ||||
|       if (e->key_val == remove_entry.key_val && | ||||
|           e->modifiers == remove_entry.modifiers) | ||||
|         { | ||||
|           pool->entries = g_slist_remove_link (pool->entries, l); | ||||
|           break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   g_hash_table_remove (pool->entries_hash, &remove_entry); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| clutter_binding_entry_invoke (ClutterBindingEntry *entry, | ||||
|                               GObject             *gobject) | ||||
| { | ||||
|   GValue params[4] = { | ||||
|     G_VALUE_INIT, | ||||
|     G_VALUE_INIT, | ||||
|     G_VALUE_INIT, | ||||
|     G_VALUE_INIT | ||||
|   }; | ||||
|   GValue result = G_VALUE_INIT; | ||||
|   gboolean retval = TRUE; | ||||
|  | ||||
|   g_value_init (¶ms[0], G_TYPE_OBJECT); | ||||
|   g_value_set_object (¶ms[0], gobject); | ||||
|  | ||||
|   g_value_init (¶ms[1], G_TYPE_STRING); | ||||
|   g_value_set_static_string (¶ms[1], entry->name); | ||||
|  | ||||
|   g_value_init (¶ms[2], G_TYPE_UINT); | ||||
|   g_value_set_uint (¶ms[2], entry->key_val); | ||||
|  | ||||
|   g_value_init (¶ms[3], CLUTTER_TYPE_MODIFIER_TYPE); | ||||
|   g_value_set_flags (¶ms[3], entry->modifiers); | ||||
|  | ||||
|   g_value_init (&result, G_TYPE_BOOLEAN); | ||||
|  | ||||
|   g_closure_invoke (entry->closure, &result, 4, params, NULL); | ||||
|  | ||||
|   retval = g_value_get_boolean (&result); | ||||
|  | ||||
|   g_value_unset (&result); | ||||
|  | ||||
|   g_value_unset (¶ms[0]); | ||||
|   g_value_unset (¶ms[1]); | ||||
|   g_value_unset (¶ms[2]); | ||||
|   g_value_unset (¶ms[3]); | ||||
|  | ||||
|   return retval; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_binding_pool_activate: | ||||
|  * @pool: a #ClutterBindingPool | ||||
|  * @key_val: the key symbol | ||||
|  * @modifiers: bitmask for the modifiers | ||||
|  * @gobject: a #GObject | ||||
|  * | ||||
|  * Activates the callback associated to the action that is | ||||
|  * bound to the @key_val and @modifiers pair. | ||||
|  * | ||||
|  * The callback has the following signature: | ||||
|  * | ||||
|  * ``` | ||||
|  *   void (* callback) (GObject             *gobject, | ||||
|  *                      const gchar         *action_name, | ||||
|  *                      guint                key_val, | ||||
|  *                      ClutterModifierType  modifiers, | ||||
|  *                      gpointer             user_data); | ||||
|  * ``` | ||||
|  * | ||||
|  * Where the #GObject instance is @gobject and the user data | ||||
|  * is the one passed when installing the action with | ||||
|  * [method@Clutter.BindingPool.install_action]. | ||||
|  * | ||||
|  * If the action bound to the @key_val, @modifiers pair has been | ||||
|  * blocked using [method@Clutter.BindingPool.block_action], the callback | ||||
|  * will not be invoked, and this function will return %FALSE. | ||||
|  * | ||||
|  * Return value: %TRUE if an action was found and was activated | ||||
|  */ | ||||
| gboolean | ||||
| clutter_binding_pool_activate (ClutterBindingPool  *pool, | ||||
|                                guint                key_val, | ||||
|                                ClutterModifierType  modifiers, | ||||
|                                GObject             *gobject) | ||||
| { | ||||
|   ClutterBindingEntry *entry = NULL; | ||||
|  | ||||
|   g_return_val_if_fail (pool != NULL, FALSE); | ||||
|   g_return_val_if_fail (key_val != 0, FALSE); | ||||
|   g_return_val_if_fail (G_IS_OBJECT (gobject), FALSE); | ||||
|  | ||||
|   modifiers = (modifiers & BINDING_MOD_MASK); | ||||
|  | ||||
|   entry = binding_pool_lookup_entry (pool, key_val, modifiers); | ||||
|   if (!entry) | ||||
|     return FALSE; | ||||
|  | ||||
|   if (!entry->is_blocked) | ||||
|     return clutter_binding_entry_invoke (entry, gobject); | ||||
|  | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_binding_pool_block_action: | ||||
|  * @pool: a #ClutterBindingPool | ||||
|  * @action_name: an action name | ||||
|  * | ||||
|  * Blocks all the actions with name @action_name inside @pool. | ||||
|  */ | ||||
| void | ||||
| clutter_binding_pool_block_action (ClutterBindingPool *pool, | ||||
|                                    const gchar        *action_name) | ||||
| { | ||||
|   GSList *l; | ||||
|  | ||||
|   g_return_if_fail (pool != NULL); | ||||
|   g_return_if_fail (action_name != NULL); | ||||
|  | ||||
|   for (l = pool->entries; l != NULL; l = l->next) | ||||
|     { | ||||
|       ClutterBindingEntry *entry = l->data; | ||||
|  | ||||
|       if (g_str_equal (entry->name, (gpointer) action_name)) | ||||
|         entry->is_blocked = TRUE; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_binding_pool_unblock_action: | ||||
|  * @pool: a #ClutterBindingPool | ||||
|  * @action_name: an action name | ||||
|  * | ||||
|  * Unblockes all the actions with name @action_name inside @pool. | ||||
|  * | ||||
|  * Unblocking an action does not cause the callback bound to it to | ||||
|  * be invoked in case [method@Clutter.BindingPool.activate] was called on | ||||
|  * an action previously blocked with [method@Clutter.BindingPool.block_action]. | ||||
|  */ | ||||
| void | ||||
| clutter_binding_pool_unblock_action (ClutterBindingPool *pool, | ||||
|                                      const gchar        *action_name) | ||||
| { | ||||
|   GSList *l; | ||||
|  | ||||
|   g_return_if_fail (pool != NULL); | ||||
|   g_return_if_fail (action_name != NULL); | ||||
|  | ||||
|   for (l = pool->entries; l != NULL; l = l->next) | ||||
|     { | ||||
|       ClutterBindingEntry *entry = l->data; | ||||
|  | ||||
|       if (g_str_equal (entry->name, (gpointer) action_name)) | ||||
|         entry->is_blocked = FALSE; | ||||
|     } | ||||
| } | ||||
| @@ -1,101 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2008  Intel Corporation. | ||||
|  * | ||||
|  * Authored By: Emmanuele Bassi <ebassi@linux.intel.com> | ||||
|  * | ||||
|  * 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/>. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <clutter/clutter.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include <glib-object.h> | ||||
|  | ||||
| #include "clutter/clutter-event.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CLUTTER_TYPE_BINDING_POOL       (clutter_binding_pool_get_type ()) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_FINAL_TYPE (ClutterBindingPool, | ||||
|                       clutter_binding_pool, | ||||
|                       CLUTTER, | ||||
|                       BINDING_POOL, | ||||
|                       GObject) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterBindingPool *  clutter_binding_pool_new              (const gchar         *name); | ||||
| CLUTTER_EXPORT | ||||
| ClutterBindingPool *  clutter_binding_pool_get_for_class    (gpointer             klass); | ||||
| CLUTTER_EXPORT | ||||
| ClutterBindingPool *  clutter_binding_pool_find             (const gchar         *name); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void                  clutter_binding_pool_install_action   (ClutterBindingPool  *pool, | ||||
|                                                              const gchar         *action_name, | ||||
|                                                              guint                key_val, | ||||
|                                                              ClutterModifierType  modifiers, | ||||
|                                                              GCallback            callback, | ||||
|                                                              gpointer             data, | ||||
|                                                              GDestroyNotify       notify); | ||||
| CLUTTER_EXPORT | ||||
| void                  clutter_binding_pool_install_closure  (ClutterBindingPool  *pool, | ||||
|                                                              const gchar         *action_name, | ||||
|                                                              guint                key_val, | ||||
|                                                              ClutterModifierType  modifiers, | ||||
|                                                              GClosure            *closure); | ||||
| CLUTTER_EXPORT | ||||
| void                  clutter_binding_pool_override_action  (ClutterBindingPool  *pool, | ||||
|                                                              guint                key_val, | ||||
|                                                              ClutterModifierType  modifiers, | ||||
|                                                              GCallback            callback, | ||||
|                                                              gpointer             data, | ||||
|                                                              GDestroyNotify       notify); | ||||
| CLUTTER_EXPORT | ||||
| void                  clutter_binding_pool_override_closure (ClutterBindingPool  *pool, | ||||
|                                                              guint                key_val, | ||||
|                                                              ClutterModifierType  modifiers, | ||||
|                                                              GClosure            *closure); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| const gchar *         clutter_binding_pool_find_action      (ClutterBindingPool  *pool, | ||||
|                                                              guint                key_val, | ||||
|                                                              ClutterModifierType  modifiers); | ||||
| CLUTTER_EXPORT | ||||
| void                  clutter_binding_pool_remove_action    (ClutterBindingPool  *pool, | ||||
|                                                              guint                key_val, | ||||
|                                                              ClutterModifierType  modifiers); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| gboolean              clutter_binding_pool_activate         (ClutterBindingPool  *pool, | ||||
|                                                              guint                key_val, | ||||
|                                                              ClutterModifierType  modifiers, | ||||
|                                                              GObject             *gobject); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void                  clutter_binding_pool_block_action     (ClutterBindingPool  *pool, | ||||
|                                                              const gchar         *action_name); | ||||
| CLUTTER_EXPORT | ||||
| void                  clutter_binding_pool_unblock_action   (ClutterBindingPool  *pool, | ||||
|                                                              const gchar         *action_name); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,203 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2010  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> | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * ClutterBlurEffect: | ||||
|  * | ||||
|  * A blur effect | ||||
|  * | ||||
|  * #ClutterBlurEffect is a sub-class of #ClutterEffect that allows blurring a | ||||
|  * actor and its contents. | ||||
|  */ | ||||
| #include "config.h" | ||||
|  | ||||
| #include "clutter/clutter-blur-effect.h" | ||||
|  | ||||
| #include "cogl/cogl.h" | ||||
|  | ||||
| #include "clutter/clutter-debug.h" | ||||
| #include "clutter/clutter-private.h" | ||||
|  | ||||
| #define BLUR_PADDING    2 | ||||
|  | ||||
| /* FIXME - lame shader; we should really have a decoupled | ||||
|  * horizontal/vertical two pass shader for the gaussian blur | ||||
|  */ | ||||
| static const gchar *box_blur_glsl_declarations = | ||||
| "uniform vec2 pixel_step;\n"; | ||||
| #define SAMPLE(offx, offy) \ | ||||
|   "cogl_texel += texture2D (cogl_sampler, cogl_tex_coord.st + pixel_step * " \ | ||||
|   "vec2 (" G_STRINGIFY (offx) ", " G_STRINGIFY (offy) "));\n" | ||||
| static const gchar *box_blur_glsl_shader = | ||||
| "  cogl_texel = texture2D (cogl_sampler, cogl_tex_coord.st);\n" | ||||
|   SAMPLE (-1.0, -1.0) | ||||
|   SAMPLE ( 0.0, -1.0) | ||||
|   SAMPLE (+1.0, -1.0) | ||||
|   SAMPLE (-1.0,  0.0) | ||||
|   SAMPLE (+1.0,  0.0) | ||||
|   SAMPLE (-1.0, +1.0) | ||||
|   SAMPLE ( 0.0, +1.0) | ||||
|   SAMPLE (+1.0, +1.0) | ||||
| "  cogl_texel /= 9.0;\n"; | ||||
| #undef SAMPLE | ||||
|  | ||||
| typedef struct _ClutterBlurEffectPrivate | ||||
| { | ||||
|   /* a back pointer to our actor, so that we can query it */ | ||||
|   ClutterActor *actor; | ||||
|  | ||||
|   gint pixel_step_uniform; | ||||
|  | ||||
|   CoglPipeline *pipeline; | ||||
| } ClutterBlurEffectPrivate; | ||||
|  | ||||
|  | ||||
| G_DEFINE_TYPE_WITH_PRIVATE (ClutterBlurEffect, | ||||
|                             clutter_blur_effect, | ||||
|                             CLUTTER_TYPE_OFFSCREEN_EFFECT); | ||||
|  | ||||
| static CoglPipeline * | ||||
| clutter_blur_effect_create_pipeline (ClutterOffscreenEffect *effect, | ||||
|                                      CoglTexture            *texture) | ||||
| { | ||||
|   ClutterBlurEffect *blur_effect = CLUTTER_BLUR_EFFECT (effect); | ||||
|   ClutterBlurEffectPrivate *priv = | ||||
|     clutter_blur_effect_get_instance_private (blur_effect); | ||||
|  | ||||
|   if (priv->pixel_step_uniform > -1) | ||||
|     { | ||||
|       float pixel_step[2]; | ||||
|       int tex_width, tex_height; | ||||
|  | ||||
|       tex_width = cogl_texture_get_width (texture); | ||||
|       tex_height = cogl_texture_get_height (texture); | ||||
|  | ||||
|       pixel_step[0] = 1.0f / tex_width; | ||||
|       pixel_step[1] = 1.0f / tex_height; | ||||
|  | ||||
|       cogl_pipeline_set_uniform_float (priv->pipeline, | ||||
|                                        priv->pixel_step_uniform, | ||||
|                                        2, /* n_components */ | ||||
|                                        1, /* count */ | ||||
|                                        pixel_step); | ||||
|     } | ||||
|  | ||||
|   cogl_pipeline_set_layer_texture (priv->pipeline, 0, texture); | ||||
|  | ||||
|   return g_object_ref (priv->pipeline); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| clutter_blur_effect_modify_paint_volume (ClutterEffect      *effect, | ||||
|                                          ClutterPaintVolume *volume) | ||||
| { | ||||
|   gfloat cur_width, cur_height; | ||||
|   graphene_point3d_t origin; | ||||
|  | ||||
|   clutter_paint_volume_get_origin (volume, &origin); | ||||
|   cur_width = clutter_paint_volume_get_width (volume); | ||||
|   cur_height = clutter_paint_volume_get_height (volume); | ||||
|  | ||||
|   origin.x -= BLUR_PADDING; | ||||
|   origin.y -= BLUR_PADDING; | ||||
|   cur_width += 2 * BLUR_PADDING; | ||||
|   cur_height += 2 * BLUR_PADDING; | ||||
|   clutter_paint_volume_set_origin (volume, &origin); | ||||
|   clutter_paint_volume_set_width (volume, cur_width); | ||||
|   clutter_paint_volume_set_height (volume, cur_height); | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_blur_effect_dispose (GObject *gobject) | ||||
| { | ||||
|   ClutterBlurEffect *self = CLUTTER_BLUR_EFFECT (gobject); | ||||
|   ClutterBlurEffectPrivate *priv = | ||||
|     clutter_blur_effect_get_instance_private (self); | ||||
|  | ||||
|   g_clear_object (&priv->pipeline); | ||||
|  | ||||
|   G_OBJECT_CLASS (clutter_blur_effect_parent_class)->dispose (gobject); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_blur_effect_class_init (ClutterBlurEffectClass *klass) | ||||
| { | ||||
|   ClutterEffectClass *effect_class = CLUTTER_EFFECT_CLASS (klass); | ||||
|   GObjectClass *gobject_class = G_OBJECT_CLASS (klass); | ||||
|   ClutterOffscreenEffectClass *offscreen_class; | ||||
|  | ||||
|   gobject_class->dispose = clutter_blur_effect_dispose; | ||||
|  | ||||
|   effect_class->modify_paint_volume = clutter_blur_effect_modify_paint_volume; | ||||
|  | ||||
|   offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass); | ||||
|   offscreen_class->create_pipeline = clutter_blur_effect_create_pipeline; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_blur_effect_init (ClutterBlurEffect *self) | ||||
| { | ||||
|   ClutterBlurEffectClass *klass = CLUTTER_BLUR_EFFECT_GET_CLASS (self); | ||||
|   ClutterBlurEffectPrivate *priv = | ||||
|     clutter_blur_effect_get_instance_private (self); | ||||
|  | ||||
|   if (G_UNLIKELY (klass->base_pipeline == NULL)) | ||||
|     { | ||||
|       CoglSnippet *snippet; | ||||
|       CoglContext *ctx = | ||||
|         clutter_backend_get_cogl_context (clutter_get_default_backend ()); | ||||
|  | ||||
|       klass->base_pipeline = cogl_pipeline_new (ctx); | ||||
|  | ||||
|       snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP, | ||||
|                                   box_blur_glsl_declarations, | ||||
|                                   NULL); | ||||
|       cogl_snippet_set_replace (snippet, box_blur_glsl_shader); | ||||
|       cogl_pipeline_add_layer_snippet (klass->base_pipeline, 0, snippet); | ||||
|       g_object_unref (snippet); | ||||
|  | ||||
|       cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0); | ||||
|     } | ||||
|  | ||||
|   priv->pipeline = cogl_pipeline_copy (klass->base_pipeline); | ||||
|  | ||||
|   priv->pixel_step_uniform = | ||||
|     cogl_pipeline_get_uniform_location (priv->pipeline, "pixel_step"); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_blur_effect_new: | ||||
|  * | ||||
|  * Creates a new #ClutterBlurEffect to be used with | ||||
|  * [method@Clutter.Actor.add_effect] | ||||
|  * | ||||
|  * Return value: the newly created #ClutterBlurEffect or %NULL | ||||
|  */ | ||||
| ClutterEffect * | ||||
| clutter_blur_effect_new (void) | ||||
| { | ||||
|   return g_object_new (CLUTTER_TYPE_BLUR_EFFECT, NULL); | ||||
| } | ||||
| @@ -1,54 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2010  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> | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <clutter/clutter.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include "clutter/clutter-effect.h" | ||||
| #include "clutter/clutter-offscreen-effect.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CLUTTER_TYPE_BLUR_EFFECT        (clutter_blur_effect_get_type ()) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_DERIVABLE_TYPE (ClutterBlurEffect, | ||||
|                           clutter_blur_effect, | ||||
|                           CLUTTER, BLUR_EFFECT, | ||||
|                           ClutterOffscreenEffect) | ||||
|  | ||||
| struct _ClutterBlurEffectClass | ||||
| { | ||||
|   ClutterOffscreenEffectClass parent_class; | ||||
|  | ||||
|   CoglPipeline *base_pipeline; | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterEffect *clutter_blur_effect_new (void); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,37 +0,0 @@ | ||||
| /* | ||||
|  * Copyright (C) 2020 Endless OS Foundation, LLC | ||||
|  * | ||||
|  * 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/>. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <glib-object.h> | ||||
|  | ||||
| #include "cogl/cogl.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| typedef struct _ClutterBlur ClutterBlur; | ||||
|  | ||||
| ClutterBlur * clutter_blur_new (CoglTexture *texture, | ||||
|                                 float        radius); | ||||
|  | ||||
| void clutter_blur_apply (ClutterBlur *blur); | ||||
|  | ||||
| CoglTexture * clutter_blur_get_texture (ClutterBlur *blur); | ||||
|  | ||||
| void clutter_blur_free (ClutterBlur *blur); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,436 +0,0 @@ | ||||
| /* | ||||
|  * Copyright (C) 2020 Endless OS Foundation, LLC | ||||
|  * | ||||
|  * 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 "config.h" | ||||
|  | ||||
| #include "clutter/clutter-blur-private.h" | ||||
|  | ||||
| #include "clutter/clutter-backend.h" | ||||
|  | ||||
| /** | ||||
|  * ClutterBlur: | ||||
|  * | ||||
|  * Blur textures | ||||
|  * | ||||
|  * #ClutterBlur is a moderately fast gaussian blur implementation. | ||||
|  * | ||||
|  * # Optimizations | ||||
|  * | ||||
|  * There are a number of optimizations in place to make this blur implementation | ||||
|  * real-time. All in all, the implementation performs best when using large | ||||
|  * blur-radii that allow downscaling the texture to smaller sizes, at small | ||||
|  * radii where no downscaling is possible this can easily halve the framerate. | ||||
|  * | ||||
|  * ## Multipass | ||||
|  * | ||||
|  * It is implemented in 2 passes: vertical and horizontal. | ||||
|  * | ||||
|  * ## Downscaling | ||||
|  * | ||||
|  * #ClutterBlur uses dynamic downscaling to speed up blurring. Downscaling | ||||
|  * happens in factors of 2 (the image is downscaled either by 2, 4, 8, 16, …) | ||||
|  * and depends on the blur radius, the texture size, among others. | ||||
|  * | ||||
|  * The texture is drawn into a downscaled framebuffer; the blur passes are | ||||
|  * applied on the downscaled texture contents; and finally, the blurred | ||||
|  * contents are drawn | ||||
|  * upscaled again. | ||||
|  * | ||||
|  * ## Hardware Interpolation | ||||
|  * | ||||
|  * This blur implementation cuts down the number of sampling operations by | ||||
|  * exploiting the hardware interpolation that is performed when sampling between | ||||
|  * pixel boundaries. This technique is described at: | ||||
|  * | ||||
|  * http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/ | ||||
|  * | ||||
|  * ## Incremental gauss-factor calculation | ||||
|  * | ||||
|  * The kernel values for the gaussian kernel are computed incrementally instead | ||||
|  * of running the expensive calculations multiple times inside the blur shader. | ||||
|  * The implementation is based on the algorithm presented by K. Turkowski in | ||||
|  * GPU Gems 3, chapter 40: | ||||
|  * | ||||
|  * https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch40.html | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| static const char *gaussian_blur_glsl_declarations = | ||||
| "uniform float sigma;                                                      \n" | ||||
| "uniform float pixel_step;                                                 \n" | ||||
| "uniform vec2 direction;                                                   \n"; | ||||
|  | ||||
| static const char *gaussian_blur_glsl = | ||||
| "  vec2 uv = vec2 (cogl_tex_coord.st);                                     \n" | ||||
| "                                                                          \n" | ||||
| "  vec3 gauss_coefficient;                                                 \n" | ||||
| "  gauss_coefficient.x = 1.0 / (sqrt (2.0 * 3.14159265) * sigma);          \n" | ||||
| "  gauss_coefficient.y = exp (-0.5 / (sigma * sigma));                     \n" | ||||
| "  gauss_coefficient.z = gauss_coefficient.y * gauss_coefficient.y;        \n" | ||||
| "                                                                          \n" | ||||
| "  float gauss_coefficient_total = gauss_coefficient.x;                    \n" | ||||
| "                                                                          \n" | ||||
| "  vec4 ret = texture2D (cogl_sampler, uv) * gauss_coefficient.x;          \n" | ||||
| "  gauss_coefficient.xy *= gauss_coefficient.yz;                           \n" | ||||
| "                                                                          \n" | ||||
| "  int n_steps = int (ceil (1.5 * sigma)) * 2;                             \n" | ||||
| "                                                                          \n" | ||||
| "  for (int i = 1; i <= n_steps; i += 2) {                                 \n" | ||||
| "    float coefficient_subtotal = gauss_coefficient.x;                     \n" | ||||
| "    gauss_coefficient.xy *= gauss_coefficient.yz;                         \n" | ||||
| "    coefficient_subtotal += gauss_coefficient.x;                          \n" | ||||
| "                                                                          \n" | ||||
| "    float gauss_ratio = gauss_coefficient.x / coefficient_subtotal;       \n" | ||||
| "                                                                          \n" | ||||
| "    float foffset = float (i) + gauss_ratio;                              \n" | ||||
| "    vec2 offset = direction * foffset * pixel_step;                       \n" | ||||
| "                                                                          \n" | ||||
| "    ret += texture2D (cogl_sampler, uv + offset) * coefficient_subtotal;  \n" | ||||
| "    ret += texture2D (cogl_sampler, uv - offset) * coefficient_subtotal;  \n" | ||||
| "                                                                          \n" | ||||
| "    gauss_coefficient_total += 2.0 * coefficient_subtotal;                \n" | ||||
| "    gauss_coefficient.xy *= gauss_coefficient.yz;                         \n" | ||||
| "  }                                                                       \n" | ||||
| "                                                                          \n" | ||||
| "  cogl_texel = ret / gauss_coefficient_total;                             \n"; | ||||
|  | ||||
| #define MIN_DOWNSCALE_SIZE 256.f | ||||
| #define MAX_SIGMA 6.f | ||||
|  | ||||
| enum | ||||
| { | ||||
|   VERTICAL, | ||||
|   HORIZONTAL, | ||||
| }; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|   CoglFramebuffer *framebuffer; | ||||
|   CoglPipeline *pipeline; | ||||
|   CoglTexture *texture; | ||||
|   int orientation; | ||||
| } BlurPass; | ||||
|  | ||||
| struct _ClutterBlur | ||||
| { | ||||
|   CoglTexture *source_texture; | ||||
|   float sigma; | ||||
|   float downscale_factor; | ||||
|  | ||||
|   BlurPass pass[2]; | ||||
| }; | ||||
|  | ||||
| static CoglPipeline* | ||||
| create_blur_pipeline (void) | ||||
| { | ||||
|   static CoglPipelineKey blur_pipeline_key = "clutter-blur-pipeline-private"; | ||||
|   CoglContext *ctx = | ||||
|     clutter_backend_get_cogl_context (clutter_get_default_backend ()); | ||||
|   CoglPipeline *blur_pipeline; | ||||
|  | ||||
|   blur_pipeline = | ||||
|     cogl_context_get_named_pipeline (ctx, &blur_pipeline_key); | ||||
|  | ||||
|   if (G_UNLIKELY (blur_pipeline == NULL)) | ||||
|     { | ||||
|       CoglSnippet *snippet; | ||||
|  | ||||
|       blur_pipeline = cogl_pipeline_new (ctx); | ||||
|       cogl_pipeline_set_layer_null_texture (blur_pipeline, 0); | ||||
|       cogl_pipeline_set_layer_filters (blur_pipeline, | ||||
|                                        0, | ||||
|                                        COGL_PIPELINE_FILTER_LINEAR, | ||||
|                                        COGL_PIPELINE_FILTER_LINEAR); | ||||
|       cogl_pipeline_set_layer_wrap_mode (blur_pipeline, | ||||
|                                          0, | ||||
|                                          COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE); | ||||
|  | ||||
|       snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP, | ||||
|                                   gaussian_blur_glsl_declarations, | ||||
|                                   NULL); | ||||
|       cogl_snippet_set_replace (snippet, gaussian_blur_glsl); | ||||
|       cogl_pipeline_add_layer_snippet (blur_pipeline, 0, snippet); | ||||
|       g_object_unref (snippet); | ||||
|  | ||||
|       cogl_context_set_named_pipeline (ctx, &blur_pipeline_key, blur_pipeline); | ||||
|     } | ||||
|  | ||||
|   return cogl_pipeline_copy (blur_pipeline); | ||||
| } | ||||
|  | ||||
| static void | ||||
| update_blur_uniforms (ClutterBlur *blur, | ||||
|                       BlurPass    *pass) | ||||
| { | ||||
|   gboolean vertical = pass->orientation == VERTICAL; | ||||
|   int sigma_uniform; | ||||
|   int pixel_step_uniform; | ||||
|   int direction_uniform; | ||||
|  | ||||
|   pixel_step_uniform = | ||||
|     cogl_pipeline_get_uniform_location (pass->pipeline, "pixel_step"); | ||||
|   if (pixel_step_uniform > -1) | ||||
|     { | ||||
|       float pixel_step; | ||||
|  | ||||
|       if (vertical) | ||||
|         pixel_step = 1.f / cogl_texture_get_height (pass->texture); | ||||
|       else | ||||
|         pixel_step = 1.f / cogl_texture_get_width (pass->texture); | ||||
|  | ||||
|       cogl_pipeline_set_uniform_1f (pass->pipeline, | ||||
|                                     pixel_step_uniform, | ||||
|                                     pixel_step); | ||||
|     } | ||||
|  | ||||
|   sigma_uniform = cogl_pipeline_get_uniform_location (pass->pipeline, "sigma"); | ||||
|   if (sigma_uniform > -1) | ||||
|     { | ||||
|       cogl_pipeline_set_uniform_1f (pass->pipeline, | ||||
|                                     sigma_uniform, | ||||
|                                     blur->sigma / blur->downscale_factor); | ||||
|     } | ||||
|  | ||||
|   direction_uniform = | ||||
|     cogl_pipeline_get_uniform_location (pass->pipeline, "direction"); | ||||
|   if (direction_uniform > -1) | ||||
|     { | ||||
|       gboolean horizontal = !vertical; | ||||
|       float direction[2] = { | ||||
|         horizontal, | ||||
|         vertical, | ||||
|       }; | ||||
|  | ||||
|       cogl_pipeline_set_uniform_float (pass->pipeline, | ||||
|                                        direction_uniform, | ||||
|                                        2, 1, | ||||
|                                        direction); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| create_fbo (ClutterBlur *blur, | ||||
|             BlurPass    *pass) | ||||
| { | ||||
|   CoglContext *ctx = | ||||
|     clutter_backend_get_cogl_context (clutter_get_default_backend ()); | ||||
|   float scaled_height; | ||||
|   float scaled_width; | ||||
|   float height; | ||||
|   float width; | ||||
|  | ||||
|   g_clear_object (&pass->texture); | ||||
|   g_clear_object (&pass->framebuffer); | ||||
|  | ||||
|   width = cogl_texture_get_width (blur->source_texture); | ||||
|   height = cogl_texture_get_height (blur->source_texture); | ||||
|   scaled_width = floorf (width / blur->downscale_factor); | ||||
|   scaled_height = floorf (height / blur->downscale_factor); | ||||
|  | ||||
|   pass->texture = cogl_texture_2d_new_with_size (ctx, | ||||
|                                                  scaled_width, | ||||
|                                                  scaled_height); | ||||
|   if (!pass->texture) | ||||
|     return FALSE; | ||||
|  | ||||
|   pass->framebuffer = | ||||
|     COGL_FRAMEBUFFER (cogl_offscreen_new_with_texture (pass->texture)); | ||||
|   if (!pass->framebuffer) | ||||
|     { | ||||
|       g_warning ("%s: Unable to create an Offscreen buffer", G_STRLOC); | ||||
|       return FALSE; | ||||
|     } | ||||
|  | ||||
|   cogl_framebuffer_orthographic (pass->framebuffer, | ||||
|                                  0.0, 0.0, | ||||
|                                  scaled_width, | ||||
|                                  scaled_height, | ||||
|                                  0.0, 1.0); | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| setup_blur_pass (ClutterBlur *blur, | ||||
|                  BlurPass    *pass, | ||||
|                  int          orientation, | ||||
|                  CoglTexture *texture) | ||||
| { | ||||
|   pass->orientation = orientation; | ||||
|   pass->pipeline = create_blur_pipeline (); | ||||
|   cogl_pipeline_set_layer_texture (pass->pipeline, 0, texture); | ||||
|  | ||||
|   if (!create_fbo (blur, pass)) | ||||
|     return FALSE; | ||||
|  | ||||
|   update_blur_uniforms (blur, pass); | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static float | ||||
| calculate_downscale_factor (float width, | ||||
|                             float height, | ||||
|                             float sigma) | ||||
| { | ||||
|   float downscale_factor = 1.f; | ||||
|   float scaled_width = width; | ||||
|   float scaled_height = height; | ||||
|   float scaled_sigma = sigma; | ||||
|  | ||||
|   /* This is the algorithm used by Firefox; keep downscaling until either the | ||||
|    * blur radius is lower than the threshold, or the downscaled texture is too | ||||
|    * small. | ||||
|    */ | ||||
|   while (scaled_sigma > MAX_SIGMA && | ||||
|          scaled_width > MIN_DOWNSCALE_SIZE && | ||||
|          scaled_height > MIN_DOWNSCALE_SIZE) | ||||
|     { | ||||
|       downscale_factor *= 2.f; | ||||
|  | ||||
|       scaled_width = width / downscale_factor; | ||||
|       scaled_height = height / downscale_factor; | ||||
|       scaled_sigma = sigma / downscale_factor; | ||||
|     } | ||||
|  | ||||
|   return downscale_factor; | ||||
| } | ||||
|  | ||||
| static void | ||||
| apply_blur_pass (BlurPass *pass) | ||||
| { | ||||
|   CoglColor transparent; | ||||
|  | ||||
|   cogl_color_init_from_4f (&transparent, 0.0, 0.0, 0.0, 0.0); | ||||
|  | ||||
|   cogl_framebuffer_clear (pass->framebuffer, | ||||
|                           COGL_BUFFER_BIT_COLOR, | ||||
|                           &transparent); | ||||
|  | ||||
|   cogl_framebuffer_draw_rectangle (pass->framebuffer, | ||||
|                                    pass->pipeline, | ||||
|                                    0, 0, | ||||
|                                    cogl_texture_get_width (pass->texture), | ||||
|                                    cogl_texture_get_height (pass->texture)); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clear_blur_pass (BlurPass *pass) | ||||
| { | ||||
|   g_clear_object (&pass->pipeline); | ||||
|   g_clear_object (&pass->texture); | ||||
|   g_clear_object (&pass->framebuffer); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_blur_new: | ||||
|  * @texture: a #CoglTexture | ||||
|  * @sigma: blur sigma | ||||
|  * | ||||
|  * Creates a new #ClutterBlur. | ||||
|  * | ||||
|  * Returns: (transfer full) (nullable): A newly created #ClutterBlur | ||||
|  */ | ||||
| ClutterBlur * | ||||
| clutter_blur_new (CoglTexture *texture, | ||||
|                   float        radius) | ||||
| { | ||||
|   ClutterBlur *blur; | ||||
|   unsigned int height; | ||||
|   unsigned int width; | ||||
|   BlurPass *hpass; | ||||
|   BlurPass *vpass; | ||||
|  | ||||
|   g_return_val_if_fail (texture != NULL, NULL); | ||||
|   g_return_val_if_fail (radius >= 0.0, NULL); | ||||
|  | ||||
|   width = cogl_texture_get_width (texture); | ||||
|   height = cogl_texture_get_height (texture); | ||||
|  | ||||
|   blur = g_new0 (ClutterBlur, 1); | ||||
|   blur->sigma = radius / 2.0; | ||||
|   blur->source_texture = g_object_ref (texture); | ||||
|   blur->downscale_factor = calculate_downscale_factor (width, | ||||
|                                                        height, | ||||
|                                                        blur->sigma); | ||||
|  | ||||
|   if (G_APPROX_VALUE (blur->sigma, 0.0, FLT_EPSILON)) | ||||
|     goto out; | ||||
|  | ||||
|   vpass = &blur->pass[VERTICAL]; | ||||
|   hpass = &blur->pass[HORIZONTAL]; | ||||
|  | ||||
|   if (!setup_blur_pass (blur, vpass, VERTICAL, texture) || | ||||
|       !setup_blur_pass (blur, hpass, HORIZONTAL, vpass->texture)) | ||||
|     { | ||||
|       clutter_blur_free (blur); | ||||
|       return NULL; | ||||
|     } | ||||
|  | ||||
| out: | ||||
|   return g_steal_pointer (&blur); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_blur_apply: | ||||
|  * @blur: a #ClutterBlur | ||||
|  * | ||||
|  * Applies the blur. The resulting texture can be retrieved by | ||||
|  * [method@Clutter.Blur.get_texture]. | ||||
|  */ | ||||
| void | ||||
| clutter_blur_apply (ClutterBlur *blur) | ||||
| { | ||||
|   if (G_APPROX_VALUE (blur->sigma, 0.0, FLT_EPSILON)) | ||||
|     return; | ||||
|  | ||||
|   apply_blur_pass (&blur->pass[VERTICAL]); | ||||
|   apply_blur_pass (&blur->pass[HORIZONTAL]); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_blur_get_texture: | ||||
|  * @blur: a #ClutterBlur | ||||
|  * | ||||
|  * Retrieves the texture where the blurred contents are stored. The | ||||
|  * contents are undefined until [method@Clutter.Blur.apply] is called. | ||||
|  * | ||||
|  * Returns: (transfer none): a #CoglTexture | ||||
|  */ | ||||
| CoglTexture * | ||||
| clutter_blur_get_texture (ClutterBlur *blur) | ||||
| { | ||||
|   if (G_APPROX_VALUE (blur->sigma, 0.0, FLT_EPSILON)) | ||||
|     return blur->source_texture; | ||||
|   else | ||||
|     return blur->pass[HORIZONTAL].texture; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_blur_free: | ||||
|  * @blur: A #ClutterBlur | ||||
|  * | ||||
|  * Frees @blur. | ||||
|  */ | ||||
| void | ||||
| clutter_blur_free (ClutterBlur *blur) | ||||
| { | ||||
|   g_assert (blur); | ||||
|  | ||||
|   clear_blur_pass (&blur->pass[VERTICAL]); | ||||
|   clear_blur_pass (&blur->pass[HORIZONTAL]); | ||||
|   g_clear_object (&blur->source_texture); | ||||
|   g_free (blur); | ||||
| } | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,72 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * 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/>. | ||||
|  * | ||||
|  * Author: | ||||
|  *   Emmanuele Bassi <ebassi@linux.intel.com> | ||||
|  * | ||||
|  * Based on the NBTK NbtkBoxLayout actor by: | ||||
|  *   Thomas Wood <thomas.wood@intel.com> | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <clutter/clutter.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include "clutter/clutter-layout-manager.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CLUTTER_TYPE_BOX_LAYOUT                 (clutter_box_layout_get_type ()) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_DERIVABLE_TYPE (ClutterBoxLayout, | ||||
|                           clutter_box_layout, | ||||
|                           CLUTTER, BOX_LAYOUT, | ||||
|                           ClutterLayoutManager) | ||||
|  | ||||
| struct _ClutterBoxLayoutClass | ||||
| { | ||||
|   /*< private >*/ | ||||
|   ClutterLayoutManagerClass parent_class; | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterLayoutManager *  clutter_box_layout_new                 (void); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void                    clutter_box_layout_set_orientation      (ClutterBoxLayout    *layout, | ||||
|                                                                  ClutterOrientation   orientation); | ||||
| CLUTTER_EXPORT | ||||
| ClutterOrientation      clutter_box_layout_get_orientation      (ClutterBoxLayout    *layout); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void                    clutter_box_layout_set_spacing          (ClutterBoxLayout    *layout, | ||||
|                                                                  guint                spacing); | ||||
| CLUTTER_EXPORT | ||||
| guint                   clutter_box_layout_get_spacing          (ClutterBoxLayout    *layout); | ||||
| CLUTTER_EXPORT | ||||
| void                    clutter_box_layout_set_homogeneous      (ClutterBoxLayout    *layout, | ||||
|                                                                  gboolean             homogeneous); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                clutter_box_layout_get_homogeneous      (ClutterBoxLayout    *layout); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,595 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2010-2012 Inclusive Design Research Centre, OCAD University. | ||||
|  * | ||||
|  * 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: | ||||
|  *   Joseph Scheuhammer <clown@alum.mit.edu> | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * ClutterBrightnessContrastEffect: | ||||
|  * | ||||
|  * Increase/decrease brightness and/or contrast of actor. | ||||
|  * | ||||
|  * #ClutterBrightnessContrastEffect is a sub-class of #ClutterEffect that | ||||
|  * changes the overall brightness of a #ClutterActor. | ||||
|  */ | ||||
| #include "config.h" | ||||
|  | ||||
| #include <math.h> | ||||
|  | ||||
| #include "cogl/cogl.h" | ||||
|  | ||||
| #include "clutter/clutter-brightness-contrast-effect.h" | ||||
| #include "clutter/clutter-debug.h" | ||||
| #include "clutter/clutter-enum-types.h" | ||||
| #include "clutter/clutter-private.h" | ||||
|  | ||||
| typedef struct _ClutterBrightnessContrastEffectPrivate | ||||
| { | ||||
|   /* Brightness and contrast changes. */ | ||||
|   gfloat brightness_red; | ||||
|   gfloat brightness_green; | ||||
|   gfloat brightness_blue; | ||||
|  | ||||
|   gfloat contrast_red; | ||||
|   gfloat contrast_green; | ||||
|   gfloat contrast_blue; | ||||
|  | ||||
|   gint brightness_multiplier_uniform; | ||||
|   gint brightness_offset_uniform; | ||||
|   gint contrast_uniform; | ||||
|  | ||||
|   CoglPipeline *pipeline; | ||||
| } ClutterBrightnessContrastEffectPrivate; | ||||
|  | ||||
|  | ||||
| /* Brightness effects in GLSL. | ||||
|  */ | ||||
| static const gchar *brightness_contrast_decls = | ||||
|   "uniform vec3 brightness_multiplier;\n" | ||||
|   "uniform vec3 brightness_offset;\n" | ||||
|   "uniform vec3 contrast;\n"; | ||||
|  | ||||
| static const gchar *brightness_contrast_source = | ||||
|   /* Apply the brightness. The brightness_offset is multiplied by the | ||||
|      alpha to keep the color pre-multiplied */ | ||||
|   "cogl_color_out.rgb = (cogl_color_out.rgb * brightness_multiplier +\n" | ||||
|   "                      brightness_offset * cogl_color_out.a);\n" | ||||
|   /* Apply the contrast */ | ||||
|   "cogl_color_out.rgb = ((cogl_color_out.rgb - 0.5 * cogl_color_out.a) *\n" | ||||
|   "                      contrast + 0.5 * cogl_color_out.a);\n"; | ||||
|  | ||||
| static const ClutterColor no_brightness_change = { 0x7f, 0x7f, 0x7f, 0xff }; | ||||
| static const ClutterColor no_contrast_change = { 0x7f, 0x7f, 0x7f, 0xff }; | ||||
| static const gfloat no_change = 0.0f; | ||||
|  | ||||
| enum | ||||
| { | ||||
|   PROP_0, | ||||
|  | ||||
|   PROP_BRIGHTNESS, | ||||
|   PROP_CONTRAST, | ||||
|  | ||||
|   PROP_LAST | ||||
| }; | ||||
|  | ||||
| static GParamSpec *obj_props[PROP_LAST]; | ||||
|  | ||||
| G_DEFINE_TYPE_WITH_PRIVATE (ClutterBrightnessContrastEffect, | ||||
|                             clutter_brightness_contrast_effect, | ||||
|                             CLUTTER_TYPE_OFFSCREEN_EFFECT) | ||||
|  | ||||
| static gboolean | ||||
| will_have_no_effect (ClutterBrightnessContrastEffect *self) | ||||
| { | ||||
|   ClutterBrightnessContrastEffectPrivate *priv = | ||||
|     clutter_brightness_contrast_effect_get_instance_private (self); | ||||
|  | ||||
|   return (G_APPROX_VALUE (priv->brightness_red, no_change, FLT_EPSILON) && | ||||
|           G_APPROX_VALUE (priv->brightness_green, no_change, FLT_EPSILON) && | ||||
|           G_APPROX_VALUE (priv->brightness_blue, no_change, FLT_EPSILON) && | ||||
|           G_APPROX_VALUE (priv->contrast_red, no_change, FLT_EPSILON) && | ||||
|           G_APPROX_VALUE (priv->contrast_green, no_change, FLT_EPSILON) && | ||||
|           G_APPROX_VALUE (priv->contrast_blue, no_change, FLT_EPSILON)); | ||||
| } | ||||
|  | ||||
| static CoglPipeline * | ||||
| clutter_brightness_contrast_effect_create_pipeline (ClutterOffscreenEffect *effect, | ||||
|                                                     CoglTexture            *texture) | ||||
| { | ||||
|   ClutterBrightnessContrastEffect *self = | ||||
|     CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect); | ||||
|   ClutterBrightnessContrastEffectPrivate *priv = | ||||
|     clutter_brightness_contrast_effect_get_instance_private (self); | ||||
|  | ||||
|   cogl_pipeline_set_layer_texture (priv->pipeline, 0, texture); | ||||
|  | ||||
|   return g_object_ref (priv->pipeline); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| clutter_brightness_contrast_effect_pre_paint (ClutterEffect       *effect, | ||||
|                                               ClutterPaintNode    *node, | ||||
|                                               ClutterPaintContext *paint_context) | ||||
| { | ||||
|   ClutterBrightnessContrastEffect *self = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect); | ||||
|   ClutterEffectClass *parent_class; | ||||
|  | ||||
|   if (will_have_no_effect (self)) | ||||
|     return FALSE; | ||||
|  | ||||
|   parent_class = | ||||
|     CLUTTER_EFFECT_CLASS (clutter_brightness_contrast_effect_parent_class); | ||||
|  | ||||
|   return parent_class->pre_paint (effect, node, paint_context); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_brightness_contrast_effect_dispose (GObject *gobject) | ||||
| { | ||||
|   ClutterBrightnessContrastEffect *self = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (gobject); | ||||
|   ClutterBrightnessContrastEffectPrivate *priv = | ||||
|     clutter_brightness_contrast_effect_get_instance_private (self); | ||||
|  | ||||
|   g_clear_object (&priv->pipeline); | ||||
|  | ||||
|   G_OBJECT_CLASS (clutter_brightness_contrast_effect_parent_class)->dispose (gobject); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_brightness_contrast_effect_set_property (GObject      *gobject, | ||||
|                                                  guint        prop_id, | ||||
|                                                  const GValue *value, | ||||
|                                                  GParamSpec   *pspec) | ||||
| { | ||||
|   ClutterBrightnessContrastEffect *effect = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (gobject); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_BRIGHTNESS: | ||||
|       { | ||||
|         const ClutterColor *color = clutter_value_get_color (value); | ||||
|         clutter_brightness_contrast_effect_set_brightness_full (effect, | ||||
|                                                                 color->red / 127.0f - 1.0f, | ||||
|                                                                 color->green / 127.0f - 1.0f, | ||||
|                                                                 color->blue / 127.0f - 1.0f); | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|     case PROP_CONTRAST: | ||||
|       { | ||||
|         const ClutterColor *color = clutter_value_get_color (value); | ||||
|         clutter_brightness_contrast_effect_set_contrast_full (effect, | ||||
|                                                               color->red / 127.0f - 1.0f, | ||||
|                                                               color->green / 127.0f - 1.0f, | ||||
|                                                               color->blue / 127.0f - 1.0f); | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_brightness_contrast_effect_get_property (GObject    *gobject, | ||||
|                                                  guint      prop_id, | ||||
|                                                  GValue     *value, | ||||
|                                                  GParamSpec *pspec) | ||||
| { | ||||
|   ClutterBrightnessContrastEffect *effect = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (gobject); | ||||
|   ClutterBrightnessContrastEffectPrivate *priv = | ||||
|     clutter_brightness_contrast_effect_get_instance_private (effect); | ||||
|   ClutterColor color; | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_BRIGHTNESS: | ||||
|       { | ||||
|         color.red = (priv->brightness_red + 1.0f) * 127.0f; | ||||
|         color.green = (priv->brightness_green + 1.0f) * 127.0f; | ||||
|         color.blue = (priv->brightness_blue + 1.0f) * 127.0f; | ||||
|         color.alpha = 0xff; | ||||
|  | ||||
|         clutter_value_set_color (value, &color); | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|     case PROP_CONTRAST: | ||||
|       { | ||||
|         color.red = (priv->contrast_red + 1.0f) * 127.0f; | ||||
|         color.green = (priv->contrast_green + 1.0f) * 127.0f; | ||||
|         color.blue = (priv->contrast_blue + 1.0f) * 127.0f; | ||||
|         color.alpha = 0xff; | ||||
|  | ||||
|         clutter_value_set_color (value, &color); | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_brightness_contrast_effect_class_init (ClutterBrightnessContrastEffectClass *klass) | ||||
| { | ||||
|   ClutterEffectClass *effect_class = CLUTTER_EFFECT_CLASS (klass); | ||||
|   GObjectClass *gobject_class = G_OBJECT_CLASS (klass); | ||||
|   ClutterOffscreenEffectClass *offscreen_class; | ||||
|  | ||||
|   offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass); | ||||
|   offscreen_class->create_pipeline = clutter_brightness_contrast_effect_create_pipeline; | ||||
|  | ||||
|   effect_class->pre_paint = clutter_brightness_contrast_effect_pre_paint; | ||||
|  | ||||
|   gobject_class->set_property = clutter_brightness_contrast_effect_set_property; | ||||
|   gobject_class->get_property = clutter_brightness_contrast_effect_get_property; | ||||
|   gobject_class->dispose = clutter_brightness_contrast_effect_dispose; | ||||
|  | ||||
|   /** | ||||
|    * ClutterBrightnessContrastEffect:brightness: | ||||
|    * | ||||
|    * The brightness change to apply to the effect. | ||||
|    * | ||||
|    * This property uses a #ClutterColor to represent the changes to each | ||||
|    * color channel. The range is [ 0, 255 ], with 127 as the value used | ||||
|    * to indicate no change; values smaller than 127 indicate a decrease | ||||
|    * in brightness, and values larger than 127 indicate an increase in | ||||
|    * brightness. | ||||
|    */ | ||||
|   obj_props[PROP_BRIGHTNESS] = | ||||
|     clutter_param_spec_color ("brightness", NULL, NULL, | ||||
|                               &no_brightness_change, | ||||
|                               G_PARAM_READWRITE | | ||||
|                               G_PARAM_STATIC_STRINGS); | ||||
|  | ||||
|   /** | ||||
|    * ClutterBrightnessContrastEffect:contrast: | ||||
|    * | ||||
|    * The contrast change to apply to the effect. | ||||
|    * | ||||
|    * This property uses a #ClutterColor to represent the changes to each | ||||
|    * color channel. The range is [ 0, 255 ], with 127 as the value used | ||||
|    * to indicate no change; values smaller than 127 indicate a decrease | ||||
|    * in contrast, and values larger than 127 indicate an increase in | ||||
|    * contrast. | ||||
|    */ | ||||
|   obj_props[PROP_CONTRAST] = | ||||
|     clutter_param_spec_color ("contrast", NULL, NULL, | ||||
|                               &no_contrast_change, | ||||
|                               G_PARAM_READWRITE | | ||||
|                               G_PARAM_STATIC_STRINGS); | ||||
|  | ||||
|   g_object_class_install_properties (gobject_class, PROP_LAST, obj_props); | ||||
| } | ||||
|  | ||||
| static void | ||||
| get_brightness_values (gfloat  value, | ||||
|                        gfloat *multiplier, | ||||
|                        gfloat *offset) | ||||
| { | ||||
|   if (value < 0.0f) | ||||
|     { | ||||
|       *multiplier = 1.0f + value; | ||||
|       *offset = 0.0f; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       *multiplier = 1.0f - value; | ||||
|       *offset = value; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static inline void | ||||
| update_uniforms (ClutterBrightnessContrastEffect *self) | ||||
| { | ||||
|   ClutterBrightnessContrastEffectPrivate *priv = | ||||
|     clutter_brightness_contrast_effect_get_instance_private (self); | ||||
|  | ||||
|   if (priv->brightness_multiplier_uniform > -1 && | ||||
|       priv->brightness_offset_uniform > -1) | ||||
|     { | ||||
|       float brightness_multiplier[3]; | ||||
|       float brightness_offset[3]; | ||||
|  | ||||
|       get_brightness_values (priv->brightness_red, | ||||
|                              brightness_multiplier + 0, | ||||
|                              brightness_offset + 0); | ||||
|       get_brightness_values (priv->brightness_green, | ||||
|                              brightness_multiplier + 1, | ||||
|                              brightness_offset + 1); | ||||
|       get_brightness_values (priv->brightness_blue, | ||||
|                              brightness_multiplier + 2, | ||||
|                              brightness_offset + 2); | ||||
|  | ||||
|       cogl_pipeline_set_uniform_float (priv->pipeline, | ||||
|                                        priv->brightness_multiplier_uniform, | ||||
|                                        3, /* n_components */ | ||||
|                                        1, /* count */ | ||||
|                                        brightness_multiplier); | ||||
|       cogl_pipeline_set_uniform_float (priv->pipeline, | ||||
|                                        priv->brightness_offset_uniform, | ||||
|                                        3, /* n_components */ | ||||
|                                        1, /* count */ | ||||
|                                        brightness_offset); | ||||
|     } | ||||
|  | ||||
|   if (priv->contrast_uniform > -1) | ||||
|     { | ||||
|       float contrast[3] = { | ||||
|         tan ((priv->contrast_red + 1) * G_PI_4), | ||||
|         tan ((priv->contrast_green + 1) * G_PI_4), | ||||
|         tan ((priv->contrast_blue + 1) * G_PI_4) | ||||
|       }; | ||||
|  | ||||
|       cogl_pipeline_set_uniform_float (priv->pipeline, | ||||
|                                        priv->contrast_uniform, | ||||
|                                        3, /* n_components */ | ||||
|                                        1, /* count */ | ||||
|                                        contrast); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_brightness_contrast_effect_init (ClutterBrightnessContrastEffect *self) | ||||
| { | ||||
|   ClutterBrightnessContrastEffectClass *klass; | ||||
|   ClutterBrightnessContrastEffectPrivate *priv = | ||||
|     clutter_brightness_contrast_effect_get_instance_private (self); | ||||
|  | ||||
|   priv->brightness_red = no_change; | ||||
|   priv->brightness_green = no_change; | ||||
|   priv->brightness_blue = no_change; | ||||
|  | ||||
|   priv->contrast_red = no_change; | ||||
|   priv->contrast_green = no_change; | ||||
|   priv->contrast_blue = no_change; | ||||
|  | ||||
|   klass = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT_GET_CLASS (self); | ||||
|  | ||||
|   if (G_UNLIKELY (klass->base_pipeline == NULL)) | ||||
|     { | ||||
|       CoglSnippet *snippet; | ||||
|       CoglContext *ctx = | ||||
|         clutter_backend_get_cogl_context (clutter_get_default_backend ()); | ||||
|  | ||||
|       klass->base_pipeline = cogl_pipeline_new (ctx); | ||||
|  | ||||
|       snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, | ||||
|                                   brightness_contrast_decls, | ||||
|                                   brightness_contrast_source); | ||||
|       cogl_pipeline_add_snippet (klass->base_pipeline, snippet); | ||||
|       g_object_unref (snippet); | ||||
|  | ||||
|       cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0); | ||||
|     } | ||||
|  | ||||
|   priv->pipeline = cogl_pipeline_copy (klass->base_pipeline); | ||||
|  | ||||
|   priv->brightness_multiplier_uniform = | ||||
|     cogl_pipeline_get_uniform_location (priv->pipeline, | ||||
|                                         "brightness_multiplier"); | ||||
|   priv->brightness_offset_uniform = | ||||
|     cogl_pipeline_get_uniform_location (priv->pipeline, | ||||
|                                         "brightness_offset"); | ||||
|   priv->contrast_uniform = | ||||
|     cogl_pipeline_get_uniform_location (priv->pipeline, "contrast"); | ||||
|  | ||||
|   update_uniforms (self); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_brightness_contrast_effect_new: | ||||
|  * | ||||
|  * Creates a new #ClutterBrightnessContrastEffect to be used with | ||||
|  * [method@Clutter.Actor.add_effect] | ||||
|  * | ||||
|  * Return value: (transfer full): the newly created | ||||
|  *   #ClutterBrightnessContrastEffect or %NULL.  Use g_object_unref() when | ||||
|  *   done. | ||||
|  */ | ||||
| ClutterEffect * | ||||
| clutter_brightness_contrast_effect_new (void) | ||||
| { | ||||
|   return g_object_new (CLUTTER_TYPE_BRIGHTNESS_CONTRAST_EFFECT, NULL); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_brightness_contrast_effect_set_brightness_full: | ||||
|  * @effect: a #ClutterBrightnessContrastEffect | ||||
|  * @red: red component of the change in brightness | ||||
|  * @green: green component of the change in brightness | ||||
|  * @blue: blue component of the change in brightness | ||||
|  * | ||||
|  * The range for each component is [-1.0, 1.0] where 0.0 designates no change, | ||||
|  * values below 0.0 mean a decrease in brightness, and values above indicate | ||||
|  * an increase. | ||||
|  */ | ||||
| void | ||||
| clutter_brightness_contrast_effect_set_brightness_full (ClutterBrightnessContrastEffect *effect, | ||||
|                                                         gfloat                           red, | ||||
|                                                         gfloat                           green, | ||||
|                                                         gfloat                           blue) | ||||
| { | ||||
|   ClutterBrightnessContrastEffectPrivate *priv; | ||||
|  | ||||
|   g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect)); | ||||
|  | ||||
|   priv = clutter_brightness_contrast_effect_get_instance_private (effect); | ||||
|   if (G_APPROX_VALUE (red, priv->brightness_red, FLT_EPSILON) && | ||||
|       G_APPROX_VALUE (green, priv->brightness_green, FLT_EPSILON) && | ||||
|       G_APPROX_VALUE (blue, priv->brightness_blue, FLT_EPSILON)) | ||||
|     return; | ||||
|  | ||||
|   priv->brightness_red = red; | ||||
|   priv->brightness_green = green; | ||||
|   priv->brightness_blue = blue; | ||||
|  | ||||
|   update_uniforms (effect); | ||||
|  | ||||
|   clutter_effect_queue_repaint (CLUTTER_EFFECT (effect)); | ||||
|  | ||||
|   g_object_notify_by_pspec (G_OBJECT (effect), obj_props[PROP_BRIGHTNESS]); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_brightness_contrast_effect_get_brightness: | ||||
|  * @effect: a #ClutterBrightnessContrastEffect | ||||
|  * @red: (out) (allow-none): return location for red component of the | ||||
|  *    change in brightness | ||||
|  * @green: (out) (allow-none): return location for green component of the | ||||
|  *    change in brightness | ||||
|  * @blue: (out) (allow-none): return location for blue component of the | ||||
|  *    change in brightness | ||||
|  * | ||||
|  * Retrieves the change in brightness used by @effect. | ||||
|  */ | ||||
| void | ||||
| clutter_brightness_contrast_effect_get_brightness (ClutterBrightnessContrastEffect *effect, | ||||
|                                                    gfloat                          *red, | ||||
|                                                    gfloat                          *green, | ||||
|                                                    gfloat                          *blue) | ||||
| { | ||||
|   ClutterBrightnessContrastEffectPrivate *priv; | ||||
|  | ||||
|   g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect)); | ||||
|  | ||||
|   priv = clutter_brightness_contrast_effect_get_instance_private (effect); | ||||
|   if (red != NULL) | ||||
|     *red = priv->brightness_red; | ||||
|  | ||||
|   if (green != NULL) | ||||
|     *green = priv->brightness_green; | ||||
|  | ||||
|   if (blue != NULL) | ||||
|     *blue = priv->brightness_blue; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_brightness_contrast_effect_set_brightness: | ||||
|  * @effect: a #ClutterBrightnessContrastEffect | ||||
|  * @brightness:  the brightness change for all three components (r, g, b) | ||||
|  * | ||||
|  * The range of @brightness is [-1.0, 1.0], where 0.0 designates no change; | ||||
|  * a value below 0.0 indicates a decrease in brightness; and a value | ||||
|  * above 0.0 indicates an increase of brightness. | ||||
|  */ | ||||
| void | ||||
| clutter_brightness_contrast_effect_set_brightness (ClutterBrightnessContrastEffect *effect, | ||||
|                                                    gfloat                           brightness) | ||||
| { | ||||
|   clutter_brightness_contrast_effect_set_brightness_full (effect, | ||||
|                                                           brightness, | ||||
|                                                           brightness, | ||||
|                                                           brightness); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_brightness_contrast_effect_set_contrast_full: | ||||
|  * @effect: a #ClutterBrightnessContrastEffect | ||||
|  * @red: red component of the change in contrast | ||||
|  * @green: green component of the change in contrast | ||||
|  * @blue: blue component of the change in contrast | ||||
|  * | ||||
|  * The range for each component is [-1.0, 1.0] where 0.0 designates no change, | ||||
|  * values below 0.0 mean a decrease in contrast, and values above indicate | ||||
|  * an increase. | ||||
|  */ | ||||
| void | ||||
| clutter_brightness_contrast_effect_set_contrast_full (ClutterBrightnessContrastEffect *effect, | ||||
|                                                       gfloat                          red, | ||||
|                                                       gfloat                          green, | ||||
|                                                       gfloat                          blue) | ||||
| { | ||||
|   ClutterBrightnessContrastEffectPrivate *priv; | ||||
|  | ||||
|   g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect)); | ||||
|  | ||||
|   priv = clutter_brightness_contrast_effect_get_instance_private (effect); | ||||
|   if (G_APPROX_VALUE (red, priv->contrast_red, FLT_EPSILON) && | ||||
|       G_APPROX_VALUE (green, priv->contrast_green, FLT_EPSILON) && | ||||
|       G_APPROX_VALUE (blue, priv->contrast_blue, FLT_EPSILON)) | ||||
|     return; | ||||
|  | ||||
|   priv->contrast_red = red; | ||||
|   priv->contrast_green = green; | ||||
|   priv->contrast_blue = blue; | ||||
|  | ||||
|   update_uniforms (effect); | ||||
|  | ||||
|   clutter_effect_queue_repaint (CLUTTER_EFFECT (effect)); | ||||
|  | ||||
|   g_object_notify_by_pspec (G_OBJECT (effect), obj_props[PROP_CONTRAST]); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_brightness_contrast_effect_get_contrast: | ||||
|  * @effect: a #ClutterBrightnessContrastEffect | ||||
|  * @red: (out) (allow-none): return location for red component of the | ||||
|  *    change in contrast | ||||
|  * @green: (out) (allow-none): return location for green component of the | ||||
|  *    change in contrast | ||||
|  * @blue: (out) (allow-none): return location for blue component of the | ||||
|  *    change in contrast | ||||
|  * | ||||
|  * Retrieves the contrast value used by @effect. | ||||
|  */ | ||||
| void | ||||
| clutter_brightness_contrast_effect_get_contrast (ClutterBrightnessContrastEffect *effect, | ||||
|                                                  gfloat                          *red, | ||||
|                                                  gfloat                          *green, | ||||
|                                                  gfloat                          *blue) | ||||
| { | ||||
|   ClutterBrightnessContrastEffectPrivate *priv; | ||||
|  | ||||
|   g_return_if_fail (CLUTTER_IS_BRIGHTNESS_CONTRAST_EFFECT (effect)); | ||||
|  | ||||
|   priv = clutter_brightness_contrast_effect_get_instance_private (effect); | ||||
|   if (red != NULL) | ||||
|     *red = priv->contrast_red; | ||||
|  | ||||
|   if (green != NULL) | ||||
|     *green = priv->contrast_green; | ||||
|  | ||||
|   if (blue != NULL) | ||||
|     *blue = priv->contrast_blue; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_brightness_contrast_effect_set_contrast: | ||||
|  * @effect: a #ClutterBrightnessContrastEffect | ||||
|  * @contrast: contrast change for all three channels | ||||
|  * | ||||
|  * The range for @contrast is [-1.0, 1.0], where 0.0 designates no change; | ||||
|  * a value below 0.0 indicates a decrease in contrast; and a value above | ||||
|  * 0.0 indicates an increase. | ||||
|  */ | ||||
| void | ||||
| clutter_brightness_contrast_effect_set_contrast (ClutterBrightnessContrastEffect *effect, | ||||
|                                                  gfloat                           contrast) | ||||
| { | ||||
|   clutter_brightness_contrast_effect_set_contrast_full (effect, | ||||
|                                                         contrast, | ||||
|                                                         contrast, | ||||
|                                                         contrast); | ||||
| } | ||||
| @@ -1,84 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2010-2012 Inclusive Design Research Centre, OCAD University. | ||||
|  * | ||||
|  * 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: | ||||
|  *   Joseph Scheuhammer <clown@alum.mit.edu> | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <clutter/clutter.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include "clutter/clutter-color.h" | ||||
| #include "clutter/clutter-effect.h" | ||||
| #include "clutter/clutter-offscreen-effect.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CLUTTER_TYPE_BRIGHTNESS_CONTRAST_EFFECT     (clutter_brightness_contrast_effect_get_type ()) | ||||
|  | ||||
|  | ||||
| struct _ClutterBrightnessContrastEffectClass | ||||
| { | ||||
|   ClutterOffscreenEffectClass parent_class; | ||||
|  | ||||
|   CoglPipeline *base_pipeline; | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_DERIVABLE_TYPE (ClutterBrightnessContrastEffect, | ||||
|                           clutter_brightness_contrast_effect, | ||||
|                           CLUTTER, BRIGHTNESS_CONTRAST_EFFECT, | ||||
|                           ClutterOffscreenEffect) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterEffect * clutter_brightness_contrast_effect_new                          (void); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void            clutter_brightness_contrast_effect_set_brightness_full          (ClutterBrightnessContrastEffect *effect, | ||||
|                                                                                  float                            red, | ||||
|                                                                                  float                            green, | ||||
|                                                                                  float                            blue); | ||||
| CLUTTER_EXPORT | ||||
| void            clutter_brightness_contrast_effect_set_brightness               (ClutterBrightnessContrastEffect *effect, | ||||
|                                                                                  float                            brightness); | ||||
| CLUTTER_EXPORT | ||||
| void            clutter_brightness_contrast_effect_get_brightness               (ClutterBrightnessContrastEffect *effect, | ||||
|                                                                                  float                           *red, | ||||
|                                                                                  float                           *green, | ||||
|                                                                                  float                           *blue); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void            clutter_brightness_contrast_effect_set_contrast_full            (ClutterBrightnessContrastEffect *effect, | ||||
|                                                                                  float                            red, | ||||
|                                                                                  float                            green, | ||||
|                                                                                  float                            blue); | ||||
| CLUTTER_EXPORT | ||||
| void            clutter_brightness_contrast_effect_set_contrast                 (ClutterBrightnessContrastEffect *effect, | ||||
|                                                                                  float                            contrast); | ||||
| CLUTTER_EXPORT | ||||
| void            clutter_brightness_contrast_effect_get_contrast                 (ClutterBrightnessContrastEffect *effect, | ||||
|                                                                                  float                           *red, | ||||
|                                                                                  float                           *green, | ||||
|                                                                                  float                           *blue); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,785 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2010  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> | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * ClutterClickAction: | ||||
|  *  | ||||
|  * Action for clickable actors | ||||
|  * | ||||
|  * #ClutterClickAction is a sub-class of [class@Action] that implements | ||||
|  * the logic for clickable actors, by using the low level events of | ||||
|  * [class@Actor], such as [signal@Actor::button-press-event] and | ||||
|  * [signal@Actor::button-release-event], to synthesize the high level | ||||
|  * [signal@ClickAction::clicked] signal. | ||||
|  * | ||||
|  * To use #ClutterClickAction you just need to apply it to a [class@Actor] | ||||
|  * using [method@Actor.add_action] and connect to the | ||||
|  * [signal@ClickAction::clicked] signal: | ||||
|  * | ||||
|  * ```c | ||||
|  *   ClutterAction *action = clutter_click_action_new (); | ||||
|  * | ||||
|  *   clutter_actor_add_action (actor, action); | ||||
|  * | ||||
|  *   g_signal_connect (action, "clicked", G_CALLBACK (on_clicked), NULL); | ||||
|  * ``` | ||||
|  * | ||||
|  * #ClutterClickAction also supports long press gestures: a long press is | ||||
|  * activated if the pointer remains pressed within a certain threshold (as | ||||
|  * defined by the [property@ClickAction:long-press-threshold] property) for a | ||||
|  * minimum amount of time (as the defined by the | ||||
|  * [property@ClickAction:long-press-duration] property). | ||||
|  * The [signal@ClickAction::long-press] signal is emitted multiple times, | ||||
|  * using different [enum@LongPressState] values; to handle long presses | ||||
|  * you should connect to the [signal@ClickAction::long-press] signal and | ||||
|  * handle the different states: | ||||
|  * | ||||
|  * ```c | ||||
|  *   static gboolean | ||||
|  *   on_long_press (ClutterClickAction    *action, | ||||
|  *                  ClutterActor          *actor, | ||||
|  *                  ClutterLongPressState  state) | ||||
|  *   { | ||||
|  *     switch (state) | ||||
|  *       { | ||||
|  *       case CLUTTER_LONG_PRESS_QUERY: | ||||
|  *         // return TRUE if the actor should support long press | ||||
|  *         // gestures, and FALSE otherwise; this state will be | ||||
|  *         // emitted on button presses | ||||
|  *         return TRUE; | ||||
|  * | ||||
|  *       case CLUTTER_LONG_PRESS_ACTIVATE: | ||||
|  *         // this state is emitted if the minimum duration has | ||||
|  *         // been reached without the gesture being cancelled. | ||||
|  *         // the return value is not used | ||||
|  *         return TRUE; | ||||
|  * | ||||
|  *       case CLUTTER_LONG_PRESS_CANCEL: | ||||
|  *         // this state is emitted if the long press was cancelled; | ||||
|  *         // for instance, the pointer went outside the actor or the | ||||
|  *         // allowed threshold, or the button was released before | ||||
|  *         // the minimum duration was reached. the return value is | ||||
|  *         // not used | ||||
|  *         return FALSE; | ||||
|  *       } | ||||
|  *   } | ||||
|  * ``` | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "clutter/clutter-click-action.h" | ||||
|  | ||||
| #include "clutter/clutter-debug.h" | ||||
| #include "clutter/clutter-enum-types.h" | ||||
| #include "clutter/clutter-marshal.h" | ||||
| #include "clutter/clutter-private.h" | ||||
|  | ||||
| struct _ClutterClickActionPrivate | ||||
| { | ||||
|   ClutterActor *stage; | ||||
|  | ||||
|   guint long_press_id; | ||||
|  | ||||
|   gint long_press_threshold; | ||||
|   gint long_press_duration; | ||||
|   gint drag_threshold; | ||||
|  | ||||
|   guint press_button; | ||||
|   ClutterInputDevice *press_device; | ||||
|   ClutterEventSequence *press_sequence; | ||||
|   ClutterModifierType modifier_state; | ||||
|   gfloat press_x; | ||||
|   gfloat press_y; | ||||
|  | ||||
|   guint is_held    : 1; | ||||
|   guint is_pressed : 1; | ||||
| }; | ||||
|  | ||||
| enum | ||||
| { | ||||
|   PROP_0, | ||||
|  | ||||
|   PROP_HELD, | ||||
|   PROP_PRESSED, | ||||
|   PROP_LONG_PRESS_THRESHOLD, | ||||
|   PROP_LONG_PRESS_DURATION, | ||||
|  | ||||
|   PROP_LAST | ||||
| }; | ||||
|  | ||||
| static GParamSpec *obj_props[PROP_LAST] = { NULL, }; | ||||
|  | ||||
| enum | ||||
| { | ||||
|   CLICKED, | ||||
|   LONG_PRESS, | ||||
|  | ||||
|   LAST_SIGNAL | ||||
| }; | ||||
|  | ||||
| static guint click_signals[LAST_SIGNAL] = { 0, }; | ||||
|  | ||||
| G_DEFINE_TYPE_WITH_PRIVATE (ClutterClickAction, clutter_click_action, CLUTTER_TYPE_ACTION) | ||||
|  | ||||
| static inline void | ||||
| click_action_set_pressed (ClutterClickAction *action, | ||||
|                           gboolean            is_pressed) | ||||
| { | ||||
|   ClutterClickActionPrivate *priv = | ||||
|     clutter_click_action_get_instance_private (action); | ||||
|  | ||||
|   is_pressed = !!is_pressed; | ||||
|  | ||||
|   if (priv->is_pressed == is_pressed) | ||||
|     return; | ||||
|  | ||||
|   priv->is_pressed = is_pressed; | ||||
|   g_object_notify_by_pspec (G_OBJECT (action), obj_props[PROP_PRESSED]); | ||||
| } | ||||
|  | ||||
| static inline void | ||||
| click_action_set_held (ClutterClickAction *action, | ||||
|                        gboolean            is_held) | ||||
| { | ||||
|   ClutterClickActionPrivate *priv = | ||||
|     clutter_click_action_get_instance_private (action); | ||||
|  | ||||
|   is_held = !!is_held; | ||||
|  | ||||
|   if (priv->is_held == is_held) | ||||
|     return; | ||||
|  | ||||
|   priv->is_held = is_held; | ||||
|   g_object_notify_by_pspec (G_OBJECT (action), obj_props[PROP_HELD]); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| click_action_emit_long_press (gpointer data) | ||||
| { | ||||
|   ClutterClickAction *action = data; | ||||
|   ClutterClickActionPrivate *priv = | ||||
|     clutter_click_action_get_instance_private (action); | ||||
|   ClutterActor *actor; | ||||
|   gboolean result; | ||||
|  | ||||
|   priv->long_press_id = 0; | ||||
|  | ||||
|   actor = clutter_actor_meta_get_actor (data); | ||||
|  | ||||
|   g_signal_emit (action, click_signals[LONG_PRESS], 0, | ||||
|                  actor, | ||||
|                  CLUTTER_LONG_PRESS_ACTIVATE, | ||||
|                  &result); | ||||
|  | ||||
|   click_action_set_pressed (action, FALSE); | ||||
|   click_action_set_held (action, FALSE); | ||||
|  | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| static inline void | ||||
| click_action_query_long_press (ClutterClickAction *action) | ||||
| { | ||||
|   ClutterClickActionPrivate *priv = | ||||
|     clutter_click_action_get_instance_private (action); | ||||
|   ClutterActor *actor; | ||||
|   gboolean result = FALSE; | ||||
|   gint timeout; | ||||
|  | ||||
|   if (priv->long_press_duration < 0) | ||||
|     { | ||||
|       ClutterSettings *settings = clutter_settings_get_default (); | ||||
|  | ||||
|       g_object_get (settings, | ||||
|                     "long-press-duration", &timeout, | ||||
|                     NULL); | ||||
|     } | ||||
|   else | ||||
|     timeout = priv->long_press_duration; | ||||
|  | ||||
|   actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action)); | ||||
|  | ||||
|   g_signal_emit (action, click_signals[LONG_PRESS], 0, | ||||
|                  actor, | ||||
|                  CLUTTER_LONG_PRESS_QUERY, | ||||
|                  &result); | ||||
|  | ||||
|   if (result) | ||||
|     { | ||||
|       g_clear_handle_id (&priv->long_press_id, g_source_remove); | ||||
|       priv->long_press_id = | ||||
|         clutter_threads_add_timeout (timeout, | ||||
|                                      click_action_emit_long_press, | ||||
|                                      action); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static inline void | ||||
| click_action_cancel_long_press (ClutterClickAction *action) | ||||
| { | ||||
|   ClutterClickActionPrivate *priv = | ||||
|     clutter_click_action_get_instance_private (action); | ||||
|  | ||||
|   if (priv->long_press_id != 0) | ||||
|     { | ||||
|       ClutterActor *actor; | ||||
|       gboolean result; | ||||
|  | ||||
|       actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action)); | ||||
|  | ||||
|       g_clear_handle_id (&priv->long_press_id, g_source_remove); | ||||
|  | ||||
|       g_signal_emit (action, click_signals[LONG_PRESS], 0, | ||||
|                      actor, | ||||
|                      CLUTTER_LONG_PRESS_CANCEL, | ||||
|                      &result); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static inline gboolean | ||||
| event_within_drag_threshold (ClutterClickAction *click_action, | ||||
|                              const ClutterEvent *event) | ||||
| { | ||||
|   ClutterClickActionPrivate *priv = | ||||
|     clutter_click_action_get_instance_private (click_action); | ||||
|   float motion_x, motion_y; | ||||
|   float delta_x, delta_y; | ||||
|  | ||||
|   clutter_event_get_coords (event, &motion_x, &motion_y); | ||||
|  | ||||
|   delta_x = ABS (motion_x - priv->press_x); | ||||
|   delta_y = ABS (motion_y - priv->press_y); | ||||
|  | ||||
|   return delta_x <= priv->drag_threshold && delta_y <= priv->drag_threshold; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| clutter_click_action_handle_event (ClutterAction      *action, | ||||
|                                    const ClutterEvent *event) | ||||
| { | ||||
|   ClutterClickAction *click_action = CLUTTER_CLICK_ACTION (action); | ||||
|   ClutterClickActionPrivate *priv = | ||||
|     clutter_click_action_get_instance_private (click_action); | ||||
|   ClutterActor *actor = | ||||
|     clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action)); | ||||
|   gboolean has_button = TRUE; | ||||
|   ClutterModifierType modifier_state; | ||||
|   ClutterActor *target; | ||||
|  | ||||
|   if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (action))) | ||||
|     return CLUTTER_EVENT_PROPAGATE; | ||||
|  | ||||
|   if (priv->press_sequence != NULL && | ||||
|       clutter_event_get_event_sequence (event) != priv->press_sequence) | ||||
|     { | ||||
|       click_action_set_held (click_action, FALSE); | ||||
|       click_action_cancel_long_press (click_action); | ||||
|       return CLUTTER_EVENT_PROPAGATE; | ||||
|     } | ||||
|  | ||||
|   switch (clutter_event_type (event)) | ||||
|     { | ||||
|     case CLUTTER_TOUCH_BEGIN: | ||||
|       has_button = FALSE; | ||||
|  | ||||
|       G_GNUC_FALLTHROUGH; | ||||
|     case CLUTTER_BUTTON_PRESS: | ||||
|       if (priv->is_held) | ||||
|         return CLUTTER_EVENT_STOP; | ||||
|  | ||||
|       target = clutter_stage_get_device_actor (CLUTTER_STAGE (clutter_actor_get_stage (actor)), | ||||
|                                                clutter_event_get_device (event), | ||||
|                                                clutter_event_get_event_sequence (event)); | ||||
|  | ||||
|       if (!clutter_actor_contains (actor, target)) | ||||
|         return CLUTTER_EVENT_PROPAGATE; | ||||
|  | ||||
|       priv->press_button = has_button ? clutter_event_get_button (event) : 0; | ||||
|       priv->press_device = clutter_event_get_device (event); | ||||
|       priv->press_sequence = clutter_event_get_event_sequence (event); | ||||
|       priv->modifier_state = clutter_event_get_state (event); | ||||
|       clutter_event_get_coords (event, &priv->press_x, &priv->press_y); | ||||
|  | ||||
|       if (priv->long_press_threshold < 0) | ||||
|         { | ||||
|           ClutterSettings *settings = clutter_settings_get_default (); | ||||
|  | ||||
|           g_object_get (settings, | ||||
|                         "dnd-drag-threshold", &priv->drag_threshold, | ||||
|                         NULL); | ||||
|         } | ||||
|       else | ||||
|         priv->drag_threshold = priv->long_press_threshold; | ||||
|  | ||||
|       if (priv->stage == NULL) | ||||
|         priv->stage = clutter_actor_get_stage (actor); | ||||
|  | ||||
|       click_action_set_pressed (click_action, TRUE); | ||||
|       click_action_set_held (click_action, TRUE); | ||||
|       click_action_query_long_press (click_action); | ||||
|       break; | ||||
|  | ||||
|     case CLUTTER_ENTER: | ||||
|       click_action_set_pressed (click_action, priv->is_held); | ||||
|       return CLUTTER_EVENT_PROPAGATE; | ||||
|  | ||||
|     case CLUTTER_LEAVE: | ||||
|       click_action_set_pressed (click_action, FALSE); | ||||
|       click_action_cancel_long_press (click_action); | ||||
|       return CLUTTER_EVENT_PROPAGATE; | ||||
|  | ||||
|     case CLUTTER_TOUCH_CANCEL: | ||||
|       clutter_click_action_release (click_action); | ||||
|       break; | ||||
|  | ||||
|     case CLUTTER_TOUCH_END: | ||||
|       has_button = FALSE; | ||||
|  | ||||
|       G_GNUC_FALLTHROUGH; | ||||
|     case CLUTTER_BUTTON_RELEASE: | ||||
|       if (!priv->is_held) | ||||
|         return CLUTTER_EVENT_PROPAGATE; | ||||
|  | ||||
|       if ((has_button && clutter_event_get_button (event) != priv->press_button) || | ||||
|           clutter_event_get_device (event) != priv->press_device || | ||||
|           clutter_event_get_event_sequence (event) != priv->press_sequence) | ||||
|         return CLUTTER_EVENT_PROPAGATE; | ||||
|  | ||||
|       click_action_set_held (click_action, FALSE); | ||||
|       click_action_cancel_long_press (click_action); | ||||
|  | ||||
|       g_clear_handle_id (&priv->long_press_id, g_source_remove); | ||||
|  | ||||
|       target = clutter_stage_get_device_actor (CLUTTER_STAGE (clutter_actor_get_stage (actor)), | ||||
|                                                clutter_event_get_device (event), | ||||
|                                                clutter_event_get_event_sequence (event)); | ||||
|  | ||||
|       if (!clutter_actor_contains (actor, target)) | ||||
|         return CLUTTER_EVENT_PROPAGATE; | ||||
|  | ||||
|       /* exclude any button-mask so that we can compare | ||||
|        * the press and release states properly */ | ||||
|       modifier_state = clutter_event_get_state (event) & | ||||
|                        ~(CLUTTER_BUTTON1_MASK | | ||||
|                          CLUTTER_BUTTON2_MASK | | ||||
|                          CLUTTER_BUTTON3_MASK | | ||||
|                          CLUTTER_BUTTON4_MASK | | ||||
|                          CLUTTER_BUTTON5_MASK); | ||||
|  | ||||
|       /* if press and release states don't match we | ||||
|        * simply ignore modifier keys. i.e. modifier keys | ||||
|        * are expected to be pressed throughout the whole | ||||
|        * click */ | ||||
|       if (modifier_state != priv->modifier_state) | ||||
|         priv->modifier_state = 0; | ||||
|  | ||||
|       click_action_set_pressed (click_action, FALSE); | ||||
|  | ||||
|       if (event_within_drag_threshold (click_action, event)) | ||||
|         g_signal_emit (click_action, click_signals[CLICKED], 0, actor); | ||||
|       break; | ||||
|  | ||||
|     case CLUTTER_MOTION: | ||||
|     case CLUTTER_TOUCH_UPDATE: | ||||
|       { | ||||
|         if (clutter_event_get_device (event) != priv->press_device || | ||||
|             clutter_event_get_event_sequence (event) != priv->press_sequence) | ||||
|           return CLUTTER_EVENT_PROPAGATE; | ||||
|  | ||||
|         if (!priv->is_held) | ||||
|           return CLUTTER_EVENT_PROPAGATE; | ||||
|  | ||||
|         if (!event_within_drag_threshold (click_action, event)) | ||||
|           clutter_click_action_release (click_action); | ||||
|       } | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|   return priv->is_held ? CLUTTER_EVENT_STOP : CLUTTER_EVENT_PROPAGATE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_click_action_sequence_cancelled (ClutterAction        *action, | ||||
|                                          ClutterInputDevice   *device, | ||||
|                                          ClutterEventSequence *sequence) | ||||
| { | ||||
|   ClutterClickAction *self = CLUTTER_CLICK_ACTION (action); | ||||
|   ClutterClickActionPrivate *priv = | ||||
|     clutter_click_action_get_instance_private (self); | ||||
|  | ||||
|   if (priv->press_device == device && priv->press_sequence == sequence) | ||||
|     clutter_click_action_release (self); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_click_action_set_actor (ClutterActorMeta *meta, | ||||
|                                 ClutterActor     *actor) | ||||
| { | ||||
|   ClutterClickAction *action = CLUTTER_CLICK_ACTION (meta); | ||||
|   ClutterClickActionPrivate *priv = | ||||
|     clutter_click_action_get_instance_private (action); | ||||
|  | ||||
|   g_clear_handle_id (&priv->long_press_id, g_source_remove); | ||||
|  | ||||
|   click_action_set_pressed (action, FALSE); | ||||
|   click_action_set_held (action, FALSE); | ||||
|  | ||||
|   CLUTTER_ACTOR_META_CLASS (clutter_click_action_parent_class)->set_actor (meta, actor); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_click_action_set_enabled (ClutterActorMeta *meta, | ||||
|                                   gboolean          is_enabled) | ||||
| { | ||||
|   ClutterClickAction *click_action = CLUTTER_CLICK_ACTION (meta); | ||||
|   ClutterActorMetaClass *parent_class = | ||||
|     CLUTTER_ACTOR_META_CLASS (clutter_click_action_parent_class); | ||||
|  | ||||
|   if (!is_enabled) | ||||
|     clutter_click_action_release (click_action); | ||||
|  | ||||
|   parent_class->set_enabled (meta, is_enabled); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_click_action_set_property (GObject      *gobject, | ||||
|                                    guint         prop_id, | ||||
|                                    const GValue *value, | ||||
|                                    GParamSpec   *pspec) | ||||
| { | ||||
|   ClutterClickActionPrivate *priv = | ||||
|     clutter_click_action_get_instance_private (CLUTTER_CLICK_ACTION (gobject)); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_LONG_PRESS_DURATION: | ||||
|       priv->long_press_duration = g_value_get_int (value); | ||||
|       break; | ||||
|  | ||||
|     case PROP_LONG_PRESS_THRESHOLD: | ||||
|       priv->long_press_threshold = g_value_get_int (value); | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_click_action_get_property (GObject    *gobject, | ||||
|                                    guint       prop_id, | ||||
|                                    GValue     *value, | ||||
|                                    GParamSpec *pspec) | ||||
| { | ||||
|   ClutterClickActionPrivate *priv = | ||||
|     clutter_click_action_get_instance_private (CLUTTER_CLICK_ACTION (gobject)); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_HELD: | ||||
|       g_value_set_boolean (value, priv->is_held); | ||||
|       break; | ||||
|  | ||||
|     case PROP_PRESSED: | ||||
|       g_value_set_boolean (value, priv->is_pressed); | ||||
|       break; | ||||
|  | ||||
|     case PROP_LONG_PRESS_DURATION: | ||||
|       g_value_set_int (value, priv->long_press_duration); | ||||
|       break; | ||||
|  | ||||
|     case PROP_LONG_PRESS_THRESHOLD: | ||||
|       g_value_set_int (value, priv->long_press_threshold); | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_click_action_dispose (GObject *gobject) | ||||
| { | ||||
|   ClutterClickActionPrivate *priv = | ||||
|     clutter_click_action_get_instance_private (CLUTTER_CLICK_ACTION (gobject)); | ||||
|  | ||||
|   g_clear_handle_id (&priv->long_press_id, g_source_remove); | ||||
|  | ||||
|   G_OBJECT_CLASS (clutter_click_action_parent_class)->dispose (gobject); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_click_action_class_init (ClutterClickActionClass *klass) | ||||
| { | ||||
|   GObjectClass *gobject_class = G_OBJECT_CLASS (klass); | ||||
|   ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass); | ||||
|   ClutterActionClass *action_class = CLUTTER_ACTION_CLASS (klass); | ||||
|  | ||||
|   action_class->handle_event = clutter_click_action_handle_event; | ||||
|   action_class->sequence_cancelled = clutter_click_action_sequence_cancelled; | ||||
|  | ||||
|   meta_class->set_actor = clutter_click_action_set_actor; | ||||
|   meta_class->set_enabled = clutter_click_action_set_enabled; | ||||
|  | ||||
|   gobject_class->dispose = clutter_click_action_dispose; | ||||
|   gobject_class->set_property = clutter_click_action_set_property; | ||||
|   gobject_class->get_property = clutter_click_action_get_property; | ||||
|  | ||||
|   /** | ||||
|    * ClutterClickAction:pressed: | ||||
|    * | ||||
|    * Whether the clickable actor should be in "pressed" state | ||||
|    */ | ||||
|   obj_props[PROP_PRESSED] = | ||||
|     g_param_spec_boolean ("pressed", NULL, NULL, | ||||
|                           FALSE, | ||||
|                           G_PARAM_READABLE | | ||||
|                           G_PARAM_STATIC_STRINGS); | ||||
|  | ||||
|   /** | ||||
|    * ClutterClickAction:held: | ||||
|    * | ||||
|    * Whether the clickable actor has the pointer grabbed | ||||
|    */ | ||||
|   obj_props[PROP_HELD] = | ||||
|     g_param_spec_boolean ("held", NULL, NULL, | ||||
|                           FALSE, | ||||
|                           G_PARAM_READABLE | | ||||
|                           G_PARAM_STATIC_STRINGS); | ||||
|  | ||||
|   /** | ||||
|    * ClutterClickAction:long-press-duration: | ||||
|    * | ||||
|    * The minimum duration of a press for it to be recognized as a long | ||||
|    * press gesture, in milliseconds. | ||||
|    * | ||||
|    * A value of -1 will make the #ClutterClickAction use the value of | ||||
|    * the [property@Settings:long-press-duration] property. | ||||
|    */ | ||||
|   obj_props[PROP_LONG_PRESS_DURATION] = | ||||
|     g_param_spec_int ("long-press-duration", NULL, NULL, | ||||
|                       -1, G_MAXINT, | ||||
|                       -1, | ||||
|                       G_PARAM_READWRITE | | ||||
|                       G_PARAM_STATIC_STRINGS); | ||||
|  | ||||
|   /** | ||||
|    * ClutterClickAction:long-press-threshold: | ||||
|    * | ||||
|    * The maximum allowed distance that can be covered (on both axes) before | ||||
|    * a long press gesture is cancelled, in pixels. | ||||
|    * | ||||
|    * A value of -1 will make the #ClutterClickAction use the value of | ||||
|    * the [property@Settings:dnd-drag-threshold] property. | ||||
|    */ | ||||
|   obj_props[PROP_LONG_PRESS_THRESHOLD] = | ||||
|     g_param_spec_int ("long-press-threshold", NULL, NULL, | ||||
|                       -1, G_MAXINT, | ||||
|                       -1, | ||||
|                       G_PARAM_READWRITE | | ||||
|                       G_PARAM_STATIC_STRINGS); | ||||
|  | ||||
|   g_object_class_install_properties (gobject_class, | ||||
|                                      PROP_LAST, | ||||
|                                      obj_props); | ||||
|  | ||||
|   /** | ||||
|    * ClutterClickAction::clicked: | ||||
|    * @action: the #ClutterClickAction that emitted the signal | ||||
|    * @actor: the #ClutterActor attached to the @action | ||||
|    * | ||||
|    * The signal is emitted when the [class@Actor] to which | ||||
|    * a #ClutterClickAction has been applied should respond to a | ||||
|    * pointer button press and release events | ||||
|    */ | ||||
|   click_signals[CLICKED] = | ||||
|     g_signal_new (I_("clicked"), | ||||
|                   G_TYPE_FROM_CLASS (klass), | ||||
|                   G_SIGNAL_RUN_LAST, | ||||
|                   G_STRUCT_OFFSET (ClutterClickActionClass, clicked), | ||||
|                   NULL, NULL, NULL, | ||||
|                   G_TYPE_NONE, 1, | ||||
|                   CLUTTER_TYPE_ACTOR); | ||||
|  | ||||
|   /** | ||||
|    * ClutterClickAction::long-press: | ||||
|    * @action: the #ClutterClickAction that emitted the signal | ||||
|    * @actor: the #ClutterActor attached to the @action | ||||
|    * @state: the long press state | ||||
|    * | ||||
|    * The signal is emitted during the long press gesture | ||||
|    * handling. | ||||
|    * | ||||
|    * This signal can be emitted multiple times with different states. | ||||
|    * | ||||
|    * The %CLUTTER_LONG_PRESS_QUERY state will be emitted on button presses, | ||||
|    * and its return value will determine whether the long press handling | ||||
|    * should be initiated. If the signal handlers will return %TRUE, the | ||||
|    * %CLUTTER_LONG_PRESS_QUERY state will be followed either by a signal | ||||
|    * emission with the %CLUTTER_LONG_PRESS_ACTIVATE state if the long press | ||||
|    * constraints were respected, or by a signal emission with the | ||||
|    * %CLUTTER_LONG_PRESS_CANCEL state if the long press was cancelled. | ||||
|    * | ||||
|    * It is possible to forcibly cancel a long press detection using | ||||
|    * [method@ClickAction.release]. | ||||
|    * | ||||
|    * Return value: Only the %CLUTTER_LONG_PRESS_QUERY state uses the | ||||
|    *   returned value of the handler; other states will ignore it | ||||
|    */ | ||||
|   click_signals[LONG_PRESS] = | ||||
|     g_signal_new (I_("long-press"), | ||||
|                   G_TYPE_FROM_CLASS (klass), | ||||
|                   G_SIGNAL_RUN_LAST, | ||||
|                   G_STRUCT_OFFSET (ClutterClickActionClass, long_press), | ||||
|                   NULL, NULL, | ||||
|                   _clutter_marshal_BOOLEAN__OBJECT_ENUM, | ||||
|                   G_TYPE_BOOLEAN, 2, | ||||
|                   CLUTTER_TYPE_ACTOR, | ||||
|                   CLUTTER_TYPE_LONG_PRESS_STATE); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_click_action_init (ClutterClickAction *self) | ||||
| { | ||||
|   ClutterClickActionPrivate *priv = | ||||
|     clutter_click_action_get_instance_private (self); | ||||
|  | ||||
|   priv->long_press_threshold = -1; | ||||
|   priv->long_press_duration = -1; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_click_action_new: | ||||
|  * | ||||
|  * Creates a new #ClutterClickAction instance | ||||
|  * | ||||
|  * Return value: the newly created #ClutterClickAction | ||||
|  */ | ||||
| ClutterAction * | ||||
| clutter_click_action_new (void) | ||||
| { | ||||
|   return g_object_new (CLUTTER_TYPE_CLICK_ACTION, NULL); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_click_action_release: | ||||
|  * @action: a #ClutterClickAction | ||||
|  * | ||||
|  * Emulates a release of the pointer button, which ungrabs the pointer | ||||
|  * and unsets the [property@ClickAction:pressed] state. | ||||
|  * | ||||
|  * This function will also cancel the long press gesture if one was | ||||
|  * initiated. | ||||
|  * | ||||
|  * This function is useful to break a grab, for instance after a certain | ||||
|  * amount of time has passed. | ||||
|  */ | ||||
| void | ||||
| clutter_click_action_release (ClutterClickAction *action) | ||||
| { | ||||
|   ClutterClickActionPrivate *priv; | ||||
|  | ||||
|   g_return_if_fail (CLUTTER_IS_CLICK_ACTION (action)); | ||||
|  | ||||
|   priv = clutter_click_action_get_instance_private (action); | ||||
|  | ||||
|   if (!priv->is_held) | ||||
|     return; | ||||
|  | ||||
|   click_action_cancel_long_press (action); | ||||
|   click_action_set_held (action, FALSE); | ||||
|   click_action_set_pressed (action, FALSE); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_click_action_get_button: | ||||
|  * @action: a #ClutterClickAction | ||||
|  * | ||||
|  * Retrieves the button that was pressed. | ||||
|  * | ||||
|  * Return value: the button value | ||||
|  */ | ||||
| guint | ||||
| clutter_click_action_get_button (ClutterClickAction *action) | ||||
| { | ||||
|   ClutterClickActionPrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_CLICK_ACTION (action), 0); | ||||
|  | ||||
|   priv = clutter_click_action_get_instance_private (action); | ||||
|  | ||||
|   return priv->press_button; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_click_action_get_state: | ||||
|  * @action: a #ClutterClickAction | ||||
|  * | ||||
|  * Retrieves the modifier state of the click action. | ||||
|  * | ||||
|  * Return value: the modifier state parameter, or 0 | ||||
|  */ | ||||
| ClutterModifierType | ||||
| clutter_click_action_get_state (ClutterClickAction *action) | ||||
| { | ||||
|   ClutterClickActionPrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_CLICK_ACTION (action), 0); | ||||
|  | ||||
|   priv = clutter_click_action_get_instance_private (action); | ||||
|  | ||||
|   return priv->modifier_state; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_click_action_get_coords: | ||||
|  * @action: a #ClutterClickAction | ||||
|  * @press_x: (out): return location for the X coordinate, or %NULL | ||||
|  * @press_y: (out): return location for the Y coordinate, or %NULL | ||||
|  * | ||||
|  * Retrieves the screen coordinates of the button press. | ||||
|  */ | ||||
| void | ||||
| 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 = priv->press_x; | ||||
|  | ||||
|   if (press_y != NULL) | ||||
|     *press_y = priv->press_y; | ||||
| } | ||||
| @@ -1,84 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2010  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> | ||||
|  * | ||||
|  * Inspired by the StClickable class in GNOME Shell, written by: | ||||
|  *   Colin Walters <walters@verbum.org> | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <clutter/clutter.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include "clutter/clutter-action.h" | ||||
| #include "clutter/clutter-event.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CLUTTER_TYPE_CLICK_ACTION (clutter_click_action_get_type ()) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_DERIVABLE_TYPE (ClutterClickAction, clutter_click_action, | ||||
|                           CLUTTER, CLICK_ACTION, ClutterAction); | ||||
|  | ||||
| typedef struct _ClutterClickActionPrivate ClutterClickActionPrivate; | ||||
|  | ||||
| /** | ||||
|  * ClutterClickActionClass: | ||||
|  * @clicked: class handler for the #ClutterClickAction::clicked signal | ||||
|  * @long_press: class handler for the #ClutterClickAction::long-press signal | ||||
|  * | ||||
|  * The #ClutterClickActionClass structure | ||||
|  * contains only private data | ||||
|  */ | ||||
| struct _ClutterClickActionClass | ||||
| { | ||||
|   /*< private >*/ | ||||
|   ClutterActionClass parent_class; | ||||
|  | ||||
|   /*< public >*/ | ||||
|   void     (* clicked)    (ClutterClickAction    *action, | ||||
|                            ClutterActor          *actor); | ||||
|  | ||||
|   gboolean (* long_press) (ClutterClickAction    *action, | ||||
|                            ClutterActor          *actor, | ||||
|                            ClutterLongPressState  state); | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterAction *        clutter_click_action_new        (void); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| guint                  clutter_click_action_get_button (ClutterClickAction *action); | ||||
| CLUTTER_EXPORT | ||||
| ClutterModifierType    clutter_click_action_get_state  (ClutterClickAction *action); | ||||
| CLUTTER_EXPORT | ||||
| void                   clutter_click_action_get_coords (ClutterClickAction *action, | ||||
|                                                         gfloat             *press_x, | ||||
|                                                         gfloat             *press_y); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void                   clutter_click_action_release    (ClutterClickAction *action); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,467 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2008  Intel Corporation. | ||||
|  * | ||||
|  * Authored By: Robert Bragg <robert@linux.intel.com> | ||||
|  * | ||||
|  * 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/>. | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * ClutterClone: | ||||
|  *  | ||||
|  * An actor that displays a clone of a source actor | ||||
|  * | ||||
|  * #ClutterClone is a [class@Clutter.Actor] which draws with the paint | ||||
|  * function of another actor, scaled to fit its own allocation. | ||||
|  * | ||||
|  * #ClutterClone can be used to efficiently clone any other actor. | ||||
|  * | ||||
|  * #ClutterClone does not require the presence of support for FBOs | ||||
|  * in the underlying GL or GLES implementation. | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "clutter/clutter-actor-private.h" | ||||
| #include "clutter/clutter-clone.h" | ||||
| #include "clutter/clutter-debug.h" | ||||
| #include "clutter/clutter-main.h" | ||||
| #include "clutter/clutter-paint-volume-private.h" | ||||
| #include "clutter/clutter-private.h" | ||||
|  | ||||
| #include "cogl/cogl.h" | ||||
|  | ||||
| typedef struct _ClutterClonePrivate | ||||
| { | ||||
|   ClutterActor *clone_source; | ||||
|   float x_scale, y_scale; | ||||
|  | ||||
|   gulong source_destroy_id; | ||||
| } ClutterClonePrivate; | ||||
|  | ||||
| G_DEFINE_TYPE_WITH_PRIVATE (ClutterClone, clutter_clone, CLUTTER_TYPE_ACTOR) | ||||
|  | ||||
| enum | ||||
| { | ||||
|   PROP_0, | ||||
|  | ||||
|   PROP_SOURCE, | ||||
|  | ||||
|   PROP_LAST | ||||
| }; | ||||
|  | ||||
| static GParamSpec *obj_props[PROP_LAST]; | ||||
|  | ||||
| static void clutter_clone_set_source_internal (ClutterClone *clone, | ||||
| 					       ClutterActor *source); | ||||
| static void | ||||
| clutter_clone_get_preferred_width (ClutterActor *self, | ||||
|                                    gfloat        for_height, | ||||
|                                    gfloat       *min_width_p, | ||||
|                                    gfloat       *natural_width_p) | ||||
| { | ||||
|   ClutterClonePrivate *priv = | ||||
|     clutter_clone_get_instance_private (CLUTTER_CLONE (self)); | ||||
|   ClutterActor *clone_source = priv->clone_source; | ||||
|  | ||||
|   if (clone_source == NULL) | ||||
|     { | ||||
|       if (min_width_p) | ||||
|         *min_width_p = 0; | ||||
|  | ||||
|       if (natural_width_p) | ||||
|         *natural_width_p = 0; | ||||
|     } | ||||
|   else | ||||
|     clutter_actor_get_preferred_width (clone_source, | ||||
|                                        for_height, | ||||
|                                        min_width_p, | ||||
|                                        natural_width_p); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_clone_get_preferred_height (ClutterActor *self, | ||||
|                                     gfloat        for_width, | ||||
|                                     gfloat       *min_height_p, | ||||
|                                     gfloat       *natural_height_p) | ||||
| { | ||||
|   ClutterClonePrivate *priv = | ||||
|     clutter_clone_get_instance_private (CLUTTER_CLONE (self)); | ||||
|   ClutterActor *clone_source = priv->clone_source; | ||||
|  | ||||
|   if (clone_source == NULL) | ||||
|     { | ||||
|       if (min_height_p) | ||||
|         *min_height_p = 0; | ||||
|  | ||||
|       if (natural_height_p) | ||||
|         *natural_height_p = 0; | ||||
|     } | ||||
|   else | ||||
|     clutter_actor_get_preferred_height (clone_source, | ||||
|                                         for_width, | ||||
|                                         min_height_p, | ||||
|                                         natural_height_p); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_clone_apply_transform (ClutterActor      *self, | ||||
|                                graphene_matrix_t *matrix) | ||||
| { | ||||
|   ClutterClonePrivate *priv = | ||||
|     clutter_clone_get_instance_private (CLUTTER_CLONE (self)); | ||||
|  | ||||
|   if (priv->clone_source) | ||||
|     graphene_matrix_scale (matrix, priv->x_scale, priv->y_scale, 1.f); | ||||
|  | ||||
|   CLUTTER_ACTOR_CLASS (clutter_clone_parent_class)->apply_transform (self, | ||||
|                                                                      matrix); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_clone_paint (ClutterActor        *actor, | ||||
|                      ClutterPaintContext *paint_context) | ||||
| { | ||||
|   ClutterClone *self = CLUTTER_CLONE (actor); | ||||
|   ClutterClonePrivate *priv = clutter_clone_get_instance_private (self); | ||||
|   gboolean was_unmapped = FALSE; | ||||
|  | ||||
|   if (priv->clone_source == NULL) | ||||
|     return; | ||||
|  | ||||
|   CLUTTER_NOTE (PAINT, "painting clone actor '%s'", | ||||
|                 _clutter_actor_get_debug_name (actor)); | ||||
|  | ||||
|   /* The final bits of magic: | ||||
|    * - We need to override the paint opacity of the actor with our own | ||||
|    *   opacity. | ||||
|    * - We need to inform the actor that it's in a clone paint (for the function | ||||
|    *   clutter_actor_is_in_clone_paint()) | ||||
|    * - We need to stop clutter_actor_paint applying the model view matrix of | ||||
|    *   the clone source actor. | ||||
|    */ | ||||
|   _clutter_actor_set_in_clone_paint (priv->clone_source, TRUE); | ||||
|   clutter_actor_set_opacity_override (priv->clone_source, | ||||
|                                       clutter_actor_get_paint_opacity (actor)); | ||||
|   _clutter_actor_set_enable_model_view_transform (priv->clone_source, FALSE); | ||||
|  | ||||
|   if (!clutter_actor_is_mapped (priv->clone_source)) | ||||
|     { | ||||
|       _clutter_actor_set_enable_paint_unmapped (priv->clone_source, TRUE); | ||||
|       was_unmapped = TRUE; | ||||
|     } | ||||
|  | ||||
|   /* If the source isn't ultimately parented to a toplevel, it can't be | ||||
|    * realized or painted. | ||||
|    */ | ||||
|   if (clutter_actor_is_realized (priv->clone_source)) | ||||
|     { | ||||
|       _clutter_actor_push_clone_paint (); | ||||
|       clutter_actor_paint (priv->clone_source, paint_context); | ||||
|       _clutter_actor_pop_clone_paint (); | ||||
|     } | ||||
|  | ||||
|   if (was_unmapped) | ||||
|     _clutter_actor_set_enable_paint_unmapped (priv->clone_source, FALSE); | ||||
|  | ||||
|   _clutter_actor_set_enable_model_view_transform (priv->clone_source, TRUE); | ||||
|   clutter_actor_set_opacity_override (priv->clone_source, -1); | ||||
|   _clutter_actor_set_in_clone_paint (priv->clone_source, FALSE); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| clutter_clone_get_paint_volume (ClutterActor       *actor, | ||||
|                                 ClutterPaintVolume *volume) | ||||
| { | ||||
|   ClutterClonePrivate *priv = | ||||
|     clutter_clone_get_instance_private (CLUTTER_CLONE (actor)); | ||||
|   const ClutterPaintVolume *source_volume; | ||||
|  | ||||
|   /* if the source is not set the paint volume is defined to be empty */ | ||||
|   if (priv->clone_source == NULL) | ||||
|     return TRUE; | ||||
|  | ||||
|   /* query the volume of the source actor and simply masquerade it as | ||||
|    * the clones volume... */ | ||||
|   source_volume = clutter_actor_get_paint_volume (priv->clone_source); | ||||
|   if (source_volume == NULL) | ||||
|     return FALSE; | ||||
|  | ||||
|   _clutter_paint_volume_set_from_volume (volume, source_volume); | ||||
|   _clutter_paint_volume_set_reference_actor (volume, actor); | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| clutter_clone_has_overlaps (ClutterActor *actor) | ||||
| { | ||||
|   ClutterClonePrivate *priv = | ||||
|     clutter_clone_get_instance_private (CLUTTER_CLONE (actor)); | ||||
|  | ||||
|   /* The clone has overlaps iff the source has overlaps */ | ||||
|  | ||||
|   if (priv->clone_source == NULL) | ||||
|     return FALSE; | ||||
|  | ||||
|   return clutter_actor_has_overlaps (priv->clone_source); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_clone_allocate (ClutterActor           *self, | ||||
|                         const ClutterActorBox  *box) | ||||
| { | ||||
|   ClutterClonePrivate *priv = | ||||
|     clutter_clone_get_instance_private (CLUTTER_CLONE (self)); | ||||
|   ClutterActorClass *parent_class; | ||||
|   ClutterActorBox source_box; | ||||
|   float x_scale, y_scale; | ||||
|  | ||||
|   /* chain up */ | ||||
|   parent_class = CLUTTER_ACTOR_CLASS (clutter_clone_parent_class); | ||||
|   parent_class->allocate (self, box); | ||||
|  | ||||
|   if (priv->clone_source == NULL) | ||||
|     return; | ||||
|  | ||||
|   /* ClutterActor delays allocating until the actor is shown; however | ||||
|    * we cannot paint it correctly in that case, so force an allocation. | ||||
|    */ | ||||
|   if (clutter_actor_get_parent (priv->clone_source) != NULL && | ||||
|       !clutter_actor_has_allocation (priv->clone_source)) | ||||
|     { | ||||
|       float x = 0.f; | ||||
|       float y = 0.f; | ||||
|  | ||||
|       clutter_actor_get_fixed_position (priv->clone_source, &x, &y); | ||||
|       clutter_actor_allocate_preferred_size (priv->clone_source, x, y); | ||||
|     } | ||||
|  | ||||
|   clutter_actor_get_allocation_box (priv->clone_source, &source_box); | ||||
|  | ||||
|   /* We need to scale what the clone-source actor paints to fill our own | ||||
|    * allocation... | ||||
|    */ | ||||
|   x_scale = clutter_actor_box_get_width (box) | ||||
|           / clutter_actor_box_get_width (&source_box); | ||||
|   y_scale = clutter_actor_box_get_height (box) | ||||
|           / clutter_actor_box_get_height (&source_box); | ||||
|  | ||||
|   if (!G_APPROX_VALUE (priv->x_scale, x_scale, FLT_EPSILON) || | ||||
|       !G_APPROX_VALUE (priv->y_scale, y_scale, FLT_EPSILON)) | ||||
|     { | ||||
|       priv->x_scale = x_scale; | ||||
|       priv->y_scale = y_scale; | ||||
|       clutter_actor_invalidate_transform (CLUTTER_ACTOR (self)); | ||||
|     } | ||||
|  | ||||
| #if 0 | ||||
|   /* XXX - this is wrong: ClutterClone cannot clone unparented | ||||
|    * actors, as it will break all invariants | ||||
|    */ | ||||
|  | ||||
|   /* we act like a "foster parent" for the source we are cloning; | ||||
|    * if the source has not been parented we have to force an | ||||
|    * allocation on it, so that we can paint it correctly from | ||||
|    * within our paint() implementation. since the actor does not | ||||
|    * have a parent, and thus it won't be painted by the usual | ||||
|    * 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); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_clone_set_property (GObject      *gobject, | ||||
|                             guint         prop_id, | ||||
|                             const GValue *value, | ||||
|                             GParamSpec   *pspec) | ||||
| { | ||||
|   ClutterClone *self = CLUTTER_CLONE (gobject); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_SOURCE: | ||||
|       clutter_clone_set_source (self, g_value_get_object (value)); | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); | ||||
|       break; | ||||
|   } | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_clone_get_property (GObject    *gobject, | ||||
|                             guint       prop_id, | ||||
|                             GValue     *value, | ||||
|                             GParamSpec *pspec) | ||||
| { | ||||
|   ClutterClonePrivate *priv = | ||||
|     clutter_clone_get_instance_private (CLUTTER_CLONE (gobject)); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_SOURCE: | ||||
|       g_value_set_object (value, priv->clone_source); | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_clone_dispose (GObject *gobject) | ||||
| { | ||||
|   clutter_clone_set_source_internal (CLUTTER_CLONE (gobject), NULL); | ||||
|  | ||||
|   G_OBJECT_CLASS (clutter_clone_parent_class)->dispose (gobject); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_clone_class_init (ClutterCloneClass *klass) | ||||
| { | ||||
|   GObjectClass *gobject_class = G_OBJECT_CLASS (klass); | ||||
|   ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); | ||||
|  | ||||
|   actor_class->apply_transform = clutter_clone_apply_transform; | ||||
|   actor_class->paint = clutter_clone_paint; | ||||
|   actor_class->get_paint_volume = clutter_clone_get_paint_volume; | ||||
|   actor_class->get_preferred_width = clutter_clone_get_preferred_width; | ||||
|   actor_class->get_preferred_height = clutter_clone_get_preferred_height; | ||||
|   actor_class->allocate = clutter_clone_allocate; | ||||
|   actor_class->has_overlaps = clutter_clone_has_overlaps; | ||||
|  | ||||
|   gobject_class->dispose = clutter_clone_dispose; | ||||
|   gobject_class->set_property = clutter_clone_set_property; | ||||
|   gobject_class->get_property = clutter_clone_get_property; | ||||
|  | ||||
|   /** | ||||
|    * ClutterClone:source: | ||||
|    * | ||||
|    * This property specifies the source actor being cloned. | ||||
|    */ | ||||
|   obj_props[PROP_SOURCE] = | ||||
|     g_param_spec_object ("source", NULL, NULL, | ||||
|                          CLUTTER_TYPE_ACTOR, | ||||
|                          G_PARAM_CONSTRUCT | | ||||
|                          G_PARAM_READWRITE | | ||||
|                          G_PARAM_STATIC_STRINGS); | ||||
|  | ||||
|   g_object_class_install_properties (gobject_class, PROP_LAST, obj_props); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_clone_init (ClutterClone *self) | ||||
| { | ||||
|   ClutterClonePrivate *priv = clutter_clone_get_instance_private (self); | ||||
|  | ||||
|   priv->x_scale = 1.f; | ||||
|   priv->y_scale = 1.f; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_clone_new: | ||||
|  * @source: a #ClutterActor, or %NULL | ||||
|  * | ||||
|  * Creates a new #ClutterActor which clones @source/ | ||||
|  * | ||||
|  * Return value: the newly created #ClutterClone | ||||
|  */ | ||||
| ClutterActor * | ||||
| clutter_clone_new (ClutterActor *source) | ||||
| { | ||||
|   return g_object_new (CLUTTER_TYPE_CLONE, "source", source,  NULL); | ||||
| } | ||||
|  | ||||
| static void | ||||
| on_source_destroyed (ClutterActor *source, | ||||
|                      ClutterClone *self) | ||||
| { | ||||
|   clutter_clone_set_source_internal (self, NULL); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_clone_set_source_internal (ClutterClone *self, | ||||
| 				   ClutterActor *source) | ||||
| { | ||||
|   ClutterClonePrivate *priv = clutter_clone_get_instance_private (self); | ||||
|  | ||||
|   if (priv->clone_source == source) | ||||
|     return; | ||||
|  | ||||
|   if (priv->clone_source != NULL) | ||||
|     { | ||||
|       g_clear_signal_handler (&priv->source_destroy_id, priv->clone_source); | ||||
|       _clutter_actor_detach_clone (priv->clone_source, CLUTTER_ACTOR (self)); | ||||
|       g_object_unref (priv->clone_source); | ||||
|       priv->clone_source = NULL; | ||||
|     } | ||||
|  | ||||
|   if (source != NULL) | ||||
|     { | ||||
|       priv->clone_source = g_object_ref (source); | ||||
|       _clutter_actor_attach_clone (priv->clone_source, CLUTTER_ACTOR (self)); | ||||
|       priv->source_destroy_id = g_signal_connect (priv->clone_source, "destroy", | ||||
|                                                   G_CALLBACK (on_source_destroyed), self); | ||||
|     } | ||||
|  | ||||
|   g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_SOURCE]); | ||||
|  | ||||
|   clutter_actor_queue_relayout (CLUTTER_ACTOR (self)); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_clone_set_source: | ||||
|  * @self: a #ClutterClone | ||||
|  * @source: (allow-none): a #ClutterActor, or %NULL | ||||
|  * | ||||
|  * Sets @source as the source actor to be cloned by @self. | ||||
|  */ | ||||
| void | ||||
| clutter_clone_set_source (ClutterClone *self, | ||||
|                           ClutterActor *source) | ||||
| { | ||||
|   g_return_if_fail (CLUTTER_IS_CLONE (self)); | ||||
|   g_return_if_fail (source == NULL || CLUTTER_IS_ACTOR (source)); | ||||
|  | ||||
|   clutter_clone_set_source_internal (self, source); | ||||
|   clutter_actor_queue_relayout (CLUTTER_ACTOR (self)); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_clone_get_source: | ||||
|  * @self: a #ClutterClone | ||||
|  * | ||||
|  * Retrieves the source #ClutterActor being cloned by @self. | ||||
|  * | ||||
|  * Return value: (transfer none): the actor source for the clone | ||||
|  */ | ||||
| ClutterActor * | ||||
| clutter_clone_get_source (ClutterClone *self) | ||||
| { | ||||
|   ClutterClonePrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_CLONE (self), NULL); | ||||
|  | ||||
|   priv = clutter_clone_get_instance_private (self); | ||||
|   return priv->clone_source; | ||||
| } | ||||
| @@ -1,61 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2008  Intel Corporation. | ||||
|  * | ||||
|  * Authored By: Robert Bragg <robert@linux.intel.com> | ||||
|  * | ||||
|  * 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/>. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <clutter/clutter.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include "clutter/clutter-actor.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CLUTTER_TYPE_CLONE              (clutter_clone_get_type ()) | ||||
|  | ||||
| /** | ||||
|  * ClutterCloneClass: | ||||
|  * | ||||
|  * The #ClutterCloneClass structure contains only private data | ||||
|  */ | ||||
| struct _ClutterCloneClass | ||||
| { | ||||
|   /*< private >*/ | ||||
|   ClutterActorClass parent_class; | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_DERIVABLE_TYPE (ClutterClone, | ||||
|                           clutter_clone, | ||||
|                           CLUTTER, CLONE, | ||||
|                           ClutterActor) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterActor *  clutter_clone_new               (ClutterActor *source); | ||||
| CLUTTER_EXPORT | ||||
| void            clutter_clone_set_source        (ClutterClone *self, | ||||
|                                                  ClutterActor *source); | ||||
| CLUTTER_EXPORT | ||||
| ClutterActor *  clutter_clone_get_source        (ClutterClone *self); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,181 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2022  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: | ||||
|  *   Naveen Kumar <naveen1.kumar@intel.com> | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * ClutterColorState: | ||||
|  * | ||||
|  * Color state of each ClutterActor | ||||
|  * | ||||
|  * The #ClutterColorState class contains the colorspace of each color | ||||
|  * states (e.g. sRGB colorspace). | ||||
|  * | ||||
|  * Each [class@Actor] would own such an object. | ||||
|  * | ||||
|  * A single #ClutterColorState object can be shared by multiple [class@Actor] | ||||
|  * or maybe a separate color state for each [class@Actor] (depending on whether | ||||
|  * #ClutterColorState would be statefull or stateless). | ||||
|  * | ||||
|  * #ClutterColorState, if not set during construction, it will default to sRGB | ||||
|  * color state | ||||
|  * | ||||
|  * The #ClutterColorState would have API to get the colorspace, whether the | ||||
|  * actor content is in pq or not, and things like that | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "clutter/clutter-color-state.h" | ||||
|  | ||||
| #include "clutter/clutter-debug.h" | ||||
| #include "clutter/clutter-enum-types.h" | ||||
| #include "clutter/clutter-private.h" | ||||
|  | ||||
| enum | ||||
| { | ||||
|   PROP_0, | ||||
|  | ||||
|   PROP_COLORSPACE, | ||||
|  | ||||
|   N_PROPS | ||||
| }; | ||||
|  | ||||
| static GParamSpec *obj_props[N_PROPS]; | ||||
|  | ||||
| typedef struct _ClutterColorStatePrivate ClutterColorStatePrivate; | ||||
|  | ||||
| struct _ClutterColorState | ||||
| { | ||||
|   GObject parent_instance; | ||||
| }; | ||||
|  | ||||
| struct _ClutterColorStatePrivate | ||||
| { | ||||
|   ClutterColorspace colorspace; | ||||
| }; | ||||
|  | ||||
| G_DEFINE_TYPE_WITH_PRIVATE (ClutterColorState, | ||||
|                             clutter_color_state, | ||||
|                             G_TYPE_OBJECT) | ||||
|  | ||||
| ClutterColorspace | ||||
| clutter_color_state_get_colorspace (ClutterColorState *color_state) | ||||
| { | ||||
|   ClutterColorStatePrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_COLOR_STATE (color_state), | ||||
|                         CLUTTER_COLORSPACE_UNKNOWN); | ||||
|  | ||||
|   priv = clutter_color_state_get_instance_private (color_state); | ||||
|  | ||||
|   return priv->colorspace; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_color_state_set_property (GObject      *object, | ||||
|                                   guint         prop_id, | ||||
|                                   const GValue *value, | ||||
|                                   GParamSpec   *pspec) | ||||
| { | ||||
|   ClutterColorState *color_state = CLUTTER_COLOR_STATE (object); | ||||
|   ClutterColorStatePrivate *priv; | ||||
|  | ||||
|   priv = clutter_color_state_get_instance_private (color_state); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_COLORSPACE: | ||||
|       priv->colorspace = g_value_get_enum (value); | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_color_state_get_property (GObject    *object, | ||||
|                                   guint       prop_id, | ||||
|                                   GValue     *value, | ||||
|                                   GParamSpec *pspec) | ||||
| { | ||||
|   ClutterColorState *color_state = CLUTTER_COLOR_STATE (object); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_COLORSPACE: | ||||
|       g_value_set_enum (value, | ||||
|                         clutter_color_state_get_colorspace (color_state)); | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_color_state_class_init (ClutterColorStateClass *klass) | ||||
| { | ||||
|   GObjectClass *gobject_class = G_OBJECT_CLASS (klass); | ||||
|  | ||||
|   gobject_class->set_property = clutter_color_state_set_property; | ||||
|   gobject_class->get_property = clutter_color_state_get_property; | ||||
|  | ||||
|   /** | ||||
|    * ClutterColorState:colorspace: | ||||
|    * | ||||
|    * Colorspace information of the each color state, | ||||
|    * defaults to sRGB colorspace | ||||
|    */ | ||||
|   obj_props[PROP_COLORSPACE] = | ||||
|     g_param_spec_enum ("colorspace", NULL, NULL, | ||||
|                        CLUTTER_TYPE_COLORSPACE, | ||||
|                        CLUTTER_COLORSPACE_SRGB, | ||||
|                        G_PARAM_READWRITE | | ||||
|                        G_PARAM_STATIC_STRINGS | | ||||
|                        G_PARAM_CONSTRUCT_ONLY); | ||||
|  | ||||
|   g_object_class_install_properties (gobject_class, N_PROPS, obj_props); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_color_state_init (ClutterColorState *color_state) | ||||
| { | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_color_state_new: | ||||
|  * | ||||
|  * Create a new ClutterColorState object. | ||||
|  * | ||||
|  * Return value: A new ClutterColorState object. | ||||
|  **/ | ||||
| ClutterColorState* | ||||
| clutter_color_state_new (ClutterColorspace colorspace) | ||||
| { | ||||
|   return g_object_new (CLUTTER_TYPE_COLOR_STATE, | ||||
|                        "colorspace", colorspace, | ||||
|                        NULL); | ||||
| } | ||||
| @@ -1,47 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2022  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: | ||||
|  *   Naveen Kumar <naveen1.kumar@intel.com> | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <clutter/clutter.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include "clutter/clutter-types.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CLUTTER_TYPE_COLOR_STATE (clutter_color_state_get_type ()) | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_FINAL_TYPE (ClutterColorState, clutter_color_state, | ||||
|                       CLUTTER, COLOR_STATE, | ||||
|                       GObject) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterColorState * clutter_color_state_new (ClutterColorspace colorspace); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterColorspace clutter_color_state_get_colorspace (ClutterColorState *color_state); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,962 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Authored By Matthew Allum  <mallum@openedhand.com> | ||||
|  * | ||||
|  * Copyright (C) 2006 OpenedHand | ||||
|  * | ||||
|  * 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 "config.h" | ||||
|  | ||||
| #include <math.h> | ||||
|  | ||||
| #include <pango/pango-attributes.h> | ||||
|  | ||||
| #include "clutter/clutter-interval.h" | ||||
| #include "clutter/clutter-main.h" | ||||
| #include "clutter/clutter-color.h" | ||||
| #include "clutter/clutter-private.h" | ||||
| #include "clutter/clutter-debug.h" | ||||
|  | ||||
| /** | ||||
|  * clutter_color_to_hls: | ||||
|  * @color: a #ClutterColor | ||||
|  * @hue: (out): return location for the hue value or %NULL | ||||
|  * @luminance: (out): return location for the luminance value or %NULL | ||||
|  * @saturation: (out): return location for the saturation value or %NULL | ||||
|  * | ||||
|  * Converts @color to the HLS format. | ||||
|  * | ||||
|  * The @hue value is in the 0 .. 360 range. The @luminance and | ||||
|  * @saturation values are in the 0 .. 1 range. | ||||
|  */ | ||||
| void | ||||
| clutter_color_to_hls (const ClutterColor *color, | ||||
| 		      float              *hue, | ||||
| 		      float              *luminance, | ||||
| 		      float              *saturation) | ||||
| { | ||||
|   float red, green, blue; | ||||
|   float min, max, delta; | ||||
|   float h, l, s; | ||||
|    | ||||
|   g_return_if_fail (color != NULL); | ||||
|  | ||||
|   red   = color->red / 255.0; | ||||
|   green = color->green / 255.0; | ||||
|   blue  = color->blue / 255.0; | ||||
|  | ||||
|   if (red > green) | ||||
|     { | ||||
|       if (red > blue) | ||||
| 	max = red; | ||||
|       else | ||||
| 	max = blue; | ||||
|  | ||||
|       if (green < blue) | ||||
| 	min = green; | ||||
|       else | ||||
| 	min = blue; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       if (green > blue) | ||||
| 	max = green; | ||||
|       else | ||||
| 	max = blue; | ||||
|  | ||||
|       if (red < blue) | ||||
| 	min = red; | ||||
|       else | ||||
| 	min = blue; | ||||
|     } | ||||
|  | ||||
|   l = (max + min) / 2; | ||||
|   s = 0; | ||||
|   h = 0; | ||||
|  | ||||
|   if (max != min) | ||||
|     { | ||||
|       if (l <= 0.5) | ||||
| 	s = (max - min) / (max + min); | ||||
|       else | ||||
| 	s = (max - min) / (2.0 - max - min); | ||||
|  | ||||
|       delta = max - min; | ||||
|  | ||||
|       if (red == max) | ||||
| 	h = (green - blue) / delta; | ||||
|       else if (green == max) | ||||
| 	h = 2.0 + (blue - red) / delta; | ||||
|       else if (blue == max) | ||||
| 	h = 4.0 + (red - green) / delta; | ||||
|  | ||||
|       h *= 60; | ||||
|  | ||||
|       if (h < 0) | ||||
| 	h += 360.0; | ||||
|     } | ||||
|  | ||||
|   if (hue) | ||||
|     *hue = h; | ||||
|  | ||||
|   if (luminance) | ||||
|     *luminance = l; | ||||
|  | ||||
|   if (saturation) | ||||
|     *saturation = s; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_color_from_hls: | ||||
|  * @color: (out): return location for a #ClutterColor | ||||
|  * @hue: hue value, in the 0 .. 360 range | ||||
|  * @luminance: luminance value, in the 0 .. 1 range | ||||
|  * @saturation: saturation value, in the 0 .. 1 range | ||||
|  * | ||||
|  * Converts a color expressed in HLS (hue, luminance and saturation) | ||||
|  * values into a #ClutterColor. | ||||
|  */ | ||||
| void | ||||
| clutter_color_from_hls (ClutterColor *color, | ||||
| 			float         hue, | ||||
| 			float         luminance, | ||||
| 			float         saturation) | ||||
| { | ||||
|   float tmp1, tmp2; | ||||
|   float tmp3[3]; | ||||
|   float clr[3]; | ||||
|   int   i; | ||||
|  | ||||
|   hue /= 360.0; | ||||
|  | ||||
|   if (saturation == 0) | ||||
|     { | ||||
|       color->red = color->green = color->blue = (luminance * 255); | ||||
|  | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   if (luminance <= 0.5) | ||||
|     tmp2 = luminance * (1.0 + saturation); | ||||
|   else | ||||
|     tmp2 = luminance + saturation - (luminance * saturation); | ||||
|  | ||||
|   tmp1 = 2.0 * luminance - tmp2; | ||||
|  | ||||
|   tmp3[0] = hue + 1.0 / 3.0; | ||||
|   tmp3[1] = hue; | ||||
|   tmp3[2] = hue - 1.0 / 3.0; | ||||
|  | ||||
|   for (i = 0; i < 3; i++) | ||||
|     { | ||||
|       if (tmp3[i] < 0) | ||||
|         tmp3[i] += 1.0; | ||||
|  | ||||
|       if (tmp3[i] > 1) | ||||
|         tmp3[i] -= 1.0; | ||||
|  | ||||
|       if (6.0 * tmp3[i] < 1.0) | ||||
|         clr[i] = tmp1 + (tmp2 - tmp1) * tmp3[i] * 6.0; | ||||
|       else if (2.0 * tmp3[i] < 1.0) | ||||
|         clr[i] = tmp2; | ||||
|       else if (3.0 * tmp3[i] < 2.0) | ||||
|         clr[i] = (tmp1 + (tmp2 - tmp1) * ((2.0 / 3.0) - tmp3[i]) * 6.0); | ||||
|       else | ||||
|         clr[i] = tmp1; | ||||
|     } | ||||
|  | ||||
|   color->red   = floorf (clr[0] * 255.0 + 0.5); | ||||
|   color->green = floorf (clr[1] * 255.0 + 0.5); | ||||
|   color->blue  = floorf (clr[2] * 255.0 + 0.5); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_color_to_pixel: | ||||
|  * @color: a #ClutterColor | ||||
|  * | ||||
|  * Converts @color into a packed 32 bit integer, containing | ||||
|  * all the four 8 bit channels used by #ClutterColor. | ||||
|  * | ||||
|  * Return value: a packed color | ||||
|  */ | ||||
| guint32 | ||||
| clutter_color_to_pixel (const ClutterColor *color) | ||||
| { | ||||
|   g_return_val_if_fail (color != NULL, 0); | ||||
|    | ||||
|   return (color->alpha       | | ||||
|           color->blue  << 8  | | ||||
|           color->green << 16 | | ||||
|           color->red   << 24); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_color_from_pixel: | ||||
|  * @color: (out caller-allocates): return location for a #ClutterColor | ||||
|  * @pixel: a 32 bit packed integer containing a color | ||||
|  * | ||||
|  * Converts @pixel from the packed representation of a four 8 bit channel | ||||
|  * color to a #ClutterColor. | ||||
|  */ | ||||
| void | ||||
| clutter_color_from_pixel (ClutterColor *color, | ||||
| 			  guint32       pixel) | ||||
| { | ||||
|   g_return_if_fail (color != NULL); | ||||
|  | ||||
|   color->red   =  pixel >> 24; | ||||
|   color->green = (pixel >> 16) & 0xff; | ||||
|   color->blue  = (pixel >> 8)  & 0xff; | ||||
|   color->alpha =  pixel        & 0xff; | ||||
| } | ||||
|  | ||||
| static inline void | ||||
| skip_whitespace (gchar **str) | ||||
| { | ||||
|   while (g_ascii_isspace (**str)) | ||||
|     *str += 1; | ||||
| } | ||||
|  | ||||
| static inline void | ||||
| parse_rgb_value (gchar   *str, | ||||
|                  guint8  *color, | ||||
|                  gchar  **endp) | ||||
| { | ||||
|   gdouble number; | ||||
|   gchar *p; | ||||
|  | ||||
|   skip_whitespace (&str); | ||||
|  | ||||
|   number = g_ascii_strtod (str, endp); | ||||
|  | ||||
|   p = *endp; | ||||
|  | ||||
|   skip_whitespace (&p); | ||||
|  | ||||
|   if (*p == '%') | ||||
|     { | ||||
|       *endp = (gchar *) (p + 1); | ||||
|  | ||||
|       *color = CLAMP (number / 100.0, 0.0, 1.0) * 255; | ||||
|     } | ||||
|   else | ||||
|     *color = CLAMP (number, 0, 255); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| parse_rgba (ClutterColor *color, | ||||
|             gchar        *str, | ||||
|             gboolean      has_alpha) | ||||
| { | ||||
|   skip_whitespace (&str); | ||||
|  | ||||
|   if (*str != '(') | ||||
|     return FALSE; | ||||
|  | ||||
|   str += 1; | ||||
|  | ||||
|   /* red */ | ||||
|   parse_rgb_value (str, &color->red, &str); | ||||
|   skip_whitespace (&str); | ||||
|   if (*str != ',') | ||||
|     return FALSE; | ||||
|  | ||||
|   str += 1; | ||||
|  | ||||
|   /* green */ | ||||
|   parse_rgb_value (str, &color->green, &str); | ||||
|   skip_whitespace (&str); | ||||
|   if (*str != ',') | ||||
|     return FALSE; | ||||
|  | ||||
|   str += 1; | ||||
|  | ||||
|   /* blue */ | ||||
|   parse_rgb_value (str, &color->blue, &str); | ||||
|   skip_whitespace (&str); | ||||
|  | ||||
|   /* alpha (optional); since the alpha channel value can only | ||||
|    * be between 0 and 1 we don't use the parse_rgb_value() | ||||
|    * function | ||||
|    */ | ||||
|   if (has_alpha) | ||||
|     { | ||||
|       gdouble number; | ||||
|  | ||||
|       if (*str != ',') | ||||
|         return FALSE; | ||||
|  | ||||
|       str += 1; | ||||
|  | ||||
|       skip_whitespace (&str); | ||||
|       number = g_ascii_strtod (str, &str); | ||||
|  | ||||
|       color->alpha = CLAMP (number * 255.0, 0, 255); | ||||
|     } | ||||
|   else | ||||
|     color->alpha = 255; | ||||
|  | ||||
|   skip_whitespace (&str); | ||||
|   if (*str != ')') | ||||
|     return FALSE; | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| parse_hsla (ClutterColor *color, | ||||
|             gchar        *str, | ||||
|             gboolean      has_alpha) | ||||
| { | ||||
|   gdouble number; | ||||
|   gdouble h, l, s; | ||||
|  | ||||
|   skip_whitespace (&str); | ||||
|  | ||||
|   if (*str != '(') | ||||
|     return FALSE; | ||||
|  | ||||
|   str += 1; | ||||
|  | ||||
|   /* hue */ | ||||
|   skip_whitespace (&str); | ||||
|   /* we don't do any angle normalization here because | ||||
|    * clutter_color_from_hls() will do it for us | ||||
|    */ | ||||
|   number = g_ascii_strtod (str, &str); | ||||
|   skip_whitespace (&str); | ||||
|   if (*str != ',') | ||||
|     return FALSE; | ||||
|  | ||||
|   h = number; | ||||
|  | ||||
|   str += 1; | ||||
|  | ||||
|   /* saturation */ | ||||
|   skip_whitespace (&str); | ||||
|   number = g_ascii_strtod (str, &str); | ||||
|   skip_whitespace (&str); | ||||
|   if (*str != '%') | ||||
|     return FALSE; | ||||
|  | ||||
|   str += 1; | ||||
|  | ||||
|   s = CLAMP (number / 100.0, 0.0, 1.0); | ||||
|   skip_whitespace (&str); | ||||
|   if (*str != ',') | ||||
|     return FALSE; | ||||
|  | ||||
|   str += 1; | ||||
|  | ||||
|   /* luminance */ | ||||
|   skip_whitespace (&str); | ||||
|   number = g_ascii_strtod (str, &str); | ||||
|   skip_whitespace (&str); | ||||
|   if (*str != '%') | ||||
|     return FALSE; | ||||
|  | ||||
|   str += 1; | ||||
|  | ||||
|   l = CLAMP (number / 100.0, 0.0, 1.0); | ||||
|   skip_whitespace (&str); | ||||
|  | ||||
|   /* alpha (optional); since the alpha channel value can only | ||||
|    * be between 0 and 1 we don't use the parse_rgb_value() | ||||
|    * function | ||||
|    */ | ||||
|   if (has_alpha) | ||||
|     { | ||||
|       if (*str != ',') | ||||
|         return FALSE; | ||||
|  | ||||
|       str += 1; | ||||
|  | ||||
|       skip_whitespace (&str); | ||||
|       number = g_ascii_strtod (str, &str); | ||||
|  | ||||
|       color->alpha = CLAMP (number * 255.0, 0, 255); | ||||
|     } | ||||
|   else | ||||
|     color->alpha = 255; | ||||
|  | ||||
|   skip_whitespace (&str); | ||||
|   if (*str != ')') | ||||
|     return FALSE; | ||||
|  | ||||
|   clutter_color_from_hls (color, h, l, s); | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_color_from_string: | ||||
|  * @color: (out caller-allocates): return location for a #ClutterColor | ||||
|  * @str: a string specifying a color | ||||
|  * | ||||
|  * Parses a string definition of a color, filling the #ClutterColor.red, | ||||
|  * #ClutterColor.green, #ClutterColor.blue and #ClutterColor.alpha fields  | ||||
|  * of @color. | ||||
|  * | ||||
|  * The @color is not allocated. | ||||
|  * | ||||
|  * The format of @str can be either one of: | ||||
|  * | ||||
|  *   - a standard name (as taken from the X11 rgb.txt file) | ||||
|  *   - an hexadecimal value in the form: `#rgb`, `#rrggbb`, `#rgba`, or `#rrggbbaa` | ||||
|  *   - a RGB color in the form: `rgb(r, g, b)` | ||||
|  *   - a RGB color in the form: `rgba(r, g, b, a)` | ||||
|  *   - a HSL color in the form: `hsl(h, s, l)` | ||||
|  *    -a HSL color in the form: `hsla(h, s, l, a)` | ||||
|  * | ||||
|  * where 'r', 'g', 'b' and 'a' are (respectively) the red, green, blue color | ||||
|  * intensities and the opacity. The 'h', 's' and 'l' are (respectively) the | ||||
|  * hue, saturation and luminance values. | ||||
|  * | ||||
|  * In the rgb() and rgba() formats, the 'r', 'g', and 'b' values are either | ||||
|  * integers between 0 and 255, or percentage values in the range between 0% | ||||
|  * and 100%; the percentages require the '%' character. The 'a' value, if | ||||
|  * specified, can only be a floating point value between 0.0 and 1.0. | ||||
|  * | ||||
|  * In the hls() and hlsa() formats, the 'h' value (hue) is an angle between | ||||
|  * 0 and 360.0 degrees; the 'l' and 's' values (luminance and saturation) are | ||||
|  * percentage values in the range between 0% and 100%. The 'a' value, if specified, | ||||
|  * can only be a floating point value between 0.0 and 1.0. | ||||
|  * | ||||
|  * Whitespace inside the definitions is ignored; no leading whitespace | ||||
|  * is allowed. | ||||
|  * | ||||
|  * If the alpha component is not specified then it is assumed to be set to | ||||
|  * be fully opaque. | ||||
|  * | ||||
|  * Return value: %TRUE if parsing succeeded, and %FALSE otherwise | ||||
|  */ | ||||
| gboolean | ||||
| clutter_color_from_string (ClutterColor *color, | ||||
|                            const gchar  *str) | ||||
| { | ||||
|   PangoColor pango_color = { 0, }; | ||||
|  | ||||
|   g_return_val_if_fail (color != NULL, FALSE); | ||||
|   g_return_val_if_fail (str != NULL, FALSE); | ||||
|  | ||||
|   if (strncmp (str, "rgb", 3) == 0) | ||||
|     { | ||||
|       gchar *s = (gchar *) str; | ||||
|       gboolean res; | ||||
|  | ||||
|       if (strncmp (str, "rgba", 4) == 0) | ||||
|         res = parse_rgba (color, s + 4, TRUE); | ||||
|       else | ||||
|         res = parse_rgba (color, s + 3, FALSE); | ||||
|  | ||||
|       return res; | ||||
|     } | ||||
|  | ||||
|   if (strncmp (str, "hsl", 3) == 0) | ||||
|     { | ||||
|       gchar *s = (gchar *) str; | ||||
|       gboolean res; | ||||
|  | ||||
|       if (strncmp (str, "hsla", 4) == 0) | ||||
|         res = parse_hsla (color, s + 4, TRUE); | ||||
|       else | ||||
|         res = parse_hsla (color, s + 3, FALSE); | ||||
|  | ||||
|       return res; | ||||
|     } | ||||
|  | ||||
|   /* if the string contains a color encoded using the hexadecimal | ||||
|    * notations (#rrggbbaa or #rgba) we attempt a rough pass at | ||||
|    * parsing the color ourselves, as we need the alpha channel that | ||||
|    * Pango can't retrieve. | ||||
|    */ | ||||
|   if (str[0] == '#' && str[1] != '\0') | ||||
|     { | ||||
|       gsize length = strlen (str + 1); | ||||
|       gint32 result; | ||||
|  | ||||
|       if (sscanf (str + 1, "%x", &result) == 1) | ||||
|         { | ||||
|           switch (length) | ||||
|             { | ||||
|             case 8: /* rrggbbaa */ | ||||
|               color->red   = (result >> 24) & 0xff; | ||||
|               color->green = (result >> 16) & 0xff; | ||||
|               color->blue  = (result >>  8) & 0xff; | ||||
|  | ||||
|               color->alpha = result & 0xff; | ||||
|  | ||||
|               return TRUE; | ||||
|  | ||||
|             case 6: /* #rrggbb */ | ||||
|               color->red   = (result >> 16) & 0xff; | ||||
|               color->green = (result >>  8) & 0xff; | ||||
|               color->blue  = result & 0xff; | ||||
|  | ||||
|               color->alpha = 0xff; | ||||
|  | ||||
|               return TRUE; | ||||
|  | ||||
|             case 4: /* #rgba */ | ||||
|               color->red   = ((result >> 12) & 0xf); | ||||
|               color->green = ((result >>  8) & 0xf); | ||||
|               color->blue  = ((result >>  4) & 0xf); | ||||
|               color->alpha = result & 0xf; | ||||
|  | ||||
|               color->red   = (color->red   << 4) | color->red; | ||||
|               color->green = (color->green << 4) | color->green; | ||||
|               color->blue  = (color->blue  << 4) | color->blue; | ||||
|               color->alpha = (color->alpha << 4) | color->alpha; | ||||
|  | ||||
|               return TRUE; | ||||
|  | ||||
|             case 3: /* #rgb */ | ||||
|               color->red   = ((result >>  8) & 0xf); | ||||
|               color->green = ((result >>  4) & 0xf); | ||||
|               color->blue  = result & 0xf; | ||||
|  | ||||
|               color->red   = (color->red   << 4) | color->red; | ||||
|               color->green = (color->green << 4) | color->green; | ||||
|               color->blue  = (color->blue  << 4) | color->blue; | ||||
|  | ||||
|               color->alpha = 0xff; | ||||
|  | ||||
|               return TRUE; | ||||
|  | ||||
|             default: | ||||
|               return FALSE; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   /* fall back to pango for X11-style named colors; see: | ||||
|    * | ||||
|    *   http://en.wikipedia.org/wiki/X11_color_names | ||||
|    * | ||||
|    * for a list. at some point we might even ship with our own list generated | ||||
|    * from X11/rgb.txt, like we generate the key symbols. | ||||
|    */ | ||||
|   if (pango_color_parse (&pango_color, str)) | ||||
|     { | ||||
|       color->red   = pango_color.red; | ||||
|       color->green = pango_color.green; | ||||
|       color->blue  = pango_color.blue; | ||||
|  | ||||
|       color->alpha = 0xff; | ||||
|  | ||||
|       return TRUE; | ||||
|     } | ||||
|  | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_color_to_string: | ||||
|  * @color: a #ClutterColor | ||||
|  * | ||||
|  * Returns a textual specification of @color in the hexadecimal form | ||||
|  * `#rrggbbaa`, where `r`, `g`, `b` and `a` are | ||||
|  * hexadecimal digits representing the red, green, blue and alpha components | ||||
|  * respectively. | ||||
|  * | ||||
|  * Return value: (transfer full): a newly-allocated text string | ||||
|  */ | ||||
| gchar * | ||||
| clutter_color_to_string (const ClutterColor *color) | ||||
| { | ||||
|   g_return_val_if_fail (color != NULL, NULL); | ||||
|  | ||||
|   return g_strdup_printf ("#%02x%02x%02x%02x", | ||||
|                           color->red, | ||||
|                           color->green, | ||||
|                           color->blue, | ||||
|                           color->alpha); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_color_equal: | ||||
|  * @v1: (type Clutter.Color): a #ClutterColor | ||||
|  * @v2: (type Clutter.Color): a #ClutterColor | ||||
|  * | ||||
|  * Compares two `ClutterColor`s and checks if they are the same. | ||||
|  * | ||||
|  * This function can be passed to g_hash_table_new() as the @key_equal_func | ||||
|  * parameter, when using `ClutterColor`s as keys in a #GHashTable. | ||||
|  * | ||||
|  * Return value: %TRUE if the two colors are the same. | ||||
|  */ | ||||
| gboolean | ||||
| clutter_color_equal (gconstpointer v1, | ||||
|                      gconstpointer v2) | ||||
| { | ||||
|   const ClutterColor *a, *b; | ||||
|  | ||||
|   g_return_val_if_fail (v1 != NULL, FALSE); | ||||
|   g_return_val_if_fail (v2 != NULL, FALSE); | ||||
|  | ||||
|   if (v1 == v2) | ||||
|     return TRUE; | ||||
|  | ||||
|   a = v1; | ||||
|   b = v2; | ||||
|  | ||||
|   return (a->red   == b->red   && | ||||
|           a->green == b->green && | ||||
|           a->blue  == b->blue  && | ||||
|           a->alpha == b->alpha); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_color_hash: | ||||
|  * @v: (type Clutter.Color): a #ClutterColor | ||||
|  * | ||||
|  * Converts a #ClutterColor to a hash value. | ||||
|  * | ||||
|  * This function can be passed to g_hash_table_new() as the @hash_func | ||||
|  * parameter, when using `ClutterColor`s as keys in a #GHashTable. | ||||
|  * | ||||
|  * Return value: a hash value corresponding to the color | ||||
|  */ | ||||
| guint | ||||
| clutter_color_hash (gconstpointer v) | ||||
| { | ||||
|   return clutter_color_to_pixel ((const ClutterColor *) v); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_color_interpolate: | ||||
|  * @initial: the initial #ClutterColor | ||||
|  * @final: the final #ClutterColor | ||||
|  * @progress: the interpolation progress | ||||
|  * @result: (out): return location for the interpolation | ||||
|  * | ||||
|  * Interpolates between @initial and @final `ClutterColor`s | ||||
|  * using @progress | ||||
|  */ | ||||
| void | ||||
| clutter_color_interpolate (const ClutterColor *initial, | ||||
|                            const ClutterColor *final, | ||||
|                            gdouble             progress, | ||||
|                            ClutterColor       *result) | ||||
| { | ||||
|   g_return_if_fail (initial != NULL); | ||||
|   g_return_if_fail (final != NULL); | ||||
|   g_return_if_fail (result != NULL); | ||||
|  | ||||
|   result->red   = initial->red   + (final->red   - initial->red)   * progress; | ||||
|   result->green = initial->green + (final->green - initial->green) * progress; | ||||
|   result->blue  = initial->blue  + (final->blue  - initial->blue)  * progress; | ||||
|   result->alpha = initial->alpha + (final->alpha - initial->alpha) * progress; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| clutter_color_progress (const GValue *a, | ||||
|                         const GValue *b, | ||||
|                         gdouble       progress, | ||||
|                         GValue       *retval) | ||||
| { | ||||
|   const ClutterColor *a_color = clutter_value_get_color (a); | ||||
|   const ClutterColor *b_color = clutter_value_get_color (b); | ||||
|   ClutterColor res = { 0, }; | ||||
|  | ||||
|   clutter_color_interpolate (a_color, b_color, progress, &res); | ||||
|   clutter_value_set_color (retval, &res); | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_color_copy: | ||||
|  * @color: a #ClutterColor | ||||
|  * | ||||
|  * Makes a copy of the color structure.  The result must be | ||||
|  * freed using [method@Clutter.Color.free]. | ||||
|  * | ||||
|  * Return value: (transfer full): an allocated copy of @color. | ||||
|  */ | ||||
| ClutterColor * | ||||
| clutter_color_copy (const ClutterColor *color) | ||||
| { | ||||
|   if (G_LIKELY (color != NULL)) | ||||
|     return g_memdup2 (color, sizeof (ClutterColor)); | ||||
|  | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_color_free: | ||||
|  * @color: a #ClutterColor | ||||
|  * | ||||
|  * Frees a color structure created with [method@Clutter.Color.copy]. | ||||
|  */ | ||||
| void | ||||
| clutter_color_free (ClutterColor *color) | ||||
| { | ||||
|   if (G_LIKELY (color != NULL)) | ||||
|     g_free (color); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_color_new: | ||||
|  * @red: red component of the color, between 0 and 255 | ||||
|  * @green: green component of the color, between 0 and 255 | ||||
|  * @blue: blue component of the color, between 0 and 255 | ||||
|  * @alpha: alpha component of the color, between 0 and 255 | ||||
|  * | ||||
|  * Creates a new #ClutterColor with the given values. | ||||
|  * | ||||
|  * This function is the equivalent of: | ||||
|  * | ||||
|  * ```c | ||||
|  *   clutter_color_init (clutter_color_alloc (), red, green, blue, alpha); | ||||
|  * ``` | ||||
|  * | ||||
|  * Return value: (transfer full): the newly allocated color. | ||||
|  *   Use [method@Clutter.Color.free] when done | ||||
|  */ | ||||
| ClutterColor * | ||||
| clutter_color_new (guint8 red, | ||||
|                    guint8 green, | ||||
|                    guint8 blue, | ||||
|                    guint8 alpha) | ||||
| { | ||||
|   return clutter_color_init (clutter_color_alloc (), | ||||
|                              red, | ||||
|                              green, | ||||
|                              blue, | ||||
|                              alpha); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_color_alloc: (constructor) | ||||
|  * | ||||
|  * Allocates a new, transparent black #ClutterColor. | ||||
|  * | ||||
|  * Return value: (transfer full): the newly allocated #ClutterColor; use | ||||
|  *   [method@Clutter.Color.free] to free its resources | ||||
|  */ | ||||
| ClutterColor * | ||||
| clutter_color_alloc (void) | ||||
| { | ||||
|   return g_new0 (ClutterColor, 1); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_color_init: | ||||
|  * @color: a #ClutterColor | ||||
|  * @red: red component of the color, between 0 and 255 | ||||
|  * @green: green component of the color, between 0 and 255 | ||||
|  * @blue: blue component of the color, between 0 and 255 | ||||
|  * @alpha: alpha component of the color, between 0 and 255 | ||||
|  * | ||||
|  * Initializes @color with the given values. | ||||
|  * | ||||
|  * Return value: (transfer none): the initialized #ClutterColor | ||||
|  */ | ||||
| ClutterColor * | ||||
| clutter_color_init (ClutterColor *color, | ||||
|                     guint8        red, | ||||
|                     guint8        green, | ||||
|                     guint8        blue, | ||||
|                     guint8        alpha) | ||||
| { | ||||
|   g_return_val_if_fail (color != NULL, NULL); | ||||
|  | ||||
|   color->red = red; | ||||
|   color->green = green; | ||||
|   color->blue = blue; | ||||
|   color->alpha = alpha; | ||||
|  | ||||
|   return color; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_value_transform_color_string (const GValue *src, | ||||
|                                       GValue       *dest) | ||||
| { | ||||
|   const ClutterColor *color = g_value_get_boxed (src); | ||||
|  | ||||
|   if (color) | ||||
|     { | ||||
|       gchar *string = clutter_color_to_string (color); | ||||
|  | ||||
|       g_value_take_string (dest, string); | ||||
|     } | ||||
|   else | ||||
|     g_value_set_string (dest, NULL); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_value_transform_string_color (const GValue *src, | ||||
|                                       GValue       *dest) | ||||
| { | ||||
|   const char *str = g_value_get_string (src); | ||||
|  | ||||
|   if (str) | ||||
|     { | ||||
|       ClutterColor color = { 0, }; | ||||
|  | ||||
|       clutter_color_from_string (&color, str); | ||||
|  | ||||
|       clutter_value_set_color (dest, &color); | ||||
|     } | ||||
|   else | ||||
|     clutter_value_set_color (dest, NULL); | ||||
| } | ||||
|  | ||||
| G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterColor, clutter_color, | ||||
|                                clutter_color_copy, | ||||
|                                clutter_color_free, | ||||
|                                CLUTTER_REGISTER_VALUE_TRANSFORM_TO (G_TYPE_STRING, clutter_value_transform_color_string) | ||||
|                                CLUTTER_REGISTER_VALUE_TRANSFORM_FROM (G_TYPE_STRING, clutter_value_transform_string_color) | ||||
|                                CLUTTER_REGISTER_INTERVAL_PROGRESS (clutter_color_progress)); | ||||
|  | ||||
| /** | ||||
|  * clutter_value_set_color: | ||||
|  * @value: a #GValue initialized to #CLUTTER_TYPE_COLOR | ||||
|  * @color: the color to set | ||||
|  * | ||||
|  * Sets @value to @color. | ||||
|  */ | ||||
| void | ||||
| clutter_value_set_color (GValue             *value, | ||||
|                          const ClutterColor *color) | ||||
| { | ||||
|   g_return_if_fail (CLUTTER_VALUE_HOLDS_COLOR (value)); | ||||
|  | ||||
|   g_value_set_boxed (value, color); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_value_get_color: | ||||
|  * @value: a #GValue initialized to #CLUTTER_TYPE_COLOR | ||||
|  * | ||||
|  * Gets the #ClutterColor contained in @value. | ||||
|  * | ||||
|  * Return value: (transfer none): the color inside the passed #GValue | ||||
|  */ | ||||
| const ClutterColor * | ||||
| clutter_value_get_color (const GValue *value) | ||||
| { | ||||
|   g_return_val_if_fail (CLUTTER_VALUE_HOLDS_COLOR (value), NULL); | ||||
|  | ||||
|   return g_value_get_boxed (value); | ||||
| } | ||||
|  | ||||
| static void | ||||
| param_color_init (GParamSpec *pspec) | ||||
| { | ||||
|   ClutterParamSpecColor *cspec = CLUTTER_PARAM_SPEC_COLOR (pspec); | ||||
|  | ||||
|   cspec->default_value = NULL; | ||||
| } | ||||
|  | ||||
| static void | ||||
| param_color_finalize (GParamSpec *pspec) | ||||
| { | ||||
|   ClutterParamSpecColor *cspec = CLUTTER_PARAM_SPEC_COLOR (pspec); | ||||
|  | ||||
|   clutter_color_free (cspec->default_value); | ||||
| } | ||||
|  | ||||
| static void | ||||
| param_color_set_default (GParamSpec *pspec, | ||||
|                          GValue     *value) | ||||
| { | ||||
|   const ClutterColor *default_value = | ||||
|     CLUTTER_PARAM_SPEC_COLOR (pspec)->default_value; | ||||
|   clutter_value_set_color (value, default_value); | ||||
| } | ||||
|  | ||||
| static gint | ||||
| param_color_values_cmp (GParamSpec   *pspec, | ||||
|                         const GValue *value1, | ||||
|                         const GValue *value2) | ||||
| { | ||||
|   const ClutterColor *color1 = g_value_get_boxed (value1); | ||||
|   const ClutterColor *color2 = g_value_get_boxed (value2); | ||||
|   int pixel1, pixel2; | ||||
|  | ||||
|   if (color1 == NULL) | ||||
|     return color2 == NULL ? 0 : -1; | ||||
|  | ||||
|   pixel1 = clutter_color_to_pixel (color1); | ||||
|   pixel2 = clutter_color_to_pixel (color2); | ||||
|  | ||||
|   if (pixel1 < pixel2) | ||||
|     return -1; | ||||
|   else if (pixel1 == pixel2) | ||||
|     return 0; | ||||
|   else | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| GType | ||||
| clutter_param_color_get_type (void) | ||||
| { | ||||
|   static GType pspec_type = 0; | ||||
|  | ||||
|   if (G_UNLIKELY (pspec_type == 0)) | ||||
|     { | ||||
|       const GParamSpecTypeInfo pspec_info = { | ||||
|         sizeof (ClutterParamSpecColor), | ||||
|         16, | ||||
|         param_color_init, | ||||
|         CLUTTER_TYPE_COLOR, | ||||
|         param_color_finalize, | ||||
|         param_color_set_default, | ||||
|         NULL, | ||||
|         param_color_values_cmp, | ||||
|       }; | ||||
|  | ||||
|       pspec_type = g_param_type_register_static (I_("ClutterParamSpecColor"), | ||||
|                                                  &pspec_info); | ||||
|     } | ||||
|  | ||||
|   return pspec_type; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_param_spec_color: (skip) | ||||
|  * @name: name of the property | ||||
|  * @nick: short name | ||||
|  * @blurb: description (can be translatable) | ||||
|  * @default_value: default value | ||||
|  * @flags: flags for the param spec | ||||
|  * | ||||
|  * Creates a #GParamSpec for properties using #ClutterColor. | ||||
|  * | ||||
|  * Return value: the newly created #GParamSpec | ||||
|  */ | ||||
| GParamSpec * | ||||
| clutter_param_spec_color (const gchar        *name, | ||||
|                           const gchar        *nick, | ||||
|                           const gchar        *blurb, | ||||
|                           const ClutterColor *default_value, | ||||
|                           GParamFlags         flags) | ||||
| { | ||||
|   ClutterParamSpecColor *cspec; | ||||
|  | ||||
|   cspec = g_param_spec_internal (CLUTTER_TYPE_PARAM_COLOR, | ||||
|                                  name, nick, blurb, flags); | ||||
|  | ||||
|   cspec->default_value = clutter_color_copy (default_value); | ||||
|  | ||||
|   return G_PARAM_SPEC (cspec); | ||||
| } | ||||
| @@ -1,182 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Authored By: Matthew Allum  <mallum@openedhand.com> | ||||
|  *              Emmanuele Bassi <ebassi@linux.intel.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/>. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <clutter/clutter.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include "clutter/clutter-types.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CLUTTER_TYPE_COLOR	(clutter_color_get_type ()) | ||||
|  | ||||
| /** | ||||
|  * ClutterColor: | ||||
|  * @red: red component, between 0 and 255 | ||||
|  * @green: green component, between 0 and 255 | ||||
|  * @blue: blue component, between 0 and 255 | ||||
|  * @alpha: alpha component, between 0 and 255 | ||||
|  * | ||||
|  * A simple type for representing colors. | ||||
|  * | ||||
|  * A #ClutterColor is expressed as a 4-tuple of values ranging from | ||||
|  * zero to 255, one for each color channel plus one for the alpha. | ||||
|  * | ||||
|  * The alpha channel is fully opaque at 255 and fully transparent at 0. | ||||
|  */ | ||||
| struct _ClutterColor | ||||
| { | ||||
|   /*< public >*/ | ||||
|   guint8 red; | ||||
|   guint8 green; | ||||
|   guint8 blue; | ||||
|  | ||||
|   guint8 alpha; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * CLUTTER_COLOR_INIT: | ||||
|  * @r: value for the red channel, between 0 and 255 | ||||
|  * @g: value for the green channel, between 0 and 255 | ||||
|  * @b: value for the blue channel, between 0 and 255 | ||||
|  * @a: value for the alpha channel, between 0 and 255 | ||||
|  * | ||||
|  * A macro that initializes a #ClutterColor, to be used when declaring it. | ||||
|  */ | ||||
| #define CLUTTER_COLOR_INIT(_r, _g, _b, _a) \ | ||||
|         (ClutterColor) { \ | ||||
|           .red = (_r), \ | ||||
|           .green = (_g), \ | ||||
|           .blue = (_b), \ | ||||
|           .alpha = (_a) \ | ||||
|         } | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| GType clutter_color_get_type (void) G_GNUC_CONST; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterColor *clutter_color_new         (guint8              red, | ||||
|                                          guint8              green, | ||||
|                                          guint8              blue, | ||||
|                                          guint8              alpha); | ||||
| CLUTTER_EXPORT | ||||
| ClutterColor *clutter_color_alloc       (void); | ||||
| CLUTTER_EXPORT | ||||
| ClutterColor *clutter_color_init        (ClutterColor       *color, | ||||
|                                          guint8              red, | ||||
|                                          guint8              green, | ||||
|                                          guint8              blue, | ||||
|                                          guint8              alpha); | ||||
| CLUTTER_EXPORT | ||||
| ClutterColor *clutter_color_copy        (const ClutterColor *color); | ||||
| CLUTTER_EXPORT | ||||
| void          clutter_color_free        (ClutterColor       *color); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| gchar *       clutter_color_to_string   (const ClutterColor *color); | ||||
| CLUTTER_EXPORT | ||||
| gboolean      clutter_color_from_string (ClutterColor       *color, | ||||
|                                          const gchar        *str); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void          clutter_color_to_hls      (const ClutterColor *color, | ||||
|                                          gfloat             *hue, | ||||
| 					 gfloat             *luminance, | ||||
| 					 gfloat             *saturation); | ||||
| CLUTTER_EXPORT | ||||
| void          clutter_color_from_hls    (ClutterColor       *color, | ||||
|                                          gfloat              hue, | ||||
|                                          gfloat              luminance, | ||||
|                                          gfloat              saturation); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| guint32       clutter_color_to_pixel    (const ClutterColor *color); | ||||
| CLUTTER_EXPORT | ||||
| void          clutter_color_from_pixel  (ClutterColor       *color, | ||||
|                                          guint32             pixel); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| guint         clutter_color_hash        (gconstpointer       v); | ||||
| CLUTTER_EXPORT | ||||
| gboolean      clutter_color_equal       (gconstpointer       v1, | ||||
|                                          gconstpointer       v2); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void          clutter_color_interpolate (const ClutterColor *initial, | ||||
|                                          const ClutterColor *final, | ||||
|                                          gdouble             progress, | ||||
|                                          ClutterColor       *result); | ||||
|  | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterColor, clutter_color_free) | ||||
|  | ||||
| #define CLUTTER_TYPE_PARAM_COLOR           (clutter_param_color_get_type ()) | ||||
| #define CLUTTER_PARAM_SPEC_COLOR(pspec)    (G_TYPE_CHECK_INSTANCE_CAST ((pspec), CLUTTER_TYPE_PARAM_COLOR, ClutterParamSpecColor)) | ||||
| #define CLUTTER_IS_PARAM_SPEC_COLOR(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), CLUTTER_TYPE_PARAM_COLOR)) | ||||
|  | ||||
| /** | ||||
|  * CLUTTER_VALUE_HOLDS_COLOR: | ||||
|  * @x: a #GValue | ||||
|  * | ||||
|  * Evaluates to %TRUE if @x holds a `ClutterColor`. | ||||
|  */ | ||||
| #define CLUTTER_VALUE_HOLDS_COLOR(x)       (G_VALUE_HOLDS ((x), CLUTTER_TYPE_COLOR)) | ||||
|  | ||||
| typedef struct _ClutterParamSpecColor  ClutterParamSpecColor; | ||||
|  | ||||
| /** | ||||
|  * ClutterParamSpecColor: (skip) | ||||
|  * @default_value: default color value | ||||
|  * | ||||
|  * A #GParamSpec subclass for defining properties holding | ||||
|  * a #ClutterColor. | ||||
|  */ | ||||
| struct _ClutterParamSpecColor | ||||
| { | ||||
|   /*< private >*/ | ||||
|   GParamSpec    parent_instance; | ||||
|  | ||||
|   /*< public >*/ | ||||
|   ClutterColor *default_value; | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void                    clutter_value_set_color         (GValue             *value, | ||||
|                                                          const ClutterColor *color); | ||||
| CLUTTER_EXPORT | ||||
| const ClutterColor *    clutter_value_get_color         (const GValue       *value); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| GType clutter_param_color_get_type (void) G_GNUC_CONST; | ||||
| CLUTTER_EXPORT | ||||
| GParamSpec *    clutter_param_spec_color        (const gchar        *name, | ||||
|                                                  const gchar        *nick, | ||||
|                                                  const gchar        *blurb, | ||||
|                                                  const ClutterColor *default_value, | ||||
|                                                  GParamFlags         flags); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,297 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2010  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> | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * ClutterColorizeEffect: | ||||
|  * | ||||
|  * A colorization effect | ||||
|  * | ||||
|  * #ClutterColorizeEffect is a sub-class of #ClutterEffect that | ||||
|  * colorizes an actor with the given tint. | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "clutter/clutter-colorize-effect.h" | ||||
|  | ||||
| #include "cogl/cogl.h" | ||||
|  | ||||
| #include "clutter/clutter-debug.h" | ||||
| #include "clutter/clutter-enum-types.h" | ||||
| #include "clutter/clutter-private.h" | ||||
|  | ||||
| typedef struct _ClutterColorizeEffectPrivate | ||||
| { | ||||
|   ClutterOffscreenEffect parent_instance; | ||||
|  | ||||
|   /* the tint of the colorization */ | ||||
|   ClutterColor tint; | ||||
|  | ||||
|   gint tint_uniform; | ||||
|  | ||||
|   CoglPipeline *pipeline; | ||||
| } ClutterColorizeEffectPrivate; | ||||
|  | ||||
| /* the magic gray vec3 has been taken from the NTSC conversion weights | ||||
|  * as defined by: | ||||
|  * | ||||
|  *   "OpenGL Superbible, 4th Edition" | ||||
|  *   -- Richard S. Wright Jr, Benjamin Lipchak, Nicholas Haemel | ||||
|  *   Addison-Wesley | ||||
|  */ | ||||
| static const gchar *colorize_glsl_declarations = | ||||
| "uniform vec3 tint;\n"; | ||||
|  | ||||
| static const gchar *colorize_glsl_source = | ||||
| "float gray = dot (cogl_color_out.rgb, vec3 (0.299, 0.587, 0.114));\n" | ||||
| "cogl_color_out.rgb = gray * tint;\n"; | ||||
|  | ||||
| /* a lame sepia */ | ||||
| static const ClutterColor default_tint = { 255, 204, 153, 255 }; | ||||
|  | ||||
| enum | ||||
| { | ||||
|   PROP_0, | ||||
|  | ||||
|   PROP_TINT, | ||||
|  | ||||
|   PROP_LAST | ||||
| }; | ||||
|  | ||||
| static GParamSpec *obj_props[PROP_LAST]; | ||||
|  | ||||
| G_DEFINE_TYPE_WITH_PRIVATE (ClutterColorizeEffect, | ||||
|                             clutter_colorize_effect, | ||||
|                             CLUTTER_TYPE_OFFSCREEN_EFFECT); | ||||
|  | ||||
| static CoglPipeline * | ||||
| clutter_colorize_effect_create_pipeline (ClutterOffscreenEffect *effect, | ||||
|                                          CoglTexture            *texture) | ||||
| { | ||||
|   ClutterColorizeEffect *colorize_effect = CLUTTER_COLORIZE_EFFECT (effect); | ||||
|   ClutterColorizeEffectPrivate *priv = | ||||
|     clutter_colorize_effect_get_instance_private (colorize_effect); | ||||
|  | ||||
|   cogl_pipeline_set_layer_texture (priv->pipeline, 0, texture); | ||||
|  | ||||
|   return g_object_ref (priv->pipeline); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_colorize_effect_dispose (GObject *gobject) | ||||
| { | ||||
|   ClutterColorizeEffect *self = CLUTTER_COLORIZE_EFFECT (gobject); | ||||
|   ClutterColorizeEffectPrivate *priv = | ||||
|     clutter_colorize_effect_get_instance_private (self); | ||||
|  | ||||
|   g_clear_object (&priv->pipeline); | ||||
|  | ||||
|   G_OBJECT_CLASS (clutter_colorize_effect_parent_class)->dispose (gobject); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_colorize_effect_set_property (GObject      *gobject, | ||||
|                                       guint         prop_id, | ||||
|                                       const GValue *value, | ||||
|                                       GParamSpec   *pspec) | ||||
| { | ||||
|   ClutterColorizeEffect *effect = CLUTTER_COLORIZE_EFFECT (gobject); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_TINT: | ||||
|       clutter_colorize_effect_set_tint (effect, | ||||
|                                         clutter_value_get_color (value)); | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_colorize_effect_get_property (GObject    *gobject, | ||||
|                                       guint       prop_id, | ||||
|                                       GValue     *value, | ||||
|                                       GParamSpec *pspec) | ||||
| { | ||||
|   ClutterColorizeEffect *effect = CLUTTER_COLORIZE_EFFECT (gobject); | ||||
|   ClutterColorizeEffectPrivate *priv = | ||||
|     clutter_colorize_effect_get_instance_private (effect); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_TINT: | ||||
|       clutter_value_set_color (value, &priv->tint); | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_colorize_effect_class_init (ClutterColorizeEffectClass *klass) | ||||
| { | ||||
|   GObjectClass *gobject_class = G_OBJECT_CLASS (klass); | ||||
|   ClutterOffscreenEffectClass *offscreen_class; | ||||
|  | ||||
|   offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass); | ||||
|   offscreen_class->create_pipeline = clutter_colorize_effect_create_pipeline; | ||||
|  | ||||
|   gobject_class->set_property = clutter_colorize_effect_set_property; | ||||
|   gobject_class->get_property = clutter_colorize_effect_get_property; | ||||
|   gobject_class->dispose = clutter_colorize_effect_dispose; | ||||
|  | ||||
|   /** | ||||
|    * ClutterColorizeEffect:tint: | ||||
|    * | ||||
|    * The tint to apply to the actor | ||||
|    */ | ||||
|   obj_props[PROP_TINT] = | ||||
|     clutter_param_spec_color ("tint", NULL, NULL, | ||||
|                               &default_tint, | ||||
|                               G_PARAM_READWRITE | | ||||
|                               G_PARAM_STATIC_STRINGS); | ||||
|  | ||||
|   g_object_class_install_properties (gobject_class, PROP_LAST, obj_props); | ||||
| } | ||||
|  | ||||
| static void | ||||
| update_tint_uniform (ClutterColorizeEffect *self) | ||||
| { | ||||
|   ClutterColorizeEffectPrivate *priv = | ||||
|     clutter_colorize_effect_get_instance_private (self); | ||||
|   if (priv->tint_uniform > -1) | ||||
|     { | ||||
|       float tint[3] = { | ||||
|         priv->tint.red / 255.0, | ||||
|         priv->tint.green / 255.0, | ||||
|         priv->tint.blue / 255.0 | ||||
|       }; | ||||
|  | ||||
|       cogl_pipeline_set_uniform_float (priv->pipeline, | ||||
|                                        priv->tint_uniform, | ||||
|                                        3, /* n_components */ | ||||
|                                        1, /* count */ | ||||
|                                        tint); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_colorize_effect_init (ClutterColorizeEffect *self) | ||||
| { | ||||
|   ClutterColorizeEffectClass *klass = CLUTTER_COLORIZE_EFFECT_GET_CLASS (self); | ||||
|   ClutterColorizeEffectPrivate *priv = | ||||
|     clutter_colorize_effect_get_instance_private (self); | ||||
|   if (G_UNLIKELY (klass->base_pipeline == NULL)) | ||||
|     { | ||||
|       CoglSnippet *snippet; | ||||
|       CoglContext *ctx = | ||||
|         clutter_backend_get_cogl_context (clutter_get_default_backend ()); | ||||
|  | ||||
|       klass->base_pipeline = cogl_pipeline_new (ctx); | ||||
|  | ||||
|       snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, | ||||
|                                   colorize_glsl_declarations, | ||||
|                                   colorize_glsl_source); | ||||
|       cogl_pipeline_add_snippet (klass->base_pipeline, snippet); | ||||
|       g_object_unref (snippet); | ||||
|  | ||||
|       cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0); | ||||
|     } | ||||
|  | ||||
|   priv->pipeline = cogl_pipeline_copy (klass->base_pipeline); | ||||
|  | ||||
|   priv->tint_uniform = | ||||
|     cogl_pipeline_get_uniform_location (priv->pipeline, "tint"); | ||||
|  | ||||
|   priv->tint = default_tint; | ||||
|  | ||||
|   update_tint_uniform (self); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_colorize_effect_new: | ||||
|  * @tint: the color to be used | ||||
|  * | ||||
|  * Creates a new #ClutterColorizeEffect to be used with | ||||
|  * [method@Clutter.Actor.add_effect] | ||||
|  * | ||||
|  * Return value: the newly created #ClutterColorizeEffect or %NULL | ||||
|  */ | ||||
| ClutterEffect * | ||||
| clutter_colorize_effect_new (const ClutterColor *tint) | ||||
| { | ||||
|   return g_object_new (CLUTTER_TYPE_COLORIZE_EFFECT, | ||||
|                        "tint", tint, | ||||
|                        NULL); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_colorize_effect_set_tint: | ||||
|  * @effect: a #ClutterColorizeEffect | ||||
|  * @tint: the color to be used | ||||
|  * | ||||
|  * Sets the tint to be used when colorizing | ||||
|  */ | ||||
| void | ||||
| clutter_colorize_effect_set_tint (ClutterColorizeEffect *effect, | ||||
|                                   const ClutterColor    *tint) | ||||
| { | ||||
|   ClutterColorizeEffectPrivate *priv; | ||||
|  | ||||
|   g_return_if_fail (CLUTTER_IS_COLORIZE_EFFECT (effect)); | ||||
|  | ||||
|   priv = clutter_colorize_effect_get_instance_private (effect); | ||||
|   priv->tint = *tint; | ||||
|  | ||||
|   update_tint_uniform (effect); | ||||
|  | ||||
|   clutter_effect_queue_repaint (CLUTTER_EFFECT (effect)); | ||||
|  | ||||
|   g_object_notify_by_pspec (G_OBJECT (effect), obj_props[PROP_TINT]); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_colorize_effect_get_tint: | ||||
|  * @effect: a #ClutterColorizeEffect | ||||
|  * @tint: (out caller-allocates): return location for the color used | ||||
|  * | ||||
|  * Retrieves the tint used by @effect | ||||
|  */ | ||||
| void | ||||
| clutter_colorize_effect_get_tint (ClutterColorizeEffect *effect, | ||||
|                                   ClutterColor          *tint) | ||||
| { | ||||
|   ClutterColorizeEffectPrivate *priv; | ||||
|  | ||||
|   g_return_if_fail (CLUTTER_IS_COLORIZE_EFFECT (effect)); | ||||
|   g_return_if_fail (tint != NULL); | ||||
|  | ||||
|   priv = clutter_colorize_effect_get_instance_private (effect); | ||||
|   *tint = priv->tint; | ||||
| } | ||||
| @@ -1,62 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2010  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> | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <clutter/clutter.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include "clutter/clutter-color.h" | ||||
| #include "clutter/clutter-effect.h" | ||||
| #include "clutter/clutter-offscreen-effect.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CLUTTER_TYPE_COLORIZE_EFFECT    (clutter_colorize_effect_get_type ()) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_DERIVABLE_TYPE (ClutterColorizeEffect, | ||||
|                           clutter_colorize_effect, | ||||
|                           CLUTTER, COLORIZE_EFFECT, | ||||
|                           ClutterOffscreenEffect) | ||||
|  | ||||
| struct _ClutterColorizeEffectClass | ||||
| { | ||||
|   ClutterOffscreenEffectClass parent_class; | ||||
|  | ||||
|   CoglPipeline *base_pipeline; | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterEffect *clutter_colorize_effect_new      (const ClutterColor *tint); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void           clutter_colorize_effect_set_tint (ClutterColorizeEffect *effect, | ||||
|                                                  const ClutterColor    *tint); | ||||
| CLUTTER_EXPORT | ||||
| void           clutter_colorize_effect_get_tint (ClutterColorizeEffect *effect, | ||||
|                                                  ClutterColor          *tint); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,32 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2010  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/>. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "clutter/clutter-constraint.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| gboolean clutter_constraint_update_allocation (ClutterConstraint *constraint, | ||||
|                                                ClutterActor      *actor, | ||||
|                                                ClutterActorBox   *allocation); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,218 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2010  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> | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * ClutterConstraint: | ||||
|  *  | ||||
|  * Abstract class for constraints on position or size | ||||
|  * | ||||
|  * #ClutterConstraint is a base abstract class for modifiers of a #ClutterActor | ||||
|  * position or size. | ||||
|  * | ||||
|  * A #ClutterConstraint sub-class should contain the logic for modifying | ||||
|  * the position or size of the #ClutterActor to which it is applied, by | ||||
|  * updating the actor's allocation. Each #ClutterConstraint can change the | ||||
|  * allocation of the actor to which they are applied by overriding the | ||||
|  * [vfunc@Clutter.Constraint.update_allocation] virtual function. | ||||
|  * | ||||
|  * ## Using Constraints | ||||
|  * | ||||
|  * Constraints can be used with fixed layout managers, like | ||||
|  * #ClutterFixedLayout, or with actors implicitly using a fixed layout | ||||
|  * manager, like #ClutterGroup and #ClutterStage. | ||||
|  * | ||||
|  * Constraints provide a way to build user interfaces by using | ||||
|  * relations between #ClutterActors, without explicit fixed | ||||
|  * positioning and sizing, similarly to how fluid layout managers like | ||||
|  * #ClutterBoxLayout lay out their children. | ||||
|  * | ||||
|  * Constraints are attached to a #ClutterActor, and are available | ||||
|  * for inspection using [method@Clutter.Actor.get_constraints]. | ||||
|  * | ||||
|  * Clutter provides different implementation of the #ClutterConstraint | ||||
|  * abstract class, for instance: | ||||
|  * | ||||
|  *  - #ClutterAlignConstraint, a constraint that can be used to align | ||||
|  *  an actor to another one on either the horizontal or the vertical | ||||
|  *  axis, using a normalized value between 0 and 1. | ||||
|  *  - #ClutterBindConstraint, a constraint binds the X, Y, width or height | ||||
|  *  of an actor to the corresponding position or size of a source actor, | ||||
|  *  with or without an offset. | ||||
|  *  - #ClutterSnapConstraint, a constraint that "snaps" together the edges | ||||
|  *  of two #ClutterActors; if an actor uses two constraints on both its | ||||
|  *  horizontal or vertical edges then it can also expand to fit the empty | ||||
|  *  space. | ||||
|  * | ||||
|  * It is important to note that Clutter does not avoid loops or | ||||
|  * competing constraints; if two or more #ClutterConstraints | ||||
|  * are operating on the same positional or dimensional attributes of an | ||||
|  * actor, or if the constraints on two different actors depend on each | ||||
|  * other, then the behavior is undefined. | ||||
|  * | ||||
|  * ## Implementing a ClutterConstraint | ||||
|  * | ||||
|  * Creating a sub-class of #ClutterConstraint requires the | ||||
|  * implementation of the [vfunc@Clutter.Constraint.update_allocation] | ||||
|  * virtual function. | ||||
|  * | ||||
|  * The `update_allocation()` virtual function is called during the | ||||
|  * allocation sequence of a #ClutterActor, and allows any #ClutterConstraint | ||||
|  * attached to that actor to modify the allocation before it is passed to | ||||
|  * the actor's #ClutterActorClass.allocate() implementation. | ||||
|  * | ||||
|  * The #ClutterActorBox passed to the `update_allocation()` implementation | ||||
|  * contains the original allocation of the #ClutterActor, plus the eventual | ||||
|  * modifications applied by the other #ClutterConstraints, in the same order | ||||
|  * the constraints have been applied to the actor. | ||||
|  * | ||||
|  * It is not necessary for a #ClutterConstraint sub-class to chain | ||||
|  * up to the parent's implementation. | ||||
|  * | ||||
|  * If a #ClutterConstraint is parametrized - i.e. if it contains | ||||
|  * properties that affect the way the constraint is implemented - it should | ||||
|  * call clutter_actor_queue_relayout() on the actor to which it is attached | ||||
|  * to whenever any parameter is changed. The actor to which it is attached | ||||
|  * can be recovered at any point using clutter_actor_meta_get_actor(). | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include <string.h> | ||||
|  | ||||
| #include "clutter/clutter-constraint-private.h" | ||||
|  | ||||
| #include "clutter/clutter-actor.h" | ||||
| #include "clutter/clutter-actor-meta-private.h" | ||||
| #include "clutter/clutter-private.h" | ||||
|  | ||||
| G_DEFINE_ABSTRACT_TYPE (ClutterConstraint, | ||||
|                         clutter_constraint, | ||||
|                         CLUTTER_TYPE_ACTOR_META); | ||||
|  | ||||
| static void | ||||
| constraint_update_allocation (ClutterConstraint *constraint, | ||||
|                               ClutterActor      *actor, | ||||
|                               ClutterActorBox   *allocation) | ||||
| { | ||||
| } | ||||
|  | ||||
| static void | ||||
| constraint_update_preferred_size (ClutterConstraint  *constraint, | ||||
|                                   ClutterActor       *actor, | ||||
|                                   ClutterOrientation  direction, | ||||
|                                   float               for_size, | ||||
|                                   float              *minimum_size, | ||||
|                                   float              *natural_size) | ||||
| { | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_constraint_set_enabled (ClutterActorMeta *meta, | ||||
|                                 gboolean          is_enabled) | ||||
| { | ||||
|   ClutterActorMetaClass *parent_class = | ||||
|     CLUTTER_ACTOR_META_CLASS (clutter_constraint_parent_class); | ||||
|   ClutterActor *actor; | ||||
|  | ||||
|   actor = clutter_actor_meta_get_actor (meta); | ||||
|   if (actor) | ||||
|     clutter_actor_queue_relayout (actor); | ||||
|  | ||||
|   parent_class->set_enabled (meta, is_enabled); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_constraint_class_init (ClutterConstraintClass *klass) | ||||
| { | ||||
|   ClutterActorMetaClass *actor_meta_class = CLUTTER_ACTOR_META_CLASS (klass); | ||||
|  | ||||
|   actor_meta_class->set_enabled = clutter_constraint_set_enabled; | ||||
|  | ||||
|   klass->update_allocation = constraint_update_allocation; | ||||
|   klass->update_preferred_size = constraint_update_preferred_size; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_constraint_init (ClutterConstraint *self) | ||||
| { | ||||
| } | ||||
|  | ||||
| /*< private > | ||||
|  * clutter_constraint_update_allocation: | ||||
|  * @constraint: a #ClutterConstraint | ||||
|  * @actor: a #ClutterActor | ||||
|  * @allocation: (inout): the allocation to modify | ||||
|  * | ||||
|  * Asks the @constraint to update the @allocation of a #ClutterActor. | ||||
|  * | ||||
|  * Returns: %TRUE if the allocation was updated | ||||
|  */ | ||||
| gboolean | ||||
| clutter_constraint_update_allocation (ClutterConstraint *constraint, | ||||
|                                       ClutterActor      *actor, | ||||
|                                       ClutterActorBox   *allocation) | ||||
| { | ||||
|   ClutterActorBox old_alloc; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_CONSTRAINT (constraint), FALSE); | ||||
|   g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), FALSE); | ||||
|   g_return_val_if_fail (allocation != NULL, FALSE); | ||||
|  | ||||
|   old_alloc = *allocation; | ||||
|  | ||||
|   CLUTTER_CONSTRAINT_GET_CLASS (constraint)->update_allocation (constraint, | ||||
|                                                                 actor, | ||||
|                                                                 allocation); | ||||
|  | ||||
|   return !clutter_actor_box_equal (allocation, &old_alloc); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_constraint_update_preferred_size: | ||||
|  * @constraint: a #ClutterConstraint | ||||
|  * @actor: a #ClutterActor | ||||
|  * @direction: a #ClutterOrientation | ||||
|  * @for_size: the size in the opposite direction | ||||
|  * @minimum_size: (inout): the minimum size to modify | ||||
|  * @natural_size: (inout): the natural size to modify | ||||
|  * | ||||
|  * Asks the @constraint to update the size request of a #ClutterActor. | ||||
|  */ | ||||
| void | ||||
| clutter_constraint_update_preferred_size (ClutterConstraint  *constraint, | ||||
|                                           ClutterActor       *actor, | ||||
|                                           ClutterOrientation  direction, | ||||
|                                           float               for_size, | ||||
|                                           float              *minimum_size, | ||||
|                                           float              *natural_size) | ||||
| { | ||||
|   g_return_if_fail (CLUTTER_IS_CONSTRAINT (constraint)); | ||||
|   g_return_if_fail (CLUTTER_IS_ACTOR (actor)); | ||||
|  | ||||
|   CLUTTER_CONSTRAINT_GET_CLASS (constraint)->update_preferred_size (constraint, actor, | ||||
|                                                                     direction, | ||||
|                                                                     for_size, | ||||
|                                                                     minimum_size, | ||||
|                                                                     natural_size); | ||||
| } | ||||
| @@ -1,106 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2010  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> | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <clutter/clutter.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include "clutter/clutter-actor-meta.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CLUTTER_TYPE_CONSTRAINT                 (clutter_constraint_get_type ()) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_DERIVABLE_TYPE (ClutterConstraint, | ||||
|                           clutter_constraint, | ||||
|                           CLUTTER, | ||||
|                           CONSTRAINT, | ||||
|                           ClutterActorMeta) | ||||
|  | ||||
| /** | ||||
|  * ClutterConstraintClass: | ||||
|  * @update_allocation: virtual function used to update the allocation | ||||
|  *   of the #ClutterActor using the #ClutterConstraint | ||||
|  * @update_preferred_size: virtual function used to update the preferred | ||||
|  *   size of the #ClutterActor using the #ClutterConstraint; optional, | ||||
|  *   since 1.22 | ||||
|  * | ||||
|  * The #ClutterConstraintClass structure contains | ||||
|  * only private data | ||||
|  */ | ||||
| struct _ClutterConstraintClass | ||||
| { | ||||
|   /*< private >*/ | ||||
|   ClutterActorMetaClass parent_class; | ||||
|  | ||||
|   /*< public >*/ | ||||
|   void (* update_allocation) (ClutterConstraint *constraint, | ||||
|                               ClutterActor      *actor, | ||||
|                               ClutterActorBox   *allocation); | ||||
|  | ||||
|   void (* update_preferred_size) (ClutterConstraint  *constraint, | ||||
|                                   ClutterActor       *actor, | ||||
|                                   ClutterOrientation  direction, | ||||
|                                   float               for_size, | ||||
|                                   float              *minimum_size, | ||||
|                                   float              *natural_size); | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void clutter_constraint_update_preferred_size (ClutterConstraint  *constraint, | ||||
|                                                ClutterActor       *actor, | ||||
|                                                ClutterOrientation  direction, | ||||
|                                                float               for_size, | ||||
|                                                float              *minimum_size, | ||||
|                                                float              *natural_size); | ||||
|  | ||||
| /* ClutterActor API */ | ||||
| CLUTTER_EXPORT | ||||
| void               clutter_actor_add_constraint            (ClutterActor      *self, | ||||
|                                                             ClutterConstraint *constraint); | ||||
| CLUTTER_EXPORT | ||||
| void               clutter_actor_add_constraint_with_name  (ClutterActor      *self, | ||||
|                                                             const gchar       *name, | ||||
|                                                             ClutterConstraint *constraint); | ||||
| CLUTTER_EXPORT | ||||
| void               clutter_actor_remove_constraint         (ClutterActor      *self, | ||||
|                                                             ClutterConstraint *constraint); | ||||
| CLUTTER_EXPORT | ||||
| void               clutter_actor_remove_constraint_by_name (ClutterActor      *self, | ||||
|                                                             const gchar       *name); | ||||
| CLUTTER_EXPORT | ||||
| GList *            clutter_actor_get_constraints           (ClutterActor      *self); | ||||
| CLUTTER_EXPORT | ||||
| ClutterConstraint *clutter_actor_get_constraint            (ClutterActor      *self, | ||||
|                                                             const gchar       *name); | ||||
| CLUTTER_EXPORT | ||||
| void               clutter_actor_clear_constraints         (ClutterActor      *self); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| gboolean           clutter_actor_has_constraints           (ClutterActor      *self); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,41 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2011  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> | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "clutter/clutter-content.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| void            _clutter_content_attached               (ClutterContent   *content, | ||||
|                                                          ClutterActor     *actor); | ||||
| void            _clutter_content_detached               (ClutterContent   *content, | ||||
|                                                          ClutterActor     *actor); | ||||
|  | ||||
| void            _clutter_content_paint_content          (ClutterContent      *content, | ||||
|                                                          ClutterActor        *actor, | ||||
|                                                          ClutterPaintNode    *node, | ||||
|                                                          ClutterPaintContext *paint_context); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,339 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2011  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> | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * ClutterContent: | ||||
|  *  | ||||
|  * Delegate for painting the content of an actor | ||||
|  * | ||||
|  * #ClutterContent is an interface to implement types responsible for | ||||
|  * painting the content of a [class@Actor]. | ||||
|  * | ||||
|  * Multiple actors can use the same #ClutterContent instance, in order | ||||
|  * to share the resources associated with painting the same content.. | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "clutter/clutter-actor-private.h" | ||||
| #include "clutter/clutter-content-private.h" | ||||
|  | ||||
| #include "clutter/clutter-debug.h" | ||||
| #include "clutter/clutter-marshal.h" | ||||
| #include "clutter/clutter-private.h" | ||||
|  | ||||
| enum | ||||
| { | ||||
|   ATTACHED, | ||||
|   DETACHED, | ||||
|  | ||||
|   LAST_SIGNAL | ||||
| }; | ||||
|  | ||||
| static GQuark quark_content_actors = 0; | ||||
|  | ||||
| static guint content_signals[LAST_SIGNAL] = { 0, }; | ||||
|  | ||||
| G_DEFINE_INTERFACE (ClutterContent, clutter_content, G_TYPE_OBJECT) | ||||
|  | ||||
| static gboolean | ||||
| clutter_content_real_get_preferred_size (ClutterContent *content, | ||||
|                                          gfloat         *width, | ||||
|                                          gfloat         *height) | ||||
| { | ||||
|   if (width != NULL) | ||||
|     *width = 0.f; | ||||
|  | ||||
|   if (height != NULL) | ||||
|     *height = 0.f; | ||||
|  | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_content_real_attached (ClutterContent *content, | ||||
|                                ClutterActor   *actor) | ||||
| { | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_content_real_detached (ClutterContent *content, | ||||
|                                ClutterActor   *actor) | ||||
| { | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_content_real_invalidate (ClutterContent *content) | ||||
| { | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_content_real_invalidate_size (ClutterContent *content) | ||||
| { | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_content_real_paint_content (ClutterContent      *content, | ||||
|                                     ClutterActor        *actor, | ||||
|                                     ClutterPaintNode    *context, | ||||
|                                     ClutterPaintContext *paint_context) | ||||
| { | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_content_default_init (ClutterContentInterface *iface) | ||||
| { | ||||
|   quark_content_actors = g_quark_from_static_string ("-clutter-content-actors"); | ||||
|  | ||||
|   iface->get_preferred_size = clutter_content_real_get_preferred_size; | ||||
|   iface->paint_content = clutter_content_real_paint_content; | ||||
|   iface->attached = clutter_content_real_attached; | ||||
|   iface->detached = clutter_content_real_detached; | ||||
|   iface->invalidate = clutter_content_real_invalidate; | ||||
|   iface->invalidate_size = clutter_content_real_invalidate_size; | ||||
|  | ||||
|   /** | ||||
|    * ClutterContent::attached: | ||||
|    * @content: the object that emitted the signal | ||||
|    * @actor: a #ClutterActor | ||||
|    * | ||||
|    * This signal is emitted each time a #ClutterContent implementation is | ||||
|    * assigned to a #ClutterActor. | ||||
|    */ | ||||
|   content_signals[ATTACHED] = | ||||
|     g_signal_new (I_("attached"), | ||||
|                   G_TYPE_FROM_INTERFACE (iface), | ||||
|                   G_SIGNAL_RUN_FIRST, | ||||
|                   G_STRUCT_OFFSET (ClutterContentInterface, attached), | ||||
|                   NULL, NULL, NULL, | ||||
|                   G_TYPE_NONE, 1, | ||||
|                   CLUTTER_TYPE_ACTOR); | ||||
|  | ||||
|   /** | ||||
|    * ClutterContent::detached: | ||||
|    * @content: the object that emitted the signal | ||||
|    * @actor: a #ClutterActor | ||||
|    * | ||||
|    * This signal is emitted each time a #ClutterContent implementation is | ||||
|    * removed from a #ClutterActor. | ||||
|    */ | ||||
|   content_signals[DETACHED] = | ||||
|     g_signal_new (I_("detached"), | ||||
|                   G_TYPE_FROM_INTERFACE (iface), | ||||
|                   G_SIGNAL_RUN_FIRST, | ||||
|                   G_STRUCT_OFFSET (ClutterContentInterface, detached), | ||||
|                   NULL, NULL, NULL, | ||||
|                   G_TYPE_NONE, 1, | ||||
|                   CLUTTER_TYPE_ACTOR); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_content_invalidate: | ||||
|  * @content: a #ClutterContent | ||||
|  * | ||||
|  * Invalidates a #ClutterContent. | ||||
|  * | ||||
|  * This function should be called by #ClutterContent implementations when | ||||
|  * they change the way a the content should be painted regardless of the | ||||
|  * actor state. | ||||
|  */ | ||||
| void | ||||
| clutter_content_invalidate (ClutterContent *content) | ||||
| { | ||||
|   GHashTable *actors; | ||||
|   GHashTableIter iter; | ||||
|   gpointer key_p, value_p; | ||||
|  | ||||
|   g_return_if_fail (CLUTTER_IS_CONTENT (content)); | ||||
|  | ||||
|   CLUTTER_CONTENT_GET_IFACE (content)->invalidate (content); | ||||
|  | ||||
|   actors = g_object_get_qdata (G_OBJECT (content), quark_content_actors); | ||||
|   if (actors == NULL) | ||||
|     return; | ||||
|  | ||||
|   g_hash_table_iter_init (&iter, actors); | ||||
|   while (g_hash_table_iter_next (&iter, &key_p, &value_p)) | ||||
|     { | ||||
|       ClutterActor *actor = key_p; | ||||
|  | ||||
|       g_assert (actor != NULL); | ||||
|  | ||||
|       clutter_actor_queue_redraw (actor); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_content_invalidate_size: | ||||
|  * @content: a #ClutterContent | ||||
|  * | ||||
|  * Signals that @content's size changed. Attached actors with request mode | ||||
|  * set to %CLUTTER_REQUEST_CONTENT_SIZE will have a relayout queued. | ||||
|  * | ||||
|  * Attached actors with other request modes are not redrawn. To redraw them | ||||
|  * too, use [method@Clutter.Content.invalidate]. | ||||
|  */ | ||||
| void | ||||
| clutter_content_invalidate_size (ClutterContent *content) | ||||
| { | ||||
|   ClutterActor *actor; | ||||
|   GHashTable *actors; | ||||
|   GHashTableIter iter; | ||||
|  | ||||
|   g_return_if_fail (CLUTTER_IS_CONTENT (content)); | ||||
|  | ||||
|   CLUTTER_CONTENT_GET_IFACE (content)->invalidate_size (content); | ||||
|  | ||||
|   actors = g_object_get_qdata (G_OBJECT (content), quark_content_actors); | ||||
|   if (actors == NULL) | ||||
|     return; | ||||
|  | ||||
|   g_hash_table_iter_init (&iter, actors); | ||||
|   while (g_hash_table_iter_next (&iter, (gpointer *) &actor, NULL)) | ||||
|     { | ||||
|       ClutterRequestMode request_mode; | ||||
|  | ||||
|       g_assert (actor != NULL); | ||||
|  | ||||
|       request_mode = clutter_actor_get_request_mode (actor); | ||||
|  | ||||
|       if (request_mode == CLUTTER_REQUEST_CONTENT_SIZE) | ||||
|         _clutter_actor_queue_only_relayout (actor); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /*< private > | ||||
|  * _clutter_content_attached: | ||||
|  * @content: a #ClutterContent | ||||
|  * @actor: a #ClutterActor | ||||
|  * | ||||
|  * Attaches @actor to the @content. | ||||
|  * | ||||
|  * This function should be used internally every time a #ClutterActor | ||||
|  * is associated to a #ClutterContent, to set up a backpointer from | ||||
|  * the @content to the @actor. | ||||
|  * | ||||
|  * This function will invoke the [vfunc@Clutter.Content.attached] virtual | ||||
|  * function. | ||||
|  */ | ||||
| void | ||||
| _clutter_content_attached (ClutterContent *content, | ||||
|                            ClutterActor   *actor) | ||||
| { | ||||
|   GObject *obj = G_OBJECT (content); | ||||
|   GHashTable *actors; | ||||
|  | ||||
|   actors = g_object_get_qdata (obj, quark_content_actors); | ||||
|   if (actors == NULL) | ||||
|     { | ||||
|       actors = g_hash_table_new (NULL, NULL); | ||||
|       g_object_set_qdata_full (obj, quark_content_actors, | ||||
|                                actors, | ||||
|                                (GDestroyNotify) g_hash_table_unref); | ||||
|     } | ||||
|  | ||||
|   g_hash_table_insert (actors, actor, actor); | ||||
|  | ||||
|   g_signal_emit (content, content_signals[ATTACHED], 0, actor); | ||||
| } | ||||
|  | ||||
| /*< private > | ||||
|  * _clutter_content_detached: | ||||
|  * @content: a #ClutterContent | ||||
|  * @actor: a #ClutterActor | ||||
|  * | ||||
|  * Detaches @actor from @content. | ||||
|  * | ||||
|  * This function should be used internally every time a #ClutterActor | ||||
|  * removes the association with a #ClutterContent. | ||||
|  * | ||||
|  * This function will invoke the [vfunc@Clutter.Content.detached] virtual | ||||
|  * function. | ||||
|  */ | ||||
| void | ||||
| _clutter_content_detached (ClutterContent *content, | ||||
|                            ClutterActor   *actor) | ||||
| { | ||||
|   GObject *obj = G_OBJECT (content); | ||||
|   GHashTable *actors; | ||||
|  | ||||
|   actors = g_object_get_qdata (obj, quark_content_actors); | ||||
|   g_assert (actors != NULL); | ||||
|  | ||||
|   g_hash_table_remove (actors, actor); | ||||
|  | ||||
|   if (g_hash_table_size (actors) == 0) | ||||
|     g_object_set_qdata (obj, quark_content_actors, NULL); | ||||
|  | ||||
|   g_signal_emit (content, content_signals[DETACHED], 0, actor); | ||||
| } | ||||
|  | ||||
| /*< private > | ||||
|  * _clutter_content_paint_content: | ||||
|  * @content: a #ClutterContent | ||||
|  * @actor: a #ClutterActor | ||||
|  * @node: a #ClutterPaintNode | ||||
|  * @paint_context: a #ClutterPaintContext | ||||
|  * | ||||
|  * Creates the render tree for the @content and @actor. | ||||
|  * | ||||
|  * This function will invoke the [vfunc@Clutter.Content.paint_content] | ||||
|  * virtual function. | ||||
|  */ | ||||
| void | ||||
| _clutter_content_paint_content (ClutterContent      *content, | ||||
|                                 ClutterActor        *actor, | ||||
|                                 ClutterPaintNode    *node, | ||||
|                                 ClutterPaintContext *paint_context) | ||||
| { | ||||
|   CLUTTER_CONTENT_GET_IFACE (content)->paint_content (content, actor, node, | ||||
|                                                       paint_context); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_content_get_preferred_size: | ||||
|  * @content: a #ClutterContent | ||||
|  * @width: (out) (optional): return location for the natural width of the content | ||||
|  * @height: (out) (optional): return location for the natural height of the content | ||||
|  * | ||||
|  * Retrieves the natural size of the @content, if any. | ||||
|  * | ||||
|  * The natural size of a #ClutterContent is defined as the size the content | ||||
|  * would have regardless of the allocation of the actor that is painting it, | ||||
|  * for instance the size of an image data. | ||||
|  * | ||||
|  * Return value: %TRUE if the content has a preferred size, and %FALSE | ||||
|  *   otherwise | ||||
|  */ | ||||
| gboolean | ||||
| clutter_content_get_preferred_size (ClutterContent *content, | ||||
|                                     gfloat         *width, | ||||
|                                     gfloat         *height) | ||||
| { | ||||
|   g_return_val_if_fail (CLUTTER_IS_CONTENT (content), FALSE); | ||||
|  | ||||
|   return CLUTTER_CONTENT_GET_IFACE (content)->get_preferred_size (content, | ||||
|                                                                   width, | ||||
|                                                                   height); | ||||
| } | ||||
| @@ -1,90 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2012  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> | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <clutter/clutter.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include "clutter/clutter-types.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CLUTTER_TYPE_CONTENT (clutter_content_get_type ()) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_INTERFACE (ClutterContent, clutter_content, CLUTTER, CONTENT, GObject) | ||||
|  | ||||
| /** | ||||
|  * ClutterContentInterface: | ||||
|  * @get_preferred_size: virtual function; should be overridden by subclasses | ||||
|  *   of #ClutterContent that have a natural size | ||||
|  * @paint_content: virtual function; called each time the content needs to | ||||
|  *   paint itself | ||||
|  * @attached: virtual function; called each time a #ClutterContent is attached | ||||
|  *   to a #ClutterActor. | ||||
|  * @detached: virtual function; called each time a #ClutterContent is detached | ||||
|  *   from a #ClutterActor. | ||||
|  * @invalidate: virtual function; called each time a #ClutterContent state | ||||
|  *   is changed. | ||||
|  * | ||||
|  * The #ClutterContentInterface structure contains only | ||||
|  * private data. | ||||
|  */ | ||||
| struct _ClutterContentInterface | ||||
| { | ||||
|   /*< private >*/ | ||||
|   GTypeInterface g_iface; | ||||
|  | ||||
|   /*< public >*/ | ||||
|   gboolean      (* get_preferred_size)  (ClutterContent   *content, | ||||
|                                          gfloat           *width, | ||||
|                                          gfloat           *height); | ||||
|   void          (* paint_content)       (ClutterContent      *content, | ||||
|                                          ClutterActor        *actor, | ||||
|                                          ClutterPaintNode    *node, | ||||
|                                          ClutterPaintContext *paint_context); | ||||
|  | ||||
|   void          (* attached)            (ClutterContent   *content, | ||||
|                                          ClutterActor     *actor); | ||||
|   void          (* detached)            (ClutterContent   *content, | ||||
|                                          ClutterActor     *actor); | ||||
|  | ||||
|   void          (* invalidate)          (ClutterContent   *content); | ||||
|  | ||||
|   void          (* invalidate_size)     (ClutterContent   *content); | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| gboolean        clutter_content_get_preferred_size      (ClutterContent *content, | ||||
|                                                          gfloat         *width, | ||||
|                                                          gfloat         *height); | ||||
| CLUTTER_EXPORT | ||||
| void            clutter_content_invalidate              (ClutterContent *content); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void            clutter_content_invalidate_size         (ClutterContent *content); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,48 +0,0 @@ | ||||
| /* | ||||
|  * Copyright (C) 2006 OpenedHand | ||||
|  * Copyright (C) 2023 Red Hat | ||||
|  * | ||||
|  * 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/>. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "clutter/clutter-context.h" | ||||
|  | ||||
| struct _ClutterContext | ||||
| { | ||||
|   GObject parent; | ||||
|  | ||||
|   ClutterBackend *backend; | ||||
|   ClutterStageManager *stage_manager; | ||||
|  | ||||
|   GAsyncQueue *events_queue; | ||||
|  | ||||
|   /* the event filters added via clutter_event_add_filter. these are | ||||
|    * ordered from least recently added to most recently added */ | ||||
|   GList *event_filters; | ||||
|  | ||||
|   CoglPangoFontMap *font_map; | ||||
|  | ||||
|   GSList *current_event; | ||||
|  | ||||
|   GList *repaint_funcs; | ||||
|   guint last_repaint_id; | ||||
|  | ||||
|   ClutterSettings *settings; | ||||
|  | ||||
|   gboolean is_initialized; | ||||
|   gboolean show_fps; | ||||
| }; | ||||
| @@ -1,319 +0,0 @@ | ||||
| /* | ||||
|  * Copyright (C) 2006 OpenedHand | ||||
|  * | ||||
|  * 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 "config.h" | ||||
|  | ||||
| #include "clutter/clutter-context-private.h" | ||||
|  | ||||
| #include <hb-glib.h> | ||||
|  | ||||
| #include "cally/cally.h" | ||||
| #include "clutter/clutter-backend-private.h" | ||||
| #include "clutter/clutter-debug.h" | ||||
| #include "clutter/clutter-graphene.h" | ||||
| #include "clutter/clutter-main.h" | ||||
| #include "clutter/clutter-paint-node-private.h" | ||||
| #include "clutter/clutter-settings-private.h" | ||||
|  | ||||
| static gboolean clutter_disable_mipmap_text = FALSE; | ||||
| static gboolean clutter_show_fps = FALSE; | ||||
|  | ||||
| #ifdef CLUTTER_ENABLE_DEBUG | ||||
| static const GDebugKey clutter_debug_keys[] = { | ||||
|   { "misc", CLUTTER_DEBUG_MISC }, | ||||
|   { "actor", CLUTTER_DEBUG_ACTOR }, | ||||
|   { "texture", CLUTTER_DEBUG_TEXTURE }, | ||||
|   { "event", CLUTTER_DEBUG_EVENT }, | ||||
|   { "paint", CLUTTER_DEBUG_PAINT }, | ||||
|   { "pick", CLUTTER_DEBUG_PICK }, | ||||
|   { "pango", CLUTTER_DEBUG_PANGO }, | ||||
|   { "backend", CLUTTER_DEBUG_BACKEND }, | ||||
|   { "scheduler", CLUTTER_DEBUG_SCHEDULER }, | ||||
|   { "script", CLUTTER_DEBUG_SCRIPT }, | ||||
|   { "shader", CLUTTER_DEBUG_SHADER }, | ||||
|   { "animation", CLUTTER_DEBUG_ANIMATION }, | ||||
|   { "layout", CLUTTER_DEBUG_LAYOUT }, | ||||
|   { "clipping", CLUTTER_DEBUG_CLIPPING }, | ||||
|   { "oob-transforms", CLUTTER_DEBUG_OOB_TRANSFORMS }, | ||||
|   { "frame-timings", CLUTTER_DEBUG_FRAME_TIMINGS }, | ||||
|   { "detailed-trace", CLUTTER_DEBUG_DETAILED_TRACE }, | ||||
|   { "grabs", CLUTTER_DEBUG_GRABS }, | ||||
|   { "frame-clock", CLUTTER_DEBUG_FRAME_CLOCK }, | ||||
|   { "gestures", CLUTTER_DEBUG_GESTURES }, | ||||
| }; | ||||
| #endif /* CLUTTER_ENABLE_DEBUG */ | ||||
|  | ||||
| static const GDebugKey clutter_pick_debug_keys[] = { | ||||
|   { "nop-picking", CLUTTER_DEBUG_NOP_PICKING }, | ||||
| }; | ||||
|  | ||||
| static const GDebugKey clutter_paint_debug_keys[] = { | ||||
|   { "disable-swap-events", CLUTTER_DEBUG_DISABLE_SWAP_EVENTS }, | ||||
|   { "disable-clipped-redraws", CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS }, | ||||
|   { "redraws", CLUTTER_DEBUG_REDRAWS }, | ||||
|   { "paint-volumes", CLUTTER_DEBUG_PAINT_VOLUMES }, | ||||
|   { "disable-culling", CLUTTER_DEBUG_DISABLE_CULLING }, | ||||
|   { "disable-offscreen-redirect", CLUTTER_DEBUG_DISABLE_OFFSCREEN_REDIRECT }, | ||||
|   { "continuous-redraw", CLUTTER_DEBUG_CONTINUOUS_REDRAW }, | ||||
|   { "paint-deform-tiles", CLUTTER_DEBUG_PAINT_DEFORM_TILES }, | ||||
|   { "damage-region", CLUTTER_DEBUG_PAINT_DAMAGE_REGION }, | ||||
|   { "disable-dynamic-max-render-time", CLUTTER_DEBUG_DISABLE_DYNAMIC_MAX_RENDER_TIME }, | ||||
|   { "max-render-time", CLUTTER_DEBUG_PAINT_MAX_RENDER_TIME }, | ||||
| }; | ||||
|  | ||||
| typedef struct _ClutterContextPrivate | ||||
| { | ||||
|   ClutterTextDirection text_direction; | ||||
| } ClutterContextPrivate; | ||||
|  | ||||
| G_DEFINE_TYPE_WITH_PRIVATE (ClutterContext, clutter_context, G_TYPE_OBJECT) | ||||
|  | ||||
| static void | ||||
| clutter_context_dispose (GObject *object) | ||||
| { | ||||
|   ClutterContext *context = CLUTTER_CONTEXT (object); | ||||
|  | ||||
|   g_clear_pointer (&context->events_queue, g_async_queue_unref); | ||||
|   g_clear_pointer (&context->backend, clutter_backend_destroy); | ||||
|  | ||||
|   G_OBJECT_CLASS (clutter_context_parent_class)->dispose (object); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_context_class_init (ClutterContextClass *klass) | ||||
| { | ||||
|   GObjectClass *object_class = G_OBJECT_CLASS (klass); | ||||
|  | ||||
|   object_class->dispose = clutter_context_dispose; | ||||
|  | ||||
|   clutter_graphene_init (); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_context_init (ClutterContext *context) | ||||
| { | ||||
|   ClutterContextPrivate *priv = clutter_context_get_instance_private (context); | ||||
|  | ||||
|   priv->text_direction = CLUTTER_TEXT_DIRECTION_LTR; | ||||
| } | ||||
|  | ||||
| ClutterTextDirection | ||||
| clutter_get_text_direction (void) | ||||
| { | ||||
|   ClutterTextDirection dir = CLUTTER_TEXT_DIRECTION_LTR; | ||||
|   const gchar *direction; | ||||
|  | ||||
|   direction = g_getenv ("CLUTTER_TEXT_DIRECTION"); | ||||
|   if (direction && *direction != '\0') | ||||
|     { | ||||
|       if (strcmp (direction, "rtl") == 0) | ||||
|         dir = CLUTTER_TEXT_DIRECTION_RTL; | ||||
|       else if (strcmp (direction, "ltr") == 0) | ||||
|         dir = CLUTTER_TEXT_DIRECTION_LTR; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       PangoLanguage *language; | ||||
|       const PangoScript *scripts; | ||||
|       int n_scripts, i; | ||||
|  | ||||
|       language = pango_language_get_default (); | ||||
|       scripts = pango_language_get_scripts (language, &n_scripts); | ||||
|  | ||||
|       for (i = 0; i < n_scripts; i++) | ||||
|         { | ||||
|           hb_script_t script; | ||||
|           hb_direction_t text_dir; | ||||
|  | ||||
|           script = hb_glib_script_to_script ((GUnicodeScript) scripts[i]); | ||||
|           text_dir = hb_script_get_horizontal_direction (script); | ||||
|  | ||||
|           if (text_dir == HB_DIRECTION_LTR) | ||||
|             dir = CLUTTER_TEXT_DIRECTION_LTR; | ||||
|           else if (text_dir == HB_DIRECTION_RTL) | ||||
|             dir = CLUTTER_TEXT_DIRECTION_RTL; | ||||
|           else | ||||
|             continue; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   CLUTTER_NOTE (MISC, "Text direction: %s", | ||||
|                 dir == CLUTTER_TEXT_DIRECTION_RTL ? "rtl" : "ltr"); | ||||
|  | ||||
|   return dir; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| clutter_context_init_real (ClutterContext       *context, | ||||
|                            ClutterContextFlags   flags, | ||||
|                            GError              **error) | ||||
| { | ||||
|   ClutterContextPrivate *priv = clutter_context_get_instance_private (context); | ||||
|  | ||||
|   /* If we are displaying the regions that would get redrawn with clipped | ||||
|    * redraws enabled we actually have to disable the clipped redrawing | ||||
|    * because otherwise we end up with nasty trails of rectangles everywhere. | ||||
|    */ | ||||
|   if (clutter_paint_debug_flags & CLUTTER_DEBUG_REDRAWS) | ||||
|     clutter_paint_debug_flags |= CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS; | ||||
|  | ||||
|   /* The same is true when drawing the outlines of paint volumes... */ | ||||
|   if (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_VOLUMES) | ||||
|     { | ||||
|       clutter_paint_debug_flags |= | ||||
|         CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS | CLUTTER_DEBUG_DISABLE_CULLING; | ||||
|     } | ||||
|  | ||||
|   if (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION) | ||||
|     g_message ("Enabling damaged region"); | ||||
|  | ||||
|   if (!_clutter_backend_create_context (context->backend, error)) | ||||
|     return FALSE; | ||||
|  | ||||
|   priv->text_direction = clutter_get_text_direction (); | ||||
|  | ||||
|   context->is_initialized = TRUE; | ||||
|  | ||||
|   /* Initialize a11y */ | ||||
|   if (!(flags & CLUTTER_CONTEXT_FLAG_NO_A11Y)) | ||||
|     cally_accessibility_init (); | ||||
|  | ||||
|   /* Initialize types required for paint nodes */ | ||||
|   clutter_paint_node_init_types (context->backend); | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| init_clutter_debug (ClutterContext *context) | ||||
| { | ||||
|   const char *env_string; | ||||
|  | ||||
| #ifdef CLUTTER_ENABLE_DEBUG | ||||
|   env_string = g_getenv ("CLUTTER_DEBUG"); | ||||
|   if (env_string != NULL) | ||||
|     { | ||||
|       clutter_debug_flags = | ||||
|         g_parse_debug_string (env_string, | ||||
|                               clutter_debug_keys, | ||||
|                               G_N_ELEMENTS (clutter_debug_keys)); | ||||
|       env_string = NULL; | ||||
|     } | ||||
| #endif /* CLUTTER_ENABLE_DEBUG */ | ||||
|  | ||||
|   env_string = g_getenv ("CLUTTER_PICK"); | ||||
|   if (env_string != NULL) | ||||
|     { | ||||
|       clutter_pick_debug_flags = | ||||
|         g_parse_debug_string (env_string, | ||||
|                               clutter_pick_debug_keys, | ||||
|                               G_N_ELEMENTS (clutter_pick_debug_keys)); | ||||
|       env_string = NULL; | ||||
|     } | ||||
|  | ||||
|   env_string = g_getenv ("CLUTTER_PAINT"); | ||||
|   if (env_string != NULL) | ||||
|     { | ||||
|       clutter_paint_debug_flags = | ||||
|         g_parse_debug_string (env_string, | ||||
|                               clutter_paint_debug_keys, | ||||
|                               G_N_ELEMENTS (clutter_paint_debug_keys)); | ||||
|       env_string = NULL; | ||||
|     } | ||||
|  | ||||
|   env_string = g_getenv ("CLUTTER_SHOW_FPS"); | ||||
|   if (env_string) | ||||
|     clutter_show_fps = TRUE; | ||||
|  | ||||
|   env_string = g_getenv ("CLUTTER_DISABLE_MIPMAPPED_TEXT"); | ||||
|   if (env_string) | ||||
|     clutter_disable_mipmap_text = TRUE; | ||||
| } | ||||
|  | ||||
| ClutterContext * | ||||
| clutter_context_new (ClutterContextFlags         flags, | ||||
|                      ClutterBackendConstructor   backend_constructor, | ||||
|                      gpointer                    user_data, | ||||
|                      GError                    **error) | ||||
| { | ||||
|   ClutterContext *context; | ||||
|  | ||||
|   context = g_object_new (CLUTTER_TYPE_CONTEXT, NULL); | ||||
|  | ||||
|   init_clutter_debug (context); | ||||
|   context->show_fps = clutter_show_fps; | ||||
|   context->is_initialized = FALSE; | ||||
|  | ||||
|   context->backend = backend_constructor (user_data); | ||||
|   context->settings = clutter_settings_get_default (); | ||||
|   _clutter_settings_set_backend (context->settings, | ||||
|                                  context->backend); | ||||
|  | ||||
|   context->events_queue = | ||||
|     g_async_queue_new_full ((GDestroyNotify) clutter_event_free); | ||||
|   context->last_repaint_id = 1; | ||||
|  | ||||
|   if (!clutter_context_init_real (context, flags, error)) | ||||
|     return NULL; | ||||
|  | ||||
|   return context; | ||||
| } | ||||
|  | ||||
| void | ||||
| clutter_context_destroy (ClutterContext *context) | ||||
| { | ||||
|   g_object_run_dispose (G_OBJECT (context)); | ||||
|   g_object_unref (context); | ||||
| } | ||||
|  | ||||
| ClutterBackend * | ||||
| clutter_context_get_backend (ClutterContext *context) | ||||
| { | ||||
|   return context->backend; | ||||
| } | ||||
|  | ||||
| CoglPangoFontMap * | ||||
| clutter_context_get_pango_fontmap (ClutterContext *context) | ||||
| { | ||||
|   CoglPangoFontMap *font_map; | ||||
|   gdouble resolution; | ||||
|   gboolean use_mipmapping; | ||||
|  | ||||
|   if (G_LIKELY (context->font_map != NULL)) | ||||
|     return context->font_map; | ||||
|  | ||||
|   font_map = COGL_PANGO_FONT_MAP (cogl_pango_font_map_new ()); | ||||
|  | ||||
|   resolution = clutter_backend_get_resolution (context->backend); | ||||
|   cogl_pango_font_map_set_resolution (font_map, resolution); | ||||
|  | ||||
|   use_mipmapping = !clutter_disable_mipmap_text; | ||||
|   cogl_pango_font_map_set_use_mipmapping (font_map, use_mipmapping); | ||||
|  | ||||
|   context->font_map = font_map; | ||||
|  | ||||
|   return context->font_map; | ||||
| } | ||||
|  | ||||
| ClutterTextDirection | ||||
| clutter_context_get_text_direction (ClutterContext *context) | ||||
| { | ||||
|   ClutterContextPrivate *priv = clutter_context_get_instance_private (context); | ||||
|  | ||||
|   return priv->text_direction; | ||||
| } | ||||
| @@ -1,67 +0,0 @@ | ||||
| /* | ||||
|  * Copyright (C) 2006 OpenedHand | ||||
|  * Copyright (C) 2023 Red Hat | ||||
|  * | ||||
|  * 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/>. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "clutter-backend.h" | ||||
| #include "clutter-stage-manager.h" | ||||
| #include "clutter-settings.h" | ||||
| #include "cogl-pango/cogl-pango.h" | ||||
|  | ||||
| typedef enum _ClutterContextFlags | ||||
| { | ||||
|   CLUTTER_CONTEXT_FLAG_NONE = 0, | ||||
|   CLUTTER_CONTEXT_FLAG_NO_A11Y = 1 << 0, | ||||
| } ClutterContextFlags; | ||||
|  | ||||
| typedef ClutterBackend * (* ClutterBackendConstructor) (gpointer user_data); | ||||
|  | ||||
| #define CLUTTER_TYPE_CONTEXT (clutter_context_get_type ()) | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_FINAL_TYPE (ClutterContext, clutter_context, | ||||
|                       CLUTTER, CONTEXT, GObject) | ||||
|  | ||||
| /** | ||||
|  * clutter_context_new: (skip) | ||||
|  */ | ||||
| ClutterContext * clutter_context_new (ClutterContextFlags         flags, | ||||
|                                       ClutterBackendConstructor   backend_constructor, | ||||
|                                       gpointer                    user_data, | ||||
|                                       GError                    **error); | ||||
|  | ||||
| /** | ||||
|  * clutter_context_destroy: (skip) | ||||
|  */ | ||||
| CLUTTER_EXPORT | ||||
| void clutter_context_destroy (ClutterContext *context); | ||||
|  | ||||
| /** | ||||
|  * clutter_context_get_backend: | ||||
|  * | ||||
|  * Returns: (transfer none): The %ClutterBackend | ||||
|  */ | ||||
| CLUTTER_EXPORT | ||||
| ClutterBackend * clutter_context_get_backend (ClutterContext *context); | ||||
|  | ||||
| /** | ||||
|  * clutter_context_get_pango_fontmap: (skip) | ||||
|  */ | ||||
| CoglPangoFontMap * clutter_context_get_pango_fontmap (ClutterContext *context); | ||||
|  | ||||
| ClutterTextDirection clutter_context_get_text_direction (ClutterContext *context); | ||||
| @@ -1,92 +0,0 @@ | ||||
| /* | ||||
|  * 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 "config.h" | ||||
|  | ||||
| #include "clutter/clutter-damage-history.h" | ||||
|  | ||||
| #define DAMAGE_HISTORY_LENGTH 0x10 | ||||
|  | ||||
| struct _ClutterDamageHistory | ||||
| { | ||||
|   MtkRegion *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], mtk_region_unref); | ||||
|  | ||||
|   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 MtkRegion      *damage) | ||||
| { | ||||
|   g_clear_pointer (&history->damages[history->index], mtk_region_unref); | ||||
|   history->damages[history->index] = mtk_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 MtkRegion * | ||||
| clutter_damage_history_lookup (ClutterDamageHistory *history, | ||||
|                                int                   age) | ||||
| { | ||||
|   return history->damages[step_damage_index (history->index, -age)]; | ||||
| } | ||||
| @@ -1,47 +0,0 @@ | ||||
| /* | ||||
|  * 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/>. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <glib.h> | ||||
|  | ||||
| #include "clutter/clutter-macros.h" | ||||
| #include "mtk/mtk.h" | ||||
|  | ||||
| typedef struct _ClutterDamageHistory ClutterDamageHistory; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterDamageHistory * clutter_damage_history_new (void); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void clutter_damage_history_free (ClutterDamageHistory *history); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| gboolean clutter_damage_history_is_age_valid (ClutterDamageHistory *history, | ||||
|                                               int                   age); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void clutter_damage_history_record (ClutterDamageHistory *history, | ||||
|                                     const MtkRegion      *damage); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void clutter_damage_history_step (ClutterDamageHistory *history); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| const MtkRegion * clutter_damage_history_lookup (ClutterDamageHistory *history, | ||||
|                                                  int                   age); | ||||
| @@ -1,51 +0,0 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <glib.h> | ||||
|  | ||||
| #include "clutter/clutter-main.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #ifdef CLUTTER_ENABLE_DEBUG | ||||
|  | ||||
| #define CLUTTER_HAS_DEBUG(type)         ((clutter_debug_flags & CLUTTER_DEBUG_##type) != FALSE) | ||||
|  | ||||
| #ifdef __GNUC__ | ||||
|  | ||||
| /* Try the GCC extension for valists in macros */ | ||||
| #define CLUTTER_NOTE(type,x,a...)                       G_STMT_START {  \ | ||||
|         if (G_UNLIKELY (CLUTTER_HAS_DEBUG (type))) {                    \ | ||||
|           _clutter_debug_message ("[" #type "]: " x, ##a); \ | ||||
|         }                                               } G_STMT_END | ||||
|  | ||||
| #else /* !__GNUC__ */ | ||||
| /* Try the C99 version; unfortunately, this does not allow us to pass | ||||
|  * empty arguments to the macro, which means we have to | ||||
|  * do an intemediate printf. | ||||
|  */ | ||||
| #define CLUTTER_NOTE(type,...)                          G_STMT_START {   \ | ||||
|         if (G_UNLIKELY (CLUTTER_HAS_DEBUG (type))) {                     \ | ||||
|           gchar *_fmt = g_strdup_printf (__VA_ARGS__);                   \ | ||||
|           _clutter_debug_message ("[" #type "]: %s", _fmt); \ | ||||
|           g_free (_fmt);                                                 \ | ||||
|         }                                               } G_STMT_END | ||||
| #endif | ||||
|  | ||||
| #else /* !CLUTTER_ENABLE_DEBUG */ | ||||
|  | ||||
| #define CLUTTER_NOTE(type,...)         G_STMT_START { } G_STMT_END | ||||
| #define CLUTTER_HAS_DEBUG(type)        FALSE | ||||
|  | ||||
| #endif /* CLUTTER_ENABLE_DEBUG */ | ||||
|  | ||||
| extern guint clutter_debug_flags; | ||||
| extern guint clutter_pick_debug_flags; | ||||
| extern guint clutter_paint_debug_flags; | ||||
| extern int clutter_max_render_time_constant_us; | ||||
|  | ||||
| void    _clutter_debug_messagev         (const char *format, | ||||
|                                          va_list     var_args) G_GNUC_PRINTF (1, 0); | ||||
| void    _clutter_debug_message          (const char *format, | ||||
|                                          ...) G_GNUC_PRINTF (1, 2); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,804 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2010  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> | ||||
|  * | ||||
|  * Based on the MxDeformTexture class, written by: | ||||
|  *   Chris Lord <chris@linux.intel.com> | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * ClutterDeformEffect: | ||||
|  *  | ||||
|  * A base class for effects deforming the geometry of an actor | ||||
|  * | ||||
|  * #ClutterDeformEffect is an abstract class providing all the plumbing | ||||
|  * for creating effects that result in the deformation of an actor's | ||||
|  * geometry. | ||||
|  * | ||||
|  * #ClutterDeformEffect uses offscreen buffers to render the contents of | ||||
|  * a #ClutterActor and then the Cogl vertex buffers API to submit the | ||||
|  * geometry to the GPU. | ||||
|  * | ||||
|  * ## Implementing ClutterDeformEffect | ||||
|  * | ||||
|  * Sub-classes of #ClutterDeformEffect should override the | ||||
|  * [vfunc@Clutter.DeformEffect.deform_vertex] virtual function; this function | ||||
|  * is called on every vertex that needs to be deformed by the effect. | ||||
|  * Each passed vertex is an in-out parameter that initially contains the | ||||
|  * position of the vertex and should be modified according to a specific | ||||
|  * deformation algorithm. | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include "cogl/cogl.h" | ||||
|  | ||||
| #include "clutter/clutter-deform-effect.h" | ||||
| #include "clutter/clutter-color.h" | ||||
| #include "clutter/clutter-debug.h" | ||||
| #include "clutter/clutter-enum-types.h" | ||||
| #include "clutter/clutter-paint-node.h" | ||||
| #include "clutter/clutter-paint-nodes.h" | ||||
| #include "clutter/clutter-private.h" | ||||
|  | ||||
| #define DEFAULT_N_TILES         32 | ||||
|  | ||||
| typedef struct _ClutterDeformEffectPrivate | ||||
| { | ||||
|   CoglPipeline *back_pipeline; | ||||
|  | ||||
|   gint x_tiles; | ||||
|   gint y_tiles; | ||||
|  | ||||
|   CoglAttributeBuffer *buffer; | ||||
|  | ||||
|   CoglPrimitive *primitive; | ||||
|  | ||||
|   CoglPrimitive *lines_primitive; | ||||
|  | ||||
|   gint n_vertices; | ||||
|  | ||||
|   gulong allocation_id; | ||||
|  | ||||
|   guint is_dirty : 1; | ||||
| } ClutterDeformEffectPrivate; | ||||
|  | ||||
| enum | ||||
| { | ||||
|   PROP_0, | ||||
|  | ||||
|   PROP_X_TILES, | ||||
|   PROP_Y_TILES, | ||||
|  | ||||
|   PROP_BACK_MATERIAL, | ||||
|  | ||||
|   PROP_LAST | ||||
| }; | ||||
|  | ||||
| static GParamSpec *obj_props[PROP_LAST]; | ||||
|  | ||||
| G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterDeformEffect, | ||||
|                                      clutter_deform_effect, | ||||
|                                      CLUTTER_TYPE_OFFSCREEN_EFFECT) | ||||
|  | ||||
| static void | ||||
| clutter_deform_effect_real_deform_vertex (ClutterDeformEffect *effect, | ||||
|                                           gfloat               width, | ||||
|                                           gfloat               height, | ||||
|                                           CoglTextureVertex   *vertex) | ||||
| { | ||||
|   g_warning ("%s: Deformation effect of type '%s' does not implement " | ||||
|              "the required ClutterDeformEffect::deform_vertex virtual " | ||||
|              "function.", | ||||
|              G_STRLOC, | ||||
|              G_OBJECT_TYPE_NAME (effect)); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_deform_effect_deform_vertex (ClutterDeformEffect *effect, | ||||
|                                      gfloat               width, | ||||
|                                      gfloat               height, | ||||
|                                      CoglTextureVertex   *vertex) | ||||
| { | ||||
|   CLUTTER_DEFORM_EFFECT_GET_CLASS (effect)->deform_vertex (effect, | ||||
|                                                            width, height, | ||||
|                                                            vertex); | ||||
| } | ||||
|  | ||||
| static void | ||||
| vbo_invalidate (ClutterActor        *actor, | ||||
|                 GParamSpec          *pspec, | ||||
|                 ClutterDeformEffect *effect) | ||||
| { | ||||
|   ClutterDeformEffectPrivate *priv = | ||||
|     clutter_deform_effect_get_instance_private (effect); | ||||
|  | ||||
|   priv->is_dirty = TRUE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_deform_effect_set_actor (ClutterActorMeta *meta, | ||||
|                                  ClutterActor     *actor) | ||||
| { | ||||
|   ClutterDeformEffect *effect = CLUTTER_DEFORM_EFFECT (meta); | ||||
|   ClutterDeformEffectPrivate *priv = | ||||
|     clutter_deform_effect_get_instance_private (effect); | ||||
|  | ||||
|   if (priv->allocation_id != 0) | ||||
|     { | ||||
|       ClutterActor *old_actor = clutter_actor_meta_get_actor (meta); | ||||
|  | ||||
|       if (old_actor != NULL) | ||||
|         g_clear_signal_handler (&priv->allocation_id, old_actor); | ||||
|  | ||||
|       priv->allocation_id = 0; | ||||
|     } | ||||
|  | ||||
|   /* we need to invalidate the VBO whenever the allocation of the actor | ||||
|    * changes | ||||
|    */ | ||||
|   if (actor != NULL) | ||||
|     priv->allocation_id = g_signal_connect (actor, "notify::allocation", | ||||
|                                             G_CALLBACK (vbo_invalidate), | ||||
|                                             meta); | ||||
|  | ||||
|   priv->is_dirty = TRUE; | ||||
|  | ||||
|   CLUTTER_ACTOR_META_CLASS (clutter_deform_effect_parent_class)->set_actor (meta, actor); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect, | ||||
|                                     ClutterPaintNode       *node, | ||||
|                                     ClutterPaintContext    *paint_context) | ||||
| { | ||||
|   ClutterDeformEffect *self = CLUTTER_DEFORM_EFFECT (effect); | ||||
|   ClutterDeformEffectPrivate *priv = | ||||
|     clutter_deform_effect_get_instance_private (self); | ||||
|   CoglPipeline *pipeline; | ||||
|   CoglDepthState depth_state; | ||||
|  | ||||
|   if (priv->is_dirty) | ||||
|     { | ||||
|       gboolean mapped_buffer; | ||||
|       CoglVertexP3T2C4 *verts; | ||||
|       ClutterActor *actor; | ||||
|       gfloat width, height; | ||||
|       guint opacity; | ||||
|       gint i, j; | ||||
|  | ||||
|       actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect)); | ||||
|       opacity = clutter_actor_get_paint_opacity (actor); | ||||
|  | ||||
|       /* if we don't have a target size, fall back to the actor's | ||||
|        * allocation, though wrong it might be | ||||
|        */ | ||||
|       if (!clutter_offscreen_effect_get_target_size (effect, &width, &height)) | ||||
|         clutter_actor_get_size (actor, &width, &height); | ||||
|  | ||||
|       /* XXX ideally, the sub-classes should tell us what they | ||||
|        * changed in the texture vertices; we then would be able to | ||||
|        * avoid resubmitting the same data, if it did not change. for | ||||
|        * the time being, we resubmit everything | ||||
|        */ | ||||
|       verts = cogl_buffer_map (COGL_BUFFER (priv->buffer), | ||||
|                                COGL_BUFFER_ACCESS_WRITE, | ||||
|                                COGL_BUFFER_MAP_HINT_DISCARD); | ||||
|  | ||||
|       /* If the map failed then we'll resort to allocating a temporary | ||||
|          buffer */ | ||||
|       if (verts == NULL) | ||||
|         { | ||||
|           mapped_buffer = FALSE; | ||||
|           verts = g_malloc (sizeof (*verts) * priv->n_vertices); | ||||
|         } | ||||
|       else | ||||
|         mapped_buffer = TRUE; | ||||
|  | ||||
|       for (i = 0; i < priv->y_tiles + 1; i++) | ||||
|         { | ||||
|           for (j = 0; j < priv->x_tiles + 1; j++) | ||||
|             { | ||||
|               CoglVertexP3T2C4 *vertex_out; | ||||
|               CoglTextureVertex vertex; | ||||
|  | ||||
|               /* CoglTextureVertex isn't an ideal structure to use for | ||||
|                  this because it contains a CoglColor. The internal | ||||
|                  layout of CoglColor is mean to be private so Clutter | ||||
|                  can not pass a pointer to it as a vertex | ||||
|                  attribute. Also it contains padding so we end up | ||||
|                  storing more data in the vertex buffer than we need | ||||
|                  to. Instead we let the application modify a dummy | ||||
|                  vertex and then copy the details back out to a more | ||||
|                  well-defined struct */ | ||||
|  | ||||
|               vertex.tx = (float) j / priv->x_tiles; | ||||
|               vertex.ty = (float) i / priv->y_tiles; | ||||
|  | ||||
|               vertex.x = width * vertex.tx; | ||||
|               vertex.y = height * vertex.ty; | ||||
|               vertex.z = 0.0f; | ||||
|  | ||||
|               cogl_color_init_from_4f (&vertex.color, 1.0, 1.0, 1.0, opacity / 255.0); | ||||
|  | ||||
|               clutter_deform_effect_deform_vertex (self, | ||||
|                                                    width, height, | ||||
|                                                    &vertex); | ||||
|  | ||||
|               vertex_out = verts + i * (priv->x_tiles + 1) + j; | ||||
|  | ||||
|               vertex_out->x = vertex.x; | ||||
|               vertex_out->y = vertex.y; | ||||
|               vertex_out->z = vertex.z; | ||||
|               vertex_out->s = vertex.tx; | ||||
|               vertex_out->t = vertex.ty; | ||||
|               vertex_out->r = cogl_color_get_red (&vertex.color) * 255.0; | ||||
|               vertex_out->g = cogl_color_get_green (&vertex.color) * 255.0; | ||||
|               vertex_out->b = cogl_color_get_blue (&vertex.color) * 255.0; | ||||
|               vertex_out->a = cogl_color_get_alpha (&vertex.color) * 255.0; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|       if (mapped_buffer) | ||||
|         cogl_buffer_unmap (COGL_BUFFER (priv->buffer)); | ||||
|       else | ||||
|         { | ||||
|           cogl_buffer_set_data (COGL_BUFFER (priv->buffer), | ||||
|                                 0, /* offset */ | ||||
|                                 verts, | ||||
|                                 sizeof (*verts) * priv->n_vertices); | ||||
|           g_free (verts); | ||||
|         } | ||||
|  | ||||
|       priv->is_dirty = FALSE; | ||||
|     } | ||||
|  | ||||
|   pipeline = clutter_offscreen_effect_get_pipeline (effect); | ||||
|  | ||||
|   /* enable depth testing */ | ||||
|   cogl_depth_state_init (&depth_state); | ||||
|   cogl_depth_state_set_test_enabled (&depth_state, TRUE); | ||||
|   cogl_depth_state_set_test_function (&depth_state, COGL_DEPTH_TEST_FUNCTION_LEQUAL); | ||||
|   cogl_pipeline_set_depth_state (pipeline, &depth_state, NULL); | ||||
|  | ||||
|   /* enable backface culling if we have a back material */ | ||||
|   if (priv->back_pipeline != NULL) | ||||
|     cogl_pipeline_set_cull_face_mode (pipeline, | ||||
|                                       COGL_PIPELINE_CULL_FACE_MODE_BACK); | ||||
|  | ||||
|   /* draw the front */ | ||||
|   if (pipeline != NULL) | ||||
|     { | ||||
|       ClutterPaintNode *front_node; | ||||
|  | ||||
|       front_node = clutter_pipeline_node_new (pipeline); | ||||
|       clutter_paint_node_set_static_name (front_node, | ||||
|                                           "ClutterDeformEffect (front)"); | ||||
|       clutter_paint_node_add_child (node, front_node); | ||||
|       clutter_paint_node_add_primitive (front_node, priv->primitive); | ||||
|       clutter_paint_node_unref (front_node); | ||||
|     } | ||||
|  | ||||
|   /* draw the back */ | ||||
|   if (priv->back_pipeline != NULL) | ||||
|     { | ||||
|       ClutterPaintNode *back_node; | ||||
|       CoglPipeline *back_pipeline; | ||||
|  | ||||
|       /* We probably shouldn't be modifying the user's material so | ||||
|          instead we make a temporary copy */ | ||||
|       back_pipeline = cogl_pipeline_copy (priv->back_pipeline); | ||||
|       cogl_pipeline_set_depth_state (back_pipeline, &depth_state, NULL); | ||||
|       cogl_pipeline_set_cull_face_mode (back_pipeline, | ||||
|                                         COGL_PIPELINE_CULL_FACE_MODE_FRONT); | ||||
|  | ||||
|  | ||||
|       back_node = clutter_pipeline_node_new (back_pipeline); | ||||
|       clutter_paint_node_set_static_name (back_node, | ||||
|                                           "ClutterDeformEffect (back)"); | ||||
|       clutter_paint_node_add_child (node, back_node); | ||||
|       clutter_paint_node_add_primitive (back_node, priv->primitive); | ||||
|  | ||||
|       clutter_paint_node_unref (back_node); | ||||
|       g_object_unref (back_pipeline); | ||||
|     } | ||||
|  | ||||
|   if (G_UNLIKELY (priv->lines_primitive != NULL)) | ||||
|     { | ||||
|       static ClutterColor red = CLUTTER_COLOR_INIT (255, 0, 0, 255); | ||||
|       ClutterPaintNode *lines_node; | ||||
|  | ||||
|       lines_node = clutter_color_node_new (&red); | ||||
|       clutter_paint_node_set_static_name (lines_node, | ||||
|                                           "ClutterDeformEffect (lines)"); | ||||
|       clutter_paint_node_add_child (node, lines_node); | ||||
|       clutter_paint_node_add_primitive (lines_node, priv->lines_primitive); | ||||
|       clutter_paint_node_unref (lines_node); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static inline void | ||||
| clutter_deform_effect_free_arrays (ClutterDeformEffect *self) | ||||
| { | ||||
|   ClutterDeformEffectPrivate *priv = | ||||
|     clutter_deform_effect_get_instance_private (self); | ||||
|  | ||||
|   g_clear_object (&priv->buffer); | ||||
|   g_clear_object (&priv->primitive); | ||||
|   g_clear_object (&priv->lines_primitive); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_deform_effect_init_arrays (ClutterDeformEffect *self) | ||||
| { | ||||
|   ClutterDeformEffectPrivate *priv = | ||||
|     clutter_deform_effect_get_instance_private (self); | ||||
|   gint x, y, direction, n_indices; | ||||
|   CoglAttribute *attributes[3]; | ||||
|   guint16 *static_indices; | ||||
|   CoglContext *ctx = | ||||
|     clutter_backend_get_cogl_context (clutter_get_default_backend ()); | ||||
|   CoglIndices *indices; | ||||
|   guint16 *idx; | ||||
|   int i; | ||||
|  | ||||
|   clutter_deform_effect_free_arrays (self); | ||||
|  | ||||
|   n_indices = ((2 + 2 * priv->x_tiles) | ||||
|                * priv->y_tiles | ||||
|                + (priv->y_tiles - 1)); | ||||
|  | ||||
|   static_indices = g_new (guint16, n_indices); | ||||
|  | ||||
| #define MESH_INDEX(x,y) ((y) * (priv->x_tiles + 1) + (x)) | ||||
|  | ||||
|   /* compute all the triangles from the various tiles */ | ||||
|   direction = 1; | ||||
|  | ||||
|   idx = static_indices; | ||||
|   idx[0] = MESH_INDEX (0, 0); | ||||
|   idx[1] = MESH_INDEX (0, 1); | ||||
|   idx += 2; | ||||
|  | ||||
|   for (y = 0; y < priv->y_tiles; y++) | ||||
|     { | ||||
|       for (x = 0; x < priv->x_tiles; x++) | ||||
|         { | ||||
|           if (direction) | ||||
|             { | ||||
|               idx[0] = MESH_INDEX (x + 1, y); | ||||
|               idx[1] = MESH_INDEX (x + 1, y + 1); | ||||
|             } | ||||
|           else | ||||
|             { | ||||
|               idx[0] = MESH_INDEX (priv->x_tiles - x - 1, y); | ||||
|               idx[1] = MESH_INDEX (priv->x_tiles - x - 1, y + 1); | ||||
|             } | ||||
|  | ||||
|           idx += 2; | ||||
|         } | ||||
|  | ||||
|       if (y == (priv->y_tiles - 1)) | ||||
|         break; | ||||
|  | ||||
|       if (direction) | ||||
|         { | ||||
|           idx[0] = MESH_INDEX (priv->x_tiles, y + 1); | ||||
|           idx[1] = MESH_INDEX (priv->x_tiles, y + 1); | ||||
|           idx[2] = MESH_INDEX (priv->x_tiles, y + 2); | ||||
|         } | ||||
|       else | ||||
|         { | ||||
|           idx[0] = MESH_INDEX (0, y + 1); | ||||
|           idx[1] = MESH_INDEX (0, y + 1); | ||||
|           idx[2] = MESH_INDEX (0, y + 2); | ||||
|         } | ||||
|  | ||||
|       idx += 3; | ||||
|  | ||||
|       direction = !direction; | ||||
|     } | ||||
|  | ||||
| #undef MESH_INDEX | ||||
|  | ||||
|   indices = cogl_indices_new (ctx, | ||||
|                               COGL_INDICES_TYPE_UNSIGNED_SHORT, | ||||
|                               static_indices, | ||||
|                               n_indices); | ||||
|  | ||||
|   g_free (static_indices); | ||||
|  | ||||
|   priv->n_vertices = (priv->x_tiles + 1) * (priv->y_tiles + 1); | ||||
|  | ||||
|   priv->buffer = | ||||
|     cogl_attribute_buffer_new (ctx, | ||||
|                                sizeof (CoglVertexP3T2C4) * | ||||
|                                priv->n_vertices, | ||||
|                                NULL); | ||||
|  | ||||
|   /* The application is expected to continuously modify the vertices | ||||
|      so we should give a hint to Cogl about that */ | ||||
|   cogl_buffer_set_update_hint (COGL_BUFFER (priv->buffer), | ||||
|                                COGL_BUFFER_UPDATE_HINT_DYNAMIC); | ||||
|  | ||||
|   attributes[0] = cogl_attribute_new (priv->buffer, | ||||
|                                       "cogl_position_in", | ||||
|                                       sizeof (CoglVertexP3T2C4), | ||||
|                                       G_STRUCT_OFFSET (CoglVertexP3T2C4, x), | ||||
|                                       3, /* n_components */ | ||||
|                                       COGL_ATTRIBUTE_TYPE_FLOAT); | ||||
|   attributes[1] = cogl_attribute_new (priv->buffer, | ||||
|                                       "cogl_tex_coord0_in", | ||||
|                                       sizeof (CoglVertexP3T2C4), | ||||
|                                       G_STRUCT_OFFSET (CoglVertexP3T2C4, s), | ||||
|                                       2, /* n_components */ | ||||
|                                       COGL_ATTRIBUTE_TYPE_FLOAT); | ||||
|   attributes[2] = cogl_attribute_new (priv->buffer, | ||||
|                                       "cogl_color_in", | ||||
|                                       sizeof (CoglVertexP3T2C4), | ||||
|                                       G_STRUCT_OFFSET (CoglVertexP3T2C4, r), | ||||
|                                       4, /* n_components */ | ||||
|                                       COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE); | ||||
|  | ||||
|   priv->primitive = | ||||
|     cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLE_STRIP, | ||||
|                                         priv->n_vertices, | ||||
|                                         attributes, | ||||
|                                         3 /* n_attributes */); | ||||
|   cogl_primitive_set_indices (priv->primitive, | ||||
|                               indices, | ||||
|                               n_indices); | ||||
|  | ||||
|   if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DEFORM_TILES)) | ||||
|     { | ||||
|       priv->lines_primitive = | ||||
|         cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_LINE_STRIP, | ||||
|                                             priv->n_vertices, | ||||
|                                             attributes, | ||||
|                                             2 /* n_attributes */); | ||||
|       cogl_primitive_set_indices (priv->lines_primitive, | ||||
|                                   indices, | ||||
|                                   n_indices); | ||||
|     } | ||||
|  | ||||
|   g_object_unref (indices); | ||||
|  | ||||
|   for (i = 0; i < 3; i++) | ||||
|     g_object_unref (attributes[i]); | ||||
|  | ||||
|   priv->is_dirty = TRUE; | ||||
| } | ||||
|  | ||||
| static inline void | ||||
| clutter_deform_effect_free_back_pipeline (ClutterDeformEffect *self) | ||||
| { | ||||
|   ClutterDeformEffectPrivate *priv = | ||||
|     clutter_deform_effect_get_instance_private (self); | ||||
|  | ||||
|   g_clear_object (&priv->back_pipeline); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_deform_effect_finalize (GObject *gobject) | ||||
| { | ||||
|   ClutterDeformEffect *self = CLUTTER_DEFORM_EFFECT (gobject); | ||||
|  | ||||
|   clutter_deform_effect_free_arrays (self); | ||||
|   clutter_deform_effect_free_back_pipeline (self); | ||||
|  | ||||
|   G_OBJECT_CLASS (clutter_deform_effect_parent_class)->finalize (gobject); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_deform_effect_set_property (GObject      *gobject, | ||||
|                                     guint         prop_id, | ||||
|                                     const GValue *value, | ||||
|                                     GParamSpec   *pspec) | ||||
| { | ||||
|   ClutterDeformEffect *self = CLUTTER_DEFORM_EFFECT (gobject); | ||||
|   ClutterDeformEffectPrivate *priv = | ||||
|     clutter_deform_effect_get_instance_private (self); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_X_TILES: | ||||
|       clutter_deform_effect_set_n_tiles (self, g_value_get_uint (value), | ||||
|                                          priv->y_tiles); | ||||
|       break; | ||||
|  | ||||
|     case PROP_Y_TILES: | ||||
|       clutter_deform_effect_set_n_tiles (self, priv->x_tiles, | ||||
|                                          g_value_get_uint (value)); | ||||
|       break; | ||||
|  | ||||
|     case PROP_BACK_MATERIAL: | ||||
|       clutter_deform_effect_set_back_material (self, g_value_get_object (value)); | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_deform_effect_get_property (GObject    *gobject, | ||||
|                                     guint       prop_id, | ||||
|                                     GValue     *value, | ||||
|                                     GParamSpec *pspec) | ||||
| { | ||||
|   ClutterDeformEffect *effect = CLUTTER_DEFORM_EFFECT (gobject); | ||||
|   ClutterDeformEffectPrivate *priv = | ||||
|     clutter_deform_effect_get_instance_private (effect); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_X_TILES: | ||||
|       g_value_set_uint (value, priv->x_tiles); | ||||
|       break; | ||||
|  | ||||
|     case PROP_Y_TILES: | ||||
|       g_value_set_uint (value, priv->y_tiles); | ||||
|       break; | ||||
|  | ||||
|     case PROP_BACK_MATERIAL: | ||||
|       g_value_set_object (value, priv->back_pipeline); | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_deform_effect_class_init (ClutterDeformEffectClass *klass) | ||||
| { | ||||
|   GObjectClass *gobject_class = G_OBJECT_CLASS (klass); | ||||
|   ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass); | ||||
|   ClutterOffscreenEffectClass *offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass); | ||||
|  | ||||
|   klass->deform_vertex = clutter_deform_effect_real_deform_vertex; | ||||
|  | ||||
|   /** | ||||
|    * ClutterDeformEffect:x-tiles: | ||||
|    * | ||||
|    * The number of horizontal tiles. The bigger the number, the | ||||
|    * smaller the tiles | ||||
|    */ | ||||
|   obj_props[PROP_X_TILES] = | ||||
|     g_param_spec_uint ("x-tiles", NULL, NULL, | ||||
|                        1, G_MAXUINT, | ||||
|                        DEFAULT_N_TILES, | ||||
|                        G_PARAM_READWRITE | | ||||
|                        G_PARAM_STATIC_STRINGS); | ||||
|  | ||||
|   /** | ||||
|    * ClutterDeformEffect:y-tiles: | ||||
|    * | ||||
|    * The number of vertical tiles. The bigger the number, the | ||||
|    * smaller the tiles | ||||
|    */ | ||||
|   obj_props[PROP_Y_TILES] = | ||||
|     g_param_spec_uint ("y-tiles", NULL, NULL, | ||||
|                        1, G_MAXUINT, | ||||
|                        DEFAULT_N_TILES, | ||||
|                        G_PARAM_READWRITE | | ||||
|                        G_PARAM_STATIC_STRINGS); | ||||
|  | ||||
|   /** | ||||
|    * ClutterDeformEffect:back-material: | ||||
|    * | ||||
|    * A material to be used when painting the back of the actor | ||||
|    * to which this effect has been applied | ||||
|    * | ||||
|    * By default, no material will be used | ||||
|    */ | ||||
|   obj_props[PROP_BACK_MATERIAL] = | ||||
|     g_param_spec_object ("back-material", NULL, NULL, | ||||
|                          COGL_TYPE_PIPELINE, | ||||
|                          G_PARAM_READWRITE | | ||||
|                          G_PARAM_STATIC_STRINGS); | ||||
|  | ||||
|   gobject_class->finalize = clutter_deform_effect_finalize; | ||||
|   gobject_class->set_property = clutter_deform_effect_set_property; | ||||
|   gobject_class->get_property = clutter_deform_effect_get_property; | ||||
|   g_object_class_install_properties (gobject_class, | ||||
|                                      PROP_LAST, | ||||
|                                      obj_props); | ||||
|  | ||||
|   meta_class->set_actor = clutter_deform_effect_set_actor; | ||||
|  | ||||
|   offscreen_class->paint_target = clutter_deform_effect_paint_target; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_deform_effect_init (ClutterDeformEffect *self) | ||||
| { | ||||
|   ClutterDeformEffectPrivate *priv = | ||||
|     clutter_deform_effect_get_instance_private (self); | ||||
|  | ||||
|   priv->x_tiles = priv->y_tiles = DEFAULT_N_TILES; | ||||
|   priv->back_pipeline = NULL; | ||||
|  | ||||
|   clutter_deform_effect_init_arrays (self); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_deform_effect_set_back_material: | ||||
|  * @effect: a #ClutterDeformEffect | ||||
|  * @material: (allow-none): a handle to a Cogl material | ||||
|  * | ||||
|  * Sets the material that should be used when drawing the back face | ||||
|  * of the actor during a deformation | ||||
|  * | ||||
|  * The #ClutterDeformEffect will take a reference on the material's | ||||
|  * handle | ||||
|  */ | ||||
| void | ||||
| clutter_deform_effect_set_back_material (ClutterDeformEffect *effect, | ||||
|                                          CoglPipeline        *pipeline) | ||||
| { | ||||
|   ClutterDeformEffectPrivate *priv; | ||||
|  | ||||
|   g_return_if_fail (CLUTTER_IS_DEFORM_EFFECT (effect)); | ||||
|   g_return_if_fail (pipeline == NULL || COGL_IS_PIPELINE (pipeline)); | ||||
|  | ||||
|   priv = clutter_deform_effect_get_instance_private (effect); | ||||
|  | ||||
|   clutter_deform_effect_free_back_pipeline (effect); | ||||
|  | ||||
|   priv->back_pipeline = pipeline; | ||||
|   if (priv->back_pipeline != NULL) | ||||
|     g_object_ref (priv->back_pipeline); | ||||
|  | ||||
|   clutter_deform_effect_invalidate (effect); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_deform_effect_get_back_material: | ||||
|  * @effect: a #ClutterDeformEffect | ||||
|  * | ||||
|  * Retrieves the handle to the back face material used by @effect | ||||
|  * | ||||
|  * Return value: (transfer none): a handle for the material, or %NULL. | ||||
|  *   The returned material is owned by the #ClutterDeformEffect and it | ||||
|  *   should not be freed directly | ||||
|  */ | ||||
| CoglPipeline* | ||||
| clutter_deform_effect_get_back_material (ClutterDeformEffect *effect) | ||||
| { | ||||
|   ClutterDeformEffectPrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_DEFORM_EFFECT (effect), NULL); | ||||
|  | ||||
|   priv = clutter_deform_effect_get_instance_private (effect); | ||||
|   return priv->back_pipeline; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_deform_effect_set_n_tiles: | ||||
|  * @effect: a #ClutterDeformEffect | ||||
|  * @x_tiles: number of horizontal tiles | ||||
|  * @y_tiles: number of vertical tiles | ||||
|  * | ||||
|  * Sets the number of horizontal and vertical tiles to be used | ||||
|  * when applying the effect | ||||
|  * | ||||
|  * More tiles allow a finer grained deformation at the expenses | ||||
|  * of computation | ||||
|  */ | ||||
| void | ||||
| clutter_deform_effect_set_n_tiles (ClutterDeformEffect *effect, | ||||
|                                    guint                x_tiles, | ||||
|                                    guint                y_tiles) | ||||
| { | ||||
|   ClutterDeformEffectPrivate *priv; | ||||
|   gboolean tiles_changed = FALSE; | ||||
|  | ||||
|   g_return_if_fail (CLUTTER_IS_DEFORM_EFFECT (effect)); | ||||
|   g_return_if_fail (x_tiles > 0 && y_tiles > 0); | ||||
|  | ||||
|   priv = clutter_deform_effect_get_instance_private (effect); | ||||
|  | ||||
|   g_object_freeze_notify (G_OBJECT (effect)); | ||||
|  | ||||
|   if (priv->x_tiles != x_tiles) | ||||
|     { | ||||
|       priv->x_tiles = x_tiles; | ||||
|  | ||||
|       g_object_notify_by_pspec (G_OBJECT (effect), obj_props[PROP_X_TILES]); | ||||
|  | ||||
|       tiles_changed = TRUE; | ||||
|     } | ||||
|  | ||||
|   if (priv->y_tiles != y_tiles) | ||||
|     { | ||||
|       priv->y_tiles = y_tiles; | ||||
|  | ||||
|       g_object_notify_by_pspec (G_OBJECT (effect), obj_props[PROP_Y_TILES]); | ||||
|  | ||||
|       tiles_changed = TRUE; | ||||
|     } | ||||
|  | ||||
|   if (tiles_changed) | ||||
|     { | ||||
|       clutter_deform_effect_init_arrays (effect); | ||||
|       clutter_deform_effect_invalidate (effect); | ||||
|     } | ||||
|  | ||||
|   g_object_thaw_notify (G_OBJECT (effect)); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_deform_effect_get_n_tiles: | ||||
|  * @effect: a #ClutterDeformEffect | ||||
|  * @x_tiles: (out): return location for the number of horizontal tiles, | ||||
|  *   or %NULL | ||||
|  * @y_tiles: (out): return location for the number of vertical tiles, | ||||
|  *   or %NULL | ||||
|  * | ||||
|  * Retrieves the number of horizontal and vertical tiles used to sub-divide | ||||
|  * the actor's geometry during the effect | ||||
|  */ | ||||
| void | ||||
| clutter_deform_effect_get_n_tiles (ClutterDeformEffect *effect, | ||||
|                                    guint               *x_tiles, | ||||
|                                    guint               *y_tiles) | ||||
| { | ||||
|   ClutterDeformEffectPrivate *priv; | ||||
|  | ||||
|   g_return_if_fail (CLUTTER_IS_DEFORM_EFFECT (effect)); | ||||
|  | ||||
|   priv = clutter_deform_effect_get_instance_private (effect); | ||||
|   if (x_tiles != NULL) | ||||
|     *x_tiles = priv->x_tiles; | ||||
|  | ||||
|   if (y_tiles != NULL) | ||||
|     *y_tiles = priv->y_tiles; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_deform_effect_invalidate: | ||||
|  * @effect: a #ClutterDeformEffect | ||||
|  * | ||||
|  * Invalidates the `effect`'s vertices and, if it is associated | ||||
|  * to an actor, it will queue a redraw | ||||
|  */ | ||||
| void | ||||
| clutter_deform_effect_invalidate (ClutterDeformEffect *effect) | ||||
| { | ||||
|   ClutterActor *actor; | ||||
|   ClutterDeformEffectPrivate *priv; | ||||
|  | ||||
|   g_return_if_fail (CLUTTER_IS_DEFORM_EFFECT (effect)); | ||||
|  | ||||
|   priv = clutter_deform_effect_get_instance_private (effect); | ||||
|   if (priv->is_dirty) | ||||
|     return; | ||||
|  | ||||
|   priv->is_dirty = TRUE; | ||||
|  | ||||
|   actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect)); | ||||
|   if (actor != NULL) | ||||
|     clutter_effect_queue_repaint (CLUTTER_EFFECT (effect)); | ||||
| } | ||||
| @@ -1,82 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2010  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> | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <clutter/clutter.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include "cogl/cogl.h" | ||||
| #include "clutter/clutter-offscreen-effect.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CLUTTER_TYPE_DEFORM_EFFECT              (clutter_deform_effect_get_type ()) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_DERIVABLE_TYPE (ClutterDeformEffect, | ||||
|                           clutter_deform_effect, | ||||
|                           CLUTTER, | ||||
|                           DEFORM_EFFECT, | ||||
|                           ClutterOffscreenEffect) | ||||
|  | ||||
| /** | ||||
|  * ClutterDeformEffectClass: | ||||
|  * @deform_vertex: virtual function; sub-classes should override this | ||||
|  *   function to compute the deformation of each vertex | ||||
|  * | ||||
|  * The #ClutterDeformEffectClass structure contains | ||||
|  * only private data | ||||
|  */ | ||||
| struct _ClutterDeformEffectClass | ||||
| { | ||||
|   /*< private >*/ | ||||
|   ClutterOffscreenEffectClass parent_class; | ||||
|  | ||||
|   /*< public >*/ | ||||
|   void (* deform_vertex) (ClutterDeformEffect *effect, | ||||
|                           gfloat               width, | ||||
|                           gfloat               height, | ||||
|                           CoglTextureVertex   *vertex); | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void            clutter_deform_effect_set_back_material (ClutterDeformEffect *effect, | ||||
|                                                          CoglPipeline        *material); | ||||
| CLUTTER_EXPORT | ||||
| CoglPipeline*   clutter_deform_effect_get_back_material (ClutterDeformEffect *effect); | ||||
| CLUTTER_EXPORT | ||||
| void            clutter_deform_effect_set_n_tiles       (ClutterDeformEffect *effect, | ||||
|                                                          guint                x_tiles, | ||||
|                                                          guint                y_tiles); | ||||
| CLUTTER_EXPORT | ||||
| void            clutter_deform_effect_get_n_tiles       (ClutterDeformEffect *effect, | ||||
|                                                          guint               *x_tiles, | ||||
|                                                          guint               *y_tiles); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void            clutter_deform_effect_invalidate        (ClutterDeformEffect *effect); | ||||
|  | ||||
| G_END_DECLS | ||||
| @@ -1,306 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2010  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> | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * ClutterDesaturateEffect: | ||||
|  * | ||||
|  * A desaturation effect | ||||
|  * | ||||
|  * #ClutterDesaturateEffect is a sub-class of #ClutterEffect that | ||||
|  * desaturates the color of an actor and its contents. The strength | ||||
|  * of the desaturation effect is controllable and animatable through | ||||
|  * the #ClutterDesaturateEffect:factor property. | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| #include <math.h> | ||||
|  | ||||
| #include "clutter/clutter-desaturate-effect.h" | ||||
|  | ||||
| #include "cogl/cogl.h" | ||||
|  | ||||
| #include "clutter/clutter-debug.h" | ||||
| #include "clutter/clutter-enum-types.h" | ||||
| #include "clutter/clutter-private.h" | ||||
|  | ||||
| typedef struct _ClutterDesaturateEffectPrivate | ||||
| { | ||||
|   /* the desaturation factor, also known as "strength" */ | ||||
|   gdouble factor; | ||||
|  | ||||
|   gint factor_uniform; | ||||
|  | ||||
|   gint tex_width; | ||||
|   gint tex_height; | ||||
|  | ||||
|   CoglPipeline *pipeline; | ||||
| } ClutterDesaturateEffectPrivate; | ||||
|  | ||||
|  | ||||
| /* the magic gray vec3 has been taken from the NTSC conversion weights | ||||
|  * as defined by: | ||||
|  * | ||||
|  *   "OpenGL Superbible, 4th edition" | ||||
|  *   -- Richard S. Wright Jr, Benjamin Lipchak, Nicholas Haemel | ||||
|  *   Addison-Wesley | ||||
|  */ | ||||
| static const gchar *desaturate_glsl_declarations = | ||||
|   "uniform float factor;\n" | ||||
|   "\n" | ||||
|   "vec3 desaturate (const vec3 color, const float desaturation)\n" | ||||
|   "{\n" | ||||
|   "  const vec3 gray_conv = vec3 (0.299, 0.587, 0.114);\n" | ||||
|   "  vec3 gray = vec3 (dot (gray_conv, color));\n" | ||||
|   "  return vec3 (mix (color.rgb, gray, desaturation));\n" | ||||
|   "}\n"; | ||||
|  | ||||
| static const gchar *desaturate_glsl_source = | ||||
|   "  cogl_color_out.rgb = desaturate (cogl_color_out.rgb, factor);\n"; | ||||
|  | ||||
| enum | ||||
| { | ||||
|   PROP_0, | ||||
|  | ||||
|   PROP_FACTOR, | ||||
|  | ||||
|   PROP_LAST | ||||
| }; | ||||
|  | ||||
| static GParamSpec *obj_props[PROP_LAST]; | ||||
|  | ||||
| G_DEFINE_TYPE_WITH_PRIVATE (ClutterDesaturateEffect, | ||||
|                             clutter_desaturate_effect, | ||||
|                             CLUTTER_TYPE_OFFSCREEN_EFFECT); | ||||
|  | ||||
| static CoglPipeline * | ||||
| clutter_desaturate_effect_create_pipeline (ClutterOffscreenEffect *effect, | ||||
|                                            CoglTexture            *texture) | ||||
| { | ||||
|   ClutterDesaturateEffect *desaturate_effect = | ||||
|     CLUTTER_DESATURATE_EFFECT (effect); | ||||
|   ClutterDesaturateEffectPrivate *priv = | ||||
|     clutter_desaturate_effect_get_instance_private (desaturate_effect); | ||||
|  | ||||
|   cogl_pipeline_set_layer_texture (priv->pipeline, 0, texture); | ||||
|  | ||||
|   return g_object_ref (priv->pipeline); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_desaturate_effect_dispose (GObject *gobject) | ||||
| { | ||||
|   ClutterDesaturateEffect *self = CLUTTER_DESATURATE_EFFECT (gobject); | ||||
|   ClutterDesaturateEffectPrivate *priv = | ||||
|     clutter_desaturate_effect_get_instance_private (self); | ||||
|  | ||||
|   g_clear_object (&priv->pipeline); | ||||
|  | ||||
|   G_OBJECT_CLASS (clutter_desaturate_effect_parent_class)->dispose (gobject); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_desaturate_effect_set_property (GObject      *gobject, | ||||
|                                         guint         prop_id, | ||||
|                                         const GValue *value, | ||||
|                                         GParamSpec   *pspec) | ||||
| { | ||||
|   ClutterDesaturateEffect *effect = CLUTTER_DESATURATE_EFFECT (gobject); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_FACTOR: | ||||
|       clutter_desaturate_effect_set_factor (effect, | ||||
|                                             g_value_get_double (value)); | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_desaturate_effect_get_property (GObject    *gobject, | ||||
|                                         guint       prop_id, | ||||
|                                         GValue     *value, | ||||
|                                         GParamSpec *pspec) | ||||
| { | ||||
|   ClutterDesaturateEffect *effect = CLUTTER_DESATURATE_EFFECT (gobject); | ||||
|   ClutterDesaturateEffectPrivate *priv = | ||||
|     clutter_desaturate_effect_get_instance_private (effect); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_FACTOR: | ||||
|       g_value_set_double (value, priv->factor); | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| update_factor_uniform (ClutterDesaturateEffect *self) | ||||
| { | ||||
|   ClutterDesaturateEffectPrivate *priv = | ||||
|     clutter_desaturate_effect_get_instance_private (self); | ||||
|  | ||||
|   if (priv->factor_uniform > -1) | ||||
|     cogl_pipeline_set_uniform_1f (priv->pipeline, | ||||
|                                   priv->factor_uniform, | ||||
|                                   priv->factor); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_desaturate_effect_class_init (ClutterDesaturateEffectClass *klass) | ||||
| { | ||||
|   GObjectClass *gobject_class = G_OBJECT_CLASS (klass); | ||||
|   ClutterOffscreenEffectClass *offscreen_class; | ||||
|  | ||||
|   offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass); | ||||
|   offscreen_class->create_pipeline = clutter_desaturate_effect_create_pipeline; | ||||
|  | ||||
|   /** | ||||
|    * ClutterDesaturateEffect:factor: | ||||
|    * | ||||
|    * The desaturation factor, between 0.0 (no desaturation) and 1.0 (full | ||||
|    * desaturation). | ||||
|    */ | ||||
|   obj_props[PROP_FACTOR] = | ||||
|     g_param_spec_double ("factor", NULL, NULL, | ||||
|                          0.0, 1.0, | ||||
|                          1.0, | ||||
|                          G_PARAM_READWRITE | | ||||
|                          G_PARAM_STATIC_STRINGS); | ||||
|  | ||||
|   gobject_class->dispose = clutter_desaturate_effect_dispose; | ||||
|   gobject_class->set_property = clutter_desaturate_effect_set_property; | ||||
|   gobject_class->get_property = clutter_desaturate_effect_get_property; | ||||
|  | ||||
|   g_object_class_install_properties (gobject_class, PROP_LAST, obj_props); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_desaturate_effect_init (ClutterDesaturateEffect *self) | ||||
| { | ||||
|   ClutterDesaturateEffectClass *klass = CLUTTER_DESATURATE_EFFECT_GET_CLASS (self); | ||||
|   ClutterDesaturateEffectPrivate *priv = | ||||
|     clutter_desaturate_effect_get_instance_private (self); | ||||
|  | ||||
|   if (G_UNLIKELY (klass->base_pipeline == NULL)) | ||||
|     { | ||||
|       CoglContext *ctx = | ||||
|         clutter_backend_get_cogl_context (clutter_get_default_backend ()); | ||||
|       CoglSnippet *snippet; | ||||
|  | ||||
|       klass->base_pipeline = cogl_pipeline_new (ctx); | ||||
|  | ||||
|       snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, | ||||
|                                   desaturate_glsl_declarations, | ||||
|                                   desaturate_glsl_source); | ||||
|       cogl_pipeline_add_snippet (klass->base_pipeline, snippet); | ||||
|       g_object_unref (snippet); | ||||
|  | ||||
|       cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0); | ||||
|     } | ||||
|  | ||||
|   priv->pipeline = cogl_pipeline_copy (klass->base_pipeline); | ||||
|  | ||||
|   priv->factor_uniform = | ||||
|     cogl_pipeline_get_uniform_location (priv->pipeline, "factor"); | ||||
|  | ||||
|   priv->factor = 1.0; | ||||
|  | ||||
|   update_factor_uniform (self); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_desaturate_effect_new: | ||||
|  * @factor: the desaturation factor, between 0.0 and 1.0 | ||||
|  * | ||||
|  * Creates a new #ClutterDesaturateEffect to be used with | ||||
|  * [method@Clutter.Actor.add_effect] | ||||
|  * | ||||
|  * Return value: the newly created #ClutterDesaturateEffect or %NULL | ||||
|  */ | ||||
| ClutterEffect * | ||||
| clutter_desaturate_effect_new (gdouble factor) | ||||
| { | ||||
|   g_return_val_if_fail (factor >= 0.0 && factor <= 1.0, NULL); | ||||
|  | ||||
|   return g_object_new (CLUTTER_TYPE_DESATURATE_EFFECT, | ||||
|                        "factor", factor, | ||||
|                        NULL); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_desaturate_effect_set_factor: | ||||
|  * @effect: a #ClutterDesaturateEffect | ||||
|  * @factor: the desaturation factor, between 0.0 and 1.0 | ||||
|  * | ||||
|  * Sets the desaturation factor for @effect, with 0.0 being "do not desaturate" | ||||
|  * and 1.0 being "fully desaturate" | ||||
|  */ | ||||
| void | ||||
| clutter_desaturate_effect_set_factor (ClutterDesaturateEffect *effect, | ||||
|                                       double                   factor) | ||||
| { | ||||
|   ClutterDesaturateEffectPrivate *priv; | ||||
|  | ||||
|   g_return_if_fail (CLUTTER_IS_DESATURATE_EFFECT (effect)); | ||||
|   g_return_if_fail (factor >= 0.0 && factor <= 1.0); | ||||
|  | ||||
|   priv = clutter_desaturate_effect_get_instance_private (effect); | ||||
|   if (fabs (priv->factor - factor) >= 0.00001) | ||||
|     { | ||||
|       priv->factor = factor; | ||||
|       update_factor_uniform (effect); | ||||
|  | ||||
|       clutter_effect_queue_repaint (CLUTTER_EFFECT (effect)); | ||||
|  | ||||
|       g_object_notify_by_pspec (G_OBJECT (effect), obj_props[PROP_FACTOR]); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_desaturate_effect_get_factor: | ||||
|  * @effect: a #ClutterDesaturateEffect | ||||
|  * | ||||
|  * Retrieves the desaturation factor of @effect | ||||
|  * | ||||
|  * Return value: the desaturation factor | ||||
|  */ | ||||
| gdouble | ||||
| clutter_desaturate_effect_get_factor (ClutterDesaturateEffect *effect) | ||||
| { | ||||
|   ClutterDesaturateEffectPrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_DESATURATE_EFFECT (effect), 0.0); | ||||
|  | ||||
|   priv = clutter_desaturate_effect_get_instance_private (effect); | ||||
|   return priv->factor; | ||||
| } | ||||
| @@ -1,60 +0,0 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright (C) 2010  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> | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <clutter/clutter.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include "clutter/clutter-effect.h" | ||||
| #include "clutter/clutter-offscreen-effect.h" | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CLUTTER_TYPE_DESATURATE_EFFECT          (clutter_desaturate_effect_get_type ()) | ||||
|  | ||||
| struct _ClutterDesaturateEffectClass | ||||
| { | ||||
|   ClutterOffscreenEffectClass parent_class; | ||||
|  | ||||
|   CoglPipeline *base_pipeline; | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_DERIVABLE_TYPE (ClutterDesaturateEffect, | ||||
|                           clutter_desaturate_effect, | ||||
|                           CLUTTER, DESATURATE_EFFECT, | ||||
|                           ClutterOffscreenEffect) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterEffect *clutter_desaturate_effect_new        (gdouble                  factor); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void           clutter_desaturate_effect_set_factor (ClutterDesaturateEffect *effect, | ||||
|                                                      gdouble                  factor); | ||||
| CLUTTER_EXPORT | ||||
| gdouble        clutter_desaturate_effect_get_factor (ClutterDesaturateEffect *effect); | ||||
|  | ||||
| G_END_DECLS | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user