Compare commits
	
		
			1 Commits
		
	
	
		
			main
			...
			wip/carlos
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 855c402e77 | 
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -103,4 +103,3 @@ doc/reference/meta.types | ||||
| .dirstamp | ||||
| **/tags.* | ||||
| build/ | ||||
| subprojects/sysprof/ | ||||
|   | ||||
							
								
								
									
										385
									
								
								.gitlab-ci.yml
									
									
									
									
									
								
							
							
						
						
									
										385
									
								
								.gitlab-ci.yml
									
									
									
									
									
								
							| @@ -1,382 +1,79 @@ | ||||
| include: | ||||
|   - remote: 'https://gitlab.freedesktop.org/freedesktop/ci-templates/-/raw/bbe5232986c9b98eb1efe62484e07216f7d1a4df/templates/fedora.yml' | ||||
|   - remote: 'https://gitlab.freedesktop.org/freedesktop/ci-templates/-/raw/bbe5232986c9b98eb1efe62484e07216f7d1a4df/templates/ci-fairy.yml' | ||||
| image: registry.gitlab.gnome.org/gnome/mutter/master:v3 | ||||
|  | ||||
| stages: | ||||
|  - review | ||||
|  - prepare | ||||
|  - code-review | ||||
|  - build | ||||
|  - test | ||||
|  - analyze | ||||
|  - deploy | ||||
|  | ||||
| variables: | ||||
|   FDO_UPSTREAM_REPO: GNOME/mutter | ||||
|  | ||||
| .mutter.fedora:34@common: | ||||
|   variables: | ||||
|     FDO_DISTRIBUTION_VERSION: 34 | ||||
|     BASE_TAG: '2021-09-15.0' | ||||
|     FDO_DISTRIBUTION_PACKAGES: | ||||
|       asciidoc | ||||
|       clang | ||||
|       gcovr | ||||
|       gdm | ||||
|       gnome-shell | ||||
|       python3-dbusmock | ||||
|       sassc | ||||
|       uncrustify | ||||
|       xorg-x11-server-Xvfb | ||||
|  | ||||
|     FDO_DISTRIBUTION_EXEC: | | ||||
|       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 libinput --setopt=install_weak_deps=False && | ||||
|       dnf builddep -y wayland-protocols --setopt=install_weak_deps=False && | ||||
|  | ||||
|       ./.gitlab-ci/install-meson-project.sh \ | ||||
|         https://gitlab.gnome.org/GNOME/glib.git \ | ||||
|         main . 02742ef957b532789c003eef80ec7f51c370e3d5 && | ||||
|  | ||||
|       ./.gitlab-ci/install-meson-project.sh \ | ||||
|         https://gitlab.gnome.org/GNOME/gsettings-desktop-schemas.git \ | ||||
|         41.alpha . && | ||||
|  | ||||
|       ./.gitlab-ci/install-meson-project.sh \ | ||||
|         https://gitlab.gnome.org/GNOME/gjs.git \ | ||||
|         1.69.2 . && | ||||
|  | ||||
|       ./.gitlab-ci/install-meson-project.sh \ | ||||
|         https://gitlab.freedesktop.org/libinput/libinput.git \ | ||||
|         1.19.0 . && | ||||
|  | ||||
|       ./.gitlab-ci/install-meson-project.sh \ | ||||
|         https://gitlab.freedesktop.org/wayland/wayland-protocols.git \ | ||||
|         1.23 . && | ||||
|  | ||||
|       rpm -e --nodeps gnome-bluetooth-libs-devel \ | ||||
|                       mutter mutter-devel \ | ||||
|                       gnome-shell && | ||||
|  | ||||
|       dnf clean all | ||||
|  | ||||
| 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:34@x86_64: | ||||
|   extends: .mutter.fedora:34@common | ||||
|   variables: | ||||
|     FDO_DISTRIBUTION_TAG: "x86_64-${BASE_TAG}" | ||||
|  | ||||
| .mutter.fedora:34@aarch64: | ||||
|   extends: .mutter.fedora:34@common | ||||
|   variables: | ||||
|     FDO_DISTRIBUTION_TAG: "aarch64-${BASE_TAG}" | ||||
|   tags: | ||||
|     - aarch64 | ||||
|  | ||||
| workflow: | ||||
|   rules: | ||||
|     - if: '$CI_MERGE_REQUEST_IID' | ||||
|     - if: '$CI_COMMIT_TAG' | ||||
|     - if: '$CI_COMMIT_BRANCH' | ||||
|  | ||||
| .pipline-guard: &pipline-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-]+$/' | ||||
|     - when: 'manual' | ||||
|  | ||||
| check-commit-log: | ||||
|   extends: | ||||
|     - .fdo.ci-fairy | ||||
|   stage: review | ||||
|   variables: | ||||
|     GIT_DEPTH: "100" | ||||
|   script: | ||||
|     - if [[ x"$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" != "x" ]] ; | ||||
|       then | ||||
|         ci-fairy check-commits --junit-xml=commit-message-junit-report.xml ; | ||||
|       else | ||||
|         echo "Not a merge request" ; | ||||
|       fi | ||||
|   artifacts: | ||||
|     expire_in: 1 week | ||||
|     paths: | ||||
|       - commit-message-junit-report.xml | ||||
|     reports: | ||||
|       junit: commit-message-junit-report.xml | ||||
|   <<: *pipline-guard | ||||
|     - ./.gitlab-ci/check-commit-log.sh | ||||
|   only: | ||||
|     - merge_requests | ||||
|  | ||||
| check-merge-request: | ||||
|   extends: | ||||
|     - .fdo.ci-fairy | ||||
|   stage: review | ||||
|   variables: | ||||
|     GIT_STRATEGY: none | ||||
|   script: | ||||
|     - if [[ x"$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" != "x" ]] ; | ||||
|       then | ||||
|         ci-fairy check-merge-request --require-allow-collaboration --junit-xml=check-merge-request-report.xml ; | ||||
|       else | ||||
|         echo "Not a merge request" ; | ||||
|       fi | ||||
|   artifacts: | ||||
|     expire_in: 1 week | ||||
|     paths: | ||||
|       - check-merge-request-report.xml | ||||
|     reports: | ||||
|       junit: check-merge-request-report.xml | ||||
|   <<: *pipline-guard | ||||
|  | ||||
| build-fedora-container@x86_64: | ||||
|   extends: | ||||
|     - .fdo.container-build@fedora@x86_64 | ||||
|     - .mutter.fedora:34@x86_64 | ||||
|   stage: prepare | ||||
|   needs: | ||||
|     - check-commit-log | ||||
|     - check-merge-request | ||||
|   variables: | ||||
|     GIT_STRATEGY: none | ||||
|  | ||||
| build-fedora-container@aarch64: | ||||
|   extends: | ||||
|     - .fdo.container-build@fedora@aarch64 | ||||
|     - .mutter.fedora:34@aarch64 | ||||
|   stage: prepare | ||||
|   needs: | ||||
|     - check-commit-log | ||||
|     - check-merge-request | ||||
|   variables: | ||||
|     GIT_STRATEGY: none | ||||
|  | ||||
| check-code-style: | ||||
|   extends: | ||||
|     - .fdo.distribution-image@fedora | ||||
|     - .mutter.fedora:34@x86_64 | ||||
|   stage: code-review | ||||
|   needs: | ||||
|     - build-fedora-container@x86_64 | ||||
|   script: | ||||
|     - if [[ x"$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" != "x" ]] ; | ||||
|       then | ||||
|         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 ; | ||||
|       else | ||||
|         echo "Not a merge request" ; | ||||
|       fi | ||||
|   allow_failure: true | ||||
|  | ||||
| .build-mutter: | ||||
|   extends: | ||||
|     - .fdo.distribution-image@fedora | ||||
| build-mutter: | ||||
|   stage: build | ||||
|   script: | ||||
|     - meson . build -Dbuildtype=debugoptimized -Db_coverage=true -Degl_device=true -Dwayland_eglstream=true --werror --prefix /usr | ||||
|     - meson compile -C build | ||||
|     - meson install -C build | ||||
|     - meson . build -Dbuildtype=debugoptimized -Degl_device=true -Dwayland_eglstream=true --werror --prefix /usr | ||||
|     - ninja -C build | ||||
|     - ninja -C build install | ||||
|   artifacts: | ||||
|     expire_in: 1 day | ||||
|     paths: | ||||
|       - build | ||||
|   only: | ||||
|     - merge_requests | ||||
|     - /^.*$/ | ||||
|  | ||||
| build-mutter@x86_64: | ||||
|   extends: | ||||
|     - .build-mutter | ||||
|     - .mutter.fedora:34@x86_64 | ||||
|   needs: | ||||
|     - build-fedora-container@x86_64 | ||||
|  | ||||
| build-mutter@aarch64: | ||||
|   extends: | ||||
|     - .build-mutter | ||||
|     - .mutter.fedora:34@aarch64 | ||||
|   needs: | ||||
|     - build-fedora-container@aarch64 | ||||
|  | ||||
| build-without-opengl-and-glx@x86_64: | ||||
|   extends: | ||||
|     - .fdo.distribution-image@fedora | ||||
|     - .mutter.fedora:34@x86_64 | ||||
| build-without-native-backend-and-wayland: | ||||
|   stage: build | ||||
|   needs: | ||||
|     - build-fedora-container@x86_64 | ||||
|   script: | ||||
|     - meson . build -Dbuildtype=debugoptimized -Dopengl=false -Dglx=false -Degl_device=true -Dwayland_eglstream=true --werror --prefix /usr | ||||
|     - meson compile -C build | ||||
|     - meson install -C build | ||||
|     - meson . build -Dbuildtype=debugoptimized -Dnative_backend=false -Dudev=false -Dwayland=false -Dcore_tests=false --werror --prefix /usr | ||||
|     - ninja -C build | ||||
|     - ninja -C build install | ||||
|   artifacts: | ||||
|     expire_in: 1 day | ||||
|     paths: | ||||
|       - build/meson-logs | ||||
|       - build | ||||
|   only: | ||||
|     - merge_requests | ||||
|     - /^.*$/ | ||||
|  | ||||
| build-without-native-backend-and-wayland@x86_64: | ||||
|   extends: | ||||
|     - .fdo.distribution-image@fedora | ||||
|     - .mutter.fedora:34@x86_64 | ||||
|   stage: build | ||||
|   needs: | ||||
|     - build-fedora-container@x86_64 | ||||
|   script: | ||||
|     - meson . build -Dbuildtype=debugoptimized -Dnative_backend=false -Dudev=false -Dwayland=false -Dcore_tests=false -Dnative_tests=false --werror --prefix /usr | ||||
|     - meson compile -C build | ||||
|     - meson install -C build | ||||
|   artifacts: | ||||
|     paths: | ||||
|       - build/meson-logs | ||||
|  | ||||
| .test-setup: &test-setup | ||||
| test-mutter: | ||||
|   stage: test | ||||
|   dependencies: | ||||
|     - build-mutter | ||||
|   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" | ||||
|   before_script: | ||||
|     - glib-compile-schemas $GSETTINGS_SCHEMA_DIR | ||||
|     # Disable e.g. audio support to not dead lock screen cast tests | ||||
|     - rm -f /usr/share/pipewire/media-session.d/with-* | ||||
|     MALLOC_PERTURB_: "123" | ||||
|   script: | ||||
|     - dconf update | ||||
|     - mkdir -m 700 $XDG_RUNTIME_DIR | ||||
|     - pipewire & sleep 2 | ||||
|     - glib-compile-schemas $GSETTINGS_SCHEMA_DIR | ||||
|     - > | ||||
|       dbus-run-session -- xvfb-run -s '+iglx -noreset' | ||||
|       meson test -C build --no-rebuild -t 10 --verbose --no-stdsplit --print-errorlogs --wrap catchsegv | ||||
|   only: | ||||
|     - merge_requests | ||||
|     - /^.*$/ | ||||
|  | ||||
| .test-mutter: | ||||
|   extends: | ||||
|     - .fdo.distribution-image@fedora | ||||
|   <<: *test-setup | ||||
| can-build-gnome-shell: | ||||
|   stage: test | ||||
|   script: | ||||
|     - dbus-run-session -- xvfb-run -a -s "$XVFB_SERVER_ARGS" | ||||
|         catchsegv meson test -C build --no-rebuild -t 10 | ||||
|   artifacts: | ||||
|     expire_in: 1 day | ||||
|     reports: | ||||
|       junit: "build/meson-logs/testlog.junit.xml" | ||||
|     name: "mutter-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}" | ||||
|     when: always | ||||
|     paths: | ||||
|       - build | ||||
|  | ||||
| test-mutter@x86_64: | ||||
|   extends: | ||||
|     - .test-mutter | ||||
|     - .mutter.fedora:34@x86_64 | ||||
|   needs: | ||||
|     - build-mutter@x86_64 | ||||
|  | ||||
| test-mutter@aarch64: | ||||
|   extends: | ||||
|     - .test-mutter | ||||
|     - .mutter.fedora:34@aarch64 | ||||
|   needs: | ||||
|     - build-mutter@aarch64 | ||||
|  | ||||
| .test-mutter-coverage: | ||||
|   extends: | ||||
|     - .fdo.distribution-image@fedora | ||||
|   stage: analyze | ||||
|   script: | ||||
|     - ninja -C build coverage | ||||
|     - cat build/meson-logs/coverage.txt | ||||
|   artifacts: | ||||
|     paths: | ||||
|       - build/meson-logs/coveragereport | ||||
|   coverage: '/^TOTAL.*\s+(\d+\%)$/' | ||||
|  | ||||
| test-mutter-coverage@x86_64: | ||||
|   extends: | ||||
|     - .test-mutter-coverage | ||||
|     - .mutter.fedora:34@x86_64 | ||||
|   needs: | ||||
|     - test-mutter@x86_64 | ||||
|  | ||||
| test-mutter-coverage@aarch64: | ||||
|   extends: | ||||
|     - .test-mutter-coverage | ||||
|     - .mutter.fedora:34@aarch64 | ||||
|   needs: | ||||
|     - test-mutter@aarch64 | ||||
|  | ||||
| can-build-gnome-shell@x86_64: | ||||
|   extends: | ||||
|     - .fdo.distribution-image@fedora | ||||
|     - .mutter.fedora:34@x86_64 | ||||
|   stage: test | ||||
|   needs: | ||||
|     - build-mutter@x86_64 | ||||
|   dependencies: | ||||
|     - build-mutter | ||||
|   before_script: | ||||
|     - meson install --no-rebuild -C build | ||||
|   script: | ||||
|     - .gitlab-ci/checkout-gnome-shell.sh | ||||
|     - meson gnome-shell gnome-shell/build --prefix /usr -Dman=false | ||||
|     - meson install -C gnome-shell/build | ||||
|  | ||||
| test-mutter-coverity: | ||||
|   rules: | ||||
|     - if: '$CI_PIPELINE_SOURCE == "schedule" && $MUTTER_SCHEDULED_JOB == "coverity"' | ||||
|       when: always | ||||
|     - when: manual | ||||
|   extends: | ||||
|     - .fdo.distribution-image@fedora | ||||
|     - .mutter.fedora:34@x86_64 | ||||
|   needs: | ||||
|     - build-fedora-container@x86_64 | ||||
|   stage: analyze | ||||
|   allow_failure: true | ||||
|   script: | ||||
|     - .gitlab-ci/download-coverity-tarball.sh | ||||
|     - CC=clang meson 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:34@x86_64 | ||||
|   <<: *test-setup | ||||
|   stage: deploy | ||||
|   needs: | ||||
|     - build-mutter@x86_64 | ||||
|   script: | ||||
|     - dbus-run-session -- xvfb-run -a -s "$XVFB_SERVER_ARGS" meson dist -C build | ||||
|   rules: | ||||
|     - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' | ||||
|       changes: | ||||
|         - "**/meson.build" | ||||
|         - meson/* | ||||
|  | ||||
| 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' | ||||
|     - ninja -C gnome-shell/build install | ||||
|   only: | ||||
|     - merge_requests | ||||
|     - /^.*$/ | ||||
|   | ||||
							
								
								
									
										32
									
								
								.gitlab-ci/Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								.gitlab-ci/Dockerfile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| # Rebuild and push with | ||||
| # | ||||
| #     cd .gitlab-ci/ | ||||
| #     podman build --format docker --no-cache -t registry.gitlab.gnome.org/gnome/mutter/master:v3 . | ||||
| #     podman push registry.gitlab.gnome.org/gnome/mutter/master:v3 | ||||
| # | ||||
|  | ||||
| FROM fedora:31 | ||||
|  | ||||
| RUN dnf -y update && dnf -y upgrade && \ | ||||
|     dnf install -y 'dnf-command(builddep)' && \ | ||||
|     dnf install -y 'dnf-command(copr)' && \ | ||||
|     dnf copr enable -y fmuellner/gnome-shell-ci && \ | ||||
|     dnf copr enable -y jadahl/mutter-ci && \ | ||||
|     dnf -y update && dnf -y upgrade && \ | ||||
|  | ||||
|     dnf builddep -y mutter && \ | ||||
|  | ||||
|     # Until Fedora catches up with new build-deps | ||||
|     dnf install -y 'pkgconfig(graphene-gobject-1.0)' 'pkgconfig(sysprof-capture-3)' && \ | ||||
|  | ||||
|     # For running unit tests | ||||
|     dnf install -y xorg-x11-server-Xvfb mesa-dri-drivers dbus dbus-x11 '*/xvfb-run' gdm-lib accountsservice-libs gnome-control-center && \ | ||||
|  | ||||
|     # GNOME Shell | ||||
|     dnf builddep -y gnome-shell --setopt=install_weak_deps=False && \ | ||||
|     dnf remove -y gnome-bluetooth-libs-devel dbus-glib-devel upower-devel python3-devel && \ | ||||
|     dnf remove -y --noautoremove mutter mutter-devel && \ | ||||
|  | ||||
|     dnf upgrade -y 'pkgconfig(libpipewire-0.3)' && \ | ||||
|  | ||||
|     dnf clean all | ||||
							
								
								
									
										60
									
								
								.gitlab-ci/check-commit-log.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										60
									
								
								.gitlab-ci/check-commit-log.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,60 @@ | ||||
| #!/usr/bin/env bash | ||||
|  | ||||
| if [ -z "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then | ||||
|   echo Cannot review non-merge request | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| git fetch $CI_MERGE_REQUEST_PROJECT_URL.git $CI_MERGE_REQUEST_TARGET_BRANCH_NAME | ||||
|  | ||||
| branch_point=$(git merge-base HEAD FETCH_HEAD) | ||||
|  | ||||
| commits=$(git log --format='format:%H' $branch_point..$CI_COMMIT_SHA) | ||||
|  | ||||
| if [ -z "$commits" ]; then | ||||
|   echo Commit range empty | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| function commit_message_has_url() { | ||||
|   commit=$1 | ||||
|   commit_message=$(git show -s --format='format:%b' $commit) | ||||
|   echo "$commit_message" | grep -qe "\($CI_MERGE_REQUEST_PROJECT_URL/\(-/\)\?\(issues\|merge_requests\)/[0-9]\+\|https://bugzilla.gnome.org/show_bug.cgi?id=[0-9]\+\)" | ||||
|   return $? | ||||
| } | ||||
|  | ||||
| function commit_message_subject_is_compliant() { | ||||
|   commit=$1 | ||||
|   commit_message_subject=$(git show -s --format='format:%s' $commit) | ||||
|  | ||||
|   if echo "$commit_message_subject" | grep -qe "\(^meta-\|^Meta\)"; then | ||||
|     echo " - message subject should not be prefixed with 'meta-' or 'Meta'" | ||||
|     return 1 | ||||
|   fi | ||||
|  | ||||
|   if echo "$commit_message_subject" | grep -qe "\.[ch]:"; then | ||||
|     echo " - message subject prefix should not include .c, .h, etc." | ||||
|     return 1 | ||||
|   fi | ||||
|  | ||||
|   return 0 | ||||
| } | ||||
|  | ||||
| RET=0 | ||||
| for commit in $commits; do | ||||
|   commit_short=$(echo $commit | cut -c -8) | ||||
|  | ||||
|   if ! commit_message_has_url $commit; then | ||||
|     echo "Commit $commit_short needs a merge request or issue URL" | ||||
|     exit 1 | ||||
|   fi | ||||
|  | ||||
|   errors=$(commit_message_subject_is_compliant $commit) | ||||
|   if [ $? != 0 ]; then | ||||
|     echo "Commit message for $commit_short is not compliant:" | ||||
|     echo "$errors" | ||||
|     RET=1 | ||||
|   fi | ||||
| done | ||||
|  | ||||
| exit $RET | ||||
| @@ -1,19 +1,11 @@ | ||||
| #!/usr/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 | ||||
| git clone https://gitlab.gnome.org/GNOME/gnome-shell.git | ||||
|  | ||||
| if [ $? -ne 0 ]; then | ||||
|   echo Checkout failed | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| @@ -23,33 +15,19 @@ 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 | ||||
|   echo Looking for $merge_request_branch on remote ... | ||||
|   if git fetch -q $merge_request_remote $merge_request_branch 2>/dev/null; then | ||||
|     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 | ||||
|   echo -n Looking for $CI_COMMIT_REF_NAME on remote ... | ||||
|   if fetch origin $CI_COMMIT_REF_NAME; then | ||||
|     echo \ found | ||||
|     gnome_shell_target=FETCH_HEAD | ||||
|   else | ||||
|     echo \ not found | ||||
|     gnome_shell_target=HEAD | ||||
|     gnome_shell_target=origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME | ||||
|     echo Using $gnome_shell_target instead | ||||
|   fi | ||||
| fi | ||||
|  | ||||
| if [ -z "$gnome_shell_target" ]; then | ||||
|   gnome_shell_target=$(git branch -r -l origin/$CI_COMMIT_REF_NAME) | ||||
|   gnome_shell_target=${gnome_shell_target:-origin/master} | ||||
|   echo Using $gnome_shell_target instead | ||||
| 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 @@ | ||||
| #!/usr/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,39 +0,0 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| set -e | ||||
|  | ||||
| if [[ $# -lt 3 ]]; then | ||||
|   echo Usage: $0 [options] [repo-url] [commit] [subdir] | ||||
|   echo  Options: | ||||
|   echo    -Dkey=val | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| MESON_OPTIONS=() | ||||
|  | ||||
| while [[ $1 =~ ^-D ]]; do | ||||
|   MESON_OPTIONS+=( "$1" ) | ||||
|   shift | ||||
| done | ||||
|  | ||||
| REPO_URL="$1" | ||||
| TAG_OR_BRANCH="$2" | ||||
| SUBDIR="$3" | ||||
| COMMIT="$4" | ||||
|  | ||||
| REPO_DIR="$(basename ${REPO_URL%.git})" | ||||
|  | ||||
| git clone --depth 1 "$REPO_URL" -b "$TAG_OR_BRANCH" | ||||
| pushd "$REPO_DIR" | ||||
| pushd "$SUBDIR" | ||||
|  | ||||
| if [ ! -z "$COMMIT" ]; then | ||||
|   git fetch origin "$COMMIT" | ||||
|   git checkout "$COMMIT" | ||||
| fi | ||||
|  | ||||
| meson --prefix=/usr _build "${MESON_OPTIONS[@]}" | ||||
| meson install -C _build | ||||
| popd | ||||
| popd | ||||
| rm -rf "$REPO_DIR" | ||||
							
								
								
									
										286
									
								
								HACKING.md
									
									
									
									
									
								
							
							
						
						
									
										286
									
								
								HACKING.md
									
									
									
									
									
								
							| @@ -1,286 +0,0 @@ | ||||
| # Style | ||||
|  | ||||
| The coding style used is primarily the GNU flavor of the [GNOME coding | ||||
| style][gnome-coding-style], with some additions described below. | ||||
|  | ||||
| ## General | ||||
|  | ||||
|  * Use this code style on new code. When changing old code with a different | ||||
|    code style, feel free to also adjust it to use this code style. | ||||
|  | ||||
|  * Use regular C types and `stdint.h` types instead of GLib fundamental | ||||
|    types, except for `gboolean`, and `guint`/`gulong` for GSource IDs and | ||||
|    signal handler IDs. That means e.g. `uint64_t` instead of `guint64`, `int` | ||||
|    instead of `gint`, `unsigned int` instead of `guint` if unsignedness | ||||
|    is of importance, `uint8_t` instead of `guchar`, and so on. | ||||
|  | ||||
|  * Try to to limit line length to 80 characters, although it's not a | ||||
|    strict limit. | ||||
|  | ||||
|  * Usage of `g_autofree` and `g_autoptr` is encouraged. The style to use is | ||||
|  | ||||
|     ```c | ||||
|     g_autofree char *text = NULL; | ||||
|     g_autoptr (MetaSomeThing) thing = NULL; | ||||
|  | ||||
|     text = g_strdup_printf ("The text: %d", a_number); | ||||
|     thing = g_object_new (META_TYPE_SOME_THING, | ||||
|                           "text", text, | ||||
|                           NULL); | ||||
|     thinger_use_thing (rocket, thing); | ||||
|     ``` | ||||
|  | ||||
|  * Declare variables at the top of the block they are used, but avoid | ||||
|    non-trivial logic among variable declarations. Non-trivial logic can be | ||||
|    getting a pointer that may be `NULL`, any kind of math, or anything | ||||
|    that may have side effects. | ||||
|  | ||||
|  * Instead of boolean arguments in functions, prefer enums or flags when | ||||
|    they're more expressive. The naming convention for flags is | ||||
|  | ||||
|     ```c | ||||
|     typedef _MetaSomeThingFlags | ||||
|     { | ||||
|       META_SOME_THING_FLAG_NONE = 0, | ||||
|       META_SOME_THING_FLAG_ALTER_REALITY = 1 << 0, | ||||
|       META_SOME_THING_FLAG_MANIPULATE_PERCEPTION = 1 << 1, | ||||
|     } MetaSomeThingFlags; | ||||
|     ``` | ||||
|  | ||||
|  * Use `g_new0 ()` etc. instead of `g_slice_new0 ()`. | ||||
|  | ||||
|  * Initialize and assign floating point variables (i.e. `float` or | ||||
|    `double`) using the form `floating_point = 3.14159` or `ratio = 2.0`. | ||||
|  | ||||
| ## Header (.h) files | ||||
|  | ||||
|  * The return type and `*` are separated by a space. | ||||
|  * Function name starts one space after the last `*`. | ||||
|  * Parenthesis comes one space after the function name. | ||||
|  | ||||
| As an example, this is how functions in a header file should look like: | ||||
|  | ||||
| ```c | ||||
| gboolean meta_udev_is_drm_device (MetaUdev    *udev, | ||||
|                                   GUdevDevice *device); | ||||
|  | ||||
| GList * meta_udev_list_drm_devices (MetaUdev  *udev, | ||||
|                                     GError   **error); | ||||
|  | ||||
| MetaUdev * meta_udev_new (MetaBackendNative *backend_native); | ||||
| ``` | ||||
|  | ||||
| ## Source code | ||||
|  | ||||
| Keep functions in the following order in source files: | ||||
|  | ||||
|   1. GPL header | ||||
|   2. Enums | ||||
|   3. Structures | ||||
|   4. Function prototypes | ||||
|   5. `G_DEFINE_TYPE()` | ||||
|   6. Static variables | ||||
|   7. Auxiliary functions | ||||
|   8. Callbacks | ||||
|   9. Interface implementations | ||||
|   10. Parent vfunc overrides | ||||
|   11. class_init and init | ||||
|   12. Public API | ||||
|  | ||||
| ### Structures | ||||
|  | ||||
| Each structure field has a space after their type name. Structure fields aren't | ||||
| aligned. For example: | ||||
|  | ||||
| ```c | ||||
| struct _MetaFooBar | ||||
| { | ||||
|   MetaFoo parent; | ||||
|  | ||||
|   MetaBar *bar; | ||||
|   MetaSomething *something; | ||||
| }; | ||||
| ``` | ||||
|  | ||||
| ### Function Prototypes | ||||
|  | ||||
| Function prototypes must be formatted just like in header files. | ||||
|  | ||||
| ### Overrides | ||||
|  | ||||
| When overriding parent class vfuncs, or implementing an interface, vfunc | ||||
| overrides should be named as a composition of the current class prefix, | ||||
| followed by the vfunc name. For example: | ||||
|  | ||||
|  | ||||
| ```c | ||||
| static void | ||||
| meta_bar_spawn_unicorn (MetaParent *parent) | ||||
| { | ||||
|   /* ... */ | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_bar_dispose (GObject *object) | ||||
| { | ||||
|   /* ... */ | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_bar_finalize (GObject *object) | ||||
| { | ||||
|   /* ... */ | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_bar_class_init (MetaBarClass *klass) | ||||
| { | ||||
|   GObjectClass *object_class = G_OBJECT_CLASS (klass); | ||||
|   MetaParentClass *parent_class = META_PARENT_CLASS (klass); | ||||
|  | ||||
|   object_class->dispose = meta_bar_dispose; | ||||
|   object_class->finalize = meta_bar_finalize; | ||||
|  | ||||
|   parent_class->spawn_unicorn = meta_bar_spawn_unicorn; | ||||
| } | ||||
| ``` | ||||
|  | ||||
| ### Interface Implementations | ||||
|  | ||||
| When implementing interfaces, two groups of functions are involved: the init | ||||
| function, and the overrides. | ||||
|  | ||||
| The interface init function is named after the interface type in snake case, | ||||
| followed by the `_iface_init` suffix. For example: | ||||
|  | ||||
|  | ||||
| ```c | ||||
| static void meta_foo_iface_init (MetaFooInterface *foo_iface); | ||||
|  | ||||
| G_DEFINE_TYPE_WITH_CODE (MetaBar, meta_bar, G_TYPE_OBJECT, | ||||
|                          G_IMPLEMENT_INTERFACE (META_TYPE_FOO, | ||||
|                                                 meta_foo_iface_init)); | ||||
| ``` | ||||
|  | ||||
| Then, when implementing each vfunc of the interface, follow the same pattern | ||||
| of the [Overrides](###Overrides) section. Here's an example: | ||||
|  | ||||
| ```c | ||||
| static void | ||||
| meta_bar_do_something (MetaFoo *foo) | ||||
| { | ||||
|   /* ... */ | ||||
| } | ||||
|  | ||||
| static void | ||||
| meta_foo_iface_init (MetaFooInterface *foo_iface) | ||||
| { | ||||
|   foo_iface->do_something = meta_bar_do_something; | ||||
| } | ||||
| ``` | ||||
|  | ||||
| ### Auxiliary Functions | ||||
|  | ||||
| Auxiliary functions are above every other functions to minimize the number of | ||||
| function prototypes in the file. These functions often grow when factoring out | ||||
| the same code between two or more functions: | ||||
|  | ||||
| ```c | ||||
| static void | ||||
| do_something_on_data (Foo *data, | ||||
|                       Bar *bar) | ||||
| { | ||||
|   /* ... */ | ||||
| } | ||||
|  | ||||
| static void | ||||
| random_function (Foo *foo) | ||||
| { | ||||
|   do_something_on_data (foo, bar); | ||||
| } | ||||
|  | ||||
| static void | ||||
| another_random_function (Foo *foo) | ||||
| { | ||||
|   do_something_on_data (foo, bar); | ||||
| } | ||||
| ``` | ||||
|  | ||||
| Sometimes, however, auxiliary functions are created to break down otherwise | ||||
| large functions - in this case, it is appropriate to keep these auxiliary | ||||
| functions close to the function they are tightly related to. | ||||
|  | ||||
| Auxiliary function names must have a verb in the imperative form, and should | ||||
| always perform an action over something. They usually don't have the class | ||||
| prefix (`meta_`, `clutter_`, or `cogl_`). For example: | ||||
|  | ||||
| ```c | ||||
| static void | ||||
| do_something_on_data (Foo *data, | ||||
|                       Bar *bar) | ||||
| { | ||||
|   /* ... */ | ||||
| } | ||||
| ``` | ||||
|  | ||||
| Exceptionally, when converting between types, auxiliary function names may | ||||
| have the class prefix to this rule. For example: | ||||
|  | ||||
| ```c | ||||
| static MetaFoo * | ||||
| meta_foo_from_bar (Bar *bar) | ||||
| { | ||||
|   /* ... */ | ||||
| } | ||||
| ``` | ||||
|  | ||||
| ### Callback Functions | ||||
|  | ||||
| Callback function names should have the name of the action in imperative | ||||
| form. They don't have any prefix, but have a `_func` suffix. For example: | ||||
|  | ||||
| ```c | ||||
| static void | ||||
| filter_something_func (Foo      *foo, | ||||
|                        Bar      *bar, | ||||
|                        gpointer  user_data) | ||||
| { | ||||
|   /* ... */ | ||||
| } | ||||
| ``` | ||||
|  | ||||
| ### Signal Callbacks | ||||
|  | ||||
| Signal callbacks generally have the signal name. They should be prefixed with | ||||
| `on_`, or suffixed with `_cb`, but not both. For example: | ||||
|  | ||||
| ```c | ||||
| static void | ||||
| on_realize (ClutterActor *actor, | ||||
|             gpointer      user_data) | ||||
| { | ||||
|   /* ... */ | ||||
| } | ||||
|  | ||||
| static void | ||||
| destroy_cb (ClutterActor *actor, | ||||
|             gpointer      user_data) | ||||
| { | ||||
|   /* ... */ | ||||
| } | ||||
| ``` | ||||
|  | ||||
| When the callback is named after the object that generated it, and the signal, | ||||
| then passive voice is used. For example: | ||||
|  | ||||
| ```c | ||||
| static void | ||||
| click_action_clicked_cb (ClutterClickAction *click_action, | ||||
|                          ClutterActor       *actor, | ||||
|                          gpointer            user_data) | ||||
| { | ||||
|   /* ... */ | ||||
| } | ||||
| ``` | ||||
|  | ||||
| [gnome-coding-style]: https://developer.gnome.org/documentation/guidelines/programming/coding-style.html | ||||
							
								
								
									
										537
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										537
									
								
								NEWS
									
									
									
									
									
								
							| @@ -1,514 +1,3 @@ | ||||
| 41.0 | ||||
| ==== | ||||
| * Avoid race in wl_seat capabilities [Olivier; !77] | ||||
| * Expose option groups/entries to introspection [Corentin; !1976] | ||||
|  | ||||
| Contributors: | ||||
|   Olivier Fourdan, Corentin Noël | ||||
|  | ||||
| Translators: | ||||
|   Daniel Șerbănescu [ro], Goran Vidović [hr], Luna Jernberg [sv], | ||||
|   eshagh shahidani [fa], Gwan-gyeong Mun [ko], Emin Tufan Çetin [tr], | ||||
|   Philipp Kiemle [de], Balázs Úr [hu], Piotr Drąg [pl], Nathan Follens [nl], | ||||
|   Jordi Mas [ca], Ask Hjorth Larsen [da] | ||||
|  | ||||
| 41.rc | ||||
| ===== | ||||
| * Add clutter_stage_paint_to_content() [Ivan; !1899] | ||||
| * Add meta_cursor_tracker_get_scale() [Ivan; !1967] | ||||
| * wayland: Make each wl_output correspond to one monitor [Jonas; !1712] | ||||
| * Expose 'inactive-since' timestamp to uresourced [Nishal; !1960] | ||||
| * Pass dirty rects to secondary GPU [Piotr; !1879] | ||||
| * Support commiting preedit string on focus loss [Carlos; !1940] | ||||
| * Improve auto-rotation support [Marco; !1233] | ||||
| * Add meta_window_actor_paint_to_content() [Robert; !1893] | ||||
| * Fixed crashes [Jonas, Ray, Robert; !1947, !1979, !1965, !1958] | ||||
| * Misc. bug fixes and cleanups [Florian, Carlos, Robert, Daniel, Erico, Dor; | ||||
|   !1957, !1924, !1970, !1971, !1972, !1973, !1974, !1977, !1978, !1975, !1886, | ||||
|   !1983, !1990, !1980] | ||||
|  | ||||
| Contributors: | ||||
|   Marco Trevisan (Treviño), Dor Askayo, Carlos Garnacho, Nishal Kulkarni, | ||||
|   Piotr Lopatka, Robert Mader, Ivan Molodetskikh, Florian Müllner, Erico Nunes, | ||||
|   Ray Strode, Daniel van Vugt, Jonas Ådahl | ||||
|  | ||||
| Translators: | ||||
|   Asier Sarasua Garmendia [eu], Claude Paroz [fr], Jiri Grönroos [fi], | ||||
|   Baurzhan Muftakhidinov [kk], Aurimas Černius [lt] | ||||
|  | ||||
| 41.beta | ||||
| ======= | ||||
| * Fix mouse position in remote desktop with fractional scaling [Pascal; !1867] | ||||
| * Manage idle monitors via MetaIdleManager [Jonas Å.; !1859] | ||||
| * Disable KMS modifiers on radeon driver [Carlos; !1872] | ||||
| * Fix fd leak [Carlos; !1870] | ||||
| * Fix adding virtual monitor to physical session [Jonas Å.; !1891] | ||||
| * Unbreak press-drag-release to pop up and select right click menus | ||||
|   [Carlos; !1885] | ||||
| * Fix VKMS detection [Jonas Å.; !1892] | ||||
| * Fix swipe cancellation [JoseExposito; !1857] | ||||
| * Add ClutterTextureContent [Robert; !1888] | ||||
| * Fix mapping tablet to monitor [Christoph; !1887] | ||||
| * Fix area screencasts when window is unredirected [Michel; !1902] | ||||
| * Don't require a newly attached buffer to apply state [Christian, Jonas; !1795] | ||||
| * Close unused mode setting and rendering devices [Jonas Å.; !1828] | ||||
| * Only support super+scroll on wayland [Florian; !1922] | ||||
| * Implement the xdg-activation protocol [Carlos; !1845] | ||||
| * Reduce input latency by computing max render time heuristically [Ivan; !1762] | ||||
| * Apply dithering to dispatch time when needed [Daniel; !1826] | ||||
| * Introduce MetaContext [Jonas Å.; !1861] | ||||
| * x11: Compute monitor scale per output [Marco; !336] | ||||
| * Shrink and optimize the rounded-background-clip shader [Daniel; !1860] | ||||
| * remote-desktop: Handle non-responding selection owners [Pascal; !1874] | ||||
| * Improve sysprof support [Jonas Å.; !1700] | ||||
| * Allow clients to delegate titlebar gestures to the compositor [Florian; !1944] | ||||
| * Fix upside-down Xshape surface with EGLstream [Robert; !1937] | ||||
| * Fix 'kms-modifiers' experimental setting [Robert; !1953] | ||||
| * Make default focus window on each workspace appear focused [Alexander; !850] | ||||
| * Plugged memory leaks [Jonas Å.; !1869] | ||||
| * Fixed crashes crash [Daniel, Jonas Å., Florian; !1883, !1895, | ||||
|   !1910, !1925, !1956] | ||||
| * Misc. bug fixes and cleanups [Jonas Å., Marco, Daniel, Florian, Georges, | ||||
|   Zander, Carlos, Robert; !1833, !1863, !1876, !1873, !1884, !1890, !1900, | ||||
|   !1912, !1916, !1911, !1920, !1865, !1927, !1923, !1929, !1100, !1932, !1931, | ||||
|   !1862, !1933, !1930, !1935, !1936, !1878, !1938, !1942, !1951, !522, !1941] | ||||
|  | ||||
| Contributors: | ||||
|   Marco Trevisan (Treviño), Zander Brown, Piotr Drąg, Michel Dänzer, | ||||
|   Carlos Garnacho, JoseExposito, Robert Mader, Alexander Mikhaylenko, | ||||
|   Ivan Molodetskikh, Florian Müllner, Georges Basile Stavracas Neto, | ||||
|   Pascal Nowack, Christian Rauch, Christoph Trassl, Daniel van Vugt, Jonas Ådahl | ||||
|  | ||||
| Translators: | ||||
|   Pawan Chitrakar [ne], Charles Monzat [fr], Dušan Kazik [sk], | ||||
|   Quentin PAGÈS [oc], Alexey Rubtsov [ru], Alexander Shopov [bg], | ||||
|   Florentina Mușat [ro], Chao-Hsiung Liao [zh_TW], Yuri Chornoivan [uk], | ||||
|   Fran Dieguez [gl], Hugo Carvalho [pt], Rafael Fontenelle [pt_BR], | ||||
|   Fabio Tomat [fur], Kukuh Syafaat [id], Yaron Shahrabani [he], | ||||
|   Marek Černocký [cs], Matej Urbančič [sl], Boyuan Yang [zh_CN], | ||||
|   Daniel Mustieles [es] | ||||
|  | ||||
| 40.1 | ||||
| ==== | ||||
| * Prevent clients from pasting old selection data [Carlos; !1772] | ||||
| * Fix forward_key IM functionality on wayland [Takao; !1802] | ||||
| * Ensure valid window texture size after viewport changes [Robert; !1799] | ||||
| * Only update cached paint volumes when necessary [Jonas D.; !1773, !1829] | ||||
| * Only disable KMS modifiers for drivers with known problems [Jonas Å; !1792] | ||||
| * Fix X11 client resize during moves [Olivier; !1777] | ||||
| * Fix performance drop during night light transition with Nvidia [Aaron; !1816] | ||||
| * kms: Don't add common modes that exceed the max bandwidth [Jonas Å.; !1834] | ||||
| * Create virtual input devices on demand [Jonas Å; !1800, !1858] | ||||
| * Fix wrong night light gamma when leaving power saving [Jonas Å.; !1835] | ||||
| * Fix picking edge case [Sebastian; !1842] | ||||
| * Properly tear down things when shutting down [Jonas Å.; !1822, !1856, !1853] | ||||
| * Fix monitor screencasting with fractional scaling [kirbykevinson; !1855] | ||||
| * Fixed crash [Carlos; !1849] | ||||
| * Plugged memory leak [Carlos; !1839] | ||||
| * Misc. bug fixes and cleanups [Carlos, Daniel, Jonas D., Jonas Å., Robert, | ||||
|   Aleksandr, Florian, Michel, Sebastian, Olivier; !1785, !1798, !1784, | ||||
|   !1791, !1801, !1807, !1786, !1793, !1804, !1820, !1824, !1819, !1803, | ||||
|   !1821, !1806, !1814, !1831, !1832, !1836, !1843, !1740, !1841, !1827, | ||||
|   !1844, !1852, !1850, !1851] | ||||
|  | ||||
| Contributors: | ||||
|   Jonas Ådahl, Michel Dänzer, Jonas Dreßler, Olivier Fourdan, Takao Fujiwara, | ||||
|   Carlos Garnacho, Sebastian Keller, kirbykevinson, Robert Mader, | ||||
|   Aleksandr Mezin, Florian Müllner, Aaron Plattner, Daniel van Vugt | ||||
|  | ||||
| Translators: | ||||
|   Bruce Cowan [en_GB], Ngọc Quân Trần [vi], Marek Černocký [cs], | ||||
|   Dz Chen [zh_CN], Yosef Or Boczko [he], Nathan Follens [nl], | ||||
|   Yuri Chornoivan [uk], Jordi Mas [ca], Piotr Drąg [pl], Tim Sabsch [de], | ||||
|   Luna Jernberg [sv], Hugo Carvalho [pt], Rafael Fontenelle [pt_BR], | ||||
|   Asier Sarasua Garmendia [eu], Quentin PAGÈS [oc], Matej Urbančič [sl] | ||||
|  | ||||
| 40.0 | ||||
| ==== | ||||
| * xwayland: Check permissions on /tmp/.X11-unix [Olivier; !1787] | ||||
|  | ||||
| Contributors: | ||||
|   Olivier Fourdan | ||||
|  | ||||
| Translators: | ||||
|   Hugo Carvalho [pt], Tim Sabsch [de], Daniel Mustieles [es], | ||||
|   Matej Urbančič [sl], Марко Костић [sr], Fran Dieguez [gl] | ||||
|  | ||||
| 40.rc | ||||
| ===== | ||||
| * Fix keyboard input from remote desktop in Xorg session [Pascal; !1732] | ||||
| * Fix restoring focus to windows using globally active input [Olivier; !1716] | ||||
| * Expose unaccalerated touchpad gesture deltas [Alexander; !1353] | ||||
| * Avoid relayout on text attribute changes when possible [Jonas D.; !1750] | ||||
| * Add remote desktop caps- and num-lock state properties [Jonas Å.; !1739] | ||||
| * Improve refresh rate calculation [Akihiko; !1737] | ||||
| * Implement presentation-time protocol [Ivan; !1484] | ||||
| * Disable double-buffered shadow buffering [Jonas Å.; !1724] | ||||
| * Fix missing cursor on tablet devices [Jonas D.; !1758] | ||||
| * Fix frame timings causing X11 clients to get stuck [Jonas Å.; !1754] | ||||
| * Fix applying input settings on X11 [Marco, Suryashankar; !1769, !1767] | ||||
| * Add headless native backend [Jonas Å.; !1698] | ||||
| * Fix high latency and stalls with proprietary nvidia driver [Daniel; !1726] | ||||
| * Fix maximized windows not reacting to strut changes [Aleksandr; !1755] | ||||
| * Only start XWayland on demand when running under systemd [Benjamin; !1771] | ||||
| * Sync LEDs when a new input device is added [Olivier; !1662] | ||||
| * Fix order in which subsurface placement operations are handled [Robert; !1768] | ||||
| * Fixed crashes [Jonas Å., Sebastian; !1745, !1747, !1759, !1748, !1776, !1775] | ||||
| * Plugged leaks [Philip, Sebastian; !1738, !1728] | ||||
| * Misc. bug fixes and cleanups [Jonas Å., Jonas D., Ivan, Florian, Marco, | ||||
|   Robert; !1688, !1744, !1736, !1749, !1752, !1753, !427, !1757, !1751, !1760, | ||||
|   !1765, !1770, !1763, !1774, !1780, !1779, !1783] | ||||
|  | ||||
| Contributors: | ||||
|   Jonas Ådahl, Benjamin Berg, Suryashankar Das, Jonas Dreßler, Olivier Fourdan, | ||||
|   Sebastian Keller, Robert Mader, Aleksandr Mezin, Alexander Mikhaylenko, | ||||
|   Ivan Molodetskikh, Florian Müllner, Pascal Nowack, Akihiko Odaki, | ||||
|   Marco Trevisan (Treviño), Daniel van Vugt, Philip Withnall | ||||
|  | ||||
| Translators: | ||||
|   Fran Dieguez [gl], Asier Sarasua Garmendia [eu], Claude Paroz [fr], | ||||
|   Piotr Drąg [pl], Hugo Carvalho [pt], Jordi Mas [ca], Fabio Tomat [fur], | ||||
|   Yuri Chornoivan [uk], Enrico Nicoletto [pt_BR], Emin Tufan Çetin [tr], | ||||
|   Daniel Șerbănescu [ro], Marek Černocký [cs], Balázs Úr [hu], | ||||
|   Aurimas Černius [lt], Kukuh Syafaat [id], A S Alam [pa], Anders Jonsson [sv], | ||||
|   Milo Casagrande [it], Gwan-gyeong Mun [ko] | ||||
|  | ||||
| 40.beta | ||||
| ======= | ||||
| * Consider clients without mapped windows for xwayland auto-shutdown | ||||
|   [Olivier; !1671] | ||||
| * Let compositor to handle super+scroll events [Florian; !1674, !1695] | ||||
| * Default to starting Xwayland on demand [Olivier; !1673] | ||||
| * xwayland: Restore abstract socket support [James, Olivier; !1669] | ||||
| * Add support for atomic mode setting [Jonas Å.; !1488] | ||||
| * Fix clip region glitches when using fractional scaling [Daniel; !1554] | ||||
| * Default to horizontal workspace layout [Georges, Florian; !1684, !1706] | ||||
| * Do not ping unmanaging windows [Florian; gnome-shell#2467] | ||||
| * Handle monitor changes during screencasts [Jonas Å.; !1691] | ||||
| * Fix unexpected jumps after restoring misbehaving clients [Jonas Å.; !1445] | ||||
| * Fix newly opened X11 windows being invisible in overview [Olivier; !1678] | ||||
| * Fix viewport of offscreen effects [Daniel; !1053] | ||||
| * Fix drag cancel animation when using geometry scaling [Robert; !1683] | ||||
| * Improve touch-mode heuristics [Carlos; !1710] | ||||
| * Integrate clipboard with remote desktop sessions [Jonas Å.; !1552] | ||||
| * Fix stuck icon in DND operation between X11 and wayland [Carlos; !1720] | ||||
| * Automatically synchronize pointer position after modal grabs  [Carlos; !1659] | ||||
| * Reimplement support for CLUTTER_SHOW_FPS [Daniel; !154] | ||||
| * Only pick on events that may move the pointer [Jonas D.; !1729, !1733] | ||||
| * Emit discrete scroll events for accumulated smooth events in virtual | ||||
|   X11 devices [Pascal; !1727] | ||||
| * Add support for rounded clipping when drawing background [Jonas D.; !1717] | ||||
| * Plugged memory leaks [Sebastian; !1307, !1699] | ||||
| * Fixed crashes [Carlos, Thomas, Jonas Å., Olivier; !1677, !1685, !1692, | ||||
|   !1719, !1718, !1735] | ||||
| * Misc. bug fixes and cleanups [Jonas Å., Carlos, Olivier, Sebastian, Björn, | ||||
|   Jonas D., Ivan, Georges, Dor, Michel, Robert; !1670, !1679, !1680, !1682, | ||||
|   !1681, !1661, !1689, !1690, !1693, !1514, !1696, !1697, !1708, !1709, !1707, | ||||
|   !1701, !1702, !1715, !1725, !1734, !1512] | ||||
|  | ||||
| Contributors: | ||||
|   Jonas Ådahl, Dor Askayo, Björn Daase, Michel Dänzer, Jonas Dreßler, | ||||
|   Olivier Fourdan, Carlos Garnacho, James Henstridge, Sebastian Keller, | ||||
|   Robert Mader, Ivan Molodetskikh, Thomas Mühlbacher, Florian Müllner, | ||||
|   Georges Basile Stavracas Neto, Pascal Nowack, Daniel van Vugt | ||||
|  | ||||
| Translators: | ||||
|   Марко Костић [sr], Jordi Mas [ca], Yuri Chornoivan [uk], | ||||
|   Daniel Șerbănescu [ro], Hugo Carvalho [pt], Fran Dieguez [gl], | ||||
|   Matej Urbančič [sl], Marek Černocký [cs], Rafael Fontenelle [pt_BR], | ||||
|   Philipp Kiemle [de], A S Alam [pa], Balázs Úr [hu], Anders Jonsson [sv], | ||||
|   Daniel Mustieles [es], Emin Tufan Çetin [tr], Kukuh Syafaat [id], | ||||
|   Aurimas Černius [lt] | ||||
|  | ||||
| 40.alpha.1.1 | ||||
| ============ | ||||
| * Adapt to settings moving to gsettings-desktop-schemas [Carlos; !1416] | ||||
| * Misc. bug fixes and cleanups [Georges; !1667] | ||||
|  | ||||
| Contributors: | ||||
|   Carlos Garnacho, Georges Basile Stavracas Neto | ||||
|  | ||||
| 40.alpha.1 | ||||
| ========== | ||||
| * Base ClutterEffects on ClutterPaintNodes [Georges; !1340, !1355] | ||||
| * xwayland: Set xrandr primary output [Aleksandr; !1558] | ||||
| * Add paint node based blur support [Georges; !1627, !1646] | ||||
| * Disable CRTCs if there is no monitor [Kai-Heng; !1561] | ||||
| * Fix updates of mipmapped animated backgrounds [Daniel; !1664] | ||||
| * Allow remote desktop clients to specify scroll source [Pascal; !1636] | ||||
| * Support the color transform matrix RandR property on X11 [Aaron; !1048] | ||||
| * Plugged memory leaks [Jonas D.; !1632] | ||||
| * Fixed crashes [Jonas Å., Olivier, Carlos; !1557, !1648, !1643, !1654, !1663] | ||||
| * Misc. bug fixes and cleanups [Olivier, Niels, Carlos, Jonas Å., Florian, | ||||
|   Jonas D., Daniel, Georges, Michel, Sebastian, Marc-Antoine; !1621, !1622, | ||||
|   !1624, !1623, !1625, !1626, !1630, !1631, !1576, !1635, !1640, !1642, | ||||
|   !1639, !1644, !1637, !1615, !1647, !1633, !1634, !1651, !1652, !1657, | ||||
|   !1660, !1658, !1665, !1649, !1668, !1655] | ||||
|  | ||||
| Contributors: | ||||
|   Jonas Ådahl, Michel Dänzer, Jonas Dreßler, Kai-Heng Feng, Olivier Fourdan, | ||||
|   Carlos Garnacho, Niels De Graef, Sebastian Keller, Aleksandr Mezin, | ||||
|   Florian Müllner, Georges Basile Stavracas Neto, Pascal Nowack, | ||||
|   Marc-Antoine Perennou, Aaron Plattner, Daniel van Vugt | ||||
|  | ||||
| Translators: | ||||
|   Kjartan Maraas [nb], Juliano de Souza Camargo [pt], Florentina Mușat [ro], | ||||
|   Daniel Mustieles [es], Jordi Mas i Hernandez [ca], Fabio Tomat [fur], | ||||
|   Philipp Kiemle [de], Asier Sarasua Garmendia [eu], Aurimas Černius [lt], | ||||
|   Fran Dieguez [gl], Hugo Carvalho [pt], Matej Urbančič [sl] | ||||
|  | ||||
| 40.alpha | ||||
| ======== | ||||
| * Replace CoglMatrix with graphene_matrix [Georges; !1439] | ||||
| * Allow to specify debug topics in MUTTER_DEBUG [Jonas Å.; !1465] | ||||
| * Fix unwanted position changes on window resize | ||||
|   [Jonas Å., Olivier, Robert; !1477, !1495] | ||||
| * Do not disable the X Security extension by default [Olivier; !1485] | ||||
| * Fix _NET_WM_FRAME_DRAWN timestamps [Jonas Å.; !1494] | ||||
| * Fix tiling to the correct monitor [Florian; #1389] | ||||
| * Only snap to window edges when CTRL is pressed [Florian; #679609] | ||||
| * Add support for scroll button locking [Peter; !1432] | ||||
| * Clip Frustra [Georges; !1489] | ||||
| * Improve tablet-mode-switch support [Hans; !1506] | ||||
| * Fix missed redraws of newly-mapped actors [Jonas D.; !1366, #1494] | ||||
| * Gracefully handle Xwayland crashes [Carlos; !1447] | ||||
| * wayland: Provide previous window dimensions on restore [Christian; !801] | ||||
| * Remove the ClutterActor::paint signal [Jonas; !1522] | ||||
| * Fix background artifacts in magnifier [Daniel; #1480] | ||||
| * Use raycasting for picking [Georges; !1509] | ||||
| * Fix monitor tiling support on X11 [Jonas Å.; #1524] | ||||
| * Fix xwayland grabs for override-redirect windows [Olivier; !1254] | ||||
| * Fix device configuration not being picked up on X11 [Carlos; !1553] | ||||
| * Support tagging devices as primary GPU via udev [Jonas Å.; !1562] | ||||
| * Fix size hints with CSD [Olivier; !1594] | ||||
| * Fix unresponsive input after screen blank [Simon; !1601] | ||||
| * Cull actors when picking [Georges; !1520] | ||||
| * Handle input in a thread [Carlos; !1403] | ||||
| * Improve freezes when switching workspace [Jonas Å.; !1616] | ||||
| * Plugged memory leaks [Ray; !1225] | ||||
| * Fixed crashes [Christian, Olivier, Daniel, Robert, Jonas Å., Florian Z., | ||||
|   Simon, Carlos; #1481, !1529, !1519, !1534, #1521, !1563, !1604, !1605, | ||||
|   !1607, !1612] | ||||
| * Misc. bug fixes and cleanups [Florian, Carlos, Olivier, Georges, Björn, | ||||
|   Jonas Å., Julius, Corentin, Bastien, Robert, Daniel, Niels, Jonas D., Uday, | ||||
|   Ian, Jordan, Piotr; !1473, !1472, !1438, #1449, !1475, !1474, !1481, !1466, | ||||
|   !1483, !1427, !1413, !1103, !1467, !1339, !1297, #1384, !1491, !528, !1496, | ||||
|   !1510, !1507, !1387, !1498, !1515, !1516, !1517, !1486, !1524, !1527, !1528, | ||||
|   !1531, !1532, !1521, !1535, #1490, !1545, !1555, !1564, !1549, !1567, !1565, | ||||
|   !1572, !1569, !1573, !1566, !1525, !1468, !1578, !1583, !1584, !1585, !1571, | ||||
|   !1327, !1586, !1590, !1588, !1050, !1596, !1592, !1587, !1599, !1577, !1511, | ||||
|   !1591, !1603, !1611, !1593, !1617, !1619] | ||||
|  | ||||
| Contributors: | ||||
|   Björn Daase, Jonas Dreßler, Piotr Drąg, Olivier Fourdan, Carlos Garnacho, | ||||
|   Hans de Goede, Niels De Graef, Peter Hutterer, Julius Lehmann, Robert Mader, | ||||
|   Simon McVittie, Florian Müllner, Georges Basile Stavracas Neto, | ||||
|   Bastien Nocera, Corentin Noël, Jordan Petridis, Uday Kiran Pichika, | ||||
|   Christian Rauch, Ian Douglas Scott, Ray Strode, Daniel van Vugt, | ||||
|   Florian Zwoch, Jonas Ådahl | ||||
|  | ||||
| Translators: | ||||
|   Juliano de Souza Camargo [pt], Ask Hjorth Larsen [da], Yuri Chornoivan [uk] | ||||
|  | ||||
| 3.38.1 | ||||
| ====== | ||||
| * Fix Night Light updates after DPMS [Jonas, Benjamin; #1392] | ||||
| * Fix button scrolling on X11 [Peter; !1431] | ||||
| * Always use correct font-dpi setting on X11 [Marco; !1444] | ||||
| * Improve handling of scanout failures [Jonas; #1410] | ||||
| * Fix middle/right button mixup in scroll button assignment [Peter; !1433] | ||||
| * Fix resizing of attached modal dialogs on wayland [Jonas; !1446] | ||||
| * Enable KMS modifiers on devices that need them [Karol; !1443] | ||||
| * Fix IM handling on X11 [Carlos; #1413] | ||||
| * Fix glitches in "undefined" screencast areas [Jonas; !1459] | ||||
| * Fix visual glitches on background with fractional scaling [Daniel; !1464] | ||||
| * Fix using correct refresh rate [Jonas; #1430] | ||||
| * Misc. bug fixes and cleanups [Daniel, Carlos, Robert, Simon, Sergio; !1362, | ||||
|   !1448, !1452, !1273, !1454, !1429, !1460, !1458, !1463, !1462] | ||||
| * Plugged memory leaks [Ray; !1449, !1451] | ||||
|  | ||||
| Contributors: | ||||
|   Marco Trevisan (Treviño), Benjamin Berg, Sergio Costas, Carlos Garnacho, | ||||
|   Karol Herbst, Peter Hutterer, Robert Mader, Simon McVittie, Ray Strode, | ||||
|   Daniel van Vugt, Jonas Ådahl | ||||
|  | ||||
| Translators: | ||||
|   Juliano de Souza Camargo [pt], Rafael Fontenelle [pt_BR], | ||||
|   Yosef Or Boczko [he], Jordi Mas [ca] | ||||
|  | ||||
| 3.38.0 | ||||
| ====== | ||||
| * screencast: Only use DMA buffers for i915 [Jonas; !1442] | ||||
| * Fixed crashes [Jonas, Simon; !1430, #1414] | ||||
|  | ||||
| Contributors: | ||||
|   Simon McVittie, Jonas Ådahl | ||||
|  | ||||
| Translators: | ||||
|   Anders Jonsson [sv], Gil Forcada [ca], Balázs Meskó [hu], Tim Sabsch [de], | ||||
|   Milo Casagrande [it], Bruce Cowan [en_GB], Rūdolfs Mazurs [lv] | ||||
|  | ||||
| 3.37.92 | ||||
| ======= | ||||
| * Fix stale cursor positions in remote desktop sessions [Georges; !1417] | ||||
| * xwayland: Add a setting to disable selected X extensions [Olivier; !1405] | ||||
| * Fix screencasting when using QXL [Jonas Å., Grey; !1318] | ||||
| * Cull actors that don't intersect with the redraw clip [Daniel; !1359] | ||||
| * Optimize painting of backgrounds when culling is unavailable [Daniel; !1363] | ||||
| * Improve support for Hangul input method [Carlos; !1286] | ||||
| * Support debug paint overlay for opaque regions [Robert; !1372] | ||||
| * Fix launching flatpak applications when autostarting Xwayland [Carlos; !1424] | ||||
| * Add support for capture scanouts in screencasts [Georges; !1421] | ||||
| * Allow integrated tablet devices to cycle outputs [Carlos; !1201] | ||||
| * Improve mapping input devices to the most relevant output [Carlos; !1202] | ||||
| * Only enable auto-rotation in touch mode [Carlos; !1311] | ||||
| * Fixed crashes [Pascal, Robert, Carlos, Benjamin, Marco; !1414, !1409, !1408, | ||||
|   !1415, #1395, !1392, !1371, #1345] | ||||
| * Misc. bug fixes and cleanups [Björn, Jonas D., Florian; !1410, !1358, !1425] | ||||
|  | ||||
| Contributors: | ||||
|   Marco Trevisan (Treviño), Benjamin Berg, Grey Christoforo, Björn Daase, | ||||
|   Jonas Dreßler, Olivier Fourdan, Carlos Garnacho, Robert Mader, | ||||
|   Florian Müllner, Georges Basile Stavracas Neto, Pascal Nowack, | ||||
|   Daniel van Vugt, Jonas Ådahl | ||||
|  | ||||
| Translators: | ||||
|   Marek Černocký [cs], Aurimas Černius [lt], Asier Sarasua Garmendia [eu], | ||||
|   Gwan-gyeong Mun [ko], Yuri Chornoivan [uk], Boyuan Yang [zh_CN], | ||||
|   Kukuh Syafaat [id], Piotr Drąg [pl], Rafael Fontenelle [pt_BR], | ||||
|   Марко Костић [sr], Matej Urbančič [sl], Fabio Tomat [fur], | ||||
|   Daniel Mustieles [es], Fran Dieguez [gl], Goran Vidović [hr], | ||||
|   Claude Paroz [fr], Andre Klapper [or, ug, te], Emin Tufan Çetin [tr] | ||||
|  | ||||
| 3.37.91 | ||||
| ======= | ||||
| * Fix initial state of display mode OSD [Jian-Hong; #1362] | ||||
| * Fixed crashes [Jonas Å., Robert; !1407, !1411] | ||||
| * Misc. bug fixes and cleanups [Jonas Å., Christian; !1404, !1364, #1331] | ||||
|  | ||||
| Contributors: | ||||
|   Jonas Ådahl, Robert Mader, Jian-Hong Pan, Christian Rauch | ||||
|  | ||||
| Translators: | ||||
|   Fran Dieguez [gl], Daniel Mustieles [es], Florentina Mușat [ro], | ||||
|   Kukuh Syafaat [id], Piotr Drąg [pl], Emin Tufan Çetin [tr], Марко Костић [sr], | ||||
|   Akarshan Biswas [bn_IN], Matej Urbančič [sl], Boyuan Yang [zh_CN], | ||||
|   Goran Vidović [hr], Rafael Fontenelle [pt_BR] | ||||
|  | ||||
| 3.37.90 | ||||
| ======= | ||||
| * Fix using NEAREST filter for backgrounds on scaled monitors [Daniel V.; !1346] | ||||
| * Screencast fixes and improvements [Jonas; !1361, !1377, !1391] | ||||
| * Support tap-button-map and tap-drag-lock touchpad settings [Giusy; !1319] | ||||
| * Fix wine copy & paste [Sebastian; !1369] | ||||
| * Fix shadows of server-side decorated XWayland windows [Olivier; #1358] | ||||
| * Replace some loaded terms with more descriptive ones [Olivier; !1396] | ||||
| * Add API to launch trusted wayland clients [Sergio; #741] | ||||
| * Skip displays with 'non-desktop' property set [Philipp; !1393] | ||||
| * Invalidate offscreen effect cache on video memory purge [Daniel V.; !1374] | ||||
| * Add wl_shm support for 10 bpc and 16 bpc half float formats [Jonas; !804] | ||||
| * Fixed crashes [Jonas, Erik, Martin; !1365, !1375, #1343] | ||||
| * Misc. bug fixes and cleanups [Daniel V., Carlos, Olivier, Christian, | ||||
|   Daniel * G., Jonas, Florian; !1370, !1376, !1385, !1352, !1386, !1390, | ||||
|   !1388, !1397, !1398, !1401] | ||||
|  | ||||
| Contributors: | ||||
|   Jonas Ådahl, Sergio Costas, Olivier Fourdan, Carlos Garnacho, | ||||
|   Christian Hergert, Sebastian Keller, Erik Kurzinger, Giusy Margarita, | ||||
|   Daniel García Moreno, Florian Müllner, Daniel van Vugt, Martin Whitaker, | ||||
|   Philipp Zabel | ||||
|  | ||||
| Translators: | ||||
|   Fabio Tomat [fur], Rafael Fontenelle [pt_BR], Jordi Mas [ca], | ||||
|   Yuri Chornoivan [uk], Alexandre Franke [fr] | ||||
|  | ||||
| 3.37.3 | ||||
| ====== | ||||
| * Support custom keyboard layouts in $XDG_CONFIG_HOME/xkb [Peter; !936] | ||||
| * Optimize resource scale computation [Jonas D.; !1196, !1276, !1343] | ||||
| * Allow animating ClutterActor's content property [Georges; !1301] | ||||
| * Implement backgrounds as ClutterContent [Georges; !1302] | ||||
| * Add ClutterAlignContraint:pivot-point property [Jonas D.; !737] | ||||
| * Fix crash on area screenshots with fractional scaling [Sebastian; !1320] | ||||
| * Do not paint textures of fully obscured windows [Robert; !1326] | ||||
| * Use a more appropriate combine function on opaque areas [Daniel; !1331] | ||||
| * Fix remote desktop being broken without screencast session [Olivier; #1307] | ||||
| * Remove more long-deprecated Clutter APIs [Adam, Georges; !1194, !1332] | ||||
| * Drive each monitor by its own frame clock [Jonas Å.; !1285] | ||||
| * Fix copy/paste failures on X11 [Carlos; !1350] | ||||
| * Mipmap background texture rendering [Daniel; !1347] | ||||
| * Plugged memory leaks [Sebastian, Jonas D.; !1293, !1281, !1304] | ||||
| * Misc. bug fixes and cleanups [Jonas Å., Jonas D., Daniel, Corentin, Carlos, | ||||
|   Sebastian, Michel, Robert, Florian; !1288, !1289, !1291, !1296, !1292, !1298, | ||||
|   !1300, !1303, !1290, !1287, !1306, !1305, !1308, !1313, !1250, !1314, !1267, | ||||
|   !1275, !1317, !1270, !1322, !1181, !1282, !1325, !1323, !1240, !1295, !1329, | ||||
|   !1333, !1334, !1336, !1341, #1312, !1345, !1349, !1356, #873, !1310, !1357] | ||||
|  | ||||
| Contributors: | ||||
|   Jonas Dreßler, Michel Dänzer, Olivier Fourdan, Carlos Garnacho, | ||||
|   Peter Hutterer, Adam Jackson, Sebastian Keller, Robert Mader, Florian Müllner, | ||||
|   Georges Basile Stavracas Neto, Corentin Noël, Daniel van Vugt, Jonas Ådahl | ||||
|  | ||||
| 3.37.2 | ||||
| ====== | ||||
| * Fix move-to-center keybinding with multiple monitors [Sergey; #1073] | ||||
| * Fix stuck buttons when a virtual device is destroyed [Carlos; !1239] | ||||
| * Use workarea when centering new windows [Akatsuki; #964] | ||||
| * Limit mipmap levels when rendering background [Daniel; !1003] | ||||
| * Broadcast clipboard/primary offers [Carlos; !1253] | ||||
| * Support primary-selection protocol from wayland-protocols [Carlos; !1255] | ||||
| * Fix monitor screen cast on X11 [Jonas Å.; !1251] | ||||
| * Support a "blank" cursor type [Florian; !1244] | ||||
| * Improve stage view damage tracking [Jonas Å.; !1237] | ||||
| * Implement touch-mode detecation for the X11 backend [Carlos; !1278] | ||||
| * Drop external keyboard detection from touch-mode heuristics [Carlos; !1277] | ||||
| * Optimize actor allocations [Jonas D.; !1247] | ||||
| * Fixed crashes [Daniel, Carlos, Jonas Å., Jonas D.; !1256, !1258, !1217, !1280] | ||||
| * Misc. bug fixes and cleanups [Christian, Jonas D., Olivier, Ting-Wei, | ||||
|   Jonas Å., Marco, Corentin, Daniel, Robert, Niels, Florian, Simon; !1231, | ||||
|   !1228, !1238, !1229, !1192, !1236, !1171, !1134, #1126, !1234, !1230, !1210, | ||||
|   !1242, !1243, !1252, !1113, !1232, !1259, !1245, !1265, !1180, !1261, !788, | ||||
|   !1264, !1235, !1218, !1150, !1274, !1271, !1279, !1283, !1272] | ||||
|  | ||||
| Contributors: | ||||
|   Marco Trevisan (Treviño), Akatsuki, Jonas Dreßler, Olivier Fourdan, | ||||
|   Carlos Garnacho, Niels De Graef, Ting-Wei Lan, Robert Mader, Simon McVittie, | ||||
|   Florian Müllner, Corentin Noël, Christian Rauch, Daniel van Vugt, | ||||
|   Sergey Zigachev, Jonas Ådahl | ||||
|  | ||||
| 3.37.1 | ||||
| ====== | ||||
| * Fix screencasting non-maximized windows [Jonas Å.; !1174] | ||||
| * Make window-aliveness checks less aggressive [Jonas Å.; !1182] | ||||
| * Fix stylus coordinates when using screen rotation [Jonas T.; #1118] | ||||
| * Preserve keyboard state on VT switch [Olivier; !1185] | ||||
| * Remove Clutter's drag and drop actions [Jonas D.; !789] | ||||
| * Cancel clicks/gestures actions on disable [Georges; !1188] | ||||
| * Fix various clipboard issues [Carlos; !1186, !1198, !1203, !1204, !1206] | ||||
| * Fix trackball button scrolling [Phillip; #1120] | ||||
| * Fix tiled monitor support [Jonas; !1199] | ||||
| * Support unredirecting fullscreen wayland surfaces [Jonas Å.; !798] | ||||
| * Support area screencasts [Jonas Å.; !1207] | ||||
| * Synchronize shadows to server-side decorations [Olivier; !1214] | ||||
| * Allow inhibiting remote access [Jonas Å.; !1212] | ||||
| * Fix overview key on X11 when using multiple keyboard layouts [Olivier; !1219] | ||||
| * Fixed crashes [Jonas, D., Carlos; !1173, !1183, !1012] | ||||
| * Misc. bug fixes and cleanups [Andre, Georges, Christian, Jonas Å., Andre, | ||||
|   Simon, Florian, Carlos, Adam, Marco, Thomas, Elias, Pekka, Jonas D., | ||||
|   Laurent; !1169, !1168, !1166, !1170, !1167, !1172, !1175, !1176, !1184, | ||||
|   !1126, !1187, !1191, !1195, !1179, !1200, !1193, !1209, !1213, !1208, | ||||
|   #1074, !1223] | ||||
|  | ||||
| Contributors: | ||||
|   Marco Trevisan (Treviño), Elias Aebi, Thomas Hindoe Paaboel Andersen, | ||||
|   Laurent Bigonville, Jonas Dreßler, Olivier Fourdan, Carlos Garnacho, | ||||
|   Adam Jackson, Andre Moreira Magalhaes, Simon McVittie, Florian Müllner, | ||||
|   Georges Basile Stavracas Neto, Pekka Paalanen, Christian Rauch, Jonas Troeger, | ||||
|   Phillip Wood, Jonas Ådahl | ||||
|  | ||||
| Translators: | ||||
|   Dušan Kazik [sk], Christian Kirbach [de] | ||||
|  | ||||
| 3.36.0 | ||||
| ====== | ||||
| * Fix placement of popup windows in multi-monitor setups [Jonas; !1110] | ||||
| @@ -954,7 +443,7 @@ Contributors: | ||||
| 3.31.92 | ||||
| ======= | ||||
| * Fix flicker of apps that use multiple SHM buffers [Jonas Å.; #199] | ||||
| * Don't disable page flips after temporary failures [Jonas Å.; #460] | ||||
| * Don't disable page flips after temporary failues [Jonas Å.; #460] | ||||
| * Improve redraw performance [Carlos; !196] | ||||
| * Add cursor-mode support to window screencasting [Jonas Å.; !413] | ||||
| * Add back support for system-wide monitor configurations [Jonas Å.; !253] | ||||
| @@ -1366,7 +855,7 @@ Translations: | ||||
| ======= | ||||
| * Reduce memory use of suspended instances [Jonas; #786299] | ||||
| * Make supported scales determination saner [Rui; #786474] | ||||
| * Fix crash on inhibit-shortcuts dialog response [Jonas; #786385] | ||||
| * Fix crash on inhibit-shortcuts dialog reponse [Jonas; #786385] | ||||
| * Support libinput's tag-and-drag setting [freeroot; #775755] | ||||
| * Avoid overlapping keybindings with multiple layouts [Jonas; #786408] | ||||
| * Fix non-transformed cursor on rotated monitors [Jonas; #786023] | ||||
| @@ -1685,7 +1174,7 @@ Translations: | ||||
| * Consider XDG_SESSION_TYPE when determining session type [Jouke; #759388] | ||||
| * Re-add support for edge scrolling on some touchpads [Bastien; #768245] | ||||
| * Support mouse and trackball acceleration profile [Jonas; #769179] | ||||
| * Draw monitor content to individual framebuffer [Jonas; #768976] | ||||
| * Draw monitor contentn to individual framebuffer [Jonas; #768976] | ||||
| * Support virtual input devices [Jonas, Carlos; #765009] | ||||
| * Set correct output scale on hotplug [Jonas; #769505] | ||||
| * Misc. bug fixes and cleanups [Florian, Jonas, Thomas, Bastien, Carlos; | ||||
| @@ -2510,7 +1999,7 @@ Translations: | ||||
| * Ignore skip-taskbar hints on parentless dialogs [Giovanni; #673399] | ||||
| * Don't save pixbuf data in user data [Tim; #706777] | ||||
| * Don't queue redraws for obscured regions [Adel; #703332] | ||||
| * Support the opaque region hints for wayland clients [Jasper; #707019] | ||||
| * Suppor the opaque region hints for wayland clients [Jasper; #707019] | ||||
| * Turn blending off when drawing entirely opaque regions [Jasper; #707019] | ||||
| * Check event timestamps before reconfiguring [Giovanni; #706735] | ||||
| * Merge the DBus API for display configuration in the wayland branch [Giovanni] | ||||
| @@ -2995,7 +2484,7 @@ Translations: | ||||
| ====== | ||||
| * Automaximize large windows on map [Adel; #671677] | ||||
| * When unmaximizing windows, make sure the unminimized size | ||||
|   is significantly less than the maximized size [Adel; #671677] | ||||
|   is signficantly less than the maximized size [Adel; #671677] | ||||
| * Don't offer maximize option for windows larger than the screen | ||||
|   [Jasper; #643606] | ||||
| * Always focus the window immediately underneath without restacking | ||||
| @@ -3095,7 +2584,7 @@ Translations: | ||||
| * Move from GConf to GSettings for preferences [Florian; #635378] | ||||
| * Add meta_display_add_keybinding()/meta_display_remove_keybinding() | ||||
|   to allow creating new keybindings at runtime [Florian; #663428] | ||||
| * Add support for new _NET_WM_STATE_FOCUSED atom in _NET_WM_STATE | ||||
| * Add suport for new _NET_WM_STATE_FOCUSED atom in _NET_WM_STATE | ||||
|   to allow applications to draw unfocused windows differently | ||||
|   [Rui; #661427] | ||||
| * Add meta_window_move_resize_frame() to allow specifying the | ||||
| @@ -3207,7 +2696,7 @@ Contributors: | ||||
|   for easy resizing with thin borders. (New draggable_border_width GConf key | ||||
|   controls the total width of visible and invisible borders.) | ||||
|   [Jasper; #644930] | ||||
| * Draw rounded window corners with antialiasing [Jasper; #628195] | ||||
| * Draw rounded window corners with antialising [Jasper; #628195] | ||||
| * Unredirect override-redirect fullscreen windows, such as full-screen | ||||
|   3D games to avoid any performance impact [Adel; #597014] | ||||
| * Add :resizable and :above properties to MetaWindow. [Tim; #653858] | ||||
| @@ -3300,7 +2789,7 @@ Translations: | ||||
| 3.0.2.1 | ||||
| ======= | ||||
| * When saving the session, use the "program name" rather than | ||||
|   hardcoding mutter, fixing session saving for gnome-shell [Matthias] | ||||
|   harcoding mutter, fixing session saving for gnome-shell [Matthias] | ||||
|   https://bugzilla.gnome.org/show_bug.cgi?id=648828 | ||||
|  | ||||
| Contributors: | ||||
| @@ -3618,7 +3107,7 @@ Bugs fixed: | ||||
|  634779 MetaWindowGroup: further optimize paints by using current scissor | ||||
|  634833 Draw the root window background | ||||
|  592382 improve shadow effect | ||||
|  628199 Add antialiasing to arc and line drawing operations | ||||
|  628199 Add antialising to arc and line drawing operations | ||||
|  633002 meta-actor-window: Use G_UNLIKELY for TFP check | ||||
|  634771 MetaStackTracker: Avoid queueing resync for obvious no-ops | ||||
|  635421 Fix crash in check_needs_shadow | ||||
| @@ -3815,7 +3304,7 @@ Fixed Bugs: | ||||
|   - Allow a theme to turn on title ellipsization | ||||
| * Performance enhancements: | ||||
|   - Stream raw damage updates to ClutterX11TexturePixmap | ||||
|     to enable partial stage updates when windows change [Robert] | ||||
|     to enable partial stage updates when windos change [Robert] | ||||
|   - Don't trap XErrors in meta_compositor_process_event [Adel] | ||||
| * Add meta_prefs_override_preference_location(); this allows | ||||
|   a plugin like GNOME Shell to redirect preferences to a | ||||
| @@ -3860,7 +3349,7 @@ Fixed Bugs: | ||||
|  613136 - remove over-restrictive assert from meta_prefs_get_workspace_name() | ||||
|  613398 - Don't trap XErrors in meta_compositor_process_event | ||||
|  615586 - Allow redirecting preferences to a different GConf key | ||||
|  615672 - can't compile mutter error: dereferencing pointer ‘p’ does break | ||||
|  615672 - cant' compile mutter error: dereferencing pointer ‘p’ does break | ||||
|           strict-aliasing rules | ||||
|  616050 - alt-tab infrastructure patches | ||||
|  616274 - mutter from git fails with gcc 4.5 (on new warning) | ||||
| @@ -4806,7 +4295,7 @@ Arthur Taylor, Elijah Newren, Josselin Mouette, Havoc Pennington, | ||||
| Benjamin Berg, and Carlo Wood for improvements in this release. | ||||
|  | ||||
|   - new icon for the force-quit dialog (Jaap) [#396655] | ||||
|   - add configurable mouse click action abilities, and clean up lots of | ||||
|   - add configureable mouse click action abilities, and clean up lots of | ||||
|     related code (Linus) [#408899, #408902, others] | ||||
|   - add schemeas for middle and right click titlebar actions (Charlie) | ||||
|     [#408903] | ||||
| @@ -5360,7 +4849,7 @@ this release. | ||||
|    running with --disable-gconf.  Make --disable-gconf actually work. | ||||
|    (Elijah) [#326661] | ||||
|  - fix some reading-from-free'd-data errors (Søren) [#327575] | ||||
|  - fix an uninitialized value problem when in raise-on-click mode | ||||
|  - fix an unitialized value problem when in raise-on-click mode | ||||
|    (Søren) [#327572] | ||||
|  - avoid flashing original-sized window when closing a maximized | ||||
|    window (Elijah) [#317254] | ||||
|   | ||||
							
								
								
									
										31
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								README.md
									
									
									
									
									
								
							| @@ -26,34 +26,15 @@ debugging purposes. | ||||
|  | ||||
| To contribute, open merge requests at https://gitlab.gnome.org/GNOME/mutter. | ||||
|  | ||||
| It can be useful to look at the documentation available at the | ||||
| [Wiki](https://gitlab.gnome.org/GNOME/mutter/-/wikis/home). | ||||
|  | ||||
| ## Coding style and conventions | ||||
|  | ||||
| See [HACKING.md](./HACKING.md). | ||||
|  | ||||
| ## Git messages | ||||
| The coding style used is primarily the GNU flavor of the [GNOME coding | ||||
| style](https://developer.gnome.org/programming-guidelines/stable/c-coding-style.html.en) | ||||
| with some minor additions such as preferring `stdint.h` types over GLib | ||||
| fundamental types, and a soft 80 character line limit. However, in general, | ||||
| look at the file you're editing for inspiration. | ||||
|  | ||||
| Commit messages should follow the [GNOME commit message | ||||
| guidelines](https://wiki.gnome.org/Git/CommitMessages). We require an URL | ||||
| to either an issue or a merge request in each commit. Try to always prefix | ||||
| commit subjects with a relevant topic, such as `compositor:` or | ||||
| `clutter/actor:`, and it's always better to write too much in the commit | ||||
| message body than too little. | ||||
|  | ||||
| ## Default branch | ||||
|  | ||||
| The default development branch is `main`. If you still have a local | ||||
| checkout under the old name, use: | ||||
| ```sh | ||||
| git checkout master | ||||
| git branch -m master main | ||||
| git fetch | ||||
| git branch --unset-upstream | ||||
| git branch -u origin/main | ||||
| git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main | ||||
| ``` | ||||
| to either an issue or a merge request in each commit. | ||||
|  | ||||
| ## License | ||||
|  | ||||
|   | ||||
							
								
								
									
										138
									
								
								check-style.py
									
									
									
									
									
								
							
							
						
						
									
										138
									
								
								check-style.py
									
									
									
									
									
								
							| @@ -1,138 +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.Popen(["git", "diff", "-U0", "--function-context", sha, "HEAD"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) | ||||
|     files = proc.stdout.read().strip().decode('utf-8') | ||||
|     return files.split('\n') | ||||
|  | ||||
| def find_chunks(diff): | ||||
|     file_entry_re = re.compile('^\+\+\+ b/(.*)$') | ||||
|     diff_chunk_re = re.compile('^@@ -\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() | ||||
|             tmp.write(b'/** *INDENT-OFF* **/\n') | ||||
|             for i, line in enumerate(f): | ||||
|                 if i == start - 2: | ||||
|                     tmp.write(b'/** *INDENT-ON* **/\n') | ||||
|  | ||||
|                 tmp.write(bytes(line, 'utf-8')) | ||||
|  | ||||
|                 if i == end - 2: | ||||
|                     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.Popen(["uncrustify", "-c", uncrustify_cfg, "-f", tmp.name], stdout=subprocess.PIPE) | ||||
|         reindented = proc.stdout.readlines() | ||||
|         proc.wait() | ||||
|         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.Popen(["diff", "-up", "--color=always", chunk['file'], formatted.name], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) | ||||
|             diff = proc.stdout.read().decode('utf-8') | ||||
|             if diff != '': | ||||
|                 output = re.sub('\t', '↦\t', diff) | ||||
|                 print(output) | ||||
|                 changed = True | ||||
|         else: | ||||
|             # Apply changes | ||||
|             diff = subprocess.Popen(["diff", "-up", chunk['file'], formatted.name], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) | ||||
|             patch = subprocess.Popen(["patch", chunk['file']], stdin=diff.stdout) | ||||
|             diff.stdout.close() | ||||
|             patch.communicate() | ||||
|  | ||||
|         formatted.close() | ||||
|  | ||||
|     return changed | ||||
|  | ||||
|  | ||||
| parser = argparse.ArgumentParser(description='Check code style.') | ||||
| 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.Popen(["git", "commit", "--all", "--amend", "-C", "HEAD"], stdout=subprocess.DEVNULL) | ||||
|     os._exit(0) | ||||
| elif dry_run is True and changed is True: | ||||
|     print ("\nIssue the following command in your local tree to apply the suggested changes (needs uncrustify installed):\n\n $ git rebase origin/main --exec \"./check-style.py -r\" \n") | ||||
|     os._exit(-1) | ||||
|  | ||||
| os._exit(0) | ||||
| @@ -28,7 +28,7 @@ | ||||
| #include "cally-actor.h" | ||||
|  | ||||
| /* | ||||
|  * Auxiliary define, in order to get the clutter actor from the AtkObject using | ||||
|  * Auxiliar define, in order to get the clutter actor from the AtkObject using | ||||
|  * AtkGObject methods | ||||
|  * | ||||
|  */ | ||||
|   | ||||
| @@ -72,7 +72,9 @@ | ||||
| #include <glib.h> | ||||
| #include <clutter/clutter.h> | ||||
|  | ||||
| #include "clutter/clutter-actor-private.h" | ||||
| #ifdef CLUTTER_WINDOWING_X11 | ||||
| #include <clutter/x11/clutter-x11.h> | ||||
| #endif | ||||
|  | ||||
| #include <math.h> | ||||
|  | ||||
| @@ -765,11 +767,10 @@ static gboolean | ||||
| cally_actor_action_do_action (AtkAction *action, | ||||
|                              gint       index) | ||||
| { | ||||
|   CallyActor *cally_actor = NULL; | ||||
|   AtkStateSet *set = NULL; | ||||
|   CallyActorPrivate *priv = NULL; | ||||
|   CallyActorActionInfo *info = NULL; | ||||
|   gboolean did_action = FALSE; | ||||
|   CallyActor           *cally_actor = NULL; | ||||
|   AtkStateSet          *set         = NULL; | ||||
|   CallyActorPrivate    *priv        = NULL; | ||||
|   CallyActorActionInfo *info        = NULL; | ||||
|  | ||||
|   cally_actor = CALLY_ACTOR (action); | ||||
|   priv = cally_actor->priv; | ||||
| @@ -777,19 +778,21 @@ cally_actor_action_do_action (AtkAction *action, | ||||
|   set = atk_object_ref_state_set (ATK_OBJECT (cally_actor)); | ||||
|  | ||||
|   if (atk_state_set_contains_state (set, ATK_STATE_DEFUNCT)) | ||||
|     goto out; | ||||
|     return FALSE; | ||||
|  | ||||
|   if (!atk_state_set_contains_state (set, ATK_STATE_SENSITIVE) || | ||||
|       !atk_state_set_contains_state (set, ATK_STATE_SHOWING)) | ||||
|     goto out; | ||||
|     return FALSE; | ||||
|  | ||||
|   g_object_unref (set); | ||||
|  | ||||
|   info = _cally_actor_get_action_info (cally_actor, index); | ||||
|  | ||||
|   if (info == NULL) | ||||
|     goto out; | ||||
|     return FALSE; | ||||
|  | ||||
|   if (info->do_action_func == NULL) | ||||
|     goto out; | ||||
|     return FALSE; | ||||
|  | ||||
|   if (!priv->action_queue) | ||||
|     priv->action_queue = g_queue_new (); | ||||
| @@ -799,12 +802,7 @@ cally_actor_action_do_action (AtkAction *action, | ||||
|   if (!priv->action_idle_handler) | ||||
|     priv->action_idle_handler = g_idle_add (idle_do_action, cally_actor); | ||||
|  | ||||
|   did_action = TRUE; | ||||
|  | ||||
| out: | ||||
|   g_clear_object (&set); | ||||
|  | ||||
|   return did_action; | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| @@ -970,7 +968,7 @@ cally_actor_real_notify_clutter (GObject    *obj, | ||||
|        * paint it; we don't want this to generate an ATK | ||||
|        * state change | ||||
|        */ | ||||
|       if (clutter_actor_is_painting_unmapped (actor)) | ||||
|       if (clutter_actor_is_in_clone_paint (actor)) | ||||
|         return; | ||||
|  | ||||
|       state = ATK_STATE_SHOWING; | ||||
| @@ -1086,7 +1084,7 @@ cally_actor_add_action_full (CallyActor          *cally_actor, | ||||
|  | ||||
|   priv = cally_actor->priv; | ||||
|  | ||||
|   info = g_new0 (CallyActorActionInfo, 1); | ||||
|   info = g_slice_new (CallyActorActionInfo); | ||||
|   info->name = g_strdup (action_name); | ||||
|   info->description = g_strdup (action_description); | ||||
|   info->keybinding = g_strdup (action_keybinding); | ||||
| @@ -1106,7 +1104,7 @@ cally_actor_add_action_full (CallyActor          *cally_actor, | ||||
|  * | ||||
|  * Removes a action, using the @action_id returned by cally_actor_add_action() | ||||
|  * | ||||
|  * Return value: %TRUE if the operation was successful, %FALSE otherwise | ||||
|  * Return value: %TRUE if the operation was succesful, %FALSE otherwise | ||||
|  * | ||||
|  * Since: 1.4 | ||||
|  */ | ||||
| @@ -1140,7 +1138,7 @@ cally_actor_remove_action (CallyActor *cally_actor, | ||||
|  * Removes an action, using the @action_name used when the action was added | ||||
|  * with cally_actor_add_action() | ||||
|  * | ||||
|  * Return value: %TRUE if the operation was successful, %FALSE otherwise | ||||
|  * Return value: %TRUE if the operation was succesful, %FALSE otherwise | ||||
|  * | ||||
|  * Since: 1.4 | ||||
|  */ | ||||
| @@ -1191,5 +1189,5 @@ _cally_actor_destroy_action_info (gpointer action_info, | ||||
|   if (info->notify) | ||||
|     info->notify (info->user_data); | ||||
|  | ||||
|   g_free (info); | ||||
|   g_slice_free (CallyActorActionInfo, info); | ||||
| } | ||||
|   | ||||
							
								
								
									
										147
									
								
								clutter/clutter/cally/cally-group.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								clutter/clutter/cally/cally-group.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,147 @@ | ||||
| /* CALLY - The Clutter Accessibility Implementation Library | ||||
|  * | ||||
|  * Copyright (C) 2008 Igalia, S.L. | ||||
|  * | ||||
|  * Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com> | ||||
|  * | ||||
|  * Based on GailContainer 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, write to the | ||||
|  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||||
|  * Boston, MA 02111-1307, USA. | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * SECTION:cally-group | ||||
|  * @Title: CallyGroup | ||||
|  * @short_description: Implementation of the ATK interfaces for a #ClutterGroup | ||||
|  * @see_also: #ClutterGroup | ||||
|  * | ||||
|  * #CallyGroup implements the required ATK interfaces of #ClutterGroup | ||||
|  * In particular it exposes each of the Clutter actors contained in the | ||||
|  * group. | ||||
|  */ | ||||
|  | ||||
| #include "clutter-build-config.h" | ||||
|  | ||||
| #include "cally-group.h" | ||||
| #include "cally-actor-private.h" | ||||
|  | ||||
| static gint       cally_group_get_n_children  (AtkObject *obj); | ||||
| static AtkObject* cally_group_ref_child       (AtkObject *obj, | ||||
|                                               gint       i); | ||||
| static void       cally_group_real_initialize (AtkObject *obj, | ||||
|                                               gpointer   data); | ||||
|  | ||||
| G_DEFINE_TYPE (CallyGroup, cally_group, CALLY_TYPE_ACTOR) | ||||
|  | ||||
| static void | ||||
| cally_group_class_init (CallyGroupClass *klass) | ||||
| { | ||||
| /*   GObjectClass   *gobject_class = G_OBJECT_CLASS (klass); */ | ||||
|   AtkObjectClass *class         = ATK_OBJECT_CLASS (klass); | ||||
|  | ||||
|   class->get_n_children = cally_group_get_n_children; | ||||
|   class->ref_child      = cally_group_ref_child; | ||||
|   class->initialize     = cally_group_real_initialize; | ||||
| } | ||||
|  | ||||
| static void | ||||
| cally_group_init (CallyGroup      *group) | ||||
| { | ||||
|   /* nothing to do yet */ | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * cally_group_new: | ||||
|  * @actor: a #ClutterGroup | ||||
|  * | ||||
|  * Creates a #CallyGroup for @actor | ||||
|  * | ||||
|  * Return value: the newly created #CallyGroup | ||||
|  * | ||||
|  * Since: 1.4 | ||||
|  */ | ||||
| AtkObject * | ||||
| cally_group_new (ClutterActor *actor) | ||||
| { | ||||
|   GObject   *object     = NULL; | ||||
|   AtkObject *accessible = NULL; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_GROUP (actor), NULL); | ||||
|  | ||||
|   object = g_object_new (CALLY_TYPE_GROUP, NULL); | ||||
|  | ||||
|   accessible = ATK_OBJECT (object); | ||||
|   atk_object_initialize (accessible, actor); | ||||
|  | ||||
|   return accessible; | ||||
| } | ||||
|  | ||||
| static gint | ||||
| cally_group_get_n_children (AtkObject *obj) | ||||
| { | ||||
|   ClutterActor *actor = NULL; | ||||
|   gint          count = 0; | ||||
|  | ||||
|   g_return_val_if_fail (CALLY_IS_GROUP (obj), count); | ||||
|  | ||||
|   actor = CALLY_GET_CLUTTER_ACTOR (obj); | ||||
|  | ||||
|   if (actor == NULL) /* defunct */ | ||||
|     return 0; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_GROUP(actor), count); | ||||
|  | ||||
|   count = clutter_actor_get_n_children (actor); | ||||
|  | ||||
|   return count; | ||||
| } | ||||
|  | ||||
| static AtkObject* | ||||
| cally_group_ref_child (AtkObject *obj, | ||||
|                        gint       i) | ||||
| { | ||||
|   AtkObject    *accessible = NULL; | ||||
|   ClutterActor *actor      = NULL; | ||||
|   ClutterActor *child      = NULL; | ||||
|  | ||||
|   g_return_val_if_fail (CALLY_IS_GROUP (obj), NULL); | ||||
|   g_return_val_if_fail ((i >= 0), NULL); | ||||
|  | ||||
|   actor = CALLY_GET_CLUTTER_ACTOR (obj); | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_GROUP(actor), NULL); | ||||
|   child = clutter_actor_get_child_at_index (actor, i); | ||||
|  | ||||
|   if (!child) | ||||
|     return NULL; | ||||
|  | ||||
|   accessible = clutter_actor_get_accessible (child); | ||||
|  | ||||
|   if (accessible != NULL) | ||||
|     g_object_ref (accessible); | ||||
|  | ||||
|   return accessible; | ||||
| } | ||||
|  | ||||
| static void | ||||
| cally_group_real_initialize (AtkObject *obj, | ||||
|                             gpointer   data) | ||||
| { | ||||
|   ATK_OBJECT_CLASS (cally_group_parent_class)->initialize (obj, data); | ||||
|  | ||||
|   obj->role = ATK_ROLE_PANEL; | ||||
| } | ||||
							
								
								
									
										87
									
								
								clutter/clutter/cally/cally-group.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								clutter/clutter/cally/cally-group.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,87 @@ | ||||
| /* CALLY - The Clutter Accessibility Implementation Library | ||||
|  * | ||||
|  * Copyright (C) 2008 Igalia, S.L. | ||||
|  * | ||||
|  * Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com> | ||||
|  * | ||||
|  * Based on GailContainer 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/>. | ||||
|  */ | ||||
|  | ||||
| #ifndef __CALLY_GROUP_H__ | ||||
| #define __CALLY_GROUP_H__ | ||||
|  | ||||
| #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_GROUP                         (cally_group_get_type ()) | ||||
| #define CALLY_GROUP(obj)                         (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_GROUP, CallyGroup)) | ||||
| #define CALLY_GROUP_CLASS(klass)                 (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_GROUP, CallyGroupClass)) | ||||
| #define CALLY_IS_GROUP(obj)                      (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_GROUP)) | ||||
| #define CALLY_IS_GROUP_CLASS(klass)              (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_GROUP)) | ||||
| #define CALLY_GROUP_GET_CLASS(obj)               (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_GROUP, CallyGroupClass)) | ||||
|  | ||||
| typedef struct _CallyGroup        CallyGroup; | ||||
| typedef struct _CallyGroupClass   CallyGroupClass; | ||||
| typedef struct _CallyGroupPrivate CallyGroupPrivate; | ||||
|  | ||||
| /** | ||||
|  * CallyGroup: | ||||
|  * | ||||
|  * The <structname>CallyGroup</structname> structure contains only | ||||
|  * private data and should be accessed using the provided API | ||||
|  * | ||||
|  * Since: 1.4 | ||||
|  */ | ||||
| struct _CallyGroup | ||||
| { | ||||
|   /*< private >*/ | ||||
|   CallyActor parent; | ||||
|  | ||||
|   CallyGroupPrivate *priv; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * CallyGroupClass: | ||||
|  * | ||||
|  * The <structname>CallyGroupClass</structname> structure contains only | ||||
|  * private data | ||||
|  * | ||||
|  * Since: 1.4 | ||||
|  */ | ||||
| struct _CallyGroupClass | ||||
| { | ||||
|   /*< private >*/ | ||||
|   CallyActorClass parent_class; | ||||
|  | ||||
|   /* padding for future expansion */ | ||||
|   gpointer _padding_dummy[8]; | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| GType      cally_group_get_type (void) G_GNUC_CONST; | ||||
| CLUTTER_EXPORT | ||||
| AtkObject* cally_group_new      (ClutterActor *actor); | ||||
|  | ||||
| G_END_DECLS | ||||
|  | ||||
| #endif /* __CALLY_GROUP_H__ */ | ||||
							
								
								
									
										98
									
								
								clutter/clutter/cally/cally-rectangle.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								clutter/clutter/cally/cally-rectangle.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,98 @@ | ||||
| /* 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, write to the | ||||
|  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||||
|  * Boston, MA 02111-1307, USA. | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * SECTION:cally-rectangle | ||||
|  * @short_description: Implementation of the ATK interfaces for a #ClutterRectangle | ||||
|  * @see_also: #ClutterRectangle | ||||
|  * | ||||
|  * #CallyRectangle implements the required ATK interfaces of #ClutterRectangle | ||||
|  * | ||||
|  * In particular it sets a proper role for the rectangle. | ||||
|  */ | ||||
|  | ||||
| #include "clutter-build-config.h" | ||||
|  | ||||
| #define CLUTTER_DISABLE_DEPRECATION_WARNINGS | ||||
|  | ||||
| #include "cally-rectangle.h" | ||||
| #include "cally-actor-private.h" | ||||
|  | ||||
| #include "clutter-color.h" | ||||
| #include "deprecated/clutter-rectangle.h" | ||||
|  | ||||
| /* AtkObject */ | ||||
| static void                  cally_rectangle_real_initialize (AtkObject *obj, | ||||
|                                                               gpointer   data); | ||||
|  | ||||
| G_DEFINE_TYPE (CallyRectangle, cally_rectangle, CALLY_TYPE_ACTOR) | ||||
|  | ||||
| static void | ||||
| cally_rectangle_class_init (CallyRectangleClass *klass) | ||||
| { | ||||
| /*   GObjectClass   *gobject_class = G_OBJECT_CLASS (klass); */ | ||||
|   AtkObjectClass *class         = ATK_OBJECT_CLASS (klass); | ||||
|  | ||||
|   class->initialize      = cally_rectangle_real_initialize; | ||||
| } | ||||
|  | ||||
| static void | ||||
| cally_rectangle_init (CallyRectangle *rectangle) | ||||
| { | ||||
|   /* nothing to do yet */ | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * cally_rectangle_new: | ||||
|  * @actor: a #ClutterActor | ||||
|  * | ||||
|  * Creates a new #CallyRectangle for the given @actor. @actor must be | ||||
|  * a #ClutterRectangle. | ||||
|  * | ||||
|  * Return value: the newly created #AtkObject | ||||
|  * | ||||
|  * Since: 1.4 | ||||
|  */ | ||||
| AtkObject* | ||||
| cally_rectangle_new (ClutterActor *actor) | ||||
| { | ||||
|   GObject   *object     = NULL; | ||||
|   AtkObject *accessible = NULL; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_RECTANGLE (actor), NULL); | ||||
|  | ||||
|   object = g_object_new (CALLY_TYPE_RECTANGLE, NULL); | ||||
|  | ||||
|   accessible = ATK_OBJECT (object); | ||||
|   atk_object_initialize (accessible, actor); | ||||
|  | ||||
|   return accessible; | ||||
| } | ||||
|  | ||||
| static void | ||||
| cally_rectangle_real_initialize (AtkObject *obj, | ||||
|                                  gpointer   data) | ||||
| { | ||||
|   ATK_OBJECT_CLASS (cally_rectangle_parent_class)->initialize (obj, data); | ||||
|  | ||||
|   obj->role = ATK_ROLE_IMAGE; | ||||
| } | ||||
							
								
								
									
										84
									
								
								clutter/clutter/cally/cally-rectangle.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								clutter/clutter/cally/cally-rectangle.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | ||||
| /* 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/>. | ||||
|  */ | ||||
|  | ||||
| #ifndef __CALLY_RECTANGLE_H__ | ||||
| #define __CALLY_RECTANGLE_H__ | ||||
|  | ||||
| #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_RECTANGLE            (cally_rectangle_get_type ()) | ||||
| #define CALLY_RECTANGLE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_RECTANGLE, CallyRectangle)) | ||||
| #define CALLY_RECTANGLE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_RECTANGLE, CallyRectangleClass)) | ||||
| #define CALLY_IS_RECTANGLE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_RECTANGLE)) | ||||
| #define CALLY_IS_RECTANGLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_RECTANGLE)) | ||||
| #define CALLY_RECTANGLE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_RECTANGLE, CallyRectangleClass)) | ||||
|  | ||||
| typedef struct _CallyRectangle         CallyRectangle; | ||||
| typedef struct _CallyRectangleClass    CallyRectangleClass; | ||||
| typedef struct _CallyRectanglePrivate  CallyRectanglePrivate; | ||||
|  | ||||
| /** | ||||
|  * CallyRectangle: | ||||
|  * | ||||
|  * The <structname>CallyRectangle</structname> structure contains only private | ||||
|  * data and should be accessed using the provided API | ||||
|  * | ||||
|  * Since: 1.4 | ||||
|  */ | ||||
| struct _CallyRectangle | ||||
| { | ||||
|   /*< private >*/ | ||||
|   CallyActor parent; | ||||
|  | ||||
|   CallyRectanglePrivate *priv; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * CallyRectangleClass: | ||||
|  * | ||||
|  * The <structname>CallyRectangleClass</structname> structure contains | ||||
|  * only private data | ||||
|  * | ||||
|  * Since: 1.4 | ||||
|  */ | ||||
| struct _CallyRectangleClass | ||||
| { | ||||
|   /*< private >*/ | ||||
|   CallyActorClass parent_class; | ||||
|  | ||||
|   /* padding for future expansion */ | ||||
|   gpointer _padding_dummy[8]; | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| GType      cally_rectangle_get_type (void) G_GNUC_CONST; | ||||
| CLUTTER_EXPORT | ||||
| AtkObject* cally_rectangle_new      (ClutterActor *actor); | ||||
|  | ||||
| G_END_DECLS | ||||
|  | ||||
| #endif /* __CALLY_RECTANGLE_H__ */ | ||||
| @@ -47,7 +47,7 @@ static AtkStateSet*          cally_stage_ref_state_set   (AtkObject *obj); | ||||
| /* AtkWindow */ | ||||
| static void                  cally_stage_window_interface_init (AtkWindowIface *iface); | ||||
|  | ||||
| /* Auxiliary */ | ||||
| /* Auxiliar */ | ||||
| static void                  cally_stage_activate_cb     (ClutterStage *stage, | ||||
|                                                           gpointer      data); | ||||
| static void                  cally_stage_deactivate_cb   (ClutterStage *stage, | ||||
| @@ -63,7 +63,7 @@ struct _CallyStagePrivate | ||||
|  | ||||
| G_DEFINE_TYPE_WITH_CODE (CallyStage, | ||||
|                          cally_stage, | ||||
|                          CALLY_TYPE_ACTOR, | ||||
|                          CALLY_TYPE_GROUP, | ||||
|                          G_ADD_PRIVATE (CallyStage) | ||||
|                          G_IMPLEMENT_INTERFACE (ATK_TYPE_WINDOW, | ||||
|                                                 cally_stage_window_interface_init)); | ||||
| @@ -134,11 +134,8 @@ cally_stage_notify_key_focus_cb (ClutterStage *stage, | ||||
|  | ||||
|       if (self->priv->key_focus != NULL) | ||||
|         { | ||||
|           if (self->priv->key_focus != CLUTTER_ACTOR (stage)) | ||||
|             { | ||||
|               g_object_remove_weak_pointer (G_OBJECT (self->priv->key_focus), | ||||
|                                             (gpointer *) &self->priv->key_focus); | ||||
|             } | ||||
|           g_object_remove_weak_pointer (G_OBJECT (self->priv->key_focus), | ||||
|                                         (gpointer *) &self->priv->key_focus); | ||||
|           old = clutter_actor_get_accessible (self->priv->key_focus); | ||||
|         } | ||||
|       else | ||||
| @@ -163,11 +160,8 @@ cally_stage_notify_key_focus_cb (ClutterStage *stage, | ||||
|        * | ||||
|        * we remove the weak pointer above. | ||||
|        */ | ||||
|       if (key_focus != CLUTTER_ACTOR (stage)) | ||||
|         { | ||||
|           g_object_add_weak_pointer (G_OBJECT (self->priv->key_focus), | ||||
|                                      (gpointer *) &self->priv->key_focus); | ||||
|         } | ||||
|       g_object_add_weak_pointer (G_OBJECT (self->priv->key_focus), | ||||
|                                  (gpointer *) &self->priv->key_focus); | ||||
|  | ||||
|       new = clutter_actor_get_accessible (key_focus); | ||||
|     } | ||||
| @@ -228,7 +222,7 @@ cally_stage_window_interface_init (AtkWindowIface *iface) | ||||
|   /* At this moment AtkWindow is just about signals */ | ||||
| } | ||||
|  | ||||
| /* Auxiliary */ | ||||
| /* Auxiliar */ | ||||
| static void | ||||
| cally_stage_activate_cb     (ClutterStage *stage, | ||||
|                              gpointer      data) | ||||
|   | ||||
| @@ -25,7 +25,7 @@ | ||||
| #error "Only <cally/cally.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include <cally/cally-actor.h> | ||||
| #include <cally/cally-group.h> | ||||
| #include <clutter/clutter.h> | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
| @@ -52,7 +52,7 @@ typedef struct _CallyStagePrivate CallyStagePrivate; | ||||
| struct _CallyStage | ||||
| { | ||||
|   /*< private >*/ | ||||
|   CallyActor parent; | ||||
|   CallyGroup parent; | ||||
|  | ||||
|   CallyStagePrivate *priv; | ||||
| }; | ||||
| @@ -68,7 +68,7 @@ struct _CallyStage | ||||
| struct _CallyStageClass | ||||
| { | ||||
|   /*< private >*/ | ||||
|   CallyActorClass parent_class; | ||||
|   CallyGroupClass parent_class; | ||||
|  | ||||
|   /* padding for future expansion */ | ||||
|   gpointer _padding_dummy[16]; | ||||
|   | ||||
| @@ -1513,7 +1513,7 @@ cally_text_get_offset_at_point (AtkText *text, | ||||
| } | ||||
|  | ||||
|  | ||||
| /******** Auxiliary private methods ******/ | ||||
| /******** Auxiliar private methods ******/ | ||||
|  | ||||
| /* ClutterText only maintains the current cursor position and a extra selection | ||||
|    bound, but this could be before or after the cursor. This method returns | ||||
| @@ -1552,7 +1552,7 @@ _cally_text_delete_text_cb (ClutterText *clutter_text, | ||||
|  | ||||
|   g_return_if_fail (CALLY_IS_TEXT (data)); | ||||
|  | ||||
|   /* Ignore zero length deletions */ | ||||
|   /* Ignore zero lengh deletions */ | ||||
|   if (end_pos - start_pos == 0) | ||||
|     return; | ||||
|  | ||||
| @@ -1653,7 +1653,7 @@ cally_text_insert_text (AtkEditableText *text, | ||||
|   clutter_text_insert_text (CLUTTER_TEXT (actor), | ||||
|                             string, *position); | ||||
|  | ||||
|   /* we suppose that the text insertion will be successful, | ||||
|   /* we suppose that the text insertion will be succesful, | ||||
|      clutter-text doesn't warn about it. A option would be search for | ||||
|      the text, but it seems not really required */ | ||||
|   *position += length; | ||||
| @@ -1866,7 +1866,7 @@ static gint | ||||
| _cally_atk_attribute_lookup_func (gconstpointer data, | ||||
|                                   gconstpointer user_data) | ||||
| { | ||||
|     AtkTextAttribute attr = (AtkTextAttribute) GPOINTER_TO_INT (user_data); | ||||
|     AtkTextAttribute attr = (AtkTextAttribute) user_data; | ||||
|     AtkAttribute *at = (AtkAttribute *) data; | ||||
|     if (!g_strcmp0 (at->name, atk_text_attribute_get_name (attr))) | ||||
|         return 0; | ||||
|   | ||||
| @@ -36,8 +36,10 @@ | ||||
| #include "cally.h" | ||||
|  | ||||
| #include "cally-actor.h" | ||||
| #include "cally-group.h" | ||||
| #include "cally-stage.h" | ||||
| #include "cally-text.h" | ||||
| #include "cally-rectangle.h" | ||||
| #include "cally-clone.h" | ||||
|  | ||||
| #include "cally-factory.h" | ||||
| @@ -50,8 +52,10 @@ | ||||
|  | ||||
| /* factories initialization*/ | ||||
| CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_ACTOR, cally_actor, cally_actor_new) | ||||
| CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_GROUP, cally_group, cally_group_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_RECTANGLE, cally_rectangle, cally_rectangle_new) | ||||
| CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_CLONE, cally_clone, cally_clone_new) | ||||
|  | ||||
| /** | ||||
| @@ -69,8 +73,10 @@ cally_accessibility_init (void) | ||||
| { | ||||
|   /* setting the factories */ | ||||
|   CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_ACTOR, cally_actor); | ||||
|   CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_GROUP, cally_group); | ||||
|   CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_STAGE, cally_stage); | ||||
|   CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_TEXT, cally_text); | ||||
|   CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_RECTANGLE, cally_rectangle); | ||||
|   CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_CLONE, cally_clone); | ||||
|  | ||||
|   /* Initialize the CallyUtility class */ | ||||
|   | ||||
| @@ -26,7 +26,9 @@ | ||||
| #include "cally-actor.h" | ||||
| #include "cally-clone.h" | ||||
| #include "cally-factory.h" | ||||
| #include "cally-group.h" | ||||
| #include "cally-main.h" | ||||
| #include "cally-rectangle.h" | ||||
| #include "cally-root.h" | ||||
| #include "cally-stage.h" | ||||
| #include "cally-text.h" | ||||
|   | ||||
| @@ -44,63 +44,18 @@ | ||||
| #include "clutter-build-config.h" | ||||
|  | ||||
| #include "clutter-action.h" | ||||
| #include "clutter-action-private.h" | ||||
|  | ||||
| #include "clutter-debug.h" | ||||
| #include "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; | ||||
| } | ||||
| G_DEFINE_ABSTRACT_TYPE (ClutterAction, clutter_action, CLUTTER_TYPE_ACTOR_META); | ||||
|  | ||||
| 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) | ||||
| { | ||||
|   return CLUTTER_ACTION_GET_CLASS (action)->handle_event (action, event); | ||||
| } | ||||
|   | ||||
| @@ -33,11 +33,28 @@ | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CLUTTER_TYPE_ACTION (clutter_action_get_type ()) | ||||
| #define CLUTTER_TYPE_ACTION             (clutter_action_get_type ()) | ||||
| #define CLUTTER_ACTION(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ACTION, ClutterAction)) | ||||
| #define CLUTTER_IS_ACTION(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ACTION)) | ||||
| #define CLUTTER_ACTION_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ACTION, ClutterActionClass)) | ||||
| #define CLUTTER_IS_ACTION_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ACTION)) | ||||
| #define CLUTTER_ACTION_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ACTION, ClutterActionClass)) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_DERIVABLE_TYPE (ClutterAction, clutter_action, | ||||
|                           CLUTTER, ACTION, ClutterActorMeta); | ||||
| typedef struct _ClutterActionClass      ClutterActionClass; | ||||
|  | ||||
| /** | ||||
|  * ClutterAction: | ||||
|  * | ||||
|  * The #ClutterAction structure contains only private data and | ||||
|  * should be accessed using the provided API. | ||||
|  * | ||||
|  * Since: 1.4 | ||||
|  */ | ||||
| struct _ClutterAction | ||||
| { | ||||
|   /*< private >*/ | ||||
|   ClutterActorMeta parent_instance; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * ClutterActionClass: | ||||
| @@ -51,9 +68,6 @@ struct _ClutterActionClass | ||||
|   /*< private >*/ | ||||
|   ClutterActorMetaClass parent_class; | ||||
|  | ||||
|   gboolean (* handle_event) (ClutterAction      *action, | ||||
|                              const ClutterEvent *event); | ||||
|  | ||||
|   void (* _clutter_action1) (void); | ||||
|   void (* _clutter_action2) (void); | ||||
|   void (* _clutter_action3) (void); | ||||
| @@ -64,6 +78,9 @@ struct _ClutterActionClass | ||||
|   void (* _clutter_action8) (void); | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| GType clutter_action_get_type (void) G_GNUC_CONST; | ||||
|  | ||||
| /* ClutterActor API */ | ||||
| CLUTTER_EXPORT | ||||
| void           clutter_actor_add_action            (ClutterActor  *self, | ||||
| @@ -73,11 +90,6 @@ 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 | ||||
| @@ -94,8 +106,6 @@ 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 | ||||
|  | ||||
| #endif /* __CLUTTER_ACTION_H__ */ | ||||
|   | ||||
| @@ -54,7 +54,7 @@ clutter_actor_box_new (gfloat x_1, | ||||
| ClutterActorBox * | ||||
| clutter_actor_box_alloc (void) | ||||
| { | ||||
|   return g_new0 (ClutterActorBox, 1); | ||||
|   return g_slice_new0 (ClutterActorBox); | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -130,7 +130,7 @@ ClutterActorBox * | ||||
| clutter_actor_box_copy (const ClutterActorBox *box) | ||||
| { | ||||
|   if (G_LIKELY (box != NULL)) | ||||
|     return g_memdup2 (box, sizeof (ClutterActorBox)); | ||||
|     return g_slice_dup (ClutterActorBox, box); | ||||
|  | ||||
|   return NULL; | ||||
| } | ||||
| @@ -148,7 +148,7 @@ void | ||||
| clutter_actor_box_free (ClutterActorBox *box) | ||||
| { | ||||
|   if (G_LIKELY (box != NULL)) | ||||
|     g_free (box); | ||||
|     g_slice_free (ClutterActorBox, box); | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -320,7 +320,7 @@ clutter_actor_box_get_area (const ClutterActorBox *box) | ||||
|  * @y: Y coordinate of the point | ||||
|  * | ||||
|  * Checks whether a point with @x, @y coordinates is contained | ||||
|  * within @box | ||||
|  * withing @box | ||||
|  * | ||||
|  * Return value: %TRUE if the point is contained by the #ClutterActorBox | ||||
|  * | ||||
| @@ -554,7 +554,7 @@ _clutter_actor_box_enlarge_for_effects (ClutterActorBox *box) | ||||
|    * | ||||
|    * 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 | ||||
|    * a fixed-size object that may be animated accross 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. | ||||
| @@ -583,7 +583,7 @@ _clutter_actor_box_enlarge_for_effects (ClutterActorBox *box) | ||||
|  | ||||
|   /* 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 | ||||
|    * size of the box will be stable and not dependant on the box's | ||||
|    * position. | ||||
|    * | ||||
|    * Adding 3px to the width/height will ensure we cover the maximum of | ||||
| @@ -615,32 +615,6 @@ clutter_actor_box_scale (ClutterActorBox *box, | ||||
|   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, | ||||
|   | ||||
| @@ -81,49 +81,24 @@ static void | ||||
| on_actor_destroy (ClutterActor     *actor, | ||||
|                   ClutterActorMeta *meta) | ||||
| { | ||||
|   ClutterActorMetaPrivate *priv = | ||||
|     clutter_actor_meta_get_instance_private (meta); | ||||
|  | ||||
|   priv->actor = NULL; | ||||
|   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) | ||||
|   if (meta->priv->actor == actor) | ||||
|     return; | ||||
|  | ||||
|   g_clear_signal_handler (&priv->destroy_id, priv->actor); | ||||
|   g_clear_signal_handler (&meta->priv->destroy_id, meta->priv->actor); | ||||
|  | ||||
|   priv->actor = actor; | ||||
|   meta->priv->actor = actor; | ||||
|  | ||||
|   if (priv->actor != NULL) | ||||
|     priv->destroy_id = g_signal_connect (priv->actor, "destroy", | ||||
|                                          G_CALLBACK (on_actor_destroy), | ||||
|                                          meta); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_actor_meta_real_set_enabled (ClutterActorMeta *meta, | ||||
|                                      gboolean          is_enabled) | ||||
| { | ||||
|   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]); | ||||
|   if (meta->priv->actor != NULL) | ||||
|     meta->priv->destroy_id = g_signal_connect (meta->priv->actor, "destroy", | ||||
|                                                G_CALLBACK (on_actor_destroy), | ||||
|                                                meta); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -156,21 +131,20 @@ clutter_actor_meta_get_property (GObject    *gobject, | ||||
|                                  GValue     *value, | ||||
|                                  GParamSpec *pspec) | ||||
| { | ||||
|   ClutterActorMetaPrivate *priv = | ||||
|     clutter_actor_meta_get_instance_private (CLUTTER_ACTOR_META (gobject)); | ||||
|   ClutterActorMeta *meta = CLUTTER_ACTOR_META (gobject); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_ACTOR: | ||||
|       g_value_set_object (value, priv->actor); | ||||
|       g_value_set_object (value, meta->priv->actor); | ||||
|       break; | ||||
|  | ||||
|     case PROP_NAME: | ||||
|       g_value_set_string (value, priv->name); | ||||
|       g_value_set_string (value, meta->priv->name); | ||||
|       break; | ||||
|  | ||||
|     case PROP_ENABLED: | ||||
|       g_value_set_boolean (value, priv->is_enabled); | ||||
|       g_value_set_boolean (value, meta->priv->is_enabled); | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
| @@ -182,8 +156,7 @@ clutter_actor_meta_get_property (GObject    *gobject, | ||||
| static void | ||||
| clutter_actor_meta_finalize (GObject *gobject) | ||||
| { | ||||
|   ClutterActorMetaPrivate *priv = | ||||
|     clutter_actor_meta_get_instance_private (CLUTTER_ACTOR_META (gobject)); | ||||
|   ClutterActorMetaPrivate *priv = CLUTTER_ACTOR_META (gobject)->priv; | ||||
|  | ||||
|   if (priv->actor != NULL) | ||||
|     g_clear_signal_handler (&priv->destroy_id, priv->actor); | ||||
| @@ -199,7 +172,6 @@ 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: | ||||
| @@ -254,11 +226,9 @@ clutter_actor_meta_class_init (ClutterActorMetaClass *klass) | ||||
| 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; | ||||
|   self->priv = clutter_actor_meta_get_instance_private (self); | ||||
|   self->priv->is_enabled = TRUE; | ||||
|   self->priv->priority = CLUTTER_ACTOR_META_PRIORITY_DEFAULT; | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -276,17 +246,13 @@ 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) | ||||
|   if (g_strcmp0 (meta->priv->name, name) == 0) | ||||
|     return; | ||||
|  | ||||
|   g_free (priv->name); | ||||
|   priv->name = g_strdup (name); | ||||
|   g_free (meta->priv->name); | ||||
|   meta->priv->name = g_strdup (name); | ||||
|  | ||||
|   g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_NAME]); | ||||
| } | ||||
| @@ -307,13 +273,9 @@ clutter_actor_meta_set_name (ClutterActorMeta *meta, | ||||
| const gchar * | ||||
| clutter_actor_meta_get_name (ClutterActorMeta *meta) | ||||
| { | ||||
|   ClutterActorMetaPrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), NULL); | ||||
|  | ||||
|   priv = clutter_actor_meta_get_instance_private (meta); | ||||
|  | ||||
|   return priv->name; | ||||
|   return meta->priv->name; | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -329,17 +291,16 @@ 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) | ||||
|   if (meta->priv->is_enabled == is_enabled) | ||||
|     return; | ||||
|  | ||||
|   CLUTTER_ACTOR_META_GET_CLASS (meta)->set_enabled (meta, is_enabled); | ||||
|   meta->priv->is_enabled = is_enabled; | ||||
|  | ||||
|   g_object_notify_by_pspec (G_OBJECT (meta), obj_props[PROP_ENABLED]); | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -355,13 +316,9 @@ clutter_actor_meta_set_enabled (ClutterActorMeta *meta, | ||||
| gboolean | ||||
| clutter_actor_meta_get_enabled (ClutterActorMeta *meta) | ||||
| { | ||||
|   ClutterActorMetaPrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), FALSE); | ||||
|  | ||||
|   priv = clutter_actor_meta_get_instance_private (meta); | ||||
|  | ||||
|   return priv->is_enabled; | ||||
|   return meta->priv->is_enabled; | ||||
| } | ||||
|  | ||||
| /* | ||||
| @@ -397,54 +354,40 @@ _clutter_actor_meta_set_actor (ClutterActorMeta *meta, | ||||
| ClutterActor * | ||||
| clutter_actor_meta_get_actor (ClutterActorMeta *meta) | ||||
| { | ||||
|   ClutterActorMetaPrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_ACTOR_META (meta), NULL); | ||||
|  | ||||
|   priv = clutter_actor_meta_get_instance_private (meta); | ||||
|  | ||||
|   return priv->actor; | ||||
|   return meta->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); | ||||
|   g_return_if_fail (meta->priv->actor == NULL); | ||||
|  | ||||
|   priv->priority = priority; | ||||
|   meta->priv->priority = priority; | ||||
| } | ||||
|  | ||||
| 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; | ||||
|   return meta->priv->priority; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| _clutter_actor_meta_is_internal (ClutterActorMeta *meta) | ||||
| { | ||||
|   ClutterActorMetaPrivate *priv = | ||||
|     clutter_actor_meta_get_instance_private (meta); | ||||
|   gint priority = priv->priority; | ||||
|   gint priority = meta->priv->priority; | ||||
|  | ||||
|   return (priority <= CLUTTER_ACTOR_META_PRIORITY_INTERNAL_LOW || | ||||
|           priority >= CLUTTER_ACTOR_META_PRIORITY_INTERNAL_HIGH); | ||||
| @@ -491,21 +434,19 @@ 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) | ||||
|   if (meta->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 | ||||
|                  meta->priv->name != NULL | ||||
|                    ? meta->priv->name | ||||
|                    : "<unknown>", | ||||
|                  clutter_actor_get_name (priv->actor) != NULL | ||||
|                    ? clutter_actor_get_name (priv->actor) | ||||
|                    : G_OBJECT_TYPE_NAME (priv->actor)); | ||||
|                  clutter_actor_get_name (meta->priv->actor) != NULL | ||||
|                    ? clutter_actor_get_name (meta->priv->actor) | ||||
|                    : G_OBJECT_TYPE_NAME (meta->priv->actor)); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
| @@ -541,16 +482,13 @@ void | ||||
| _clutter_meta_group_remove_meta (ClutterMetaGroup *group, | ||||
|                                  ClutterActorMeta *meta) | ||||
| { | ||||
|   ClutterActorMetaPrivate *priv = | ||||
|     clutter_actor_meta_get_instance_private (meta); | ||||
|  | ||||
|   if (priv->actor != group->actor) | ||||
|   if (meta->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 | ||||
|                  meta->priv->name != NULL | ||||
|                    ? meta->priv->name | ||||
|                    : "<unknown>", | ||||
|                  clutter_actor_get_name (group->actor) != NULL | ||||
|                    ? clutter_actor_get_name (group->actor) | ||||
| @@ -693,10 +631,8 @@ _clutter_meta_group_get_meta (ClutterMetaGroup *group, | ||||
|   for (l = group->meta; l != NULL; l = l->next) | ||||
|     { | ||||
|       ClutterActorMeta *meta = l->data; | ||||
|       ClutterActorMetaPrivate *priv = | ||||
|         clutter_actor_meta_get_instance_private (meta); | ||||
|  | ||||
|       if (g_strcmp0 (priv->name, name) == 0) | ||||
|       if (g_strcmp0 (meta->priv->name, name) == 0) | ||||
|         return meta; | ||||
|     } | ||||
|  | ||||
| @@ -716,8 +652,6 @@ _clutter_meta_group_get_meta (ClutterMetaGroup *group, | ||||
| 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); | ||||
|   return meta->priv->name != NULL ? meta->priv->name | ||||
|                                   : G_OBJECT_TYPE_NAME (meta); | ||||
| } | ||||
|   | ||||
| @@ -33,13 +33,31 @@ | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CLUTTER_TYPE_ACTOR_META (clutter_actor_meta_get_type ()) | ||||
| #define CLUTTER_TYPE_ACTOR_META                 (clutter_actor_meta_get_type ()) | ||||
| #define CLUTTER_ACTOR_META(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ACTOR_META, ClutterActorMeta)) | ||||
| #define CLUTTER_IS_ACTOR_META(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_ACTOR_META)) | ||||
| #define CLUTTER_ACTOR_META_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_ACTOR_META, ClutterActorMetaClass)) | ||||
| #define CLUTTER_IS_ACTOR_META_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_ACTOR_META)) | ||||
| #define CLUTTER_ACTOR_META_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_ACTOR_META, ClutterActorMetaClass)) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_DERIVABLE_TYPE (ClutterActorMeta, clutter_actor_meta, | ||||
|                           CLUTTER, ACTOR_META, GInitiallyUnowned); | ||||
| typedef struct _ClutterActorMetaPrivate         ClutterActorMetaPrivate; | ||||
| typedef struct _ClutterActorMetaClass           ClutterActorMetaClass; | ||||
|  | ||||
| typedef struct _ClutterActorMetaPrivate ClutterActorMetaPrivate; | ||||
| /** | ||||
|  * ClutterActorMeta: | ||||
|  * | ||||
|  * The #ClutterActorMeta structure contains only | ||||
|  * private data and should be accessed using the provided API | ||||
|  * | ||||
|  * Since: 1.4 | ||||
|  */ | ||||
| struct _ClutterActorMeta | ||||
| { | ||||
|   /*< private >*/ | ||||
|   GInitiallyUnowned parent_instance; | ||||
|  | ||||
|   ClutterActorMetaPrivate *priv; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * ClutterActorMetaClass: | ||||
| @@ -69,9 +87,6 @@ struct _ClutterActorMetaClass | ||||
|   void (* set_actor) (ClutterActorMeta *meta, | ||||
|                       ClutterActor     *actor); | ||||
|  | ||||
|   void (* set_enabled) (ClutterActorMeta *meta, | ||||
|                         gboolean          is_enabled); | ||||
|  | ||||
|   /*< private >*/ | ||||
|   void (* _clutter_meta1) (void); | ||||
|   void (* _clutter_meta2) (void); | ||||
| @@ -79,8 +94,12 @@ struct _ClutterActorMetaClass | ||||
|   void (* _clutter_meta4) (void); | ||||
|   void (* _clutter_meta5) (void); | ||||
|   void (* _clutter_meta6) (void); | ||||
|   void (* _clutter_meta7) (void); | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| GType clutter_actor_meta_get_type (void) G_GNUC_CONST; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void            clutter_actor_meta_set_name     (ClutterActorMeta *meta, | ||||
|                                                  const gchar      *name); | ||||
|   | ||||
| @@ -26,6 +26,23 @@ | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| /*< private > | ||||
|  * ClutterRedrawFlags: | ||||
|  * @CLUTTER_REDRAW_CLIPPED_TO_ALLOCATION: Tells clutter the maximum | ||||
|  *   extents of what needs to be redrawn lies within the actors | ||||
|  *   current allocation. (Only use this for 2D actors though because | ||||
|  *   any actor with depth may be projected outside of its allocation) | ||||
|  * | ||||
|  * Flags passed to the clutter_actor_queue_redraw_with_clip () | ||||
|  * function | ||||
|  * | ||||
|  * Since: 1.6 | ||||
|  */ | ||||
| typedef enum | ||||
| { | ||||
|   CLUTTER_REDRAW_CLIPPED_TO_ALLOCATION  = 1 << 0 | ||||
| } ClutterRedrawFlags; | ||||
|  | ||||
| /*< private > | ||||
|  * ClutterActorTraverseFlags: | ||||
|  * CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST: Traverse the graph in | ||||
| @@ -93,12 +110,35 @@ typedef ClutterActorTraverseVisitFlags (*ClutterTraverseCallback) (ClutterActor | ||||
| typedef gboolean (*ClutterForeachCallback) (ClutterActor *actor, | ||||
|                                             gpointer      user_data); | ||||
|  | ||||
| typedef struct _AnchorCoord             AnchorCoord; | ||||
| typedef struct _SizeRequest             SizeRequest; | ||||
|  | ||||
| typedef struct _ClutterLayoutInfo       ClutterLayoutInfo; | ||||
| typedef struct _ClutterTransformInfo    ClutterTransformInfo; | ||||
| typedef struct _ClutterAnimationInfo    ClutterAnimationInfo; | ||||
|  | ||||
| /* Internal helper struct to represent a point that can be stored in | ||||
|    either direct pixel coordinates or as a fraction of the actor's | ||||
|    size. It is used for the anchor point, scale center and rotation | ||||
|    centers. */ | ||||
| struct _AnchorCoord | ||||
| { | ||||
|   gboolean is_fractional; | ||||
|  | ||||
|   union | ||||
|   { | ||||
|     /* Used when is_fractional == TRUE */ | ||||
|     struct | ||||
|     { | ||||
|       gdouble x; | ||||
|       gdouble y; | ||||
|     } fraction; | ||||
|  | ||||
|     /* Use when is_fractional == FALSE */ | ||||
|     graphene_point3d_t units; | ||||
|   } v; | ||||
| }; | ||||
|  | ||||
| struct _SizeRequest | ||||
| { | ||||
|   guint  age; | ||||
| @@ -143,15 +183,24 @@ ClutterLayoutInfo *             _clutter_actor_peek_layout_info | ||||
|  | ||||
| struct _ClutterTransformInfo | ||||
| { | ||||
|   /* rotation */ | ||||
|   /* rotation (angle and center) */ | ||||
|   gdouble rx_angle; | ||||
|   AnchorCoord rx_center; | ||||
|  | ||||
|   gdouble ry_angle; | ||||
|   AnchorCoord ry_center; | ||||
|  | ||||
|   gdouble rz_angle; | ||||
|   AnchorCoord rz_center; | ||||
|  | ||||
|   /* scaling */ | ||||
|   gdouble scale_x; | ||||
|   gdouble scale_y; | ||||
|   gdouble scale_z; | ||||
|   AnchorCoord scale_center; | ||||
|  | ||||
|   /* anchor point */ | ||||
|   AnchorCoord anchor; | ||||
|  | ||||
|   /* translation */ | ||||
|   graphene_point3d_t translation; | ||||
| @@ -163,10 +212,10 @@ struct _ClutterTransformInfo | ||||
|   graphene_point_t pivot; | ||||
|   gfloat pivot_z; | ||||
|  | ||||
|   graphene_matrix_t transform; | ||||
|   CoglMatrix transform; | ||||
|   guint transform_set : 1; | ||||
|  | ||||
|   graphene_matrix_t child_transform; | ||||
|   CoglMatrix child_transform; | ||||
|   guint child_transform_set : 1; | ||||
| }; | ||||
|  | ||||
| @@ -203,11 +252,11 @@ void                            _clutter_actor_traverse | ||||
|                                                                                          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_apply_modelview_transform                (ClutterActor *self, | ||||
|                                                                                          CoglMatrix   *matrix); | ||||
| void                            _clutter_actor_apply_relative_transformation_matrix     (ClutterActor *self, | ||||
|                                                                                          ClutterActor *ancestor, | ||||
|                                                                                          CoglMatrix   *matrix); | ||||
|  | ||||
| void                            _clutter_actor_rerealize                                (ClutterActor    *self, | ||||
|                                                                                          ClutterCallback  callback, | ||||
| @@ -228,21 +277,30 @@ void                            _clutter_actor_set_has_pointer | ||||
| void                            _clutter_actor_set_has_key_focus                        (ClutterActor *self, | ||||
|                                                                                          gboolean      has_key_focus); | ||||
|  | ||||
| void                            _clutter_actor_queue_redraw_with_clip                   (ClutterActor             *self, | ||||
|                                                                                          ClutterRedrawFlags        flags, | ||||
|                                                                                          const ClutterPaintVolume *clip_volume); | ||||
| void                            _clutter_actor_queue_redraw_full                        (ClutterActor             *self, | ||||
|                                                                                          ClutterRedrawFlags        flags, | ||||
|                                                                                          const ClutterPaintVolume *volume, | ||||
|                                                                                          ClutterEffect            *effect); | ||||
|  | ||||
| void                            _clutter_actor_finish_queue_redraw                      (ClutterActor *self); | ||||
| void                            _clutter_actor_finish_queue_redraw                      (ClutterActor       *self, | ||||
|                                                                                          ClutterPaintVolume *clip); | ||||
|  | ||||
| gboolean                        _clutter_actor_set_default_paint_volume                 (ClutterActor       *self, | ||||
|                                                                                          GType               check_gtype, | ||||
|                                                                                          ClutterPaintVolume *volume); | ||||
|  | ||||
| const char *                    _clutter_actor_get_debug_name                           (ClutterActor *self); | ||||
| const gchar *                   _clutter_actor_get_debug_name                           (ClutterActor *self); | ||||
|  | ||||
| void                            _clutter_actor_push_clone_paint                         (void); | ||||
| void                            _clutter_actor_pop_clone_paint                          (void); | ||||
|  | ||||
| void                            _clutter_actor_shader_pre_paint                         (ClutterActor *actor, | ||||
|                                                                                          gboolean      repeat); | ||||
| void                            _clutter_actor_shader_post_paint                        (ClutterActor *actor); | ||||
|  | ||||
| ClutterActorAlign               _clutter_actor_get_effective_x_align                    (ClutterActor *self); | ||||
|  | ||||
| void                            _clutter_actor_handle_event                             (ClutterActor       *actor, | ||||
| @@ -252,25 +310,17 @@ void                            _clutter_actor_attach_clone | ||||
|                                                                                          ClutterActor *clone); | ||||
| void                            _clutter_actor_detach_clone                             (ClutterActor *actor, | ||||
|                                                                                          ClutterActor *clone); | ||||
| void                            _clutter_actor_queue_redraw_on_clones                   (ClutterActor *actor); | ||||
| void                            _clutter_actor_queue_relayout_on_clones                 (ClutterActor *actor); | ||||
| void                            _clutter_actor_queue_only_relayout                      (ClutterActor *actor); | ||||
| void                            clutter_actor_clear_stage_views_recursive               (ClutterActor *actor); | ||||
| void                            _clutter_actor_queue_update_resource_scale_recursive    (ClutterActor *actor); | ||||
|  | ||||
| float                           clutter_actor_get_real_resource_scale                   (ClutterActor *actor); | ||||
| gboolean                        _clutter_actor_get_real_resource_scale                  (ClutterActor *actor, | ||||
|                                                                                          float        *resource_scale); | ||||
|  | ||||
| ClutterPaintNode *              clutter_actor_create_texture_paint_node                 (ClutterActor *self, | ||||
|                                                                                          CoglTexture  *texture); | ||||
|  | ||||
| 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); | ||||
|  | ||||
| gboolean clutter_actor_get_redraw_clip (ClutterActor       *self, | ||||
|                                         ClutterPaintVolume *dst_old_pv, | ||||
|                                         ClutterPaintVolume *dst_new_pv); | ||||
|  | ||||
| G_END_DECLS | ||||
|  | ||||
| #endif /* __CLUTTER_ACTOR_PRIVATE_H__ */ | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -142,6 +142,11 @@ struct _ClutterActor | ||||
|  * ClutterActorClass: | ||||
|  * @show: signal class handler for #ClutterActor::show; it must chain | ||||
|  *   up to the parent's implementation | ||||
|  * @show_all: virtual function for containers and composite actors, to | ||||
|  *   determine which children should be shown when calling | ||||
|  *   clutter_actor_show_all() on the actor. Defaults to calling | ||||
|  *   clutter_actor_show(). This virtual function is deprecated and it | ||||
|  *   should not be overridden. | ||||
|  * @hide: signal class handler for #ClutterActor::hide; it must chain | ||||
|  *   up to the parent's implementation | ||||
|  * @hide_all: virtual function for containers and composite actors, to | ||||
| @@ -170,23 +175,18 @@ struct _ClutterActor | ||||
|  * @get_preferred_height: virtual function, used when querying the minimum | ||||
|  *   and natural heights of an actor for a given width; it is used by | ||||
|  *   clutter_actor_get_preferred_height() | ||||
|  * @allocate: virtual function, used when 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. | ||||
|  * @allocate: virtual function, used when settings the coordinates of an | ||||
|  *   actor; it is used by clutter_actor_allocate(); it must chain up to | ||||
|  *   the parent's implementation, or call clutter_actor_set_allocation() | ||||
|  * @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 | ||||
|  *   the allocation; it must chain up to the parent's implementation | ||||
|  * @parent_set: signal class handler for the #ClutterActor::parent-set | ||||
|  * @destroy: signal class handler for #ClutterActor::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 | ||||
|  * @queue_redraw: class handler for #ClutterActor::queue-redraw | ||||
|  * @event: class handler for #ClutterActor::event | ||||
|  * @button_press_event: class handler for #ClutterActor::button-press-event | ||||
|  * @button_release_event: class handler for | ||||
| @@ -223,6 +223,7 @@ struct _ClutterActorClass | ||||
|  | ||||
|   /*< public >*/ | ||||
|   void (* show)                 (ClutterActor          *self); | ||||
|   void (* show_all)             (ClutterActor          *self); | ||||
|   void (* hide)                 (ClutterActor          *self); | ||||
|   void (* hide_all)             (ClutterActor          *self); | ||||
|   void (* realize)              (ClutterActor          *self); | ||||
| @@ -238,6 +239,10 @@ struct _ClutterActorClass | ||||
|   void (* pick)                 (ClutterActor          *actor, | ||||
|                                  ClutterPickContext    *pick_context); | ||||
|  | ||||
|   gboolean (* queue_redraw)     (ClutterActor          *actor, | ||||
|                                  ClutterActor          *leaf_that_queued, | ||||
|                                  ClutterPaintVolume    *paint_volume); | ||||
|  | ||||
|   /* size negotiation */ | ||||
|   void (* get_preferred_width)  (ClutterActor           *self, | ||||
|                                  gfloat                  for_height, | ||||
| @@ -248,11 +253,12 @@ struct _ClutterActorClass | ||||
|                                  gfloat                 *min_height_p, | ||||
|                                  gfloat                 *natural_height_p); | ||||
|   void (* allocate)             (ClutterActor           *self, | ||||
|                                  const ClutterActorBox  *box); | ||||
|                                  const ClutterActorBox  *box, | ||||
|                                  ClutterAllocationFlags  flags); | ||||
|  | ||||
|   /* transformations */ | ||||
|   void (* apply_transform)      (ClutterActor           *actor, | ||||
|                                  graphene_matrix_t      *matrix); | ||||
|                                  ClutterMatrix          *matrix); | ||||
|  | ||||
|   /* event signals */ | ||||
|   gboolean (* event)                (ClutterActor         *actor, | ||||
| @@ -294,9 +300,6 @@ struct _ClutterActorClass | ||||
|   gboolean (* touch_event)          (ClutterActor         *self, | ||||
|                                      ClutterTouchEvent    *event); | ||||
|   gboolean (* has_accessible)       (ClutterActor         *self); | ||||
|   void     (* resource_scale_changed) (ClutterActor *self); | ||||
|   float    (* calculate_resource_scale) (ClutterActor *self, | ||||
|                                          int           phase); | ||||
|  | ||||
|   /*< private >*/ | ||||
|   /* padding for future expansion */ | ||||
| @@ -412,31 +415,38 @@ void                            clutter_actor_get_preferred_size | ||||
|                                                                                  gfloat                      *natural_height_p); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_allocate                          (ClutterActor                *self, | ||||
|                                                                                  const ClutterActorBox       *box); | ||||
|                                                                                  const ClutterActorBox       *box, | ||||
|                                                                                  ClutterAllocationFlags       flags); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_allocate_preferred_size           (ClutterActor                *self, | ||||
|                                                                                  float                        x, | ||||
|                                                                                  float                        y); | ||||
|                                                                                  ClutterAllocationFlags       flags); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_allocate_available_size           (ClutterActor                *self, | ||||
|                                                                                  gfloat                       x, | ||||
|                                                                                  gfloat                       y, | ||||
|                                                                                  gfloat                       available_width, | ||||
|                                                                                  gfloat                       available_height); | ||||
|                                                                                  gfloat                       available_height, | ||||
|                                                                                  ClutterAllocationFlags       flags); | ||||
| 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); | ||||
|                                                                                  gboolean                     y_fill, | ||||
|                                                                                  ClutterAllocationFlags       flags); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_allocation                    (ClutterActor                *self, | ||||
|                                                                                  const ClutterActorBox       *box); | ||||
|                                                                                  const ClutterActorBox       *box, | ||||
|                                                                                  ClutterAllocationFlags       flags); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_get_allocation_box                (ClutterActor                *self, | ||||
|                                                                                  ClutterActorBox             *box); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_get_allocation_vertices           (ClutterActor                *self, | ||||
|                                                                                  ClutterActor                *ancestor, | ||||
|                                                                                  graphene_point3d_t          *verts); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_has_allocation                    (ClutterActor                *self); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_size                          (ClutterActor                *self, | ||||
| @@ -451,10 +461,6 @@ void                            clutter_actor_set_position | ||||
|                                                                                  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); | ||||
| @@ -586,8 +592,7 @@ void                            clutter_actor_set_offscreen_redirect | ||||
| CLUTTER_EXPORT | ||||
| ClutterOffscreenRedirect        clutter_actor_get_offscreen_redirect            (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_should_pick                       (ClutterActor               *self, | ||||
|                                                                                  ClutterPickContext         *pick_context); | ||||
| gboolean                        clutter_actor_should_pick_paint                 (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_is_in_clone_paint                 (ClutterActor               *self); | ||||
| CLUTTER_EXPORT | ||||
| @@ -595,7 +600,8 @@ gboolean                        clutter_actor_get_paint_box | ||||
|                                                                                  ClutterActorBox            *box); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| float                           clutter_actor_get_resource_scale                (ClutterActor *self); | ||||
| gboolean                        clutter_actor_get_resource_scale                (ClutterActor *self, | ||||
|                                                                                  gfloat       *resource_scale); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| gboolean                        clutter_actor_has_overlaps                      (ClutterActor               *self); | ||||
| @@ -799,21 +805,16 @@ void                            clutter_actor_get_translation | ||||
|                                                                                  gfloat                     *translate_z); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_transform                     (ClutterActor               *self, | ||||
|                                                                                  const graphene_matrix_t    *transform); | ||||
|                                                                                  const ClutterMatrix        *transform); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_get_transform                     (ClutterActor               *self, | ||||
|                                                                                  graphene_matrix_t          *transform); | ||||
|                                                                                  ClutterMatrix              *transform); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_set_child_transform               (ClutterActor               *self, | ||||
|                                                                                  const graphene_matrix_t    *transform); | ||||
|                                                                                  const ClutterMatrix        *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); | ||||
|  | ||||
|                                                                                  ClutterMatrix              *transform); | ||||
| CLUTTER_EXPORT | ||||
| void                            clutter_actor_get_transformed_position          (ClutterActor               *self, | ||||
|                                                                                  gfloat                     *x, | ||||
| @@ -883,11 +884,6 @@ void                            clutter_actor_set_opacity_override | ||||
| 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 | ||||
| @@ -925,15 +921,6 @@ 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); | ||||
|  | ||||
| G_END_DECLS | ||||
|  | ||||
| #endif /* __CLUTTER_ACTOR_H__ */ | ||||
|   | ||||
| @@ -58,7 +58,6 @@ struct _ClutterAlignConstraint | ||||
|   ClutterActor *actor; | ||||
|   ClutterActor *source; | ||||
|   ClutterAlignAxis align_axis; | ||||
|   graphene_point_t pivot; | ||||
|   gfloat factor; | ||||
| }; | ||||
|  | ||||
| @@ -73,7 +72,6 @@ enum | ||||
|  | ||||
|   PROP_SOURCE, | ||||
|   PROP_ALIGN_AXIS, | ||||
|   PROP_PIVOT_POINT, | ||||
|   PROP_FACTOR, | ||||
|  | ||||
|   PROP_LAST | ||||
| @@ -86,11 +84,13 @@ G_DEFINE_TYPE (ClutterAlignConstraint, | ||||
|                CLUTTER_TYPE_CONSTRAINT); | ||||
|  | ||||
| static void | ||||
| source_queue_relayout (ClutterActor           *actor, | ||||
|                        ClutterAlignConstraint *align) | ||||
| source_position_changed (ClutterActor           *actor, | ||||
|                          const ClutterActorBox  *allocation, | ||||
|                          ClutterAllocationFlags  flags, | ||||
|                          ClutterAlignConstraint *align) | ||||
| { | ||||
|   if (align->actor != NULL) | ||||
|     _clutter_actor_queue_only_relayout (align->actor); | ||||
|     clutter_actor_queue_relayout (align->actor); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -135,41 +135,35 @@ clutter_align_constraint_update_allocation (ClutterConstraint *constraint, | ||||
|   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; | ||||
|   gfloat source_x, source_y; | ||||
|  | ||||
|   if (align->source == NULL) | ||||
|     return; | ||||
|  | ||||
|   clutter_actor_box_get_size (allocation, &actor_width, &actor_height); | ||||
|  | ||||
|   clutter_actor_get_position (align->source, &source_x, &source_y); | ||||
|   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->x1 = ((source_width - actor_width) * align->factor) | ||||
|                      + source_x; | ||||
|       allocation->x2 = allocation->x1 + actor_width; | ||||
|       break; | ||||
|  | ||||
|     case CLUTTER_ALIGN_Y_AXIS: | ||||
|       allocation->y1 += offset_y_start + (source_height * align->factor); | ||||
|       allocation->y1 = ((source_height - actor_height) * align->factor) | ||||
|                      + source_y; | ||||
|       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->x1 = ((source_width - actor_width) * align->factor) | ||||
|                      + source_x; | ||||
|       allocation->y1 = ((source_height - actor_height) * align->factor) | ||||
|                      + source_y; | ||||
|       allocation->x2 = allocation->x1 + actor_width; | ||||
|       allocation->y2 = allocation->y1 + actor_height; | ||||
|       break; | ||||
| @@ -193,7 +187,7 @@ clutter_align_constraint_dispose (GObject *gobject) | ||||
|                                             G_CALLBACK (source_destroyed), | ||||
|                                             align); | ||||
|       g_signal_handlers_disconnect_by_func (align->source, | ||||
|                                             G_CALLBACK (source_queue_relayout), | ||||
|                                             G_CALLBACK (source_position_changed), | ||||
|                                             align); | ||||
|       align->source = NULL; | ||||
|     } | ||||
| @@ -219,10 +213,6 @@ clutter_align_constraint_set_property (GObject      *gobject, | ||||
|       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; | ||||
| @@ -251,16 +241,6 @@ clutter_align_constraint_get_property (GObject    *gobject, | ||||
|       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; | ||||
| @@ -314,30 +294,6 @@ clutter_align_constraint_class_init (ClutterAlignConstraintClass *klass) | ||||
|                        CLUTTER_ALIGN_X_AXIS, | ||||
|                        CLUTTER_PARAM_READWRITE | 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", | ||||
|                        P_("Pivot point"), | ||||
|                        P_("The pivot point"), | ||||
|                        GRAPHENE_TYPE_POINT, | ||||
|                        G_PARAM_READWRITE | | ||||
|                        G_PARAM_STATIC_STRINGS); | ||||
|  | ||||
|   /** | ||||
|    * ClutterAlignConstraint:factor: | ||||
|    * | ||||
| @@ -370,8 +326,6 @@ 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; | ||||
| } | ||||
|  | ||||
| @@ -449,15 +403,15 @@ clutter_align_constraint_set_source (ClutterAlignConstraint *align, | ||||
|                                             G_CALLBACK (source_destroyed), | ||||
|                                             align); | ||||
|       g_signal_handlers_disconnect_by_func (old_source, | ||||
|                                             G_CALLBACK (source_queue_relayout), | ||||
|                                             G_CALLBACK (source_position_changed), | ||||
|                                             align); | ||||
|     } | ||||
|  | ||||
|   align->source = source; | ||||
|   if (align->source != NULL) | ||||
|     { | ||||
|       g_signal_connect (align->source, "queue-relayout", | ||||
|                         G_CALLBACK (source_queue_relayout), | ||||
|       g_signal_connect (align->source, "allocation-changed", | ||||
|                         G_CALLBACK (source_position_changed), | ||||
|                         align); | ||||
|       g_signal_connect (align->source, "destroy", | ||||
|                         G_CALLBACK (source_destroyed), | ||||
| @@ -534,60 +488,6 @@ clutter_align_constraint_get_align_axis (ClutterAlignConstraint *align) | ||||
|   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 | ||||
|  * clutter_align_constraint_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 | ||||
|   | ||||
| @@ -67,12 +67,6 @@ void               clutter_align_constraint_set_align_axis (ClutterAlignConstrai | ||||
| 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 | ||||
|   | ||||
| @@ -27,23 +27,35 @@ | ||||
|  * @short_description: Interface for animatable classes | ||||
|  * | ||||
|  * #ClutterAnimatable is an interface that allows a #GObject class | ||||
|  * to control how an actor will animate a property. | ||||
|  * to control how a #ClutterAnimation will animate a property. | ||||
|  * | ||||
|  * Each #ClutterAnimatable should implement the | ||||
|  * #ClutterAnimatableInterface.interpolate_property() virtual function of the | ||||
|  * interface to compute the animation state between two values of an interval | ||||
|  * depending on a progress factor, expressed as a floating point value. | ||||
|  * | ||||
|  * If a #ClutterAnimatable is animated by a #ClutterAnimation | ||||
|  * instance, the #ClutterAnimation will call | ||||
|  * clutter_animatable_interpolate_property() passing the name of the | ||||
|  * currently animated property; the values interval; and the progress factor. | ||||
|  * The #ClutterAnimatable implementation should return the computed value for | ||||
|  * the animated | ||||
|  * property. | ||||
|  * | ||||
|  * #ClutterAnimatable is available since Clutter 1.0 | ||||
|  */ | ||||
|  | ||||
| #include "clutter-build-config.h" | ||||
|  | ||||
| #define CLUTTER_DISABLE_DEPRECATION_WARNINGS | ||||
|  | ||||
| #include "clutter-animatable.h" | ||||
| #include "clutter-interval.h" | ||||
| #include "clutter-debug.h" | ||||
| #include "clutter-private.h" | ||||
|  | ||||
| #include "deprecated/clutter-animation.h" | ||||
|  | ||||
| G_DEFINE_INTERFACE (ClutterAnimatable, clutter_animatable, G_TYPE_OBJECT); | ||||
|  | ||||
| static void | ||||
| @@ -194,25 +206,3 @@ clutter_animatable_interpolate_value (ClutterAnimatable *animatable, | ||||
|   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); | ||||
| } | ||||
|   | ||||
| @@ -42,6 +42,8 @@ G_DECLARE_INTERFACE (ClutterAnimatable, clutter_animatable, | ||||
|  | ||||
| /** | ||||
|  * ClutterAnimatableInterface: | ||||
|  * @animate_property: virtual function for custom interpolation of a | ||||
|  *   property. This virtual function is deprecated | ||||
|  * @find_property: virtual function for retrieving the #GParamSpec of | ||||
|  *   an animatable property | ||||
|  * @get_initial_state: virtual function for retrieving the initial | ||||
| @@ -50,7 +52,9 @@ G_DECLARE_INTERFACE (ClutterAnimatable, clutter_animatable, | ||||
|  *   animatable property | ||||
|  * @interpolate_value: virtual function for interpolating the progress | ||||
|  *   of a property | ||||
|  * @get_actor: virtual function for getting associated actor | ||||
|  * | ||||
|  * Base interface for #GObject<!-- -->s that can be animated by a | ||||
|  * a #ClutterAnimation. | ||||
|  * | ||||
|  * Since: 1.0 | ||||
|  */ | ||||
| @@ -60,6 +64,13 @@ struct _ClutterAnimatableInterface | ||||
|   GTypeInterface parent_iface; | ||||
|  | ||||
|   /*< public >*/ | ||||
|   gboolean    (* animate_property)  (ClutterAnimatable *animatable, | ||||
|                                      ClutterAnimation  *animation, | ||||
|                                      const gchar       *property_name, | ||||
|                                      const GValue      *initial_value, | ||||
|                                      const GValue      *final_value, | ||||
|                                      gdouble            progress, | ||||
|                                      GValue            *value); | ||||
|   GParamSpec *(* find_property)     (ClutterAnimatable *animatable, | ||||
|                                      const gchar       *property_name); | ||||
|   void        (* get_initial_state) (ClutterAnimatable *animatable, | ||||
| @@ -73,7 +84,6 @@ struct _ClutterAnimatableInterface | ||||
|                                      ClutterInterval   *interval, | ||||
|                                      gdouble            progress, | ||||
|                                      GValue            *value); | ||||
|   ClutterActor * (* get_actor)      (ClutterAnimatable *animatable); | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| @@ -94,9 +104,6 @@ gboolean    clutter_animatable_interpolate_value (ClutterAnimatable *animatable, | ||||
|                                                   gdouble            progress, | ||||
|                                                   GValue            *value); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterActor * clutter_animatable_get_actor      (ClutterAnimatable *animatable); | ||||
|  | ||||
| G_END_DECLS | ||||
|  | ||||
| #endif /* __CLUTTER_ANIMATABLE_H__ */ | ||||
|   | ||||
| @@ -30,7 +30,9 @@ | ||||
|  | ||||
| #ifndef __GI_SCANNER__ | ||||
|  | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterAction, g_object_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActor, g_object_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActorMeta, g_object_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterAlignConstraint, g_object_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBackend, g_object_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBindConstraint, g_object_unref) | ||||
| @@ -41,15 +43,19 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBoxLayout, g_object_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBrightnessContrastEffect, g_object_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterCanvas, g_object_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterChildMeta, g_object_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterClickAction, g_object_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterClone, g_object_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterColorizeEffect, g_object_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterConstraint, g_object_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterContainer, g_object_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDeformEffect, g_object_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDesaturateEffect, g_object_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDragAction, g_object_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDropAction, g_object_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterEffect, g_object_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterFixedLayout, g_object_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterFlowLayout, g_object_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterGestureAction, g_object_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterGridLayout, g_object_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterImage, g_object_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterInputDevice, g_object_unref) | ||||
| @@ -83,6 +89,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterZoomAction, g_object_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterActorBox, clutter_actor_box_free) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterColor, clutter_color_free) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterMargin, clutter_margin_free) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterMatrix, clutter_matrix_free) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintContext, clutter_paint_context_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintNode, clutter_paint_node_unref) | ||||
| G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintVolume, clutter_paint_volume_free) | ||||
|   | ||||
| @@ -53,8 +53,6 @@ struct _ClutterBackend | ||||
|   gfloat units_per_em; | ||||
|   gint32 units_serial; | ||||
|  | ||||
|   float fallback_resource_scale; | ||||
|  | ||||
|   ClutterStageWindow *stage_window; | ||||
|  | ||||
|   ClutterInputMethod *input_method; | ||||
| @@ -66,12 +64,18 @@ struct _ClutterBackendClass | ||||
|   GObjectClass parent_class; | ||||
|  | ||||
|   /* vfuncs */ | ||||
|   gboolean              (* finish_init)        (ClutterBackend  *backend, | ||||
|   gboolean              (* pre_parse)          (ClutterBackend  *backend, | ||||
|                                                 GError         **error); | ||||
|   gboolean              (* post_parse)         (ClutterBackend  *backend, | ||||
|                                                 GError         **error); | ||||
|   ClutterStageWindow *  (* create_stage)       (ClutterBackend  *backend, | ||||
|                                                 ClutterStage    *wrapper, | ||||
|                                                 GError         **error); | ||||
|   void                  (* init_events)        (ClutterBackend  *backend); | ||||
|   void                  (* init_features)      (ClutterBackend  *backend); | ||||
|   void                  (* add_options)        (ClutterBackend  *backend, | ||||
|                                                 GOptionGroup    *group); | ||||
|   ClutterFeatureFlags   (* get_features)       (ClutterBackend  *backend); | ||||
|   CoglRenderer *        (* get_renderer)       (ClutterBackend  *backend, | ||||
|                                                 GError         **error); | ||||
|   CoglDisplay *         (* get_display)        (ClutterBackend  *backend, | ||||
| @@ -87,28 +91,40 @@ struct _ClutterBackendClass | ||||
|  | ||||
|   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); | ||||
| }; | ||||
|  | ||||
| ClutterBackend *        _clutter_create_backend                         (void); | ||||
|  | ||||
| ClutterStageWindow *    _clutter_backend_create_stage                   (ClutterBackend         *backend, | ||||
|                                                                          ClutterStage           *wrapper, | ||||
|                                                                          GError                **error); | ||||
| gboolean                _clutter_backend_create_context                 (ClutterBackend         *backend, | ||||
|                                                                          GError                **error); | ||||
|  | ||||
| gboolean                _clutter_backend_finish_init                    (ClutterBackend         *backend, | ||||
| void                    _clutter_backend_add_options                    (ClutterBackend         *backend, | ||||
|                                                                          GOptionGroup           *group); | ||||
| gboolean                _clutter_backend_pre_parse                      (ClutterBackend         *backend, | ||||
|                                                                          GError                **error); | ||||
| gboolean                _clutter_backend_post_parse                     (ClutterBackend         *backend, | ||||
|                                                                          GError                **error); | ||||
|  | ||||
| void                    _clutter_backend_init_events                    (ClutterBackend         *backend); | ||||
| void                    _clutter_backend_copy_event_data                (ClutterBackend         *backend, | ||||
|                                                                          const ClutterEvent     *src, | ||||
|                                                                          ClutterEvent           *dest); | ||||
| void                    _clutter_backend_free_event_data                (ClutterBackend         *backend, | ||||
|                                                                          ClutterEvent           *event); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                _clutter_backend_translate_event                (ClutterBackend         *backend, | ||||
|                                                                          gpointer                native, | ||||
|                                                                          ClutterEvent           *event); | ||||
|  | ||||
| ClutterFeatureFlags     _clutter_backend_get_features                   (ClutterBackend         *backend); | ||||
|  | ||||
| gfloat                  _clutter_backend_get_units_per_em               (ClutterBackend         *backend, | ||||
|                                                                          PangoFontDescription   *font_desc); | ||||
| gint32                  _clutter_backend_get_units_serial               (ClutterBackend         *backend); | ||||
| @@ -118,17 +134,6 @@ void                    clutter_set_allowed_drivers                     (const c | ||||
| 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 | ||||
|  | ||||
| #endif /* __CLUTTER_BACKEND_PRIVATE_H__ */ | ||||
|   | ||||
| @@ -40,6 +40,8 @@ | ||||
|  | ||||
| #include "clutter-build-config.h" | ||||
|  | ||||
| #define CLUTTER_ENABLE_EXPERIMENTAL_API | ||||
|  | ||||
| #include "clutter-backend-private.h" | ||||
| #include "clutter-debug.h" | ||||
| #include "clutter-event-private.h" | ||||
| @@ -50,8 +52,25 @@ | ||||
| #include "clutter-stage-private.h" | ||||
| #include "clutter-stage-window.h" | ||||
|  | ||||
| #ifdef CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT | ||||
| #include "wayland/clutter-wayland-compositor.h" | ||||
| #endif | ||||
|  | ||||
| #include <cogl/cogl.h> | ||||
|  | ||||
| #ifdef CLUTTER_INPUT_X11 | ||||
| #include "x11/clutter-backend-x11.h" | ||||
| #endif | ||||
| #ifdef CLUTTER_WINDOWING_EGL | ||||
| #include "egl/clutter-backend-eglnative.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT | ||||
| #include <cogl/cogl-wayland-server.h> | ||||
| #include <wayland-server.h> | ||||
| #include "wayland/clutter-wayland-compositor.h" | ||||
| #endif | ||||
|  | ||||
| #define DEFAULT_FONT_NAME       "Sans 10" | ||||
|  | ||||
| enum | ||||
| @@ -67,6 +86,12 @@ G_DEFINE_ABSTRACT_TYPE (ClutterBackend, clutter_backend, G_TYPE_OBJECT) | ||||
|  | ||||
| static guint backend_signals[LAST_SIGNAL] = { 0, }; | ||||
|  | ||||
| /* Global for being able to specify a compositor side wayland display | ||||
|  * pointer before clutter initialization */ | ||||
| #ifdef CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT | ||||
| static struct wl_display *_wayland_compositor_display; | ||||
| #endif | ||||
|  | ||||
| static void | ||||
| clutter_backend_dispose (GObject *gobject) | ||||
| { | ||||
| @@ -75,20 +100,28 @@ clutter_backend_dispose (GObject *gobject) | ||||
|   /* clear the events still in the queue of the main context */ | ||||
|   _clutter_clear_events_queue (); | ||||
|  | ||||
|   g_clear_object (&backend->dummy_onscreen); | ||||
|   g_clear_pointer (&backend->dummy_onscreen, cogl_object_unref); | ||||
|   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_OBJECT_CLASS (clutter_backend_parent_class)->dispose (gobject); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_backend_finalize (GObject *gobject) | ||||
| { | ||||
|   ClutterBackend *backend = CLUTTER_BACKEND (gobject); | ||||
|  | ||||
|   g_source_destroy (backend->cogl_source); | ||||
|  | ||||
|   g_free (backend->font_name); | ||||
|   clutter_backend_set_font_options (backend, NULL); | ||||
|   g_clear_object (&backend->input_method); | ||||
|  | ||||
|   G_OBJECT_CLASS (clutter_backend_parent_class)->dispose (gobject); | ||||
|   G_OBJECT_CLASS (clutter_backend_parent_class)->finalize (gobject); | ||||
| } | ||||
|  | ||||
| static gfloat | ||||
| @@ -189,20 +222,22 @@ clutter_backend_do_real_create_context (ClutterBackend  *backend, | ||||
| { | ||||
|   ClutterBackendClass *klass; | ||||
|   CoglSwapChain *swap_chain; | ||||
|   GError *internal_error; | ||||
|  | ||||
|   klass = CLUTTER_BACKEND_GET_CLASS (backend); | ||||
|  | ||||
|   swap_chain = NULL; | ||||
|   internal_error = NULL; | ||||
|  | ||||
|   CLUTTER_NOTE (BACKEND, "Creating Cogl renderer"); | ||||
|   backend->cogl_renderer = klass->get_renderer (backend, error); | ||||
|   backend->cogl_renderer = klass->get_renderer (backend, &internal_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)) | ||||
|   if (!cogl_renderer_connect (backend->cogl_renderer, &internal_error)) | ||||
|     goto error; | ||||
|  | ||||
|   CLUTTER_NOTE (BACKEND, "Creating Cogl swap chain"); | ||||
| @@ -214,7 +249,7 @@ clutter_backend_do_real_create_context (ClutterBackend  *backend, | ||||
|       backend->cogl_display = klass->get_display (backend, | ||||
|                                                   backend->cogl_renderer, | ||||
|                                                   swap_chain, | ||||
|                                                   error); | ||||
|                                                   &internal_error); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
| @@ -230,7 +265,7 @@ clutter_backend_do_real_create_context (ClutterBackend  *backend, | ||||
|        */ | ||||
|       res = cogl_renderer_check_onscreen_template (backend->cogl_renderer, | ||||
|                                                    tmpl, | ||||
|                                                    error); | ||||
|                                                    &internal_error); | ||||
|  | ||||
|       if (!res) | ||||
|         goto error; | ||||
| @@ -244,12 +279,17 @@ clutter_backend_do_real_create_context (ClutterBackend  *backend, | ||||
|   if (backend->cogl_display == NULL) | ||||
|     goto error; | ||||
|  | ||||
| #ifdef CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT | ||||
|   cogl_wayland_display_set_compositor_display (backend->cogl_display, | ||||
|                                                _wayland_compositor_display); | ||||
| #endif | ||||
|  | ||||
|   CLUTTER_NOTE (BACKEND, "Setting up the display"); | ||||
|   if (!cogl_display_setup (backend->cogl_display, error)) | ||||
|   if (!cogl_display_setup (backend->cogl_display, &internal_error)) | ||||
|     goto error; | ||||
|  | ||||
|   CLUTTER_NOTE (BACKEND, "Creating the Cogl context"); | ||||
|   backend->cogl_context = cogl_context_new (backend->cogl_display, error); | ||||
|   backend->cogl_context = cogl_context_new (backend->cogl_display, &internal_error); | ||||
|   if (backend->cogl_context == NULL) | ||||
|     goto error; | ||||
|  | ||||
| @@ -353,7 +393,8 @@ clutter_backend_real_create_context (ClutterBackend  *backend, | ||||
|       if (internal_error != NULL) | ||||
|         g_propagate_error (error, internal_error); | ||||
|       else | ||||
|         g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, | ||||
|         g_set_error_literal (error, CLUTTER_INIT_ERROR, | ||||
|                              CLUTTER_INIT_ERROR_BACKEND, | ||||
|                              "Unable to initialize the Clutter backend: no available drivers found."); | ||||
|  | ||||
|       return FALSE; | ||||
| @@ -365,12 +406,134 @@ clutter_backend_real_create_context (ClutterBackend  *backend, | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static ClutterFeatureFlags | ||||
| clutter_backend_real_get_features (ClutterBackend *backend) | ||||
| { | ||||
|   ClutterFeatureFlags flags = 0; | ||||
|  | ||||
|   if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN)) | ||||
|     { | ||||
|       CLUTTER_NOTE (BACKEND, "Cogl supports multiple onscreen framebuffers"); | ||||
|       flags |= CLUTTER_FEATURE_STAGE_MULTIPLE; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       CLUTTER_NOTE (BACKEND, "Cogl only supports one onscreen framebuffer"); | ||||
|       flags |= CLUTTER_FEATURE_STAGE_STATIC; | ||||
|     } | ||||
|  | ||||
|   if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_THROTTLE)) | ||||
|     { | ||||
|       CLUTTER_NOTE (BACKEND, "Cogl supports swap buffers throttling"); | ||||
|       flags |= CLUTTER_FEATURE_SWAP_THROTTLE; | ||||
|     } | ||||
|   else | ||||
|     CLUTTER_NOTE (BACKEND, "Cogl doesn't support swap buffers throttling"); | ||||
|  | ||||
|   if (cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT)) | ||||
|     { | ||||
|       CLUTTER_NOTE (BACKEND, "Cogl supports swap buffers complete events"); | ||||
|       flags |= CLUTTER_FEATURE_SWAP_EVENTS; | ||||
|     } | ||||
|  | ||||
|   return flags; | ||||
| } | ||||
|  | ||||
| static const char *allowed_backends; | ||||
|  | ||||
| static ClutterBackend * (* custom_backend_func) (void); | ||||
|  | ||||
| static const struct { | ||||
|   const char *name; | ||||
|   ClutterBackend * (* create_backend) (void); | ||||
| } available_backends[] = { | ||||
| #ifdef CLUTTER_WINDOWING_X11 | ||||
|   { CLUTTER_WINDOWING_X11, clutter_backend_x11_new }, | ||||
| #endif | ||||
| #ifdef CLUTTER_WINDOWING_EGL | ||||
|   { CLUTTER_WINDOWING_EGL, clutter_backend_egl_native_new }, | ||||
| #endif | ||||
|   { NULL, NULL }, | ||||
| }; | ||||
|  | ||||
| void | ||||
| clutter_set_custom_backend_func (ClutterBackend *(* func) (void)) | ||||
| { | ||||
|   custom_backend_func = func; | ||||
| } | ||||
|  | ||||
| ClutterBackend * | ||||
| _clutter_create_backend (void) | ||||
| { | ||||
|   const char *backends_list; | ||||
|   ClutterBackend *retval; | ||||
|   gboolean allow_any; | ||||
|   char **backends; | ||||
|   int i; | ||||
|  | ||||
|   if (custom_backend_func) | ||||
|     { | ||||
|       retval = custom_backend_func (); | ||||
|  | ||||
|       if (!retval) | ||||
|         g_error ("Failed to create custom backend."); | ||||
|  | ||||
|       return retval; | ||||
|     } | ||||
|  | ||||
|   if (allowed_backends == NULL) | ||||
|     allowed_backends = "*"; | ||||
|  | ||||
|   allow_any = strstr (allowed_backends, "*") != NULL; | ||||
|  | ||||
|   backends_list = g_getenv ("CLUTTER_BACKEND"); | ||||
|   if (backends_list == NULL) | ||||
|     backends_list = allowed_backends; | ||||
|  | ||||
|   backends = g_strsplit (backends_list, ",", 0); | ||||
|  | ||||
|   retval = NULL; | ||||
|  | ||||
|   for (i = 0; retval == NULL && backends[i] != NULL; i++) | ||||
|     { | ||||
|       const char *backend = backends[i]; | ||||
|       gboolean is_any = g_str_equal (backend, "*"); | ||||
|       int j; | ||||
|  | ||||
|       for (j = 0; available_backends[j].name != NULL; j++) | ||||
|         { | ||||
|           if ((is_any && allow_any) || | ||||
|               (is_any && strstr (allowed_backends, available_backends[j].name)) || | ||||
|               g_str_equal (backend, available_backends[j].name)) | ||||
|             { | ||||
|               retval = available_backends[j].create_backend (); | ||||
|               if (retval != NULL) | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   g_strfreev (backends); | ||||
|  | ||||
|   if (retval == NULL) | ||||
|     g_error ("No default Clutter backend found."); | ||||
|  | ||||
|   return retval; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_backend_real_init_events (ClutterBackend *backend) | ||||
| { | ||||
|   g_error ("Unknown input backend"); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_backend_class_init (ClutterBackendClass *klass) | ||||
| { | ||||
|   GObjectClass *gobject_class = G_OBJECT_CLASS (klass); | ||||
|  | ||||
|   gobject_class->dispose = clutter_backend_dispose; | ||||
|   gobject_class->finalize = clutter_backend_finalize; | ||||
|  | ||||
|   /** | ||||
|    * ClutterBackend::resolution-changed: | ||||
| @@ -426,7 +589,9 @@ clutter_backend_class_init (ClutterBackendClass *klass) | ||||
|   klass->resolution_changed = clutter_backend_real_resolution_changed; | ||||
|   klass->font_changed = clutter_backend_real_font_changed; | ||||
|  | ||||
|   klass->init_events = clutter_backend_real_init_events; | ||||
|   klass->create_context = clutter_backend_real_create_context; | ||||
|   klass->get_features = clutter_backend_real_get_features; | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -436,21 +601,47 @@ clutter_backend_init (ClutterBackend *self) | ||||
|   self->units_serial = 1; | ||||
|  | ||||
|   self->dummy_onscreen = NULL; | ||||
|  | ||||
|   self->fallback_resource_scale = 1.f; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| _clutter_backend_finish_init (ClutterBackend  *backend, | ||||
|                               GError         **error) | ||||
| void | ||||
| _clutter_backend_add_options (ClutterBackend *backend, | ||||
|                               GOptionGroup   *group) | ||||
| { | ||||
|   ClutterBackendClass *klass; | ||||
|  | ||||
|   g_assert (CLUTTER_IS_BACKEND (backend)); | ||||
|  | ||||
|   klass = CLUTTER_BACKEND_GET_CLASS (backend); | ||||
|   if (klass->finish_init) | ||||
|     return klass->finish_init (backend, error); | ||||
|   if (klass->add_options) | ||||
|     klass->add_options (backend, group); | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| _clutter_backend_pre_parse (ClutterBackend  *backend, | ||||
|                             GError         **error) | ||||
| { | ||||
|   ClutterBackendClass *klass; | ||||
|  | ||||
|   g_assert (CLUTTER_IS_BACKEND (backend)); | ||||
|  | ||||
|   klass = CLUTTER_BACKEND_GET_CLASS (backend); | ||||
|   if (klass->pre_parse) | ||||
|     return klass->pre_parse (backend, error); | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| _clutter_backend_post_parse (ClutterBackend  *backend, | ||||
|                              GError         **error) | ||||
| { | ||||
|   ClutterBackendClass *klass; | ||||
|  | ||||
|   g_assert (CLUTTER_IS_BACKEND (backend)); | ||||
|  | ||||
|   klass = CLUTTER_BACKEND_GET_CLASS (backend); | ||||
|   if (klass->post_parse) | ||||
|     return klass->post_parse (backend, error); | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
| @@ -495,6 +686,57 @@ _clutter_backend_create_context (ClutterBackend  *backend, | ||||
|   return klass->create_context (backend, error); | ||||
| } | ||||
|  | ||||
| ClutterFeatureFlags | ||||
| _clutter_backend_get_features (ClutterBackend *backend) | ||||
| { | ||||
|   ClutterBackendClass *klass; | ||||
|   GError *error; | ||||
|  | ||||
|   g_assert (CLUTTER_IS_BACKEND (backend)); | ||||
|  | ||||
|   klass = CLUTTER_BACKEND_GET_CLASS (backend); | ||||
|  | ||||
|   /* we need to have a context here; so we create the | ||||
|    * GL context first and the ask for features. if the | ||||
|    * context already exists this should be a no-op | ||||
|    */ | ||||
|   error = NULL; | ||||
|   if (klass->create_context != NULL) | ||||
|     { | ||||
|       gboolean res; | ||||
|  | ||||
|       res = klass->create_context (backend, &error); | ||||
|       if (!res) | ||||
|         { | ||||
|           if (error) | ||||
|             { | ||||
|               g_critical ("Unable to create a context: %s", error->message); | ||||
|               g_error_free (error); | ||||
|             } | ||||
|           else | ||||
|             g_critical ("Unable to create a context: unknown error"); | ||||
|  | ||||
|           return 0; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   if (klass->get_features) | ||||
|     return klass->get_features (backend); | ||||
|    | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| void | ||||
| _clutter_backend_init_events (ClutterBackend *backend) | ||||
| { | ||||
|   ClutterBackendClass *klass; | ||||
|  | ||||
|   g_assert (CLUTTER_IS_BACKEND (backend)); | ||||
|  | ||||
|   klass = CLUTTER_BACKEND_GET_CLASS (backend); | ||||
|   klass->init_events (backend); | ||||
| } | ||||
|  | ||||
| gfloat | ||||
| _clutter_backend_get_units_per_em (ClutterBackend       *backend, | ||||
|                                    PangoFontDescription *font_desc) | ||||
| @@ -509,6 +751,31 @@ _clutter_backend_get_units_per_em (ClutterBackend       *backend, | ||||
|   return backend->units_per_em; | ||||
| } | ||||
|  | ||||
| void | ||||
| _clutter_backend_copy_event_data (ClutterBackend     *backend, | ||||
|                                   const ClutterEvent *src, | ||||
|                                   ClutterEvent       *dest) | ||||
| { | ||||
|   ClutterSeatClass *seat_class; | ||||
|   ClutterSeat *seat; | ||||
|  | ||||
|   seat = clutter_backend_get_default_seat (backend); | ||||
|   seat_class = CLUTTER_SEAT_GET_CLASS (seat); | ||||
|   seat_class->copy_event_data (seat, src, dest); | ||||
| } | ||||
|  | ||||
| void | ||||
| _clutter_backend_free_event_data (ClutterBackend *backend, | ||||
|                                   ClutterEvent   *event) | ||||
| { | ||||
|   ClutterSeatClass *seat_class; | ||||
|   ClutterSeat *seat; | ||||
|  | ||||
|   seat = clutter_backend_get_default_seat (backend); | ||||
|   seat_class = CLUTTER_SEAT_GET_CLASS (seat); | ||||
|   seat_class->free_event_data (seat, event); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_get_default_backend: | ||||
|  * | ||||
| @@ -678,6 +945,31 @@ clutter_backend_get_cogl_context (ClutterBackend *backend) | ||||
|   return backend->cogl_context; | ||||
| } | ||||
|  | ||||
| #ifdef CLUTTER_HAS_WAYLAND_COMPOSITOR_SUPPORT | ||||
| /** | ||||
|  * clutter_wayland_set_compositor_display: | ||||
|  * @display: A compositor side struct wl_display pointer | ||||
|  * | ||||
|  * This informs Clutter of your compositor side Wayland display | ||||
|  * object. This must be called before calling clutter_init(). | ||||
|  * | ||||
|  * Since: 1.8 | ||||
|  * Stability: unstable | ||||
|  */ | ||||
| void | ||||
| clutter_wayland_set_compositor_display (void *display) | ||||
| { | ||||
|   if (_clutter_context_is_initialized ()) | ||||
|     { | ||||
|       g_warning ("%s() can only be used before calling clutter_init()", | ||||
|                  G_STRFUNC); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   _wayland_compositor_display = display; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| void | ||||
| clutter_set_allowed_drivers (const char *drivers) | ||||
| { | ||||
| @@ -739,29 +1031,3 @@ clutter_backend_get_default_seat (ClutterBackend *backend) | ||||
|  | ||||
|   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); | ||||
| } | ||||
|   | ||||
| @@ -33,6 +33,7 @@ | ||||
|  | ||||
| #include <cogl/cogl.h> | ||||
|  | ||||
| #include <clutter/clutter-config.h> | ||||
| #include <clutter/clutter-keymap.h> | ||||
| #include <clutter/clutter-types.h> | ||||
| #include <clutter/clutter-seat.h> | ||||
|   | ||||
| @@ -59,7 +59,7 @@ | ||||
| ClutterMargin * | ||||
| clutter_margin_new (void) | ||||
| { | ||||
|   return g_new0 (ClutterMargin, 1); | ||||
|   return g_slice_new0 (ClutterMargin); | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -77,7 +77,7 @@ ClutterMargin * | ||||
| clutter_margin_copy (const ClutterMargin *margin_) | ||||
| { | ||||
|   if (G_LIKELY (margin_ != NULL)) | ||||
|     return g_memdup2 (margin_, sizeof (ClutterMargin)); | ||||
|     return g_slice_dup (ClutterMargin, margin_); | ||||
|  | ||||
|   return NULL; | ||||
| } | ||||
| @@ -95,9 +95,198 @@ void | ||||
| clutter_margin_free (ClutterMargin *margin_) | ||||
| { | ||||
|   if (G_LIKELY (margin_ != NULL)) | ||||
|     g_free (margin_); | ||||
|     g_slice_free (ClutterMargin, margin_); | ||||
| } | ||||
|  | ||||
| G_DEFINE_BOXED_TYPE (ClutterMargin, clutter_margin, | ||||
|                      clutter_margin_copy, | ||||
|                      clutter_margin_free) | ||||
|  | ||||
| /** | ||||
|  * ClutterMatrix: | ||||
|  * | ||||
|  * A type representing a 4x4 matrix. | ||||
|  * | ||||
|  * It is identicaly to #CoglMatrix. | ||||
|  * | ||||
|  * Since: 1.12 | ||||
|  */ | ||||
|  | ||||
| static gpointer | ||||
| clutter_matrix_copy (gpointer data) | ||||
| { | ||||
|   return cogl_matrix_copy (data); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| clutter_matrix_progress (const GValue *a, | ||||
|                          const GValue *b, | ||||
|                          gdouble       progress, | ||||
|                          GValue       *retval) | ||||
| { | ||||
|   const ClutterMatrix *matrix1 = g_value_get_boxed (a); | ||||
|   const ClutterMatrix *matrix2 = g_value_get_boxed (b); | ||||
|   graphene_point3d_t scale1 = GRAPHENE_POINT3D_INIT (1.f, 1.f, 1.f); | ||||
|   float shear1[3] = { 0.f, 0.f, 0.f }; | ||||
|   graphene_point3d_t rotate1 = GRAPHENE_POINT3D_INIT_ZERO; | ||||
|   graphene_point3d_t translate1 = GRAPHENE_POINT3D_INIT_ZERO; | ||||
|   ClutterVertex4 perspective1 = { 0.f, 0.f, 0.f, 0.f }; | ||||
|   graphene_point3d_t scale2 = GRAPHENE_POINT3D_INIT (1.f, 1.f, 1.f); | ||||
|   float shear2[3] = { 0.f, 0.f, 0.f }; | ||||
|   graphene_point3d_t rotate2 = GRAPHENE_POINT3D_INIT_ZERO; | ||||
|   graphene_point3d_t translate2 = GRAPHENE_POINT3D_INIT_ZERO; | ||||
|   ClutterVertex4 perspective2 = { 0.f, 0.f, 0.f, 0.f }; | ||||
|   graphene_point3d_t scale_res = GRAPHENE_POINT3D_INIT (1.f, 1.f, 1.f); | ||||
|   float shear_res = 0.f; | ||||
|   graphene_point3d_t rotate_res = GRAPHENE_POINT3D_INIT_ZERO; | ||||
|   graphene_point3d_t translate_res = GRAPHENE_POINT3D_INIT_ZERO; | ||||
|   ClutterVertex4 perspective_res = { 0.f, 0.f, 0.f, 0.f }; | ||||
|   ClutterMatrix res; | ||||
|  | ||||
|   clutter_matrix_init_identity (&res); | ||||
|  | ||||
|   _clutter_util_matrix_decompose (matrix1, | ||||
|                                   &scale1, shear1, &rotate1, &translate1, | ||||
|                                   &perspective1); | ||||
|   _clutter_util_matrix_decompose (matrix2, | ||||
|                                   &scale2, shear2, &rotate2, &translate2, | ||||
|                                   &perspective2); | ||||
|  | ||||
|   /* perspective */ | ||||
|   _clutter_util_vertex4_interpolate (&perspective1, &perspective2, progress, &perspective_res); | ||||
|   res.wx = perspective_res.x; | ||||
|   res.wy = perspective_res.y; | ||||
|   res.wz = perspective_res.z; | ||||
|   res.ww = perspective_res.w; | ||||
|  | ||||
|   /* translation */ | ||||
|   graphene_point3d_interpolate (&translate1, &translate2, progress, &translate_res); | ||||
|   cogl_matrix_translate (&res, translate_res.x, translate_res.y, translate_res.z); | ||||
|  | ||||
|   /* rotation */ | ||||
|   graphene_point3d_interpolate (&rotate1, &rotate2, progress, &rotate_res); | ||||
|   cogl_matrix_rotate (&res, rotate_res.x, 1.0f, 0.0f, 0.0f); | ||||
|   cogl_matrix_rotate (&res, rotate_res.y, 0.0f, 1.0f, 0.0f); | ||||
|   cogl_matrix_rotate (&res, rotate_res.z, 0.0f, 0.0f, 1.0f); | ||||
|  | ||||
|   /* skew */ | ||||
|   shear_res = shear1[2] + (shear2[2] - shear1[2]) * progress; /* YZ */ | ||||
|   if (shear_res != 0.f) | ||||
|     _clutter_util_matrix_skew_yz (&res, shear_res); | ||||
|  | ||||
|   shear_res = shear1[1] + (shear2[1] - shear1[1]) * progress; /* XZ */ | ||||
|   if (shear_res != 0.f) | ||||
|     _clutter_util_matrix_skew_xz (&res, shear_res); | ||||
|  | ||||
|   shear_res = shear1[0] + (shear2[0] - shear1[0]) * progress; /* XY */ | ||||
|   if (shear_res != 0.f) | ||||
|     _clutter_util_matrix_skew_xy (&res, shear_res); | ||||
|  | ||||
|   /* scale */ | ||||
|   graphene_point3d_interpolate (&scale1, &scale2, progress, &scale_res); | ||||
|   cogl_matrix_scale (&res, scale_res.x, scale_res.y, scale_res.z); | ||||
|  | ||||
|   g_value_set_boxed (retval, &res); | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterMatrix, clutter_matrix, | ||||
|                                clutter_matrix_copy, | ||||
|                                clutter_matrix_free, | ||||
|                                CLUTTER_REGISTER_INTERVAL_PROGRESS (clutter_matrix_progress)) | ||||
|  | ||||
| /** | ||||
|  * clutter_matrix_alloc: | ||||
|  * | ||||
|  * Allocates enough memory to hold a #ClutterMatrix. | ||||
|  * | ||||
|  * Return value: (transfer full): the newly allocated #ClutterMatrix | ||||
|  * | ||||
|  * Since: 1.12 | ||||
|  */ | ||||
| ClutterMatrix * | ||||
| clutter_matrix_alloc (void) | ||||
| { | ||||
|   return g_new0 (ClutterMatrix, 1); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_matrix_free: | ||||
|  * @matrix: (allow-none): a #ClutterMatrix | ||||
|  * | ||||
|  * Frees the memory allocated by clutter_matrix_alloc(). | ||||
|  * | ||||
|  * Since: 1.12 | ||||
|  */ | ||||
| void | ||||
| clutter_matrix_free (ClutterMatrix *matrix) | ||||
| { | ||||
|   cogl_matrix_free (matrix); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_matrix_init_identity: | ||||
|  * @matrix: a #ClutterMatrix | ||||
|  * | ||||
|  * Initializes @matrix with the identity matrix, i.e.: | ||||
|  * | ||||
|  * |[ | ||||
|  *   .xx = 1.0, .xy = 0.0, .xz = 0.0, .xw = 0.0 | ||||
|  *   .yx = 0.0, .yy = 1.0, .yz = 0.0, .yw = 0.0 | ||||
|  *   .zx = 0.0, .zy = 0.0, .zz = 1.0, .zw = 0.0 | ||||
|  *   .wx = 0.0, .wy = 0.0, .wz = 0.0, .ww = 1.0 | ||||
|  * ]| | ||||
|  * | ||||
|  * Return value: (transfer none): the initialized #ClutterMatrix | ||||
|  * | ||||
|  * Since: 1.12 | ||||
|  */ | ||||
| ClutterMatrix * | ||||
| clutter_matrix_init_identity (ClutterMatrix *matrix) | ||||
| { | ||||
|   cogl_matrix_init_identity (matrix); | ||||
|  | ||||
|   return matrix; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_matrix_init_from_array: | ||||
|  * @matrix: a #ClutterMatrix | ||||
|  * @values: (array fixed-size=16): a C array of 16 floating point values, | ||||
|  *   representing a 4x4 matrix, with column-major order | ||||
|  * | ||||
|  * Initializes @matrix with the contents of a C array of floating point | ||||
|  * values. | ||||
|  * | ||||
|  * Return value: (transfer none): the initialzed #ClutterMatrix | ||||
|  * | ||||
|  * Since: 1.12 | ||||
|  */ | ||||
| ClutterMatrix * | ||||
| clutter_matrix_init_from_array (ClutterMatrix *matrix, | ||||
|                                 const float    values[16]) | ||||
| { | ||||
|   cogl_matrix_init_from_array (matrix, values); | ||||
|  | ||||
|   return matrix; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_matrix_init_from_matrix: | ||||
|  * @a: the #ClutterMatrix to initialize | ||||
|  * @b: the #ClutterMatrix to copy | ||||
|  * | ||||
|  * Initializes the #ClutterMatrix @a with the contents of the | ||||
|  * #ClutterMatrix @b. | ||||
|  * | ||||
|  * Return value: (transfer none): the initialized #ClutterMatrix | ||||
|  * | ||||
|  * Since: 1.12 | ||||
|  */ | ||||
| ClutterMatrix * | ||||
| clutter_matrix_init_from_matrix (ClutterMatrix       *a, | ||||
|                                  const ClutterMatrix *b) | ||||
| { | ||||
|   return memcpy (a, b, sizeof (ClutterMatrix)); | ||||
| } | ||||
|   | ||||
| @@ -35,7 +35,7 @@ | ||||
| #undef CBZ_L2T_INTERPOLATION | ||||
|  | ||||
| /**************************************************************************** | ||||
|  * ClutterBezier -- representation of a cubic bezier curve                   * | ||||
|  * ClutterBezier -- represenation of a cubic bezier curve                   * | ||||
|  * (private; a building block for the public bspline object)                * | ||||
|  ****************************************************************************/ | ||||
|  | ||||
| @@ -104,7 +104,7 @@ struct _ClutterBezier | ||||
| ClutterBezier * | ||||
| _clutter_bezier_new (void) | ||||
| { | ||||
|   return g_new0 (ClutterBezier, 1); | ||||
|   return g_slice_new0 (ClutterBezier); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -112,7 +112,7 @@ _clutter_bezier_free (ClutterBezier * b) | ||||
| { | ||||
|   if (G_LIKELY (b)) | ||||
|     { | ||||
|       g_free (b); | ||||
|       g_slice_free (ClutterBezier, b); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -213,7 +213,7 @@ sqrti (int number) | ||||
|      * algorithm does not calculate the square root, but its reciprocal ('y' | ||||
|      * below), which is only at the end turned to the inverse value. In order | ||||
|      * for the algorithm to produce satisfactory results, the reciprocal value | ||||
|      * must be represented with sufficient precision; the 16.16 we use | ||||
|      * must be represented with sufficient precission; the 16.16 we use | ||||
|      * elsewhere in clutter is not good enough, and 10.22 is used instead. | ||||
|      */ | ||||
|     _FixedT x; | ||||
| @@ -236,7 +236,7 @@ sqrti (int number) | ||||
|     /* Now, we convert the float to 10.22 fixed. We exploit the mechanism | ||||
|      * described at http://www.d6.com/users/checker/pdfs/gdmfp.pdf. | ||||
|      * | ||||
|      * We want 22 bit fraction; a single precision float uses 23 bit | ||||
|      * We want 22 bit fraction; a single precission float uses 23 bit | ||||
|      * mantisa, so we only need to add 2^(23-22) (no need for the 1.5 | ||||
|      * multiplier as we are only dealing with positive numbers). | ||||
|      * | ||||
| @@ -256,7 +256,7 @@ sqrti (int number) | ||||
|     flt2.i = (flt2.i >> 11) * (y_1 >> 11); | ||||
|  | ||||
|     /* If the original argument is less than 342, we do another | ||||
|      * iteration to improve precision (for arguments >= 342, the single | ||||
|      * iteration to improve precission (for arguments >= 342, the single | ||||
|      * iteration produces generally better results). | ||||
|      */ | ||||
|     if (x < 171) | ||||
|   | ||||
| @@ -406,7 +406,8 @@ get_actor_align_factor (ClutterActorAlign alignment) | ||||
| static void | ||||
| clutter_bin_layout_allocate (ClutterLayoutManager   *manager, | ||||
|                              ClutterContainer       *container, | ||||
|                              const ClutterActorBox  *allocation) | ||||
|                              const ClutterActorBox  *allocation, | ||||
|                              ClutterAllocationFlags  flags) | ||||
| { | ||||
|   gfloat allocation_x, allocation_y; | ||||
|   gfloat available_w, available_h; | ||||
| @@ -514,7 +515,8 @@ clutter_bin_layout_allocate (ClutterLayoutManager   *manager, | ||||
|  | ||||
|       clutter_actor_allocate_align_fill (child, &child_alloc, | ||||
|                                          x_align, y_align, | ||||
|                                          x_fill, y_fill); | ||||
|                                          x_fill, y_fill, | ||||
|                                          flags); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -38,14 +38,12 @@ | ||||
|  * | ||||
|  * |[<!-- language="C" --> | ||||
|  * // source | ||||
|  * rect[0] = clutter_actor_new (); | ||||
|  * clutter_actor_set_background_color (rect[0], &red_color); | ||||
|  * rect[0] = clutter_rectangle_new_with_color (&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); | ||||
|  * rect[1] = clutter_rectangle_new_with_color (&green_color); | ||||
|  * clutter_actor_set_size (rect[1], 100, 100); | ||||
|  * clutter_actor_set_opacity (rect[1], 0); | ||||
|  * | ||||
| @@ -55,8 +53,7 @@ | ||||
|  * 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); | ||||
|  * rect[2] = clutter_rectangle_new_with_color (&blue_color); | ||||
|  * clutter_actor_set_size (rect[2], 100, 100); | ||||
|  * clutter_actor_set_opacity (rect[2], 0); | ||||
|  * | ||||
| @@ -168,9 +165,6 @@ clutter_bind_constraint_update_preferred_size (ClutterConstraint  *constraint, | ||||
|         bind->coordinate == CLUTTER_BIND_ALL)) | ||||
|     return; | ||||
|  | ||||
|   if (clutter_actor_contains (bind->source, actor)) | ||||
|     return; | ||||
|  | ||||
|   switch (direction) | ||||
|     { | ||||
|     case CLUTTER_ORIENTATION_HORIZONTAL: | ||||
|   | ||||
| @@ -189,7 +189,7 @@ binding_entry_new (const gchar         *name, | ||||
|  | ||||
|   modifiers = modifiers & BINDING_MOD_MASK; | ||||
|  | ||||
|   entry = g_new0 (ClutterBindingEntry, 1); | ||||
|   entry = g_slice_new (ClutterBindingEntry); | ||||
|   entry->key_val = key_val; | ||||
|   entry->modifiers = modifiers; | ||||
|   entry->name = (gchar *) g_intern_string (name); | ||||
| @@ -221,7 +221,7 @@ binding_entry_free (gpointer data) | ||||
|  | ||||
|       g_closure_unref (entry->closure); | ||||
|  | ||||
|       g_free (entry); | ||||
|       g_slice_free (ClutterBindingEntry, entry); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -39,6 +39,8 @@ | ||||
|  | ||||
| #include "clutter-build-config.h" | ||||
|  | ||||
| #define CLUTTER_ENABLE_EXPERIMENTAL_API | ||||
|  | ||||
| #include "clutter-blur-effect.h" | ||||
|  | ||||
| #include "cogl/cogl.h" | ||||
| @@ -79,6 +81,9 @@ struct _ClutterBlurEffect | ||||
|  | ||||
|   gint pixel_step_uniform; | ||||
|  | ||||
|   gint tex_width; | ||||
|   gint tex_height; | ||||
|  | ||||
|   CoglPipeline *pipeline; | ||||
| }; | ||||
|  | ||||
| @@ -93,42 +98,20 @@ G_DEFINE_TYPE (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); | ||||
|  | ||||
|   if (blur_effect->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 (blur_effect->pipeline, | ||||
|                                        blur_effect->pixel_step_uniform, | ||||
|                                        2, /* n_components */ | ||||
|                                        1, /* count */ | ||||
|                                        pixel_step); | ||||
|     } | ||||
|  | ||||
|   cogl_pipeline_set_layer_texture (blur_effect->pipeline, 0, texture); | ||||
|  | ||||
|   return cogl_object_ref (blur_effect->pipeline); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| clutter_blur_effect_pre_paint (ClutterEffect       *effect, | ||||
|                                ClutterPaintNode    *node, | ||||
|                                ClutterPaintContext *paint_context) | ||||
| { | ||||
|   ClutterBlurEffect *self = CLUTTER_BLUR_EFFECT (effect); | ||||
|   ClutterEffectClass *parent_class; | ||||
|  | ||||
|   if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect))) | ||||
|     return FALSE; | ||||
|  | ||||
|   self->actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect)); | ||||
|   if (self->actor == NULL) | ||||
|     return FALSE; | ||||
|  | ||||
|   if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL)) | ||||
|     { | ||||
|       /* if we don't have support for GLSL shaders then we | ||||
| @@ -142,7 +125,59 @@ clutter_blur_effect_pre_paint (ClutterEffect       *effect, | ||||
|     } | ||||
|  | ||||
|   parent_class = CLUTTER_EFFECT_CLASS (clutter_blur_effect_parent_class); | ||||
|   return parent_class->pre_paint (effect, node, paint_context); | ||||
|   if (parent_class->pre_paint (effect, paint_context)) | ||||
|     { | ||||
|       ClutterOffscreenEffect *offscreen_effect = | ||||
|         CLUTTER_OFFSCREEN_EFFECT (effect); | ||||
|       CoglHandle texture; | ||||
|  | ||||
|       texture = clutter_offscreen_effect_get_texture (offscreen_effect); | ||||
|       self->tex_width = cogl_texture_get_width (texture); | ||||
|       self->tex_height = cogl_texture_get_height (texture); | ||||
|  | ||||
|       if (self->pixel_step_uniform > -1) | ||||
|         { | ||||
|           gfloat pixel_step[2]; | ||||
|  | ||||
|           pixel_step[0] = 1.0f / self->tex_width; | ||||
|           pixel_step[1] = 1.0f / self->tex_height; | ||||
|  | ||||
|           cogl_pipeline_set_uniform_float (self->pipeline, | ||||
|                                            self->pixel_step_uniform, | ||||
|                                            2, /* n_components */ | ||||
|                                            1, /* count */ | ||||
|                                            pixel_step); | ||||
|         } | ||||
|  | ||||
|       cogl_pipeline_set_layer_texture (self->pipeline, 0, texture); | ||||
|  | ||||
|       return TRUE; | ||||
|     } | ||||
|   else | ||||
|     return FALSE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_blur_effect_paint_target (ClutterOffscreenEffect *effect, | ||||
|                                   ClutterPaintContext    *paint_context) | ||||
| { | ||||
|   ClutterBlurEffect *self = CLUTTER_BLUR_EFFECT (effect); | ||||
|   CoglFramebuffer *framebuffer = | ||||
|     clutter_paint_context_get_framebuffer (paint_context); | ||||
|   guint8 paint_opacity; | ||||
|  | ||||
|   paint_opacity = clutter_actor_get_paint_opacity (self->actor); | ||||
|  | ||||
|   cogl_pipeline_set_color4ub (self->pipeline, | ||||
|                               paint_opacity, | ||||
|                               paint_opacity, | ||||
|                               paint_opacity, | ||||
|                               paint_opacity); | ||||
|  | ||||
|   cogl_framebuffer_draw_rectangle (framebuffer, | ||||
|                                    self->pipeline, | ||||
|                                    0, 0, | ||||
|                                    self->tex_width, self->tex_height); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| @@ -194,7 +229,7 @@ clutter_blur_effect_class_init (ClutterBlurEffectClass *klass) | ||||
|   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; | ||||
|   offscreen_class->paint_target = clutter_blur_effect_paint_target; | ||||
| } | ||||
|  | ||||
| static void | ||||
|   | ||||
| @@ -1,40 +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/>. | ||||
|  */ | ||||
|  | ||||
| #ifndef CLUTTER_BLUR_PRIVATE_H | ||||
| #define CLUTTER_BLUR_PRIVATE_H | ||||
|  | ||||
| #include <glib-object.h> | ||||
|  | ||||
| #include <cogl/cogl.h> | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| typedef struct _ClutterBlur ClutterBlur; | ||||
|  | ||||
| ClutterBlur * clutter_blur_new (CoglTexture *texture, | ||||
|                                 float        sigma); | ||||
|  | ||||
| void clutter_blur_apply (ClutterBlur *blur); | ||||
|  | ||||
| CoglTexture * clutter_blur_get_texture (ClutterBlur *blur); | ||||
|  | ||||
| void clutter_blur_free (ClutterBlur *blur); | ||||
|  | ||||
| G_END_DECLS | ||||
|  | ||||
| #endif /* CLUTTER_BLUR_PRIVATE_H */ | ||||
| @@ -1,431 +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 "clutter-blur-private.h" | ||||
|  | ||||
| #include "clutter-backend.h" | ||||
|  | ||||
| /** | ||||
|  * SECTION:clutter-blur | ||||
|  * @short_description: 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); | ||||
|       cogl_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_pointer (&pass->texture, cogl_object_unref); | ||||
|   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 (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_4ub (&transparent, 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_pointer (&pass->pipeline, cogl_object_unref); | ||||
|   g_clear_pointer (&pass->texture, cogl_object_unref); | ||||
|   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        sigma) | ||||
| { | ||||
|   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 (sigma >= 0.0, NULL); | ||||
|  | ||||
|   width = cogl_texture_get_width (texture); | ||||
|   height = cogl_texture_get_height (texture); | ||||
|  | ||||
|   blur = g_new0 (ClutterBlur, 1); | ||||
|   blur->sigma = sigma; | ||||
|   blur->source_texture = cogl_object_ref (texture); | ||||
|   blur->downscale_factor = calculate_downscale_factor (width, height, sigma); | ||||
|  | ||||
|   if (G_APPROX_VALUE (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 | ||||
|  * 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 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]); | ||||
|   cogl_clear_object (&blur->source_texture); | ||||
|   g_free (blur); | ||||
| } | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -105,6 +105,64 @@ void                    clutter_box_layout_set_pack_start       (ClutterBoxLayou | ||||
| CLUTTER_EXPORT | ||||
| gboolean                clutter_box_layout_get_pack_start       (ClutterBoxLayout    *layout); | ||||
|  | ||||
| CLUTTER_DEPRECATED_FOR(clutter_box_layout_set_orientation) | ||||
| void                    clutter_box_layout_set_vertical         (ClutterBoxLayout    *layout, | ||||
|                                                                  gboolean             vertical); | ||||
| CLUTTER_DEPRECATED_FOR(clutter_box_layout_get_orientation) | ||||
| gboolean                clutter_box_layout_get_vertical         (ClutterBoxLayout    *layout); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void                    clutter_box_layout_pack                 (ClutterBoxLayout    *layout, | ||||
|                                                                  ClutterActor        *actor, | ||||
|                                                                  gboolean             expand, | ||||
|                                                                  gboolean             x_fill, | ||||
|                                                                  gboolean             y_fill, | ||||
|                                                                  ClutterBoxAlignment  x_align, | ||||
|                                                                  ClutterBoxAlignment  y_align); | ||||
| CLUTTER_DEPRECATED | ||||
| void                    clutter_box_layout_set_alignment        (ClutterBoxLayout    *layout, | ||||
|                                                                  ClutterActor        *actor, | ||||
|                                                                  ClutterBoxAlignment  x_align, | ||||
|                                                                  ClutterBoxAlignment  y_align); | ||||
| CLUTTER_DEPRECATED | ||||
| void                    clutter_box_layout_get_alignment        (ClutterBoxLayout    *layout, | ||||
|                                                                  ClutterActor        *actor, | ||||
|                                                                  ClutterBoxAlignment *x_align, | ||||
|                                                                  ClutterBoxAlignment *y_align); | ||||
| CLUTTER_DEPRECATED | ||||
| void                    clutter_box_layout_set_fill             (ClutterBoxLayout    *layout, | ||||
|                                                                  ClutterActor        *actor, | ||||
|                                                                  gboolean             x_fill, | ||||
|                                                                  gboolean             y_fill); | ||||
| CLUTTER_DEPRECATED | ||||
| void                    clutter_box_layout_get_fill             (ClutterBoxLayout    *layout, | ||||
|                                                                  ClutterActor        *actor, | ||||
|                                                                  gboolean            *x_fill, | ||||
|                                                                  gboolean            *y_fill); | ||||
| CLUTTER_DEPRECATED | ||||
| void                    clutter_box_layout_set_expand           (ClutterBoxLayout    *layout, | ||||
|                                                                  ClutterActor        *actor, | ||||
|                                                                  gboolean             expand); | ||||
| CLUTTER_DEPRECATED | ||||
| gboolean                clutter_box_layout_get_expand           (ClutterBoxLayout    *layout, | ||||
|                                                                  ClutterActor        *actor); | ||||
|  | ||||
| CLUTTER_DEPRECATED | ||||
| void                    clutter_box_layout_set_use_animations   (ClutterBoxLayout    *layout, | ||||
|                                                                  gboolean             animate); | ||||
| CLUTTER_DEPRECATED | ||||
| gboolean                clutter_box_layout_get_use_animations   (ClutterBoxLayout    *layout); | ||||
| CLUTTER_DEPRECATED | ||||
| void                    clutter_box_layout_set_easing_mode      (ClutterBoxLayout    *layout, | ||||
|                                                                  gulong               mode); | ||||
| CLUTTER_DEPRECATED | ||||
| gulong                  clutter_box_layout_get_easing_mode      (ClutterBoxLayout    *layout); | ||||
| CLUTTER_DEPRECATED | ||||
| void                    clutter_box_layout_set_easing_duration  (ClutterBoxLayout    *layout, | ||||
|                                                                  guint                msecs); | ||||
| CLUTTER_DEPRECATED | ||||
| guint                   clutter_box_layout_get_easing_duration  (ClutterBoxLayout    *layout); | ||||
|  | ||||
| G_END_DECLS | ||||
|  | ||||
| #endif /* __CLUTTER_BOX_LAYOUT_H__ */ | ||||
|   | ||||
| @@ -41,6 +41,8 @@ | ||||
|  | ||||
| #include <math.h> | ||||
|  | ||||
| #define CLUTTER_ENABLE_EXPERIMENTAL_API | ||||
|  | ||||
| #include "clutter-brightness-contrast-effect.h" | ||||
|  | ||||
| #include <cogl/cogl.h> | ||||
| @@ -67,6 +69,9 @@ struct _ClutterBrightnessContrastEffect | ||||
|   gint brightness_offset_uniform; | ||||
|   gint contrast_uniform; | ||||
|  | ||||
|   gint tex_width; | ||||
|   gint tex_height; | ||||
|  | ||||
|   CoglPipeline *pipeline; | ||||
| }; | ||||
|  | ||||
| @@ -124,26 +129,16 @@ will_have_no_effect (ClutterBrightnessContrastEffect *self) | ||||
|           G_APPROX_VALUE (self->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); | ||||
|  | ||||
|   cogl_pipeline_set_layer_texture (self->pipeline, 0, texture); | ||||
|  | ||||
|   return cogl_object_ref (self->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 (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect))) | ||||
|     return FALSE; | ||||
|  | ||||
|   if (will_have_no_effect (self)) | ||||
|     return FALSE; | ||||
|  | ||||
| @@ -162,8 +157,47 @@ clutter_brightness_contrast_effect_pre_paint (ClutterEffect       *effect, | ||||
|  | ||||
|   parent_class = | ||||
|     CLUTTER_EFFECT_CLASS (clutter_brightness_contrast_effect_parent_class); | ||||
|   if (parent_class->pre_paint (effect, paint_context)) | ||||
|     { | ||||
|       ClutterOffscreenEffect *offscreen_effect = | ||||
|         CLUTTER_OFFSCREEN_EFFECT (effect); | ||||
|       CoglHandle texture; | ||||
|  | ||||
|   return parent_class->pre_paint (effect, node, paint_context); | ||||
|       texture = clutter_offscreen_effect_get_texture (offscreen_effect); | ||||
|       self->tex_width = cogl_texture_get_width (texture); | ||||
|       self->tex_height = cogl_texture_get_height (texture); | ||||
|  | ||||
|       cogl_pipeline_set_layer_texture (self->pipeline, 0, texture); | ||||
|  | ||||
|       return TRUE; | ||||
|     } | ||||
|   else | ||||
|     return FALSE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_brightness_contrast_effect_paint_target (ClutterOffscreenEffect *effect, | ||||
|                                                  ClutterPaintContext    *paint_context) | ||||
| { | ||||
|   ClutterBrightnessContrastEffect *self = CLUTTER_BRIGHTNESS_CONTRAST_EFFECT (effect); | ||||
|   CoglFramebuffer *framebuffer = | ||||
|    clutter_paint_context_get_framebuffer (paint_context); | ||||
|   ClutterActor *actor; | ||||
|   guint8 paint_opacity; | ||||
|  | ||||
|   actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect)); | ||||
|   paint_opacity = clutter_actor_get_paint_opacity (actor); | ||||
|  | ||||
|   cogl_pipeline_set_color4ub (self->pipeline, | ||||
|                               paint_opacity, | ||||
|                               paint_opacity, | ||||
|                               paint_opacity, | ||||
|                               paint_opacity); | ||||
|  | ||||
|   cogl_framebuffer_draw_rectangle (framebuffer, | ||||
|                                    self->pipeline, | ||||
|                                    0, 0, | ||||
|                                    self->tex_width, self->tex_height); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -263,7 +297,7 @@ clutter_brightness_contrast_effect_class_init (ClutterBrightnessContrastEffectCl | ||||
|   ClutterOffscreenEffectClass *offscreen_class; | ||||
|  | ||||
|   offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass); | ||||
|   offscreen_class->create_pipeline = clutter_brightness_contrast_effect_create_pipeline; | ||||
|   offscreen_class->paint_target = clutter_brightness_contrast_effect_paint_target; | ||||
|  | ||||
|   effect_class->pre_paint = clutter_brightness_contrast_effect_pre_paint; | ||||
|  | ||||
|   | ||||
| @@ -4,5 +4,11 @@ | ||||
| /* List of Cogl drivers */ | ||||
| #mesondefine CLUTTER_DRIVERS | ||||
|  | ||||
| /* Have evdev support for input handling */ | ||||
| #mesondefine HAVE_EVDEV | ||||
|  | ||||
| /* Building with libwacom for advanced tablet management */ | ||||
| #mesondefine HAVE_LIBWACOM | ||||
|  | ||||
| /* Supports PangoFt2 */ | ||||
| #mesondefine HAVE_PANGO_FT2 | ||||
|   | ||||
| @@ -50,6 +50,8 @@ | ||||
|  | ||||
| #include "clutter-canvas.h" | ||||
|  | ||||
| #define CLUTTER_ENABLE_EXPERIMENTAL_API | ||||
|  | ||||
| #include "clutter-actor-private.h" | ||||
| #include "clutter-backend.h" | ||||
| #include "clutter-cairo.h" | ||||
|   | ||||
| @@ -105,6 +105,8 @@ struct _ClutterClickActionPrivate | ||||
| { | ||||
|   ClutterActor *stage; | ||||
|  | ||||
|   gulong event_id; | ||||
|   gulong capture_id; | ||||
|   guint long_press_id; | ||||
|  | ||||
|   gint long_press_threshold; | ||||
| @@ -112,7 +114,7 @@ struct _ClutterClickActionPrivate | ||||
|   gint drag_threshold; | ||||
|  | ||||
|   guint press_button; | ||||
|   ClutterInputDevice *press_device; | ||||
|   gint press_device_id; | ||||
|   ClutterEventSequence *press_sequence; | ||||
|   ClutterModifierType modifier_state; | ||||
|   gfloat press_x; | ||||
| @@ -148,12 +150,16 @@ static guint click_signals[LAST_SIGNAL] = { 0, }; | ||||
|  | ||||
| G_DEFINE_TYPE_WITH_PRIVATE (ClutterClickAction, clutter_click_action, CLUTTER_TYPE_ACTION) | ||||
|  | ||||
| /* forward declaration */ | ||||
| static gboolean on_captured_event (ClutterActor       *stage, | ||||
|                                    ClutterEvent       *event, | ||||
|                                    ClutterClickAction *action); | ||||
|  | ||||
| static inline void | ||||
| click_action_set_pressed (ClutterClickAction *action, | ||||
|                           gboolean            is_pressed) | ||||
| { | ||||
|   ClutterClickActionPrivate *priv = | ||||
|     clutter_click_action_get_instance_private (action); | ||||
|   ClutterClickActionPrivate *priv = action->priv; | ||||
|  | ||||
|   is_pressed = !!is_pressed; | ||||
|  | ||||
| @@ -168,8 +174,7 @@ static inline void | ||||
| click_action_set_held (ClutterClickAction *action, | ||||
|                        gboolean            is_held) | ||||
| { | ||||
|   ClutterClickActionPrivate *priv = | ||||
|     clutter_click_action_get_instance_private (action); | ||||
|   ClutterClickActionPrivate *priv = action->priv; | ||||
|  | ||||
|   is_held = !!is_held; | ||||
|  | ||||
| @@ -184,8 +189,7 @@ static gboolean | ||||
| click_action_emit_long_press (gpointer data) | ||||
| { | ||||
|   ClutterClickAction *action = data; | ||||
|   ClutterClickActionPrivate *priv = | ||||
|     clutter_click_action_get_instance_private (action); | ||||
|   ClutterClickActionPrivate *priv = action->priv; | ||||
|   ClutterActor *actor; | ||||
|   gboolean result; | ||||
|  | ||||
| @@ -198,6 +202,8 @@ click_action_emit_long_press (gpointer data) | ||||
|                  CLUTTER_LONG_PRESS_ACTIVATE, | ||||
|                  &result); | ||||
|  | ||||
|   g_clear_signal_handler (&priv->capture_id, priv->stage); | ||||
|  | ||||
|   click_action_set_pressed (action, FALSE); | ||||
|   click_action_set_held (action, FALSE); | ||||
|  | ||||
| @@ -207,8 +213,7 @@ click_action_emit_long_press (gpointer data) | ||||
| static inline void | ||||
| click_action_query_long_press (ClutterClickAction *action) | ||||
| { | ||||
|   ClutterClickActionPrivate *priv = | ||||
|     clutter_click_action_get_instance_private (action); | ||||
|   ClutterClickActionPrivate *priv = action->priv; | ||||
|   ClutterActor *actor; | ||||
|   gboolean result = FALSE; | ||||
|   gint timeout; | ||||
| @@ -233,7 +238,6 @@ click_action_query_long_press (ClutterClickAction *action) | ||||
|  | ||||
|   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, | ||||
| @@ -244,8 +248,7 @@ click_action_query_long_press (ClutterClickAction *action) | ||||
| static inline void | ||||
| click_action_cancel_long_press (ClutterClickAction *action) | ||||
| { | ||||
|   ClutterClickActionPrivate *priv = | ||||
|     clutter_click_action_get_instance_private (action); | ||||
|   ClutterClickActionPrivate *priv = action->priv; | ||||
|  | ||||
|   if (priv->long_press_id != 0) | ||||
|     { | ||||
| @@ -263,51 +266,25 @@ click_action_cancel_long_press (ClutterClickAction *action) | ||||
|     } | ||||
| } | ||||
|  | ||||
| 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) | ||||
| on_event (ClutterActor       *actor, | ||||
|           ClutterEvent       *event, | ||||
|           ClutterClickAction *action) | ||||
| { | ||||
|   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)); | ||||
|   ClutterClickActionPrivate *priv = action->priv; | ||||
|   gboolean has_button = TRUE; | ||||
|   ClutterModifierType modifier_state; | ||||
|  | ||||
|   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; | ||||
|     case CLUTTER_BUTTON_PRESS: | ||||
|       if (has_button && clutter_event_get_click_count (event) != 1) | ||||
|         return CLUTTER_EVENT_PROPAGATE; | ||||
|  | ||||
|       if (priv->is_held) | ||||
|         return CLUTTER_EVENT_STOP; | ||||
|  | ||||
| @@ -315,7 +292,7 @@ clutter_click_action_handle_event (ClutterAction      *action, | ||||
|         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_device_id = clutter_event_get_device_id (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); | ||||
| @@ -334,22 +311,47 @@ clutter_click_action_handle_event (ClutterAction      *action, | ||||
|       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); | ||||
|       priv->capture_id = g_signal_connect_after (priv->stage, "captured-event", | ||||
|                                                  G_CALLBACK (on_captured_event), | ||||
|                                                  action); | ||||
|  | ||||
|       click_action_set_pressed (action, TRUE); | ||||
|       click_action_set_held (action, TRUE); | ||||
|       click_action_query_long_press (action); | ||||
|       break; | ||||
|  | ||||
|     case CLUTTER_ENTER: | ||||
|       click_action_set_pressed (click_action, priv->is_held); | ||||
|       click_action_set_pressed (action, priv->is_held); | ||||
|       break; | ||||
|  | ||||
|     case CLUTTER_LEAVE: | ||||
|       click_action_set_pressed (click_action, priv->is_held); | ||||
|       click_action_cancel_long_press (click_action); | ||||
|       click_action_set_pressed (action, priv->is_held); | ||||
|       click_action_cancel_long_press (action); | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|   return CLUTTER_EVENT_PROPAGATE; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| on_captured_event (ClutterActor       *stage, | ||||
|                    ClutterEvent       *event, | ||||
|                    ClutterClickAction *action) | ||||
| { | ||||
|   ClutterClickActionPrivate *priv = action->priv; | ||||
|   ClutterActor *actor; | ||||
|   ClutterModifierType modifier_state; | ||||
|   gboolean has_button = TRUE; | ||||
|  | ||||
|   actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action)); | ||||
|  | ||||
|   switch (clutter_event_type (event)) | ||||
|     { | ||||
|     case CLUTTER_TOUCH_CANCEL: | ||||
|       clutter_click_action_release (click_action); | ||||
|       clutter_click_action_release (action); | ||||
|       break; | ||||
|  | ||||
|     case CLUTTER_TOUCH_END: | ||||
| @@ -359,12 +361,16 @@ clutter_click_action_handle_event (ClutterAction      *action, | ||||
|         return CLUTTER_EVENT_STOP; | ||||
|  | ||||
|       if ((has_button && clutter_event_get_button (event) != priv->press_button) || | ||||
|           clutter_event_get_device (event) != priv->press_device || | ||||
|           (has_button && clutter_event_get_click_count (event) != 1) || | ||||
|           clutter_event_get_device_id (event) != priv->press_device_id || | ||||
|           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); | ||||
|       click_action_set_held (action, FALSE); | ||||
|       click_action_cancel_long_press (action); | ||||
|  | ||||
|       /* disconnect the capture */ | ||||
|       g_clear_signal_handler (&priv->capture_id, priv->stage); | ||||
|  | ||||
|       g_clear_handle_id (&priv->long_press_id, g_source_remove); | ||||
|  | ||||
| @@ -387,24 +393,31 @@ clutter_click_action_handle_event (ClutterAction      *action, | ||||
|       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); | ||||
|       click_action_set_pressed (action, FALSE); | ||||
|       g_signal_emit (action, click_signals[CLICKED], 0, actor); | ||||
|       break; | ||||
|  | ||||
|     case CLUTTER_MOTION: | ||||
|     case CLUTTER_TOUCH_UPDATE: | ||||
|       { | ||||
|         if (clutter_event_get_device (event) != priv->press_device || | ||||
|         gfloat motion_x, motion_y; | ||||
|         gfloat delta_x, delta_y; | ||||
|  | ||||
|         if (clutter_event_get_device_id (event) != priv->press_device_id || | ||||
|             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); | ||||
|         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); | ||||
|  | ||||
|         if (delta_x > priv->drag_threshold || | ||||
|             delta_y > priv->drag_threshold) | ||||
|           click_action_cancel_long_press (action); | ||||
|       } | ||||
|       break; | ||||
|  | ||||
| @@ -412,7 +425,7 @@ clutter_click_action_handle_event (ClutterAction      *action, | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|   return priv->is_held ? CLUTTER_EVENT_STOP : CLUTTER_EVENT_PROPAGATE; | ||||
|   return CLUTTER_EVENT_STOP; | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -420,39 +433,47 @@ clutter_click_action_set_actor (ClutterActorMeta *meta, | ||||
|                                 ClutterActor     *actor) | ||||
| { | ||||
|   ClutterClickAction *action = CLUTTER_CLICK_ACTION (meta); | ||||
|   ClutterClickActionPrivate *priv = | ||||
|     clutter_click_action_get_instance_private (action); | ||||
|   ClutterClickActionPrivate *priv = action->priv; | ||||
|  | ||||
|   if (priv->event_id != 0) | ||||
|     { | ||||
|       ClutterActor *old_actor = clutter_actor_meta_get_actor (meta); | ||||
|  | ||||
|       if (old_actor != NULL) | ||||
|         g_clear_signal_handler (&priv->event_id, old_actor); | ||||
|  | ||||
|       priv->event_id = 0; | ||||
|     } | ||||
|  | ||||
|   if (priv->capture_id != 0) | ||||
|     { | ||||
|       if (priv->stage != NULL) | ||||
|         g_clear_signal_handler (&priv->capture_id, priv->stage); | ||||
|  | ||||
|       priv->capture_id = 0; | ||||
|       priv->stage = NULL; | ||||
|     } | ||||
|  | ||||
|   g_clear_handle_id (&priv->long_press_id, g_source_remove); | ||||
|  | ||||
|   click_action_set_pressed (action, FALSE); | ||||
|   click_action_set_held (action, FALSE); | ||||
|  | ||||
|   if (actor != NULL) | ||||
|     priv->event_id = g_signal_connect (actor, "event", | ||||
|                                        G_CALLBACK (on_event), | ||||
|                                        action); | ||||
|  | ||||
|   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)); | ||||
|   ClutterClickActionPrivate *priv = CLUTTER_CLICK_ACTION (gobject)->priv; | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
| @@ -476,8 +497,7 @@ clutter_click_action_get_property (GObject    *gobject, | ||||
|                                    GValue     *value, | ||||
|                                    GParamSpec *pspec) | ||||
| { | ||||
|   ClutterClickActionPrivate *priv = | ||||
|     clutter_click_action_get_instance_private (CLUTTER_CLICK_ACTION (gobject)); | ||||
|   ClutterClickActionPrivate *priv = CLUTTER_CLICK_ACTION (gobject)->priv; | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
| @@ -506,25 +526,26 @@ clutter_click_action_get_property (GObject    *gobject, | ||||
| static void | ||||
| clutter_click_action_dispose (GObject *gobject) | ||||
| { | ||||
|   ClutterClickActionPrivate *priv = | ||||
|     clutter_click_action_get_instance_private (CLUTTER_CLICK_ACTION (gobject)); | ||||
|   ClutterClickActionPrivate *priv = CLUTTER_CLICK_ACTION (gobject)->priv; | ||||
|  | ||||
|   g_clear_signal_handler (&priv->event_id, | ||||
|                           clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (gobject))); | ||||
|  | ||||
|   g_clear_signal_handler (&priv->capture_id, priv->stage); | ||||
|  | ||||
|   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; | ||||
|  | ||||
|   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; | ||||
| @@ -662,11 +683,9 @@ clutter_click_action_class_init (ClutterClickActionClass *klass) | ||||
| 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; | ||||
|   self->priv = clutter_click_action_get_instance_private (self); | ||||
|   self->priv->long_press_threshold = -1; | ||||
|   self->priv->long_press_duration = -1; | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -706,11 +725,14 @@ clutter_click_action_release (ClutterClickAction *action) | ||||
|  | ||||
|   g_return_if_fail (CLUTTER_IS_CLICK_ACTION (action)); | ||||
|  | ||||
|   priv = clutter_click_action_get_instance_private (action); | ||||
|   priv = action->priv; | ||||
|  | ||||
|   if (!priv->is_held) | ||||
|     return; | ||||
|  | ||||
|   /* disconnect the capture */ | ||||
|   g_clear_signal_handler (&priv->capture_id, priv->stage); | ||||
|  | ||||
|   click_action_cancel_long_press (action); | ||||
|   click_action_set_held (action, FALSE); | ||||
|   click_action_set_pressed (action, FALSE); | ||||
| @@ -729,13 +751,9 @@ clutter_click_action_release (ClutterClickAction *action) | ||||
| guint | ||||
| clutter_click_action_get_button (ClutterClickAction *action) | ||||
| { | ||||
|   ClutterClickActionPrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_CLICK_ACTION (action), 0); | ||||
|  | ||||
|   priv = clutter_click_action_get_instance_private (action); | ||||
|  | ||||
|   return priv->press_button; | ||||
|   return action->priv->press_button; | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -751,13 +769,9 @@ clutter_click_action_get_button (ClutterClickAction *action) | ||||
| ClutterModifierType | ||||
| clutter_click_action_get_state (ClutterClickAction *action) | ||||
| { | ||||
|   ClutterClickActionPrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_CLICK_ACTION (action), 0); | ||||
|  | ||||
|   priv = clutter_click_action_get_instance_private (action); | ||||
|  | ||||
|   return priv->modifier_state; | ||||
|   return action->priv->modifier_state; | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -775,15 +789,11 @@ 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; | ||||
|     *press_x = action->priv->press_x; | ||||
|  | ||||
|   if (press_y != NULL) | ||||
|     *press_y = priv->press_y; | ||||
|     *press_y = action->priv->press_y; | ||||
| } | ||||
|   | ||||
| @@ -37,13 +37,32 @@ | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CLUTTER_TYPE_CLICK_ACTION (clutter_click_action_get_type ()) | ||||
| #define CLUTTER_TYPE_CLICK_ACTION               (clutter_click_action_get_type ()) | ||||
| #define CLUTTER_CLICK_ACTION(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_CLICK_ACTION, ClutterClickAction)) | ||||
| #define CLUTTER_IS_CLICK_ACTION(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_CLICK_ACTION)) | ||||
| #define CLUTTER_CLICK_ACTION_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_CLICK_ACTION, ClutterClickActionClass)) | ||||
| #define CLUTTER_IS_CLICK_ACTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_CLICK_ACTION)) | ||||
| #define CLUTTER_CLICK_ACTION_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_CLICK_ACTION, ClutterClickActionClass)) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_DERIVABLE_TYPE (ClutterClickAction, clutter_click_action, | ||||
|                           CLUTTER, CLICK_ACTION, ClutterAction); | ||||
| typedef struct _ClutterClickAction              ClutterClickAction; | ||||
| typedef struct _ClutterClickActionPrivate       ClutterClickActionPrivate; | ||||
| typedef struct _ClutterClickActionClass         ClutterClickActionClass; | ||||
|  | ||||
| typedef struct _ClutterClickActionPrivate ClutterClickActionPrivate; | ||||
| /** | ||||
|  * ClutterClickAction: | ||||
|  * | ||||
|  * The #ClutterClickAction structure contains | ||||
|  * only private data and should be accessed using the provided API | ||||
|  * | ||||
|  * Since: 1.4 | ||||
|  */ | ||||
| struct _ClutterClickAction | ||||
| { | ||||
|   /*< private >*/ | ||||
|   ClutterAction parent_instance; | ||||
|  | ||||
|   ClutterClickActionPrivate *priv; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * ClutterClickActionClass: | ||||
| @@ -78,6 +97,9 @@ struct _ClutterClickActionClass | ||||
|   void (* _clutter_click_action7) (void); | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| GType clutter_click_action_get_type (void) G_GNUC_CONST; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterAction *        clutter_click_action_new        (void); | ||||
|  | ||||
|   | ||||
| @@ -39,6 +39,7 @@ | ||||
|  | ||||
| #include "clutter-build-config.h" | ||||
|  | ||||
| #define CLUTTER_ENABLE_EXPERIMENTAL_API | ||||
| #include "clutter-actor-private.h" | ||||
| #include "clutter-clone.h" | ||||
| #include "clutter-debug.h" | ||||
| @@ -51,8 +52,6 @@ | ||||
| struct _ClutterClonePrivate | ||||
| { | ||||
|   ClutterActor *clone_source; | ||||
|   float x_scale, y_scale; | ||||
|  | ||||
|   gulong source_destroy_id; | ||||
| }; | ||||
|  | ||||
| @@ -120,17 +119,36 @@ clutter_clone_get_preferred_height (ClutterActor *self, | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_clone_apply_transform (ClutterActor      *self, | ||||
|                                graphene_matrix_t *matrix) | ||||
| clutter_clone_apply_transform (ClutterActor *self, CoglMatrix *matrix) | ||||
| { | ||||
|   ClutterClonePrivate *priv = CLUTTER_CLONE (self)->priv; | ||||
|   ClutterActorBox box, source_box; | ||||
|   gfloat x_scale, y_scale; | ||||
|  | ||||
|  | ||||
|   if (priv->clone_source) | ||||
|     graphene_matrix_scale (matrix, priv->x_scale, priv->y_scale, 1.f); | ||||
|  | ||||
|   /* First chain up and apply all the standard ClutterActor | ||||
|    * transformations... */ | ||||
|   CLUTTER_ACTOR_CLASS (clutter_clone_parent_class)->apply_transform (self, | ||||
|                                                                      matrix); | ||||
|  | ||||
|   /* if we don't have a source, nothing else to do */ | ||||
|   if (priv->clone_source == NULL) | ||||
|     return; | ||||
|  | ||||
|   /* get our allocated size */ | ||||
|   clutter_actor_get_allocation_box (self, &box); | ||||
|  | ||||
|   /* and get the allocated size of the source */ | ||||
|   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); | ||||
|  | ||||
|   cogl_matrix_scale (matrix, x_scale, y_scale, x_scale); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -195,7 +213,7 @@ clutter_clone_get_paint_volume (ClutterActor       *actor, | ||||
|   if (priv->clone_source == NULL) | ||||
|     return TRUE; | ||||
|  | ||||
|   /* query the volume of the source actor and simply masquerade it as | ||||
|   /* query the volume of the source actor and simply masquarade it as | ||||
|    * the clones volume... */ | ||||
|   source_volume = clutter_actor_get_paint_volume (priv->clone_source); | ||||
|   if (source_volume == NULL) | ||||
| @@ -222,16 +240,15 @@ clutter_clone_has_overlaps (ClutterActor *actor) | ||||
|  | ||||
| static void | ||||
| clutter_clone_allocate (ClutterActor           *self, | ||||
|                         const ClutterActorBox  *box) | ||||
|                         const ClutterActorBox  *box, | ||||
|                         ClutterAllocationFlags  flags) | ||||
| { | ||||
|   ClutterClonePrivate *priv = CLUTTER_CLONE (self)->priv; | ||||
|   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); | ||||
|   parent_class->allocate (self, box, flags); | ||||
|  | ||||
|   if (priv->clone_source == NULL) | ||||
|     return; | ||||
| @@ -241,31 +258,7 @@ clutter_clone_allocate (ClutterActor           *self, | ||||
|    */ | ||||
|   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)); | ||||
|     } | ||||
|     clutter_actor_allocate_preferred_size (priv->clone_source, flags); | ||||
|  | ||||
| #if 0 | ||||
|   /* XXX - this is wrong: ClutterClone cannot clone unparented | ||||
| @@ -280,7 +273,7 @@ clutter_clone_allocate (ClutterActor           *self, | ||||
|    * paint cycle, we can safely give it as much size as it requires | ||||
|    */ | ||||
|   if (clutter_actor_get_parent (priv->clone_source) == NULL) | ||||
|     clutter_actor_allocate_preferred_size (priv->clone_source); | ||||
|     clutter_actor_allocate_preferred_size (priv->clone_source, flags); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| @@ -372,9 +365,6 @@ static void | ||||
| clutter_clone_init (ClutterClone *self) | ||||
| { | ||||
|   self->priv = clutter_clone_get_instance_private (self); | ||||
|  | ||||
|   self->priv->x_scale = 1.f; | ||||
|   self->priv->y_scale = 1.f; | ||||
| } | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -611,7 +611,7 @@ parse_hsla (ClutterColor *color, | ||||
| /** | ||||
|  * clutter_color_from_string: | ||||
|  * @color: (out caller-allocates): return location for a #ClutterColor | ||||
|  * @str: a string specifying a color | ||||
|  * @str: a string specifiying a color | ||||
|  * | ||||
|  * Parses a string definition of a color, filling the #ClutterColor.red, | ||||
|  * #ClutterColor.green, #ClutterColor.blue and #ClutterColor.alpha fields  | ||||
| @@ -911,7 +911,7 @@ ClutterColor * | ||||
| clutter_color_copy (const ClutterColor *color) | ||||
| { | ||||
|   if (G_LIKELY (color != NULL)) | ||||
|     return g_memdup2 (color, sizeof (ClutterColor)); | ||||
|     return g_slice_dup (ClutterColor, color); | ||||
|  | ||||
|   return NULL; | ||||
| } | ||||
| @@ -928,7 +928,7 @@ void | ||||
| clutter_color_free (ClutterColor *color) | ||||
| { | ||||
|   if (G_LIKELY (color != NULL)) | ||||
|     g_free (color); | ||||
|     g_slice_free (ClutterColor, color); | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -977,7 +977,7 @@ clutter_color_new (guint8 red, | ||||
| ClutterColor * | ||||
| clutter_color_alloc (void) | ||||
| { | ||||
|   return g_new0 (ClutterColor, 1); | ||||
|   return g_slice_new0 (ClutterColor); | ||||
| } | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -39,6 +39,8 @@ | ||||
|  | ||||
| #include "clutter-build-config.h" | ||||
|  | ||||
| #define CLUTTER_ENABLE_EXPERIMENTAL_API | ||||
|  | ||||
| #include "clutter-colorize-effect.h" | ||||
|  | ||||
| #include "cogl/cogl.h" | ||||
| @@ -57,6 +59,9 @@ struct _ClutterColorizeEffect | ||||
|  | ||||
|   gint tint_uniform; | ||||
|  | ||||
|   gint tex_width; | ||||
|   gint tex_height; | ||||
|  | ||||
|   CoglPipeline *pipeline; | ||||
| }; | ||||
|  | ||||
| @@ -99,24 +104,16 @@ G_DEFINE_TYPE (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); | ||||
|  | ||||
|   cogl_pipeline_set_layer_texture (colorize_effect->pipeline, 0, texture); | ||||
|  | ||||
|   return cogl_object_ref (colorize_effect->pipeline); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| clutter_colorize_effect_pre_paint (ClutterEffect       *effect, | ||||
|                                    ClutterPaintNode    *node, | ||||
|                                    ClutterPaintContext *paint_context) | ||||
| { | ||||
|   ClutterColorizeEffect *self = CLUTTER_COLORIZE_EFFECT (effect); | ||||
|   ClutterEffectClass *parent_class; | ||||
|  | ||||
|   if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect))) | ||||
|     return FALSE; | ||||
|  | ||||
|   if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL)) | ||||
|     { | ||||
|       /* if we don't have support for GLSL shaders then we | ||||
| @@ -130,7 +127,47 @@ clutter_colorize_effect_pre_paint (ClutterEffect       *effect, | ||||
|     } | ||||
|  | ||||
|   parent_class = CLUTTER_EFFECT_CLASS (clutter_colorize_effect_parent_class); | ||||
|   return parent_class->pre_paint (effect, node, paint_context); | ||||
|   if (parent_class->pre_paint (effect, paint_context)) | ||||
|     { | ||||
|       ClutterOffscreenEffect *offscreen_effect = | ||||
|         CLUTTER_OFFSCREEN_EFFECT (effect); | ||||
|       CoglHandle texture; | ||||
|  | ||||
|       texture = clutter_offscreen_effect_get_texture (offscreen_effect); | ||||
|       self->tex_width = cogl_texture_get_width (texture); | ||||
|       self->tex_height = cogl_texture_get_height (texture); | ||||
|  | ||||
|       cogl_pipeline_set_layer_texture (self->pipeline, 0, texture); | ||||
|  | ||||
|       return TRUE; | ||||
|     } | ||||
|   else | ||||
|     return FALSE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_colorize_effect_paint_target (ClutterOffscreenEffect *effect, | ||||
|                                       ClutterPaintContext    *paint_context) | ||||
| { | ||||
|   ClutterColorizeEffect *self = CLUTTER_COLORIZE_EFFECT (effect); | ||||
|   CoglFramebuffer *framebuffer = | ||||
|     clutter_paint_context_get_framebuffer (paint_context); | ||||
|   ClutterActor *actor; | ||||
|   guint8 paint_opacity; | ||||
|  | ||||
|   actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect)); | ||||
|   paint_opacity = clutter_actor_get_paint_opacity (actor); | ||||
|  | ||||
|   cogl_pipeline_set_color4ub (self->pipeline, | ||||
|                               paint_opacity, | ||||
|                               paint_opacity, | ||||
|                               paint_opacity, | ||||
|                               paint_opacity); | ||||
|  | ||||
|   cogl_framebuffer_draw_rectangle (framebuffer, | ||||
|                                    self->pipeline, | ||||
|                                    0, 0, | ||||
|                                    self->tex_width, self->tex_height); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -196,7 +233,7 @@ clutter_colorize_effect_class_init (ClutterColorizeEffectClass *klass) | ||||
|   ClutterOffscreenEffectClass *offscreen_class; | ||||
|  | ||||
|   offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass); | ||||
|   offscreen_class->create_pipeline = clutter_colorize_effect_create_pipeline; | ||||
|   offscreen_class->paint_target = clutter_colorize_effect_paint_target; | ||||
|  | ||||
|   effect_class->pre_paint = clutter_colorize_effect_pre_paint; | ||||
|  | ||||
|   | ||||
							
								
								
									
										16
									
								
								clutter/clutter/clutter-config.h.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								clutter/clutter/clutter-config.h.in
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| #if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <clutter/clutter.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #ifndef __CLUTTER_CONFIG_H__ | ||||
| #define __CLUTTER_CONFIG_H__ | ||||
|  | ||||
| #include <glib.h> | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| @CLUTTER_CONFIG_DEFINES@ | ||||
|  | ||||
| G_END_DECLS | ||||
|  | ||||
| #endif /* __CLUTTER_CONFIG_H__ */ | ||||
| @@ -160,26 +160,28 @@ constraint_update_preferred_size (ClutterConstraint  *constraint, | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_constraint_set_enabled (ClutterActorMeta *meta, | ||||
|                                 gboolean          is_enabled) | ||||
| clutter_constraint_notify (GObject    *gobject, | ||||
|                            GParamSpec *pspec) | ||||
| { | ||||
|   ClutterActorMetaClass *parent_class = | ||||
|     CLUTTER_ACTOR_META_CLASS (clutter_constraint_parent_class); | ||||
|   ClutterActor *actor; | ||||
|   if (strcmp (pspec->name, "enabled") == 0) | ||||
|     { | ||||
|       ClutterActorMeta *meta = CLUTTER_ACTOR_META (gobject); | ||||
|       ClutterActor *actor = clutter_actor_meta_get_actor (meta); | ||||
|  | ||||
|   actor = clutter_actor_meta_get_actor (meta); | ||||
|   if (actor) | ||||
|     clutter_actor_queue_relayout (actor); | ||||
|       if (actor != NULL) | ||||
|         clutter_actor_queue_relayout (actor); | ||||
|     } | ||||
|  | ||||
|   parent_class->set_enabled (meta, is_enabled); | ||||
|   if (G_OBJECT_CLASS (clutter_constraint_parent_class)->notify != NULL) | ||||
|     G_OBJECT_CLASS (clutter_constraint_parent_class)->notify (gobject, pspec); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_constraint_class_init (ClutterConstraintClass *klass) | ||||
| { | ||||
|   ClutterActorMetaClass *actor_meta_class = CLUTTER_ACTOR_META_CLASS (klass); | ||||
|   GObjectClass *gobject_class = G_OBJECT_CLASS (klass); | ||||
|  | ||||
|   actor_meta_class->set_enabled = clutter_constraint_set_enabled; | ||||
|   gobject_class->notify = clutter_constraint_notify; | ||||
|  | ||||
|   klass->update_allocation = constraint_update_allocation; | ||||
|   klass->update_preferred_size = constraint_update_preferred_size; | ||||
|   | ||||
| @@ -119,6 +119,31 @@ container_real_remove (ClutterContainer *container, | ||||
|   clutter_actor_remove_child (CLUTTER_ACTOR (container), actor); | ||||
| } | ||||
|  | ||||
| static void | ||||
| container_real_raise (ClutterContainer *container, | ||||
|                       ClutterActor     *child, | ||||
|                       ClutterActor     *sibling) | ||||
| { | ||||
|   ClutterActor *self = CLUTTER_ACTOR (container); | ||||
|  | ||||
|   clutter_actor_set_child_above_sibling (self, child, sibling); | ||||
| } | ||||
|  | ||||
| static void | ||||
| container_real_lower (ClutterContainer *container, | ||||
|                       ClutterActor     *child, | ||||
|                       ClutterActor     *sibling) | ||||
| { | ||||
|   ClutterActor *self = CLUTTER_ACTOR (container); | ||||
|  | ||||
|   clutter_actor_set_child_below_sibling (self, child, sibling); | ||||
| } | ||||
|  | ||||
| static void | ||||
| container_real_sort_depth_order (ClutterContainer *container) | ||||
| { | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_container_default_init (ClutterContainerInterface *iface) | ||||
| { | ||||
| @@ -188,6 +213,9 @@ clutter_container_default_init (ClutterContainerInterface *iface) | ||||
|  | ||||
|   iface->add = container_real_add; | ||||
|   iface->remove = container_real_remove; | ||||
|   iface->raise = container_real_raise; | ||||
|   iface->lower = container_real_lower; | ||||
|   iface->sort_depth_order = container_real_sort_depth_order; | ||||
|  | ||||
|   iface->child_meta_type = G_TYPE_INVALID; | ||||
|   iface->create_child_meta = create_child_meta; | ||||
| @@ -420,6 +448,202 @@ clutter_container_remove_actor (ClutterContainer *container, | ||||
|   container_remove_actor (container, actor); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_container_get_children: | ||||
|  * @container: a #ClutterContainer | ||||
|  * | ||||
|  * Retrieves all the children of @container. | ||||
|  * | ||||
|  * Return value: (element-type Clutter.Actor) (transfer container): a list | ||||
|  *   of #ClutterActor<!-- -->s. Use g_list_free() on the returned | ||||
|  *   list when done. | ||||
|  * | ||||
|  * Since: 0.4 | ||||
|  * | ||||
|  * Deprecated: 1.10: Use clutter_actor_get_children() instead. | ||||
|  */ | ||||
| GList * | ||||
| clutter_container_get_children (ClutterContainer *container) | ||||
| { | ||||
|   g_return_val_if_fail (CLUTTER_IS_CONTAINER (container), NULL); | ||||
|  | ||||
|   return clutter_actor_get_children (CLUTTER_ACTOR (container)); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_container_raise_child: (virtual raise) | ||||
|  * @container: a #ClutterContainer | ||||
|  * @actor: the actor to raise | ||||
|  * @sibling: (allow-none): the sibling to raise to, or %NULL to raise | ||||
|  *   to the top | ||||
|  * | ||||
|  * Raises @actor to @sibling level, in the depth ordering. | ||||
|  * | ||||
|  * This function calls the #ClutterContainerIface.raise() virtual function, | ||||
|  * which has been deprecated. The default implementation will call | ||||
|  * clutter_actor_set_child_above_sibling(). | ||||
|  * | ||||
|  * Since: 0.6 | ||||
|  * | ||||
|  * Deprecated: 1.10: Use clutter_actor_set_child_above_sibling() instead. | ||||
|  */ | ||||
| void | ||||
| clutter_container_raise_child (ClutterContainer *container, | ||||
|                                ClutterActor     *actor, | ||||
|                                ClutterActor     *sibling) | ||||
| { | ||||
|   ClutterContainerIface *iface; | ||||
|   ClutterActor *self; | ||||
|  | ||||
|   g_return_if_fail (CLUTTER_IS_CONTAINER (container)); | ||||
|   g_return_if_fail (CLUTTER_IS_ACTOR (actor)); | ||||
|   g_return_if_fail (sibling == NULL || CLUTTER_IS_ACTOR (sibling)); | ||||
|  | ||||
|   if (actor == sibling) | ||||
|     return; | ||||
|  | ||||
|   self = CLUTTER_ACTOR (container); | ||||
|  | ||||
|   if (clutter_actor_get_parent (actor) != self) | ||||
|     { | ||||
|       g_warning ("Actor of type '%s' is not a child of the container " | ||||
|                  "of type '%s'", | ||||
|                  g_type_name (G_OBJECT_TYPE (actor)), | ||||
|                  g_type_name (G_OBJECT_TYPE (container))); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   if (sibling != NULL && | ||||
|       clutter_actor_get_parent (sibling) != self) | ||||
|     { | ||||
|       g_warning ("Actor of type '%s' is not a child of the container " | ||||
|                  "of type '%s'", | ||||
|                  g_type_name (G_OBJECT_TYPE (sibling)), | ||||
|                  g_type_name (G_OBJECT_TYPE (container))); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   iface = CLUTTER_CONTAINER_GET_IFACE (container); | ||||
|  | ||||
| #ifdef CLUTTER_ENABLE_DEBUG | ||||
|   if (G_UNLIKELY (_clutter_diagnostic_enabled ())) | ||||
|     { | ||||
|       if (iface->raise != container_real_raise) | ||||
|         _clutter_diagnostic_message ("The ClutterContainer::raise() " | ||||
|                                      "virtual function has been deprecated " | ||||
|                                      "and it should not be overridden by " | ||||
|                                      "newly written code"); | ||||
|     } | ||||
| #endif /* CLUTTER_ENABLE_DEBUG */ | ||||
|  | ||||
|   iface->raise (container, actor, sibling); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_container_lower_child: (virtual lower) | ||||
|  * @container: a #ClutterContainer | ||||
|  * @actor: the actor to raise | ||||
|  * @sibling: (allow-none): the sibling to lower to, or %NULL to lower | ||||
|  *   to the bottom | ||||
|  * | ||||
|  * Lowers @actor to @sibling level, in the depth ordering. | ||||
|  * | ||||
|  * This function calls the #ClutterContainerIface.lower() virtual function, | ||||
|  * which has been deprecated. The default implementation will call | ||||
|  * clutter_actor_set_child_below_sibling(). | ||||
|  * | ||||
|  * Since: 0.6 | ||||
|  * | ||||
|  * Deprecated: 1.10: Use clutter_actor_set_child_below_sibling() instead. | ||||
|  */ | ||||
| void | ||||
| clutter_container_lower_child (ClutterContainer *container, | ||||
|                                ClutterActor     *actor, | ||||
|                                ClutterActor     *sibling) | ||||
| { | ||||
|   ClutterContainerIface *iface; | ||||
|   ClutterActor *self; | ||||
|  | ||||
|   g_return_if_fail (CLUTTER_IS_CONTAINER (container)); | ||||
|   g_return_if_fail (CLUTTER_IS_ACTOR (actor)); | ||||
|   g_return_if_fail (sibling == NULL || CLUTTER_IS_ACTOR (sibling)); | ||||
|  | ||||
|   if (actor == sibling) | ||||
|     return; | ||||
|  | ||||
|   self = CLUTTER_ACTOR (container); | ||||
|  | ||||
|   if (clutter_actor_get_parent (actor) != self) | ||||
|     { | ||||
|       g_warning ("Actor of type '%s' is not a child of the container " | ||||
|                  "of type '%s'", | ||||
|                  g_type_name (G_OBJECT_TYPE (actor)), | ||||
|                  g_type_name (G_OBJECT_TYPE (container))); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   if (sibling != NULL&& | ||||
|       clutter_actor_get_parent (sibling) != self) | ||||
|     { | ||||
|       g_warning ("Actor of type '%s' is not a child of the container " | ||||
|                  "of type '%s'", | ||||
|                  g_type_name (G_OBJECT_TYPE (sibling)), | ||||
|                  g_type_name (G_OBJECT_TYPE (container))); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   iface = CLUTTER_CONTAINER_GET_IFACE (container); | ||||
|  | ||||
| #ifdef CLUTTER_ENABLE_DEBUG | ||||
|   if (G_UNLIKELY (_clutter_diagnostic_enabled ())) | ||||
|     { | ||||
|       if (iface->lower != container_real_lower) | ||||
|         _clutter_diagnostic_message ("The ClutterContainer::lower() " | ||||
|                                      "virtual function has been deprecated " | ||||
|                                      "and it should not be overridden by " | ||||
|                                      "newly written code"); | ||||
|     } | ||||
| #endif /* CLUTTER_ENABLE_DEBUG */ | ||||
|  | ||||
|   iface->lower (container, actor, sibling); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_container_sort_depth_order: | ||||
|  * @container: a #ClutterContainer | ||||
|  * | ||||
|  * Sorts a container's children using their depth. This function should not | ||||
|  * be normally used by applications. | ||||
|  * | ||||
|  * Since: 0.6 | ||||
|  * | ||||
|  * Deprecated: 1.10: The #ClutterContainerIface.sort_depth_order() virtual | ||||
|  *   function should not be used any more; the default implementation in | ||||
|  *   #ClutterContainer does not do anything. | ||||
|  */ | ||||
| void | ||||
| clutter_container_sort_depth_order (ClutterContainer *container) | ||||
| { | ||||
|   ClutterContainerIface *iface; | ||||
|  | ||||
|   g_return_if_fail (CLUTTER_IS_CONTAINER (container)); | ||||
|  | ||||
|   iface = CLUTTER_CONTAINER_GET_IFACE (container); | ||||
|  | ||||
| #ifdef CLUTTER_ENABLE_DEBUG | ||||
|   if (G_UNLIKELY (_clutter_diagnostic_enabled ())) | ||||
|     { | ||||
|       if (iface->sort_depth_order != container_real_sort_depth_order) | ||||
|         _clutter_diagnostic_message ("The ClutterContainer::sort_depth_order() " | ||||
|                                      "virtual function has been deprecated " | ||||
|                                      "and it should not be overridden by " | ||||
|                                      "newly written code"); | ||||
|     } | ||||
| #endif /* CLUTTER_ENABLE_DEBUG */ | ||||
|  | ||||
|   iface->sort_depth_order (container); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_container_find_child_by_name: | ||||
|  * @container: a #ClutterContainer | ||||
| @@ -444,7 +668,7 @@ clutter_container_find_child_by_name (ClutterContainer *container, | ||||
|   g_return_val_if_fail (CLUTTER_IS_CONTAINER (container), NULL); | ||||
|   g_return_val_if_fail (child_name != NULL, NULL); | ||||
|  | ||||
|   children = clutter_actor_get_children (CLUTTER_ACTOR (container)); | ||||
|   children = clutter_container_get_children (container); | ||||
|  | ||||
|   for (iter = children; iter; iter = g_list_next (iter)) | ||||
|     { | ||||
|   | ||||
| @@ -59,6 +59,13 @@ typedef struct _ClutterContainerIface   ClutterContainerIface; | ||||
|  *   function is deprecated, and it should not be overridden. | ||||
|  * @remove: virtual function for removing an actor from the container. This | ||||
|  *   virtual function is deprecated, and it should not be overridden. | ||||
|  * @raise: virtual function for raising a child. This virtual function is | ||||
|  *   deprecated and it should not be overridden. | ||||
|  * @lower: virtual function for lowering a child. This virtual function is | ||||
|  *   deprecated and it should not be overridden. | ||||
|  * @sort_depth_order: virtual function for sorting the children of a | ||||
|  *   container depending on their depth. This virtual function is deprecated | ||||
|  *   and it should not be overridden. | ||||
|  * @child_meta_type: The GType used for storing auxiliary information about | ||||
|  *   each of the containers children. | ||||
|  * @create_child_meta: virtual function that gets called for each added | ||||
| @@ -67,7 +74,7 @@ typedef struct _ClutterContainerIface   ClutterContainerIface; | ||||
|  *   fields in the instance and add the record to a data structure for | ||||
|  *   subsequent access for #ClutterContainerIface::get_child_meta | ||||
|  * @destroy_child_meta: virtual function that gets called when a child is | ||||
|  *   removed; it should release all resources held by the record | ||||
|  *   removed; it shuld release all resources held by the record | ||||
|  * @get_child_meta: return the record for a container child | ||||
|  * @actor_added: class handler for #ClutterContainer::actor-added | ||||
|  * @actor_removed: class handler for #ClutterContainer::actor-removed | ||||
| @@ -90,6 +97,15 @@ struct _ClutterContainerIface | ||||
|   void (* remove)           (ClutterContainer *container, | ||||
|                              ClutterActor     *actor); | ||||
|  | ||||
|   /* child stacking */ | ||||
|   void (* raise)            (ClutterContainer *container, | ||||
|                              ClutterActor     *actor, | ||||
|                              ClutterActor     *sibling); | ||||
|   void (* lower)            (ClutterContainer *container, | ||||
|                              ClutterActor     *actor, | ||||
|                              ClutterActor     *sibling); | ||||
|   void (* sort_depth_order) (ClutterContainer *container); | ||||
|  | ||||
|   /* ClutterChildMeta management */ | ||||
|   GType                child_meta_type; | ||||
|   void              (* create_child_meta)  (ClutterContainer *container, | ||||
|   | ||||
| @@ -322,8 +322,8 @@ _clutter_content_paint_content (ClutterContent      *content, | ||||
| /** | ||||
|  * 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 | ||||
|  * @width: (out): return location for the natural width of the content | ||||
|  * @height: (out): return location for the natural height of the content | ||||
|  * | ||||
|  * Retrieves the natural size of the @content, if any. | ||||
|  * | ||||
|   | ||||
| @@ -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 "clutter-build-config.h" | ||||
|  | ||||
| #include "clutter-damage-history.h" | ||||
|  | ||||
| #define DAMAGE_HISTORY_LENGTH 0x10 | ||||
|  | ||||
| struct _ClutterDamageHistory | ||||
| { | ||||
|   cairo_region_t *damages[DAMAGE_HISTORY_LENGTH]; | ||||
|   int index; | ||||
| }; | ||||
|  | ||||
| ClutterDamageHistory * | ||||
| clutter_damage_history_new (void) | ||||
| { | ||||
|   ClutterDamageHistory *history; | ||||
|  | ||||
|   history = g_new0 (ClutterDamageHistory, 1); | ||||
|  | ||||
|   return history; | ||||
| } | ||||
|  | ||||
| void | ||||
| clutter_damage_history_free (ClutterDamageHistory *history) | ||||
| { | ||||
|   int i; | ||||
|  | ||||
|   for (i = 0; i < G_N_ELEMENTS (history->damages); i++) | ||||
|     g_clear_pointer (&history->damages[i], cairo_region_destroy); | ||||
|  | ||||
|   g_free (history); | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| clutter_damage_history_is_age_valid (ClutterDamageHistory *history, | ||||
|                                      int                   age) | ||||
| { | ||||
|   if (age >= DAMAGE_HISTORY_LENGTH || | ||||
|       age < 1) | ||||
|     return FALSE; | ||||
|  | ||||
|   if (!clutter_damage_history_lookup (history, age)) | ||||
|     return FALSE; | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| void | ||||
| clutter_damage_history_record (ClutterDamageHistory *history, | ||||
|                                const cairo_region_t *damage) | ||||
| { | ||||
|   g_clear_pointer (&history->damages[history->index], cairo_region_destroy); | ||||
|   history->damages[history->index] = cairo_region_copy (damage); | ||||
| } | ||||
|  | ||||
| static inline int | ||||
| step_damage_index (int current, | ||||
|                    int diff) | ||||
| { | ||||
|   return (current + diff) & (DAMAGE_HISTORY_LENGTH - 1); | ||||
| } | ||||
|  | ||||
| void | ||||
| clutter_damage_history_step (ClutterDamageHistory *history) | ||||
| { | ||||
|   history->index = step_damage_index (history->index, 1); | ||||
| } | ||||
|  | ||||
| const cairo_region_t * | ||||
| clutter_damage_history_lookup (ClutterDamageHistory *history, | ||||
|                                int                   age) | ||||
| { | ||||
|   return history->damages[step_damage_index (history->index, -age)]; | ||||
| } | ||||
| @@ -1,50 +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/>. | ||||
|  */ | ||||
|  | ||||
| #ifndef CLUTTER_DAMAGE_HISTORY_H | ||||
| #define CLUTTER_DAMAGE_HISTORY_H | ||||
|  | ||||
| #include <cairo.h> | ||||
| #include <glib.h> | ||||
|  | ||||
| #include "clutter-macros.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 cairo_region_t *damage); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void clutter_damage_history_step (ClutterDamageHistory *history); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| const cairo_region_t * clutter_damage_history_lookup (ClutterDamageHistory *history, | ||||
|                                                       int                   age); | ||||
|  | ||||
| #endif /* CLUTTER_DAMAGE_HISTORY_H */ | ||||
| @@ -41,7 +41,6 @@ G_BEGIN_DECLS | ||||
| 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); | ||||
|   | ||||
| @@ -53,16 +53,14 @@ | ||||
|  | ||||
| #include "clutter-build-config.h" | ||||
|  | ||||
| #define CLUTTER_ENABLE_EXPERIMENTAL_API | ||||
| #include "clutter-deform-effect.h" | ||||
|  | ||||
| #include <cogl/cogl.h> | ||||
|  | ||||
| #include "clutter-color.h" | ||||
| #include "clutter-debug.h" | ||||
| #include "clutter-enum-types.h" | ||||
| #include "clutter-offscreen-effect-private.h" | ||||
| #include "clutter-paint-node.h" | ||||
| #include "clutter-paint-nodes.h" | ||||
| #include "clutter-private.h" | ||||
|  | ||||
| #define DEFAULT_N_TILES         32 | ||||
| @@ -130,9 +128,10 @@ clutter_deform_effect_deform_vertex (ClutterDeformEffect *effect, | ||||
| } | ||||
|  | ||||
| static void | ||||
| vbo_invalidate (ClutterActor        *actor, | ||||
|                 GParamSpec          *pspec, | ||||
|                 ClutterDeformEffect *effect) | ||||
| vbo_invalidate (ClutterActor           *actor, | ||||
|                 const ClutterActorBox  *allocation, | ||||
|                 ClutterAllocationFlags  flags, | ||||
|                 ClutterDeformEffect    *effect) | ||||
| { | ||||
|   effect->priv->is_dirty = TRUE; | ||||
| } | ||||
| @@ -157,7 +156,7 @@ clutter_deform_effect_set_actor (ClutterActorMeta *meta, | ||||
|    * changes | ||||
|    */ | ||||
|   if (actor != NULL) | ||||
|     priv->allocation_id = g_signal_connect (actor, "notify::allocation", | ||||
|     priv->allocation_id = g_signal_connect (actor, "allocation-changed", | ||||
|                                             G_CALLBACK (vbo_invalidate), | ||||
|                                             meta); | ||||
|  | ||||
| @@ -168,16 +167,19 @@ clutter_deform_effect_set_actor (ClutterActorMeta *meta, | ||||
|  | ||||
| static void | ||||
| clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect, | ||||
|                                     ClutterPaintNode       *node, | ||||
|                                     ClutterPaintContext    *paint_context) | ||||
| { | ||||
|   ClutterDeformEffect *self= CLUTTER_DEFORM_EFFECT (effect); | ||||
|   ClutterDeformEffectPrivate *priv = self->priv; | ||||
|   CoglHandle material; | ||||
|   CoglPipeline *pipeline; | ||||
|   CoglDepthState depth_state; | ||||
|   CoglFramebuffer *fb = | ||||
|     clutter_paint_context_get_framebuffer (paint_context); | ||||
|  | ||||
|   if (priv->is_dirty) | ||||
|     { | ||||
|       graphene_rect_t rect; | ||||
|       gboolean mapped_buffer; | ||||
|       CoglVertexP3T2C4 *verts; | ||||
|       ClutterActor *actor; | ||||
| @@ -191,7 +193,12 @@ clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect, | ||||
|       /* 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)) | ||||
|       if (clutter_offscreen_effect_get_target_rect (effect, &rect)) | ||||
|         { | ||||
|           width = graphene_rect_get_width (&rect); | ||||
|           height = graphene_rect_get_height (&rect); | ||||
|         } | ||||
|       else | ||||
|         clutter_actor_get_size (actor, &width, &height); | ||||
|  | ||||
|       /* XXX ideally, the sub-classes should tell us what they | ||||
| @@ -271,7 +278,8 @@ clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect, | ||||
|       priv->is_dirty = FALSE; | ||||
|     } | ||||
|  | ||||
|   pipeline = clutter_offscreen_effect_get_pipeline (effect); | ||||
|   material = clutter_offscreen_effect_get_target (effect); | ||||
|   pipeline = COGL_PIPELINE (material); | ||||
|  | ||||
|   /* enable depth testing */ | ||||
|   cogl_depth_state_init (&depth_state); | ||||
| @@ -285,22 +293,12 @@ clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect, | ||||
|                                       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); | ||||
|     } | ||||
|   if (material != NULL) | ||||
|     cogl_framebuffer_draw_primitive (fb, pipeline, priv->primitive); | ||||
|  | ||||
|   /* 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 | ||||
| @@ -310,30 +308,20 @@ clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect, | ||||
|       cogl_pipeline_set_cull_face_mode (back_pipeline, | ||||
|                                         COGL_PIPELINE_CULL_FACE_MODE_FRONT); | ||||
|  | ||||
|       cogl_framebuffer_draw_primitive (fb, back_pipeline, priv->primitive); | ||||
|  | ||||
|       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); | ||||
|       cogl_object_unref (back_pipeline); | ||||
|     } | ||||
|  | ||||
|   if (G_UNLIKELY (priv->lines_primitive != NULL)) | ||||
|     { | ||||
|       const ClutterColor *red; | ||||
|       ClutterPaintNode *lines_node; | ||||
|  | ||||
|       red = clutter_color_get_static (CLUTTER_COLOR_RED); | ||||
|  | ||||
|       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); | ||||
|       CoglContext *ctx = | ||||
|         clutter_backend_get_cogl_context (clutter_get_default_backend ()); | ||||
|       CoglPipeline *lines_pipeline = cogl_pipeline_new (ctx); | ||||
|       cogl_pipeline_set_color4f (lines_pipeline, 1.0, 0, 0, 1.0); | ||||
|       cogl_framebuffer_draw_primitive (fb, lines_pipeline, | ||||
|                                        priv->lines_primitive); | ||||
|       cogl_object_unref (lines_pipeline); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -3,7 +3,16 @@ | ||||
|  | ||||
| #define __CLUTTER_DEPRECATED_H_INSIDE__ | ||||
|  | ||||
| #include "deprecated/clutter-actor.h" | ||||
| #include "deprecated/clutter-alpha.h" | ||||
| #include "deprecated/clutter-animation.h" | ||||
| #include "deprecated/clutter-box.h" | ||||
| #include "deprecated/clutter-container.h" | ||||
| #include "deprecated/clutter-group.h" | ||||
| #include "deprecated/clutter-rectangle.h" | ||||
| #include "deprecated/clutter-stage.h" | ||||
| #include "deprecated/clutter-state.h" | ||||
| #include "deprecated/clutter-timeline.h" | ||||
|  | ||||
| #undef __CLUTTER_DEPRECATED_H_INSIDE__ | ||||
|  | ||||
|   | ||||
| @@ -28,7 +28,7 @@ | ||||
|  * @see_also: #ClutterEffect, #ClutterOffscreenEffect | ||||
|  * | ||||
|  * #ClutterDesaturateEffect is a sub-class of #ClutterEffect that | ||||
|  * desaturates the color of an actor and its contents. The strength | ||||
|  * desaturates the color of an actor and its contents. The strenght | ||||
|  * of the desaturation effect is controllable and animatable through | ||||
|  * the #ClutterDesaturateEffect:factor property. | ||||
|  * | ||||
| @@ -41,6 +41,8 @@ | ||||
|  | ||||
| #include "clutter-build-config.h" | ||||
|  | ||||
| #define CLUTTER_ENABLE_EXPERIMENTAL_API | ||||
|  | ||||
| #include <math.h> | ||||
|  | ||||
| #include "clutter-desaturate-effect.h" | ||||
| @@ -109,25 +111,16 @@ G_DEFINE_TYPE (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); | ||||
|  | ||||
|   cogl_pipeline_set_layer_texture (desaturate_effect->pipeline, 0, texture); | ||||
|  | ||||
|   return cogl_object_ref (desaturate_effect->pipeline); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| clutter_desaturate_effect_pre_paint (ClutterEffect       *effect, | ||||
|                                      ClutterPaintNode    *node, | ||||
|                                      ClutterPaintContext *paint_context) | ||||
| { | ||||
|   ClutterDesaturateEffect *self = CLUTTER_DESATURATE_EFFECT (effect); | ||||
|   ClutterEffectClass *parent_class; | ||||
|  | ||||
|   if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect))) | ||||
|     return FALSE; | ||||
|  | ||||
|   if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL)) | ||||
|     { | ||||
|       /* if we don't have support for GLSL shaders then we | ||||
| @@ -141,7 +134,52 @@ clutter_desaturate_effect_pre_paint (ClutterEffect       *effect, | ||||
|     } | ||||
|  | ||||
|   parent_class = CLUTTER_EFFECT_CLASS (clutter_desaturate_effect_parent_class); | ||||
|   return parent_class->pre_paint (effect, node, paint_context); | ||||
|   if (parent_class->pre_paint (effect, paint_context)) | ||||
|     { | ||||
|       ClutterOffscreenEffect *offscreen_effect = | ||||
|         CLUTTER_OFFSCREEN_EFFECT (effect); | ||||
|       CoglHandle texture; | ||||
|  | ||||
|       texture = clutter_offscreen_effect_get_texture (offscreen_effect); | ||||
|       self->tex_width = cogl_texture_get_width (texture); | ||||
|       self->tex_height = cogl_texture_get_height (texture); | ||||
|  | ||||
|       cogl_pipeline_set_layer_texture (self->pipeline, 0, texture); | ||||
|  | ||||
|       return TRUE; | ||||
|     } | ||||
|   else | ||||
|     return FALSE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_desaturate_effect_paint_target (ClutterOffscreenEffect *effect, | ||||
|                                         ClutterPaintContext    *paint_context) | ||||
| { | ||||
|   ClutterDesaturateEffect *self = CLUTTER_DESATURATE_EFFECT (effect); | ||||
|   CoglFramebuffer *framebuffer = | ||||
|    clutter_paint_context_get_framebuffer (paint_context); | ||||
|   ClutterActor *actor; | ||||
|   CoglHandle texture; | ||||
|   guint8 paint_opacity; | ||||
|  | ||||
|   texture = clutter_offscreen_effect_get_texture (effect); | ||||
|   cogl_pipeline_set_layer_texture (self->pipeline, 0, texture); | ||||
|  | ||||
|   actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect)); | ||||
|   paint_opacity = clutter_actor_get_paint_opacity (actor); | ||||
|  | ||||
|   cogl_pipeline_set_color4ub (self->pipeline, | ||||
|                               paint_opacity, | ||||
|                               paint_opacity, | ||||
|                               paint_opacity, | ||||
|                               paint_opacity); | ||||
|  | ||||
|   cogl_framebuffer_draw_rectangle (framebuffer, | ||||
|                                    self->pipeline, | ||||
|                                    0, 0, | ||||
|                                    cogl_texture_get_width (texture), | ||||
|                                    cogl_texture_get_height (texture)); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -216,7 +254,7 @@ clutter_desaturate_effect_class_init (ClutterDesaturateEffectClass *klass) | ||||
|   ClutterOffscreenEffectClass *offscreen_class; | ||||
|  | ||||
|   offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass); | ||||
|   offscreen_class->create_pipeline = clutter_desaturate_effect_create_pipeline; | ||||
|   offscreen_class->paint_target = clutter_desaturate_effect_paint_target; | ||||
|  | ||||
|   effect_class->pre_paint = clutter_desaturate_effect_pre_paint; | ||||
|  | ||||
|   | ||||
							
								
								
									
										1316
									
								
								clutter/clutter/clutter-drag-action.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1316
									
								
								clutter/clutter/clutter-drag-action.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										152
									
								
								clutter/clutter/clutter-drag-action.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								clutter/clutter/clutter-drag-action.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,152 @@ | ||||
| /* | ||||
|  * 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> | ||||
|  */ | ||||
|  | ||||
| #ifndef __CLUTTER_DRAG_ACTION_H__ | ||||
| #define __CLUTTER_DRAG_ACTION_H__ | ||||
|  | ||||
| #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_DRAG_ACTION                (clutter_drag_action_get_type ()) | ||||
| #define CLUTTER_DRAG_ACTION(obj)                (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_DRAG_ACTION, ClutterDragAction)) | ||||
| #define CLUTTER_IS_DRAG_ACTION(obj)             (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_DRAG_ACTION)) | ||||
| #define CLUTTER_DRAG_ACTION_CLASS(klass)        (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_DRAG_ACTION, ClutterDragActionClass)) | ||||
| #define CLUTTER_IS_DRAG_ACTION_CLASS(klass)     (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_DRAG_ACTION)) | ||||
| #define CLUTTER_DRAG_ACTION_GET_CLASS(obj)      (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_DRAG_ACTION, ClutterDragActionClass)) | ||||
|  | ||||
| typedef struct _ClutterDragAction               ClutterDragAction; | ||||
| typedef struct _ClutterDragActionPrivate        ClutterDragActionPrivate; | ||||
| typedef struct _ClutterDragActionClass          ClutterDragActionClass; | ||||
|  | ||||
| /** | ||||
|  * ClutterDragAction: | ||||
|  * | ||||
|  * The #ClutterDragAction structure contains only | ||||
|  * private data and should be accessed using the provided API | ||||
|  * | ||||
|  * Since: 1.4 | ||||
|  */ | ||||
| struct _ClutterDragAction | ||||
| { | ||||
|   /*< private >*/ | ||||
|   ClutterAction parent_instance; | ||||
|  | ||||
|   ClutterDragActionPrivate *priv; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * ClutterDragActionClass: | ||||
|  * @drag_begin: class handler of the #ClutterDragAction::drag-begin signal | ||||
|  * @drag_motion: class handler of the #ClutterDragAction::drag-motion signal | ||||
|  * @drag_end: class handler of the #ClutterDragAction::drag-end signal | ||||
|  * @drag_progress: class handler of the #ClutterDragAction::drag-progress signal | ||||
|  * | ||||
|  * The #ClutterDragActionClass structure contains | ||||
|  * only private data | ||||
|  * | ||||
|  * Since: 1.4 | ||||
|  */ | ||||
| struct _ClutterDragActionClass | ||||
| { | ||||
|   /*< private >*/ | ||||
|   ClutterActionClass parent_class; | ||||
|  | ||||
|   /*< public >*/ | ||||
|   void          (* drag_begin)          (ClutterDragAction   *action, | ||||
|                                          ClutterActor        *actor, | ||||
|                                          gfloat               event_x, | ||||
|                                          gfloat               event_y, | ||||
|                                          ClutterModifierType  modifiers); | ||||
|   void          (* drag_motion)         (ClutterDragAction   *action, | ||||
|                                          ClutterActor        *actor, | ||||
|                                          gfloat               delta_x, | ||||
|                                          gfloat               delta_y); | ||||
|   void          (* drag_end)            (ClutterDragAction   *action, | ||||
|                                          ClutterActor        *actor, | ||||
|                                          gfloat               event_x, | ||||
|                                          gfloat               event_y, | ||||
|                                          ClutterModifierType  modifiers); | ||||
|   gboolean      (* drag_progress)       (ClutterDragAction   *action, | ||||
|                                          ClutterActor        *actor, | ||||
|                                          gfloat               delta_x, | ||||
|                                          gfloat               delta_y); | ||||
|  | ||||
|   /*< private >*/ | ||||
|   void (* _clutter_drag_action1) (void); | ||||
|   void (* _clutter_drag_action2) (void); | ||||
|   void (* _clutter_drag_action3) (void); | ||||
|   void (* _clutter_drag_action4) (void); | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| GType clutter_drag_action_get_type (void) G_GNUC_CONST; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterAction * clutter_drag_action_new                   (void); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void            clutter_drag_action_set_drag_threshold (ClutterDragAction *action, | ||||
|                                                         gint               x_threshold, | ||||
|                                                         gint               y_threshold); | ||||
| CLUTTER_EXPORT | ||||
| void            clutter_drag_action_get_drag_threshold (ClutterDragAction *action, | ||||
|                                                         guint             *x_threshold, | ||||
|                                                         guint             *y_threshold); | ||||
| CLUTTER_EXPORT | ||||
| void            clutter_drag_action_set_drag_handle    (ClutterDragAction *action, | ||||
|                                                         ClutterActor      *handle); | ||||
| CLUTTER_EXPORT | ||||
| ClutterActor *  clutter_drag_action_get_drag_handle    (ClutterDragAction *action); | ||||
| CLUTTER_EXPORT | ||||
| void            clutter_drag_action_set_drag_axis      (ClutterDragAction *action, | ||||
|                                                         ClutterDragAxis    axis); | ||||
| CLUTTER_EXPORT | ||||
| ClutterDragAxis clutter_drag_action_get_drag_axis      (ClutterDragAction *action); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void            clutter_drag_action_get_press_coords   (ClutterDragAction *action, | ||||
|                                                         gfloat            *press_x, | ||||
|                                                         gfloat            *press_y); | ||||
| CLUTTER_EXPORT | ||||
| void            clutter_drag_action_get_motion_coords  (ClutterDragAction *action, | ||||
|                                                         gfloat            *motion_x, | ||||
|                                                         gfloat            *motion_y); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| gboolean        clutter_drag_action_get_drag_area      (ClutterDragAction *action, | ||||
|                                                         graphene_rect_t   *drag_area); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void            clutter_drag_action_set_drag_area      (ClutterDragAction     *action, | ||||
|                                                         const graphene_rect_t *drag_area); | ||||
|  | ||||
| G_END_DECLS | ||||
|  | ||||
| #endif /* __CLUTTER_DRAG_ACTION_H__ */ | ||||
							
								
								
									
										527
									
								
								clutter/clutter/clutter-drop-action.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										527
									
								
								clutter/clutter/clutter-drop-action.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,527 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright © 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> | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * SECTION:clutter-drop-action | ||||
|  * @Title: ClutterDropAction | ||||
|  * @short_description: An action for drop targets | ||||
|  * | ||||
|  * #ClutterDropAction is a #ClutterAction that allows a #ClutterActor | ||||
|  * implementation to control what happens when an actor dragged using | ||||
|  * a #ClutterDragAction crosses the target area or when a dragged actor | ||||
|  * is released (or "dropped") on the target area. | ||||
|  * | ||||
|  * A trivial use of #ClutterDropAction consists in connecting to the | ||||
|  * #ClutterDropAction::drop signal and handling the drop from there, | ||||
|  * for instance: | ||||
|  * | ||||
|  * |[<!-- language="C" --> | ||||
|  *   ClutterAction *action = clutter_drop_action (); | ||||
|  * | ||||
|  *   g_signal_connect (action, "drop", G_CALLBACK (on_drop), NULL); | ||||
|  *   clutter_actor_add_action (an_actor, action); | ||||
|  * ]| | ||||
|  * | ||||
|  * The #ClutterDropAction::can-drop can be used to control whether the | ||||
|  * #ClutterDropAction::drop signal is going to be emitted; returning %FALSE | ||||
|  * from a handler connected to the #ClutterDropAction::can-drop signal will | ||||
|  * cause the #ClutterDropAction::drop signal to be skipped when the input | ||||
|  * device button is released. | ||||
|  * | ||||
|  * It's important to note that #ClutterDropAction will only work with | ||||
|  * actors dragged using #ClutterDragAction. | ||||
|  * | ||||
|  * See [drop-action.c](https://git.gnome.org/browse/clutter/tree/examples/drop-action.c?h=clutter-1.18) | ||||
|  * for an example of how to use #ClutterDropAction. | ||||
|  * | ||||
|  * #ClutterDropAction is available since Clutter 1.8 | ||||
|  */ | ||||
|  | ||||
| #include "clutter-build-config.h" | ||||
|  | ||||
| #include "clutter-drop-action.h" | ||||
|  | ||||
| #include "clutter-actor-meta-private.h" | ||||
| #include "clutter-actor-private.h" | ||||
| #include "clutter-drag-action.h" | ||||
| #include "clutter-main.h" | ||||
| #include "clutter-marshal.h" | ||||
| #include "clutter-stage-private.h" | ||||
|  | ||||
| struct _ClutterDropActionPrivate | ||||
| { | ||||
|   ClutterActor *actor; | ||||
|   ClutterActor *stage; | ||||
|  | ||||
|   gulong mapped_id; | ||||
| }; | ||||
|  | ||||
| typedef struct _DropTarget { | ||||
|   ClutterActor *stage; | ||||
|  | ||||
|   gulong capture_id; | ||||
|  | ||||
|   GHashTable *actions; | ||||
|  | ||||
|   ClutterDropAction *last_action; | ||||
| } DropTarget; | ||||
|  | ||||
| enum | ||||
| { | ||||
|   CAN_DROP, | ||||
|   OVER_IN, | ||||
|   OVER_OUT, | ||||
|   DROP, | ||||
|   DROP_CANCEL, | ||||
|  | ||||
|   LAST_SIGNAL | ||||
| }; | ||||
|  | ||||
| static guint drop_signals[LAST_SIGNAL] = { 0, }; | ||||
|  | ||||
| G_DEFINE_TYPE_WITH_PRIVATE (ClutterDropAction, clutter_drop_action, CLUTTER_TYPE_ACTION) | ||||
|  | ||||
| static void | ||||
| drop_target_free (gpointer _data) | ||||
| { | ||||
|   DropTarget *data = _data; | ||||
|  | ||||
|   g_clear_signal_handler (&data->capture_id, data->stage); | ||||
|   g_hash_table_destroy (data->actions); | ||||
|   g_free (data); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| on_stage_capture (ClutterStage *stage, | ||||
|                   ClutterEvent *event, | ||||
|                   gpointer      user_data) | ||||
| { | ||||
|   DropTarget *data = user_data; | ||||
|   gfloat event_x, event_y; | ||||
|   ClutterActor *actor, *drag_actor; | ||||
|   ClutterDropAction *drop_action; | ||||
|   ClutterInputDevice *device; | ||||
|   gboolean was_reactive; | ||||
|  | ||||
|   switch (clutter_event_type (event)) | ||||
|     { | ||||
|     case CLUTTER_MOTION: | ||||
|     case CLUTTER_BUTTON_RELEASE: | ||||
|       if (clutter_event_type (event) == CLUTTER_MOTION && | ||||
|           !(clutter_event_get_state (event) & CLUTTER_BUTTON1_MASK)) | ||||
|         return CLUTTER_EVENT_PROPAGATE; | ||||
|  | ||||
|       if (clutter_event_type (event) == CLUTTER_BUTTON_RELEASE && | ||||
|           clutter_event_get_button (event) != CLUTTER_BUTTON_PRIMARY) | ||||
|         return CLUTTER_EVENT_PROPAGATE; | ||||
|  | ||||
|       device = clutter_event_get_device (event); | ||||
|       drag_actor = _clutter_stage_get_pointer_drag_actor (stage, device); | ||||
|       if (drag_actor == NULL) | ||||
|         return CLUTTER_EVENT_PROPAGATE; | ||||
|       break; | ||||
|  | ||||
|     case CLUTTER_TOUCH_UPDATE: | ||||
|     case CLUTTER_TOUCH_END: | ||||
|       drag_actor = _clutter_stage_get_touch_drag_actor (stage, | ||||
|                                                         clutter_event_get_event_sequence (event)); | ||||
|       if (drag_actor == NULL) | ||||
|         return CLUTTER_EVENT_PROPAGATE; | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       return CLUTTER_EVENT_PROPAGATE; | ||||
|     } | ||||
|  | ||||
|   clutter_event_get_coords (event, &event_x, &event_y); | ||||
|  | ||||
|   /* get the actor under the cursor, excluding the dragged actor; we | ||||
|    * use reactivity because it won't cause any scene invalidation | ||||
|    */ | ||||
|   was_reactive = clutter_actor_get_reactive (drag_actor); | ||||
|   clutter_actor_set_reactive (drag_actor, FALSE); | ||||
|  | ||||
|   actor = clutter_stage_get_actor_at_pos (stage, CLUTTER_PICK_REACTIVE, | ||||
|                                           event_x, | ||||
|                                           event_y); | ||||
|   if (actor == NULL || actor == CLUTTER_ACTOR (stage)) | ||||
|     { | ||||
|       if (data->last_action != NULL) | ||||
|         { | ||||
|           ClutterActorMeta *meta = CLUTTER_ACTOR_META (data->last_action); | ||||
|  | ||||
|           g_signal_emit (data->last_action, drop_signals[OVER_OUT], 0, | ||||
|                          clutter_actor_meta_get_actor (meta)); | ||||
|  | ||||
|           data->last_action = NULL; | ||||
|         } | ||||
|  | ||||
|       goto out; | ||||
|     } | ||||
|  | ||||
|   drop_action = g_hash_table_lookup (data->actions, actor); | ||||
|  | ||||
|   if (drop_action == NULL) | ||||
|     { | ||||
|       if (data->last_action != NULL) | ||||
|         { | ||||
|           ClutterActorMeta *meta = CLUTTER_ACTOR_META (data->last_action); | ||||
|  | ||||
|           g_signal_emit (data->last_action, drop_signals[OVER_OUT], 0, | ||||
|                          clutter_actor_meta_get_actor (meta)); | ||||
|  | ||||
|           data->last_action = NULL; | ||||
|         } | ||||
|  | ||||
|       goto out; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       if (data->last_action != drop_action) | ||||
|         { | ||||
|           ClutterActorMeta *meta; | ||||
|  | ||||
|           if (data->last_action != NULL) | ||||
|             { | ||||
|               meta = CLUTTER_ACTOR_META (data->last_action); | ||||
|  | ||||
|               g_signal_emit (data->last_action, drop_signals[OVER_OUT], 0, | ||||
|                              clutter_actor_meta_get_actor (meta)); | ||||
|             } | ||||
|  | ||||
|           meta = CLUTTER_ACTOR_META (drop_action); | ||||
|  | ||||
|           g_signal_emit (drop_action, drop_signals[OVER_IN], 0, | ||||
|                          clutter_actor_meta_get_actor (meta)); | ||||
|         } | ||||
|  | ||||
|       data->last_action = drop_action; | ||||
|     } | ||||
|  | ||||
| out: | ||||
|   if (clutter_event_type (event) == CLUTTER_BUTTON_RELEASE || | ||||
|       clutter_event_type (event) == CLUTTER_TOUCH_END) | ||||
|     { | ||||
|       if (data->last_action != NULL) | ||||
|         { | ||||
|           ClutterActorMeta *meta = CLUTTER_ACTOR_META (data->last_action); | ||||
|           gboolean can_drop = FALSE; | ||||
|  | ||||
|           g_signal_emit (data->last_action, drop_signals[CAN_DROP], 0, | ||||
|                          clutter_actor_meta_get_actor (meta), | ||||
|                          event_x, event_y, | ||||
|                          &can_drop); | ||||
|  | ||||
|           if (can_drop) | ||||
|             { | ||||
|               g_signal_emit (data->last_action, drop_signals[DROP], 0, | ||||
|                              clutter_actor_meta_get_actor (meta), | ||||
|                              event_x, event_y); | ||||
|             } | ||||
| 	  else | ||||
|             { | ||||
|               g_signal_emit (data->last_action, drop_signals[DROP_CANCEL], 0, | ||||
|                              clutter_actor_meta_get_actor (meta), | ||||
|                              event_x, event_y); | ||||
|             } | ||||
|  | ||||
|         } | ||||
|  | ||||
|       data->last_action = NULL; | ||||
|     } | ||||
|  | ||||
|   if (drag_actor != NULL) | ||||
|     clutter_actor_set_reactive (drag_actor, was_reactive); | ||||
|  | ||||
|   return CLUTTER_EVENT_PROPAGATE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| drop_action_register (ClutterDropAction *self) | ||||
| { | ||||
|   ClutterDropActionPrivate *priv = self->priv; | ||||
|   DropTarget *data; | ||||
|  | ||||
|   g_assert (priv->stage != NULL); | ||||
|  | ||||
|   data = g_object_get_data (G_OBJECT (priv->stage), "__clutter_drop_targets"); | ||||
|   if (data == NULL) | ||||
|     { | ||||
|       data = g_new0 (DropTarget, 1); | ||||
|  | ||||
|       data->stage = priv->stage; | ||||
|       data->actions = g_hash_table_new (NULL, NULL); | ||||
|       data->capture_id = g_signal_connect (priv->stage, "captured-event", | ||||
|                                            G_CALLBACK (on_stage_capture), | ||||
|                                            data); | ||||
|       g_object_set_data_full (G_OBJECT (priv->stage), "__clutter_drop_targets", | ||||
|                               data, | ||||
|                               drop_target_free); | ||||
|     } | ||||
|  | ||||
|   g_hash_table_replace (data->actions, priv->actor, self); | ||||
| } | ||||
|  | ||||
| static void | ||||
| drop_action_unregister (ClutterDropAction *self) | ||||
| { | ||||
|   ClutterDropActionPrivate *priv = self->priv; | ||||
|   DropTarget *data = NULL; | ||||
|  | ||||
|   if (priv->stage != NULL) | ||||
|     data = g_object_get_data (G_OBJECT (priv->stage), "__clutter_drop_targets"); | ||||
|  | ||||
|   if (data == NULL) | ||||
|     return; | ||||
|  | ||||
|   g_hash_table_remove (data->actions, priv->actor); | ||||
|   if (g_hash_table_size (data->actions) == 0) | ||||
|     g_object_set_data (G_OBJECT (data->stage), "__clutter_drop_targets", NULL); | ||||
| } | ||||
|  | ||||
| static void | ||||
| on_actor_mapped (ClutterActor      *actor, | ||||
|                  GParamSpec        *pspec, | ||||
|                  ClutterDropAction *self) | ||||
| { | ||||
|   if (clutter_actor_is_mapped (actor)) | ||||
|     { | ||||
|       if (self->priv->stage == NULL) | ||||
|         self->priv->stage = clutter_actor_get_stage (actor); | ||||
|  | ||||
|       drop_action_register (self); | ||||
|     } | ||||
|   else | ||||
|     drop_action_unregister (self); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_drop_action_set_actor (ClutterActorMeta *meta, | ||||
|                                ClutterActor     *actor) | ||||
| { | ||||
|   ClutterDropActionPrivate *priv = CLUTTER_DROP_ACTION (meta)->priv; | ||||
|  | ||||
|   if (priv->actor != NULL) | ||||
|     { | ||||
|       drop_action_unregister (CLUTTER_DROP_ACTION (meta)); | ||||
|  | ||||
|       g_clear_signal_handler (&priv->mapped_id, priv->actor); | ||||
|  | ||||
|       priv->stage = NULL; | ||||
|       priv->actor = NULL; | ||||
|     } | ||||
|  | ||||
|   priv->actor = actor; | ||||
|  | ||||
|   if (priv->actor != NULL) | ||||
|     { | ||||
|       priv->stage = clutter_actor_get_stage (actor); | ||||
|       priv->mapped_id = g_signal_connect (actor, "notify::mapped", | ||||
|                                           G_CALLBACK (on_actor_mapped), | ||||
|                                           meta); | ||||
|  | ||||
|       if (priv->stage != NULL) | ||||
|         drop_action_register (CLUTTER_DROP_ACTION (meta)); | ||||
|     } | ||||
|  | ||||
|   CLUTTER_ACTOR_META_CLASS (clutter_drop_action_parent_class)->set_actor (meta, actor); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| signal_accumulator (GSignalInvocationHint *ihint, | ||||
|                     GValue                *return_accu, | ||||
|                     const GValue          *handler_return, | ||||
|                     gpointer               user_data) | ||||
| { | ||||
|   gboolean continue_emission; | ||||
|  | ||||
|   continue_emission = g_value_get_boolean (handler_return); | ||||
|   g_value_set_boolean (return_accu, continue_emission); | ||||
|  | ||||
|   return continue_emission; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| clutter_drop_action_real_can_drop (ClutterDropAction *action, | ||||
|                                    ClutterActor      *actor, | ||||
|                                    gfloat             event_x, | ||||
|                                    gfloat             event_y) | ||||
| { | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_drop_action_class_init (ClutterDropActionClass *klass) | ||||
| { | ||||
|   ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass); | ||||
|  | ||||
|   meta_class->set_actor = clutter_drop_action_set_actor; | ||||
|  | ||||
|   klass->can_drop = clutter_drop_action_real_can_drop; | ||||
|  | ||||
|   /** | ||||
|    * ClutterDropAction::can-drop: | ||||
|    * @action: the #ClutterDropAction that emitted the signal | ||||
|    * @actor: the #ClutterActor attached to the @action | ||||
|    * @event_x: the X coordinate (in stage space) of the drop event | ||||
|    * @event_y: the Y coordinate (in stage space) of the drop event | ||||
|    * | ||||
|    * The ::can-drop signal is emitted when the dragged actor is dropped | ||||
|    * on @actor. The return value of the ::can-drop signal will determine | ||||
|    * whether or not the #ClutterDropAction::drop signal is going to be | ||||
|    * emitted on @action. | ||||
|    * | ||||
|    * The default implementation of #ClutterDropAction returns %TRUE for | ||||
|    * this signal. | ||||
|    * | ||||
|    * Return value: %TRUE if the drop is accepted, and %FALSE otherwise | ||||
|    * | ||||
|    * Since: 1.8 | ||||
|    */ | ||||
|   drop_signals[CAN_DROP] = | ||||
|     g_signal_new (I_("can-drop"), | ||||
|                   G_TYPE_FROM_CLASS (klass), | ||||
|                   G_SIGNAL_RUN_LAST, | ||||
|                   G_STRUCT_OFFSET (ClutterDropActionClass, can_drop), | ||||
|                   signal_accumulator, NULL, | ||||
|                   _clutter_marshal_BOOLEAN__OBJECT_FLOAT_FLOAT, | ||||
|                   G_TYPE_BOOLEAN, 3, | ||||
|                   CLUTTER_TYPE_ACTOR, | ||||
|                   G_TYPE_FLOAT, | ||||
|                   G_TYPE_FLOAT); | ||||
|  | ||||
|   /** | ||||
|    * ClutterDropAction::over-in: | ||||
|    * @action: the #ClutterDropAction that emitted the signal | ||||
|    * @actor: the #ClutterActor attached to the @action | ||||
|    * | ||||
|    * The ::over-in signal is emitted when the dragged actor crosses | ||||
|    * into @actor. | ||||
|    * | ||||
|    * Since: 1.8 | ||||
|    */ | ||||
|   drop_signals[OVER_IN] = | ||||
|     g_signal_new (I_("over-in"), | ||||
|                   G_TYPE_FROM_CLASS (klass), | ||||
|                   G_SIGNAL_RUN_LAST, | ||||
|                   G_STRUCT_OFFSET (ClutterDropActionClass, over_in), | ||||
|                   NULL, NULL, NULL, | ||||
|                   G_TYPE_NONE, 1, | ||||
|                   CLUTTER_TYPE_ACTOR); | ||||
|  | ||||
|   /** | ||||
|    * ClutterDropAction::over-out: | ||||
|    * @action: the #ClutterDropAction that emitted the signal | ||||
|    * @actor: the #ClutterActor attached to the @action | ||||
|    * | ||||
|    * The ::over-out signal is emitted when the dragged actor crosses | ||||
|    * outside @actor. | ||||
|    * | ||||
|    * Since: 1.8 | ||||
|    */ | ||||
|   drop_signals[OVER_OUT] = | ||||
|     g_signal_new (I_("over-out"), | ||||
|                   G_TYPE_FROM_CLASS (klass), | ||||
|                   G_SIGNAL_RUN_LAST, | ||||
|                   G_STRUCT_OFFSET (ClutterDropActionClass, over_out), | ||||
|                   NULL, NULL, NULL, | ||||
|                   G_TYPE_NONE, 1, | ||||
|                   CLUTTER_TYPE_ACTOR); | ||||
|  | ||||
|   /** | ||||
|    * ClutterDropAction::drop: | ||||
|    * @action: the #ClutterDropAction that emitted the signal | ||||
|    * @actor: the #ClutterActor attached to the @action | ||||
|    * @event_x: the X coordinate (in stage space) of the drop event | ||||
|    * @event_y: the Y coordinate (in stage space) of the drop event | ||||
|    * | ||||
|    * The ::drop signal is emitted when the dragged actor is dropped | ||||
|    * on @actor. This signal is only emitted if at least an handler of | ||||
|    * #ClutterDropAction::can-drop returns %TRUE. | ||||
|    * | ||||
|    * Since: 1.8 | ||||
|    */ | ||||
|   drop_signals[DROP] = | ||||
|     g_signal_new (I_("drop"), | ||||
|                   G_TYPE_FROM_CLASS (klass), | ||||
|                   G_SIGNAL_RUN_LAST, | ||||
|                   G_STRUCT_OFFSET (ClutterDropActionClass, drop), | ||||
|                   NULL, NULL, | ||||
|                   _clutter_marshal_VOID__OBJECT_FLOAT_FLOAT, | ||||
|                   G_TYPE_NONE, 3, | ||||
|                   CLUTTER_TYPE_ACTOR, | ||||
|                   G_TYPE_FLOAT, | ||||
|                   G_TYPE_FLOAT); | ||||
|  | ||||
|  | ||||
|   /** | ||||
|    * ClutterDropAction::drop-cancel: | ||||
|    * @action: the #ClutterDropAction that emitted the signal | ||||
|    * @actor: the #ClutterActor attached to the @action | ||||
|    * @event_x: the X coordinate (in stage space) of the drop event | ||||
|    * @event_y: the Y coordinate (in stage space) of the drop event | ||||
|    * | ||||
|    * The ::drop-cancel signal is emitted when the drop is refused | ||||
|    * by an emission of the #ClutterDropAction::can-drop signal. | ||||
|    * | ||||
|    * After the ::drop-cancel signal is fired the active drag is | ||||
|    * terminated. | ||||
|    * | ||||
|    * Since: 1.12 | ||||
|    */ | ||||
|   drop_signals[DROP_CANCEL] = | ||||
|     g_signal_new (I_("drop-cancel"), | ||||
|                   G_TYPE_FROM_CLASS (klass), | ||||
|                   G_SIGNAL_RUN_LAST, | ||||
|                   G_STRUCT_OFFSET (ClutterDropActionClass, drop), | ||||
|                   NULL, NULL, | ||||
|                   _clutter_marshal_VOID__OBJECT_FLOAT_FLOAT, | ||||
|                   G_TYPE_NONE, 3, | ||||
|                   CLUTTER_TYPE_ACTOR, | ||||
|                   G_TYPE_FLOAT, | ||||
|                   G_TYPE_FLOAT); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_drop_action_init (ClutterDropAction *self) | ||||
| { | ||||
|   self->priv = clutter_drop_action_get_instance_private (self); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_drop_action_new: | ||||
|  * | ||||
|  * Creates a new #ClutterDropAction. | ||||
|  * | ||||
|  * Use clutter_actor_add_action() to add the action to a #ClutterActor. | ||||
|  * | ||||
|  * Return value: the newly created #ClutterDropAction | ||||
|  * | ||||
|  * Since: 1.8 | ||||
|  */ | ||||
| ClutterAction * | ||||
| clutter_drop_action_new (void) | ||||
| { | ||||
|   return g_object_new (CLUTTER_TYPE_DROP_ACTION, NULL); | ||||
| } | ||||
							
								
								
									
										115
									
								
								clutter/clutter/clutter-drop-action.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								clutter/clutter/clutter-drop-action.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,115 @@ | ||||
| /* | ||||
|  * Clutter. | ||||
|  * | ||||
|  * An OpenGL based 'interactive canvas' library. | ||||
|  * | ||||
|  * Copyright © 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> | ||||
|  */ | ||||
|  | ||||
| #ifndef __CLUTTER_DROP_ACTION_H__ | ||||
| #define __CLUTTER_DROP_ACTION_H__ | ||||
|  | ||||
| #if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <clutter/clutter.h> can be directly included." | ||||
| #endif | ||||
|  | ||||
| #include <clutter/clutter-action.h> | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CLUTTER_TYPE_DROP_ACTION                (clutter_drop_action_get_type ()) | ||||
| #define CLUTTER_DROP_ACTION(obj)                (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_DROP_ACTION, ClutterDropAction)) | ||||
| #define CLUTTER_IS_DROP_ACTION(obj)             (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_DROP_ACTION)) | ||||
| #define CLUTTER_DROP_ACTION_CLASS(klass)        (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_DROP_ACTION, ClutterDropActionClass)) | ||||
| #define CLUTTER_IS_DROP_ACTION_CLASS(klass)     (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_DROP_ACTION)) | ||||
| #define CLUTTER_DROP_ACTION_GET_CLASS(obj)      (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_DROP_ACTION, ClutterDropActionClass)) | ||||
|  | ||||
| typedef struct _ClutterDropAction               ClutterDropAction; | ||||
| typedef struct _ClutterDropActionPrivate        ClutterDropActionPrivate; | ||||
| typedef struct _ClutterDropActionClass          ClutterDropActionClass; | ||||
|  | ||||
| /** | ||||
|  * ClutterDropAction: | ||||
|  * | ||||
|  * The #ClutterDropAction structure contains only | ||||
|  * private data and should be accessed using the provided API. | ||||
|  * | ||||
|  * Since: 1.8 | ||||
|  */ | ||||
| struct _ClutterDropAction | ||||
| { | ||||
|   /*< private >*/ | ||||
|   ClutterAction parent_instance; | ||||
|  | ||||
|   ClutterDropActionPrivate *priv; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * ClutterDropActionClass: | ||||
|  * @can_drop: class handler for the #ClutterDropAction::can-drop signal | ||||
|  * @over_in: class handler for the #ClutterDropAction::over-in signal | ||||
|  * @over_out: class handler for the #ClutterDropAction::over-out signal | ||||
|  * @drop: class handler for the #ClutterDropAction::drop signal | ||||
|  * | ||||
|  * The #ClutterDropActionClass structure contains | ||||
|  * only private data. | ||||
|  * | ||||
|  * Since: 1.8 | ||||
|  */ | ||||
| struct _ClutterDropActionClass | ||||
| { | ||||
|   /*< private >*/ | ||||
|   ClutterActionClass parent_class; | ||||
|  | ||||
|   /*< public >*/ | ||||
|   gboolean (* can_drop) (ClutterDropAction *action, | ||||
|                          ClutterActor      *actor, | ||||
|                          gfloat             event_x, | ||||
|                          gfloat             event_y); | ||||
|  | ||||
|   void     (* over_in)  (ClutterDropAction *action, | ||||
|                          ClutterActor      *actor); | ||||
|   void     (* over_out) (ClutterDropAction *action, | ||||
|                          ClutterActor      *actor); | ||||
|  | ||||
|   void     (* drop)     (ClutterDropAction *action, | ||||
|                          ClutterActor      *actor, | ||||
|                          gfloat             event_x, | ||||
|                          gfloat             event_y); | ||||
|  | ||||
|   /*< private >*/ | ||||
|   void (*_clutter_drop_action1) (void); | ||||
|   void (*_clutter_drop_action2) (void); | ||||
|   void (*_clutter_drop_action3) (void); | ||||
|   void (*_clutter_drop_action4) (void); | ||||
|   void (*_clutter_drop_action5) (void); | ||||
|   void (*_clutter_drop_action6) (void); | ||||
|   void (*_clutter_drop_action7) (void); | ||||
|   void (*_clutter_drop_action8) (void); | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| GType clutter_drop_action_get_type (void) G_GNUC_CONST; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterAction *         clutter_drop_action_new         (void); | ||||
|  | ||||
| G_END_DECLS | ||||
|  | ||||
| #endif /* __CLUTTER_DROP_ACTION_H__ */ | ||||
| @@ -5,11 +5,14 @@ | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| gboolean        _clutter_effect_pre_paint               (ClutterEffect           *effect, | ||||
|                                                          ClutterPaintContext     *paint_context); | ||||
| void            _clutter_effect_post_paint              (ClutterEffect           *effect, | ||||
|                                                          ClutterPaintContext     *paint_context); | ||||
| gboolean        _clutter_effect_modify_paint_volume     (ClutterEffect           *effect, | ||||
|                                                          ClutterPaintVolume      *volume); | ||||
| gboolean        _clutter_effect_has_custom_paint_volume (ClutterEffect           *effect); | ||||
| void            _clutter_effect_paint                   (ClutterEffect           *effect, | ||||
|                                                          ClutterPaintNode        *node, | ||||
|                                                          ClutterPaintContext     *paint_context, | ||||
|                                                          ClutterEffectPaintFlags  flags); | ||||
| void            _clutter_effect_pick                    (ClutterEffect           *effect, | ||||
|   | ||||
| @@ -169,8 +169,6 @@ | ||||
| #include "clutter-effect-private.h" | ||||
| #include "clutter-enum-types.h" | ||||
| #include "clutter-marshal.h" | ||||
| #include "clutter-paint-node-private.h" | ||||
| #include "clutter-paint-nodes.h" | ||||
| #include "clutter-private.h" | ||||
| #include "clutter-actor-private.h" | ||||
|  | ||||
| @@ -180,7 +178,6 @@ G_DEFINE_ABSTRACT_TYPE (ClutterEffect, | ||||
|  | ||||
| static gboolean | ||||
| clutter_effect_real_pre_paint (ClutterEffect       *effect, | ||||
|                                ClutterPaintNode    *node, | ||||
|                                ClutterPaintContext *paint_context) | ||||
| { | ||||
|   return TRUE; | ||||
| @@ -188,7 +185,6 @@ clutter_effect_real_pre_paint (ClutterEffect       *effect, | ||||
|  | ||||
| static void | ||||
| clutter_effect_real_post_paint (ClutterEffect       *effect, | ||||
|                                 ClutterPaintNode    *node, | ||||
|                                 ClutterPaintContext *paint_context) | ||||
| { | ||||
| } | ||||
| @@ -200,54 +196,26 @@ clutter_effect_real_modify_paint_volume (ClutterEffect      *effect, | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| add_actor_node (ClutterEffect    *effect, | ||||
|                 ClutterPaintNode *node) | ||||
| { | ||||
|   ClutterPaintNode *actor_node; | ||||
|   ClutterActor *actor; | ||||
|  | ||||
|   actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect)); | ||||
|  | ||||
|   actor_node = clutter_actor_node_new (actor, -1); | ||||
|   clutter_paint_node_add_child (node, actor_node); | ||||
|   clutter_paint_node_unref (actor_node); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_effect_real_paint_node (ClutterEffect           *effect, | ||||
|                                 ClutterPaintNode        *node, | ||||
|                                 ClutterPaintContext     *paint_context, | ||||
|                                 ClutterEffectPaintFlags  flags) | ||||
| { | ||||
|   add_actor_node (effect, node); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_effect_real_paint (ClutterEffect           *effect, | ||||
|                            ClutterPaintNode        *node, | ||||
|                            ClutterPaintContext     *paint_context, | ||||
|                            ClutterEffectPaintFlags  flags) | ||||
| { | ||||
|   ClutterEffectClass *effect_class = CLUTTER_EFFECT_GET_CLASS (effect); | ||||
|   ClutterActorMeta *actor_meta = CLUTTER_ACTOR_META (effect); | ||||
|   ClutterActor *actor; | ||||
|   gboolean pre_paint_succeeded; | ||||
|  | ||||
|   /* The default implementation provides a compatibility wrapper for | ||||
|      effects that haven't migrated to use the 'paint' virtual yet. This | ||||
|      just calls the old pre and post virtuals before chaining on */ | ||||
|  | ||||
|   pre_paint_succeeded = effect_class->pre_paint (effect, node,paint_context); | ||||
|   pre_paint_succeeded = _clutter_effect_pre_paint (effect, paint_context); | ||||
|  | ||||
|   actor = clutter_actor_meta_get_actor (actor_meta); | ||||
|   clutter_actor_continue_paint (actor, paint_context); | ||||
|  | ||||
|   if (pre_paint_succeeded) | ||||
|     { | ||||
|       effect_class->paint_node (effect, node, paint_context, flags); | ||||
|       effect_class->post_paint (effect, node, paint_context); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       /* Just paint the actor as fallback */ | ||||
|       add_actor_node (effect, node); | ||||
|     } | ||||
|     _clutter_effect_post_paint (effect, paint_context); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -262,32 +230,33 @@ clutter_effect_real_pick (ClutterEffect      *effect, | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_effect_set_enabled (ClutterActorMeta *meta, | ||||
|                             gboolean          is_enabled) | ||||
| clutter_effect_notify (GObject    *gobject, | ||||
|                        GParamSpec *pspec) | ||||
| { | ||||
|   ClutterActorMetaClass *parent_class = | ||||
|     CLUTTER_ACTOR_META_CLASS (clutter_effect_parent_class); | ||||
|   ClutterActor *actor; | ||||
|   if (strcmp (pspec->name, "enabled") == 0) | ||||
|     { | ||||
|       ClutterActorMeta *meta = CLUTTER_ACTOR_META (gobject); | ||||
|       ClutterActor *actor = clutter_actor_meta_get_actor (meta); | ||||
|  | ||||
|   actor = clutter_actor_meta_get_actor (meta); | ||||
|   if (actor) | ||||
|     clutter_actor_queue_redraw (actor); | ||||
|       if (actor != NULL) | ||||
|         clutter_actor_queue_redraw (actor); | ||||
|     } | ||||
|  | ||||
|   parent_class->set_enabled (meta, is_enabled); | ||||
|   if (G_OBJECT_CLASS (clutter_effect_parent_class)->notify != NULL) | ||||
|     G_OBJECT_CLASS (clutter_effect_parent_class)->notify (gobject, pspec); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_effect_class_init (ClutterEffectClass *klass) | ||||
| { | ||||
|   ClutterActorMetaClass *actor_meta_class = CLUTTER_ACTOR_META_CLASS (klass); | ||||
|   GObjectClass *gobject_class = G_OBJECT_CLASS (klass); | ||||
|  | ||||
|   actor_meta_class->set_enabled = clutter_effect_set_enabled; | ||||
|   gobject_class->notify = clutter_effect_notify; | ||||
|  | ||||
|   klass->pre_paint = clutter_effect_real_pre_paint; | ||||
|   klass->post_paint = clutter_effect_real_post_paint; | ||||
|   klass->modify_paint_volume = clutter_effect_real_modify_paint_volume; | ||||
|   klass->paint = clutter_effect_real_paint; | ||||
|   klass->paint_node = clutter_effect_real_paint_node; | ||||
|   klass->pick = clutter_effect_real_pick; | ||||
| } | ||||
|  | ||||
| @@ -296,18 +265,32 @@ clutter_effect_init (ClutterEffect *self) | ||||
| { | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| _clutter_effect_pre_paint (ClutterEffect       *effect, | ||||
|                            ClutterPaintContext *paint_context) | ||||
| { | ||||
|   g_return_val_if_fail (CLUTTER_IS_EFFECT (effect), FALSE); | ||||
|  | ||||
|   return CLUTTER_EFFECT_GET_CLASS (effect)->pre_paint (effect, paint_context); | ||||
| } | ||||
|  | ||||
| void | ||||
| _clutter_effect_post_paint (ClutterEffect       *effect, | ||||
|                             ClutterPaintContext *paint_context) | ||||
| { | ||||
|   g_return_if_fail (CLUTTER_IS_EFFECT (effect)); | ||||
|  | ||||
|   CLUTTER_EFFECT_GET_CLASS (effect)->post_paint (effect, paint_context); | ||||
| } | ||||
|  | ||||
| void | ||||
| _clutter_effect_paint (ClutterEffect           *effect, | ||||
|                        ClutterPaintNode        *node, | ||||
|                        ClutterPaintContext     *paint_context, | ||||
|                        ClutterEffectPaintFlags  flags) | ||||
| { | ||||
|   g_return_if_fail (CLUTTER_IS_EFFECT (effect)); | ||||
|  | ||||
|   CLUTTER_EFFECT_GET_CLASS (effect)->paint (effect, | ||||
|                                             node, | ||||
|                                             paint_context, | ||||
|                                             flags); | ||||
|   CLUTTER_EFFECT_GET_CLASS (effect)->paint (effect, paint_context, flags); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -368,7 +351,7 @@ _clutter_effect_has_custom_paint_volume (ClutterEffect *effect) | ||||
|  * the actor itself so the %CLUTTER_EFFECT_PAINT_ACTOR_DIRTY would still | ||||
|  * not be set. The effect can detect this case by keeping track of the | ||||
|  * last modelview matrix that was used to render the actor and | ||||
|  * verifying that it remains the same in the next paint. | ||||
|  * veryifying that it remains the same in the next paint. | ||||
|  * | ||||
|  * Any other effects that are layered on top of the passed in effect | ||||
|  * will still be passed the %CLUTTER_EFFECT_PAINT_ACTOR_DIRTY flag. If | ||||
| @@ -392,6 +375,7 @@ clutter_effect_queue_repaint (ClutterEffect *effect) | ||||
|   /* If the effect has no actor then nothing needs to be done */ | ||||
|   if (actor != NULL) | ||||
|     _clutter_actor_queue_redraw_full (actor, | ||||
|                                       0, /* flags */ | ||||
|                                       NULL, /* clip volume */ | ||||
|                                       effect /* effect */); | ||||
| } | ||||
|   | ||||
| @@ -77,21 +77,14 @@ struct _ClutterEffectClass | ||||
|  | ||||
|   /*< public >*/ | ||||
|   gboolean (* pre_paint)           (ClutterEffect           *effect, | ||||
|                                     ClutterPaintNode        *node, | ||||
|                                     ClutterPaintContext     *paint_context); | ||||
|   void     (* post_paint)          (ClutterEffect           *effect, | ||||
|                                     ClutterPaintNode        *node, | ||||
|                                     ClutterPaintContext     *paint_context); | ||||
|  | ||||
|   gboolean (* modify_paint_volume) (ClutterEffect           *effect, | ||||
|                                     ClutterPaintVolume      *volume); | ||||
|  | ||||
|   void     (* paint)               (ClutterEffect           *effect, | ||||
|                                     ClutterPaintNode        *node, | ||||
|                                     ClutterPaintContext     *paint_context, | ||||
|                                     ClutterEffectPaintFlags  flags); | ||||
|   void     (* paint_node)          (ClutterEffect           *effect, | ||||
|                                     ClutterPaintNode        *node, | ||||
|                                     ClutterPaintContext     *paint_context, | ||||
|                                     ClutterEffectPaintFlags  flags); | ||||
|   void     (* pick)                (ClutterEffect           *effect, | ||||
|   | ||||
| @@ -14,9 +14,9 @@ | ||||
| GType | ||||
| @enum_name@_get_type (void) | ||||
| { | ||||
|   static size_t g_enum_type_id = 0; | ||||
|   static volatile gsize g_enum_type_id__volatile = 0; | ||||
|  | ||||
|   if (g_once_init_enter (&g_enum_type_id)) | ||||
|   if (g_once_init_enter (&g_enum_type_id__volatile)) | ||||
|     { | ||||
|       static const G@Type@Value values[] = { | ||||
| /*** END value-header ***/ | ||||
| @@ -28,13 +28,14 @@ GType | ||||
| /*** BEGIN value-tail ***/ | ||||
|         { 0, NULL, NULL } | ||||
|       }; | ||||
|       GType id; | ||||
|       GType g_enum_type_id; | ||||
|  | ||||
|       id = g_@type@_register_static (g_intern_static_string ("@EnumName@"), values); | ||||
|       g_enum_type_id = | ||||
|         g_@type@_register_static (g_intern_static_string ("@EnumName@"), values); | ||||
|  | ||||
|       g_once_init_leave (&g_enum_type_id, id); | ||||
|       g_once_init_leave (&g_enum_type_id__volatile, g_enum_type_id); | ||||
|     } | ||||
|  | ||||
|   return g_enum_type_id; | ||||
|   return g_enum_type_id__volatile; | ||||
| } | ||||
| /*** END value-tail ***/ | ||||
|   | ||||
| @@ -127,7 +127,7 @@ typedef enum /*< prefix=CLUTTER_REQUEST >*/ | ||||
|  * @CLUTTER_EASE_IN_OUT_QUAD: quadratic tweening, combininig | ||||
|  *    %CLUTTER_EASE_IN_QUAD and %CLUTTER_EASE_OUT_QUAD | ||||
|  * @CLUTTER_EASE_IN_CUBIC: cubic tweening | ||||
|  * @CLUTTER_EASE_OUT_CUBIC: cubic tweening, inverse of | ||||
|  * @CLUTTER_EASE_OUT_CUBIC: cubic tweening, invers of | ||||
|  *    %CLUTTER_EASE_IN_CUBIC | ||||
|  * @CLUTTER_EASE_IN_OUT_CUBIC: cubic tweening, combining | ||||
|  *    %CLUTTER_EASE_IN_CUBIC and %CLUTTER_EASE_OUT_CUBIC | ||||
| @@ -190,7 +190,7 @@ typedef enum /*< prefix=CLUTTER_REQUEST >*/ | ||||
|  * @CLUTTER_ANIMATION_LAST: last animation mode, used as a guard for | ||||
|  *   registered global alpha functions | ||||
|  * | ||||
|  * The animation modes used by #ClutterAnimatable. This | ||||
|  * The animation modes used by #ClutterAlpha and #ClutterAnimation. This | ||||
|  * enumeration can be expanded in later versions of Clutter. | ||||
|  * | ||||
|  * <figure id="easing-modes"> | ||||
| @@ -387,6 +387,44 @@ typedef enum | ||||
|   CLUTTER_MODIFIER_MASK = 0x5c001fff | ||||
| } ClutterModifierType; | ||||
|  | ||||
| /** | ||||
|  * ClutterKeyboardA11yFlags: | ||||
|  * @CLUTTER_A11Y_KEYBOARD_ENABLED: | ||||
|  * @CLUTTER_A11Y_TIMEOUT_ENABLED: | ||||
|  * @CLUTTER_A11Y_MOUSE_KEYS_ENABLED: | ||||
|  * @CLUTTER_A11Y_SLOW_KEYS_ENABLED: | ||||
|  * @CLUTTER_A11Y_SLOW_KEYS_BEEP_PRESS: | ||||
|  * @CLUTTER_A11Y_SLOW_KEYS_BEEP_ACCEPT: | ||||
|  * @CLUTTER_A11Y_SLOW_KEYS_BEEP_REJECT: | ||||
|  * @CLUTTER_A11Y_BOUNCE_KEYS_ENABLED: | ||||
|  * @CLUTTER_A11Y_BOUNCE_KEYS_BEEP_REJECT: | ||||
|  * @CLUTTER_A11Y_TOGGLE_KEYS_ENABLED: | ||||
|  * @CLUTTER_A11Y_STICKY_KEYS_ENABLED: | ||||
|  * @CLUTTER_A11Y_STICKY_KEYS_TWO_KEY_OFF: | ||||
|  * @CLUTTER_A11Y_STICKY_KEYS_BEEP: | ||||
|  * @CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP: | ||||
|  * | ||||
|  * Keyboard accessibility features applied to a ClutterInputDevice keyboard. | ||||
|  * | ||||
|  */ | ||||
| typedef enum | ||||
| { | ||||
|   CLUTTER_A11Y_KEYBOARD_ENABLED          = 1 << 0, | ||||
|   CLUTTER_A11Y_TIMEOUT_ENABLED           = 1 << 1, | ||||
|   CLUTTER_A11Y_MOUSE_KEYS_ENABLED        = 1 << 2, | ||||
|   CLUTTER_A11Y_SLOW_KEYS_ENABLED         = 1 << 3, | ||||
|   CLUTTER_A11Y_SLOW_KEYS_BEEP_PRESS      = 1 << 4, | ||||
|   CLUTTER_A11Y_SLOW_KEYS_BEEP_ACCEPT     = 1 << 5, | ||||
|   CLUTTER_A11Y_SLOW_KEYS_BEEP_REJECT     = 1 << 6, | ||||
|   CLUTTER_A11Y_BOUNCE_KEYS_ENABLED       = 1 << 7, | ||||
|   CLUTTER_A11Y_BOUNCE_KEYS_BEEP_REJECT   = 1 << 8, | ||||
|   CLUTTER_A11Y_TOGGLE_KEYS_ENABLED       = 1 << 9, | ||||
|   CLUTTER_A11Y_STICKY_KEYS_ENABLED       = 1 << 10, | ||||
|   CLUTTER_A11Y_STICKY_KEYS_TWO_KEY_OFF   = 1 << 11, | ||||
|   CLUTTER_A11Y_STICKY_KEYS_BEEP          = 1 << 12, | ||||
|   CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP = 1 << 13, | ||||
| } ClutterKeyboardA11yFlags; | ||||
|  | ||||
| /** | ||||
|  * ClutterPointerA11yFlags: | ||||
|  * @CLUTTER_A11Y_POINTER_ENABLED: | ||||
| @@ -475,7 +513,7 @@ typedef enum { | ||||
|  *   a toplevel, and all parents visible) | ||||
|  * @CLUTTER_ACTOR_REALIZED: the resources associated to the actor have been | ||||
|  *   allocated | ||||
|  * @CLUTTER_ACTOR_REACTIVE: the actor 'reacts' to mouse events emitting event | ||||
|  * @CLUTTER_ACTOR_REACTIVE: the actor 'reacts' to mouse events emmitting event | ||||
|  *   signals | ||||
|  * @CLUTTER_ACTOR_VISIBLE: the actor has been shown by the application program | ||||
|  * @CLUTTER_ACTOR_NO_LAYOUT: the actor provides an explicit layout management | ||||
| @@ -516,6 +554,32 @@ typedef enum /*< prefix=CLUTTER_OFFSCREEN_REDIRECT >*/ | ||||
|   CLUTTER_OFFSCREEN_REDIRECT_ON_IDLE               = 1 << 2 | ||||
| } ClutterOffscreenRedirect; | ||||
|  | ||||
| /** | ||||
|  * ClutterAllocationFlags: | ||||
|  * @CLUTTER_ALLOCATION_NONE: No flag set | ||||
|  * @CLUTTER_ABSOLUTE_ORIGIN_CHANGED: Whether the absolute origin of the | ||||
|  *   actor has changed; this implies that any ancestor of the actor has | ||||
|  *   been moved. | ||||
|  * @CLUTTER_DELEGATE_LAYOUT: Whether the allocation should be delegated | ||||
|  *   to the #ClutterLayoutManager instance stored inside the | ||||
|  *   #ClutterActor:layout-manager property of #ClutterActor. This flag | ||||
|  *   should only be used if you are subclassing #ClutterActor and | ||||
|  *   overriding the #ClutterActorClass.allocate() virtual function, but | ||||
|  *   you wish to use the default implementation of the virtual function | ||||
|  *   inside #ClutterActor. Added in Clutter 1.10. | ||||
|  * | ||||
|  * Flags passed to the #ClutterActorClass.allocate() virtual function | ||||
|  * and to the clutter_actor_allocate() function. | ||||
|  * | ||||
|  * Since: 1.0 | ||||
|  */ | ||||
| typedef enum | ||||
| { | ||||
|   CLUTTER_ALLOCATION_NONE         = 0, | ||||
|   CLUTTER_ABSOLUTE_ORIGIN_CHANGED = 1 << 1, | ||||
|   CLUTTER_DELEGATE_LAYOUT         = 1 << 2 | ||||
| } ClutterAllocationFlags; | ||||
|  | ||||
| /** | ||||
|  * ClutterAlignAxis: | ||||
|  * @CLUTTER_ALIGN_X_AXIS: Maintain the alignment on the X axis | ||||
| @@ -802,8 +866,7 @@ typedef enum /*< flags prefix=CLUTTER_EVENT >*/ | ||||
|   CLUTTER_EVENT_NONE              = 0, | ||||
|   CLUTTER_EVENT_FLAG_SYNTHETIC    = 1 << 0, | ||||
|   CLUTTER_EVENT_FLAG_INPUT_METHOD = 1 << 1, | ||||
|   CLUTTER_EVENT_FLAG_REPEATED     = 1 << 2, | ||||
|   CLUTTER_EVENT_FLAG_RELATIVE_MOTION = 1 << 3, | ||||
|   CLUTTER_EVENT_FLAG_REPEATED     = 1 << 2 | ||||
| } ClutterEventFlags; | ||||
|  | ||||
| /** | ||||
| @@ -817,6 +880,10 @@ typedef enum /*< flags prefix=CLUTTER_EVENT >*/ | ||||
|  * @CLUTTER_BUTTON_PRESS: Pointer button press event | ||||
|  * @CLUTTER_BUTTON_RELEASE: Pointer button release event | ||||
|  * @CLUTTER_SCROLL: Pointer scroll event | ||||
|  * @CLUTTER_STAGE_STATE: Stage state change event | ||||
|  * @CLUTTER_DESTROY_NOTIFY: Destroy notification event | ||||
|  * @CLUTTER_CLIENT_MESSAGE: Client message event | ||||
|  * @CLUTTER_DELETE: Stage delete event | ||||
|  * @CLUTTER_TOUCH_BEGIN: A new touch event sequence has started; | ||||
|  *   event added in 1.10 | ||||
|  * @CLUTTER_TOUCH_UPDATE: A touch event sequence has been updated; | ||||
| @@ -829,11 +896,6 @@ typedef enum /*< flags prefix=CLUTTER_EVENT >*/ | ||||
|  *   determined by its phase field; event added in 1.24 | ||||
|  * @CLUTTER_TOUCHPAD_SWIPE: A swipe gesture event, the current state is | ||||
|  *   determined by its phase field; event added in 1.24 | ||||
|  * @CLUTTER_TOUCHPAD_HOLD: A hold gesture event, the current state is | ||||
|  *   determined by its phase field. A hold gesture starts when the user places a | ||||
|  *   finger on the touchpad and ends when all fingers are lifted. It is | ||||
|  *   cancelled when the finger(s) move past a certain threshold. | ||||
|  *   Event added in 40.4 | ||||
|  * @CLUTTER_PROXIMITY_IN: A tool entered in proximity to a tablet; | ||||
|  *   event added in 1.28 | ||||
|  * @CLUTTER_PROXIMITY_OUT: A tool left from the proximity area of a tablet; | ||||
| @@ -856,24 +918,22 @@ typedef enum /*< prefix=CLUTTER >*/ | ||||
|   CLUTTER_BUTTON_PRESS, | ||||
|   CLUTTER_BUTTON_RELEASE, | ||||
|   CLUTTER_SCROLL, | ||||
|   CLUTTER_STAGE_STATE, | ||||
|   CLUTTER_DESTROY_NOTIFY, | ||||
|   CLUTTER_CLIENT_MESSAGE, | ||||
|   CLUTTER_DELETE, | ||||
|   CLUTTER_TOUCH_BEGIN, | ||||
|   CLUTTER_TOUCH_UPDATE, | ||||
|   CLUTTER_TOUCH_END, | ||||
|   CLUTTER_TOUCH_CANCEL, | ||||
|   CLUTTER_TOUCHPAD_PINCH, | ||||
|   CLUTTER_TOUCHPAD_SWIPE, | ||||
|   CLUTTER_TOUCHPAD_HOLD, | ||||
|   CLUTTER_PROXIMITY_IN, | ||||
|   CLUTTER_PROXIMITY_OUT, | ||||
|   CLUTTER_PAD_BUTTON_PRESS, | ||||
|   CLUTTER_PAD_BUTTON_RELEASE, | ||||
|   CLUTTER_PAD_STRIP, | ||||
|   CLUTTER_PAD_RING, | ||||
|   CLUTTER_DEVICE_ADDED, | ||||
|   CLUTTER_DEVICE_REMOVED, | ||||
|   CLUTTER_IM_COMMIT, | ||||
|   CLUTTER_IM_DELETE, | ||||
|   CLUTTER_IM_PREEDIT, | ||||
|  | ||||
|   CLUTTER_EVENT_LAST            /* helper */ | ||||
| } ClutterEventType; | ||||
| @@ -902,9 +962,28 @@ typedef enum /*< prefix=CLUTTER_SCROLL >*/ | ||||
|   CLUTTER_SCROLL_SMOOTH | ||||
| } ClutterScrollDirection; | ||||
|  | ||||
| /** | ||||
|  * ClutterStageState: | ||||
|  * @CLUTTER_STAGE_STATE_ACTIVATED: Activated mask | ||||
|  * | ||||
|  * Stage state masks, used by the #ClutterEvent of type %CLUTTER_STAGE_STATE. | ||||
|  * | ||||
|  * Since: 0.4 | ||||
|  */ | ||||
| typedef enum | ||||
| { | ||||
|   CLUTTER_STAGE_STATE_ACTIVATED        = (1 << 3) | ||||
| } ClutterStageState; | ||||
|  | ||||
| /** | ||||
|  * ClutterFeatureFlags: | ||||
|  * @CLUTTER_FEATURE_SWAP_THROTTLE: Set if backend throttles buffer swaps. | ||||
|  * @CLUTTER_FEATURE_STAGE_STATIC: Set if stage size if fixed (i.e framebuffer) | ||||
|  * @CLUTTER_FEATURE_STAGE_CURSOR: Set if stage has a graphical cursor. | ||||
|  * @CLUTTER_FEATURE_SHADERS_GLSL: Set if the backend supports GLSL shaders. | ||||
|  * @CLUTTER_FEATURE_OFFSCREEN: Set if the backend supports offscreen rendering. | ||||
|  * @CLUTTER_FEATURE_STAGE_MULTIPLE: Set if multiple stages are supported. | ||||
|  * @CLUTTER_FEATURE_SWAP_EVENTS: Set if the GLX_INTEL_swap_event is supported. | ||||
|  * | ||||
|  * Runtime flags indicating specific features available via Clutter window | ||||
|  * system and graphics backend. | ||||
| @@ -913,7 +992,13 @@ typedef enum /*< prefix=CLUTTER_SCROLL >*/ | ||||
|  */ | ||||
| typedef enum | ||||
| { | ||||
|   CLUTTER_FEATURE_SWAP_THROTTLE          = (1 << 3), | ||||
|   CLUTTER_FEATURE_STAGE_STATIC           = (1 << 6), | ||||
|   CLUTTER_FEATURE_STAGE_CURSOR           = (1 << 8), | ||||
|   CLUTTER_FEATURE_SHADERS_GLSL           = (1 << 9), | ||||
|   CLUTTER_FEATURE_OFFSCREEN              = (1 << 10), | ||||
|   CLUTTER_FEATURE_STAGE_MULTIPLE         = (1 << 11), | ||||
|   CLUTTER_FEATURE_SWAP_EVENTS            = (1 << 12) | ||||
| } ClutterFeatureFlags; | ||||
|  | ||||
| /** | ||||
| @@ -975,11 +1060,11 @@ typedef enum | ||||
|  | ||||
| /** | ||||
|  * ClutterInputMode: | ||||
|  * @CLUTTER_INPUT_MODE_LOGICAL: A logical, virtual device | ||||
|  * @CLUTTER_INPUT_MODE_PHYSICAL: A physical device, attached to | ||||
|  *   a logical device | ||||
|  * @CLUTTER_INPUT_MODE_FLOATING: A physical device, not attached | ||||
|  *   to a logical device | ||||
|  * @CLUTTER_INPUT_MODE_MASTER: A master, virtual device | ||||
|  * @CLUTTER_INPUT_MODE_SLAVE: A slave, physical device, attached to | ||||
|  *   a master device | ||||
|  * @CLUTTER_INPUT_MODE_FLOATING: A slave, physical device, not attached | ||||
|  *   to a master device | ||||
|  * | ||||
|  * The mode for input devices available. | ||||
|  * | ||||
| @@ -987,8 +1072,8 @@ typedef enum | ||||
|  */ | ||||
| typedef enum | ||||
| { | ||||
|   CLUTTER_INPUT_MODE_LOGICAL, | ||||
|   CLUTTER_INPUT_MODE_PHYSICAL, | ||||
|   CLUTTER_INPUT_MODE_MASTER, | ||||
|   CLUTTER_INPUT_MODE_SLAVE, | ||||
|   CLUTTER_INPUT_MODE_FLOATING | ||||
| } ClutterInputMode; | ||||
|  | ||||
| @@ -1028,20 +1113,6 @@ typedef enum | ||||
|   CLUTTER_INPUT_AXIS_LAST | ||||
| } ClutterInputAxis; | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   CLUTTER_INPUT_AXIS_FLAG_NONE = 0, | ||||
|   CLUTTER_INPUT_AXIS_FLAG_X = 1 << CLUTTER_INPUT_AXIS_X, | ||||
|   CLUTTER_INPUT_AXIS_FLAG_Y = 1 << CLUTTER_INPUT_AXIS_Y, | ||||
|   CLUTTER_INPUT_AXIS_FLAG_PRESSURE = 1 << CLUTTER_INPUT_AXIS_PRESSURE, | ||||
|   CLUTTER_INPUT_AXIS_FLAG_XTILT = 1 << CLUTTER_INPUT_AXIS_XTILT, | ||||
|   CLUTTER_INPUT_AXIS_FLAG_YTILT = 1 << CLUTTER_INPUT_AXIS_YTILT, | ||||
|   CLUTTER_INPUT_AXIS_FLAG_WHEEL = 1 << CLUTTER_INPUT_AXIS_WHEEL, | ||||
|   CLUTTER_INPUT_AXIS_FLAG_DISTANCE = 1 << CLUTTER_INPUT_AXIS_DISTANCE, | ||||
|   CLUTTER_INPUT_AXIS_FLAG_ROTATION = 1 << CLUTTER_INPUT_AXIS_ROTATION, | ||||
|   CLUTTER_INPUT_AXIS_FLAG_SLIDER = 1 << CLUTTER_INPUT_AXIS_SLIDER, | ||||
| } ClutterInputAxisFlags; | ||||
|  | ||||
| /** | ||||
|  * ClutterSnapEdge: | ||||
|  * @CLUTTER_SNAP_EDGE_TOP: the top edge | ||||
| @@ -1155,7 +1226,7 @@ typedef enum /*< prefix=CLUTTER_TEXTURE >*/ | ||||
|  * | ||||
|  * Since: 0.8 | ||||
|  * | ||||
|  * Deprecated: 1.22: The #ClutterTexture class was the only user of | ||||
|  * Deprecated: 1.22: The #ClutterTexture class was the only used ot | ||||
|  *   this API; use #ClutterImage and clutter_actor_set_content_scaling_filters() | ||||
|  *   instead. | ||||
|  */ | ||||
| @@ -1272,6 +1343,8 @@ typedef enum | ||||
|  *   painting the stages | ||||
|  * @CLUTTER_REPAINT_FLAGS_POST_PAINT: Run the repaint function after | ||||
|  *   painting the stages | ||||
|  * @CLUTTER_REPAINT_FLAGS_QUEUE_REDRAW_ON_ADD: Ensure that a new frame | ||||
|  *   is queued after adding the repaint function | ||||
|  * | ||||
|  * Flags to pass to clutter_threads_add_repaint_func_full(). | ||||
|  * | ||||
| @@ -1281,6 +1354,7 @@ typedef enum | ||||
| { | ||||
|   CLUTTER_REPAINT_FLAGS_PRE_PAINT = 1 << 0, | ||||
|   CLUTTER_REPAINT_FLAGS_POST_PAINT = 1 << 1, | ||||
|   CLUTTER_REPAINT_FLAGS_QUEUE_REDRAW_ON_ADD = 1 << 2 | ||||
| } ClutterRepaintFlags; | ||||
|  | ||||
| /** | ||||
| @@ -1435,6 +1509,24 @@ typedef enum | ||||
|   CLUTTER_STEP_MODE_END | ||||
| } ClutterStepMode; | ||||
|  | ||||
| /** | ||||
|  * ClutterZoomAxis: | ||||
|  * @CLUTTER_ZOOM_X_AXIS: Scale only on the X axis | ||||
|  * @CLUTTER_ZOOM_Y_AXIS: Scale only on the Y axis | ||||
|  * @CLUTTER_ZOOM_BOTH: Scale on both axis | ||||
|  * | ||||
|  * The axis of the constraint that should be applied by the | ||||
|  * zooming action. | ||||
|  * | ||||
|  * Since: 1.12 | ||||
|  */ | ||||
| typedef enum /*< prefix=CLUTTER_ZOOM >*/ | ||||
| { | ||||
|   CLUTTER_ZOOM_X_AXIS, | ||||
|   CLUTTER_ZOOM_Y_AXIS, | ||||
|   CLUTTER_ZOOM_BOTH | ||||
| } ClutterZoomAxis; | ||||
|  | ||||
| /** | ||||
|  * ClutterGestureTriggerEdge: | ||||
|  * @CLUTTER_GESTURE_TRIGGER_EDGE_NONE: Tell #ClutterGestureAction that | ||||
| @@ -1573,10 +1665,9 @@ typedef enum | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   CLUTTER_PAD_FEATURE_BUTTON, | ||||
|   CLUTTER_PAD_FEATURE_RING, | ||||
|   CLUTTER_PAD_FEATURE_STRIP, | ||||
| } ClutterInputDevicePadFeature; | ||||
|   CLUTTER_INPUT_DEVICE_MAPPING_ABSOLUTE, | ||||
|   CLUTTER_INPUT_DEVICE_MAPPING_RELATIVE, | ||||
| } ClutterInputDeviceMapping; | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
| @@ -1616,18 +1707,6 @@ typedef enum | ||||
|   CLUTTER_INPUT_PANEL_STATE_TOGGLE, | ||||
| } ClutterInputPanelState; | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   CLUTTER_PREEDIT_RESET_CLEAR, | ||||
|   CLUTTER_PREEDIT_RESET_COMMIT, | ||||
| } ClutterPreeditResetMode; | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   CLUTTER_PHASE_CAPTURE, | ||||
|   CLUTTER_PHASE_BUBBLE, | ||||
| } ClutterEventPhase; | ||||
|  | ||||
| G_END_DECLS | ||||
|  | ||||
| #endif /* __CLUTTER_ENUMS_H__ */ | ||||
|   | ||||
| @@ -18,6 +18,7 @@ gboolean        _clutter_event_process_filters          (ClutterEvent       *eve | ||||
|  | ||||
| /* clears the event queue inside the main context */ | ||||
| void            _clutter_clear_events_queue             (void); | ||||
| void            _clutter_clear_events_queue_for_stage   (ClutterStage       *stage); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void            _clutter_event_set_platform_data        (ClutterEvent       *event, | ||||
|   | ||||
| @@ -73,6 +73,8 @@ typedef struct _ClutterEventFilter { | ||||
|   gpointer user_data; | ||||
| } ClutterEventFilter; | ||||
|  | ||||
| static GHashTable *all_events = NULL; | ||||
|  | ||||
| G_DEFINE_BOXED_TYPE (ClutterEvent, clutter_event, | ||||
|                      clutter_event_copy, | ||||
|                      clutter_event_free); | ||||
| @@ -94,6 +96,15 @@ G_DEFINE_BOXED_TYPE (ClutterEventSequence, clutter_event_sequence, | ||||
|                      clutter_event_sequence_copy, | ||||
|                      clutter_event_sequence_free); | ||||
|  | ||||
| static gboolean | ||||
| is_event_allocated (const ClutterEvent *event) | ||||
| { | ||||
|   if (all_events == NULL) | ||||
|     return FALSE; | ||||
|  | ||||
|   return g_hash_table_lookup (all_events, event) != NULL; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * _clutter_event_get_platform_data: | ||||
|  * @event: a #ClutterEvent | ||||
| @@ -107,6 +118,9 @@ G_DEFINE_BOXED_TYPE (ClutterEventSequence, clutter_event_sequence, | ||||
| gpointer | ||||
| _clutter_event_get_platform_data (const ClutterEvent *event) | ||||
| { | ||||
|   if (!is_event_allocated (event)) | ||||
|     return NULL; | ||||
|  | ||||
|   return ((ClutterEventPrivate *) event)->platform_data; | ||||
| } | ||||
|  | ||||
| @@ -123,6 +137,9 @@ void | ||||
| _clutter_event_set_platform_data (ClutterEvent *event, | ||||
|                                   gpointer      data) | ||||
| { | ||||
|   if (!is_event_allocated (event)) | ||||
|     return; | ||||
|  | ||||
|   ((ClutterEventPrivate *) event)->platform_data = data; | ||||
| } | ||||
|  | ||||
| @@ -130,6 +147,9 @@ void | ||||
| _clutter_event_set_pointer_emulated (ClutterEvent *event, | ||||
|                                      gboolean      is_emulated) | ||||
| { | ||||
|   if (!is_event_allocated (event)) | ||||
|     return; | ||||
|  | ||||
|   ((ClutterEventPrivate *) event)->is_pointer_emulated = !!is_emulated; | ||||
| } | ||||
|  | ||||
| @@ -384,6 +404,10 @@ clutter_event_get_position (const ClutterEvent *event, | ||||
|     case CLUTTER_NOTHING: | ||||
|     case CLUTTER_KEY_PRESS: | ||||
|     case CLUTTER_KEY_RELEASE: | ||||
|     case CLUTTER_STAGE_STATE: | ||||
|     case CLUTTER_DESTROY_NOTIFY: | ||||
|     case CLUTTER_CLIENT_MESSAGE: | ||||
|     case CLUTTER_DELETE: | ||||
|     case CLUTTER_EVENT_LAST: | ||||
|     case CLUTTER_PROXIMITY_IN: | ||||
|     case CLUTTER_PROXIMITY_OUT: | ||||
| @@ -391,11 +415,6 @@ clutter_event_get_position (const ClutterEvent *event, | ||||
|     case CLUTTER_PAD_BUTTON_RELEASE: | ||||
|     case CLUTTER_PAD_STRIP: | ||||
|     case CLUTTER_PAD_RING: | ||||
|     case CLUTTER_DEVICE_ADDED: | ||||
|     case CLUTTER_DEVICE_REMOVED: | ||||
|     case CLUTTER_IM_COMMIT: | ||||
|     case CLUTTER_IM_DELETE: | ||||
|     case CLUTTER_IM_PREEDIT: | ||||
|       graphene_point_init (position, 0.f, 0.f); | ||||
|       break; | ||||
|  | ||||
| @@ -433,11 +452,6 @@ clutter_event_get_position (const ClutterEvent *event, | ||||
|       graphene_point_init (position, event->touchpad_swipe.x, | ||||
|                            event->touchpad_swipe.y); | ||||
|       break; | ||||
|  | ||||
|     case CLUTTER_TOUCHPAD_HOLD: | ||||
|       graphene_point_init (position, event->touchpad_hold.x, | ||||
|                            event->touchpad_hold.y); | ||||
|       break; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -464,6 +478,10 @@ clutter_event_set_coords (ClutterEvent *event, | ||||
|     case CLUTTER_NOTHING: | ||||
|     case CLUTTER_KEY_PRESS: | ||||
|     case CLUTTER_KEY_RELEASE: | ||||
|     case CLUTTER_STAGE_STATE: | ||||
|     case CLUTTER_DESTROY_NOTIFY: | ||||
|     case CLUTTER_CLIENT_MESSAGE: | ||||
|     case CLUTTER_DELETE: | ||||
|     case CLUTTER_EVENT_LAST: | ||||
|     case CLUTTER_PROXIMITY_IN: | ||||
|     case CLUTTER_PROXIMITY_OUT: | ||||
| @@ -471,11 +489,6 @@ clutter_event_set_coords (ClutterEvent *event, | ||||
|     case CLUTTER_PAD_BUTTON_RELEASE: | ||||
|     case CLUTTER_PAD_STRIP: | ||||
|     case CLUTTER_PAD_RING: | ||||
|     case CLUTTER_DEVICE_ADDED: | ||||
|     case CLUTTER_DEVICE_REMOVED: | ||||
|     case CLUTTER_IM_COMMIT: | ||||
|     case CLUTTER_IM_DELETE: | ||||
|     case CLUTTER_IM_PREEDIT: | ||||
|       break; | ||||
|  | ||||
|     case CLUTTER_ENTER: | ||||
| @@ -517,11 +530,6 @@ clutter_event_set_coords (ClutterEvent *event, | ||||
|       event->touchpad_swipe.x = x; | ||||
|       event->touchpad_swipe.y = y; | ||||
|       break; | ||||
|  | ||||
|     case CLUTTER_TOUCHPAD_HOLD: | ||||
|       event->touchpad_hold.x = x; | ||||
|       event->touchpad_hold.y = y; | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -707,6 +715,9 @@ clutter_event_set_scroll_delta (ClutterEvent *event, | ||||
|   g_return_if_fail (event != NULL); | ||||
|   g_return_if_fail (event->type == CLUTTER_SCROLL); | ||||
|  | ||||
|   if (!is_event_allocated (event)) | ||||
|     return; | ||||
|  | ||||
|   event->scroll.direction = CLUTTER_SCROLL_SMOOTH; | ||||
|  | ||||
|   ((ClutterEventPrivate *) event)->delta_x = dx; | ||||
| @@ -737,8 +748,13 @@ clutter_event_get_scroll_delta (const ClutterEvent *event, | ||||
|   g_return_if_fail (event->type == CLUTTER_SCROLL); | ||||
|   g_return_if_fail (event->scroll.direction == CLUTTER_SCROLL_SMOOTH); | ||||
|  | ||||
|   delta_x = ((ClutterEventPrivate *) event)->delta_x; | ||||
|   delta_y = ((ClutterEventPrivate *) event)->delta_y; | ||||
|   delta_x = delta_y = 0; | ||||
|  | ||||
|   if (is_event_allocated (event)) | ||||
|     { | ||||
|       delta_x = ((ClutterEventPrivate *) event)->delta_x; | ||||
|       delta_y = ((ClutterEventPrivate *) event)->delta_y; | ||||
|     } | ||||
|  | ||||
|   if (dx != NULL) | ||||
|     *dx = delta_x; | ||||
| @@ -833,6 +849,27 @@ clutter_event_set_button (ClutterEvent *event, | ||||
|   event->button.button = button; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_event_get_click_count: | ||||
|  * @event: a #ClutterEvent of type %CLUTTER_BUTTON_PRESS or | ||||
|  *   of type %CLUTTER_BUTTON_RELEASE | ||||
|  * | ||||
|  * Retrieves the number of clicks of @event | ||||
|  * | ||||
|  * Return value: the click count | ||||
|  * | ||||
|  * Since: 1.0 | ||||
|  */ | ||||
| guint32 | ||||
| clutter_event_get_click_count (const ClutterEvent *event) | ||||
| { | ||||
|   g_return_val_if_fail (event != NULL, 0); | ||||
|   g_return_val_if_fail (event->type == CLUTTER_BUTTON_PRESS || | ||||
|                         event->type == CLUTTER_BUTTON_RELEASE, 0); | ||||
|  | ||||
|   return event->button.click_count; | ||||
| } | ||||
|  | ||||
| /* keys */ | ||||
|  | ||||
| /** | ||||
| @@ -991,6 +1028,29 @@ clutter_event_get_event_sequence (const ClutterEvent *event) | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_event_get_device_id: | ||||
|  * @event: a clutter event  | ||||
|  * | ||||
|  * Retrieves the events device id if set. | ||||
|  * | ||||
|  * Return value: A unique identifier for the device or -1 if the event has | ||||
|  *   no specific device set. | ||||
|  */ | ||||
| gint | ||||
| clutter_event_get_device_id (const ClutterEvent *event) | ||||
| { | ||||
|   ClutterInputDevice *device = NULL; | ||||
|  | ||||
|   g_return_val_if_fail (event != NULL, CLUTTER_POINTER_DEVICE); | ||||
|  | ||||
|   device = clutter_event_get_device (event); | ||||
|   if (device != NULL) | ||||
|     return clutter_input_device_get_device_id (device); | ||||
|  | ||||
|   return -1; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_event_get_device_type: | ||||
|  * @event: a #ClutterEvent | ||||
| @@ -1029,20 +1089,24 @@ void | ||||
| clutter_event_set_device (ClutterEvent       *event, | ||||
|                           ClutterInputDevice *device) | ||||
| { | ||||
|   ClutterEventPrivate *real_event = (ClutterEventPrivate *) event; | ||||
|  | ||||
|   g_return_if_fail (event != NULL); | ||||
|   g_return_if_fail (device == NULL || CLUTTER_IS_INPUT_DEVICE (device)); | ||||
|  | ||||
|   g_set_object (&real_event->device, device); | ||||
|   if (is_event_allocated (event)) | ||||
|     { | ||||
|       ClutterEventPrivate *real_event = (ClutterEventPrivate *) event; | ||||
|  | ||||
|       g_set_object (&real_event->device, device); | ||||
|     } | ||||
|  | ||||
|   switch (event->type) | ||||
|     { | ||||
|     case CLUTTER_NOTHING: | ||||
|     case CLUTTER_STAGE_STATE: | ||||
|     case CLUTTER_DESTROY_NOTIFY: | ||||
|     case CLUTTER_CLIENT_MESSAGE: | ||||
|     case CLUTTER_DELETE: | ||||
|     case CLUTTER_EVENT_LAST: | ||||
|     case CLUTTER_IM_COMMIT: | ||||
|     case CLUTTER_IM_DELETE: | ||||
|     case CLUTTER_IM_PREEDIT: | ||||
|       break; | ||||
|  | ||||
|     case CLUTTER_ENTER: | ||||
| @@ -1077,7 +1141,6 @@ clutter_event_set_device (ClutterEvent       *event, | ||||
|  | ||||
|     case CLUTTER_TOUCHPAD_PINCH: | ||||
|     case CLUTTER_TOUCHPAD_SWIPE: | ||||
|     case CLUTTER_TOUCHPAD_HOLD: | ||||
|       /* Rely on priv data for these */ | ||||
|       break; | ||||
|  | ||||
| @@ -1098,11 +1161,6 @@ clutter_event_set_device (ClutterEvent       *event, | ||||
|     case CLUTTER_PAD_RING: | ||||
|       event->pad_ring.device = device; | ||||
|       break; | ||||
|  | ||||
|     case CLUTTER_DEVICE_ADDED: | ||||
|     case CLUTTER_DEVICE_REMOVED: | ||||
|       event->device.device = device; | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -1127,19 +1185,24 @@ ClutterInputDevice * | ||||
| clutter_event_get_device (const ClutterEvent *event) | ||||
| { | ||||
|   ClutterInputDevice *device = NULL; | ||||
|   ClutterEventPrivate *real_event = (ClutterEventPrivate *) event; | ||||
|  | ||||
|   g_return_val_if_fail (event != NULL, NULL); | ||||
|  | ||||
|   if (real_event->device != NULL) | ||||
|     return real_event->device; | ||||
|   if (is_event_allocated (event)) | ||||
|     { | ||||
|       ClutterEventPrivate *real_event = (ClutterEventPrivate *) event; | ||||
|  | ||||
|       if (real_event->device != NULL) | ||||
|         return real_event->device; | ||||
|     } | ||||
|  | ||||
|   switch (event->type) | ||||
|     { | ||||
|     case CLUTTER_NOTHING: | ||||
|     case CLUTTER_IM_COMMIT: | ||||
|     case CLUTTER_IM_DELETE: | ||||
|     case CLUTTER_IM_PREEDIT: | ||||
|     case CLUTTER_STAGE_STATE: | ||||
|     case CLUTTER_DESTROY_NOTIFY: | ||||
|     case CLUTTER_CLIENT_MESSAGE: | ||||
|     case CLUTTER_DELETE: | ||||
|     case CLUTTER_EVENT_LAST: | ||||
|       break; | ||||
|  | ||||
| @@ -1175,7 +1238,6 @@ clutter_event_get_device (const ClutterEvent *event) | ||||
|  | ||||
|     case CLUTTER_TOUCHPAD_PINCH: | ||||
|     case CLUTTER_TOUCHPAD_SWIPE: | ||||
|     case CLUTTER_TOUCHPAD_HOLD: | ||||
|       /* Rely on priv data for these */ | ||||
|       break; | ||||
|  | ||||
| @@ -1196,11 +1258,6 @@ clutter_event_get_device (const ClutterEvent *event) | ||||
|     case CLUTTER_PAD_RING: | ||||
|       device = event->pad_ring.device; | ||||
|       break; | ||||
|  | ||||
|     case CLUTTER_DEVICE_ADDED: | ||||
|     case CLUTTER_DEVICE_REMOVED: | ||||
|       device = event->device.device; | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|   return device; | ||||
| @@ -1219,11 +1276,14 @@ void | ||||
| clutter_event_set_device_tool (ClutterEvent           *event, | ||||
|                                ClutterInputDeviceTool *tool) | ||||
| { | ||||
|   ClutterEventPrivate *real_event = (ClutterEventPrivate *) event; | ||||
|  | ||||
|   g_return_if_fail (event != NULL); | ||||
|  | ||||
|   real_event->tool = tool; | ||||
|   if (is_event_allocated (event)) | ||||
|     { | ||||
|       ClutterEventPrivate *real_event = (ClutterEventPrivate *) event; | ||||
|  | ||||
|       real_event->tool = tool; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -1239,11 +1299,16 @@ clutter_event_set_device_tool (ClutterEvent           *event, | ||||
| ClutterInputDeviceTool * | ||||
| clutter_event_get_device_tool (const ClutterEvent *event) | ||||
| { | ||||
|   ClutterEventPrivate *real_event = (ClutterEventPrivate *) event; | ||||
|  | ||||
|   g_return_val_if_fail (event != NULL, NULL); | ||||
|  | ||||
|   return real_event->tool; | ||||
|   if (is_event_allocated (event)) | ||||
|     { | ||||
|       ClutterEventPrivate *real_event = (ClutterEventPrivate *) event; | ||||
|  | ||||
|       return real_event->tool; | ||||
|     } | ||||
|  | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -1260,11 +1325,16 @@ clutter_event_new (ClutterEventType type) | ||||
|   ClutterEvent *new_event; | ||||
|   ClutterEventPrivate *priv; | ||||
|  | ||||
|   priv = g_new0 (ClutterEventPrivate, 1); | ||||
|   priv = g_slice_new0 (ClutterEventPrivate); | ||||
|  | ||||
|   new_event = (ClutterEvent *) priv; | ||||
|   new_event->type = new_event->any.type = type; | ||||
|  | ||||
|   if (G_UNLIKELY (all_events == NULL)) | ||||
|     all_events = g_hash_table_new (NULL, NULL); | ||||
|  | ||||
|   g_hash_table_replace (all_events, priv, GUINT_TO_POINTER (1)); | ||||
|  | ||||
|   return new_event; | ||||
| } | ||||
|  | ||||
| @@ -1281,7 +1351,8 @@ clutter_event_copy (const ClutterEvent *event) | ||||
| { | ||||
|   ClutterEvent *new_event; | ||||
|   ClutterEventPrivate *new_real_event; | ||||
|   ClutterEventPrivate *real_event = (ClutterEventPrivate *) event; | ||||
|   ClutterInputDevice *device; | ||||
|   gint n_axes = 0; | ||||
|  | ||||
|   g_return_val_if_fail (event != NULL, NULL); | ||||
|  | ||||
| @@ -1290,45 +1361,45 @@ clutter_event_copy (const ClutterEvent *event) | ||||
|  | ||||
|   *new_event = *event; | ||||
|  | ||||
|   g_set_object (&new_real_event->device, real_event->device); | ||||
|   g_set_object (&new_real_event->source_device, real_event->source_device); | ||||
|   new_real_event->delta_x = real_event->delta_x; | ||||
|   new_real_event->delta_y = real_event->delta_y; | ||||
|   new_real_event->is_pointer_emulated = real_event->is_pointer_emulated; | ||||
|   new_real_event->base_state = real_event->base_state; | ||||
|   new_real_event->button_state = real_event->button_state; | ||||
|   new_real_event->latched_state = real_event->latched_state; | ||||
|   new_real_event->locked_state = real_event->locked_state; | ||||
|   new_real_event->tool = real_event->tool; | ||||
|   if (is_event_allocated (event)) | ||||
|     { | ||||
|       ClutterEventPrivate *real_event = (ClutterEventPrivate *) event; | ||||
|  | ||||
|       g_set_object (&new_real_event->device, real_event->device); | ||||
|       g_set_object (&new_real_event->source_device, real_event->source_device); | ||||
|       new_real_event->delta_x = real_event->delta_x; | ||||
|       new_real_event->delta_y = real_event->delta_y; | ||||
|       new_real_event->is_pointer_emulated = real_event->is_pointer_emulated; | ||||
|       new_real_event->base_state = real_event->base_state; | ||||
|       new_real_event->button_state = real_event->button_state; | ||||
|       new_real_event->latched_state = real_event->latched_state; | ||||
|       new_real_event->locked_state = real_event->locked_state; | ||||
|       new_real_event->tool = real_event->tool; | ||||
|     } | ||||
|  | ||||
|   device = clutter_event_get_device (event); | ||||
|   if (device != NULL) | ||||
|     n_axes = clutter_input_device_get_n_axes (device); | ||||
|  | ||||
|   switch (event->type) | ||||
|     { | ||||
|     case CLUTTER_BUTTON_PRESS: | ||||
|     case CLUTTER_BUTTON_RELEASE: | ||||
|       if (event->button.axes != NULL) | ||||
|         { | ||||
|           new_event->button.axes = | ||||
|             g_memdup2 (event->button.axes, | ||||
|                        sizeof (double) * CLUTTER_INPUT_AXIS_LAST); | ||||
|         } | ||||
|         new_event->button.axes = g_memdup (event->button.axes, | ||||
|                                            sizeof (gdouble) * n_axes); | ||||
|       break; | ||||
|  | ||||
|     case CLUTTER_SCROLL: | ||||
|       if (event->scroll.axes != NULL) | ||||
|         { | ||||
|           new_event->scroll.axes = | ||||
|             g_memdup2 (event->scroll.axes, | ||||
|                        sizeof (double) * CLUTTER_INPUT_AXIS_LAST); | ||||
|         } | ||||
|         new_event->scroll.axes = g_memdup (event->scroll.axes, | ||||
|                                            sizeof (gdouble) * n_axes); | ||||
|       break; | ||||
|  | ||||
|     case CLUTTER_MOTION: | ||||
|       if (event->motion.axes != NULL) | ||||
|         { | ||||
|           new_event->motion.axes = | ||||
|             g_memdup2 (event->motion.axes, | ||||
|                        sizeof (double) * CLUTTER_INPUT_AXIS_LAST); | ||||
|         } | ||||
|         new_event->motion.axes = g_memdup (event->motion.axes, | ||||
|                                            sizeof (gdouble) * n_axes); | ||||
|       break; | ||||
|  | ||||
|     case CLUTTER_TOUCH_BEGIN: | ||||
| @@ -1336,26 +1407,19 @@ clutter_event_copy (const ClutterEvent *event) | ||||
|     case CLUTTER_TOUCH_END: | ||||
|     case CLUTTER_TOUCH_CANCEL: | ||||
|       if (event->touch.axes != NULL) | ||||
|         { | ||||
|           new_event->touch.axes = | ||||
|             g_memdup2 (event->touch.axes, | ||||
|                       sizeof (double) * CLUTTER_INPUT_AXIS_LAST); | ||||
|         } | ||||
|       break; | ||||
|  | ||||
|     case CLUTTER_DEVICE_ADDED: | ||||
|     case CLUTTER_DEVICE_REMOVED: | ||||
|       new_event->device.device = event->device.device; | ||||
|       break; | ||||
|     case CLUTTER_IM_COMMIT: | ||||
|     case CLUTTER_IM_PREEDIT: | ||||
|       new_event->im.text = g_strdup (event->im.text); | ||||
|         new_event->touch.axes = g_memdup (event->touch.axes, | ||||
|                                           sizeof (gdouble) * n_axes); | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|   if (is_event_allocated (event)) | ||||
|     _clutter_backend_copy_event_data (clutter_get_default_backend (), | ||||
|                                       event, | ||||
|                                       new_event); | ||||
|  | ||||
|   return new_event; | ||||
| } | ||||
|  | ||||
| @@ -1370,10 +1434,15 @@ clutter_event_free (ClutterEvent *event) | ||||
| { | ||||
|   if (G_LIKELY (event != NULL)) | ||||
|     { | ||||
|       ClutterEventPrivate *real_event = (ClutterEventPrivate *) event; | ||||
|       _clutter_backend_free_event_data (clutter_get_default_backend (), event); | ||||
|  | ||||
|       g_clear_object (&real_event->device); | ||||
|       g_clear_object (&real_event->source_device); | ||||
|       if (is_event_allocated (event)) | ||||
|         { | ||||
|           ClutterEventPrivate *real_event = (ClutterEventPrivate *) event; | ||||
|  | ||||
|           g_clear_object (&real_event->device); | ||||
|           g_clear_object (&real_event->source_device); | ||||
|         } | ||||
|  | ||||
|       switch (event->type) | ||||
|         { | ||||
| @@ -1397,16 +1466,12 @@ clutter_event_free (ClutterEvent *event) | ||||
|           g_free (event->touch.axes); | ||||
|           break; | ||||
|  | ||||
|         case CLUTTER_IM_COMMIT: | ||||
|         case CLUTTER_IM_PREEDIT: | ||||
|           g_free (event->im.text); | ||||
|           break; | ||||
|  | ||||
|         default: | ||||
|           break; | ||||
|         } | ||||
|  | ||||
|       g_free ((ClutterEventPrivate *) event); | ||||
|       g_hash_table_remove (all_events, event); | ||||
|       g_slice_free (ClutterEventPrivate, (ClutterEventPrivate *) event); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -1424,11 +1489,40 @@ ClutterEvent * | ||||
| clutter_event_get (void) | ||||
| { | ||||
|   ClutterMainContext *context = _clutter_context_get_default (); | ||||
|   ClutterEvent *event; | ||||
|  | ||||
|   event = g_async_queue_try_pop (context->events_queue); | ||||
|   if (context->events_queue == NULL) | ||||
|     return NULL; | ||||
|  | ||||
|   return event; | ||||
|   if (g_queue_is_empty (context->events_queue)) | ||||
|     return NULL; | ||||
|  | ||||
|   return g_queue_pop_tail (context->events_queue); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_event_peek: | ||||
|  *  | ||||
|  * Returns a pointer to the first event from the event queue but  | ||||
|  * does not remove it.  | ||||
|  * | ||||
|  * Return value: (transfer none): A #ClutterEvent or NULL if queue empty. | ||||
|  * | ||||
|  * Since: 0.4 | ||||
|  */ | ||||
| ClutterEvent * | ||||
| clutter_event_peek (void) | ||||
| { | ||||
|   ClutterMainContext *context = _clutter_context_get_default (); | ||||
|  | ||||
|   g_return_val_if_fail (context != NULL, NULL); | ||||
|    | ||||
|   if (context->events_queue == NULL) | ||||
|     return NULL; | ||||
|  | ||||
|   if (g_queue_is_empty (context->events_queue)) | ||||
|     return NULL; | ||||
|  | ||||
|   return g_queue_peek_tail (context->events_queue); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -1436,9 +1530,21 @@ _clutter_event_push (const ClutterEvent *event, | ||||
|                      gboolean            do_copy) | ||||
| { | ||||
|   ClutterMainContext *context = _clutter_context_get_default (); | ||||
|   ClutterInputDevice *device; | ||||
|  | ||||
|   g_assert (context != NULL); | ||||
|  | ||||
|   if (context->events_queue == NULL) | ||||
|     context->events_queue = g_queue_new (); | ||||
|  | ||||
|   /* disabled devices don't propagate events */ | ||||
|   device = clutter_event_get_device (event); | ||||
|   if (device != NULL) | ||||
|     { | ||||
|       if (!clutter_input_device_get_enabled (device)) | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|   if (do_copy) | ||||
|     { | ||||
|       ClutterEvent *copy; | ||||
| @@ -1447,8 +1553,7 @@ _clutter_event_push (const ClutterEvent *event, | ||||
|       event = copy; | ||||
|     } | ||||
|  | ||||
|   g_async_queue_push (context->events_queue, (gpointer) event); | ||||
|   g_main_context_wakeup (NULL); | ||||
|   g_queue_push_head (context->events_queue, (gpointer) event); | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -1485,7 +1590,10 @@ clutter_events_pending (void) | ||||
|  | ||||
|   g_return_val_if_fail (context != NULL, FALSE); | ||||
|  | ||||
|   return g_async_queue_length (context->events_queue) > 0; | ||||
|   if (context->events_queue == NULL) | ||||
|     return FALSE; | ||||
|  | ||||
|   return g_queue_is_empty (context->events_queue) == FALSE; | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -1555,6 +1663,9 @@ clutter_event_get_source_device (const ClutterEvent *event) | ||||
| { | ||||
|   ClutterEventPrivate *real_event; | ||||
|  | ||||
|   if (!is_event_allocated (event)) | ||||
|     return NULL; | ||||
|  | ||||
|   real_event = (ClutterEventPrivate *) event; | ||||
|  | ||||
|   if (real_event->source_device != NULL) | ||||
| @@ -1583,6 +1694,9 @@ clutter_event_set_source_device (ClutterEvent       *event, | ||||
|   g_return_if_fail (event != NULL); | ||||
|   g_return_if_fail (device == NULL || CLUTTER_IS_INPUT_DEVICE (device)); | ||||
|  | ||||
|   if (!is_event_allocated (event)) | ||||
|     return; | ||||
|  | ||||
|   real_event = (ClutterEventPrivate *) event; | ||||
|   g_set_object (&real_event->source_device, device); | ||||
| } | ||||
| @@ -1603,10 +1717,15 @@ clutter_event_get_axes (const ClutterEvent *event, | ||||
|                         guint              *n_axes) | ||||
| { | ||||
|   gdouble *retval = NULL; | ||||
|   guint len = 0; | ||||
|  | ||||
|   switch (event->type) | ||||
|     { | ||||
|     case CLUTTER_NOTHING: | ||||
|     case CLUTTER_STAGE_STATE: | ||||
|     case CLUTTER_DESTROY_NOTIFY: | ||||
|     case CLUTTER_CLIENT_MESSAGE: | ||||
|     case CLUTTER_DELETE: | ||||
|     case CLUTTER_ENTER: | ||||
|     case CLUTTER_LEAVE: | ||||
|     case CLUTTER_KEY_PRESS: | ||||
| @@ -1614,8 +1733,6 @@ clutter_event_get_axes (const ClutterEvent *event, | ||||
|     case CLUTTER_EVENT_LAST: | ||||
|     case CLUTTER_PROXIMITY_IN: | ||||
|     case CLUTTER_PROXIMITY_OUT: | ||||
|     case CLUTTER_DEVICE_ADDED: | ||||
|     case CLUTTER_DEVICE_REMOVED: | ||||
|       break; | ||||
|  | ||||
|     case CLUTTER_SCROLL: | ||||
| @@ -1640,19 +1757,26 @@ clutter_event_get_axes (const ClutterEvent *event, | ||||
|  | ||||
|     case CLUTTER_TOUCHPAD_PINCH: | ||||
|     case CLUTTER_TOUCHPAD_SWIPE: | ||||
|     case CLUTTER_TOUCHPAD_HOLD: | ||||
|     case CLUTTER_PAD_BUTTON_PRESS: | ||||
|     case CLUTTER_PAD_BUTTON_RELEASE: | ||||
|     case CLUTTER_PAD_STRIP: | ||||
|     case CLUTTER_PAD_RING: | ||||
|     case CLUTTER_IM_COMMIT: | ||||
|     case CLUTTER_IM_DELETE: | ||||
|     case CLUTTER_IM_PREEDIT: | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|   if (retval != NULL) | ||||
|     { | ||||
|       ClutterInputDevice *device; | ||||
|  | ||||
|       device = clutter_event_get_device (event); | ||||
|       if (device != NULL) | ||||
|         len = clutter_input_device_get_n_axes (device); | ||||
|       else | ||||
|         retval = NULL; | ||||
|     } | ||||
|  | ||||
|   if (n_axes) | ||||
|     *n_axes = CLUTTER_INPUT_AXIS_LAST; | ||||
|     *n_axes = len; | ||||
|  | ||||
|   return retval; | ||||
| } | ||||
| @@ -1771,6 +1895,9 @@ clutter_event_is_pointer_emulated (const ClutterEvent *event) | ||||
| { | ||||
|   g_return_val_if_fail (event != NULL, FALSE); | ||||
|  | ||||
|   if (!is_event_allocated (event)) | ||||
|     return FALSE; | ||||
|  | ||||
|   return ((ClutterEventPrivate *) event)->is_pointer_emulated; | ||||
| } | ||||
|  | ||||
| @@ -1822,7 +1949,7 @@ clutter_event_add_filter (ClutterStage          *stage, | ||||
|                           gpointer               user_data) | ||||
| { | ||||
|   ClutterMainContext *context = _clutter_context_get_default (); | ||||
|   ClutterEventFilter *event_filter = g_new0 (ClutterEventFilter, 1); | ||||
|   ClutterEventFilter *event_filter = g_slice_new (ClutterEventFilter); | ||||
|   static guint event_filter_id = 0; | ||||
|  | ||||
|   event_filter->stage = stage; | ||||
| @@ -1863,7 +1990,7 @@ clutter_event_remove_filter (guint id) | ||||
|             event_filter->notify (event_filter->user_data); | ||||
|  | ||||
|           context->event_filters = g_list_delete_link (context->event_filters, l); | ||||
|           g_free (event_filter); | ||||
|           g_slice_free (ClutterEventFilter, event_filter); | ||||
|           return; | ||||
|         } | ||||
|     } | ||||
| @@ -1886,15 +2013,12 @@ clutter_event_get_touchpad_gesture_finger_count (const ClutterEvent *event) | ||||
| { | ||||
|   g_return_val_if_fail (event != NULL, 0); | ||||
|   g_return_val_if_fail (event->type == CLUTTER_TOUCHPAD_SWIPE || | ||||
|                         event->type == CLUTTER_TOUCHPAD_PINCH || | ||||
|                         event->type == CLUTTER_TOUCHPAD_HOLD, 0); | ||||
|                         event->type == CLUTTER_TOUCHPAD_PINCH, 0); | ||||
|  | ||||
|   if (event->type == CLUTTER_TOUCHPAD_SWIPE) | ||||
|     return event->touchpad_swipe.n_fingers; | ||||
|   else if (event->type == CLUTTER_TOUCHPAD_PINCH) | ||||
|     return event->touchpad_pinch.n_fingers; | ||||
|   else if (event->type == CLUTTER_TOUCHPAD_HOLD) | ||||
|     return event->touchpad_hold.n_fingers; | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
| @@ -1953,15 +2077,12 @@ clutter_event_get_gesture_phase (const ClutterEvent *event) | ||||
| { | ||||
|   g_return_val_if_fail (event != NULL, 0); | ||||
|   g_return_val_if_fail (event->type == CLUTTER_TOUCHPAD_PINCH || | ||||
|                         event->type == CLUTTER_TOUCHPAD_SWIPE || | ||||
|                         event->type == CLUTTER_TOUCHPAD_HOLD, 0); | ||||
|                         event->type == CLUTTER_TOUCHPAD_SWIPE, 0); | ||||
|  | ||||
|   if (event->type == CLUTTER_TOUCHPAD_PINCH) | ||||
|     return event->touchpad_pinch.phase; | ||||
|   else if (event->type == CLUTTER_TOUCHPAD_SWIPE) | ||||
|     return event->touchpad_swipe.phase; | ||||
|   else if (event->type == CLUTTER_TOUCHPAD_HOLD) | ||||
|     return event->touchpad_hold.phase; | ||||
|  | ||||
|   /* Shouldn't ever happen */ | ||||
|   return CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN; | ||||
| @@ -1987,8 +2108,7 @@ clutter_event_get_gesture_motion_delta (const ClutterEvent *event, | ||||
| { | ||||
|   g_return_if_fail (event != NULL); | ||||
|   g_return_if_fail (event->type == CLUTTER_TOUCHPAD_PINCH || | ||||
|                     event->type == CLUTTER_TOUCHPAD_SWIPE || | ||||
|                     event->type == CLUTTER_TOUCHPAD_HOLD); | ||||
|                     event->type == CLUTTER_TOUCHPAD_SWIPE); | ||||
|  | ||||
|   if (event->type == CLUTTER_TOUCHPAD_PINCH) | ||||
|     { | ||||
| @@ -2004,59 +2124,8 @@ clutter_event_get_gesture_motion_delta (const ClutterEvent *event, | ||||
|       if (dy) | ||||
|         *dy = event->touchpad_swipe.dy; | ||||
|     } | ||||
|   else if (event->type == CLUTTER_TOUCHPAD_HOLD) | ||||
|     { | ||||
|       if (dx) | ||||
|         *dx = 0; | ||||
|       if (dy) | ||||
|         *dy = 0; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * clutter_event_get_gesture_motion_delta_unaccelerated: | ||||
|  * @event: A clutter touchpad gesture event | ||||
|  * @dx: (out) (allow-none): the displacement relative to the pointer | ||||
|  *      position in the X axis, or %NULL | ||||
|  * @dy: (out) (allow-none): the displacement relative to the pointer | ||||
|  *      position in the Y axis, or %NULL | ||||
|  * | ||||
|  * Returns the unaccelerated gesture motion deltas relative to the current | ||||
|  * pointer position. Unlike clutter_event_get_gesture_motion_delta(), | ||||
|  * pointer acceleration is ignored. | ||||
|  **/ | ||||
| void | ||||
| clutter_event_get_gesture_motion_delta_unaccelerated (const ClutterEvent *event, | ||||
|                                                       gdouble            *dx, | ||||
|                                                       gdouble            *dy) | ||||
| { | ||||
|   g_return_if_fail (event != NULL); | ||||
|   g_return_if_fail (event->type == CLUTTER_TOUCHPAD_PINCH || | ||||
|                     event->type == CLUTTER_TOUCHPAD_SWIPE || | ||||
|                     event->type == CLUTTER_TOUCHPAD_HOLD); | ||||
|  | ||||
|   if (event->type == CLUTTER_TOUCHPAD_PINCH) | ||||
|     { | ||||
|       if (dx) | ||||
|         *dx = event->touchpad_pinch.dx_unaccel; | ||||
|       if (dy) | ||||
|         *dy = event->touchpad_pinch.dy_unaccel; | ||||
|     } | ||||
|   else if (event->type == CLUTTER_TOUCHPAD_SWIPE) | ||||
|     { | ||||
|       if (dx) | ||||
|         *dx = event->touchpad_swipe.dx_unaccel; | ||||
|       if (dy) | ||||
|         *dy = event->touchpad_swipe.dy_unaccel; | ||||
|     } | ||||
|   else if (event->type == CLUTTER_TOUCHPAD_HOLD) | ||||
|     { | ||||
|       if (dx) | ||||
|         *dx = 0; | ||||
|       if (dy) | ||||
|         *dy = 0; | ||||
|     } | ||||
| } | ||||
| /** | ||||
|  * clutter_event_get_scroll_source: | ||||
|  * @event: an scroll event | ||||
| @@ -2177,58 +2246,3 @@ clutter_event_get_pad_event_details (const ClutterEvent *event, | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| uint32_t | ||||
| clutter_event_get_event_code (const ClutterEvent *event) | ||||
| { | ||||
|   if (event->type == CLUTTER_KEY_PRESS || | ||||
|       event->type == CLUTTER_KEY_RELEASE) | ||||
|     return event->key.evdev_code; | ||||
|   else if (event->type == CLUTTER_BUTTON_PRESS || | ||||
|            event->type == CLUTTER_BUTTON_RELEASE) | ||||
|     return event->button.evdev_code; | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| int32_t | ||||
| clutter_event_sequence_get_slot (const ClutterEventSequence *sequence) | ||||
| { | ||||
|   g_return_val_if_fail (sequence != NULL, -1); | ||||
|  | ||||
|   return GPOINTER_TO_INT (sequence) - 1; | ||||
| } | ||||
|  | ||||
| int64_t | ||||
| clutter_event_get_time_us (const ClutterEvent *event) | ||||
| { | ||||
|   if (event->type == CLUTTER_MOTION) | ||||
|     return event->motion.time_us; | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| clutter_event_get_relative_motion (const ClutterEvent *event, | ||||
|                                    double             *dx, | ||||
|                                    double             *dy, | ||||
|                                    double             *dx_unaccel, | ||||
|                                    double             *dy_unaccel) | ||||
| { | ||||
|   if (event->type == CLUTTER_MOTION && | ||||
|       event->motion.flags & CLUTTER_EVENT_FLAG_RELATIVE_MOTION) | ||||
|     { | ||||
|       if (dx) | ||||
|         *dx = event->motion.dx; | ||||
|       if (dy) | ||||
|         *dy = event->motion.dy; | ||||
|       if (dx_unaccel) | ||||
|         *dx_unaccel = event->motion.dx_unaccel; | ||||
|       if (dy_unaccel) | ||||
|         *dy_unaccel = event->motion.dy_unaccel; | ||||
|  | ||||
|       return TRUE; | ||||
|     } | ||||
|   else | ||||
|     return FALSE; | ||||
| } | ||||
|   | ||||
| @@ -112,17 +112,15 @@ typedef struct _ClutterButtonEvent      ClutterButtonEvent; | ||||
| typedef struct _ClutterKeyEvent         ClutterKeyEvent; | ||||
| typedef struct _ClutterMotionEvent      ClutterMotionEvent; | ||||
| typedef struct _ClutterScrollEvent      ClutterScrollEvent; | ||||
| typedef struct _ClutterStageStateEvent  ClutterStageStateEvent; | ||||
| typedef struct _ClutterCrossingEvent    ClutterCrossingEvent; | ||||
| typedef struct _ClutterTouchEvent       ClutterTouchEvent; | ||||
| typedef struct _ClutterTouchpadPinchEvent ClutterTouchpadPinchEvent; | ||||
| typedef struct _ClutterTouchpadSwipeEvent ClutterTouchpadSwipeEvent; | ||||
| typedef struct _ClutterTouchpadHoldEvent ClutterTouchpadHoldEvent; | ||||
| typedef struct _ClutterProximityEvent   ClutterProximityEvent; | ||||
| typedef struct _ClutterPadButtonEvent   ClutterPadButtonEvent; | ||||
| typedef struct _ClutterPadStripEvent    ClutterPadStripEvent; | ||||
| typedef struct _ClutterPadRingEvent     ClutterPadRingEvent; | ||||
| typedef struct _ClutterDeviceEvent      ClutterDeviceEvent; | ||||
| typedef struct _ClutterIMEvent          ClutterIMEvent; | ||||
|  | ||||
| /** | ||||
|  * ClutterAnyEvent: | ||||
| @@ -174,7 +172,6 @@ struct _ClutterKeyEvent | ||||
|   guint keyval; | ||||
|   guint16 hardware_keycode; | ||||
|   gunichar unicode_value; | ||||
|   uint32_t evdev_code; | ||||
|   ClutterInputDevice *device; | ||||
| }; | ||||
|  | ||||
| @@ -189,6 +186,8 @@ struct _ClutterKeyEvent | ||||
|  * @y: event Y coordinate, relative to the stage | ||||
|  * @modifier_state: button modifiers | ||||
|  * @button: event button | ||||
|  * @click_count: number of button presses within the default time | ||||
|  *   and radius | ||||
|  * @axes: reserved for future use | ||||
|  * @device: the device that originated the event. If you want the physical | ||||
|  * device the event originated from, use clutter_event_get_source_device() | ||||
| @@ -213,9 +212,9 @@ struct _ClutterButtonEvent | ||||
|   gfloat y; | ||||
|   ClutterModifierType modifier_state; | ||||
|   guint32 button; | ||||
|   guint click_count; | ||||
|   gdouble *axes; /* Future use */ | ||||
|   ClutterInputDevice *device; | ||||
|   uint32_t evdev_code; | ||||
| }; | ||||
|  | ||||
| /** | ||||
| @@ -305,12 +304,6 @@ struct _ClutterMotionEvent | ||||
|   ClutterModifierType modifier_state; | ||||
|   gdouble *axes; /* Future use */ | ||||
|   ClutterInputDevice *device; | ||||
|  | ||||
|   int64_t time_us; | ||||
|   double dx; | ||||
|   double dy; | ||||
|   double dx_unaccel; | ||||
|   double dy_unaccel; | ||||
| }; | ||||
|  | ||||
| /** | ||||
| @@ -352,6 +345,32 @@ struct _ClutterScrollEvent | ||||
|   ClutterScrollFinishFlags finish_flags; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * ClutterStageStateEvent: | ||||
|  * @type: event type | ||||
|  * @time: event time | ||||
|  * @flags: event flags | ||||
|  * @stage: event source stage | ||||
|  * @source: event source actor (unused) | ||||
|  * @changed_mask: bitwise OR of the changed flags | ||||
|  * @new_state: bitwise OR of the current state flags | ||||
|  * | ||||
|  * Event signalling a change in the #ClutterStage state. | ||||
|  * | ||||
|  * Since: 0.2 | ||||
|  */ | ||||
| struct _ClutterStageStateEvent | ||||
| { | ||||
|   ClutterEventType type; | ||||
|   guint32 time; | ||||
|   ClutterEventFlags flags; | ||||
|   ClutterStage *stage; | ||||
|   ClutterActor *source; /* XXX: should probably be the stage itself */ | ||||
|  | ||||
|   ClutterStageState changed_mask; | ||||
|   ClutterStageState new_state; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * ClutterTouchEvent: | ||||
|  * @type: event type | ||||
| @@ -412,10 +431,6 @@ struct _ClutterTouchEvent | ||||
|  * @y: the Y coordinate of the pointer, relative to the stage | ||||
|  * @dx: movement delta of the pinch focal point in the X axis | ||||
|  * @dy: movement delta of the pinch focal point in the Y axis | ||||
|  * @dx_unaccel: unaccelerated movement delta of the pinch focal | ||||
|  *   point in the X axis | ||||
|  * @dy_unaccel: unaccelerated movement delta of the pinch focal | ||||
|  *   point in the Y axis | ||||
|  * @angle_delta: angle delta in degrees, clockwise rotations are | ||||
|  *   represented by positive deltas | ||||
|  * @scale: the current scale | ||||
| @@ -443,8 +458,6 @@ struct _ClutterTouchpadPinchEvent | ||||
|   gfloat y; | ||||
|   gfloat dx; | ||||
|   gfloat dy; | ||||
|   gfloat dx_unaccel; | ||||
|   gfloat dy_unaccel; | ||||
|   gfloat angle_delta; | ||||
|   gfloat scale; | ||||
|   guint n_fingers; | ||||
| @@ -461,12 +474,8 @@ struct _ClutterTouchpadPinchEvent | ||||
|  * @n_fingers: the number of fingers triggering the swipe | ||||
|  * @x: the X coordinate of the pointer, relative to the stage | ||||
|  * @y: the Y coordinate of the pointer, relative to the stage | ||||
|  * @dx: movement delta of the swipe center point in the X axis | ||||
|  * @dy: movement delta of the swipe center point in the Y axis | ||||
|  * @dx_unaccel: unaccelerated movement delta of the swipe center | ||||
|  *   point in the X axis | ||||
|  * @dy_unaccel: unaccelerated movement delta of the swipe center | ||||
|  *   point in the Y axis | ||||
|  * @dx: movement delta of the pinch focal point in the X axis | ||||
|  * @dy: movement delta of the pinch focal point in the Y axis | ||||
|  * | ||||
|  * Used for touchpad swipe gesture events. The current state of the | ||||
|  * gesture will be determined by the @phase field. | ||||
| @@ -487,44 +496,6 @@ struct _ClutterTouchpadSwipeEvent | ||||
|   gfloat y; | ||||
|   gfloat dx; | ||||
|   gfloat dy; | ||||
|   gfloat dx_unaccel; | ||||
|   gfloat dy_unaccel; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * ClutterTouchpadHoldEvent | ||||
|  * @type: event type | ||||
|  * @time: event time | ||||
|  * @flags: event flags | ||||
|  * @stage: event source stage | ||||
|  * @source: event source actor (unused) | ||||
|  * @phase: the current phase of the gesture | ||||
|  * @n_fingers: the number of fingers triggering the swipe | ||||
|  * @x: the X coordinate of the pointer, relative to the stage | ||||
|  * @y: the Y coordinate of the pointer, relative to the stage | ||||
|  * | ||||
|  * Used for touchpad hold gesture events. The current state of the | ||||
|  * gesture will be determined by the @phase field. | ||||
|  * | ||||
|  * A hold gesture starts when the user places one or many fingers on the | ||||
|  * touchpad and ends when all fingers are lifted. It is cancelled when the | ||||
|  * finger(s) move past a certain threshold. | ||||
|  * Unlike swipe and pinch, @phase can only be | ||||
|  * CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN, CLUTTER_TOUCHPAD_GESTURE_PHASE_END and | ||||
|  * CLUTTER_TOUCHPAD_GESTURE_PHASE_CANCEL. | ||||
|  */ | ||||
| struct _ClutterTouchpadHoldEvent | ||||
| { | ||||
|   ClutterEventType type; | ||||
|   guint32 time; | ||||
|   ClutterEventFlags flags; | ||||
|   ClutterStage *stage; | ||||
|   ClutterActor *source; | ||||
|  | ||||
|   ClutterTouchpadGesturePhase phase; | ||||
|   uint32_t n_fingers; | ||||
|   float x; | ||||
|   float y; | ||||
| }; | ||||
|  | ||||
| struct _ClutterPadButtonEvent | ||||
| @@ -573,31 +544,6 @@ struct _ClutterPadRingEvent | ||||
|   guint32 mode; | ||||
| }; | ||||
|  | ||||
| struct _ClutterDeviceEvent | ||||
| { | ||||
|   ClutterEventType type; | ||||
|   guint32 time; | ||||
|   ClutterEventFlags flags; | ||||
|   ClutterStage *stage; | ||||
|   ClutterActor *source; | ||||
|  | ||||
|   ClutterInputDevice *device; | ||||
| }; | ||||
|  | ||||
| struct _ClutterIMEvent | ||||
| { | ||||
|   ClutterEventType type; | ||||
|   uint32_t time; | ||||
|   ClutterEventFlags flags; | ||||
|   ClutterStage *stage; | ||||
|   ClutterActor *source; | ||||
|  | ||||
|   char *text; | ||||
|   int32_t offset; | ||||
|   uint32_t len; | ||||
|   ClutterPreeditResetMode mode; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * ClutterEvent: | ||||
|  * | ||||
| @@ -615,17 +561,15 @@ union _ClutterEvent | ||||
|   ClutterKeyEvent key; | ||||
|   ClutterMotionEvent motion; | ||||
|   ClutterScrollEvent scroll; | ||||
|   ClutterStageStateEvent stage_state; | ||||
|   ClutterCrossingEvent crossing; | ||||
|   ClutterTouchEvent touch; | ||||
|   ClutterTouchpadPinchEvent touchpad_pinch; | ||||
|   ClutterTouchpadSwipeEvent touchpad_swipe; | ||||
|   ClutterTouchpadHoldEvent touchpad_hold; | ||||
|   ClutterProximityEvent proximity; | ||||
|   ClutterPadButtonEvent pad_button; | ||||
|   ClutterPadStripEvent pad_strip; | ||||
|   ClutterPadRingEvent pad_ring; | ||||
|   ClutterDeviceEvent device; | ||||
|   ClutterIMEvent im; | ||||
| }; | ||||
|  | ||||
| /** | ||||
| @@ -657,6 +601,8 @@ gboolean                clutter_events_pending                  (void); | ||||
| CLUTTER_EXPORT | ||||
| ClutterEvent *          clutter_event_get                       (void); | ||||
| CLUTTER_EXPORT | ||||
| ClutterEvent *          clutter_event_peek                      (void); | ||||
| CLUTTER_EXPORT | ||||
| void                    clutter_event_put                       (const ClutterEvent     *event); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| @@ -727,6 +673,8 @@ void                    clutter_event_set_stage                 (ClutterEvent | ||||
| CLUTTER_EXPORT | ||||
| ClutterStage *          clutter_event_get_stage                 (const ClutterEvent     *event); | ||||
| CLUTTER_EXPORT | ||||
| gint                    clutter_event_get_device_id             (const ClutterEvent     *event); | ||||
| CLUTTER_EXPORT | ||||
| ClutterInputDeviceType  clutter_event_get_device_type           (const ClutterEvent     *event); | ||||
| CLUTTER_EXPORT | ||||
| void                    clutter_event_set_coords                (ClutterEvent           *event, | ||||
| @@ -775,6 +723,8 @@ void                    clutter_event_set_button                (ClutterEvent | ||||
| CLUTTER_EXPORT | ||||
| guint32                 clutter_event_get_button                (const ClutterEvent     *event); | ||||
| CLUTTER_EXPORT | ||||
| guint                   clutter_event_get_click_count           (const ClutterEvent     *event); | ||||
| CLUTTER_EXPORT | ||||
| void                    clutter_event_set_related               (ClutterEvent           *event, | ||||
|                                                                  ClutterActor           *actor); | ||||
| CLUTTER_EXPORT | ||||
| @@ -823,11 +773,6 @@ void                    clutter_event_get_gesture_motion_delta       (const Clut | ||||
|                                                                       gdouble                *dx, | ||||
|                                                                       gdouble                *dy); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void                    clutter_event_get_gesture_motion_delta_unaccelerated (const ClutterEvent     *event, | ||||
|                                                                               gdouble                *dx, | ||||
|                                                                               gdouble                *dy); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterScrollSource      clutter_event_get_scroll_source             (const ClutterEvent     *event); | ||||
|  | ||||
| @@ -842,20 +787,6 @@ gboolean                 clutter_event_get_pad_event_details         (const Clut | ||||
|                                                                       guint                  *number, | ||||
|                                                                       guint                  *mode, | ||||
|                                                                       gdouble                *value); | ||||
| CLUTTER_EXPORT | ||||
| uint32_t                 clutter_event_get_event_code                (const ClutterEvent     *event); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| int32_t                  clutter_event_sequence_get_slot (const ClutterEventSequence *sequence); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| int64_t                  clutter_event_get_time_us (const ClutterEvent *event); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                 clutter_event_get_relative_motion (const ClutterEvent *event, | ||||
|                                                             double             *dx, | ||||
|                                                             double             *dy, | ||||
|                                                             double             *dx_unaccel, | ||||
|                                                             double             *dy_unaccel); | ||||
|  | ||||
|  | ||||
| G_END_DECLS | ||||
|   | ||||
| @@ -64,13 +64,16 @@ clutter_features_from_cogl (void) | ||||
|    | ||||
|   clutter_flags |= CLUTTER_FEATURE_SHADERS_GLSL; | ||||
|    | ||||
|   clutter_flags |= CLUTTER_FEATURE_OFFSCREEN; | ||||
|    | ||||
|   return clutter_flags; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| clutter_feature_init (ClutterMainContext  *context, | ||||
|                       GError             **error) | ||||
| _clutter_feature_init (GError **error) | ||||
| { | ||||
|   ClutterMainContext *context; | ||||
|  | ||||
|   CLUTTER_NOTE (MISC, "checking features"); | ||||
|  | ||||
|   if (!__features) | ||||
| @@ -83,11 +86,14 @@ clutter_feature_init (ClutterMainContext  *context, | ||||
|   if (__features->features_set) | ||||
|     return TRUE; | ||||
|  | ||||
|   context = _clutter_context_get_default (); | ||||
|  | ||||
|   /* makes sure we have a GL context; if we have, this is a no-op */ | ||||
|   if (!_clutter_backend_create_context (context->backend, error)) | ||||
|     return FALSE; | ||||
|  | ||||
|   __features->flags = clutter_features_from_cogl (); | ||||
|   __features->flags = (clutter_features_from_cogl () | ||||
|                     | _clutter_backend_get_features (context->backend)); | ||||
|  | ||||
|   __features->features_set = TRUE; | ||||
|  | ||||
|   | ||||
| @@ -131,7 +131,8 @@ clutter_fixed_layout_get_preferred_height (ClutterLayoutManager *manager, | ||||
| static void | ||||
| clutter_fixed_layout_allocate (ClutterLayoutManager   *manager, | ||||
|                                ClutterContainer       *container, | ||||
|                                const ClutterActorBox  *allocation) | ||||
|                                const ClutterActorBox  *allocation, | ||||
|                                ClutterAllocationFlags  flags) | ||||
| { | ||||
|   ClutterActor *child; | ||||
|  | ||||
| @@ -139,11 +140,7 @@ clutter_fixed_layout_allocate (ClutterLayoutManager   *manager, | ||||
|        child != NULL; | ||||
|        child = clutter_actor_get_next_sibling (child)) | ||||
|     { | ||||
|       float x = 0.f; | ||||
|       float y = 0.f; | ||||
|  | ||||
|       clutter_actor_get_fixed_position (child, &x, &y); | ||||
|       clutter_actor_allocate_preferred_size (child, x, y); | ||||
|       clutter_actor_allocate_preferred_size (child, flags); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -566,7 +566,8 @@ clutter_flow_layout_get_preferred_height (ClutterLayoutManager *manager, | ||||
| static void | ||||
| clutter_flow_layout_allocate (ClutterLayoutManager   *manager, | ||||
|                               ClutterContainer       *container, | ||||
|                               const ClutterActorBox  *allocation) | ||||
|                               const ClutterActorBox  *allocation, | ||||
|                               ClutterAllocationFlags  flags) | ||||
| { | ||||
|   ClutterFlowLayoutPrivate *priv = CLUTTER_FLOW_LAYOUT (manager)->priv; | ||||
|   ClutterActor *actor, *child; | ||||
| @@ -728,7 +729,7 @@ clutter_flow_layout_allocate (ClutterLayoutManager   *manager, | ||||
|       child_alloc.y1 = ceil (item_y); | ||||
|       child_alloc.x2 = ceil (child_alloc.x1 + item_width); | ||||
|       child_alloc.y2 = ceil (child_alloc.y1 + item_height); | ||||
|       clutter_actor_allocate (child, &child_alloc); | ||||
|       clutter_actor_allocate (child, &child_alloc, flags); | ||||
|  | ||||
|       if (priv->orientation == CLUTTER_FLOW_HORIZONTAL) | ||||
|         item_x = new_x; | ||||
| @@ -913,7 +914,7 @@ clutter_flow_layout_class_init (ClutterFlowLayoutClass *klass) | ||||
|    * ClutterFlowLayout:orientation: | ||||
|    * | ||||
|    * The orientation of the #ClutterFlowLayout. The children | ||||
|    * of the layout will be laid out following the orientation. | ||||
|    * of the layout will be layed out following the orientation. | ||||
|    * | ||||
|    * This property also controls the overflowing directions | ||||
|    * | ||||
|   | ||||
| @@ -1,843 +0,0 @@ | ||||
| /* | ||||
|  * Copyright (C) 2019 Red Hat Inc. | ||||
|  * | ||||
|  * This library is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Lesser General Public | ||||
|  * License as published by the Free Software Foundation; either | ||||
|  * version 2 of the License, or (at your option) any later version. | ||||
|  * | ||||
|  * This library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * Lesser General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Lesser General Public | ||||
|  * License along with this library. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| #include "clutter-build-config.h" | ||||
|  | ||||
| #include "clutter/clutter-frame-clock.h" | ||||
|  | ||||
| #include "clutter/clutter-debug.h" | ||||
| #include "clutter/clutter-main.h" | ||||
| #include "clutter/clutter-private.h" | ||||
| #include "clutter/clutter-timeline-private.h" | ||||
| #include "cogl/cogl-trace.h" | ||||
|  | ||||
| enum | ||||
| { | ||||
|   DESTROY, | ||||
|  | ||||
|   N_SIGNALS | ||||
| }; | ||||
|  | ||||
| static guint signals[N_SIGNALS]; | ||||
|  | ||||
| /* An estimate queue holds several int64_t values. Adding a new value to the | ||||
|  * queue overwrites the oldest value. | ||||
|  */ | ||||
| #define ESTIMATE_QUEUE_LENGTH 16 | ||||
|  | ||||
| typedef struct _EstimateQueue | ||||
| { | ||||
|   int64_t values[ESTIMATE_QUEUE_LENGTH]; | ||||
|   int next_index; | ||||
| } EstimateQueue; | ||||
|  | ||||
| /* When heuristic render time is off, | ||||
|  * wait 2ms after vblank before starting to draw next frame. | ||||
|  */ | ||||
| #define SYNC_DELAY_FALLBACK_US ms2us (2) | ||||
|  | ||||
| typedef struct _ClutterFrameListener | ||||
| { | ||||
|   const ClutterFrameListenerIface *iface; | ||||
|   gpointer user_data; | ||||
| } ClutterFrameListener; | ||||
|  | ||||
| typedef struct _ClutterClockSource | ||||
| { | ||||
|   GSource source; | ||||
|  | ||||
|   ClutterFrameClock *frame_clock; | ||||
| } ClutterClockSource; | ||||
|  | ||||
| typedef enum _ClutterFrameClockState | ||||
| { | ||||
|   CLUTTER_FRAME_CLOCK_STATE_INIT, | ||||
|   CLUTTER_FRAME_CLOCK_STATE_IDLE, | ||||
|   CLUTTER_FRAME_CLOCK_STATE_SCHEDULED, | ||||
|   CLUTTER_FRAME_CLOCK_STATE_DISPATCHING, | ||||
|   CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED, | ||||
| } ClutterFrameClockState; | ||||
|  | ||||
| struct _ClutterFrameClock | ||||
| { | ||||
|   GObject parent; | ||||
|  | ||||
|   float refresh_rate; | ||||
|   int64_t refresh_interval_us; | ||||
|   ClutterFrameListener listener; | ||||
|  | ||||
|   GSource *source; | ||||
|  | ||||
|   int64_t frame_count; | ||||
|  | ||||
|   ClutterFrameClockState state; | ||||
|   int64_t last_dispatch_time_us; | ||||
|   int64_t last_dispatch_lateness_us; | ||||
|   int64_t last_presentation_time_us; | ||||
|  | ||||
|   gboolean is_next_presentation_time_valid; | ||||
|   int64_t next_presentation_time_us; | ||||
|  | ||||
|   /* Buffer must be submitted to KMS and GPU rendering must be finished | ||||
|    * this amount of time before the next presentation time. | ||||
|    */ | ||||
|   int64_t vblank_duration_us; | ||||
|   /* Last KMS buffer submission time. */ | ||||
|   int64_t last_flip_time_us; | ||||
|  | ||||
|   /* Last few durations between dispatch start and buffer swap. */ | ||||
|   EstimateQueue dispatch_to_swap_us; | ||||
|   /* Last few durations between buffer swap and GPU rendering finish. */ | ||||
|   EstimateQueue swap_to_rendering_done_us; | ||||
|   /* Last few durations between buffer swap and KMS submission. */ | ||||
|   EstimateQueue swap_to_flip_us; | ||||
|   /* If we got new measurements last frame. */ | ||||
|   gboolean got_measurements_last_frame; | ||||
|  | ||||
|   gboolean pending_reschedule; | ||||
|   gboolean pending_reschedule_now; | ||||
|  | ||||
|   int inhibit_count; | ||||
|  | ||||
|   GList *timelines; | ||||
| }; | ||||
|  | ||||
| G_DEFINE_TYPE (ClutterFrameClock, clutter_frame_clock, | ||||
|                G_TYPE_OBJECT) | ||||
|  | ||||
| static void | ||||
| estimate_queue_add_value (EstimateQueue *queue, | ||||
|                           int64_t        value) | ||||
| { | ||||
|   queue->values[queue->next_index] = value; | ||||
|   queue->next_index = (queue->next_index + 1) % ESTIMATE_QUEUE_LENGTH; | ||||
| } | ||||
|  | ||||
| float | ||||
| clutter_frame_clock_get_refresh_rate (ClutterFrameClock *frame_clock) | ||||
| { | ||||
|   return frame_clock->refresh_rate; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_frame_clock_set_refresh_rate (ClutterFrameClock *frame_clock, | ||||
|                                       float              refresh_rate) | ||||
| { | ||||
|   frame_clock->refresh_rate = refresh_rate; | ||||
|   frame_clock->refresh_interval_us = | ||||
|     (int64_t) (0.5 + G_USEC_PER_SEC / refresh_rate); | ||||
| } | ||||
|  | ||||
| void | ||||
| clutter_frame_clock_add_timeline (ClutterFrameClock *frame_clock, | ||||
|                                   ClutterTimeline   *timeline) | ||||
| { | ||||
|   gboolean is_first; | ||||
|  | ||||
|   if (g_list_find (frame_clock->timelines, timeline)) | ||||
|     return; | ||||
|  | ||||
|   is_first = !frame_clock->timelines; | ||||
|  | ||||
|   frame_clock->timelines = g_list_prepend (frame_clock->timelines, timeline); | ||||
|  | ||||
|   if (is_first) | ||||
|     clutter_frame_clock_schedule_update (frame_clock); | ||||
| } | ||||
|  | ||||
| void | ||||
| clutter_frame_clock_remove_timeline (ClutterFrameClock *frame_clock, | ||||
|                                      ClutterTimeline   *timeline) | ||||
| { | ||||
|   frame_clock->timelines = g_list_remove (frame_clock->timelines, timeline); | ||||
| } | ||||
|  | ||||
| static void | ||||
| advance_timelines (ClutterFrameClock *frame_clock, | ||||
|                    int64_t            time_us) | ||||
| { | ||||
|   GList *timelines; | ||||
|   GList *l; | ||||
|  | ||||
|   /* we protect ourselves from timelines being removed during | ||||
|    * the advancement by other timelines by copying the list of | ||||
|    * timelines, taking a reference on them, iterating over the | ||||
|    * copied list and then releasing the reference. | ||||
|    * | ||||
|    * we cannot simply take a reference on the timelines and still | ||||
|    * use the list held by the master clock because the do_tick() | ||||
|    * might result in the creation of a new timeline, which gets | ||||
|    * added at the end of the list with no reference increase and | ||||
|    * thus gets disposed at the end of the iteration. | ||||
|    * | ||||
|    * this implies that a newly added timeline will not be advanced | ||||
|    * by this clock iteration, which is perfectly fine since we're | ||||
|    * in its first cycle. | ||||
|    * | ||||
|    * we also cannot steal the frame clock timelines list because | ||||
|    * a timeline might be removed as the direct result of do_tick() | ||||
|    * and remove_timeline() would not find the timeline, failing | ||||
|    * and leaving a dangling pointer behind. | ||||
|    */ | ||||
|  | ||||
|   timelines = g_list_copy (frame_clock->timelines); | ||||
|   g_list_foreach (timelines, (GFunc) g_object_ref, NULL); | ||||
|  | ||||
|   for (l = timelines; l; l = l->next) | ||||
|     { | ||||
|       ClutterTimeline *timeline = l->data; | ||||
|  | ||||
|       _clutter_timeline_do_tick (timeline, time_us / 1000); | ||||
|     } | ||||
|  | ||||
|   g_list_free_full (timelines, g_object_unref); | ||||
| } | ||||
|  | ||||
| static void | ||||
| maybe_reschedule_update (ClutterFrameClock *frame_clock) | ||||
| { | ||||
|   if (frame_clock->pending_reschedule || | ||||
|       frame_clock->timelines) | ||||
|     { | ||||
|       frame_clock->pending_reschedule = FALSE; | ||||
|  | ||||
|       if (frame_clock->pending_reschedule_now) | ||||
|         { | ||||
|           frame_clock->pending_reschedule_now = FALSE; | ||||
|           clutter_frame_clock_schedule_update_now (frame_clock); | ||||
|         } | ||||
|       else | ||||
|         { | ||||
|           clutter_frame_clock_schedule_update (frame_clock); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| void | ||||
| clutter_frame_clock_notify_presented (ClutterFrameClock *frame_clock, | ||||
|                                       ClutterFrameInfo  *frame_info) | ||||
| { | ||||
|   frame_clock->last_presentation_time_us = frame_info->presentation_time; | ||||
|  | ||||
|   frame_clock->got_measurements_last_frame = FALSE; | ||||
|  | ||||
|   if (frame_info->cpu_time_before_buffer_swap_us != 0 && | ||||
|       frame_info->gpu_rendering_duration_ns != 0) | ||||
|     { | ||||
|       int64_t dispatch_to_swap_us, swap_to_rendering_done_us, swap_to_flip_us; | ||||
|  | ||||
|       dispatch_to_swap_us = | ||||
|         frame_info->cpu_time_before_buffer_swap_us - | ||||
|         frame_clock->last_dispatch_time_us; | ||||
|       swap_to_rendering_done_us = | ||||
|         frame_info->gpu_rendering_duration_ns / 1000; | ||||
|       swap_to_flip_us = | ||||
|         frame_clock->last_flip_time_us - | ||||
|         frame_info->cpu_time_before_buffer_swap_us; | ||||
|  | ||||
|       CLUTTER_NOTE (FRAME_TIMINGS, | ||||
|                     "dispatch2swap %ld µs, swap2render %ld µs, swap2flip %ld µs", | ||||
|                     dispatch_to_swap_us, | ||||
|                     swap_to_rendering_done_us, | ||||
|                     swap_to_flip_us); | ||||
|  | ||||
|       estimate_queue_add_value (&frame_clock->dispatch_to_swap_us, | ||||
|                                 dispatch_to_swap_us); | ||||
|       estimate_queue_add_value (&frame_clock->swap_to_rendering_done_us, | ||||
|                                 swap_to_rendering_done_us); | ||||
|       estimate_queue_add_value (&frame_clock->swap_to_flip_us, | ||||
|                                 swap_to_flip_us); | ||||
|  | ||||
|       frame_clock->got_measurements_last_frame = TRUE; | ||||
|     } | ||||
|  | ||||
|   if (frame_info->refresh_rate > 1) | ||||
|     { | ||||
|       clutter_frame_clock_set_refresh_rate (frame_clock, | ||||
|                                             frame_info->refresh_rate); | ||||
|     } | ||||
|  | ||||
|   switch (frame_clock->state) | ||||
|     { | ||||
|     case CLUTTER_FRAME_CLOCK_STATE_INIT: | ||||
|     case CLUTTER_FRAME_CLOCK_STATE_IDLE: | ||||
|     case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED: | ||||
|       g_warn_if_reached (); | ||||
|       break; | ||||
|     case CLUTTER_FRAME_CLOCK_STATE_DISPATCHING: | ||||
|     case CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED: | ||||
|       frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_IDLE; | ||||
|       maybe_reschedule_update (frame_clock); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void | ||||
| clutter_frame_clock_notify_ready (ClutterFrameClock *frame_clock) | ||||
| { | ||||
|   switch (frame_clock->state) | ||||
|     { | ||||
|     case CLUTTER_FRAME_CLOCK_STATE_INIT: | ||||
|     case CLUTTER_FRAME_CLOCK_STATE_IDLE: | ||||
|     case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED: | ||||
|       g_warn_if_reached (); | ||||
|       break; | ||||
|     case CLUTTER_FRAME_CLOCK_STATE_DISPATCHING: | ||||
|     case CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED: | ||||
|       frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_IDLE; | ||||
|       maybe_reschedule_update (frame_clock); | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static int64_t | ||||
| clutter_frame_clock_compute_max_render_time_us (ClutterFrameClock *frame_clock) | ||||
| { | ||||
|   int64_t refresh_interval_us; | ||||
|   int64_t max_dispatch_to_swap_us = 0; | ||||
|   int64_t max_swap_to_rendering_done_us = 0; | ||||
|   int64_t max_swap_to_flip_us = 0; | ||||
|   int64_t max_render_time_us; | ||||
|   int i; | ||||
|  | ||||
|   refresh_interval_us = | ||||
|     (int64_t) (0.5 + G_USEC_PER_SEC / frame_clock->refresh_rate); | ||||
|  | ||||
|   if (!frame_clock->got_measurements_last_frame || | ||||
|       G_UNLIKELY (clutter_paint_debug_flags & | ||||
|                   CLUTTER_DEBUG_DISABLE_DYNAMIC_MAX_RENDER_TIME)) | ||||
|     return refresh_interval_us - SYNC_DELAY_FALLBACK_US; | ||||
|  | ||||
|   for (i = 0; i < ESTIMATE_QUEUE_LENGTH; ++i) | ||||
|     { | ||||
|       max_dispatch_to_swap_us = | ||||
|         MAX (max_dispatch_to_swap_us, | ||||
|              frame_clock->dispatch_to_swap_us.values[i]); | ||||
|       max_swap_to_rendering_done_us = | ||||
|         MAX (max_swap_to_rendering_done_us, | ||||
|              frame_clock->swap_to_rendering_done_us.values[i]); | ||||
|       max_swap_to_flip_us = | ||||
|         MAX (max_swap_to_flip_us, | ||||
|              frame_clock->swap_to_flip_us.values[i]); | ||||
|     } | ||||
|  | ||||
|   /* Max render time shows how early the frame clock needs to be dispatched | ||||
|    * to make it to the predicted next presentation time. It is composed of: | ||||
|    * - An estimate of duration from dispatch start to buffer swap. | ||||
|    * - Maximum between estimates of duration from buffer swap to GPU rendering | ||||
|    *   finish and duration from buffer swap to buffer submission to KMS. This | ||||
|    *   is because both of these things need to happen before the vblank, and | ||||
|    *   they are done in parallel. | ||||
|    * - Duration of the vblank. | ||||
|    * - A constant to account for variations in the above estimates. | ||||
|    */ | ||||
|   max_render_time_us = | ||||
|     max_dispatch_to_swap_us + | ||||
|     MAX (max_swap_to_rendering_done_us, max_swap_to_flip_us) + | ||||
|     frame_clock->vblank_duration_us + | ||||
|     clutter_max_render_time_constant_us; | ||||
|  | ||||
|   max_render_time_us = CLAMP (max_render_time_us, 0, refresh_interval_us); | ||||
|  | ||||
|   return max_render_time_us; | ||||
| } | ||||
|  | ||||
| static void | ||||
| calculate_next_update_time_us (ClutterFrameClock *frame_clock, | ||||
|                                int64_t           *out_next_update_time_us, | ||||
|                                int64_t           *out_next_presentation_time_us) | ||||
| { | ||||
|   int64_t last_presentation_time_us; | ||||
|   int64_t now_us; | ||||
|   int64_t refresh_interval_us; | ||||
|   int64_t min_render_time_allowed_us; | ||||
|   int64_t max_render_time_allowed_us; | ||||
|   int64_t last_next_presentation_time_us; | ||||
|   int64_t time_since_last_next_presentation_time_us; | ||||
|   int64_t next_presentation_time_us; | ||||
|   int64_t next_update_time_us; | ||||
|  | ||||
|   now_us = g_get_monotonic_time (); | ||||
|  | ||||
|   refresh_interval_us = frame_clock->refresh_interval_us; | ||||
|  | ||||
|   if (frame_clock->last_presentation_time_us == 0) | ||||
|     { | ||||
|       *out_next_update_time_us = | ||||
|         frame_clock->last_dispatch_time_us ? | ||||
|         ((frame_clock->last_dispatch_time_us - | ||||
|           frame_clock->last_dispatch_lateness_us) + refresh_interval_us) : | ||||
|         now_us; | ||||
|  | ||||
|       *out_next_presentation_time_us = 0; | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   min_render_time_allowed_us = refresh_interval_us / 2; | ||||
|   max_render_time_allowed_us = | ||||
|     clutter_frame_clock_compute_max_render_time_us (frame_clock); | ||||
|  | ||||
|   if (min_render_time_allowed_us > max_render_time_allowed_us) | ||||
|     min_render_time_allowed_us = max_render_time_allowed_us; | ||||
|  | ||||
|   /* | ||||
|    * The common case is that the next presentation happens 1 refresh interval | ||||
|    * after the last presentation: | ||||
|    * | ||||
|    *        last_presentation_time_us | ||||
|    *       /       next_presentation_time_us | ||||
|    *      /       / | ||||
|    *     /       / | ||||
|    * |--|--o----|-------|--> presentation times | ||||
|    * |  |  \    | | ||||
|    * |  |   now_us | ||||
|    * |  \______/ | ||||
|    * | refresh_interval_us | ||||
|    * | | ||||
|    * 0 | ||||
|    * | ||||
|    */ | ||||
|   last_presentation_time_us = frame_clock->last_presentation_time_us; | ||||
|   next_presentation_time_us = last_presentation_time_us + refresh_interval_us; | ||||
|  | ||||
|   /* | ||||
|    * However, the last presentation could have happened more than a frame ago. | ||||
|    * For example, due to idling (nothing on screen changed, so no need to | ||||
|    * redraw) or due to frames missing deadlines (GPU busy with heavy rendering). | ||||
|    * The following code adjusts next_presentation_time_us to be in the future, | ||||
|    * but still aligned to display presentation times. Instead of | ||||
|    * next presentation = last presentation + 1 * refresh interval, it will be | ||||
|    * next presentation = last presentation + N * refresh interval. | ||||
|    */ | ||||
|   if (next_presentation_time_us < now_us) | ||||
|     { | ||||
|       int64_t presentation_phase_us; | ||||
|       int64_t current_phase_us; | ||||
|       int64_t current_refresh_interval_start_us; | ||||
|  | ||||
|       /* | ||||
|        * Let's say we're just past next_presentation_time_us. | ||||
|        * | ||||
|        * First, we compute presentation_phase_us. Real presentation times don't | ||||
|        * have to be exact multiples of refresh_interval_us and | ||||
|        * presentation_phase_us represents this difference. Next, we compute | ||||
|        * current phase and the refresh interval start corresponding to now_us. | ||||
|        * Finally, add presentation_phase_us and a refresh interval to get the | ||||
|        * next presentation after now_us. | ||||
|        * | ||||
|        *        last_presentation_time_us | ||||
|        *       /       next_presentation_time_us | ||||
|        *      /       /   now_us | ||||
|        *     /       /   /   new next_presentation_time_us | ||||
|        * |--|-------|---o---|-------|--> presentation times | ||||
|        * |        __| | ||||
|        * |       |presentation_phase_us | ||||
|        * |       | | ||||
|        * |       |     now_us - presentation_phase_us | ||||
|        * |       |    / | ||||
|        * |-------|---o---|-------|-----> integer multiples of refresh_interval_us | ||||
|        * |       \__/ | ||||
|        * |       |current_phase_us | ||||
|        * |       \ | ||||
|        * |        current_refresh_interval_start_us | ||||
|        * 0 | ||||
|        * | ||||
|        */ | ||||
|  | ||||
|       presentation_phase_us = last_presentation_time_us % refresh_interval_us; | ||||
|       current_phase_us = (now_us - presentation_phase_us) % refresh_interval_us; | ||||
|       current_refresh_interval_start_us = | ||||
|         now_us - presentation_phase_us - current_phase_us; | ||||
|  | ||||
|       next_presentation_time_us = | ||||
|         current_refresh_interval_start_us + | ||||
|         presentation_phase_us + | ||||
|         refresh_interval_us; | ||||
|     } | ||||
|  | ||||
|   /* | ||||
|    * Skip one interval if we got an early presented event. | ||||
|    * | ||||
|    *        last frame this was last_presentation_time | ||||
|    *       /       frame_clock->next_presentation_time_us | ||||
|    *      /       / | ||||
|    * |---|-o-----|-x-----> | ||||
|    *       |       \ | ||||
|    *       \        next_presentation_time_us is thus right after the last one | ||||
|    *        but got an unexpected early presentation | ||||
|    *             \_/ | ||||
|    *             time_since_last_next_presentation_time_us | ||||
|    * | ||||
|    */ | ||||
|   last_next_presentation_time_us = frame_clock->next_presentation_time_us; | ||||
|   time_since_last_next_presentation_time_us = | ||||
|     next_presentation_time_us - last_next_presentation_time_us; | ||||
|   if (frame_clock->is_next_presentation_time_valid && | ||||
|       time_since_last_next_presentation_time_us < (refresh_interval_us / 2)) | ||||
|     { | ||||
|       next_presentation_time_us = | ||||
|         frame_clock->next_presentation_time_us + refresh_interval_us; | ||||
|     } | ||||
|  | ||||
|   while (next_presentation_time_us < now_us + min_render_time_allowed_us) | ||||
|     next_presentation_time_us += refresh_interval_us; | ||||
|  | ||||
|   next_update_time_us = next_presentation_time_us - max_render_time_allowed_us; | ||||
|  | ||||
|   *out_next_update_time_us = next_update_time_us; | ||||
|   *out_next_presentation_time_us = next_presentation_time_us; | ||||
| } | ||||
|  | ||||
| void | ||||
| clutter_frame_clock_inhibit (ClutterFrameClock *frame_clock) | ||||
| { | ||||
|   frame_clock->inhibit_count++; | ||||
|  | ||||
|   if (frame_clock->inhibit_count == 1) | ||||
|     { | ||||
|       switch (frame_clock->state) | ||||
|         { | ||||
|         case CLUTTER_FRAME_CLOCK_STATE_INIT: | ||||
|         case CLUTTER_FRAME_CLOCK_STATE_IDLE: | ||||
|           break; | ||||
|         case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED: | ||||
|           frame_clock->pending_reschedule = TRUE; | ||||
|           frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_IDLE; | ||||
|           break; | ||||
|         case CLUTTER_FRAME_CLOCK_STATE_DISPATCHING: | ||||
|         case CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED: | ||||
|           break; | ||||
|         } | ||||
|  | ||||
|       g_source_set_ready_time (frame_clock->source, -1); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void | ||||
| clutter_frame_clock_uninhibit (ClutterFrameClock *frame_clock) | ||||
| { | ||||
|   g_return_if_fail (frame_clock->inhibit_count > 0); | ||||
|  | ||||
|   frame_clock->inhibit_count--; | ||||
|  | ||||
|   if (frame_clock->inhibit_count == 0) | ||||
|     maybe_reschedule_update (frame_clock); | ||||
| } | ||||
|  | ||||
| void | ||||
| clutter_frame_clock_schedule_update_now (ClutterFrameClock *frame_clock) | ||||
| { | ||||
|   int64_t next_update_time_us = -1; | ||||
|  | ||||
|   if (frame_clock->inhibit_count > 0) | ||||
|     { | ||||
|       frame_clock->pending_reschedule = TRUE; | ||||
|       frame_clock->pending_reschedule_now = TRUE; | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   switch (frame_clock->state) | ||||
|     { | ||||
|     case CLUTTER_FRAME_CLOCK_STATE_INIT: | ||||
|     case CLUTTER_FRAME_CLOCK_STATE_IDLE: | ||||
|       next_update_time_us = g_get_monotonic_time (); | ||||
|       break; | ||||
|     case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED: | ||||
|       return; | ||||
|     case CLUTTER_FRAME_CLOCK_STATE_DISPATCHING: | ||||
|     case CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED: | ||||
|       frame_clock->pending_reschedule = TRUE; | ||||
|       frame_clock->pending_reschedule_now = TRUE; | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   g_warn_if_fail (next_update_time_us != -1); | ||||
|  | ||||
|   g_source_set_ready_time (frame_clock->source, next_update_time_us); | ||||
|   frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_SCHEDULED; | ||||
|   frame_clock->is_next_presentation_time_valid = FALSE; | ||||
| } | ||||
|  | ||||
| void | ||||
| clutter_frame_clock_schedule_update (ClutterFrameClock *frame_clock) | ||||
| { | ||||
|   int64_t next_update_time_us = -1; | ||||
|  | ||||
|   if (frame_clock->inhibit_count > 0) | ||||
|     { | ||||
|       frame_clock->pending_reschedule = TRUE; | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   switch (frame_clock->state) | ||||
|     { | ||||
|     case CLUTTER_FRAME_CLOCK_STATE_INIT: | ||||
|       next_update_time_us = g_get_monotonic_time (); | ||||
|       break; | ||||
|     case CLUTTER_FRAME_CLOCK_STATE_IDLE: | ||||
|       calculate_next_update_time_us (frame_clock, | ||||
|                                      &next_update_time_us, | ||||
|                                      &frame_clock->next_presentation_time_us); | ||||
|       frame_clock->is_next_presentation_time_valid = | ||||
|         (frame_clock->next_presentation_time_us != 0); | ||||
|       break; | ||||
|     case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED: | ||||
|       return; | ||||
|     case CLUTTER_FRAME_CLOCK_STATE_DISPATCHING: | ||||
|     case CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED: | ||||
|       frame_clock->pending_reschedule = TRUE; | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   g_warn_if_fail (next_update_time_us != -1); | ||||
|  | ||||
|   g_source_set_ready_time (frame_clock->source, next_update_time_us); | ||||
|   frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_SCHEDULED; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_frame_clock_dispatch (ClutterFrameClock *frame_clock, | ||||
|                               int64_t            time_us) | ||||
| { | ||||
|   int64_t frame_count; | ||||
|   ClutterFrameResult result; | ||||
|   int64_t ideal_dispatch_time_us, lateness_us; | ||||
|  | ||||
|   COGL_TRACE_BEGIN_SCOPED (ClutterFrameClockDispatch, "Frame Clock (dispatch)"); | ||||
|  | ||||
|   ideal_dispatch_time_us = (frame_clock->last_dispatch_time_us - | ||||
|                             frame_clock->last_dispatch_lateness_us) + | ||||
|                            frame_clock->refresh_interval_us; | ||||
|  | ||||
|   lateness_us = time_us - ideal_dispatch_time_us; | ||||
|   if (lateness_us < 0 || lateness_us >= frame_clock->refresh_interval_us) | ||||
|     frame_clock->last_dispatch_lateness_us = 0; | ||||
|   else | ||||
|     frame_clock->last_dispatch_lateness_us = lateness_us; | ||||
|  | ||||
|   frame_clock->last_dispatch_time_us = time_us; | ||||
|   g_source_set_ready_time (frame_clock->source, -1); | ||||
|  | ||||
|   frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_DISPATCHING; | ||||
|  | ||||
|   frame_count = frame_clock->frame_count++; | ||||
|  | ||||
|   COGL_TRACE_BEGIN (ClutterFrameClockEvents, "Frame Clock (before frame)"); | ||||
|   if (frame_clock->listener.iface->before_frame) | ||||
|     { | ||||
|       frame_clock->listener.iface->before_frame (frame_clock, | ||||
|                                                  frame_count, | ||||
|                                                  frame_clock->listener.user_data); | ||||
|     } | ||||
|   COGL_TRACE_END (ClutterFrameClockEvents); | ||||
|  | ||||
|   COGL_TRACE_BEGIN (ClutterFrameClockTimelines, "Frame Clock (timelines)"); | ||||
|   advance_timelines (frame_clock, time_us); | ||||
|   COGL_TRACE_END (ClutterFrameClockTimelines); | ||||
|  | ||||
|   COGL_TRACE_BEGIN (ClutterFrameClockFrame, "Frame Clock (frame)"); | ||||
|   result = frame_clock->listener.iface->frame (frame_clock, | ||||
|                                                frame_count, | ||||
|                                                time_us, | ||||
|                                                frame_clock->listener.user_data); | ||||
|   COGL_TRACE_END (ClutterFrameClockFrame); | ||||
|  | ||||
|   switch (frame_clock->state) | ||||
|     { | ||||
|     case CLUTTER_FRAME_CLOCK_STATE_INIT: | ||||
|     case CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED: | ||||
|       g_warn_if_reached (); | ||||
|       break; | ||||
|     case CLUTTER_FRAME_CLOCK_STATE_IDLE: | ||||
|     case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED: | ||||
|       break; | ||||
|     case CLUTTER_FRAME_CLOCK_STATE_DISPATCHING: | ||||
|       switch (result) | ||||
|         { | ||||
|         case CLUTTER_FRAME_RESULT_PENDING_PRESENTED: | ||||
|           frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED; | ||||
|           break; | ||||
|         case CLUTTER_FRAME_RESULT_IDLE: | ||||
|           frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_IDLE; | ||||
|           maybe_reschedule_update (frame_clock); | ||||
|           break; | ||||
|         } | ||||
|       break; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| frame_clock_source_dispatch (GSource     *source, | ||||
|                              GSourceFunc  callback, | ||||
|                              gpointer     user_data) | ||||
| { | ||||
|   ClutterClockSource *clock_source = (ClutterClockSource *) source; | ||||
|   ClutterFrameClock *frame_clock = clock_source->frame_clock; | ||||
|   int64_t dispatch_time_us; | ||||
|  | ||||
|   dispatch_time_us = g_source_get_time (source); | ||||
|   clutter_frame_clock_dispatch (frame_clock, dispatch_time_us); | ||||
|  | ||||
|   return G_SOURCE_CONTINUE; | ||||
| } | ||||
|  | ||||
| void | ||||
| clutter_frame_clock_record_flip_time (ClutterFrameClock *frame_clock, | ||||
|                                       int64_t            flip_time_us) | ||||
| { | ||||
|   frame_clock->last_flip_time_us = flip_time_us; | ||||
| } | ||||
|  | ||||
| GString * | ||||
| clutter_frame_clock_get_max_render_time_debug_info (ClutterFrameClock *frame_clock) | ||||
| { | ||||
|   int64_t max_dispatch_to_swap_us = 0; | ||||
|   int64_t max_swap_to_rendering_done_us = 0; | ||||
|   int64_t max_swap_to_flip_us = 0; | ||||
|   int i; | ||||
|   GString *string; | ||||
|  | ||||
|   string = g_string_new (NULL); | ||||
|   g_string_append_printf (string, "Max render time: %ld µs", | ||||
|                           clutter_frame_clock_compute_max_render_time_us (frame_clock)); | ||||
|  | ||||
|   if (frame_clock->got_measurements_last_frame) | ||||
|     g_string_append_printf (string, " ="); | ||||
|   else | ||||
|     g_string_append_printf (string, " (no measurements last frame)"); | ||||
|  | ||||
|   for (i = 0; i < ESTIMATE_QUEUE_LENGTH; ++i) | ||||
|     { | ||||
|       max_dispatch_to_swap_us = | ||||
|         MAX (max_dispatch_to_swap_us, | ||||
|              frame_clock->dispatch_to_swap_us.values[i]); | ||||
|       max_swap_to_rendering_done_us = | ||||
|         MAX (max_swap_to_rendering_done_us, | ||||
|              frame_clock->swap_to_rendering_done_us.values[i]); | ||||
|       max_swap_to_flip_us = | ||||
|         MAX (max_swap_to_flip_us, | ||||
|              frame_clock->swap_to_flip_us.values[i]); | ||||
|     } | ||||
|  | ||||
|   g_string_append_printf (string, "\nVblank duration: %ld µs +", | ||||
|                           frame_clock->vblank_duration_us); | ||||
|   g_string_append_printf (string, "\nDispatch to swap: %ld µs +", | ||||
|                           max_dispatch_to_swap_us); | ||||
|   g_string_append_printf (string, "\nmax(Swap to rendering done: %ld µs,", | ||||
|                           max_swap_to_rendering_done_us); | ||||
|   g_string_append_printf (string, "\nSwap to flip: %ld µs) +", | ||||
|                           max_swap_to_flip_us); | ||||
|   g_string_append_printf (string, "\nConstant: %d µs", | ||||
|                           clutter_max_render_time_constant_us); | ||||
|  | ||||
|   return string; | ||||
| } | ||||
|  | ||||
| static GSourceFuncs frame_clock_source_funcs = { | ||||
|   NULL, | ||||
|   NULL, | ||||
|   frame_clock_source_dispatch, | ||||
|   NULL | ||||
| }; | ||||
|  | ||||
| static void | ||||
| init_frame_clock_source (ClutterFrameClock *frame_clock) | ||||
| { | ||||
|   GSource *source; | ||||
|   ClutterClockSource *clock_source; | ||||
|   g_autofree char *name = NULL; | ||||
|  | ||||
|   source = g_source_new (&frame_clock_source_funcs, sizeof (ClutterClockSource)); | ||||
|   clock_source = (ClutterClockSource *) source; | ||||
|  | ||||
|   name = g_strdup_printf ("Clutter frame clock (%p)", frame_clock); | ||||
|   g_source_set_name (source, name); | ||||
|   g_source_set_priority (source, CLUTTER_PRIORITY_REDRAW); | ||||
|   g_source_set_can_recurse (source, FALSE); | ||||
|   clock_source->frame_clock = frame_clock; | ||||
|  | ||||
|   frame_clock->source = source; | ||||
|   g_source_attach (source, NULL); | ||||
| } | ||||
|  | ||||
| ClutterFrameClock * | ||||
| clutter_frame_clock_new (float                            refresh_rate, | ||||
|                          int64_t                          vblank_duration_us, | ||||
|                          const ClutterFrameListenerIface *iface, | ||||
|                          gpointer                         user_data) | ||||
| { | ||||
|   ClutterFrameClock *frame_clock; | ||||
|  | ||||
|   g_assert_cmpfloat (refresh_rate, >, 0.0); | ||||
|  | ||||
|   frame_clock = g_object_new (CLUTTER_TYPE_FRAME_CLOCK, NULL); | ||||
|  | ||||
|   frame_clock->listener.iface = iface; | ||||
|   frame_clock->listener.user_data = user_data; | ||||
|  | ||||
|   init_frame_clock_source (frame_clock); | ||||
|  | ||||
|   clutter_frame_clock_set_refresh_rate (frame_clock, refresh_rate); | ||||
|   frame_clock->vblank_duration_us = vblank_duration_us; | ||||
|  | ||||
|   return frame_clock; | ||||
| } | ||||
|  | ||||
| void | ||||
| clutter_frame_clock_destroy (ClutterFrameClock *frame_clock) | ||||
| { | ||||
|   g_object_run_dispose (G_OBJECT (frame_clock)); | ||||
|   g_object_unref (frame_clock); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_frame_clock_dispose (GObject *object) | ||||
| { | ||||
|   ClutterFrameClock *frame_clock = CLUTTER_FRAME_CLOCK (object); | ||||
|  | ||||
|   if (frame_clock->source) | ||||
|     { | ||||
|       g_signal_emit (frame_clock, signals[DESTROY], 0); | ||||
|       g_source_destroy (frame_clock->source); | ||||
|       g_clear_pointer (&frame_clock->source, g_source_unref); | ||||
|     } | ||||
|  | ||||
|   G_OBJECT_CLASS (clutter_frame_clock_parent_class)->dispose (object); | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_frame_clock_init (ClutterFrameClock *frame_clock) | ||||
| { | ||||
|   frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_INIT; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_frame_clock_class_init (ClutterFrameClockClass *klass) | ||||
| { | ||||
|   GObjectClass *object_class = G_OBJECT_CLASS (klass); | ||||
|  | ||||
|   object_class->dispose = clutter_frame_clock_dispose; | ||||
|  | ||||
|   signals[DESTROY] = | ||||
|     g_signal_new (I_("destroy"), | ||||
|                   G_TYPE_FROM_CLASS (object_class), | ||||
|                   G_SIGNAL_RUN_LAST, | ||||
|                   0, | ||||
|                   NULL, NULL, NULL, | ||||
|                   G_TYPE_NONE, | ||||
|                   0); | ||||
| } | ||||
| @@ -1,99 +0,0 @@ | ||||
| /* | ||||
|  * Copyright (C) 2019 Red Hat Inc. | ||||
|  * | ||||
|  * This library is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Lesser General Public | ||||
|  * License as published by the Free Software Foundation; either | ||||
|  * version 2 of the License, or (at your option) any later version. | ||||
|  * | ||||
|  * This library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * Lesser General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Lesser General Public | ||||
|  * License along with this library. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| #ifndef CLUTTER_FRAME_CLOCK_H | ||||
| #define CLUTTER_FRAME_CLOCK_H | ||||
|  | ||||
| #if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <clutter/clutter.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include <glib.h> | ||||
| #include <glib-object.h> | ||||
| #include <stdint.h> | ||||
|  | ||||
| #include "clutter/clutter-types.h" | ||||
|  | ||||
| typedef enum _ClutterFrameResult | ||||
| { | ||||
|   CLUTTER_FRAME_RESULT_PENDING_PRESENTED, | ||||
|   CLUTTER_FRAME_RESULT_IDLE, | ||||
| } ClutterFrameResult; | ||||
|  | ||||
| #define CLUTTER_TYPE_FRAME_CLOCK (clutter_frame_clock_get_type ()) | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_FINAL_TYPE (ClutterFrameClock, clutter_frame_clock, | ||||
|                       CLUTTER, FRAME_CLOCK, | ||||
|                       GObject) | ||||
|  | ||||
| /** | ||||
|  * ClutterFrameListenerIface: (skip) | ||||
|  */ | ||||
| typedef struct _ClutterFrameListenerIface | ||||
| { | ||||
|   void (* before_frame) (ClutterFrameClock *frame_clock, | ||||
|                          int64_t            frame_count, | ||||
|                          gpointer           user_data); | ||||
|   ClutterFrameResult (* frame) (ClutterFrameClock *frame_clock, | ||||
|                                 int64_t            frame_count, | ||||
|                                 int64_t            time_us, | ||||
|                                 gpointer           user_data); | ||||
| } ClutterFrameListenerIface; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterFrameClock * clutter_frame_clock_new (float                            refresh_rate, | ||||
|                                              int64_t                          vblank_duration_us, | ||||
|                                              const ClutterFrameListenerIface *iface, | ||||
|                                              gpointer                         user_data); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void clutter_frame_clock_destroy (ClutterFrameClock *frame_clock); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void clutter_frame_clock_notify_presented (ClutterFrameClock *frame_clock, | ||||
|                                            ClutterFrameInfo  *frame_info); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void clutter_frame_clock_notify_ready (ClutterFrameClock *frame_clock); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void clutter_frame_clock_schedule_update (ClutterFrameClock *frame_clock); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void clutter_frame_clock_schedule_update_now (ClutterFrameClock *frame_clock); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void clutter_frame_clock_inhibit (ClutterFrameClock *frame_clock); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void clutter_frame_clock_uninhibit (ClutterFrameClock *frame_clock); | ||||
|  | ||||
| void clutter_frame_clock_add_timeline (ClutterFrameClock *frame_clock, | ||||
|                                        ClutterTimeline   *timeline); | ||||
|  | ||||
| void clutter_frame_clock_remove_timeline (ClutterFrameClock *frame_clock, | ||||
|                                           ClutterTimeline   *timeline); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| float clutter_frame_clock_get_refresh_rate (ClutterFrameClock *frame_clock); | ||||
|  | ||||
| void clutter_frame_clock_record_flip_time (ClutterFrameClock *frame_clock, | ||||
|                                            int64_t            flip_time_us); | ||||
|  | ||||
| GString * clutter_frame_clock_get_max_render_time_debug_info (ClutterFrameClock *frame_clock); | ||||
|  | ||||
| #endif /* CLUTTER_FRAME_CLOCK_H */ | ||||
| @@ -1,33 +0,0 @@ | ||||
| /* | ||||
|  * Copyright (C) 2020 Red Hat Inc. | ||||
|  * | ||||
|  * This library is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Lesser General Public | ||||
|  * License as published by the Free Software Foundation; either | ||||
|  * version 2 of the License, or (at your option) any later version. | ||||
|  * | ||||
|  * This library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * Lesser General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Lesser General Public | ||||
|  * License along with this library. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| #ifndef CLUTTER_FRAME_PRIVATE_H | ||||
| #define CLUTTER_FRAME_PRIVATE_H | ||||
|  | ||||
| #include "clutter/clutter-frame.h" | ||||
|  | ||||
| struct _ClutterFrame | ||||
| { | ||||
|   gboolean has_result; | ||||
|   ClutterFrameResult result; | ||||
| }; | ||||
|  | ||||
| #define CLUTTER_FRAME_INIT ((ClutterFrame) { 0 }) | ||||
|  | ||||
| ClutterFrameResult clutter_frame_get_result (ClutterFrame *frame); | ||||
|  | ||||
| #endif /* CLUTTER_FRAME_PRIVATE_H */ | ||||
| @@ -1,42 +0,0 @@ | ||||
| /* | ||||
|  * Copyright (C) 2020 Red Hat Inc. | ||||
|  * | ||||
|  * This library is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Lesser General Public | ||||
|  * License as published by the Free Software Foundation; either | ||||
|  * version 2 of the License, or (at your option) any later version. | ||||
|  * | ||||
|  * This library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * Lesser General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Lesser General Public | ||||
|  * License along with this library. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| #include "clutter/clutter-frame-private.h" | ||||
|  | ||||
| ClutterFrameResult | ||||
| clutter_frame_get_result (ClutterFrame *frame) | ||||
| { | ||||
|   g_return_val_if_fail (frame->has_result, CLUTTER_FRAME_RESULT_IDLE); | ||||
|  | ||||
|   return frame->result; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| clutter_frame_has_result (ClutterFrame *frame) | ||||
| { | ||||
|   return frame->has_result; | ||||
| } | ||||
|  | ||||
| void | ||||
| clutter_frame_set_result (ClutterFrame       *frame, | ||||
|                           ClutterFrameResult  result) | ||||
| { | ||||
|   g_warn_if_fail (!frame->has_result); | ||||
|  | ||||
|   frame->result = result; | ||||
|   frame->has_result = TRUE; | ||||
| } | ||||
| @@ -1,36 +0,0 @@ | ||||
| /* | ||||
|  * Copyright (C) 2020 Red Hat Inc. | ||||
|  * | ||||
|  * This library is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Lesser General Public | ||||
|  * License as published by the Free Software Foundation; either | ||||
|  * version 2 of the License, or (at your option) any later version. | ||||
|  * | ||||
|  * This library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * Lesser General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Lesser General Public | ||||
|  * License along with this library. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| #ifndef CLUTTER_FRAME_H | ||||
| #define CLUTTER_FRAME_H | ||||
|  | ||||
| #if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) | ||||
| #error "Only <clutter/clutter.h> can be included directly." | ||||
| #endif | ||||
|  | ||||
| #include "clutter/clutter-frame-clock.h" | ||||
|  | ||||
| typedef struct _ClutterFrame ClutterFrame; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void clutter_frame_set_result (ClutterFrame       *frame, | ||||
|                                ClutterFrameResult  result); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| gboolean clutter_frame_has_result (ClutterFrame *frame); | ||||
|  | ||||
| #endif /* CLUTTER_FRAME_H */ | ||||
| @@ -118,6 +118,9 @@ struct _ClutterGestureActionPrivate | ||||
|   gint requested_nb_points; | ||||
|   GArray *points; | ||||
|  | ||||
|   gulong actor_capture_id; | ||||
|   gulong stage_capture_id; | ||||
|  | ||||
|   ClutterGestureTriggerEdge edge; | ||||
|   float distance_x, distance_y; | ||||
|  | ||||
| @@ -152,11 +155,9 @@ static guint gesture_signals[LAST_SIGNAL] = { 0, }; | ||||
| G_DEFINE_TYPE_WITH_PRIVATE (ClutterGestureAction, clutter_gesture_action, CLUTTER_TYPE_ACTION) | ||||
|  | ||||
| static GesturePoint * | ||||
| gesture_register_point (ClutterGestureAction *action, | ||||
|                         const ClutterEvent   *event) | ||||
| gesture_register_point (ClutterGestureAction *action, ClutterEvent *event) | ||||
| { | ||||
|   ClutterGestureActionPrivate *priv = | ||||
|     clutter_gesture_action_get_instance_private (action); | ||||
|   ClutterGestureActionPrivate *priv = action->priv; | ||||
|   GesturePoint *point = NULL; | ||||
|  | ||||
|   if (priv->points->len >= MAX_GESTURE_POINTS) | ||||
| @@ -186,11 +187,10 @@ gesture_register_point (ClutterGestureAction *action, | ||||
|  | ||||
| static GesturePoint * | ||||
| gesture_find_point (ClutterGestureAction *action, | ||||
|                     const ClutterEvent   *event, | ||||
|                     int                  *position) | ||||
|                     ClutterEvent *event, | ||||
|                     gint *position) | ||||
| { | ||||
|   ClutterGestureActionPrivate *priv = | ||||
|     clutter_gesture_action_get_instance_private (action); | ||||
|   ClutterGestureActionPrivate *priv = action->priv; | ||||
|   GesturePoint *point = NULL; | ||||
|   ClutterEventType type = clutter_event_type (event); | ||||
|   ClutterInputDevice *device = clutter_event_get_device (event); | ||||
| @@ -220,18 +220,17 @@ gesture_find_point (ClutterGestureAction *action, | ||||
| static void | ||||
| gesture_unregister_point (ClutterGestureAction *action, gint position) | ||||
| { | ||||
|   ClutterGestureActionPrivate *priv = | ||||
|     clutter_gesture_action_get_instance_private (action); | ||||
|   ClutterGestureActionPrivate *priv = action->priv; | ||||
|  | ||||
|   if (priv->points->len == 0) | ||||
|   if (action->priv->points->len == 0) | ||||
|     return; | ||||
|  | ||||
|   g_array_remove_index (priv->points, position); | ||||
| } | ||||
|  | ||||
| static void | ||||
| gesture_update_motion_point (GesturePoint       *point, | ||||
|                              const ClutterEvent *event) | ||||
| gesture_update_motion_point (GesturePoint *point, | ||||
|                              ClutterEvent *event) | ||||
| { | ||||
|   gfloat motion_x, motion_y; | ||||
|   gint64 _time; | ||||
| @@ -252,8 +251,8 @@ gesture_update_motion_point (GesturePoint       *point, | ||||
| } | ||||
|  | ||||
| static void | ||||
| gesture_update_release_point (GesturePoint       *point, | ||||
|                               const ClutterEvent *event) | ||||
| gesture_update_release_point (GesturePoint *point, | ||||
|                               ClutterEvent *event) | ||||
| { | ||||
|   gint64 _time; | ||||
|  | ||||
| @@ -281,7 +280,7 @@ gesture_get_default_threshold (void) | ||||
| static gboolean | ||||
| gesture_point_pass_threshold (ClutterGestureAction *action, | ||||
|                               GesturePoint         *point, | ||||
|                               const ClutterEvent   *event) | ||||
|                               ClutterEvent         *event) | ||||
| { | ||||
|   float threshold_x, threshold_y; | ||||
|   gfloat motion_x, motion_y; | ||||
| @@ -304,24 +303,24 @@ gesture_point_unset (GesturePoint *point) | ||||
| static void | ||||
| cancel_gesture (ClutterGestureAction *action) | ||||
| { | ||||
|   ClutterGestureActionPrivate *priv = | ||||
|     clutter_gesture_action_get_instance_private (action); | ||||
|   ClutterGestureActionPrivate *priv = action->priv; | ||||
|   ClutterActor *actor; | ||||
|  | ||||
|   priv->in_gesture = FALSE; | ||||
|  | ||||
|   g_clear_signal_handler (&priv->stage_capture_id, priv->stage); | ||||
|  | ||||
|   actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action)); | ||||
|   g_signal_emit (action, gesture_signals[GESTURE_CANCEL], 0, actor); | ||||
|  | ||||
|   g_array_set_size (priv->points, 0); | ||||
|   g_array_set_size (action->priv->points, 0); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| begin_gesture (ClutterGestureAction *action, | ||||
|                ClutterActor         *actor) | ||||
| { | ||||
|   ClutterGestureActionPrivate *priv = | ||||
|     clutter_gesture_action_get_instance_private (action); | ||||
|   ClutterGestureActionPrivate *priv = action->priv; | ||||
|   gboolean return_value; | ||||
|  | ||||
|   priv->in_gesture = TRUE; | ||||
| @@ -350,50 +349,33 @@ begin_gesture (ClutterGestureAction *action, | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| clutter_gesture_action_handle_event (ClutterAction      *action, | ||||
|                                      const ClutterEvent *event) | ||||
| stage_captured_event_cb (ClutterActor         *stage, | ||||
|                          ClutterEvent         *event, | ||||
|                          ClutterGestureAction *action) | ||||
| { | ||||
|   ClutterGestureAction *gesture_action = CLUTTER_GESTURE_ACTION (action); | ||||
|   ClutterGestureActionPrivate *priv = | ||||
|     clutter_gesture_action_get_instance_private (gesture_action); | ||||
|   ClutterActor *actor = | ||||
|     clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action)); | ||||
|   ClutterGestureActionPrivate *priv = action->priv; | ||||
|   ClutterActor *actor; | ||||
|   gint position; | ||||
|   float threshold_x, threshold_y; | ||||
|   gboolean return_value; | ||||
|   GesturePoint *point; | ||||
|   ClutterEventType event_type; | ||||
|  | ||||
|   if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (action))) | ||||
|   event_type = clutter_event_type (event); | ||||
|   if (event_type != CLUTTER_TOUCH_CANCEL && | ||||
|       event_type != CLUTTER_TOUCH_UPDATE && | ||||
|       event_type != CLUTTER_TOUCH_END && | ||||
|       event_type != CLUTTER_MOTION && | ||||
|       event_type != CLUTTER_BUTTON_RELEASE) | ||||
|     return CLUTTER_EVENT_PROPAGATE; | ||||
|  | ||||
|   event_type = clutter_event_type (event); | ||||
|   if ((point = gesture_find_point (action, event, &position)) == NULL) | ||||
|     return CLUTTER_EVENT_PROPAGATE; | ||||
|  | ||||
|   if (event_type == CLUTTER_BUTTON_PRESS || | ||||
|       event_type == CLUTTER_TOUCH_BEGIN) | ||||
|     { | ||||
|       point = gesture_register_point (gesture_action, event); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       if ((point = gesture_find_point (gesture_action, event, &position)) == NULL) | ||||
|         return CLUTTER_EVENT_PROPAGATE; | ||||
|     } | ||||
|   actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action)); | ||||
|  | ||||
|   switch (clutter_event_type (event)) | ||||
|     { | ||||
|     case CLUTTER_BUTTON_PRESS: | ||||
|     case CLUTTER_TOUCH_BEGIN: | ||||
|       if (priv->stage == NULL) | ||||
|         priv->stage = clutter_actor_get_stage (actor); | ||||
|  | ||||
|       /* Start the gesture immediately if the gesture has no | ||||
|        * _TRIGGER_EDGE_AFTER drag threshold. */ | ||||
|       if ((priv->points->len >= priv->requested_nb_points) && | ||||
|           (priv->edge != CLUTTER_GESTURE_TRIGGER_EDGE_AFTER)) | ||||
|         begin_gesture (gesture_action, actor); | ||||
|  | ||||
|       break; | ||||
|     case CLUTTER_MOTION: | ||||
|       { | ||||
|         ClutterModifierType mods = clutter_event_get_state (event); | ||||
| @@ -404,7 +386,7 @@ clutter_gesture_action_handle_event (ClutterAction      *action, | ||||
|          */ | ||||
|         if (!(mods & CLUTTER_BUTTON1_MASK)) | ||||
|           { | ||||
|             cancel_gesture (gesture_action); | ||||
|             cancel_gesture (action); | ||||
|             return CLUTTER_EVENT_PROPAGATE; | ||||
|           } | ||||
|       } | ||||
| @@ -422,41 +404,41 @@ clutter_gesture_action_handle_event (ClutterAction      *action, | ||||
|           /* Wait until the drag threshold has been exceeded | ||||
|            * before starting _TRIGGER_EDGE_AFTER gestures. */ | ||||
|           if (priv->edge == CLUTTER_GESTURE_TRIGGER_EDGE_AFTER && | ||||
|               gesture_point_pass_threshold (gesture_action, point, event)) | ||||
|               gesture_point_pass_threshold (action, point, event)) | ||||
|             { | ||||
|               gesture_update_motion_point (point, event); | ||||
|               return CLUTTER_EVENT_PROPAGATE; | ||||
|             } | ||||
|  | ||||
|           gesture_update_motion_point (point, event); | ||||
|           if (!begin_gesture (action, actor)) | ||||
|             { | ||||
|               if ((point = gesture_find_point (action, event, &position)) != NULL) | ||||
|                 gesture_update_motion_point (point, event); | ||||
|               return CLUTTER_EVENT_PROPAGATE; | ||||
|             } | ||||
|  | ||||
|           if (!begin_gesture (gesture_action, actor)) | ||||
|             return CLUTTER_EVENT_PROPAGATE; | ||||
|  | ||||
|           if ((point = gesture_find_point (gesture_action, event, &position)) == NULL) | ||||
|           if ((point = gesture_find_point (action, event, &position)) == NULL) | ||||
|             return CLUTTER_EVENT_PROPAGATE; | ||||
|         } | ||||
|  | ||||
|       gesture_update_motion_point (point, event); | ||||
|  | ||||
|       g_signal_emit (gesture_action, gesture_signals[GESTURE_PROGRESS], 0, actor, | ||||
|       g_signal_emit (action, gesture_signals[GESTURE_PROGRESS], 0, actor, | ||||
|                      &return_value); | ||||
|       if (!return_value) | ||||
|         { | ||||
|           cancel_gesture (gesture_action); | ||||
|           cancel_gesture (action); | ||||
|           return CLUTTER_EVENT_PROPAGATE; | ||||
|         } | ||||
|  | ||||
|       /* Check if a _TRIGGER_EDGE_BEFORE gesture needs to be cancelled because | ||||
|        * the drag threshold has been exceeded. */ | ||||
|       clutter_gesture_action_get_threshold_trigger_distance (gesture_action, | ||||
|                                                              &threshold_x, | ||||
|                                                              &threshold_y); | ||||
|       clutter_gesture_action_get_threshold_trigger_distance (action, &threshold_x, &threshold_y); | ||||
|       if (priv->edge == CLUTTER_GESTURE_TRIGGER_EDGE_BEFORE && | ||||
|           ((fabsf (point->press_y - point->last_motion_y) > threshold_y) || | ||||
|            (fabsf (point->press_x - point->last_motion_x) > threshold_x))) | ||||
|         { | ||||
|           cancel_gesture (gesture_action); | ||||
|           cancel_gesture (action); | ||||
|           return CLUTTER_EVENT_PROPAGATE; | ||||
|         } | ||||
|       break; | ||||
| @@ -470,10 +452,10 @@ clutter_gesture_action_handle_event (ClutterAction      *action, | ||||
|             ((priv->points->len - 1) < priv->requested_nb_points)) | ||||
|           { | ||||
|             priv->in_gesture = FALSE; | ||||
|             g_signal_emit (gesture_action, gesture_signals[GESTURE_END], 0, actor); | ||||
|             g_signal_emit (action, gesture_signals[GESTURE_END], 0, actor); | ||||
|           } | ||||
|  | ||||
|         gesture_unregister_point (gesture_action, position); | ||||
|         gesture_unregister_point (action, position); | ||||
|       } | ||||
|       break; | ||||
|  | ||||
| @@ -484,10 +466,10 @@ clutter_gesture_action_handle_event (ClutterAction      *action, | ||||
|         if (priv->in_gesture) | ||||
|           { | ||||
|             priv->in_gesture = FALSE; | ||||
|             cancel_gesture (gesture_action); | ||||
|             cancel_gesture (action); | ||||
|           } | ||||
|  | ||||
|         gesture_unregister_point (gesture_action, position); | ||||
|         gesture_unregister_point (action, position); | ||||
|       } | ||||
|       break; | ||||
|  | ||||
| @@ -495,30 +477,83 @@ clutter_gesture_action_handle_event (ClutterAction      *action, | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|   return priv->in_gesture ? | ||||
|     CLUTTER_EVENT_STOP : | ||||
|     CLUTTER_EVENT_PROPAGATE; | ||||
|   if (priv->points->len == 0) | ||||
|     g_clear_signal_handler (&priv->stage_capture_id, priv->stage); | ||||
|  | ||||
|   return CLUTTER_EVENT_PROPAGATE; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| actor_captured_event_cb (ClutterActor *actor, | ||||
|                          ClutterEvent *event, | ||||
|                          ClutterGestureAction *action) | ||||
| { | ||||
|   ClutterGestureActionPrivate *priv = action->priv; | ||||
|   GesturePoint *point G_GNUC_UNUSED; | ||||
|  | ||||
|   if ((clutter_event_type (event) != CLUTTER_BUTTON_PRESS) && | ||||
|       (clutter_event_type (event) != CLUTTER_TOUCH_BEGIN)) | ||||
|     return CLUTTER_EVENT_PROPAGATE; | ||||
|  | ||||
|   if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (action))) | ||||
|     return CLUTTER_EVENT_PROPAGATE; | ||||
|  | ||||
|   point = gesture_register_point (action, event); | ||||
|  | ||||
|   if (priv->stage == NULL) | ||||
|     priv->stage = clutter_actor_get_stage (actor); | ||||
|  | ||||
|   if (priv->stage_capture_id == 0) | ||||
|     priv->stage_capture_id = | ||||
|       g_signal_connect_after (priv->stage, "captured-event", | ||||
|                               G_CALLBACK (stage_captured_event_cb), | ||||
|                               action); | ||||
|  | ||||
|   /* Start the gesture immediately if the gesture has no | ||||
|    * _TRIGGER_EDGE_AFTER drag threshold. */ | ||||
|   if ((priv->points->len >= priv->requested_nb_points) && | ||||
|       (priv->edge != CLUTTER_GESTURE_TRIGGER_EDGE_AFTER)) | ||||
|     begin_gesture (action, actor); | ||||
|  | ||||
|   return CLUTTER_EVENT_PROPAGATE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| clutter_gesture_action_set_enabled (ClutterActorMeta *meta, | ||||
|                                     gboolean          is_enabled) | ||||
| clutter_gesture_action_set_actor (ClutterActorMeta *meta, | ||||
|                                   ClutterActor     *actor) | ||||
| { | ||||
|   ClutterGestureActionPrivate *priv = CLUTTER_GESTURE_ACTION (meta)->priv; | ||||
|   ClutterActorMetaClass *meta_class = | ||||
|     CLUTTER_ACTOR_META_CLASS (clutter_gesture_action_parent_class); | ||||
|   ClutterGestureAction *gesture_action = CLUTTER_GESTURE_ACTION (meta); | ||||
|   ClutterGestureActionPrivate *priv = | ||||
|     clutter_gesture_action_get_instance_private (gesture_action); | ||||
|  | ||||
|   if (!is_enabled) | ||||
|   if (priv->actor_capture_id != 0) | ||||
|     { | ||||
|       if (priv->in_gesture) | ||||
|         cancel_gesture (gesture_action); | ||||
|       else | ||||
|         g_array_set_size (priv->points, 0); | ||||
|       ClutterActor *old_actor = clutter_actor_meta_get_actor (meta); | ||||
|  | ||||
|       if (old_actor != NULL) | ||||
|         g_clear_signal_handler (&priv->actor_capture_id, old_actor); | ||||
|  | ||||
|       priv->actor_capture_id = 0; | ||||
|     } | ||||
|  | ||||
|   meta_class->set_enabled (meta, is_enabled); | ||||
|   if (priv->stage_capture_id != 0) | ||||
|     { | ||||
|       if (priv->stage != NULL) | ||||
|         g_clear_signal_handler (&priv->stage_capture_id, priv->stage); | ||||
|  | ||||
|       priv->stage_capture_id = 0; | ||||
|       priv->stage = NULL; | ||||
|     } | ||||
|  | ||||
|   if (actor != NULL) | ||||
|     { | ||||
|       priv->actor_capture_id = | ||||
|         g_signal_connect (actor, "captured-event", | ||||
|                           G_CALLBACK (actor_captured_event_cb), | ||||
|                           meta); | ||||
|     } | ||||
|  | ||||
|   meta_class->set_actor (meta, actor); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| @@ -535,8 +570,6 @@ clutter_gesture_action_set_property (GObject      *gobject, | ||||
|                                      GParamSpec   *pspec) | ||||
| { | ||||
|   ClutterGestureAction *self = CLUTTER_GESTURE_ACTION (gobject); | ||||
|   ClutterGestureActionPrivate *priv = | ||||
|     clutter_gesture_action_get_instance_private (self); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
| @@ -549,15 +582,11 @@ clutter_gesture_action_set_property (GObject      *gobject, | ||||
|       break; | ||||
|  | ||||
|     case PROP_THRESHOLD_TRIGGER_DISTANCE_X: | ||||
|       clutter_gesture_action_set_threshold_trigger_distance (self, | ||||
|                                                              g_value_get_float (value), | ||||
|                                                              priv->distance_y); | ||||
|       clutter_gesture_action_set_threshold_trigger_distance (self, g_value_get_float (value), self->priv->distance_y); | ||||
|       break; | ||||
|  | ||||
|     case PROP_THRESHOLD_TRIGGER_DISTANCE_Y: | ||||
|       clutter_gesture_action_set_threshold_trigger_distance (self, | ||||
|                                                              priv->distance_x, | ||||
|                                                              g_value_get_float (value)); | ||||
|       clutter_gesture_action_set_threshold_trigger_distance (self, self->priv->distance_x, g_value_get_float (value)); | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
| @@ -572,29 +601,28 @@ clutter_gesture_action_get_property (GObject    *gobject, | ||||
|                                      GValue     *value, | ||||
|                                      GParamSpec *pspec) | ||||
| { | ||||
|   ClutterGestureActionPrivate *priv = | ||||
|     clutter_gesture_action_get_instance_private (CLUTTER_GESTURE_ACTION (gobject)); | ||||
|   ClutterGestureAction *self = CLUTTER_GESTURE_ACTION (gobject); | ||||
|  | ||||
|   switch (prop_id) | ||||
|     { | ||||
|     case PROP_N_TOUCH_POINTS: | ||||
|       g_value_set_int (value, priv->requested_nb_points); | ||||
|       g_value_set_int (value, self->priv->requested_nb_points); | ||||
|       break; | ||||
|  | ||||
|     case PROP_THRESHOLD_TRIGGER_EDGE: | ||||
|       g_value_set_enum (value, priv->edge); | ||||
|       g_value_set_enum (value, self->priv->edge); | ||||
|       break; | ||||
|  | ||||
|     case PROP_THRESHOLD_TRIGGER_DISTANCE_X: | ||||
|       if (priv->distance_x > 0.0) | ||||
|         g_value_set_float (value, priv->distance_x); | ||||
|       if (self->priv->distance_x > 0.0) | ||||
|         g_value_set_float (value, self->priv->distance_x); | ||||
|       else | ||||
|         g_value_set_float (value, gesture_get_default_threshold ()); | ||||
|       break; | ||||
|  | ||||
|     case PROP_THRESHOLD_TRIGGER_DISTANCE_Y: | ||||
|       if (priv->distance_y > 0.0) | ||||
|         g_value_set_float (value, priv->distance_y); | ||||
|       if (self->priv->distance_y > 0.0) | ||||
|         g_value_set_float (value, self->priv->distance_y); | ||||
|       else | ||||
|         g_value_set_float (value, gesture_get_default_threshold ()); | ||||
|       break; | ||||
| @@ -608,8 +636,7 @@ clutter_gesture_action_get_property (GObject    *gobject, | ||||
| static void | ||||
| clutter_gesture_action_finalize (GObject *gobject) | ||||
| { | ||||
|   ClutterGestureActionPrivate *priv = | ||||
|     clutter_gesture_action_get_instance_private (CLUTTER_GESTURE_ACTION (gobject)); | ||||
|   ClutterGestureActionPrivate *priv = CLUTTER_GESTURE_ACTION (gobject)->priv; | ||||
|  | ||||
|   g_array_unref (priv->points); | ||||
|  | ||||
| @@ -621,15 +648,12 @@ clutter_gesture_action_class_init (ClutterGestureActionClass *klass) | ||||
| { | ||||
|   GObjectClass *gobject_class = G_OBJECT_CLASS (klass); | ||||
|   ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass); | ||||
|   ClutterActionClass *action_class = CLUTTER_ACTION_CLASS (klass); | ||||
|  | ||||
|   gobject_class->finalize = clutter_gesture_action_finalize; | ||||
|   gobject_class->set_property = clutter_gesture_action_set_property; | ||||
|   gobject_class->get_property = clutter_gesture_action_get_property; | ||||
|  | ||||
|   meta_class->set_enabled = clutter_gesture_action_set_enabled; | ||||
|  | ||||
|   action_class->handle_event = clutter_gesture_action_handle_event; | ||||
|   meta_class->set_actor = clutter_gesture_action_set_actor; | ||||
|  | ||||
|   klass->gesture_begin = default_event_handler; | ||||
|   klass->gesture_progress = default_event_handler; | ||||
| @@ -803,14 +827,13 @@ clutter_gesture_action_class_init (ClutterGestureActionClass *klass) | ||||
| static void | ||||
| clutter_gesture_action_init (ClutterGestureAction *self) | ||||
| { | ||||
|   ClutterGestureActionPrivate *priv = | ||||
|     clutter_gesture_action_get_instance_private (self); | ||||
|   self->priv = clutter_gesture_action_get_instance_private (self); | ||||
|  | ||||
|   priv->points = g_array_sized_new (FALSE, TRUE, sizeof (GesturePoint), 3); | ||||
|   g_array_set_clear_func (priv->points, (GDestroyNotify) gesture_point_unset); | ||||
|   self->priv->points = g_array_sized_new (FALSE, TRUE, sizeof (GesturePoint), 3); | ||||
|   g_array_set_clear_func (self->priv->points, (GDestroyNotify) gesture_point_unset); | ||||
|  | ||||
|   priv->requested_nb_points = 1; | ||||
|   priv->edge = CLUTTER_GESTURE_TRIGGER_EDGE_NONE; | ||||
|   self->priv->requested_nb_points = 1; | ||||
|   self->priv->edge = CLUTTER_GESTURE_TRIGGER_EDGE_NONE; | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -849,21 +872,16 @@ clutter_gesture_action_get_press_coords (ClutterGestureAction *action, | ||||
|                                          gfloat               *press_x, | ||||
|                                          gfloat               *press_y) | ||||
| { | ||||
|   ClutterGestureActionPrivate *priv; | ||||
|  | ||||
|   g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action)); | ||||
|  | ||||
|   priv = clutter_gesture_action_get_instance_private (action); | ||||
|  | ||||
|   g_return_if_fail (priv->points->len > point); | ||||
|   g_return_if_fail (action->priv->points->len > point); | ||||
|  | ||||
|   if (press_x) | ||||
|     *press_x = g_array_index (priv->points, | ||||
|     *press_x = g_array_index (action->priv->points, | ||||
|                               GesturePoint, | ||||
|                               point).press_x; | ||||
|  | ||||
|   if (press_y) | ||||
|     *press_y = g_array_index (priv->points, | ||||
|     *press_y = g_array_index (action->priv->points, | ||||
|                               GesturePoint, | ||||
|                               point).press_y; | ||||
| } | ||||
| @@ -889,21 +907,16 @@ clutter_gesture_action_get_motion_coords (ClutterGestureAction *action, | ||||
|                                           gfloat               *motion_x, | ||||
|                                           gfloat               *motion_y) | ||||
| { | ||||
|   ClutterGestureActionPrivate *priv; | ||||
|  | ||||
|   g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action)); | ||||
|  | ||||
|   priv = clutter_gesture_action_get_instance_private (action); | ||||
|  | ||||
|   g_return_if_fail (priv->points->len > point); | ||||
|   g_return_if_fail (action->priv->points->len > point); | ||||
|  | ||||
|   if (motion_x) | ||||
|     *motion_x = g_array_index (priv->points, | ||||
|     *motion_x = g_array_index (action->priv->points, | ||||
|                                GesturePoint, | ||||
|                                point).last_motion_x; | ||||
|  | ||||
|   if (motion_y) | ||||
|     *motion_y = g_array_index (priv->points, | ||||
|     *motion_y = g_array_index (action->priv->points, | ||||
|                                GesturePoint, | ||||
|                                point).last_motion_y; | ||||
| } | ||||
| @@ -931,19 +944,15 @@ clutter_gesture_action_get_motion_delta (ClutterGestureAction *action, | ||||
|                                          gfloat               *delta_x, | ||||
|                                          gfloat               *delta_y) | ||||
| { | ||||
|   ClutterGestureActionPrivate *priv; | ||||
|   gfloat d_x, d_y; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), 0); | ||||
|   g_return_val_if_fail (action->priv->points->len > point, 0); | ||||
|  | ||||
|   priv = clutter_gesture_action_get_instance_private (action); | ||||
|  | ||||
|   g_return_val_if_fail (priv->points->len > point, 0); | ||||
|  | ||||
|   d_x = g_array_index (priv->points, | ||||
|   d_x = g_array_index (action->priv->points, | ||||
|                        GesturePoint, | ||||
|                        point).last_delta_x; | ||||
|   d_y = g_array_index (priv->points, | ||||
|   d_y = g_array_index (action->priv->points, | ||||
|                        GesturePoint, | ||||
|                        point).last_delta_y; | ||||
|  | ||||
| @@ -977,21 +986,16 @@ clutter_gesture_action_get_release_coords (ClutterGestureAction *action, | ||||
|                                            gfloat               *release_x, | ||||
|                                            gfloat               *release_y) | ||||
| { | ||||
|   ClutterGestureActionPrivate *priv; | ||||
|  | ||||
|   g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action)); | ||||
|  | ||||
|   priv = clutter_gesture_action_get_instance_private (action); | ||||
|  | ||||
|   g_return_if_fail (priv->points->len > point); | ||||
|   g_return_if_fail (action->priv->points->len > point); | ||||
|  | ||||
|   if (release_x) | ||||
|     *release_x = g_array_index (priv->points, | ||||
|     *release_x = g_array_index (action->priv->points, | ||||
|                                 GesturePoint, | ||||
|                                 point).release_x; | ||||
|  | ||||
|   if (release_y) | ||||
|     *release_y = g_array_index (priv->points, | ||||
|     *release_y = g_array_index (action->priv->points, | ||||
|                                 GesturePoint, | ||||
|                                 point).release_y; | ||||
| } | ||||
| @@ -1017,20 +1021,16 @@ clutter_gesture_action_get_velocity (ClutterGestureAction *action, | ||||
|                                      gfloat               *velocity_x, | ||||
|                                      gfloat               *velocity_y) | ||||
| { | ||||
|   ClutterGestureActionPrivate *priv; | ||||
|   gfloat d_x, d_y, distance, velocity; | ||||
|   gint64 d_t; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), 0); | ||||
|  | ||||
|   priv = clutter_gesture_action_get_instance_private (action); | ||||
|  | ||||
|   g_return_val_if_fail (priv->points->len > point, 0); | ||||
|   g_return_val_if_fail (action->priv->points->len > point, 0); | ||||
|  | ||||
|   distance = clutter_gesture_action_get_motion_delta (action, point, | ||||
|                                                       &d_x, &d_y); | ||||
|  | ||||
|   d_t = g_array_index (priv->points, | ||||
|   d_t = g_array_index (action->priv->points, | ||||
|                        GesturePoint, | ||||
|                        point).last_delta_time; | ||||
|  | ||||
| @@ -1057,13 +1057,9 @@ clutter_gesture_action_get_velocity (ClutterGestureAction *action, | ||||
| gint | ||||
| clutter_gesture_action_get_n_touch_points (ClutterGestureAction *action) | ||||
| { | ||||
|   ClutterGestureActionPrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), 0); | ||||
|  | ||||
|   priv = clutter_gesture_action_get_instance_private (action); | ||||
|  | ||||
|   return priv->requested_nb_points; | ||||
|   return action->priv->requested_nb_points; | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -1084,7 +1080,7 @@ clutter_gesture_action_set_n_touch_points (ClutterGestureAction *action, | ||||
|   g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action)); | ||||
|   g_return_if_fail (nb_points >= 1); | ||||
|  | ||||
|   priv = clutter_gesture_action_get_instance_private (action); | ||||
|   priv = action->priv; | ||||
|  | ||||
|   if (priv->requested_nb_points == nb_points) | ||||
|     return; | ||||
| @@ -1138,13 +1134,9 @@ clutter_gesture_action_set_n_touch_points (ClutterGestureAction *action, | ||||
| guint | ||||
| clutter_gesture_action_get_n_current_points (ClutterGestureAction *action) | ||||
| { | ||||
|   ClutterGestureActionPrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), 0); | ||||
|  | ||||
|   priv = clutter_gesture_action_get_instance_private (action); | ||||
|  | ||||
|   return priv->points->len; | ||||
|   return action->priv->points->len; | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -1162,15 +1154,10 @@ ClutterEventSequence * | ||||
| clutter_gesture_action_get_sequence (ClutterGestureAction *action, | ||||
|                                      guint                 point) | ||||
| { | ||||
|   ClutterGestureActionPrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), NULL); | ||||
|   g_return_val_if_fail (action->priv->points->len > point, NULL); | ||||
|  | ||||
|   priv = clutter_gesture_action_get_instance_private (action); | ||||
|  | ||||
|   g_return_val_if_fail (priv->points->len > point, NULL); | ||||
|  | ||||
|   return g_array_index (priv->points, GesturePoint, point).sequence; | ||||
|   return g_array_index (action->priv->points, GesturePoint, point).sequence; | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -1189,15 +1176,10 @@ ClutterInputDevice * | ||||
| clutter_gesture_action_get_device (ClutterGestureAction *action, | ||||
|                                    guint                 point) | ||||
| { | ||||
|   ClutterGestureActionPrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), NULL); | ||||
|   g_return_val_if_fail (action->priv->points->len > point, NULL); | ||||
|  | ||||
|   priv = clutter_gesture_action_get_instance_private (action); | ||||
|  | ||||
|   g_return_val_if_fail (priv->points->len > point, NULL); | ||||
|  | ||||
|   return g_array_index (priv->points, GesturePoint, point).device; | ||||
|   return g_array_index (action->priv->points, GesturePoint, point).device; | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -1217,15 +1199,11 @@ clutter_gesture_action_get_last_event (ClutterGestureAction *action, | ||||
|                                        guint                 point) | ||||
| { | ||||
|   GesturePoint *gesture_point; | ||||
|   ClutterGestureActionPrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), NULL); | ||||
|   g_return_val_if_fail (action->priv->points->len > point, NULL); | ||||
|  | ||||
|   priv = clutter_gesture_action_get_instance_private (action); | ||||
|  | ||||
|   g_return_val_if_fail (priv->points->len > point, NULL); | ||||
|  | ||||
|   gesture_point = &g_array_index (priv->points, GesturePoint, point); | ||||
|   gesture_point = &g_array_index (action->priv->points, GesturePoint, point); | ||||
|  | ||||
|   return gesture_point->last_event; | ||||
| } | ||||
| @@ -1262,16 +1240,12 @@ void | ||||
| clutter_gesture_action_set_threshold_trigger_edge (ClutterGestureAction      *action, | ||||
|                                                    ClutterGestureTriggerEdge  edge) | ||||
| { | ||||
|   ClutterGestureActionPrivate *priv; | ||||
|  | ||||
|   g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action)); | ||||
|  | ||||
|   priv = clutter_gesture_action_get_instance_private (action); | ||||
|  | ||||
|   if (priv->edge == edge) | ||||
|   if (action->priv->edge == edge) | ||||
|     return; | ||||
|  | ||||
|   priv->edge = edge; | ||||
|   action->priv->edge = edge; | ||||
|  | ||||
|   g_object_notify_by_pspec (G_OBJECT (action), gesture_props[PROP_THRESHOLD_TRIGGER_EDGE]); | ||||
| } | ||||
| @@ -1290,14 +1264,10 @@ clutter_gesture_action_set_threshold_trigger_edge (ClutterGestureAction      *ac | ||||
| ClutterGestureTriggerEdge | ||||
| clutter_gesture_action_get_threshold_trigger_edge (ClutterGestureAction *action) | ||||
| { | ||||
|   ClutterGestureActionPrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), | ||||
|                         CLUTTER_GESTURE_TRIGGER_EDGE_NONE); | ||||
|  | ||||
|   priv = clutter_gesture_action_get_instance_private (action); | ||||
|  | ||||
|   return priv->edge; | ||||
|   return action->priv->edge; | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -1337,21 +1307,17 @@ clutter_gesture_action_set_threshold_trigger_distance (ClutterGestureAction | ||||
|                                                        float                      x, | ||||
|                                                        float                      y) | ||||
| { | ||||
|   ClutterGestureActionPrivate *priv; | ||||
|  | ||||
|   g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action)); | ||||
|  | ||||
|   priv = clutter_gesture_action_get_instance_private (action); | ||||
|  | ||||
|   if (fabsf (x - priv->distance_x) > FLOAT_EPSILON) | ||||
|   if (fabsf (x - action->priv->distance_x) > FLOAT_EPSILON) | ||||
|     { | ||||
|       priv->distance_x = x; | ||||
|       action->priv->distance_x = x; | ||||
|       g_object_notify_by_pspec (G_OBJECT (action), gesture_props[PROP_THRESHOLD_TRIGGER_DISTANCE_X]); | ||||
|     } | ||||
|  | ||||
|   if (fabsf (y - priv->distance_y) > FLOAT_EPSILON) | ||||
|   if (fabsf (y - action->priv->distance_y) > FLOAT_EPSILON) | ||||
|     { | ||||
|       priv->distance_y = y; | ||||
|       action->priv->distance_y = y; | ||||
|       g_object_notify_by_pspec (G_OBJECT (action), gesture_props[PROP_THRESHOLD_TRIGGER_DISTANCE_Y]); | ||||
|     } | ||||
| } | ||||
| @@ -1372,23 +1338,19 @@ clutter_gesture_action_get_threshold_trigger_distance (ClutterGestureAction *act | ||||
|                                                        float                *x, | ||||
|                                                        float                *y) | ||||
| { | ||||
|   ClutterGestureActionPrivate *priv; | ||||
|  | ||||
|   g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action)); | ||||
|  | ||||
|   priv = clutter_gesture_action_get_instance_private (action); | ||||
|  | ||||
|   if (x != NULL) | ||||
|     { | ||||
|       if (priv->distance_x > 0.0) | ||||
|         *x = priv->distance_x; | ||||
|       if (action->priv->distance_x > 0.0) | ||||
|         *x = action->priv->distance_x; | ||||
|       else | ||||
|         *x = gesture_get_default_threshold (); | ||||
|     } | ||||
|   if (y != NULL) | ||||
|     { | ||||
|       if (priv->distance_y > 0.0) | ||||
|         *y = priv->distance_y; | ||||
|       if (action->priv->distance_y > 0.0) | ||||
|         *y = action->priv->distance_y; | ||||
|       else | ||||
|         *y = gesture_get_default_threshold (); | ||||
|     } | ||||
|   | ||||
| @@ -34,13 +34,32 @@ | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CLUTTER_TYPE_GESTURE_ACTION (clutter_gesture_action_get_type ()) | ||||
| #define CLUTTER_TYPE_GESTURE_ACTION               (clutter_gesture_action_get_type ()) | ||||
| #define CLUTTER_GESTURE_ACTION(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_GESTURE_ACTION, ClutterGestureAction)) | ||||
| #define CLUTTER_IS_GESTURE_ACTION(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_GESTURE_ACTION)) | ||||
| #define CLUTTER_GESTURE_ACTION_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_GESTURE_ACTION, ClutterGestureActionClass)) | ||||
| #define CLUTTER_IS_GESTURE_ACTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_GESTURE_ACTION)) | ||||
| #define CLUTTER_GESTURE_ACTION_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_GESTURE_ACTION, ClutterGestureActionClass)) | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| G_DECLARE_DERIVABLE_TYPE (ClutterGestureAction, clutter_gesture_action, | ||||
|                           CLUTTER, GESTURE_ACTION, ClutterAction); | ||||
| typedef struct _ClutterGestureAction              ClutterGestureAction; | ||||
| typedef struct _ClutterGestureActionPrivate       ClutterGestureActionPrivate; | ||||
| typedef struct _ClutterGestureActionClass         ClutterGestureActionClass; | ||||
|  | ||||
| typedef struct _ClutterGestureActionPrivate ClutterGestureActionPrivate; | ||||
| /** | ||||
|  * ClutterGestureAction: | ||||
|  * | ||||
|  * The #ClutterGestureAction structure contains | ||||
|  * only private data and should be accessed using the provided API | ||||
|  * | ||||
|  * Since: 1.8 | ||||
|  */ | ||||
| struct _ClutterGestureAction | ||||
| { | ||||
|   /*< private >*/ | ||||
|   ClutterAction parent_instance; | ||||
|  | ||||
|   ClutterGestureActionPrivate *priv; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * ClutterGestureActionClass: | ||||
| @@ -82,6 +101,9 @@ struct _ClutterGestureActionClass | ||||
|   void (* _clutter_gesture_action6) (void); | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| GType clutter_gesture_action_get_type (void) G_GNUC_CONST; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterAction *        clutter_gesture_action_new                      (void); | ||||
|  | ||||
|   | ||||
| @@ -29,23 +29,6 @@ | ||||
| #include "clutter-private.h" | ||||
| #include "clutter-types.h" | ||||
|  | ||||
| static gboolean | ||||
| graphene_matrix_progress (const GValue *a, | ||||
|                           const GValue *b, | ||||
|                           double        progress, | ||||
|                           GValue       *retval) | ||||
| { | ||||
|   const graphene_matrix_t *am = g_value_get_boxed (a); | ||||
|   const graphene_matrix_t *bm = g_value_get_boxed (b); | ||||
|   graphene_matrix_t res; | ||||
|  | ||||
|   graphene_matrix_interpolate (am, bm, progress, &res); | ||||
|  | ||||
|   g_value_set_boxed (retval, &res); | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| graphene_point_progress (const GValue *a, | ||||
|                          const GValue *b, | ||||
| @@ -117,8 +100,6 @@ graphene_size_progress (const GValue *a, | ||||
| void | ||||
| clutter_graphene_init (void) | ||||
| { | ||||
|   clutter_interval_register_progress_func (GRAPHENE_TYPE_MATRIX, | ||||
|                                            graphene_matrix_progress); | ||||
|   clutter_interval_register_progress_func (GRAPHENE_TYPE_POINT, | ||||
|                                            graphene_point_progress); | ||||
|   clutter_interval_register_progress_func (GRAPHENE_TYPE_POINT3D, | ||||
|   | ||||
| @@ -1391,7 +1391,8 @@ allocate_child (ClutterGridRequest *request, | ||||
| static void | ||||
| clutter_grid_layout_allocate (ClutterLayoutManager   *layout, | ||||
|                               ClutterContainer       *container, | ||||
|                               const ClutterActorBox  *allocation) | ||||
|                               const ClutterActorBox  *allocation, | ||||
|                               ClutterAllocationFlags  flags) | ||||
| { | ||||
|   ClutterGridLayout *self = CLUTTER_GRID_LAYOUT (layout); | ||||
|   ClutterOrientation orientation; | ||||
| @@ -1452,7 +1453,7 @@ clutter_grid_layout_allocate (ClutterLayoutManager   *layout, | ||||
|       child_allocation.x2 = child_allocation.x1 + width; | ||||
|       child_allocation.y2 = child_allocation.y1 + height; | ||||
|  | ||||
|       clutter_actor_allocate (child, &child_allocation); | ||||
|       clutter_actor_allocate (child, &child_allocation, flags); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										96
									
								
								clutter/clutter/clutter-group.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								clutter/clutter/clutter-group.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | ||||
| /* | ||||
|  * 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/>. | ||||
|  */ | ||||
|  | ||||
| #ifndef __CLUTTER_GROUP_H__ | ||||
| #define __CLUTTER_GROUP_H__ | ||||
|  | ||||
| #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-types.h> | ||||
| #include <clutter/clutter-actor.h> | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| #define CLUTTER_TYPE_GROUP              (clutter_group_get_type ()) | ||||
| #define CLUTTER_GROUP(obj)              (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_GROUP, ClutterGroup)) | ||||
| #define CLUTTER_GROUP_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_GROUP, ClutterGroupClass)) | ||||
| #define CLUTTER_IS_GROUP(obj)           (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_GROUP)) | ||||
| #define CLUTTER_IS_GROUP_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_GROUP)) | ||||
| #define CLUTTER_GROUP_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_GROUP, ClutterGroupClass)) | ||||
|  | ||||
| /* XXX - ClutterGroup is to be considered fully deprecated; the only | ||||
|  * reason we keep this header is because ClutterStage inherits from | ||||
|  * ClutterGroup, and thus we need to have a structure definition for | ||||
|  * the Stage object to expand. | ||||
|  */ | ||||
|  | ||||
| typedef struct _ClutterGroup            ClutterGroup; | ||||
| typedef struct _ClutterGroupClass       ClutterGroupClass; | ||||
| typedef struct _ClutterGroupPrivate     ClutterGroupPrivate; | ||||
|  | ||||
| /** | ||||
|  * ClutterGroup: | ||||
|  * | ||||
|  * The #ClutterGroup structure contains only private data | ||||
|  * and should be accessed using the provided API | ||||
|  * | ||||
|  * Since: 0.2 | ||||
|  */ | ||||
| struct _ClutterGroup | ||||
| { | ||||
|   /*< private >*/ | ||||
|   ClutterActor parent_instance; | ||||
|  | ||||
|   ClutterGroupPrivate *priv; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * ClutterGroupClass: | ||||
|  * | ||||
|  * The #ClutterGroupClass structure contains only private data | ||||
|  * | ||||
|  * Since: 0.2 | ||||
|  */ | ||||
| struct _ClutterGroupClass | ||||
| { | ||||
|   /*< private >*/ | ||||
|   ClutterActorClass parent_class; | ||||
|  | ||||
|   /* padding for future expansion */ | ||||
|   void (*_clutter_reserved1) (void); | ||||
|   void (*_clutter_reserved2) (void); | ||||
|   void (*_clutter_reserved3) (void); | ||||
|   void (*_clutter_reserved4) (void); | ||||
|   void (*_clutter_reserved5) (void); | ||||
|   void (*_clutter_reserved6) (void); | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| GType clutter_group_get_type (void) G_GNUC_CONST; | ||||
|  | ||||
| G_END_DECLS | ||||
|  | ||||
| #endif /* __CLUTTER_GROUP_H__ */ | ||||
| @@ -44,7 +44,7 @@ _clutter_id_pool_new  (guint initial_size) | ||||
| { | ||||
|   ClutterIDPool *self; | ||||
|  | ||||
|   self = g_new0 (ClutterIDPool, 1); | ||||
|   self = g_slice_new (ClutterIDPool); | ||||
|  | ||||
|   self->array = g_array_sized_new (FALSE, FALSE,  | ||||
|                                    sizeof (gpointer), initial_size); | ||||
| @@ -59,7 +59,7 @@ _clutter_id_pool_free (ClutterIDPool *id_pool) | ||||
|  | ||||
|   g_array_free (id_pool->array, TRUE); | ||||
|   g_slist_free (id_pool->free_ids); | ||||
|   g_free (id_pool); | ||||
|   g_slice_free (ClutterIDPool, id_pool); | ||||
| } | ||||
|  | ||||
| guint32 | ||||
|   | ||||
| @@ -38,6 +38,8 @@ | ||||
|  | ||||
| #include "clutter-build-config.h" | ||||
|  | ||||
| #define CLUTTER_ENABLE_EXPERIMENTAL_API | ||||
|  | ||||
| #include "clutter-image.h" | ||||
|  | ||||
| #include "clutter-actor-private.h" | ||||
|   | ||||
| @@ -32,6 +32,44 @@ | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| typedef struct _ClutterAxisInfo | ||||
| { | ||||
|   ClutterInputAxis axis; | ||||
|  | ||||
|   double min_axis; | ||||
|   double max_axis; | ||||
|  | ||||
|   double min_value; | ||||
|   double max_value; | ||||
|  | ||||
|   double resolution; | ||||
| } ClutterAxisInfo; | ||||
|  | ||||
| typedef struct _ClutterKeyInfo | ||||
| { | ||||
|   guint keyval; | ||||
|   ClutterModifierType modifiers; | ||||
| } ClutterKeyInfo; | ||||
|  | ||||
| typedef struct _ClutterScrollInfo | ||||
| { | ||||
|   guint axis_id; | ||||
|   ClutterScrollDirection direction; | ||||
|   double increment; | ||||
|  | ||||
|   double last_value; | ||||
|   guint last_value_valid : 1; | ||||
| } ClutterScrollInfo; | ||||
|  | ||||
| typedef struct _ClutterTouchInfo | ||||
| { | ||||
|   ClutterEventSequence *sequence; | ||||
|   ClutterActor *actor; | ||||
|  | ||||
|   float current_x; | ||||
|   float current_y; | ||||
| } ClutterTouchInfo; | ||||
|  | ||||
| typedef struct _ClutterPtrA11yData | ||||
| { | ||||
|   int n_btn_pressed; | ||||
| @@ -53,15 +91,165 @@ struct _ClutterInputDevice | ||||
| { | ||||
|   GObject parent_instance; | ||||
|  | ||||
|   int id; | ||||
|  | ||||
|   ClutterInputDeviceType device_type; | ||||
|   ClutterInputMode device_mode; | ||||
|  | ||||
|   char *device_name; | ||||
|  | ||||
|   ClutterSeat *seat; | ||||
|  | ||||
|   ClutterBackend *backend; | ||||
|  | ||||
|   /* the associated device */ | ||||
|   ClutterInputDevice *associated; | ||||
|  | ||||
|   GList *slaves; | ||||
|  | ||||
|   /* the actor underneath the pointer */ | ||||
|   ClutterActor *cursor_actor; | ||||
|   GHashTable   *inv_touch_sequence_actors; | ||||
|  | ||||
|   /* the actor that has a grab in place for the device */ | ||||
|   ClutterActor *pointer_grab_actor; | ||||
|   ClutterActor *keyboard_grab_actor; | ||||
|   GHashTable   *sequence_grab_actors; | ||||
|   GHashTable   *inv_sequence_grab_actors; | ||||
|  | ||||
|   /* the current click count */ | ||||
|   int click_count; | ||||
|  | ||||
|   /* the stage the device is on */ | ||||
|   ClutterStage *stage; | ||||
|  | ||||
|   /* the current state */ | ||||
|   float current_x; | ||||
|   float current_y; | ||||
|   uint32_t current_time; | ||||
|   int current_button_number; | ||||
|   ClutterModifierType current_state; | ||||
|  | ||||
|   /* the current touch points states */ | ||||
|   GHashTable *touch_sequences_info; | ||||
|  | ||||
|   /* the previous state, used for click count generation */ | ||||
|   int previous_x; | ||||
|   int previous_y; | ||||
|   uint32_t previous_time; | ||||
|   int previous_button_number; | ||||
|   ClutterModifierType previous_state; | ||||
|  | ||||
|   GArray *axes; | ||||
|  | ||||
|   guint n_keys; | ||||
|   GArray *keys; | ||||
|  | ||||
|   GArray *scroll_info; | ||||
|  | ||||
|   char *vendor_id; | ||||
|   char *product_id; | ||||
|   char *node_path; | ||||
|  | ||||
|   GPtrArray *tools; | ||||
|  | ||||
|   int n_rings; | ||||
|   int n_strips; | ||||
|   int n_mode_groups; | ||||
|  | ||||
|   ClutterInputDeviceMapping mapping_mode; | ||||
|  | ||||
|   guint has_cursor : 1; | ||||
|   guint is_enabled : 1; | ||||
|  | ||||
|   /* Accessiblity */ | ||||
|   ClutterVirtualInputDevice *accessibility_virtual_device; | ||||
|   ClutterPtrA11yData *ptr_a11y_data; | ||||
| }; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void _clutter_input_device_set_associated_device (ClutterInputDevice *device, | ||||
|                                                   ClutterInputDevice *associated); | ||||
| CLUTTER_EXPORT | ||||
| void _clutter_input_device_add_slave (ClutterInputDevice *master, | ||||
|                                       ClutterInputDevice *slave); | ||||
| CLUTTER_EXPORT | ||||
| void _clutter_input_device_remove_slave (ClutterInputDevice *master, | ||||
|                                          ClutterInputDevice *slave); | ||||
| CLUTTER_EXPORT | ||||
| void clutter_input_device_update_from_tool (ClutterInputDevice     *device, | ||||
|                                             ClutterInputDeviceTool *tool); | ||||
| CLUTTER_EXPORT | ||||
| ClutterStage * _clutter_input_device_get_stage (ClutterInputDevice *device); | ||||
| CLUTTER_EXPORT | ||||
| void _clutter_input_device_set_stage (ClutterInputDevice *device, | ||||
|                                       ClutterStage       *stage); | ||||
| CLUTTER_EXPORT | ||||
| void _clutter_input_device_set_coords (ClutterInputDevice   *device, | ||||
|                                        ClutterEventSequence *sequence, | ||||
|                                        gfloat                x, | ||||
|                                        gfloat                y, | ||||
|                                        ClutterStage         *stage); | ||||
| CLUTTER_EXPORT | ||||
| void _clutter_input_device_set_state (ClutterInputDevice  *device, | ||||
|                                       ClutterModifierType  state); | ||||
| CLUTTER_EXPORT | ||||
| void _clutter_input_device_set_time (ClutterInputDevice *device, | ||||
|                                      guint32             time_); | ||||
| void _clutter_input_device_set_actor (ClutterInputDevice   *device, | ||||
|                                       ClutterEventSequence *sequence, | ||||
|                                       ClutterActor         *actor, | ||||
|                                       gboolean              emit_crossing); | ||||
| CLUTTER_EXPORT | ||||
| ClutterActor * clutter_input_device_update (ClutterInputDevice   *device, | ||||
| 					    ClutterEventSequence *sequence, | ||||
| 					    gboolean              emit_crossing); | ||||
| CLUTTER_EXPORT | ||||
| void _clutter_input_device_add_event_sequence (ClutterInputDevice *device, | ||||
|                                                ClutterEvent       *event); | ||||
| CLUTTER_EXPORT | ||||
| void _clutter_input_device_remove_event_sequence (ClutterInputDevice *device, | ||||
|                                                   ClutterEvent       *event); | ||||
| CLUTTER_EXPORT | ||||
| void _clutter_input_device_set_n_keys (ClutterInputDevice *device, | ||||
|                                        guint               n_keys); | ||||
| CLUTTER_EXPORT | ||||
| gboolean _clutter_input_device_translate_axis (ClutterInputDevice *device, | ||||
|                                                guint               index_, | ||||
|                                                gdouble             value, | ||||
|                                                gdouble            *axis_value); | ||||
| CLUTTER_EXPORT | ||||
| guint _clutter_input_device_add_axis (ClutterInputDevice *device, | ||||
|                                       ClutterInputAxis    axis, | ||||
|                                       gdouble             minimum, | ||||
|                                       gdouble             maximum, | ||||
|                                       gdouble             resolution); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void _clutter_input_device_reset_axes (ClutterInputDevice *device); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void _clutter_input_device_add_scroll_info (ClutterInputDevice     *device, | ||||
|                                             guint                   index_, | ||||
|                                             ClutterScrollDirection  direction, | ||||
|                                             gdouble                 increment); | ||||
| CLUTTER_EXPORT | ||||
| gboolean _clutter_input_device_get_scroll_delta (ClutterInputDevice     *device, | ||||
|                                                  guint                   index_, | ||||
|                                                  gdouble                 value, | ||||
|                                                  ClutterScrollDirection *direction_p, | ||||
|                                                  gdouble                *delta_p); | ||||
| CLUTTER_EXPORT | ||||
| void _clutter_input_device_reset_scroll_info (ClutterInputDevice *device); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void clutter_input_device_add_tool (ClutterInputDevice     *device, | ||||
|                                     ClutterInputDeviceTool *tool); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterInputDeviceTool * | ||||
|    clutter_input_device_lookup_tool (ClutterInputDevice         *device, | ||||
|                                      guint64                     serial, | ||||
|                                      ClutterInputDeviceToolType  type); | ||||
|  | ||||
| #endif /* CLUTTER_INPUT_DEVICE_PRIVATE_H */ | ||||
|   | ||||
| @@ -33,7 +33,6 @@ struct _ClutterInputDeviceToolPrivate | ||||
|   ClutterInputDeviceToolType type; | ||||
|   guint64 serial; | ||||
|   guint64 id; | ||||
|   ClutterInputAxisFlags axes; | ||||
| }; | ||||
|  | ||||
| enum | ||||
| @@ -42,7 +41,6 @@ enum | ||||
|   PROP_TYPE, | ||||
|   PROP_SERIAL, | ||||
|   PROP_ID, | ||||
|   PROP_AXES, | ||||
|   PROP_LAST | ||||
| }; | ||||
|  | ||||
| @@ -72,9 +70,6 @@ clutter_input_device_tool_set_property (GObject      *object, | ||||
|     case PROP_ID: | ||||
|       priv->id = g_value_get_uint64 (value); | ||||
|       break; | ||||
|     case PROP_AXES: | ||||
|       priv->axes = g_value_get_flags (value); | ||||
|       break; | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||||
|     } | ||||
| @@ -102,9 +97,6 @@ clutter_input_device_tool_get_property (GObject    *object, | ||||
|     case PROP_ID: | ||||
|       g_value_set_uint64 (value, priv->id); | ||||
|       break; | ||||
|     case PROP_AXES: | ||||
|       g_value_set_flags (value, priv->axes); | ||||
|       break; | ||||
|     default: | ||||
|       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | ||||
|     } | ||||
| @@ -137,13 +129,6 @@ clutter_input_device_tool_class_init (ClutterInputDeviceToolClass *klass) | ||||
|                          P_("Tool ID"), | ||||
|                          0, G_MAXUINT64, 0, | ||||
|                          CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); | ||||
|   props[PROP_AXES] = | ||||
|     g_param_spec_flags ("axes", | ||||
|                         P_("Axes"), | ||||
|                         P_("Axes"), | ||||
|                         CLUTTER_TYPE_INPUT_AXIS_FLAGS, | ||||
|                         CLUTTER_INPUT_AXIS_FLAG_NONE, | ||||
|                         CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); | ||||
|  | ||||
|   g_object_class_install_properties (gobject_class, PROP_LAST, props); | ||||
| } | ||||
| @@ -219,15 +204,3 @@ clutter_input_device_tool_get_id (ClutterInputDeviceTool *tool) | ||||
|  | ||||
|   return priv->id; | ||||
| } | ||||
|  | ||||
| ClutterInputAxisFlags | ||||
| clutter_input_device_tool_get_axes (ClutterInputDeviceTool *tool) | ||||
| { | ||||
|   ClutterInputDeviceToolPrivate *priv; | ||||
|  | ||||
|   g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE_TOOL (tool), 0); | ||||
|  | ||||
|   priv = clutter_input_device_tool_get_instance_private (tool); | ||||
|  | ||||
|   return priv->axes; | ||||
| } | ||||
|   | ||||
| @@ -64,9 +64,6 @@ ClutterInputDeviceToolType clutter_input_device_tool_get_tool_type (ClutterInput | ||||
| CLUTTER_EXPORT | ||||
| guint64                    clutter_input_device_tool_get_id        (ClutterInputDeviceTool *tool); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterInputAxisFlags      clutter_input_device_tool_get_axes      (ClutterInputDeviceTool *tool); | ||||
|  | ||||
| G_END_DECLS | ||||
|  | ||||
| #endif /* __CLUTTER_INPUT_DEVICE_TOOL_H__ */ | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -34,10 +34,19 @@ | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| typedef void (*ClutterEmitInputDeviceEvent) (ClutterEvent       *event, | ||||
|                                              ClutterInputDevice *device); | ||||
|  | ||||
| struct _ClutterInputDeviceClass | ||||
| { | ||||
|   GObjectClass parent_class; | ||||
|  | ||||
|   gboolean (* keycode_to_evdev) (ClutterInputDevice *device, | ||||
|                                  guint               hardware_keycode, | ||||
|                                  guint              *evdev_keycode); | ||||
|   void (* update_from_tool) (ClutterInputDevice     *device, | ||||
|                              ClutterInputDeviceTool *tool); | ||||
|  | ||||
|   gboolean (* is_mode_switch_button) (ClutterInputDevice *device, | ||||
|                                       guint               group, | ||||
|                                       guint               button); | ||||
| @@ -47,9 +56,10 @@ struct _ClutterInputDeviceClass | ||||
|   gboolean (* is_grouped) (ClutterInputDevice *device, | ||||
|                            ClutterInputDevice *other_device); | ||||
|  | ||||
|   int (* get_pad_feature_group) (ClutterInputDevice           *device, | ||||
|                                  ClutterInputDevicePadFeature  feature, | ||||
|                                  int                           n_feature); | ||||
|   /* Keyboard accessbility */ | ||||
|   void (* process_kbd_a11y_event) (ClutterEvent               *event, | ||||
|                                    ClutterInputDevice         *device, | ||||
|                                    ClutterEmitInputDeviceEvent emit_event_func); | ||||
| }; | ||||
|  | ||||
| #define CLUTTER_TYPE_INPUT_DEVICE               (clutter_input_device_get_type ()) | ||||
| @@ -72,13 +82,64 @@ GType clutter_input_device_get_type (void) G_GNUC_CONST; | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterInputDeviceType  clutter_input_device_get_device_type    (ClutterInputDevice  *device); | ||||
| CLUTTER_EXPORT | ||||
| gint                    clutter_input_device_get_device_id      (ClutterInputDevice  *device); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| gboolean                clutter_input_device_get_coords        (ClutterInputDevice   *device, | ||||
|                                                                 ClutterEventSequence *sequence, | ||||
|                                                                 graphene_point_t     *point); | ||||
| CLUTTER_EXPORT | ||||
| ClutterModifierType     clutter_input_device_get_modifier_state (ClutterInputDevice  *device); | ||||
| CLUTTER_EXPORT | ||||
| ClutterActor *          clutter_input_device_get_pointer_actor  (ClutterInputDevice  *device); | ||||
| CLUTTER_EXPORT | ||||
| ClutterStage *          clutter_input_device_get_pointer_stage  (ClutterInputDevice  *device); | ||||
| CLUTTER_EXPORT | ||||
| const gchar *           clutter_input_device_get_device_name    (ClutterInputDevice  *device); | ||||
| CLUTTER_EXPORT | ||||
| ClutterInputMode        clutter_input_device_get_device_mode    (ClutterInputDevice  *device); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                clutter_input_device_get_has_cursor     (ClutterInputDevice  *device); | ||||
| CLUTTER_EXPORT | ||||
| void                    clutter_input_device_set_enabled        (ClutterInputDevice  *device, | ||||
|                                                                  gboolean             enabled); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                clutter_input_device_get_enabled        (ClutterInputDevice  *device); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| guint                   clutter_input_device_get_n_axes         (ClutterInputDevice  *device); | ||||
| CLUTTER_EXPORT | ||||
| ClutterInputAxis        clutter_input_device_get_axis           (ClutterInputDevice  *device, | ||||
|                                                                  guint                index_); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                clutter_input_device_get_axis_value     (ClutterInputDevice  *device, | ||||
|                                                                  gdouble             *axes, | ||||
|                                                                  ClutterInputAxis     axis, | ||||
|                                                                  gdouble             *value); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| guint                   clutter_input_device_get_n_keys         (ClutterInputDevice  *device); | ||||
| CLUTTER_EXPORT | ||||
| void                    clutter_input_device_set_key            (ClutterInputDevice  *device, | ||||
|                                                                  guint                index_, | ||||
|                                                                  guint                keyval, | ||||
|                                                                  ClutterModifierType  modifiers); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                clutter_input_device_get_key            (ClutterInputDevice  *device, | ||||
|                                                                  guint                index_, | ||||
|                                                                  guint               *keyval, | ||||
|                                                                  ClutterModifierType *modifiers); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterInputDevice *    clutter_input_device_get_associated_device (ClutterInputDevice *device); | ||||
| CLUTTER_EXPORT | ||||
| GList *                 clutter_input_device_get_slave_devices  (ClutterInputDevice  *device); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void                    clutter_input_device_update_from_event  (ClutterInputDevice  *device, | ||||
|                                                                  ClutterEvent        *event, | ||||
|                                                                  gboolean             update_stage); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void                    clutter_input_device_grab               (ClutterInputDevice  *device, | ||||
| @@ -99,6 +160,11 @@ CLUTTER_EXPORT | ||||
| ClutterActor *          clutter_input_device_sequence_get_grabbed_actor (ClutterInputDevice   *device, | ||||
|                                                                          ClutterEventSequence *sequence); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| gboolean                clutter_input_device_keycode_to_evdev   (ClutterInputDevice *device, | ||||
|                                                                  guint               hardware_keycode, | ||||
|                                                                  guint              *evdev_keycode); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| const gchar *           clutter_input_device_get_vendor_id      (ClutterInputDevice *device); | ||||
| CLUTTER_EXPORT | ||||
| @@ -110,9 +176,6 @@ CLUTTER_EXPORT | ||||
| gint                    clutter_input_device_get_n_strips       (ClutterInputDevice *device); | ||||
| CLUTTER_EXPORT | ||||
| gint                    clutter_input_device_get_n_mode_groups  (ClutterInputDevice *device); | ||||
| CLUTTER_EXPORT | ||||
| int                     clutter_input_device_get_n_buttons (ClutterInputDevice *device); | ||||
|  | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| gint                    clutter_input_device_get_group_n_modes  (ClutterInputDevice *device, | ||||
| @@ -129,17 +192,18 @@ gint                    clutter_input_device_get_mode_switch_button_group (Clutt | ||||
| CLUTTER_EXPORT | ||||
| const gchar *           clutter_input_device_get_device_node    (ClutterInputDevice *device); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| ClutterInputDeviceMapping clutter_input_device_get_mapping_mode (ClutterInputDevice *device); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| void                      clutter_input_device_set_mapping_mode (ClutterInputDevice        *device, | ||||
|                                                                  ClutterInputDeviceMapping  mapping); | ||||
| CLUTTER_EXPORT | ||||
| gboolean                  clutter_input_device_is_grouped       (ClutterInputDevice *device, | ||||
|                                                                  ClutterInputDevice *other_device); | ||||
| CLUTTER_EXPORT | ||||
| ClutterSeat *             clutter_input_device_get_seat         (ClutterInputDevice *device); | ||||
|  | ||||
| CLUTTER_EXPORT | ||||
| int clutter_input_device_get_pad_feature_group (ClutterInputDevice           *device, | ||||
|                                                 ClutterInputDevicePadFeature  feature, | ||||
|                                                 int                           n_feature); | ||||
|  | ||||
| G_END_DECLS | ||||
|  | ||||
| #endif /* __CLUTTER_INPUT_DEVICE_H__ */ | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user